TheRunningMan
Участник
- Сообщения
- 147
- Реакции
- 10
Привет!
В общем ситация такая, я перделываю плагин лазерных мин, но это не суть...
Дело такое при взрыве мины мне нужно что б она отталкивала, посредством ентити env_explosion, т.е. объект ломается, спаумится эта интитя и тут же взрывается, по магнитуде наноси тповреждение, я это повреждение хукаю через сдкхук от этой энтити, и происходит система отталкивания, которую мне подсказали взять из ZombieReloaded, вот что я там нашел...
Конечно, некоторые моменты мне были не понятны зачем и для чего и что это вообще, ибо саму физику процесса никто не объясняет, я это использовал, но не хукал player_hurt, а хукал провреждение от энтити взрыва( это правильно или я уже здесь ошибся), в общем измени ли получилось так...
тут наврено не понятно больше две последние функции, что они и для чего, понятно что есть комментарии, но как говорится изложите по русски))
Само создание энтити
И так проблема в отталкивании, оно есть, но не правильно, т.е. когда я указываю владельца энтити он отталкивает относитнльно его или точнее относительно тог окуда владелец смотрит, вот я взорву, и куда я смотрел туда и оттолкнет, если я не указываю владельца, то конечно отталкивает нормально тноситенльо взрыва в разные стороны, я честно не понимаю в чем проблема, потому что сам особо не шарю, но пытаюсь разобраться, эксперименты хорошо, я все плагины написал на экспериментах))) но все таки если не знаешь или не понмиаешь, то лучше чтоб указали где ошибка или пояснили хотя в чем она заключается...
В общем ситация такая, я перделываю плагин лазерных мин, но это не суть...
Дело такое при взрыве мины мне нужно что б она отталкивала, посредством ентити env_explosion, т.е. объект ломается, спаумится эта интитя и тут же взрывается, по магнитуде наноси тповреждение, я это повреждение хукаю через сдкхук от этой энтити, и происходит система отталкивания, которую мне подсказали взять из ZombieReloaded, вот что я там нашел...
PHP:
new g_iToolsVelocity;
public OnPluginStart()
{
HookEvent("player_hurt", EventPlayerHurt);
g_iToolsVelocity = FindSendPropInfo("CBasePlayer", "m_vecVelocity[0]");
}
public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
{
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
new hitgroup = GetEventInt(event, "hitgroup");
new dmg_health = GetEventInt(event, "dmg_health");
decl String:weapon[WEAPONS_MAX_LENGTH];
GetEventString(event, "weapon", weapon, sizeof(weapon));
// Forward event to modules.
ClassAlphaUpdate(index);
InfectOnClientHurt(index, attacker, weapon);
AccountOnClientHurt(index, attacker, dmg_health);
SEffectsOnClientHurt(index);
KnockbackOnClientHurt(index, attacker, weapon, hitgroup, dmg_health);
NapalmOnClientHurt(index, attacker, weapon);
ZHPOnClientHurt(index);
}
KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_health)
{
// If attacker is invalid, then stop.
if (!ZRIsClientValid(attacker))
{
return;
}
// Client is a human, then stop.
if (InfectIsClientHuman(client))
{
return;
}
// If attacker is a zombie, then stop.
if (InfectIsClientInfected(attacker))
{
return;
}
// Get zombie knockback value.
new Float:knockback = ClassGetKnockback(client);
new Float:clientloc[3];
new Float:attackerloc[3];
GetClientAbsOrigin(client, clientloc);
// Check if a grenade was thrown.
if (StrEqual(weapon, "hegrenade"))
{
// Get the location of the grenade.
if (KnockbackFindExplodingGrenade(attackerloc) == -1)
{
// If the grenade wasn't found, then stop.
return;
}
}
else
{
// Get attackers eye position.
GetClientEyePosition(attacker, attackerloc);
// Get attackers eye angles.
new Float:attackerang[3];
GetClientEyeAngles(attacker, attackerang);
// Calculate knockback end-vector.
TR_TraceRayFilter(attackerloc, attackerang, MASK_ALL, RayType_Infinite, KnockbackTRFilter);
TR_GetEndPosition(clientloc);
}
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (weapons)
{
new weaponindex = WeaponsNameToIndex(weapon);
if (weaponindex != -1)
{
// Apply weapon knockback multiplier.
knockback *= WeaponsGetKnockback(weaponindex);
}
}
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (hitgroups)
{
new hitgroupindex = HitgroupToIndex(hitgroup);
if (hitgroupindex != -1)
{
// Apply hitgroup knockback multiplier.
knockback *= HitgroupsGetKnockback(hitgroupindex);
}
}
// Apply damage knockback multiplier.
knockback *= float(dmg_health);
// Apply knockback.
KnockbackSetVelocity(client, attackerloc, clientloc, knockback);
}
KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude)
{
// Create vector from the given starting and ending points.
new Float:vector[3];
MakeVectorFromPoints(startpoint, endpoint, vector);
// Normalize the vector (equal magnitude at varying distances).
NormalizeVector(vector, vector);
// Apply the magnitude by scaling the vector (multiplying each of its components).
ScaleVector(vector, magnitude);
// ADD the given vector to the client's current velocity.
ToolsClientVelocity(client, vector);
}
stock ToolsClientVelocity(client, Float:vecVelocity[3], bool:apply = true, bool:stack = true)
{
// If retrieve if true, then get client's velocity.
if (!apply)
{
// x = vector component.
for (new x = 0; x < 3; x++)
{
vecVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
// Stop here.
return;
}
// If stack is true, then add client's velocity.
if (stack)
{
// Get client's velocity.
new Float:vecClientVelocity[3];
// x = vector component.
for (new x = 0; x < 3; x++)
{
vecClientVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
AddVectors(vecClientVelocity, vecVelocity, vecVelocity);
}
// Apply velocity on client.
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vecVelocity);
}
Конечно, некоторые моменты мне были не понятны зачем и для чего и что это вообще, ибо саму физику процесса никто не объясняет, я это использовал, но не хукал player_hurt, а хукал провреждение от энтити взрыва( это правильно или я уже здесь ошибся), в общем измени ли получилось так...
PHP:
public OnClientPutInServer(client)
{
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamageClient);
}
public Action:OnTakeDamageClient(client, &attacker, &inflictor, &Float:damage, &damagetype)
{
decl String:classname[64];
if(attacker > 0 && IsValidEdict(attacker))
{
GetEdictClassname(inflictor, classname, sizeof(classname));
if(StrEqual(classname, "grenadeee") && client > 0 && ZR_IsClientHuman(client))
return Plugin_Handled;
if(StrEqual(classname, "grenadeee") && client > 0 && ZR_IsClientZombie(client))
{
KnockbackOnClientHurt(client, inflictor, damage);
return Plugin_Changed;
}
}
return Plugin_Continue;
}
KnockbackOnClientHurt(client, attacker, Float:dmg_health)
{
new Float:knockback = 1.1;
new Float:clientloc[3];
new Float:attackerloc[3];
GetClientAbsOrigin(client, clientloc);
GetEntPropVector(attacker, Prop_Send, "m_vecOrigin", attackerloc);
knockback *= dmg_health;
KnockbackSetVelocity(client, attackerloc, clientloc, knockback);
}
KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude)
{
new Float:vector[3];
MakeVectorFromPoints(startpoint, endpoint, vector);
NormalizeVector(vector, vector);
ScaleVector(vector, magnitude);
ToolsClientVelocity(client, vector);
}
ToolsClientVelocity(client, Float:vecVelocity[3], bool:apply = true, bool:stack = true)
{
if (!apply)
{
for (new x = 0; x < 3; x++)
{
vecVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
return;
}
if (stack)
{
new Float:vecClientVelocity[3];
for (new x = 0; x < 3; x++)
{
vecClientVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
AddVectors(vecClientVelocity, vecVelocity, vecVelocity);
}
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vecVelocity);
}
тут наврено не понятно больше две последние функции, что они и для чего, понятно что есть комментарии, но как говорится изложите по русски))
Само создание энтити
PHP:
public mineBreak(const String:output[], caller, activator, Float:delay)
{
//Это узнаем индекс клиента через индекс мины
new owner = ZR_GetClientByLasermine(caller);
if (owner == -1)
return;
decl Float:vecPos[3];
GetEntPropVector(caller, Prop_Send, "m_vecOrigin", vecPos);
new iExplosion = CreateEntityByName("env_explosion");
if(iExplosion != -1)
{
DispatchKeyValue( iExplosion, "classname", "grenadeee");
DispatchKeyValue ( iExplosion , "iMagnitude" , "1000" );
DispatchKeyValue ( iExplosion , "iRadiusOverride" , "300" );
DispatchKeyValue ( iExplosion , "fireballsprite" , "sprites/zerogxplode.spr" );
DispatchKeyValue ( iExplosion , "rendermode" , "5" );
AcceptEntityInput ( iExplosion , "Enable" );
DispatchSpawn(iExplosion);
TeleportEntity(iExplosion, vecPos, NULL_VECTOR, NULL_VECTOR);
ActivateEntity(iExplosion);
SetEntProp(iExplosion, Prop_Data, "m_iCustomDamageType", DMG_BLAST);
SetEntPropEnt(iExplosion, Prop_Data, "m_hOwnerEntity", owner);
AcceptEntityInput(iExplosion, "Explode");
}
}
И так проблема в отталкивании, оно есть, но не правильно, т.е. когда я указываю владельца энтити он отталкивает относитнльно его или точнее относительно тог окуда владелец смотрит, вот я взорву, и куда я смотрел туда и оттолкнет, если я не указываю владельца, то конечно отталкивает нормально тноситенльо взрыва в разные стороны, я честно не понимаю в чем проблема, потому что сам особо не шарю, но пытаюсь разобраться, эксперименты хорошо, я все плагины написал на экспериментах))) но все таки если не знаешь или не понмиаешь, то лучше чтоб указали где ошибка или пояснили хотя в чем она заключается...