mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-05 23:03:20 +00:00
Add projectile magnet, fix dep bots
This commit is contained in:
parent
280c67157e
commit
c2e446750c
7 changed files with 206 additions and 92 deletions
Binary file not shown.
|
@ -4,7 +4,7 @@
|
|||
//Allow MAX_TROLLS to be defined elsewhere
|
||||
#if defined MAX_TROLLS
|
||||
#else
|
||||
#define MAX_TROLLS 45
|
||||
#define MAX_TROLLS 46
|
||||
#endif
|
||||
|
||||
enum trollModifier {
|
||||
|
@ -278,7 +278,7 @@ int GetTroll(const char[] name, Troll troll) {
|
|||
troll = Trolls[i];
|
||||
return i;
|
||||
}
|
||||
PrintToServer("GetTroll: Troll was not found \"%s\"", name);
|
||||
ThrowError("GetTroll: Troll was not found \"%s\"", name);
|
||||
return -1;
|
||||
}
|
||||
int GetTrollID(const char[] name) {
|
||||
|
@ -311,6 +311,11 @@ void ToggleTroll(int client, const char[] name, int flags = 0) {
|
|||
troll.activeFlagClients[client] = flags;
|
||||
}
|
||||
|
||||
void SetTrollFlags(int client, const char[] name, int flags = -1) {
|
||||
int index = GetTrollID(name);
|
||||
Trolls[index].activeFlagClients[client] = flags;
|
||||
}
|
||||
|
||||
void ApplyTroll(int victim, const char[] name, int activator, trollModifier modifier, int flags = 0, bool silent = false) {
|
||||
static Troll troll;
|
||||
int trollIndex = GetTroll(name, troll);
|
||||
|
@ -413,6 +418,7 @@ bool IsTrollActive(int client, const char[] troll) {
|
|||
}
|
||||
static int i = 0;
|
||||
if(trollKV.GetValue(troll, i)) {
|
||||
PrintToChatAll("index: %d. val: %d", i, Trolls[i].activeFlagClients[client] );
|
||||
return Trolls[i].activeFlagClients[client] != -1;
|
||||
}
|
||||
ThrowError("Troll \"%s\" does not exist", troll);
|
||||
|
@ -425,15 +431,11 @@ bool IsTrollActiveByRawID(int client, int id) {
|
|||
|
||||
|
||||
void EnableTroll(int client, const char[] troll, int flags = 0) {
|
||||
if(!IsTrollActive(client, troll)) {
|
||||
ToggleTroll(client, troll, flags);
|
||||
}
|
||||
SetTrollFlags(client, troll, flags);
|
||||
}
|
||||
|
||||
void DisableTroll(int client, const char[] troll) {
|
||||
if(IsTrollActive(client, troll)) {
|
||||
ToggleTroll(client, troll);
|
||||
}
|
||||
SetTrollFlags(client, troll, -1);
|
||||
}
|
||||
|
||||
public void SetCategory(const char[] newCat) {
|
||||
|
|
|
@ -32,53 +32,63 @@ public void OnClientPutInServer(int client) {
|
|||
SDKHook(client, SDKHook_OnTakeDamage, Event_TakeDamage);
|
||||
SDKHook(client, SDKHook_OnTakeDamageAlive, NerfGun_OnTakeDamage);
|
||||
}
|
||||
/* Projectile Magnet:
|
||||
1. Create watch timer on EntityCreateCallback
|
||||
2. Test velocity over time
|
||||
3. If velocity goes negative, its at apex:
|
||||
- TraceRay to victim
|
||||
- If collision && molotov (maybe acid/):
|
||||
Get End Position
|
||||
If Distance From End Position & Victim < 100 units or so
|
||||
Allow
|
||||
- If no collision, set angle to player, set velocity accordingly
|
||||
*/
|
||||
|
||||
#define CAR_MODEL_COUNT 4
|
||||
static char CAR_MODELS[CAR_MODEL_COUNT][] = {
|
||||
"props_vehicles\\car001a_phy.mdl",
|
||||
"props_vehicles\\car001b_phy.mdl",
|
||||
"props_vehicles\\car002a_physics.mdl",
|
||||
"props_vehicles\\car002b_physics.mdl"
|
||||
};
|
||||
|
||||
public void OnEntityCreated(int entity, const char[] classname) {
|
||||
if(entity >= MaxClients) {
|
||||
if(StrEqual(classname, "infected", false))
|
||||
SDKHook(entity, SDKHook_OnTakeDamageAlive, NerfGun_OnTakeDamage);
|
||||
else if(StrContains(classname, "_projectile", true) > -1 ) {
|
||||
else if(StrEqual(classname, "prop_physics")) {
|
||||
char model[64];
|
||||
GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model));
|
||||
for(int i = 0; i < CAR_MODEL_COUNT; i++) {
|
||||
if(StrEqual(CAR_MODELS[i], model)) {
|
||||
HookSingleEntityOutput(entity, "OnHitByTank", OnCarHitByTank);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(StrEqual(classname, "prop_car_alarm")) {
|
||||
HookSingleEntityOutput(entity, "OnHitByTank", OnCarHitByTank);
|
||||
} else if(StrEqual(classname, "tank_rock") || StrContains(classname, "_projectile", true) > -1 ) {
|
||||
RequestFrame(EntityCreateCallback, entity);
|
||||
} /*else if(g_iRockThrows > 0 && StrEqual(classname, "tank_rock")) {
|
||||
--g_iRockThrows;
|
||||
SDKHook(entity, SDKHook_SpawnPost, SpawnPost);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnCarHitByTank(const char[] output, int caller, int activator, float delay) {
|
||||
entLastHeight[activator] = -10000.0;
|
||||
CreateTimer(0.1, Timer_WaitForApex, EntIndexToEntRef(activator), TIMER_REPEAT);
|
||||
}
|
||||
|
||||
/*void SpawnPost(int entity) {
|
||||
RequestFrame(SetRockVelocity, EntIndexToEntRef(entity))
|
||||
}
|
||||
|
||||
void SetRockVelocity(int entity) {
|
||||
entity = EntRefToEntIndex(entity);
|
||||
entity = EntRefToEntIndex(entity);
|
||||
|
||||
if(!IsValidEntity(entity)) return;
|
||||
if(!IsValidEntity(entity)) return;
|
||||
|
||||
float vel[3];
|
||||
|
||||
GetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
||||
GetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
||||
|
||||
ScaleVector(vel, 0.4);
|
||||
|
||||
// z_tank_throw_force
|
||||
//SetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
||||
vel[2] += 150.0;
|
||||
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vel);
|
||||
// z_tank_throw_force
|
||||
//SetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
||||
vel[2] += 150.0;
|
||||
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vel);
|
||||
PrintToChatAll("set rock %d vel", entity);
|
||||
|
||||
}*/
|
||||
|
||||
void EntityCreateCallback(int entity) {
|
||||
if(!HasEntProp(entity, Prop_Send, "m_hOwnerEntity") || !IsValidEntity(entity)) return;
|
||||
static char class[16];
|
||||
|
@ -121,14 +131,26 @@ void EntityCreateCallback(int entity) {
|
|||
}
|
||||
SpawnItem("pipe_bomb", pos);
|
||||
}
|
||||
return;
|
||||
} else if(Trolls[slipperyShoesIndex].IsActive(entOwner)) {
|
||||
if(Trolls[slipperyShoesIndex].activeFlagClients[entOwner] & 4) {
|
||||
L4D_StaggerPlayer(entOwner, entOwner, NULL_VECTOR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
entLastHeight[entity] = -10000.0;
|
||||
CreateTimer(0.1, Timer_WaitForApex, EntIndexToEntRef(entity), TIMER_REPEAT);
|
||||
}
|
||||
|
||||
enum ProjectileMagnetType {
|
||||
ProjType_Specials = 1,
|
||||
ProjType_Survivors = 2,
|
||||
ProjType_Cars = 4,
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||
int userid = event.GetInt("userid");
|
||||
if(spIsActive)
|
||||
|
@ -666,7 +688,7 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
|||
LookAtClient(client, pdata[client].shootAtTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inverted control code:
|
||||
if(Trolls[invertedTrollIndex].IsActive(client)) {
|
||||
|
@ -732,10 +754,10 @@ public Action Event_TakeDamage(int victim, int& attacker, int& inflictor, float&
|
|||
} else if(Trolls[reverseFF].IsActive(attacker) && damagetype != DMG_BURN && attacker != victim && GetClientTeam(attacker) == GetClientTeam(victim)) {
|
||||
|
||||
float returnDmg = damage; //default is 1:1
|
||||
if(Trolls[reverseFF].activeFlagClients[attacker] & 4) {
|
||||
returnDmg /= 2.0;
|
||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 2) {
|
||||
if(Trolls[reverseFF].activeFlagClients[attacker] & 2) {
|
||||
returnDmg *= 2.0;
|
||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 4) {
|
||||
returnDmg /= 2.0;
|
||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 8) {
|
||||
returnDmg = 0.0;
|
||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 16) {
|
||||
|
@ -916,8 +938,8 @@ stock int FindClosestVisibleClient(int source) {
|
|||
static float pos[3], ang[3];
|
||||
GetClientEyePosition(source, pos);
|
||||
GetClientEyeAngles(source, ang);
|
||||
Handle handle = TR_TraceRayFilterEx(pos, ang, MASK_VISIBLE, RayType_Infinite, TraceEntityFilterPlayer, source);
|
||||
return TR_GetEntityIndex(handle);
|
||||
TR_TraceRayFilter(pos, ang, MASK_VISIBLE, RayType_Infinite, TraceEntityFilterPlayer, source);
|
||||
return TR_GetEntityIndex();
|
||||
}
|
||||
|
||||
public bool TraceEntityFilterPlayer(int entity, int mask, any data) {
|
||||
|
|
|
@ -465,7 +465,7 @@ void ClearInventory(int client) {
|
|||
}
|
||||
}
|
||||
|
||||
void StopHealingBots() {
|
||||
void StopHealingBots(bool dontKill = false) {
|
||||
healTargetPlayer = 0;
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
pdata[i].flags &= ~view_as<int>(Flag_IsTargettingHealer);
|
||||
|
@ -474,57 +474,14 @@ void StopHealingBots() {
|
|||
KickClient(i);
|
||||
}
|
||||
}
|
||||
if(!dontKill && IsValidHandle(stopHealingTimer)) {
|
||||
delete stopHealingTimer;
|
||||
}
|
||||
stopHealingTimer = null;
|
||||
if(hAbmAutoHard != null) hAbmAutoHard.IntValue = wasAbmAutoHard;
|
||||
if(hSbFixEnabled != null) hSbFixEnabled.BoolValue = wasSbFixEnabled;
|
||||
}
|
||||
|
||||
// Spawns a env_rock_launcher to throw at a random specified target name.
|
||||
// Does not auto fire, need to call input LaunchRock
|
||||
// Damage -1 will not override damage
|
||||
// autoDeleteTime of <= 0.0 will persist forever.
|
||||
stock int CreateRockLauncher(const float origin[3], const float ang[3], const char[] targetName, float damage = -1.0, float autoDeleteTime = 0.0) {
|
||||
int launcher = CreateEntityByName("env_rock_launcher");
|
||||
if(launcher == -1) return -1;
|
||||
// DispatchKeyValue(launcher, "targetname", "ftt_rock_launcher");
|
||||
DispatchKeyValue(launcher, "RockTargetName", targetName);
|
||||
if(damage >= 0.0) {
|
||||
DispatchKeyValueFloat(launcher, "RockDamageOverride", damage);
|
||||
}
|
||||
if(autoDeleteTime > 0.0) CreateTimer(autoDeleteTime, Timer_Delete, launcher);
|
||||
DispatchSpawn(launcher);
|
||||
TeleportEntity(launcher, origin, ang, NULL_VECTOR);
|
||||
PrintToChatAll("Created rock launcher at %f %f %f at ang %f %f %f", origin[0], origin[1], origin[2], ang[0], ang[1], ang[2]);
|
||||
// AcceptEntityInput(launcher, "Kill");
|
||||
return launcher;
|
||||
}
|
||||
|
||||
#define FTT_TARGET_NAME "ftt_target"
|
||||
stock bool ThrowRockAtPosition(const float origin[3], float pos[3], float damage = -1.0) {
|
||||
CreateTarget(pos, FTT_TARGET_NAME, 0.2);
|
||||
GetVectorAngles(pos, pos);
|
||||
int launcher = CreateRockLauncher(origin, pos, FTT_TARGET_NAME, damage, 0.0);
|
||||
g_iRockThrows++;
|
||||
AcceptEntityInput(launcher, "LaunchRock");
|
||||
AcceptEntityInput(launcher, "Kill");
|
||||
return true;
|
||||
}
|
||||
stock bool ThrowRockAtEntity(const float origin[3], int target, float damage = -1.0) {
|
||||
float pos[3];
|
||||
GetEntPropVector(target, Prop_Send, "m_vecOrigin", pos);
|
||||
return ThrowRockAtPosition(origin, pos, damage);
|
||||
}
|
||||
|
||||
int CreateTarget(const float origin[3], const char[] targetName, float duration = 0.0) {
|
||||
int target = CreateEntityByName("info_target");
|
||||
DispatchKeyValue(target, "targetname", targetName);
|
||||
|
||||
TeleportEntity(target, origin, NULL_VECTOR, NULL_VECTOR);
|
||||
DispatchSpawn(target);
|
||||
if(duration > 0.0) {
|
||||
CreateTimer(duration, Timer_Delete, target);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
bool IsAnySurvivorInRange(const float origin[3], float range, int ignorePlayer = 0) {
|
||||
float pos[3];
|
||||
|
@ -538,4 +495,51 @@ bool IsAnySurvivorInRange(const float origin[3], float range, int ignorePlayer =
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetRandomThrowableMagnetTarget(ProjectileMagnetType type, int owner = -1) {
|
||||
static int throwMagnetIndex;
|
||||
if(throwMagnetIndex == 0) throwMagnetIndex = GetTrollID("Projectile Magnet");
|
||||
ArrayList checkList = new ArrayList();
|
||||
for(int i = 1; i <= MaxClients; i++) {
|
||||
if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && Trolls[throwMagnetIndex].IsActive(i)) {
|
||||
if(type == ProjType_Survivors && owner != i) {
|
||||
// If the projectile is not owned by player, check if troll flag not enabled
|
||||
if(~Trolls[throwMagnetIndex].activeFlagClients[i] & view_as<int>(ProjType_Survivors)) continue;
|
||||
} else if(~Trolls[throwMagnetIndex].activeFlagClients[i] & view_as<int>(type)) {
|
||||
// Skip if client does not have flag
|
||||
continue;
|
||||
}
|
||||
checkList.Push(i);
|
||||
}
|
||||
}
|
||||
int target = -1;
|
||||
if(checkList.Length > 0) {
|
||||
target = checkList.Get(0, checkList.Length - 1);
|
||||
}
|
||||
delete checkList;
|
||||
return target;
|
||||
}
|
||||
|
||||
stock bool CanSeePoint(const float origin[3], const float point[3]) {
|
||||
TR_TraceRay(origin, point, MASK_ALL, RayType_EndPoint);
|
||||
|
||||
return !TR_DidHit(); // Can see point if no collisions
|
||||
}
|
||||
|
||||
stock LookAtPoint(int entity, const float destination[3]){
|
||||
float angles[3], pos[3], result[3];
|
||||
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos);
|
||||
MakeVectorFromPoints(destination, pos, result);
|
||||
GetVectorAngles(result, angles);
|
||||
if(angles[0] >= 270){
|
||||
angles[0] -= 270;
|
||||
angles[0] = (90-angles[0]);
|
||||
}else{
|
||||
if(angles[0] <= 90){
|
||||
angles[0] *= -1;
|
||||
}
|
||||
}
|
||||
angles[1] -= 180;
|
||||
TeleportEntity(entity, NULL_VECTOR, angles, NULL_VECTOR);
|
||||
}
|
|
@ -223,6 +223,7 @@ public Action Timer_CheckForChargerOpportunity(Handle h, int userid) {
|
|||
if(activator) PrintToChat(activator, "Auto charge timed out after %d attempts", pdata[client].smartChargeAttempts);
|
||||
pdata[client].smartChargeAttempts = 0;
|
||||
pdata[client].smartChargeActivator = 0;
|
||||
DisableTroll(client, "Smart Charge");
|
||||
return Plugin_Stop;
|
||||
}
|
||||
return Plugin_Continue;
|
||||
|
@ -237,7 +238,7 @@ public bool Filter_CheckChargerValid(int entity, int contentsMask, any data) {
|
|||
public Action Timer_UpdateHealTargetPos(Handle h) {
|
||||
int healTarget = GetClientOfUserId(healTargetPlayer);
|
||||
if(healTarget == 0) {
|
||||
PrintToServer("[FTT] Lost heal target, stopping");
|
||||
PrintToServer("[FTT] Dep Bots: Lost heal target, stopping");
|
||||
return Plugin_Stop;
|
||||
}
|
||||
GetAbsOrigin(healTarget, healTargetPos);
|
||||
|
@ -290,7 +291,77 @@ Action Timer_SpawnHealBotsPost(Handle h) {
|
|||
}
|
||||
return Plugin_Handled;
|
||||
}
|
||||
Action Timer_StopHealBots(Handle h) {
|
||||
StopHealingBots();
|
||||
Action Timer_StopHealBots(Handle h, DataPack pack) {
|
||||
pack.Reset();
|
||||
int activator = GetClientOfUserId(pack.ReadCell());
|
||||
int victim = GetClientOfUserId(pack.ReadCell());
|
||||
if(activator) {
|
||||
PrintToChat(activator, "Dep bots has expired");
|
||||
}
|
||||
if(victim) {
|
||||
DisableTroll(victim, "Dep Bots");
|
||||
}
|
||||
// TODO: stop right one
|
||||
StopHealingBots(true);
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
|
||||
#define NO_ATTEMPT_MAX_DIST 1000.0
|
||||
#define NO_ATTEMPT_MAX_DIST_OPT NO_ATTEMPT_MAX_DIST * NO_ATTEMPT_MAX_DIST
|
||||
|
||||
|
||||
Action Timer_WaitForApex(Handle h, int entref) {
|
||||
if(!IsValidEntity(entref)) return Plugin_Stop;
|
||||
int entity = EntRefToEntIndex(entref);
|
||||
|
||||
static float pos[3];
|
||||
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos);
|
||||
|
||||
if(entLastHeight[entity] > pos[2]) {
|
||||
char classname[32];
|
||||
GetEntityClassname(entity, classname, sizeof(classname));
|
||||
|
||||
int target;
|
||||
if(StrEqual(classname, "tank_rock") || StrEqual(classname, "spitter_projectile"))
|
||||
target = GetRandomThrowableMagnetTarget(ProjType_Specials);
|
||||
else if(StrEqual(classname, "prop_physics") || StrEqual(classname, "prop_car_alarm"))
|
||||
target = GetRandomThrowableMagnetTarget(ProjType_Cars)
|
||||
else {
|
||||
int entOwner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
|
||||
target = GetRandomThrowableMagnetTarget(ProjType_Survivors, entOwner);
|
||||
}
|
||||
|
||||
if(target > 0) {
|
||||
float targetPos[3], vel[3];
|
||||
GetClientAbsOrigin(target, targetPos);
|
||||
TR_TraceRay(pos, targetPos, MASK_SHOT, RayType_EndPoint);
|
||||
if(TR_DidHit()) {
|
||||
TR_GetEndPosition(pos);
|
||||
if(GetVectorDistance(pos, targetPos, true) > NO_ATTEMPT_MAX_DIST_OPT) {
|
||||
return Plugin_Stop;
|
||||
}
|
||||
}
|
||||
|
||||
// SetEntityMoveType(entity, MOVETYPE_FLY);
|
||||
SetEntityGravity(entity, 0.001);
|
||||
float distance = GetVectorDistance(pos, targetPos);
|
||||
SubtractVectors(targetPos, pos, vel);
|
||||
ScaleVector(vel, 1000.0 / distance);
|
||||
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vel);
|
||||
|
||||
CreateTimer(3.0, Timer_ResetGravity, entref);
|
||||
}
|
||||
return Plugin_Stop;
|
||||
}
|
||||
entLastHeight[entity] = pos[2];
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
Action Timer_ResetGravity(Handle h, int entref) {
|
||||
if(IsValidEntity(entref)) {
|
||||
int entity = EntRefToEntIndex(entref);
|
||||
SetEntityGravity(entity, 800.0);
|
||||
}
|
||||
return Plugin_Handled;
|
||||
}
|
|
@ -21,6 +21,12 @@ void SetupTrolls() {
|
|||
#if defined _behavior_included
|
||||
index = SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant);
|
||||
#endif
|
||||
index = SetupTroll("Projectile Magnet", "Makes all projectiles (biles, molotovs, pipes, tank rocks) go to player", TrollMod_Constant);
|
||||
Trolls[index].AddCustomFlagPrompt("Target Sources", true);
|
||||
// Tied to: ProjectileMagnetType
|
||||
Trolls[index].AddFlag("Infected (rocks/goo)", true);
|
||||
Trolls[index].AddFlag("Teammates (grenades)", false);
|
||||
Trolls[index].AddFlag("Thrown Cars (wip)", false);
|
||||
|
||||
/// CATEGORY: Infected
|
||||
SetCategory("Infected");
|
||||
|
@ -138,7 +144,6 @@ void SetupTrolls() {
|
|||
Trolls[index].AddFlag("0.5x Ratio", false); //4
|
||||
Trolls[index].AddFlag("0.0x Ratio (None)", false); //8
|
||||
Trolls[index].AddFlag("3x Ratio", false); //16
|
||||
Trolls[index].AddFlag("-2x Ratio", false); //16
|
||||
index = SetupTroll("Dep Bots", "Makes bots heal a player. At any cost", TrollMod_Constant);
|
||||
Trolls[index].AddFlagPrompt(false);
|
||||
Trolls[index].AddFlag("Do not spawn extra", true); // 1
|
||||
|
@ -361,6 +366,11 @@ bool ApplyAffect(int victim, const Troll troll, int activator, trollModifier mod
|
|||
if(!toActive) {
|
||||
StopHealingBots();
|
||||
return true;
|
||||
} else if(healTargetPlayer != 0) {
|
||||
if(IsValidHandle(stopHealingTimer)) {
|
||||
TriggerTimer(stopHealingTimer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool spawnExtra = flags & 2 > 0;
|
||||
|
||||
|
@ -398,7 +408,10 @@ bool ApplyAffect(int victim, const Troll troll, int activator, trollModifier mod
|
|||
}
|
||||
CreateTimer(2.0, Timer_UpdateHealTargetPos, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||
if(timeout > 0.0) {
|
||||
CreateTimer(timeout, Timer_StopHealBots);
|
||||
DataPack pack;
|
||||
stopHealingTimer = CreateDataTimer(timeout, Timer_StopHealBots, pack);
|
||||
pack.WriteCell(GetClientUserId(activator));
|
||||
pack.WriteCell(GetClientUserId(victim))
|
||||
}
|
||||
|
||||
if(spawnExtra && numBots > 0) {
|
||||
|
|
|
@ -88,8 +88,10 @@ enum SpecialInternalFlags {
|
|||
|
||||
int healTargetPlayer;
|
||||
float healTargetPos[3];
|
||||
Handle stopHealingTimer;
|
||||
|
||||
float entLastHeight[2048];
|
||||
|
||||
int g_iRockThrows;
|
||||
|
||||
#define MODEL_CAR "models/props_vehicles/cara_95sedan.mdl"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue