Initial commit
This commit is contained in:
429
scripting/towerdefense/handler/aoe.sp
Normal file
429
scripting/towerdefense/handler/aoe.sp
Normal file
@@ -0,0 +1,429 @@
|
||||
/**
|
||||
* Checks for clients near AoE Towers
|
||||
*
|
||||
* @param hTimer Timer Handle
|
||||
* @param iTower The tower
|
||||
* @noreturn
|
||||
*/
|
||||
public Action Timer_ClientNearAoETower(Handle hTimer) {
|
||||
for (int iClient = 1; iClient <= MaxClients; iClient++) {
|
||||
if (IsClientInGame(iClient) && IsPlayerAlive(iClient)) {
|
||||
if (IsTower(iClient)) {
|
||||
int iTower = iClient;
|
||||
TDTowerId iTowerId = GetTowerId(iTower);
|
||||
|
||||
if (iTowerId == TDTower_AoE_Engineer) {
|
||||
float fAreaScale = 80.0 * Tower_GetAreaScale(GetTowerId(iTower));
|
||||
CreateBeamBoxAroundClient(iTower, fAreaScale, true, 0.2, { 231, 76, 60, 25 });
|
||||
Tower_ObjectNearAoEEngineer(iTower, iClient);
|
||||
}
|
||||
if (iTowerId == TDTower_Medic) {
|
||||
float fAreaScale = 160.0 * Tower_GetAreaScale(GetTowerId(iTower));
|
||||
CreateBeamBoxAroundClient(iTower, fAreaScale, true, 0.2, { 46, 204, 113, 25 });
|
||||
Tower_ObjectNearAoEMedic(iTower);
|
||||
}
|
||||
if (iTowerId == TDTower_Kritz_Medic) {
|
||||
float fAreaScale = 60.0 * Tower_GetAreaScale(GetTowerId(iTower));
|
||||
CreateBeamBoxAroundClient(iTower, fAreaScale, true, 0.2, { 41, 128, 185, 25 });
|
||||
Tower_ObjectNearKritzMedic(iTower);
|
||||
}
|
||||
if (iTowerId == TDTower_Slow_Spy) {
|
||||
float fAreaScale = 100.0 * Tower_GetAreaScale(GetTowerId(iTower));
|
||||
CreateBeamBoxAroundClient(iTower, fAreaScale, false, 0.2, { 44, 62, 80, 25 });
|
||||
Tower_ObjectNearAoESpy(iTower);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Player is close to AoEMedic
|
||||
*
|
||||
* @param iTower The tower
|
||||
* @param iClient The player
|
||||
* @noreturn
|
||||
*/
|
||||
public void Tower_ObjectNearAoEMedic(int iTower) {
|
||||
for (int iClient = 1; iClient <= MaxClients; iClient++) {
|
||||
if (IsDefender(iClient) && IsClientInZone(iClient, g_fBeamPoints[iTower])) {
|
||||
Player_AddHealth(iClient, 5);
|
||||
|
||||
// Check if there is no Beam
|
||||
if (g_iHealBeamIndex[iClient][0] == 0 && g_iHealBeamIndex[iClient][1] == 0) {
|
||||
AttachHealBeam(iTower, iClient);
|
||||
}
|
||||
|
||||
} else {
|
||||
Tower_ObjectNotNearAoEMedic(iClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Player isn't close to AoEMedic
|
||||
*
|
||||
* @param iTower The tower
|
||||
* @param iClient The player
|
||||
* @noreturn
|
||||
*/
|
||||
public void Tower_ObjectNotNearAoEMedic(int iClient) {
|
||||
// Remove Beam if there is one
|
||||
if (g_iHealBeamIndex[iClient][0] != 0) {
|
||||
if (IsValidEdict(g_iHealBeamIndex[iClient][0])) {
|
||||
RemoveEdict(g_iHealBeamIndex[iClient][0]);
|
||||
g_iHealBeamIndex[iClient][0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_iHealBeamIndex[iClient][1] != 0) {
|
||||
if (IsValidEdict(g_iHealBeamIndex[iClient][1])) {
|
||||
RemoveEdict(g_iHealBeamIndex[iClient][1]);
|
||||
g_iHealBeamIndex[iClient][1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Player is close to AoEEngineer
|
||||
*
|
||||
* @param iTower The tower
|
||||
* @param iClient The player
|
||||
* @noreturn
|
||||
*/
|
||||
public void Tower_ObjectNearAoEEngineer(int iTower, int iClient) {
|
||||
if (iAoEEngineerTimer < 3 && !IsTowerAttached(iTower)) {
|
||||
iAoEEngineerTimer++;
|
||||
return;
|
||||
} else if (!IsTowerAttached(iTower)) {
|
||||
iAoEEngineerTimer = 0;
|
||||
}
|
||||
int iSentry = -1, iDispenser = -1;
|
||||
float fLocation[3];
|
||||
|
||||
// Sentries
|
||||
while ((iSentry = FindEntityByClassname(iSentry, "obj_sentrygun")) != -1) {
|
||||
if (!IsValidEntity(iSentry)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GetEntPropVector(iSentry, Prop_Send, "m_vecOrigin", fLocation);
|
||||
fLocation[2] += 20.0;
|
||||
|
||||
if (IsPointInZone(fLocation, g_fBeamPoints[iTower])) {
|
||||
int iShellsMax, iHealthMax, iRocketsMax, iMetalMax;
|
||||
|
||||
if (IsMiniSentry(iSentry)) {
|
||||
iShellsMax = 150;
|
||||
iHealthMax = 150;
|
||||
iRocketsMax = 0;
|
||||
iMetalMax = 0;
|
||||
} else {
|
||||
switch (GetBuildingLevel(iSentry)) {
|
||||
case 1: {
|
||||
iShellsMax = 150;
|
||||
iHealthMax = 150;
|
||||
iRocketsMax = 0;
|
||||
iMetalMax = 1000;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
iShellsMax = 200;
|
||||
iHealthMax = 180;
|
||||
iRocketsMax = 0;
|
||||
iMetalMax = 1000;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
iShellsMax = 200;
|
||||
iHealthMax = 216;
|
||||
iRocketsMax = 20;
|
||||
iMetalMax = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int iState = GetEntProp(iSentry, Prop_Send, "m_iState");
|
||||
|
||||
// If is not building up
|
||||
if (iState != 0) {
|
||||
int iShells = GetEntProp(iSentry, Prop_Send, "m_iAmmoShells");
|
||||
int iHealth = GetEntProp(iSentry, Prop_Send, "m_iHealth");
|
||||
int iRockets = GetEntProp(iSentry, Prop_Send, "m_iAmmoRockets");
|
||||
int iMetal = GetEntProp(iSentry, Prop_Send, "m_iUpgradeMetal");
|
||||
|
||||
if (IsMiniSentry(iSentry)) {
|
||||
int iShellsPerHit = 20; // Default: 40
|
||||
|
||||
if (iShells + iShellsPerHit < iShellsMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iAmmoShells", iShells + iShellsPerHit);
|
||||
} else if (iShells < iShellsMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iAmmoShells", iShellsMax);
|
||||
}
|
||||
} else {
|
||||
int iMetalPerHit = 10; // Default: 25
|
||||
int iHealthPerHit = 50; // Default: 105
|
||||
int iShellsPerHit = 20; // Default: 40
|
||||
int iRocketsPerHit = 4; // Default: 8
|
||||
|
||||
if (iMetal < iMetalMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iUpgradeMetal", iMetal + iMetalPerHit);
|
||||
|
||||
// Upgrade to the next level
|
||||
} else if (iMetalMax != 0 && !g_bAoEEngineerAttack) {
|
||||
float fLocationTower[3];
|
||||
GetClientAbsOrigin(iTower, fLocationTower);
|
||||
|
||||
TeleportEntity(iTower, fLocation, NULL_VECTOR, NULL_VECTOR);
|
||||
|
||||
g_bAoEEngineerAttack = true;
|
||||
|
||||
DataPack hPack = new DataPack();
|
||||
hPack.WriteFloat(float(iTower));
|
||||
hPack.WriteFloat(fLocationTower[0]);
|
||||
hPack.WriteFloat(fLocationTower[1]);
|
||||
hPack.WriteFloat(fLocationTower[2]);
|
||||
|
||||
CreateTimer(0.2, Timer_TeleportAoEEngineerBack, hPack, _);
|
||||
}
|
||||
|
||||
if (iHealth + iHealthPerHit < iHealthMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iHealth", iHealth + iHealthPerHit);
|
||||
} else if (iHealth < iHealthMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iHealth", iHealthMax);
|
||||
}
|
||||
|
||||
if (iShells + iShellsPerHit < iShellsMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iAmmoShells", iShells + iShellsPerHit);
|
||||
} else if (iShells < iShellsMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iAmmoShells", iShellsMax);
|
||||
}
|
||||
if (iRockets + iRocketsPerHit < iRocketsMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iAmmoRockets", iRockets + iRocketsPerHit);
|
||||
} else if (iRockets < iRocketsMax) {
|
||||
SetEntProp(iSentry, Prop_Send, "m_iAmmoRockets", iRocketsMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dispensers
|
||||
while ((iDispenser = FindEntityByClassname(iDispenser, "obj_dispenser")) != -1) {
|
||||
if (!IsValidEntity(iDispenser)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GetEntPropVector(iDispenser, Prop_Send, "m_vecOrigin", fLocation);
|
||||
|
||||
fLocation[2] += 20.0;
|
||||
|
||||
if (IsPointInZone(fLocation, g_fBeamPoints[iTower])) {
|
||||
int iHealthMax, iMetalMax;
|
||||
|
||||
switch (GetBuildingLevel(iDispenser)) {
|
||||
case 1: {
|
||||
iHealthMax = 150;
|
||||
iMetalMax = 500;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
iHealthMax = 180;
|
||||
iMetalMax = 500;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
iHealthMax = 216;
|
||||
iMetalMax = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int iBuildingUp = GetEntProp(iDispenser, Prop_Send, "m_bBuilding");
|
||||
if (iBuildingUp != 1) { // Is not building up
|
||||
int iHealth = GetEntProp(iDispenser, Prop_Send, "m_iHealth");
|
||||
int iMetal = GetEntProp(iDispenser, Prop_Send, "m_iUpgradeMetal");
|
||||
int iMetalPerHit = 10; // Default: 25
|
||||
int iHealthPerHit = 50; // Default: 105
|
||||
|
||||
if (iMetal < iMetalMax) {
|
||||
SetEntProp(iDispenser, Prop_Send, "m_iUpgradeMetal", iMetal + iMetalPerHit);
|
||||
} else if (iMetalMax != 0 && !g_bAoEEngineerAttack) { // Upgrade to the next level
|
||||
float fLocationTower[3];
|
||||
GetClientAbsOrigin(iTower, fLocationTower);
|
||||
|
||||
TeleportEntity(iTower, fLocation, NULL_VECTOR, NULL_VECTOR);
|
||||
|
||||
g_bAoEEngineerAttack = true;
|
||||
|
||||
DataPack hPack = new DataPack();
|
||||
hPack.WriteFloat(float(iTower));
|
||||
hPack.WriteFloat(fLocationTower[0]);
|
||||
hPack.WriteFloat(fLocationTower[1]);
|
||||
hPack.WriteFloat(fLocationTower[2]);
|
||||
|
||||
CreateTimer(0.5, Timer_TeleportAoEEngineerBack, hPack, _);
|
||||
}
|
||||
|
||||
if (iHealth + iHealthPerHit < iHealthMax) {
|
||||
SetEntProp(iDispenser, Prop_Send, "m_iHealth", iHealth + iHealthPerHit);
|
||||
} else if (iHealth < iHealthMax) {
|
||||
SetEntProp(iDispenser, Prop_Send, "m_iHealth", iHealthMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Action Timer_TeleportAoEEngineerBack(Handle hTimer, DataPack hPack) {
|
||||
hPack.Reset();
|
||||
|
||||
g_bAoEEngineerAttack = false;
|
||||
int iTower = RoundToZero(ReadPackFloat(hPack));
|
||||
float fLocation[3];
|
||||
fLocation[0] = hPack.ReadFloat();
|
||||
fLocation[1] = hPack.ReadFloat();
|
||||
fLocation[2] = hPack.ReadFloat();
|
||||
TeleportEntity(iTower, fLocation, NULL_VECTOR, NULL_VECTOR);
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Player is close to KritzMedic
|
||||
*
|
||||
* @param iTower The tower
|
||||
* @noreturn
|
||||
*/
|
||||
public void Tower_ObjectNearKritzMedic(int iTower) {
|
||||
// If Kritz Time is up
|
||||
if (TF2_GetUberLevel(iTower) <= 0.0)
|
||||
g_bKritzMedicCharged = false;
|
||||
|
||||
// If Bot is fully charged, charge player
|
||||
if (g_bKritzMedicCharged && TF2_GetUberLevel(iTower) > 0.0) {
|
||||
TF2_SetUberLevel(iTower, TF2_GetUberLevel(iTower) - 0.02);
|
||||
for (int iClient = 1; iClient <= MaxClients; iClient++) {
|
||||
if (IsValidClient(iClient))
|
||||
TF2_AddCondition(iClient, TFCond_Kritzkrieged, 0.3);
|
||||
}
|
||||
// If Bot is fully charged
|
||||
} else if (TF2_GetUberLevel(iTower) >= 1.0) {
|
||||
g_bKritzMedicCharged = true;
|
||||
} else if (iAoEKritzMedicTimer < 3 && !IsTowerAttached(iTower)) {
|
||||
iAoEKritzMedicTimer++;
|
||||
return;
|
||||
} else if (!IsTowerAttached(iTower)) {
|
||||
iAoEKritzMedicTimer = 0;
|
||||
}
|
||||
for (int iClient = 1; iClient <= MaxClients; iClient++) {
|
||||
if (IsDefender(iClient) && IsClientInZone(iClient, g_fBeamPoints[iTower])) {
|
||||
float fUberLevel = TF2_GetUberLevel(iTower);
|
||||
TF2_SetUberLevel(iTower, fUberLevel + 0.01);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Player is close to AoESpy
|
||||
*
|
||||
* @param iTower The tower
|
||||
* @param iClient The player
|
||||
* @noreturn
|
||||
*/
|
||||
public void Tower_ObjectNearAoESpy(int iTower) {
|
||||
for (int iClient = 1; iClient <= MaxClients; iClient++) {
|
||||
if (IsAttacker(iClient) && IsClientInZone(iClient, g_fBeamPoints[iTower]) && !g_iSlowAttacker[iClient])
|
||||
g_iSlowAttacker[iClient] = true;
|
||||
else if (g_iSlowAttacker[iClient] && IsClientInZone(iClient, g_fBeamPoints[iTower]))
|
||||
TF2_AddCondition(iClient, TFCond_TeleportedGlow, 1.0);
|
||||
else if (g_iSlowAttacker[iClient])
|
||||
g_iSlowAttacker[iClient] = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level of an building.
|
||||
*
|
||||
* @param iEntity The buildings entity index.
|
||||
* @return The buildings level.
|
||||
*/
|
||||
public int GetBuildingLevel(int iEntity) {
|
||||
return GetEntProp(iEntity, Prop_Send, "m_iUpgradeLevel");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks wheter a sentry is a Mini-Sentry or not.
|
||||
*
|
||||
* @param iSentry The sentries entity index.
|
||||
* @return True if mini, false otherwise.
|
||||
*/
|
||||
public bool IsMiniSentry(int iSentry) {
|
||||
return ((GetEntProp(iSentry, Prop_Send, "m_bMiniBuilding") == 0) ? false : true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a beam between two entities
|
||||
*
|
||||
* @param iEntity The start point
|
||||
* @param iTarget The target
|
||||
* @noreturn
|
||||
*/
|
||||
stock void AttachHealBeam(int iEntity, int iTarget) {
|
||||
int iParticleIndex1 = CreateEntityByName("info_particle_system");
|
||||
int iParticleIndex2 = CreateEntityByName("info_particle_system");
|
||||
|
||||
if (IsValidEdict(iParticleIndex1)) {
|
||||
char sEntityName[128];
|
||||
Format(sEntityName, sizeof(sEntityName), "target%i", iEntity);
|
||||
DispatchKeyValue(iEntity, "targetname", sEntityName);
|
||||
|
||||
char sTargetName1[128];
|
||||
Format(sTargetName1, sizeof(sTargetName1), "target%i", iTarget);
|
||||
DispatchKeyValue(iTarget, "targetname", sTargetName1);
|
||||
|
||||
char sTargetName2[128];
|
||||
Format(sTargetName2, sizeof(sTargetName2), "tf2particle%i", iTarget);
|
||||
|
||||
DispatchKeyValue(iParticleIndex2, "targetname", sTargetName2);
|
||||
DispatchKeyValue(iParticleIndex2, "parentname", sTargetName1);
|
||||
|
||||
SetVariantString(sTargetName1);
|
||||
AcceptEntityInput(iParticleIndex2, "SetParent");
|
||||
|
||||
SetVariantString("flag");
|
||||
AcceptEntityInput(iParticleIndex2, "SetParentAttachment");
|
||||
|
||||
DispatchKeyValue(iParticleIndex1, "targetname", "tf2particle");
|
||||
DispatchKeyValue(iParticleIndex1, "parentname", sEntityName);
|
||||
DispatchKeyValue(iParticleIndex1, "effect_name", "dispenser_heal_blue");
|
||||
DispatchKeyValue(iParticleIndex1, "cpoint1", sTargetName2);
|
||||
|
||||
DispatchSpawn(iParticleIndex1);
|
||||
|
||||
SetVariantString(sEntityName);
|
||||
AcceptEntityInput(iParticleIndex1, "SetParent");
|
||||
|
||||
SetVariantString("flag");
|
||||
AcceptEntityInput(iParticleIndex1, "SetParentAttachment");
|
||||
|
||||
ActivateEntity(iParticleIndex1);
|
||||
AcceptEntityInput(iParticleIndex1, "start");
|
||||
|
||||
g_iHealBeamIndex[iTarget][0] = iParticleIndex1;
|
||||
g_iHealBeamIndex[iTarget][1] = iParticleIndex2;
|
||||
}
|
||||
}
|
||||
|
||||
stock float TF2_GetUberLevel(int iClient) {
|
||||
int iIndex = GetPlayerWeaponSlot(iClient, 1);
|
||||
if (iIndex > 0)
|
||||
return GetEntPropFloat(iIndex, Prop_Send, "m_flChargeLevel");
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
stock void TF2_SetUberLevel(int iClient, float fUberLevel) {
|
||||
int iIndex = GetPlayerWeaponSlot(iClient, 1);
|
||||
if (iIndex > 0)
|
||||
SetEntPropFloat(iIndex, Prop_Send, "m_flChargeLevel", fUberLevel);
|
||||
}
|
Reference in New Issue
Block a user