mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 05:13:21 +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
|
//Allow MAX_TROLLS to be defined elsewhere
|
||||||
#if defined MAX_TROLLS
|
#if defined MAX_TROLLS
|
||||||
#else
|
#else
|
||||||
#define MAX_TROLLS 45
|
#define MAX_TROLLS 46
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum trollModifier {
|
enum trollModifier {
|
||||||
|
@ -278,7 +278,7 @@ int GetTroll(const char[] name, Troll troll) {
|
||||||
troll = Trolls[i];
|
troll = Trolls[i];
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
PrintToServer("GetTroll: Troll was not found \"%s\"", name);
|
ThrowError("GetTroll: Troll was not found \"%s\"", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int GetTrollID(const char[] name) {
|
int GetTrollID(const char[] name) {
|
||||||
|
@ -311,6 +311,11 @@ void ToggleTroll(int client, const char[] name, int flags = 0) {
|
||||||
troll.activeFlagClients[client] = flags;
|
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) {
|
void ApplyTroll(int victim, const char[] name, int activator, trollModifier modifier, int flags = 0, bool silent = false) {
|
||||||
static Troll troll;
|
static Troll troll;
|
||||||
int trollIndex = GetTroll(name, troll);
|
int trollIndex = GetTroll(name, troll);
|
||||||
|
@ -413,6 +418,7 @@ bool IsTrollActive(int client, const char[] troll) {
|
||||||
}
|
}
|
||||||
static int i = 0;
|
static int i = 0;
|
||||||
if(trollKV.GetValue(troll, i)) {
|
if(trollKV.GetValue(troll, i)) {
|
||||||
|
PrintToChatAll("index: %d. val: %d", i, Trolls[i].activeFlagClients[client] );
|
||||||
return Trolls[i].activeFlagClients[client] != -1;
|
return Trolls[i].activeFlagClients[client] != -1;
|
||||||
}
|
}
|
||||||
ThrowError("Troll \"%s\" does not exist", troll);
|
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) {
|
void EnableTroll(int client, const char[] troll, int flags = 0) {
|
||||||
if(!IsTrollActive(client, troll)) {
|
SetTrollFlags(client, troll, flags);
|
||||||
ToggleTroll(client, troll, flags);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisableTroll(int client, const char[] troll) {
|
void DisableTroll(int client, const char[] troll) {
|
||||||
if(IsTrollActive(client, troll)) {
|
SetTrollFlags(client, troll, -1);
|
||||||
ToggleTroll(client, troll);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetCategory(const char[] newCat) {
|
public void SetCategory(const char[] newCat) {
|
||||||
|
|
|
@ -32,53 +32,63 @@ public void OnClientPutInServer(int client) {
|
||||||
SDKHook(client, SDKHook_OnTakeDamage, Event_TakeDamage);
|
SDKHook(client, SDKHook_OnTakeDamage, Event_TakeDamage);
|
||||||
SDKHook(client, SDKHook_OnTakeDamageAlive, NerfGun_OnTakeDamage);
|
SDKHook(client, SDKHook_OnTakeDamageAlive, NerfGun_OnTakeDamage);
|
||||||
}
|
}
|
||||||
/* Projectile Magnet:
|
|
||||||
1. Create watch timer on EntityCreateCallback
|
#define CAR_MODEL_COUNT 4
|
||||||
2. Test velocity over time
|
static char CAR_MODELS[CAR_MODEL_COUNT][] = {
|
||||||
3. If velocity goes negative, its at apex:
|
"props_vehicles\\car001a_phy.mdl",
|
||||||
- TraceRay to victim
|
"props_vehicles\\car001b_phy.mdl",
|
||||||
- If collision && molotov (maybe acid/):
|
"props_vehicles\\car002a_physics.mdl",
|
||||||
Get End Position
|
"props_vehicles\\car002b_physics.mdl"
|
||||||
If Distance From End Position & Victim < 100 units or so
|
};
|
||||||
Allow
|
|
||||||
- If no collision, set angle to player, set velocity accordingly
|
|
||||||
*/
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname) {
|
public void OnEntityCreated(int entity, const char[] classname) {
|
||||||
if(entity >= MaxClients) {
|
if(entity >= MaxClients) {
|
||||||
if(StrEqual(classname, "infected", false))
|
if(StrEqual(classname, "infected", false))
|
||||||
SDKHook(entity, SDKHook_OnTakeDamageAlive, NerfGun_OnTakeDamage);
|
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);
|
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) {
|
/*void SpawnPost(int entity) {
|
||||||
RequestFrame(SetRockVelocity, EntIndexToEntRef(entity))
|
RequestFrame(SetRockVelocity, EntIndexToEntRef(entity))
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRockVelocity(int entity) {
|
void SetRockVelocity(int entity) {
|
||||||
entity = EntRefToEntIndex(entity);
|
entity = EntRefToEntIndex(entity);
|
||||||
|
|
||||||
if(!IsValidEntity(entity)) return;
|
if(!IsValidEntity(entity)) return;
|
||||||
|
|
||||||
float vel[3];
|
float vel[3];
|
||||||
|
|
||||||
GetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
GetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
||||||
|
|
||||||
ScaleVector(vel, 0.4);
|
ScaleVector(vel, 0.4);
|
||||||
|
|
||||||
// z_tank_throw_force
|
// z_tank_throw_force
|
||||||
//SetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
//SetEntPropVector(entity, Prop_Send, "m_vecVelocity", vel);
|
||||||
vel[2] += 150.0;
|
vel[2] += 150.0;
|
||||||
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vel);
|
TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, vel);
|
||||||
PrintToChatAll("set rock %d vel", entity);
|
PrintToChatAll("set rock %d vel", entity);
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
void EntityCreateCallback(int entity) {
|
void EntityCreateCallback(int entity) {
|
||||||
if(!HasEntProp(entity, Prop_Send, "m_hOwnerEntity") || !IsValidEntity(entity)) return;
|
if(!HasEntProp(entity, Prop_Send, "m_hOwnerEntity") || !IsValidEntity(entity)) return;
|
||||||
static char class[16];
|
static char class[16];
|
||||||
|
@ -121,14 +131,26 @@ void EntityCreateCallback(int entity) {
|
||||||
}
|
}
|
||||||
SpawnItem("pipe_bomb", pos);
|
SpawnItem("pipe_bomb", pos);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
} else if(Trolls[slipperyShoesIndex].IsActive(entOwner)) {
|
} else if(Trolls[slipperyShoesIndex].IsActive(entOwner)) {
|
||||||
if(Trolls[slipperyShoesIndex].activeFlagClients[entOwner] & 4) {
|
if(Trolls[slipperyShoesIndex].activeFlagClients[entOwner] & 4) {
|
||||||
L4D_StaggerPlayer(entOwner, entOwner, NULL_VECTOR);
|
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) {
|
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast) {
|
||||||
int userid = event.GetInt("userid");
|
int userid = event.GetInt("userid");
|
||||||
if(spIsActive)
|
if(spIsActive)
|
||||||
|
@ -666,7 +688,7 @@ public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3
|
||||||
LookAtClient(client, pdata[client].shootAtTarget);
|
LookAtClient(client, pdata[client].shootAtTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inverted control code:
|
// Inverted control code:
|
||||||
if(Trolls[invertedTrollIndex].IsActive(client)) {
|
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)) {
|
} else if(Trolls[reverseFF].IsActive(attacker) && damagetype != DMG_BURN && attacker != victim && GetClientTeam(attacker) == GetClientTeam(victim)) {
|
||||||
|
|
||||||
float returnDmg = damage; //default is 1:1
|
float returnDmg = damage; //default is 1:1
|
||||||
if(Trolls[reverseFF].activeFlagClients[attacker] & 4) {
|
if(Trolls[reverseFF].activeFlagClients[attacker] & 2) {
|
||||||
returnDmg /= 2.0;
|
|
||||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 2) {
|
|
||||||
returnDmg *= 2.0;
|
returnDmg *= 2.0;
|
||||||
|
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 4) {
|
||||||
|
returnDmg /= 2.0;
|
||||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 8) {
|
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 8) {
|
||||||
returnDmg = 0.0;
|
returnDmg = 0.0;
|
||||||
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 16) {
|
} else if(Trolls[reverseFF].activeFlagClients[attacker] & 16) {
|
||||||
|
@ -916,8 +938,8 @@ stock int FindClosestVisibleClient(int source) {
|
||||||
static float pos[3], ang[3];
|
static float pos[3], ang[3];
|
||||||
GetClientEyePosition(source, pos);
|
GetClientEyePosition(source, pos);
|
||||||
GetClientEyeAngles(source, ang);
|
GetClientEyeAngles(source, ang);
|
||||||
Handle handle = TR_TraceRayFilterEx(pos, ang, MASK_VISIBLE, RayType_Infinite, TraceEntityFilterPlayer, source);
|
TR_TraceRayFilter(pos, ang, MASK_VISIBLE, RayType_Infinite, TraceEntityFilterPlayer, source);
|
||||||
return TR_GetEntityIndex(handle);
|
return TR_GetEntityIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TraceEntityFilterPlayer(int entity, int mask, any data) {
|
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;
|
healTargetPlayer = 0;
|
||||||
for(int i = 1; i <= MaxClients; i++) {
|
for(int i = 1; i <= MaxClients; i++) {
|
||||||
pdata[i].flags &= ~view_as<int>(Flag_IsTargettingHealer);
|
pdata[i].flags &= ~view_as<int>(Flag_IsTargettingHealer);
|
||||||
|
@ -474,57 +474,14 @@ void StopHealingBots() {
|
||||||
KickClient(i);
|
KickClient(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!dontKill && IsValidHandle(stopHealingTimer)) {
|
||||||
|
delete stopHealingTimer;
|
||||||
|
}
|
||||||
|
stopHealingTimer = null;
|
||||||
if(hAbmAutoHard != null) hAbmAutoHard.IntValue = wasAbmAutoHard;
|
if(hAbmAutoHard != null) hAbmAutoHard.IntValue = wasAbmAutoHard;
|
||||||
if(hSbFixEnabled != null) hSbFixEnabled.BoolValue = wasSbFixEnabled;
|
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) {
|
bool IsAnySurvivorInRange(const float origin[3], float range, int ignorePlayer = 0) {
|
||||||
float pos[3];
|
float pos[3];
|
||||||
|
@ -538,4 +495,51 @@ bool IsAnySurvivorInRange(const float origin[3], float range, int ignorePlayer =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
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);
|
if(activator) PrintToChat(activator, "Auto charge timed out after %d attempts", pdata[client].smartChargeAttempts);
|
||||||
pdata[client].smartChargeAttempts = 0;
|
pdata[client].smartChargeAttempts = 0;
|
||||||
pdata[client].smartChargeActivator = 0;
|
pdata[client].smartChargeActivator = 0;
|
||||||
|
DisableTroll(client, "Smart Charge");
|
||||||
return Plugin_Stop;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
|
@ -237,7 +238,7 @@ public bool Filter_CheckChargerValid(int entity, int contentsMask, any data) {
|
||||||
public Action Timer_UpdateHealTargetPos(Handle h) {
|
public Action Timer_UpdateHealTargetPos(Handle h) {
|
||||||
int healTarget = GetClientOfUserId(healTargetPlayer);
|
int healTarget = GetClientOfUserId(healTargetPlayer);
|
||||||
if(healTarget == 0) {
|
if(healTarget == 0) {
|
||||||
PrintToServer("[FTT] Lost heal target, stopping");
|
PrintToServer("[FTT] Dep Bots: Lost heal target, stopping");
|
||||||
return Plugin_Stop;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
GetAbsOrigin(healTarget, healTargetPos);
|
GetAbsOrigin(healTarget, healTargetPos);
|
||||||
|
@ -290,7 +291,77 @@ Action Timer_SpawnHealBotsPost(Handle h) {
|
||||||
}
|
}
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
Action Timer_StopHealBots(Handle h) {
|
Action Timer_StopHealBots(Handle h, DataPack pack) {
|
||||||
StopHealingBots();
|
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;
|
return Plugin_Handled;
|
||||||
}
|
}
|
|
@ -21,6 +21,12 @@ void SetupTrolls() {
|
||||||
#if defined _behavior_included
|
#if defined _behavior_included
|
||||||
index = SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant);
|
index = SetupTroll("Witch Magnet", "All witches when startled will target any player with this troll", TrollMod_Constant);
|
||||||
#endif
|
#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
|
/// CATEGORY: Infected
|
||||||
SetCategory("Infected");
|
SetCategory("Infected");
|
||||||
|
@ -138,7 +144,6 @@ void SetupTrolls() {
|
||||||
Trolls[index].AddFlag("0.5x Ratio", false); //4
|
Trolls[index].AddFlag("0.5x Ratio", false); //4
|
||||||
Trolls[index].AddFlag("0.0x Ratio (None)", false); //8
|
Trolls[index].AddFlag("0.0x Ratio (None)", false); //8
|
||||||
Trolls[index].AddFlag("3x Ratio", false); //16
|
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);
|
index = SetupTroll("Dep Bots", "Makes bots heal a player. At any cost", TrollMod_Constant);
|
||||||
Trolls[index].AddFlagPrompt(false);
|
Trolls[index].AddFlagPrompt(false);
|
||||||
Trolls[index].AddFlag("Do not spawn extra", true); // 1
|
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) {
|
if(!toActive) {
|
||||||
StopHealingBots();
|
StopHealingBots();
|
||||||
return true;
|
return true;
|
||||||
|
} else if(healTargetPlayer != 0) {
|
||||||
|
if(IsValidHandle(stopHealingTimer)) {
|
||||||
|
TriggerTimer(stopHealingTimer);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
bool spawnExtra = flags & 2 > 0;
|
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);
|
CreateTimer(2.0, Timer_UpdateHealTargetPos, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
||||||
if(timeout > 0.0) {
|
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) {
|
if(spawnExtra && numBots > 0) {
|
||||||
|
|
|
@ -88,8 +88,10 @@ enum SpecialInternalFlags {
|
||||||
|
|
||||||
int healTargetPlayer;
|
int healTargetPlayer;
|
||||||
float healTargetPos[3];
|
float healTargetPos[3];
|
||||||
|
Handle stopHealingTimer;
|
||||||
|
|
||||||
|
float entLastHeight[2048];
|
||||||
|
|
||||||
int g_iRockThrows;
|
|
||||||
|
|
||||||
#define MODEL_CAR "models/props_vehicles/cara_95sedan.mdl"
|
#define MODEL_CAR "models/props_vehicles/cara_95sedan.mdl"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue