diff --git a/.github/workflows/plugin.yml b/.github/workflows/plugin.yml index b5c30138..34894fa1 100644 --- a/.github/workflows/plugin.yml +++ b/.github/workflows/plugin.yml @@ -24,7 +24,7 @@ jobs: id: setup-sp uses: rumblefrog/setup-sp@master with: - version: '1.11.6960' + version: '1.12.7164' version-file: ./scripting/include/srccoop/public.inc define-name: SRCCOOP_VERSION diff --git a/README.md b/README.md index 784ca06c..05d74185 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ The script installation will automatically go through the process of installing quit ``` - Install [Metamod:Source](https://www.sourcemm.net/downloads.php?branch=stable) (latest tested build ➤ __1155__) onto the server. -- Install [SourceMod](https://www.sourcemod.net/downloads.php?branch=stable) (latest tested build ➤ __6968__) onto the server. +- Install [SourceMod](https://www.sourcemod.net/downloads.php?branch=stable) (latest tested build ➤ __7164__) onto the server. - Install [the latest SourceCoop release](https://github.com/ampreeT/SourceCoop/releases) onto the server. - [Forward the necessary ports.](#port-forwarding) diff --git a/scripting/include/srccoop.inc b/scripting/include/srccoop.inc index 1775e054..0187c0c4 100644 --- a/scripting/include/srccoop.inc +++ b/scripting/include/srccoop.inc @@ -12,9 +12,6 @@ #if !defined SRCCOOP_CUSTOM_COMPILE -// Uncomment to disable debugging -// #define NO_DEBUG - #if defined SRCCOOP_HL2DM #define CHECK_ENGINE "HL2DM"; if (GetEngineVersion() != Engine_HL2DM) @@ -145,9 +142,6 @@ #include #include -#pragma newdecls required -#pragma semicolon 1 - #include #include diff --git a/scripting/include/srccoop/classdef.inc b/scripting/include/srccoop/classdef.inc index 51d58211..2904303f 100644 --- a/scripting/include/srccoop/classdef.inc +++ b/scripting/include/srccoop/classdef.inc @@ -10,7 +10,6 @@ IServerGameClients g_ServerGameClients; CPlayerInfoManager g_pPlayerInfoManager; -CGlobalVars gpGlobals; ConVar ai_los_mode; @@ -412,9 +411,6 @@ stock void InitClassdef(GameData pGameConfig) #if defined SRCCOOP_BLACKMESA InitClassdefBM(pGameConfig); #endif - - if (!(gpGlobals = g_pPlayerInfoManager.GetGlobalVars())) - SetFailState("Could not get gpGlobals from PlayerInfoManager"); } #define NULL_CBASEENTITY view_as(-1) @@ -3307,7 +3303,7 @@ methodmap CGlobalVarsBase public void SetMaxPlayers(const int iMaxPlayers) { assert(this.IsValid(), "Invalid state") - assert(IsInBounds(iMaxPlayers, 0, MaxClients), "Invalid maxplayers [%d]", iMaxPlayers) + assert1(IsInBounds(iMaxPlayers, 0, MaxClients), "Invalid maxplayers [%d]", iMaxPlayers) StoreToAddress(view_as
(this) + 0x14, iMaxPlayers, NumberType_Int32); } diff --git a/scripting/include/srccoop/config.inc b/scripting/include/srccoop/config.inc index 591c3413..7b6d50c4 100644 --- a/scripting/include/srccoop/config.inc +++ b/scripting/include/srccoop/config.inc @@ -53,29 +53,29 @@ enum struct SourceCoopConfig //------------------------------------------------------ - CONF_INIT(\ - CONF_STR(SND_BRINGALL)\ - CONF_FLT(SND_BRINGALL_VOL)\ - CONF_STR(SND_PORTAL)\ - CONF_FLT(SND_PORTAL_VOL)\ - CONF_STR(PORTAL_PARTICLE)\ - CONF_FLT(PORTAL_TOUCH_SIZE)\ - CONF_CLR(FROZEN_FADE_COLOR)\ - CONF_INT(FROZEN_FADE_DUR_IN)\ - CONF_INT(FROZEN_FADE_DUR_OUT)\ - CONF_STR(SND_TICK)\ - CONF_FLT(SND_TICK_VOL)\ - CONF_STR(SND_3)\ - CONF_STR(SND_2)\ - CONF_STR(SND_1)\ - CONF_STR(SND_CHANGELEVEL)\ - CONF_FLT(SND_CHANGELEVEL_VOL)\ - CONF_STR(SND_CHANGELEVEL_TICK)\ - CONF_FLT(SND_CHANGELEVEL_TICK_VOL)\ - CONF_STR(CHANGELEVEL_EFFECT_MODEL)\ - CONF_INT(CHANGELEVEL_EFFECT_AMOUNT)\ - CONF_FLT(CHANGELEVEL_EFFECT_SPEED)\ - CONF_FLT(CHANGELEVEL_EFFECT_PERIOD)\ + CONF_INIT( + CONF_STR(SND_BRINGALL) + CONF_FLT(SND_BRINGALL_VOL) + CONF_STR(SND_PORTAL) + CONF_FLT(SND_PORTAL_VOL) + CONF_STR(PORTAL_PARTICLE) + CONF_FLT(PORTAL_TOUCH_SIZE) + CONF_CLR(FROZEN_FADE_COLOR) + CONF_INT(FROZEN_FADE_DUR_IN) + CONF_INT(FROZEN_FADE_DUR_OUT) + CONF_STR(SND_TICK) + CONF_FLT(SND_TICK_VOL) + CONF_STR(SND_3) + CONF_STR(SND_2) + CONF_STR(SND_1) + CONF_STR(SND_CHANGELEVEL) + CONF_FLT(SND_CHANGELEVEL_VOL) + CONF_STR(SND_CHANGELEVEL_TICK) + CONF_FLT(SND_CHANGELEVEL_TICK_VOL) + CONF_STR(CHANGELEVEL_EFFECT_MODEL) + CONF_INT(CHANGELEVEL_EFFECT_AMOUNT) + CONF_FLT(CHANGELEVEL_EFFECT_SPEED) + CONF_FLT(CHANGELEVEL_EFFECT_PERIOD) ) } diff --git a/scripting/include/srccoop/entitypatch.inc b/scripting/include/srccoop/entitypatch.inc index 07f873d6..eed9e7d6 100644 --- a/scripting/include/srccoop/entitypatch.inc +++ b/scripting/include/srccoop/entitypatch.inc @@ -972,7 +972,7 @@ public MRESReturn Hook_AIConditionsThink(int _this) if (!conditionsElement) continue; - CBaseEntity pActor = CBaseEntity(LoadEntityHandleFromAddress(conditionsElement)); + CBaseEntity pActor = CBaseEntity(LoadEntityFromHandleAddress(conditionsElement)); if (!pActor.IsValid()) continue; diff --git a/scripting/include/srccoop/globals.inc b/scripting/include/srccoop/globals.inc index 0371272f..a1a4b65e 100644 --- a/scripting/include/srccoop/globals.inc +++ b/scripting/include/srccoop/globals.inc @@ -180,6 +180,7 @@ ArrayList g_pCoopModeMemPatchList; // ---------------------------- IServerGameDLL g_ServerGameDLL; IServerTools g_ServerTools; +CGlobalVars gpGlobals; // ---------------------------- // Plugin variables diff --git a/scripting/include/srccoop/levellump.inc b/scripting/include/srccoop/levellump.inc index 38181791..466ef035 100644 --- a/scripting/include/srccoop/levellump.inc +++ b/scripting/include/srccoop/levellump.inc @@ -276,7 +276,7 @@ methodmap CEntityListLump < ArrayList { public CEntityListLump() { - return view_as(new ArrayList(sizeof(CEntityInfoLump))); + return view_as(new ArrayList()); } // cast diff --git a/scripting/include/srccoop/util/assert.inc b/scripting/include/srccoop/util/assert.inc index 84037699..0eb050b0 100644 --- a/scripting/include/srccoop/util/assert.inc +++ b/scripting/include/srccoop/util/assert.inc @@ -8,15 +8,21 @@ /* * Assertion utility - only compiled into debug code -* Params: 1 => condition, 2 => message + format arguments +* Params: 0 => condition, 1 => message, 2+ => format arguments */ #if defined DEBUG - #define assert(%1,%2) if (!(%1)) SetFailState(%2); + #define assert(%0,%1) if (!(%0)) SetFailState(%1); + #define assert1(%0,%1,%2) if (!(%0)) SetFailState(%1,%2); + #define assert2(%0,%1,%2,%3) if (!(%0)) SetFailState(%1,%2,%3); + #define assert3(%0,%1,%2,%3,%4) if (!(%0)) SetFailState(%1,%2,%3,%4); #else - #define assert(%1,%2) + #define assert(%0,%1) + #define assert1(%0,%1,%2) + #define assert2(%0,%1,%2,%3) + #define assert3(%0,%1,%2,%3,%4) #endif \ No newline at end of file diff --git a/scripting/include/srccoop/utils.inc b/scripting/include/srccoop/utils.inc index 0ca5ee0d..6c432a51 100644 --- a/scripting/include/srccoop/utils.inc +++ b/scripting/include/srccoop/utils.inc @@ -206,34 +206,6 @@ stock int LoadStringFromAddress(Address addr, char[] buffer, int maxlen, bool &b return c; } -/** - * DEPRECATE with SM 1.12 => LoadEntityFromHandleAddress - * Retrieves an entity index from a raw entity handle address. - * - * Note that SourceMod's entity conversion routine is an implementation detail that may change. - * - * @param addr Address to a memory location. - * @return Entity index, or -1 if not valid. - */ -stock int LoadEntityHandleFromAddress(Address addr) -{ - return EntRefToEntIndex(Deref(addr) | (1 << 31)); -} - -/** - * DEPRECATE with SM 1.12 => StoreEntityToHandleAddress - * Stores an entity into a raw entity handle address. Stores zero if the entity is not valid. - * - * Note that SourceMod's entity conversion routine is an implementation detail that may change. - * - * @param addr Address to a memory location. - * @param entity Entity index. - */ -stock void StoreEntityHandleToAddress(Address addr, int entity) -{ - StoreToAddress(addr, IsValidEntity(entity)? EntIndexToEntRef(entity) & ~(1 << 31) : 0, NumberType_Int32); -} - /** * Returns an entity index from its address by attempting to read the * CBaseEntity::m_RefEHandle member. This assumes the address of a CBaseEntity is @@ -246,7 +218,7 @@ stock int GetEntityFromAddress(Address pEntity) { static int offs_RefEHandle; if (offs_RefEHandle) - return LoadEntityHandleFromAddress(pEntity + offs_RefEHandle); + return LoadEntityFromHandleAddress(pEntity + offs_RefEHandle); // if we don't have it already, attempt to lookup offset based on SDK information // CWorld is derived from CBaseEntity so it should have both offsets @@ -274,30 +246,6 @@ stock int GetEntityFromAddress(Address pEntity) return GetEntityFromAddress(pEntity); } -//------------------------------------------------------ -// Cookie utils -//------------------------------------------------------ -#if defined _clientprefs_included -stock bool GetCookieBool(Cookie cookie, int client) -{ - static char szBuffer[2]; - cookie.Get(client, szBuffer, sizeof(szBuffer)); - return StringToInt(szBuffer) == 1; -} - -stock void SetCookieBool(Cookie cookie, int client, bool val) -{ - cookie.Set(client, val? "1" : "0"); -} - -stock bool IsCookieSet(Cookie cookie, int client) -{ - static char szBuffer[2]; - cookie.Get(client, szBuffer, sizeof(szBuffer)); - return szBuffer[0] != '\0'; -} -#endif - //------------------------------------------------------ // Text utils //------------------------------------------------------ diff --git a/scripting/include/srccoop_api.inc b/scripting/include/srccoop_api.inc index 06be5798..98323226 100644 --- a/scripting/include/srccoop_api.inc +++ b/scripting/include/srccoop_api.inc @@ -7,13 +7,18 @@ #pragma semicolon 1 #if !defined SRCCOOP_CUSTOM_COMPILE + #if defined SRCCOOP_HL2DM + #else + #if !defined SRCCOOP_BLACKMESA // SRCCOOP_BLACKMESA is the fallback if no other definition is passed #define SRCCOOP_BLACKMESA #endif + #endif + #endif diff --git a/scripting/srccoop.sp b/scripting/srccoop.sp index ce342178..c7016794 100644 --- a/scripting/srccoop.sp +++ b/scripting/srccoop.sp @@ -29,6 +29,9 @@ void LoadGameData() if (!(g_ServerTools = IServerTools(GetInterface(pGameConfig, "server", "IServerTools")))) SetFailState("Could not get interface for %s", "IServerTools"); + if (!(gpGlobals = g_pPlayerInfoManager.GetGlobalVars())) + SetFailState("Could not get gpGlobals from PlayerInfoManager"); + // Calls #if defined PLAYERPATCH_SERVERSIDE_RAGDOLLS diff --git a/scripting/srccoop_addon_earbleed.sp b/scripting/srccoop_addon_earbleed.sp index 553e442a..614f4fc4 100644 --- a/scripting/srccoop_addon_earbleed.sp +++ b/scripting/srccoop_addon_earbleed.sp @@ -18,7 +18,7 @@ public Plugin myinfo = #define MENUITEM_TOGGLE_EARBLEED "ToggleEarBleed" -CookieCompat pEnabledCookie; +Cookie pEnabledCookie; ConVar pConvarDefault; void LoadGameData() @@ -43,7 +43,7 @@ public void OnPluginStart() InitSourceCoopAddon(); LoadGameData(); - pEnabledCookie = view_as(new Cookie("sourcecoop_earbleed_enabled", "Earbleed toggle", CookieAccess_Protected)); + pEnabledCookie = new Cookie("sourcecoop_earbleed_enabled", "Earbleed toggle", CookieAccess_Protected); pConvarDefault = CreateConVar("sourcecoop_earbleed_default", "0", "Sets the default setting of the earbleed player preference.", _, true, 0.0, true, 1.0); } @@ -112,27 +112,4 @@ public MRESReturn Hook_SetPlayerDSP(DHookParam hParams) bool ShouldRing(int client) { return view_as(AreClientCookiesCached(client)? pEnabledCookie.GetInt(client, pConvarDefault.IntValue) : pConvarDefault.IntValue); -} - -// SM 1.11 Compat - undo when 1.12 stable -methodmap CookieCompat < Cookie -{ - public int GetInt(int client, int defaultValue = 0) - { - char buffer[11]; - this.Get(client, buffer, sizeof(buffer)); - - int value; - if (!StringToIntEx(buffer, value)) - { - value = defaultValue; - } - return value; - } - public void SetInt(int client, int value) { - char sValue[11]; - IntToString(value, sValue, sizeof(sValue)); - - this.Set(client, sValue); - } } \ No newline at end of file diff --git a/scripting/srccoop_addon_killsounds.sp b/scripting/srccoop_addon_killsounds.sp index 4881d09f..357e71a2 100644 --- a/scripting/srccoop_addon_killsounds.sp +++ b/scripting/srccoop_addon_killsounds.sp @@ -54,20 +54,20 @@ public void MyMenuHandler(TopMenu topmenu, TopMenuAction action, TopMenuObject o { if (action == TopMenuAction_DisplayOption) { - Format(buffer, maxlength, "%T", GetCookieBool(pEnabledCookie, param) ? "disable killsounds" : "enable killsounds", param); + Format(buffer, maxlength, "%T", pEnabledCookie.GetInt(param, pConvarDefault.BoolValue) ? "disable killsounds" : "enable killsounds", param); } else if (action == TopMenuAction_SelectOption) { if (AreClientCookiesCached(param)) { - if (GetCookieBool(pEnabledCookie, param)) + if (pEnabledCookie.GetInt(param, pConvarDefault.BoolValue)) { - SetCookieBool(pEnabledCookie, param, false); + pEnabledCookie.SetInt(param, false); Msg(param, "%t", "killsounds disabled"); } else { - SetCookieBool(pEnabledCookie, param, true); + pEnabledCookie.SetInt(param, true); Msg(param, "%t", "killsounds enabled"); } } @@ -80,15 +80,6 @@ public void OnConfigsExecuted() PrecacheSound(szSoundPath, true); } -public void OnClientCookiesCached(int client) -{ - if (!IsCookieSet(pEnabledCookie, client)) - { - // new player - set the default - SetCookieBool(pEnabledCookie, client, pConvarDefault.BoolValue); - } -} - public void Event_EntityKilled(Event hEvent, const char[] szName, bool bDontBroadcast) { CBaseEntity pKilled = CBaseEntity(hEvent.GetInt("entindex_killed")); @@ -96,7 +87,7 @@ public void Event_EntityKilled(Event hEvent, const char[] szName, bool bDontBroa if (pAttacker.IsClassPlayer() && pKilled.IsClassNPC()) { - if (GetCookieBool(pEnabledCookie, pAttacker.entindex)) + if (pEnabledCookie.GetInt(pAttacker.entindex, pConvarDefault.BoolValue)) { EmitSoundToClient(pAttacker.entindex, szSoundPath, .level = SNDLEVEL_NONE, .volume = flSoundVol); } diff --git a/scripting/srccoop_addon_revive.sp b/scripting/srccoop_addon_revive.sp index 8f59f985..4c21a398 100644 --- a/scripting/srccoop_addon_revive.sp +++ b/scripting/srccoop_addon_revive.sp @@ -29,15 +29,15 @@ enum struct ReviveConfig char BAR_MODEL[PLATFORM_MAX_PATH]; char RAGDOLL_PARTICLE[128]; - CONF_INIT(\ - CONF_STR(SND_START)\ - CONF_STR(SND_DENY)\ - CONF_STR(SND_RESPAWN)\ - CONF_INT(SND_RESPAWN_PITCH)\ - CONF_INT(SNDLEVEL)\ - CONF_CLR(BAR_COLOR)\ - CONF_STR(BAR_MODEL)\ - CONF_STR(RAGDOLL_PARTICLE)\ + CONF_INIT( + CONF_STR(SND_START) + CONF_STR(SND_DENY) + CONF_STR(SND_RESPAWN) + CONF_INT(SND_RESPAWN_PITCH) + CONF_INT(SNDLEVEL) + CONF_CLR(BAR_COLOR) + CONF_STR(BAR_MODEL) + CONF_STR(RAGDOLL_PARTICLE) ) } diff --git a/scripting/srccoop_addon_scoring.sp b/scripting/srccoop_addon_scoring.sp index 797dbf45..698ff101 100644 --- a/scripting/srccoop_addon_scoring.sp +++ b/scripting/srccoop_addon_scoring.sp @@ -7,43 +7,18 @@ #pragma newdecls required #pragma semicolon 1 -#define COLOR_MURDER "\x07CC00FF" -#define COLOR_MURDER_VICTIM "\x0700B1AF" -#define COLOR_KILL_SCORE_ENT "\x071BE5BD" -#define COLOR_CRIMSON "\x07E31919" -#define COLOR_WHITE "\x07FFFFFF" - -#define MAX_DAMAGE_AWARDED_PER_HIT 500.0 -#define MAX_COMBO 50 - -#define MENUITEM_TOGGLE_KILLFEED "ToggleKillfeed" - -StringMap hTrie; -Handle hDmgTimer; -StringMap hDmgTrie; -StringMap hComboTimeTrie; -ArrayList lNpcDamageTracker; - -Cookie pKillfeedEnabledCookie; -ConVar pConvarKillfeedDefault; - public Plugin myinfo = { name = "SourceCoop Scoring", - author = "Rock & Alienmario", - description = "Player scores for killing NPCs + chat killfeed", + author = "", + description = "Placeholder plugin", version = SRCCOOP_VERSION, url = SRCCOOP_URL }; +/* public void OnPluginStart() { - PopulateEntityNameMap(); - InitComboTracker(); - HookEvent("entity_killed", Event_EntKilled); - pKillfeedEnabledCookie = new Cookie("sourcecoop_killfeed_enabled", "Killfeed", CookieAccess_Protected); - pConvarKillfeedDefault = CreateConVar("sourcecoop_killfeed_default", "0", "Sets the default setting of the killfeed player preference.", _, true, 0.0, true, 1.0); - InitSourceCoopAddon(); } @@ -55,466 +30,8 @@ public void OnLibraryAdded(const char[] name) TopMenuObject pMenuCategory = pCoopMenu.FindCategory(COOPMENU_CATEGORY_OTHER); if (pMenuCategory != INVALID_TOPMENUOBJECT) { - pCoopMenu.AddItem(MENUITEM_TOGGLE_KILLFEED, MyMenuHandler, pMenuCategory); - } - } -} -public void MyMenuHandler(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength) -{ - if (action == TopMenuAction_DisplayOption) - { - Format(buffer, maxlength, GetCookieBool(pKillfeedEnabledCookie, param) ? "Disable killfeed" : "Enable killfeed"); - } - else if (action == TopMenuAction_SelectOption) - { - if (AreClientCookiesCached(param)) - { - if (GetCookieBool(pKillfeedEnabledCookie, param)) - { - SetCookieBool(pKillfeedEnabledCookie, param, false); - Msg(param, "Killfeed disabled."); - } - else - { - SetCookieBool(pKillfeedEnabledCookie, param, true); - Msg(param, "Killfeed enabled."); - } } - topmenu.Display(param, TopMenuPosition_LastCategory); - } -} - -public void OnClientCookiesCached(int client) -{ - if (!IsCookieSet(pKillfeedEnabledCookie, client)) - { - // new player - set the default - SetCookieBool(pKillfeedEnabledCookie, client, pConvarKillfeedDefault.BoolValue); } } - -// name fix copied from Alienmario's HL2MP deathnotices -public void EntityNameFix(char[] szName) -{ - GetTrieString(hTrie, szName, szName, 32); -} - -public void PopulateEntityNameMap() -{ - if (hTrie == null) - { - hTrie = new StringMap(); - - // Weapons - SetTrieString(hTrie, "weapon_crowbar", "Crowbar"); - SetTrieString(hTrie, "weapon_crossbow", "Crossbow"); - SetTrieString(hTrie, "weapon_357", "Revolver"); - SetTrieString(hTrie, "weapon_shotgun", "Shotgun"); - SetTrieString(hTrie, "weapon_mp5", "MP5"); - SetTrieString(hTrie, "weapon_glock", "Glock"); - SetTrieString(hTrie, "weapon_tau", "Tau Cannon"); - SetTrieString(hTrie, "weapon_gluon", "Gluon Gun"); - SetTrieString(hTrie, "weapon_assassin_glock", "Silenced Glock"); - SetTrieString(hTrie, "projectile_electric_ball", "Electric Orb"); - SetTrieString(hTrie, "projectile_electrocluster_chunk", "Electrocluster"); - - // Projectiles & Grenades - SetTrieString(hTrie, "grenade_hornet", "Hive Hand"); - SetTrieString(hTrie, "grenade_mp5_contact", "MP5 Grenade"); - SetTrieString(hTrie, "grenade_tripmine", "Tripmine"); - SetTrieString(hTrie, "grenade_frag", "Frag Grenade"); - SetTrieString(hTrie, "grenade_bolt", "Explosive Bolt"); - SetTrieString(hTrie, "grenade_satchel", "Satchel Charge"); - SetTrieString(hTrie, "grenade_rpg", "Rocket Launcher"); - SetTrieString(hTrie, "grenade_tow", "Mounted Rocket Launcher"); - SetTrieString(hTrie, "grenade_spit", "Toxic Spit"); - - // NPCS - SetTrieString(hTrie, "npc_human_scientist", "a Friendly Scientist"); - SetTrieString(hTrie, "npc_human_scientist_female", "a Friendly Scientist"); - SetTrieString(hTrie, "npc_human_security", "a Friendly Security Guard"); - SetTrieString(hTrie, "npc_barnacle", "Barnacle"); - SetTrieString(hTrie, "npc_vortigaunt", "Vortigaunt"); - SetTrieString(hTrie, "npc_alien_slave", "Vortigaunt"); - SetTrieString(hTrie, "npc_alien_grunt", "Alien Grunt"); - SetTrieString(hTrie, "npc_alien_grunt_melee", "Alien Grunt"); - SetTrieString(hTrie, "npc_alien_grunt_unarmored", "Unarmored Alien Grunt"); - SetTrieString(hTrie, "npc_alien_grunt_elite", "Elite Alien Grunt"); - SetTrieString(hTrie, "npc_human_assassin", "Ninja"); - SetTrieString(hTrie, "npc_human_medic", "HECU Medic"); - SetTrieString(hTrie, "npc_human_grunt", "HECU Grunt"); - SetTrieString(hTrie, "npc_human_commander", "HECU Commander"); - SetTrieString(hTrie, "npc_human_grenadier", "HECU Grenadier"); - SetTrieString(hTrie, "npc_headcrab", "Headcrab"); - SetTrieString(hTrie, "npc_houndeye", "Houndeye"); - SetTrieString(hTrie, "npc_zombie_scientist", "Scientist Zombie"); - SetTrieString(hTrie, "npc_zombie_scientist_torso", "Half a Scientist Zombie"); - SetTrieString(hTrie, "npc_zombie_security", "Barney Zombie"); - SetTrieString(hTrie, "npc_zombie_grunt", "HECU Zombie"); - SetTrieString(hTrie, "npc_zombie_grunt_torso", "Half a HECU Zombie"); - SetTrieString(hTrie, "npc_zombie_hev", "HEV Zombie"); - SetTrieString(hTrie, "npc_bullsquid", "Bullsquid"); - SetTrieString(hTrie, "npc_sentry_ground", "Ground Turret"); - SetTrieString(hTrie, "npc_sentry_ceiling", "Ceiling Turret"); - SetTrieString(hTrie, "npc_sniper", "Sniper"); - SetTrieString(hTrie, "npc_apache", "Apache"); - SetTrieString(hTrie, "npc_ichthyosaur", "a Dumb Fish"); - SetTrieString(hTrie, "npc_snark", "Snark"); - SetTrieString(hTrie, "npc_crow", "Crow"); - SetTrieString(hTrie, "npc_abrams", "Abrams Tank"); - SetTrieString(hTrie, "npc_lav", "Light Tank"); - SetTrieString(hTrie, "npc_osprey", "Osprey"); - SetTrieString(hTrie, "npc_xortEB", "Vortigaunt"); - SetTrieString(hTrie, "npc_xort", "Friendly Vortigaunt"); - SetTrieString(hTrie, "npc_alien_controller", "Alien Controller"); - SetTrieString(hTrie, "npc_xontroller", "Alien Controller"); - SetTrieString(hTrie, "npc_gargantua", "Gargantua"); - SetTrieString(hTrie, "npc_tentacle", "Outer-Space Octopus"); - - // Xen - SetTrieString(hTrie, "npc_houndeye_knockback", "Armored Houndeye"); - SetTrieString(hTrie, "npc_houndeye_suicide", "Baby Houndeye"); - SetTrieString(hTrie, "npc_beneathticle", "Beneathticle"); - SetTrieString(hTrie, "npc_protozoan", "Floaty Boi"); - SetTrieString(hTrie, "npc_xentree", "Xen Tree"); - SetTrieString(hTrie, "npc_xenturret", "Xen Turret"); - SetTrieString(hTrie, "npc_headcrab_baby", "Baby Headcrab"); - SetTrieString(hTrie, "npc_bullsquid_melee", "Melee Bullsquid"); - SetTrieString(hTrie, "npc_gonarch", "The Gonarch"); - SetTrieString(hTrie, "npc_xen_grun", "Xen Grunt"); - SetTrieString(hTrie, "npc_nihalinth", "The Nihalinth"); - - // misc - SetTrieString(hTrie, "prop_physics", "a physics prop"); - SetTrieString(hTrie, "func_50cal", "50 Cal Mounted Gun"); - } -} - -public void Event_EntKilled(Event event, const char[] name, bool dontBroadcast) -{ - CBaseEntity pKilled = CBaseEntity(event.GetInt("entindex_killed")); - CBaseEntity pAttacker = CBaseEntity(event.GetInt("entindex_attacker")); - CBaseEntity pInflictor = CBaseEntity(event.GetInt("entindex_inflictor")); - - char szKilledName[32]; - pKilled.GetClassname(szKilledName, sizeof(szKilledName)); - char szAttackerName[32]; - pAttacker.GetClassname(szAttackerName, sizeof(szAttackerName)); - char szInflictorClass[32]; - pInflictor.GetClassname(szInflictorClass, sizeof(szInflictorClass)); - - EntityNameFix(szInflictorClass); - - if (pAttacker.IsClassPlayer()) - { - CBasePlayer pClient = view_as(pAttacker.GetEntIndex()); - if (pKilled.IsClassNPC()) - { - CAI_BaseNPC pNPC = CAI_BaseNPC(pKilled.GetEntIndex()); - // A player killed an NPC - pClient.GetName(szAttackerName, sizeof(szAttackerName)); - - // Killing friendly NPCs should be punished! - if ((StrContains(szKilledName, "human_scientist", false) > -1) || - (StrContains(szKilledName, "human_security", false) > -1)) - { - EntityNameFix(szKilledName); - PrintToChatKillfeed("%s%s%s brutally murdered %s%s%s in cold blood with %s%s", COLOR_MURDER, szAttackerName, COLOR_CRIMSON, COLOR_MURDER_VICTIM, szKilledName, COLOR_CRIMSON, COLOR_MURDER, szInflictorClass); - pClient.ModifyScore(-10); - } - // Monsters should reward points tho - else - { - EntityNameFix(szKilledName); - char szMessage[254]; - - // Check to see if the npc that was killed was targetting another player - char szSavedName[32]; - char szSavedNameColor[] = COLOR_KILL_SCORE_ENT; - StrCat(szMessage, sizeof(szMessage), "%s%s%s killed %s%s%s with %s%s"); - - // Did the NPC that was killed have an enemy targeted? - CBaseEntity pKilledEnemy = pNPC.GetEnemy(); - - int iPointsToAward = 1; - if (pKilledEnemy.IsValid()) - { - // Was it a player different from the killer? - if (pKilledEnemy.IsClassPlayer() && pKilledEnemy.GetEntIndex() != pClient.GetEntIndex()) - { - CBasePlayer pTargetClient = CBasePlayer(pKilledEnemy.GetEntIndex()); - iPointsToAward += 1; - pTargetClient.GetName(szSavedName, sizeof(szSavedName)); - StrCat(szMessage, sizeof(szMessage), "%s saving %s%s"); - } - // Or an NPC - else if (pKilledEnemy.IsClassNPC()) - { - // Was the NPC friendly? - pKilledEnemy.GetClassname(szSavedName, sizeof(szSavedName)); - - if ((StrContains(szSavedName, "human_scientist", false) > -1) || - (StrContains(szSavedName, "human_security", false) > -1)) - { - iPointsToAward += 1; - szSavedNameColor = COLOR_MURDER_VICTIM; - } - else - szSavedNameColor = COLOR_CRIMSON; - - EntityNameFix(szSavedName); - StrCat(szMessage, sizeof(szMessage), "%s saving %s%s"); - } - } - - PrintToChatKillfeed(szMessage, COLOR_KILL_SCORE_ENT, szAttackerName, COLOR_WHITE, COLOR_KILL_SCORE_ENT, szKilledName, COLOR_WHITE, COLOR_KILL_SCORE_ENT, szInflictorClass, COLOR_MURDER, szSavedNameColor, szSavedName); - pClient.ModifyScore(iPointsToAward); - - // Loop through clients, printing in chat the amount of damage each player inflicted to this NPC. - float[] attackers = new float[MaxClients + 1]; - float fTotalDamage = 0.0; - lNpcDamageTracker.GetArray(pKilled.GetEntIndex(), attackers); - - // Gotta calculate the damage total first to see if it's worthy of being broadcast in chat... - for (int iClientIndex = 0; iClientIndex <= MaxClients; iClientIndex++) - { - float fDamageInflicted = attackers[iClientIndex]; - CBasePlayer pDamagerDealer = CBasePlayer(iClientIndex); - if (!pDamagerDealer.IsValid() || fDamageInflicted <= 0) - continue; - fTotalDamage += fDamageInflicted; - } - - for (int iClientIndex = 0; iClientIndex <= MaxClients; iClientIndex++) - { - float fDamageInflicted = attackers[iClientIndex]; - CBasePlayer pDamagerDealer = CBasePlayer(iClientIndex); - if (!pDamagerDealer.IsValid() || fDamageInflicted <= 0) - continue; - - char szDmgDealerName[32]; - pDamagerDealer.GetName(szDmgDealerName, sizeof(szDmgDealerName)); - - // Damage combo - - float fPlrDmgLast; - - if (!GetTrieValue(hDmgTrie, szDmgDealerName, fPlrDmgLast)) - fPlrDmgLast = 0.0; - - float fNewDmgCombo = fPlrDmgLast + fDamageInflicted; - - if (GetCookieBool(pKillfeedEnabledCookie, iClientIndex)) - PrintCenterText(iClientIndex, "COMBO +%.0f (%.0f)", fDamageInflicted, fNewDmgCombo); - - if (fTotalDamage >= 100) - PrintToChatKillfeed("%s%s%s dealt %s%.0f%s damage.", COLOR_KILL_SCORE_ENT, szDmgDealerName, COLOR_WHITE, COLOR_MURDER, fDamageInflicted, COLOR_MURDER_VICTIM); - - // Add damage to combo, reset combo counter to 6000 ms - SetTrieValue(hDmgTrie, szDmgDealerName, fNewDmgCombo); - SetTrieValue(hComboTimeTrie, szDmgDealerName, 6000); - } - } - } - } - else if (pAttacker.IsClassNPC()) - { - if (pKilled.IsClassPlayer()) - { - // An NPC killed a player... - CBasePlayer pClient = view_as(pKilled.GetEntIndex()); - pClient.GetName(szKilledName, sizeof(szKilledName)); - EntityNameFix(szAttackerName); - - char szMessage[254]; - StrCat(szMessage, sizeof(szMessage), "%s%s%s was killed by %s%s"); - - if (strcmp(szAttackerName, szInflictorClass, false) != 0) - StrCat(szMessage, sizeof(szMessage), "%s with %s%s"); - - PrintToChatKillfeed(szMessage, COLOR_CRIMSON, szKilledName, COLOR_WHITE, COLOR_CRIMSON, szAttackerName, COLOR_WHITE, COLOR_CRIMSON, szInflictorClass); - } - } -} - -// Taken from basechat.sp -void SendDialogToOne(int iClientIndex, int iRed, int iGreen, int iBlue, const char[] szText, any ...) -{ - char szMessage[100]; - VFormat(szMessage, sizeof(szMessage), szText, 6); - - KeyValues kv = new KeyValues("Stuff", "title", szMessage); - kv.SetColor("color", iRed, iGreen, iBlue, 255); - kv.SetNum("level", 1); - kv.SetNum("time", 10); - - CreateDialog(iClientIndex, kv, DialogType_Msg); - - delete kv; -} - -// Adaptation of PrintToChatAll with killfeed enable check -void PrintToChatKillfeed(const char[] format, any ...) -{ - char buffer[254]; - - for (int i = 1; i <= MaxClients; i++) - { - if (IsClientInGame(i) && GetCookieBool(pKillfeedEnabledCookie, i)) - { - SetGlobalTransTarget(i); - VFormat(buffer, sizeof(buffer), format, 2); - PrintToChat(i, "%s", buffer); - } - } -} - -public void OnEntityCreated(int iEntIndex, const char[] szClassname) -{ - CBaseEntity pEntity = CBaseEntity(iEntIndex); - if (pEntity.IsClassNPC()) - { - float[] clients = new float[MaxClients + 1]; - for (int iClientIndex = 0; iClientIndex <= MaxClients; iClientIndex++) - { - clients[iClientIndex] = 0.0; - } - - // Each NPC needs an array of damage that clients have done to them - lNpcDamageTracker.SetArray(iEntIndex, clients); - - // Hook NPC damage - SDKHook(iEntIndex, SDKHook_OnTakeDamage, Hook_OnNpcTakeDamage); - } -} - -public void InitComboTracker() -{ - if (hDmgTimer == null) - { - lNpcDamageTracker = CreateArray(MaxClients + 1, GetMaxEntities()); - hDmgTimer = CreateTimer(0.1, Timer_DamageUpdate, _, TIMER_REPEAT); - hDmgTrie = new StringMap(); - hComboTimeTrie = new StringMap(); - } -} - -public Action Timer_DamageUpdate(Handle hTimer) -{ - for (int iClientIndex = 0; iClientIndex <= MaxClients; iClientIndex++) - { - CBasePlayer pPlayer = CBasePlayer(iClientIndex); - if (!pPlayer.IsValid()) - continue; - - char szPlayerName[32]; - pPlayer.GetName(szPlayerName, sizeof(szPlayerName)); - - int iComboMsLeft = 0; - float fDamageDone = 0.0; - - bool bPlayerHasCombo = GetTrieValue(hDmgTrie, szPlayerName, fDamageDone) && - GetTrieValue(hComboTimeTrie, szPlayerName, iComboMsLeft); - - if (bPlayerHasCombo) - { - // subtract 100ms from timer - iComboMsLeft -= 100; - SetTrieValue(hComboTimeTrie, szPlayerName, iComboMsLeft); - if (fDamageDone <= 0) - continue; - - // Timer is up! - if (iComboMsLeft <= 0) - { - // Reset combo back to zero and notify player of their final combo - SetTrieValue(hDmgTrie, szPlayerName, 0.0); - - - // Calculate bonus score for combo - float fDmgMinus100Clamped = fDamageDone - 100.0 > 0.0 ? fDamageDone - 100.0 : 0.0; - int iScoreToGive = RoundFloat(Pow(fDmgMinus100Clamped/60.0,1.25)); - bool bMaxCombo = false; - - // Clamp max score to MAX_COMBO (in case of obscene combo bonuses) - if (iScoreToGive >= MAX_COMBO) - { - iScoreToGive = MAX_COMBO; - bMaxCombo = true; - } - - if (GetCookieBool(pKillfeedEnabledCookie, iClientIndex)) - { - if (iScoreToGive > 0) - { - SendDialogToOne(iClientIndex, 255, 50, 50, "Bonus Points +%d", iScoreToGive); - PrintToChat(iClientIndex, "%sFinal Combo: %s(%.0f Dmg for +%d Points)%s!", - COLOR_WHITE, COLOR_KILL_SCORE_ENT, fDamageDone, iScoreToGive, COLOR_WHITE); - if (bMaxCombo) - PrintCenterText(iClientIndex, "MAXIMUM COMBO COMPLETE"); - else - PrintCenterText(iClientIndex, "COMBO COMPLETE"); - } - else - { - PrintCenterText(iClientIndex, "COMBO OVER"); - } - } - - pPlayer.ModifyScore(iScoreToGive); - - if (fDamageDone >= 400) - { - if (bMaxCombo) - PrintToChatKillfeed("%s%s%s GOT A MAX COMBO OF %s%.0f%s DAMAGE! GRANTING THEM A SCORE BONUS OF %s%d", - COLOR_KILL_SCORE_ENT, szPlayerName, COLOR_MURDER, COLOR_KILL_SCORE_ENT, fDamageDone, COLOR_MURDER, COLOR_KILL_SCORE_ENT, iScoreToGive); - else - PrintToChatKillfeed("%s%s%s GOT A %s%.0f%s DAMAGE COMBO! GRANTING THEM A SCORE BONUS OF %s%d", - COLOR_KILL_SCORE_ENT, szPlayerName, COLOR_MURDER, COLOR_KILL_SCORE_ENT, fDamageDone, COLOR_MURDER, COLOR_KILL_SCORE_ENT, iScoreToGive); - } - - } - } - } - return Plugin_Continue; -} - -public Action Hook_OnNpcTakeDamage(int iVictim, int &iAttacker, int &iInflictor, float &fDamage, int &iDamageType, int &iWeapon, float vfDamageForce[3], float vfDamagePosition[3]) -{ - CBaseEntity pAttacker = CBaseEntity(iAttacker); - - // If the damage was done by a player, add it to the NPC's damage list - if (pAttacker.IsClassPlayer()) - { - float[] attackers = new float[MaxClients + 1]; - lNpcDamageTracker.GetArray(iVictim, attackers); - - float fDamageToAward = fDamage; - - // DOESNT WORK: - // CBaseCombatCharacter pVictim = CBaseCombatCharacter(iVictim); - // int iHealth = pVictim.GetHealth(); - - // WORKAROUND: - int iHealth = GetEntProp(iVictim, Prop_Data, "m_iHealth", 1); - - // Prevent overkill damage from being recorded - if (fDamage > iHealth) - fDamageToAward = float(iHealth); - - // No negative damage - if (fDamageToAward <= 0) - fDamageToAward = 0.0; - - // Cap the max damage awarded from any given source to prevent obscene numbers due to edge cases - if (fDamageToAward > MAX_DAMAGE_AWARDED_PER_HIT) - fDamageToAward = MAX_DAMAGE_AWARDED_PER_HIT; - - attackers[iAttacker] += fDamageToAward; - - lNpcDamageTracker.SetArray(iVictim, attackers); - } - - return Plugin_Continue; -} \ No newline at end of file +*/ \ No newline at end of file diff --git a/scripts/srccoop-bms-linux-install.sh b/scripts/srccoop-bms-linux-install.sh index 50eba210..3e869ac1 100644 --- a/scripts/srccoop-bms-linux-install.sh +++ b/scripts/srccoop-bms-linux-install.sh @@ -27,7 +27,7 @@ wget $(wget -qO- "https://www.sourcemm.net/downloads.php" | grep "