diff --git a/README.md b/README.md index 68cb34f..af9a84b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Installation: **[View Releases](https://github.com/Batfoxkid/Freak-Fortress-2-Rewrite/releases)** -Use `New Install Package` for installing for the first time +Use `New Install Package` for installing for the first time Use `Update Package` to update your current version of Rewrite Required: diff --git a/addons/sourcemod/scripting/ff2r_default_abilities.sp b/addons/sourcemod/scripting/ff2r_default_abilities.sp index bb25d45..dc7f74f 100644 --- a/addons/sourcemod/scripting/ff2r_default_abilities.sp +++ b/addons/sourcemod/scripting/ff2r_default_abilities.sp @@ -117,6 +117,7 @@ "blue" "255" // Weapon blue "class" "" // Override class setup "force switch" "false" // Always force weapon switch + "lifetime" "" // Weapon lifetime (Won't replace weapon slot if used) "plugin_name" "ff2r_default_abilities" } @@ -276,8 +277,9 @@ "emergency" "2000.0" // Super Jump upward velocity added when touching a hazard "stun" "2.0" // Teleport stun duration "flags" "97" // Teleport stun flags - "slowdown" "1.0" // Teleport sutn slowdown + "slowdown" "1.0" // Teleport stun slowdown "reset on attack" "false" // Reset charge on attack + "targets" "3" // Teleport targets (1=Teammates, 2=Enemies) "plugin_name" "ff2r_default_abilities" } @@ -860,7 +862,12 @@ public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float { int target = -1; + button = ability.GetInt("targets", 3); + bool friendly = view_as(button & 1); + bool enemies = view_as(button & 2); + float pos1[3]; + if(!emergency) { FF2R_StartLagCompensation(client); @@ -869,51 +876,85 @@ public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float Handle trace = TR_TraceRayFilterEx(pos1, angles, MASK_PLAYERSOLID, RayType_Infinite, TraceRay_DontHitSelf, client); TR_GetEndPosition(pos1, trace); + delete trace; + } + + float distance; + float pos2[3]; + float scale = GetEntPropFloat(client, Prop_Send, "m_flModelScale"); + int team1 = GetClientTeam(client); + + for(int i = 1; i <= MaxClients; i++) + { + if(i == client || !IsClientInGame(i) || !IsPlayerAlive(i)) + continue; - float distance; - float pos2[3]; - float scale = GetEntPropFloat(client, Prop_Send, "m_flModelScale"); + int team2 = GetClientTeam(i); - for(int i = 1; i <= MaxClients; i++) + if(!friendly) { - if(i == client || !IsClientInGame(i) || !IsPlayerAlive(i)) - continue; - - if(!SpecTeam && GetClientTeam(i) <= view_as(TFTeam_Spectator)) + if(team1 == team2) continue; - - if(scale < GetEntPropFloat(i, Prop_Send, "m_flModelScale")) + } + + if(!enemies) + { + if(team1 != team2) continue; - - GetEntPropVector(i, Prop_Send, "m_vecOrigin", pos2); - float dist = GetVectorDistance(pos1, pos2, true); - if(target == -1 || dist < distance) - { - distance = dist; - target = i; - } } + + if(team1 > view_as(TFTeam_Spectator) && !SpecTeam && team2 <= view_as(TFTeam_Spectator)) + continue; + if(scale < GetEntPropFloat(i, Prop_Send, "m_flModelScale")) + continue; + + if(emergency) + { + target = i; + break; + } + + GetEntPropVector(i, Prop_Send, "m_vecOrigin", pos2); + float dist = GetVectorDistance(pos1, pos2, true); + if(target == -1 || dist < distance) + { + distance = dist; + target = i; + } + } + + if(!emergency) + { FF2R_FinishLagCompensation(client); } if(target != -1) { float stun = ability.GetFloat("stun", 2.0); - int flags = ability.GetInt("flags", TF_STUNFLAGS_LOSERSTATE); - float slowdown = ability.GetFloat("slowdown", 1.0); - - TF2_StunPlayer(client, stun, slowdown, flags); - DataPack pack; - CreateDataTimer(stun, Timer_RestoreCollision, pack, TIMER_FLAG_NO_MAPCHANGE); - pack.WriteCell(GetClientUserId(client)); - pack.WriteCell(GetEntProp(client, Prop_Send, "m_CollisionGroup")); - - SetEntityCollisionGroup(client, 2); + if(stun > 0.0) + { + int flags = ability.GetInt("flags", TF_STUNFLAGS_LOSERSTATE); + float slowdown = ability.GetFloat("slowdown", 1.0); + + if(slowdown > 0.0) + TF2_RemoveCondition(client, TFCond_MegaHeal); + + TF2_StunPlayer(client, stun, slowdown, flags); + SetEntPropFloat(client, Prop_Send, "m_flNextAttack", GetGameTime() + stun); + + TF2_AddCondition(target, TFCond_UberchargedHidden, 0.2, client); + + DataPack pack; + CreateDataTimer(stun, Timer_RestoreCollision, pack, TIMER_FLAG_NO_MAPCHANGE); + pack.WriteCell(GetClientUserId(client)); + pack.WriteCell(GetEntProp(client, Prop_Send, "m_CollisionGroup")); + + SetEntityCollisionGroup(client, 2); + } GetEntPropVector(target, Prop_Send, "m_vecOrigin", pos1); - TF2_AddCondition(target, TFCond_UberchargedHidden, 0.2, client); SetEntProp(client, Prop_Send, "m_bDucked", true); SetEntityFlags(client, GetEntityFlags(client) | FL_DUCKING); @@ -2183,8 +2224,10 @@ void Rage_NewWeapon(int client, ConfigData cfg, const char[] ability) TFClassType class = TF2_GetPlayerClass(client); GetClassWeaponClassname(class, classname, sizeof(classname)); bool wearable = StrContains(classname, "tf_weap") != 0; + + float lifetime = cfg.GetFloat("lifetime"); - if(!wearable) + if(!wearable && lifetime <= 0.0) { int slot = cfg.GetInt("weapon slot", -99); if(slot == -99) @@ -2406,6 +2449,15 @@ void Rage_NewWeapon(int client, ConfigData cfg, const char[] ability) FakeClientCommand(client, "use %s", classname); } } + + if(lifetime > 0.0) + { + DataPack pack; + CreateDataTimer(lifetime, Timer_RemoveItem, pack, TIMER_FLAG_NO_MAPCHANGE); + pack.WriteCell(EntIndexToEntRef(entity)); + pack.WriteCell(GetClientUserId(client)); + pack.WriteCell(wearable); + } } else if(forceClass != TFClass_Unknown) { @@ -2413,6 +2465,31 @@ void Rage_NewWeapon(int client, ConfigData cfg, const char[] ability) } } +public Action Timer_RemoveItem(Handle timer, DataPack pack) +{ + pack.Reset(); + int entity = EntRefToEntIndex(pack.ReadCell()); + if(entity != INVALID_ENT_REFERENCE) + { + int client = GetClientOfUserId(pack.ReadCell()); + if(client) + { + if(pack.ReadCell()) + { + TF2_RemoveWearable(client, entity); + } + else + { + if(GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon") == entity) + ClientCommand(client, "lastinv"); + + TF2_RemoveItem(client, entity); + } + } + } + return Plugin_Continue; +} + void Rage_CloneAttack(int client, ConfigData cfg) { int team = GetClientTeam(client); @@ -3303,6 +3380,20 @@ void GetClassWeaponClassname(TFClassType class, char[] name, int length) } } +void TF2_RemoveItem(int client, int weapon) +{ + int entity = GetEntPropEnt(weapon, Prop_Send, "m_hExtraWearable"); + if(entity != -1) + TF2_RemoveWearable(client, entity); + + entity = GetEntPropEnt(weapon, Prop_Send, "m_hExtraWearableViewModel"); + if(entity != -1) + TF2_RemoveWearable(client, entity); + + RemovePlayerItem(client, weapon); + RemoveEntity(weapon); +} + int TF2_GetClassnameSlot(const char[] classname, bool econ = false) { if(StrEqual(classname, "player")) diff --git a/addons/sourcemod/scripting/ff2r_menu_abilities.sp b/addons/sourcemod/scripting/ff2r_menu_abilities.sp index 0339922..0a465a1 100644 --- a/addons/sourcemod/scripting/ff2r_menu_abilities.sp +++ b/addons/sourcemod/scripting/ff2r_menu_abilities.sp @@ -445,7 +445,7 @@ public bool ShowMenuAll(int client, bool ticked) } } - if(ViewingMenu[client] || (enabled && GetClientMenu(client) == MenuSource_None)) + if(enabled && (ViewingMenu[client] || GetClientMenu(client) == MenuSource_None)) ShowMenu(client, client, boss, ability, enabled, ticked); int team1 = GetClientTeam(client); @@ -594,7 +594,7 @@ public void ShowMenu(int target, int client, BossData boss, AbilityData ability, { if(FF2R_GetBossData(i)) { - if(GetClientTeam(i) == team) + if(IsPlayerAlive(i) && GetClientTeam(i) == team) allies++; } else if(GetClientTeam(i) > view_as(TFTeam_Spectator)) @@ -884,7 +884,7 @@ public int ShowMenuH(Menu menu, MenuAction action, int client, int selection) { if(FF2R_GetBossData(i)) { - if(GetClientTeam(i) == team) + if(IsPlayerAlive(i) && GetClientTeam(i) == team) allies++; } else if(GetClientTeam(i) > view_as(TFTeam_Spectator)) @@ -1039,7 +1039,7 @@ public void RefreshSpells(int client, BossData boss, AbilityData ability) { if(FF2R_GetBossData(i)) { - if(GetClientTeam(i) == team) + if(IsPlayerAlive(i) && GetClientTeam(i) == team) allies++; } } diff --git a/addons/sourcemod/scripting/freak_fortress_2/bosses.sp b/addons/sourcemod/scripting/freak_fortress_2/bosses.sp index f38a9a4..0c35bac 100644 --- a/addons/sourcemod/scripting/freak_fortress_2/bosses.sp +++ b/addons/sourcemod/scripting/freak_fortress_2/bosses.sp @@ -2097,8 +2097,12 @@ static void EquipBoss(int client, bool weapons) if(!wearable && !value) { - value = true; - SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", entity); + level = TF2_GetClassnameSlot(classname); + if(level >= TFWeaponSlot_Primary && level <= TFWeaponSlot_Melee) + { + value = true; + SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", entity); + } } } else if(forceClass != TFClass_Unknown) diff --git a/addons/sourcemod/scripting/freak_fortress_2/commands.sp b/addons/sourcemod/scripting/freak_fortress_2/commands.sp index 78facde..6564c54 100644 --- a/addons/sourcemod/scripting/freak_fortress_2/commands.sp +++ b/addons/sourcemod/scripting/freak_fortress_2/commands.sp @@ -356,10 +356,5 @@ public Action Command_EurekaTeleport(int client, const char[] command, int args) static bool IsEmptyServer() { - for(int client = 1; client <= MaxClients; client++) - { - if(IsClientInGame(client) && GetClientTeam(client) > TFTeam_Spectator) - return false; - } - return true; + return GameRules_GetRoundState() < RoundState_StartGame; } \ No newline at end of file diff --git a/addons/sourcemod/scripting/freak_fortress_2/events.sp b/addons/sourcemod/scripting/freak_fortress_2/events.sp index 1048757..02eeb5b 100644 --- a/addons/sourcemod/scripting/freak_fortress_2/events.sp +++ b/addons/sourcemod/scripting/freak_fortress_2/events.sp @@ -63,11 +63,11 @@ void Events_CheckAlivePlayers(int exclude = 0, bool alive = true, bool resetMax if((spec || team > TFTeam_Spectator) && ((!alive && team > TFTeam_Spectator) || IsPlayerAlive(i))) { PlayersAlive[team]++; - if(team == TFTeam_Blue && !bluBoss && Client(i).IsBoss && Client(i).Cfg.GetSection("sound_lastman")) + if(team == TFTeam_Blue && !bluBoss && Client(i).IsBoss && IsPlayerAlive(i) && Client(i).Cfg.GetSection("sound_lastman")) { bluBoss = i; } - else if(team != TFTeam_Blue && !redBoss && Client(i).IsBoss && Client(i).Cfg.GetSection("sound_lastman")) + else if(team != TFTeam_Blue && !redBoss && Client(i).IsBoss && IsPlayerAlive(i) && Client(i).Cfg.GetSection("sound_lastman")) { redBoss = i; }