[CSS] Неверно откидывает(геометрия)

horr0rjkee

Участник
Сообщения
5
Реакции
0
Вообщем делал откидывание, при взрыве гранаты.
PHP:
#include <sourcemod>
new VelocityOffset[3],BaseVelocityOffset;
public OnPluginStart()
{
	HookEvent("hegrenade_detonate", OnBounce);
	VelocityOffset[0]=FindSendPropOffs("CBasePlayer","m_vecVelocity[0]");
	VelocityOffset[1]=FindSendPropOffs("CBasePlayer","m_vecVelocity[1]");
	VelocityOffset[2]=FindSendPropOffs("CBasePlayer","m_vecVelocity[2]");
	BaseVelocityOffset=FindSendPropOffs("CBasePlayer","m_vecBaseVelocity");
}

public OnBounce(Handle:event, const String:name[], bool:dontBroadcast) 
{	
	new Float:finalvec[3], Float:angle, Float:gpos[3], Float:plpos[3];
	gpos[0] = GetEventFloat(event, "x");
	gpos[1] = GetEventFloat(event, "y");
	gpos[2] = GetEventFloat(event, "z");
	for(new i = 1; i <= MaxClients; i++)
	{
		if(!IsClientInGame(i)) continue;
		if(IsClientInRangeOfPoint(i, 400.0, gpos))
		{
			GetClientAbsOrigin(i, plpos);
			angle = ArcTangent2(gpos[0]-plpos[0], gpos[1]-plpos[1]);
			PrintToChat(i, "atan2(%0.1f-%0.1f, %0.1f-%0.1f): %f", gpos[0],plpos[0],gpos[1],plpos[1],RadToDeg(angle));
			finalvec[0]=GetEntDataFloat(i,VelocityOffset[0]) + Cosine(angle+DegToRad(180.0))*250.0;
			finalvec[1]=GetEntDataFloat(i,VelocityOffset[1]) + Sine(angle+DegToRad(180.0))*250.0;
			finalvec[2]=GetEntDataFloat(i,VelocityOffset[2]) + 50.0;
			SetEntDataVector(i,BaseVelocityOffset,finalvec,true);
		}
	}
	
}

stock IsClientInRangeOfPoint(client, Float:radius, Float:cpos[3]) //by horr0r
{
	if(!IsClientInGame(client)) return false;
	new Float:ppos[3];
	GetClientAbsOrigin(client, ppos);
	if(GetDistance(ppos, cpos) <= radius) return true;
	return false;
}
stock Float:GetDistance(Float:pos1[3], Float:pos2[3]) //by horr0r
{
	return SquareRoot( Pow(pos2[0] - pos1[0], 2.0) + Pow(pos2[1] - pos1[1], 2.0) + Pow(pos2[2]-pos1[2], 2.0) );
}
.
Но я не понимаю, почему тут не работает? Вроде все просто.
1) Получаем позицию игрока и гранаты.
2) Находим угол для ускорения по векторам. Используя atan2(поз.гранаты - поз.игрока).
3) К вектору велосити X прибавляем косинус полученного угла.
4) К вектору велосити Y прибавляем синус полученного угла.
Основная ошибка в том, что откидывает в неправильный угол, проблема не в atan2(проверял).
Прошу, помогите. В другой игре, все это работает!
P.S. Последние две функции (из моего инклюда вырезал, просто лень весь инклюд сюда закидывать):
IsClientInRangeOfPoint - проверяет, в радиусе ли игрок от определенной точки.
GetDistance - возвращает дистанцию между двумя точками.
 
Последнее редактирование:

vanbka9

Участник
Сообщения
14
Реакции
13
Как-то так...:) взял с ZombieReloaded
PHP:
new offsBaseVelocity,
	Float:knockback = 4.0; // сила отброса

public OnPluginStart()
{
	offsBaseVelocity = FindSendPropInfo("CBasePlayer", "m_vecBaseVelocity");
	if (offsBaseVelocity == -1)
	{
		SetFailState("Couldn't find \"m_vecBaseVelocity\"!");
	}
	HookEvent("player_hurt", PlayerHurt);
}

public Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
{
	new index = GetClientOfUserId(GetEventInt(event, "userid"));
	new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
	new dmg = GetEventInt(event, "dmg_health");
	decl String:weapon[32];
	GetEventString(event, "weapon", weapon, sizeof(weapon));
	if (attacker != 0)
	{
		new Float:clientloc[3];
		GetClientAbsOrigin(index, clientloc);
		if (StrEqual(weapon, "hegrenade"))
		{
			new Float:heLoc[3];
			FindExplodingGrenade(heLoc);
			KnockBack(index, clientloc, heLoc, knockback, dmg, true);
		}
	}
}

KnockBack(client, const Float:clientloc[3], const Float:attackerloc[3], Float:power, dmg, bool:boost)
{
	new Float:vector[3];
	MakeVectorFromPoints(attackerloc, clientloc, vector);
	NormalizeVector(vector, vector);
	vector[0] *= power * (float(dmg) * 1.5);
	vector[1] *= power * (float(dmg) * 1.5);
	vector[2] *= power * (float(dmg) * 1.5);
	if (boost)
	{
		for (new i = 0; i < 3; i++)
		{
			if (vector[i] > 250.0)
			{
				vector[i] = 250.0;
			}		
			else if (vector[i] < -250.0)
			{
				vector[i] = -250.0;
			}
		}
		ScaleVector(vector, 4.0);
	}
	SetEntDataVector(client, offsBaseVelocity, vector, true);
}

FindExplodingGrenade(Float:heLoc[3])
{
	decl String:classname[64];
	new maxentities = GetMaxEntities();
	for (new x = GetMaxClients(); x <= maxentities; x++)
	{
		if (IsValidEdict(x))
		{
			GetEdictClassname(x, classname, sizeof(classname));
			if (StrEqual(classname, "hegrenade_projectile"))
			{
				new takedamage = GetEntProp(x, Prop_Data, "m_takedamage");
				if (takedamage == 0)
				{
					GetEntPropVector(x, Prop_Send, "m_vecOrigin", heLoc);
					return x;
				}
			}
		}
	}
	return -1;
}
P.S. Добавил цикл проверки вектора во избежание такой ошибки, если значение больше 1000 => "DataTable warning: (class player): Out-of-range value (-1015.915162) in SendProp Float 'm_vecBaseVelocity', clamping".
 

Вложения

  • KnockBack.sp
    2 КБ · Просмотры: 16
Последнее редактирование:

horr0rjkee

Участник
Сообщения
5
Реакции
0
Эти функции скинь пожалуйста:
MakeVectorFromPoints,
NormalizeVector,
ScaleVector.

Скорее всего вся соль, в функции "MakeVectorFromPoints". Она угол возвращает. Между двумя позициями. Как и
PHP:
ArcTangent2(пИx-пГx, пИy-пГy);
C-подобный:
пИx - позиция игрока X
пИy - позиция игрока Y
пГx - позиция гранаты X
пГy - позиция гранаты Y
 
Последнее редактирование:

vanbka9

Участник
Сообщения
14
Реакции
13
Нет. Всё гораздо проще. Всё это есть в API

MakeVectorFromPoints
PHP:
stock MakeVectorFromPoints(const Float:pt1[3], const Float:pt2[3], Float:output[3])
{
	output[0] = pt2[0] - pt1[0];
	output[1] = pt2[1] - pt1[1];
	output[2] = pt2[2] - pt1[2];
}
NormalizeVector ПРИМЕР
PHP:
Syntax:
native Float:NormalizeVector(const Float:vec[3], Float:result[3]);

Usage:
 vec		Vector.
 result	Resultant vector.
Notes:
Normalizes a vector. The input array can be the same as the output array.

Return:
Vector length.
ScaleVector
PHP:
stock ScaleVector(Float:vec[3], Float:scale)
{
	vec[0] *= scale;
	vec[1] *= scale;
	vec[2] *= scale;
}
 

wanted241

Real-Gamer.Ru
Сообщения
428
Реакции
161
Эти функции скинь пожалуйста:
MakeVectorFromPoints,
NormalizeVector,
ScaleVector.

Скорее всего вся соль, в функции "MakeVectorFromPoints". Она угол возвращает. Между двумя позициями. Как и
PHP:
ArcTangent2(пИx-пГx, пИy-пГy);
C-подобный:
пИx - позиция игрока X
пИy - позиция игрока Y
пГx - позиция гранаты X
пГy - позиция гранаты Y

1. http://docs.sourcemod.net/api/index.php?fastload=show&id=558&
2. http://docs.sourcemod.net/api/index.php?fastload=show&id=550&
3. http://docs.sourcemod.net/api/index.php?fastload=show&id=556&
 
Сверху Снизу