forked from UNLOZE/sm-plugins
added vscripts core and the moving npc from that asian dude. added includes as well because we already have something called vscripts.inc i guess
This commit is contained in:
@@ -0,0 +1,331 @@
|
||||
#if defined _MovingNPC_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _MovingNPC_included
|
||||
#include <basic>
|
||||
//#include <vscripts>
|
||||
#include <vscripts_moving_npc>
|
||||
#include <float>
|
||||
|
||||
stock float operator%(float oper1, float oper2)
|
||||
{
|
||||
return FloatMod(oper1, oper2);
|
||||
}
|
||||
|
||||
public bool IsValidPlayer(int player)
|
||||
{
|
||||
return player >= 1 && player <= MAXPLAYERS && IsValidEntity(player) && IsPlayerAlive(player);
|
||||
}
|
||||
|
||||
public float GetDistance(const float v1[3], const float v2[3])
|
||||
{
|
||||
return SquareRoot((v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]) + (v1[2] - v2[2]) * (v1[2] - v2[2]));
|
||||
}
|
||||
|
||||
methodmap MovingNpc < Basic
|
||||
{
|
||||
public MovingNpc(int entity, float tickrate = 0.1, float distance = 5000.0, float retarget = 7.5, float forward_factor = 1.0, float turning_factor = 0.5, float lifetime = 0.0)
|
||||
{
|
||||
Basic myclass = new Basic();
|
||||
myclass.SetFloat("fRate", tickrate);
|
||||
myclass.SetFloat("fDistance", distance);
|
||||
myclass.SetFloat("fRetarget", retarget);
|
||||
myclass.SetFloat("fForward", forward_factor);
|
||||
myclass.SetFloat("fTurning", turning_factor);
|
||||
myclass.SetFloat("fLifetime", lifetime);
|
||||
myclass.SetInt("iEntity", entity);
|
||||
myclass.SetInt("iTarget", -1);
|
||||
myclass.SetInt("iTf", -1);
|
||||
myclass.SetInt("iTs", -1);
|
||||
myclass.SetFloat("fTtime", 0.0);
|
||||
myclass.SetBool("bTicking", false);
|
||||
myclass.SetHandle("hLifeTimer", null);
|
||||
myclass.SetBool("bKill", false);
|
||||
return view_as<MovingNpc>(myclass);
|
||||
}
|
||||
property bool kill
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetBool("bKill");
|
||||
}
|
||||
public set(bool val)
|
||||
{
|
||||
this.SetBool("bKill", val);
|
||||
}
|
||||
}
|
||||
property Handle lifetimer
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetHandle("hLifeTimer");
|
||||
}
|
||||
public set(Handle val)
|
||||
{
|
||||
this.SetHandle("hLifeTimer", val);
|
||||
}
|
||||
}
|
||||
property float lifetime
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fLifetime");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fLifetime", val);
|
||||
}
|
||||
}
|
||||
property float rate
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fRate");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fRate", val);
|
||||
}
|
||||
}
|
||||
property float distance
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fDistance");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fDistance", val);
|
||||
}
|
||||
}
|
||||
property float retarget
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fRetarget");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fRetarget", val);
|
||||
}
|
||||
}
|
||||
property float forward_factor
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fForward");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fForward", val);
|
||||
}
|
||||
}
|
||||
property float turning_factor
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fTurning");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fTurning", val);
|
||||
}
|
||||
}
|
||||
property int entity
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iEntity");
|
||||
}
|
||||
public set(int val)
|
||||
{
|
||||
this.SetInt("iEntity", val);
|
||||
}
|
||||
}
|
||||
property int target
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iTarget");
|
||||
}
|
||||
public set(int val)
|
||||
{
|
||||
this.SetInt("iTarget", val);
|
||||
}
|
||||
}
|
||||
property int tf
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iTf");
|
||||
}
|
||||
public set(int val)
|
||||
{
|
||||
this.SetInt("iTf", val);
|
||||
}
|
||||
}
|
||||
property int ts
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetInt("iTs");
|
||||
}
|
||||
public set(int val)
|
||||
{
|
||||
this.SetInt("iTs", val);
|
||||
}
|
||||
}
|
||||
property float ttime
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetFloat("fTtime");
|
||||
}
|
||||
public set(float val)
|
||||
{
|
||||
this.SetFloat("fTtime", val);
|
||||
}
|
||||
}
|
||||
property bool ticking
|
||||
{
|
||||
public get()
|
||||
{
|
||||
return this.GetBool("bTicking");
|
||||
}
|
||||
public set(bool val)
|
||||
{
|
||||
this.SetBool("bTicking", val);
|
||||
}
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if(!this.ticking)
|
||||
{
|
||||
this.ticking = true;
|
||||
Vscripts_CreateTimer(this.rate, Tick_Cb, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if(this.ticking)
|
||||
{
|
||||
this.ticking = false;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetTargetYaw(const float start[3], const float target[3])
|
||||
{
|
||||
float yaw = 0.00;
|
||||
float v[3];
|
||||
SubtractVectors(start, target, v);
|
||||
float vl = SquareRoot(v[0] * v[0] + v[1] * v[1]);
|
||||
yaw = 180.0 * ArcCosine(v[0] / vl) / 3.14159;
|
||||
if (v[1] < 0.0)
|
||||
yaw = -yaw;
|
||||
return yaw;
|
||||
}
|
||||
|
||||
public void SetThruster(bool fwd, int caller)
|
||||
{
|
||||
if(fwd)
|
||||
this.tf = caller;
|
||||
else
|
||||
this.ts = caller;
|
||||
}
|
||||
|
||||
public void SearchTarget()
|
||||
{
|
||||
this.ttime = 0.00;
|
||||
this.target = -1;
|
||||
int h = -1;
|
||||
ArrayList candidates = new ArrayList();
|
||||
float orig[3];
|
||||
Vscripts_GetOrigin(this.entity, orig);
|
||||
while (-1 != (h = Vscripts_FindEntityByClassnameWithin(h, "player", orig, this.distance)))
|
||||
{
|
||||
//check if target is a valid player + CT team(3) + health above 0 (not dead)
|
||||
if (GetClientTeam(h) == 3 && IsPlayerAlive(h))
|
||||
{
|
||||
//check if the target is in sight of the npc (this physbox origin+48 height)
|
||||
float t_orig[3];
|
||||
Vscripts_GetOrigin(this.entity, orig);
|
||||
orig[2] += 40.0;
|
||||
Vscripts_GetOrigin(h, t_orig);
|
||||
t_orig[2] += 48.0;
|
||||
if (Vscripts_TraceLine(orig, t_orig, this.entity) == 1.00)
|
||||
candidates.Push(h); //if everything required is OK, add the target to the list of candidates
|
||||
}
|
||||
}
|
||||
if(candidates.Length == 0)
|
||||
{
|
||||
delete candidates;
|
||||
return;
|
||||
}
|
||||
this.target = candidates.Get(GetRandomInt(0, candidates.Length - 1));
|
||||
|
||||
delete candidates;
|
||||
}
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
Vscripts_EntFireByIndex(this.tf, "Deactivate", "", 0.0, -1);
|
||||
Vscripts_EntFireByIndex(this.ts, "Deactivate", "", 0.0, -1);
|
||||
if (!IsValidPlayer(this.target) || GetClientTeam(this.target) != 3 || this.ttime >= this.retarget)
|
||||
{
|
||||
this.SearchTarget();
|
||||
}
|
||||
this.ttime+=this.rate;
|
||||
Vscripts_EntFireByIndex(this.tf, "Activate", "", 0.02, -1);
|
||||
Vscripts_EntFireByIndex(this.ts, "Activate", "", 0.02, -1);
|
||||
if(!IsValidPlayer(this.target))
|
||||
{
|
||||
Vscripts_CreateTimer(this.rate, Tick_Cb, this);
|
||||
return;
|
||||
}
|
||||
float angl[3], s_orig[3], t_orig[3];
|
||||
Vscripts_GetAngles(this.entity, angl);
|
||||
Vscripts_GetOrigin(this.entity, s_orig);
|
||||
Vscripts_GetOrigin(this.target, t_orig);
|
||||
float sa = angl[1];
|
||||
float ta = this.GetTargetYaw(s_orig, t_orig);
|
||||
float ang = FloatAbs((sa - ta + 360.0) % 360.0);
|
||||
if (ang >= 180.0)
|
||||
Vscripts_EntFireByIndex(this.ts, "AddOutput", "angles 0 270 0", 0.0, -1);
|
||||
else
|
||||
Vscripts_EntFireByIndex(this.ts, "AddOutput", "angles 0 90 0", 0.0, -1);
|
||||
float angdif = (sa - ta - 180.0);
|
||||
while (angdif > 360.0) { angdif -= 180.0; }
|
||||
while (angdif < -180.0) { angdif += 360.0; }
|
||||
angdif = FloatAbs(angdif);
|
||||
char input[MAX_INPUT_NAME];
|
||||
Format(input, sizeof(input), "force %.4f", 3000.0 * this.forward_factor);
|
||||
Vscripts_EntFireByIndex(this.tf, "AddOutput", input, 0.0, -1);
|
||||
Format(input, sizeof(input), "force %.4f", (3.0 * this.turning_factor) * angdif);
|
||||
Vscripts_EntFireByIndex(this.ts, "AddOutput", input, 0.0, -1);
|
||||
Vscripts_CreateTimer(this.rate, Tick_Cb, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick_Cb(MovingNpc npc)
|
||||
{
|
||||
if(npc.kill)
|
||||
{
|
||||
if(npc.lifetimer)
|
||||
KillTimer(npc.lifetimer);
|
||||
delete npc;
|
||||
return;
|
||||
}
|
||||
|
||||
if(npc.ticking)
|
||||
{
|
||||
npc.Tick();
|
||||
}
|
||||
else
|
||||
{
|
||||
Vscripts_EntFireByIndex(npc.tf, "Deactivate", "", 0.0, -1);
|
||||
Vscripts_EntFireByIndex(npc.ts, "Deactivate", "", 0.0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
**
|
||||
*/
|
||||
#if defined _VSCRIPTS_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _VSCRIPTS_included
|
||||
#include <sdktools>
|
||||
#undef REQUIRE_EXTENSIONS
|
||||
#include <eventqueue>
|
||||
#define REQUIRE_EXTENSIONS
|
||||
|
||||
#define MAX_ENT_NAME 32
|
||||
#define MAX_INPUT_NAME 32
|
||||
|
||||
typedef VscriptTimerCallback = function void(any data);
|
||||
|
||||
native void Vscripts_CreateTimer(float interval, VscriptTimerCallback func, any data = INVALID_HANDLE);
|
||||
native bool Vscripts_IsEventQueueLoaded();
|
||||
native bool Vscripts_TraceFilterSimple(int entity, int contentsMask, int ignore = -1);
|
||||
|
||||
forward void Vscritps_OnTemplateInstanceCreated(int template, const int[] createdEntities, int size);
|
||||
|
||||
stock int Vscripts_GetEntityIndexByHammerID(int HammerID, const char[] classname = "*", int startEnt = -1)
|
||||
{
|
||||
while((startEnt = FindEntityByClassname(startEnt,classname))!= -1) {
|
||||
if (GetEntProp(startEnt, Prop_Data, "m_iHammerID") == HammerID)
|
||||
return startEnt;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
stock int Vscripts_GetEntityIndexByName(const char[] name, const char[] classname = "*", int startEnt = -1)
|
||||
{
|
||||
char buffer[MAX_ENT_NAME];
|
||||
int ch = FindCharInString(name, '*', true);
|
||||
while((startEnt = FindEntityByClassname(startEnt, classname))!= -1){
|
||||
GetEntityClassname(startEnt, buffer, sizeof(buffer));
|
||||
if (strcmp(name, buffer) == 0)
|
||||
return startEnt;
|
||||
|
||||
GetEntPropString(startEnt, Prop_Data, "m_iName", buffer, sizeof(buffer));
|
||||
if(strncmp(name, buffer, ch) == 0)
|
||||
return startEnt;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int Vscripts_FindEntityByClassnameWithin(int startEnt, const char[] classname, const float origin[3], const float radius)
|
||||
{
|
||||
float torigin[3];
|
||||
while((startEnt = FindEntityByClassname(startEnt,classname))!= -1){
|
||||
Vscripts_GetOrigin(startEnt, torigin);
|
||||
if(GetVectorDistance(torigin, origin) <= radius) return startEnt;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public float Vscripts_TraceLine(const float origin[3], const float v2[3], int entity)
|
||||
{
|
||||
TR_TraceRayFilter(origin, v2, MASK_NPCWORLDSTATIC, RayType_EndPoint, TraceEntityFilterSelf, entity);
|
||||
float fraction_left = TR_GetFractionLeftSolid(INVALID_HANDLE), fraction = 0.0;
|
||||
if (fraction_left && TR_StartSolid(INVALID_HANDLE)) {
|
||||
fraction = 1.0 - fraction_left;
|
||||
}
|
||||
else {
|
||||
fraction = TR_GetFraction(INVALID_HANDLE);
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
|
||||
bool TraceEntityFilterSelf(int entity, int contentsMask, int data)
|
||||
{
|
||||
return Vscripts_TraceFilterSimple(entity, contentsMask, data);
|
||||
}
|
||||
|
||||
public void Vscripts_GetOrigin(int entity, float buffer[3])
|
||||
{
|
||||
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", buffer);
|
||||
}
|
||||
|
||||
public void Vscripts_GetAngles(int entity, float buffer[3])
|
||||
{
|
||||
GetEntPropVector(entity, Prop_Send, "m_angRotation", buffer);
|
||||
}
|
||||
|
||||
public void Vscripts_SetAngles(int entity, const float buffer[3])
|
||||
{
|
||||
TeleportEntity(entity, NULL_VECTOR, buffer, NULL_VECTOR);
|
||||
}
|
||||
|
||||
public void Vscripts_SetOrigin(int entity, const float buffer[3])
|
||||
{
|
||||
TeleportEntity(entity, buffer, NULL_VECTOR, NULL_VECTOR);
|
||||
}
|
||||
|
||||
public void Vscripts_GetForwardVector(int entity, float buffer[3])
|
||||
{
|
||||
float tmp[3];
|
||||
Vscripts_GetAngles(entity, tmp);
|
||||
GetAngleVectors(tmp, buffer, NULL_VECTOR, NULL_VECTOR);
|
||||
}
|
||||
|
||||
public void Vscripts_SetForwardVector(int entity, const float buffer[3])
|
||||
{
|
||||
float tmp[3];
|
||||
GetVectorAngles(buffer, tmp);
|
||||
Vscripts_SetAngles(entity, tmp);
|
||||
}
|
||||
|
||||
stock void Vscripts_EntFire(const char[] target, const char[] input, const char[] parametr, float delay, int activator = -1)
|
||||
{
|
||||
if(Vscripts_IsEventQueueLoaded())
|
||||
EQ_AddEventByName(target, input, parametr, delay, activator);
|
||||
else
|
||||
{
|
||||
DataPack data = CreateDataPack();
|
||||
data.WriteString(input);
|
||||
data.WriteString(parametr);
|
||||
data.WriteCell(activator >= 0 ? EntIndexToEntRef(activator) : -1);
|
||||
data.WriteCell(true);
|
||||
data.WriteString(target);
|
||||
Vscripts_CreateTimer(delay, InputDelay, data);
|
||||
}
|
||||
}
|
||||
|
||||
stock void Vscripts_EntFireByIndex(int target, const char[] input, const char[] parametr, float delay, int activator = -1)
|
||||
{
|
||||
if(Vscripts_IsEventQueueLoaded())
|
||||
EQ_AddEvent(target, input, parametr, delay, activator);
|
||||
else
|
||||
{
|
||||
DataPack data = CreateDataPack();
|
||||
data.WriteString(input);
|
||||
data.WriteString(parametr);
|
||||
data.WriteCell(activator >= 0 ? EntIndexToEntRef(activator) : -1);
|
||||
data.WriteCell(false);
|
||||
data.WriteCell(EntIndexToEntRef(target));
|
||||
Vscripts_CreateTimer(delay, InputDelay, data);
|
||||
}
|
||||
}
|
||||
|
||||
void InputDelay(DataPack data)
|
||||
{
|
||||
char input[MAX_INPUT_NAME], parametr[2*MAX_ENT_NAME];
|
||||
data.Reset();
|
||||
data.ReadString(input, sizeof(input));
|
||||
data.ReadString(parametr, sizeof(parametr));
|
||||
int activator = data.ReadCell();
|
||||
int target = -1;
|
||||
if(view_as<bool>(data.ReadCell()) == true)
|
||||
{
|
||||
char name[MAX_ENT_NAME];
|
||||
data.ReadString(name, sizeof(name));
|
||||
while((target = Vscripts_GetEntityIndexByName(name, _, target)) != -1)
|
||||
{
|
||||
SetVariantString(parametr);
|
||||
AcceptEntityInput(target, input, activator != -1 ? EntRefToEntIndex(activator) : -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target = EntRefToEntIndex(data.ReadCell());
|
||||
if(IsValidEntity(target))
|
||||
{
|
||||
SetVariantString(parametr);
|
||||
AcceptEntityInput(target, input, activator != -1 ? EntRefToEntIndex(activator) : -1);
|
||||
}
|
||||
}
|
||||
data.Reset(true);
|
||||
delete data;
|
||||
}
|
||||
|
||||
public SharedPlugin __pl_vscripts=
|
||||
{
|
||||
name = "vscripts",
|
||||
file = "Vscripts_Core.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1
|
||||
#else
|
||||
required = 0
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public void __pl_vscripts_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("Vscripts_CreateTimer");
|
||||
MarkNativeAsOptional("Vscripts_IsEventQueueLoaded");
|
||||
MarkNativeAsOptional("Vscripts_TraceFilterSimple");
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user