amxmodx/dlls/sven/moduleconfig.cpp
2007-03-13 18:44:23 +00:00

345 lines
15 KiB
C++

/* AMX Mod X
* Sven Co-op Module
*
* by the AMX Mod X Development Team
*
* This file is part of AMX Mod X.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "svencoop.h"
//
// EXTERNS
//
int gmsgScoreInfo;
KeyValueData g_kvd;
Trie<char,String> g_allyNameTrie, g_enemyNameTrie;
//
// GLOBALS
//
int g_lastDeadflag[33] = { 0 }, g_grenadeCount = 0,
g_spawnFwd = -1, g_healFwd = -1, g_grenadeFwd = -1;
edict_t *g_grenadeList[32] = { NULL };
//
// AMXX HOOKS
//
void OnAmxxAttach()
{
MF_AddNatives(svencoop_Exports);
// sc_set_displayname
g_kvd.szClassName = "";
g_kvd.szKeyName = "";
g_kvd.szValue = "";
g_kvd.fHandled = 0;
// sc_get_displayname, default displaynames
g_allyNameTrie.Insert("monster_alien_babyvoltigore", 27, String("Friendly Baby Voltigore"));
g_enemyNameTrie.Insert("monster_alien_babyvoltigore", 27, String("Baby Voltigore"));
g_allyNameTrie.Insert("monster_alien_controller", 24, String("Friendly Alien Controller"));
g_enemyNameTrie.Insert("monster_alien_controller", 24, String("Alien Controller"));
g_allyNameTrie.Insert("monster_alien_grunt", 19, String("Friendly Alien Grunt"));
g_enemyNameTrie.Insert("monster_alien_grunt", 19, String("Alien Grunt"));
g_allyNameTrie.Insert("monster_alien_slave", 19, String("Friendly Alien Slave"));
g_enemyNameTrie.Insert("monster_alien_slave", 19, String("Alien Slave"));
g_allyNameTrie.Insert("monster_vortigaunt", 18, String("Friendly Alien Slave"));
g_enemyNameTrie.Insert("monster_vortigaunt", 18, String("Alien Slave"));
g_allyNameTrie.Insert("monster_alien_voltigore", 23, String("Friendly Voltigore"));
g_enemyNameTrie.Insert("monster_alien_voltigore", 23, String("Voltigore"));
g_allyNameTrie.Insert("monster_apache", 14, String("Apache"));
g_enemyNameTrie.Insert("monster_apache", 14, String("Apache"));
g_allyNameTrie.Insert("monster_blkop_apache", 20, String("Apache"));
g_enemyNameTrie.Insert("monster_blkop_apache", 20, String("Apache"));
g_allyNameTrie.Insert("monster_assassin_repel", 22, String("Friendly Male Assassin"));
g_enemyNameTrie.Insert("monster_assassin_repel", 22, String("Male Assassin"));
g_allyNameTrie.Insert("monster_male_assassin", 21, String("Friendly Male Assassin"));
g_enemyNameTrie.Insert("monster_male_assassin", 21, String("Male Assassin"));
g_allyNameTrie.Insert("monster_babycrab", 16, String("Friendly Head Crab"));
g_enemyNameTrie.Insert("monster_babycrab", 16, String("Head Crab"));
g_allyNameTrie.Insert("monster_headcrab", 16, String("Friendly Head Crab"));
g_enemyNameTrie.Insert("monster_headcrab", 16, String("Head Crab"));
g_allyNameTrie.Insert("monster_babygarg", 16, String("Friendly Baby Gargantua"));
g_enemyNameTrie.Insert("monster_babygarg", 16, String("Baby Gargantua"));
g_allyNameTrie.Insert("monster_barnacle", 16, String("Barnacle"));
g_enemyNameTrie.Insert("monster_barnacle", 16, String("Barnacle"));
g_allyNameTrie.Insert("monster_barney", 14, String("Barney"));
g_enemyNameTrie.Insert("monster_barney", 14, String("Barnabus"));
g_allyNameTrie.Insert("monster_bigmomma", 16, String("Friendly Big Momma"));
g_enemyNameTrie.Insert("monster_bigmomma", 16, String("Big Momma"));
g_allyNameTrie.Insert("monster_blkop_osprey", 20, String("Friendly Black Ops Osprey"));
g_enemyNameTrie.Insert("monster_blkop_osprey", 20, String("Black Ops Osprey"));
g_allyNameTrie.Insert("monster_bloater", 15, String("Friendly Bloater"));
g_enemyNameTrie.Insert("monster_bloater", 15, String("Bloater"));
g_allyNameTrie.Insert("monster_bullchicken", 19, String("Friendly Bull Squid"));
g_enemyNameTrie.Insert("monster_bullchicken", 19, String("Bull Squid"));
g_allyNameTrie.Insert("monster_chumtoad", 16, String("Chubby"));
g_enemyNameTrie.Insert("monster_chumtoad", 16, String("Chumtoad"));
g_allyNameTrie.Insert("monster_cleansuit_scientist", 27, String("Cleansuit Scientist"));
g_enemyNameTrie.Insert("monster_cleansuit_scientist", 27, String("Cleansuit Scientist"));
g_allyNameTrie.Insert("monster_cockroach", 17, String("Roach"));
g_enemyNameTrie.Insert("monster_cockroach", 17, String("Roach"));
g_allyNameTrie.Insert("monster_gargantua", 17, String("Friendly Gargantua"));
g_enemyNameTrie.Insert("monster_gargantua", 17, String("Gargantua"));
g_allyNameTrie.Insert("monster_gman", 12, String("Government Man"));
g_enemyNameTrie.Insert("monster_gman", 12, String("Government Man"));
g_allyNameTrie.Insert("monster_gonome", 14, String("Friendly Gonome"));
g_enemyNameTrie.Insert("monster_gonome", 14, String("Gonome"));
g_allyNameTrie.Insert("monster_houndeye", 16, String("Friendly Hound Eye"));
g_enemyNameTrie.Insert("monster_houndeye", 16, String("Hound Eye"));
g_allyNameTrie.Insert("monster_human_assassin", 22, String("Friendly Female Assassin"));
g_enemyNameTrie.Insert("monster_human_assassin", 22, String("Female Assassin"));
g_allyNameTrie.Insert("monster_human_grunt", 19, String("Friendly Human Grunt"));
g_enemyNameTrie.Insert("monster_human_grunt", 19, String("Human Grunt"));
g_allyNameTrie.Insert("monster_grunt_repel", 19, String("Friendly Human Grunt"));
g_enemyNameTrie.Insert("monster_grunt_repel", 19, String("Human Grunt"));
g_allyNameTrie.Insert("monster_human_grunt_ally", 24, String("Ally Grunt"));
g_enemyNameTrie.Insert("monster_human_grunt_ally", 24, String("Enemy Grunt"));
g_allyNameTrie.Insert("monster_grunt_ally_repel", 24, String("Ally Grunt"));
g_enemyNameTrie.Insert("monster_grunt_ally_repel", 24, String("Enemy Grunt"));
g_allyNameTrie.Insert("monster_human_medic_ally", 24, String("Medic Grunt"));
g_enemyNameTrie.Insert("monster_human_medic_ally", 24, String("Enemy Medic Grunt"));
g_allyNameTrie.Insert("monster_medic_ally_repel", 24, String("Medic Grunt"));
g_enemyNameTrie.Insert("monster_medic_ally_repel", 24, String("Enemy Medic Grunt"));
g_allyNameTrie.Insert("monster_human_torch_ally", 24, String("Torch Grunt"));
g_enemyNameTrie.Insert("monster_human_torch_ally", 24, String("Enemy Torch Grunt"));
g_allyNameTrie.Insert("monster_torch_ally_repel", 24, String("Torch Grunt"));
g_enemyNameTrie.Insert("monster_torch_ally_repel", 24, String("Enemy Torch Grunt"));
g_allyNameTrie.Insert("monster_hwgrunt", 15, String("Friendly Heavy Weapons Grunt"));
g_enemyNameTrie.Insert("monster_hwgrunt", 15, String("Heavy Weapons Grunt"));
g_allyNameTrie.Insert("monster_hwgrunt_repel", 21, String("Friendly Heavy Weapons Grunt"));
g_enemyNameTrie.Insert("monster_hwgrunt_repel", 21, String("Heavy Weapons Grunt"));
g_allyNameTrie.Insert("monster_ichthyosaur", 19, String("Friendly Ichthyosaur"));
g_enemyNameTrie.Insert("monster_ichthyosaur", 19, String("Ichthyosaur"));
g_allyNameTrie.Insert("monster_leech", 13, String("Leech"));
g_enemyNameTrie.Insert("monster_leech", 13, String("Leech"));
g_allyNameTrie.Insert("monster_miniturret", 18, String("Mini-Turret"));
g_enemyNameTrie.Insert("monster_miniturret", 18, String("Mini-Turret"));
g_allyNameTrie.Insert("monster_nihilanth", 17, String(""));
g_enemyNameTrie.Insert("monster_nihilanth", 17, String(""));
g_allyNameTrie.Insert("monster_osprey", 14, String("Friendly Osprey Helicopter"));
g_enemyNameTrie.Insert("monster_osprey", 14, String("Osprey Helicopter"));
g_allyNameTrie.Insert("monster_otis", 12, String("Otis"));
g_enemyNameTrie.Insert("monster_otis", 12, String("Enemy Otis"));
g_allyNameTrie.Insert("monster_pitdrone", 16, String("Friendly Pit Drone"));
g_enemyNameTrie.Insert("monster_pitdrone", 16, String("Pit Drone"));
g_allyNameTrie.Insert("monster_rat", 11, String("Rat"));
g_enemyNameTrie.Insert("monster_rat", 11, String("Rat"));
g_allyNameTrie.Insert("monster_robogrunt", 17, String("Friendly Robo Grunt"));
g_enemyNameTrie.Insert("monster_robogrunt", 17, String("Robo Grunt"));
g_allyNameTrie.Insert("monster_robogrunt_repel", 23, String("Friendly Robo Grunt"));
g_enemyNameTrie.Insert("monster_robogrunt_repel", 23, String("Robo Grunt"));
g_allyNameTrie.Insert("monster_scientist", 17, String("Scientist"));
g_enemyNameTrie.Insert("monster_scientist", 17, String("Scientist"));
g_allyNameTrie.Insert("monster_sitting_scientist", 25, String("Scientist"));
g_enemyNameTrie.Insert("monster_sitting_scientist", 25, String("Scientist"));
g_allyNameTrie.Insert("monster_sentry", 14, String("Sentry Turret"));
g_enemyNameTrie.Insert("monster_sentry", 14, String("Sentry Turret"));
g_allyNameTrie.Insert("monster_shockroach", 18, String("Friendly Shock Roach"));
g_enemyNameTrie.Insert("monster_shockroach", 18, String("Shock Roach"));
g_allyNameTrie.Insert("monster_shocktrooper", 20, String("Friendly Shock Trooper"));
g_enemyNameTrie.Insert("monster_shocktrooper", 20, String("Shock Trooper"));
g_allyNameTrie.Insert("monster_snark", 13, String("Snark"));
g_enemyNameTrie.Insert("monster_snark", 13, String("Snark"));
g_allyNameTrie.Insert("monster_tentacle", 16, String("Tentacle"));
g_enemyNameTrie.Insert("monster_tentacle", 16, String("Tentacle"));
g_allyNameTrie.Insert("monster_tentaclemaw", 19, String("Tentacle"));
g_enemyNameTrie.Insert("monster_tentaclemaw", 19, String("Tentacle"));
g_allyNameTrie.Insert("monster_turret", 14, String("Turret"));
g_enemyNameTrie.Insert("monster_turret", 14, String("Turret"));
g_allyNameTrie.Insert("monster_zombie", 14, String("Friendly Zombie"));
g_enemyNameTrie.Insert("monster_zombie", 14, String("Zombie"));
g_allyNameTrie.Insert("monster_zombie_barney", 21, String("Friendly Zombie Barney"));
g_enemyNameTrie.Insert("monster_zombie_barney", 21, String("Zombie Barney"));
g_allyNameTrie.Insert("monster_zombie_soldier", 22, String("Friendly Zombie Soldier"));
g_enemyNameTrie.Insert("monster_zombie_soldier", 22, String("Zombie Soldier"));
}
void OnPluginsLoaded()
{
g_spawnFwd = MF_RegisterForward("sc_client_spawn", ET_IGNORE, FP_CELL, FP_DONE);
g_healFwd = MF_RegisterForward("sc_client_heal", ET_IGNORE, FP_CELL, FP_CELL, FP_FLOAT, FP_CELL, FP_CELL, FP_DONE);
g_grenadeFwd = MF_RegisterForward("sc_grenade_throw", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
}
//
// METAMOD HOOKS
//
/***GetEntityAPI2******************/
// sc_client_heal
void DispatchThink(edict_t *pEntity)
{
if(g_healFwd != -1 && UTIL_IsMonster(pEntity))
*((float *)pEntity->pvPrivateData + OFFSET_LAST_HEALTH) = pEntity->v.health;
RETURN_META(MRES_IGNORED);
}
// sc_get_displayname
void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
{
// catch displayname and store it ourselves for our native
// TODO: store this somewhere else besides in the pev
if(FStrEq(pkvd->szKeyName, "displayname"))
pentKeyvalue->v.message = ALLOC_STRING(pkvd->szValue);
RETURN_META(MRES_IGNORED);
}
// sc_client_spawn
void ClientPutInServer(edict_t *pPlayer)
{
g_lastDeadflag[ENTINDEX(pPlayer)] = -1;
RETURN_META(MRES_IGNORED);
}
// sc_client_spawn / sc_client_heal
void PlayerPreThink(edict_t *pPlayer)
{
if(g_spawnFwd != -1)
{
int index = ENTINDEX(pPlayer);
if(g_lastDeadflag[index] == -1 || (g_lastDeadflag[index] != DEAD_NO && pPlayer->v.deadflag == DEAD_NO))
MF_ExecuteForward(g_spawnFwd, index);
g_lastDeadflag[index] = pPlayer->v.deadflag;
}
if(g_healFwd != -1)
*((float *)pPlayer->pvPrivateData + OFFSET_LAST_HEALTH) = pPlayer->v.health;
RETURN_META(MRES_IGNORED);
}
// sc_grenade_throw
void StartFrame()
{
if(g_grenadeFwd == -1 || !g_grenadeCount)
RETURN_META(MRES_IGNORED);
edict_t *pGrenade = g_grenadeList[0];
if(!FNullEnt(pGrenade) && pGrenade->v.owner)
{
const char *model = STRING(pGrenade->v.model);
int wId = 0;
switch(model[7])
{
case 'g': wId = SCW_ARGRENADE; break; // models/grenade.mdl
case 'w': wId = SCW_HANDGRENADE; break; // models/w_grenade.mdl
//case 'c': wId = SCW_BANANA; break; // models/cretegibs.mdl
}
if(wId) MF_ExecuteForward(g_grenadeFwd, ENTINDEX(pGrenade->v.owner),
ENTINDEX(pGrenade), wId, UTIL_IsPlayer(pGrenade->v.owner));
}
// shift the list
g_grenadeList[0] = NULL;
if(--g_grenadeCount)
{
for(int i=1;i<=g_grenadeCount;i++) g_grenadeList[i-1] = g_grenadeList[i];
g_grenadeList[g_grenadeCount] = NULL;
}
RETURN_META(MRES_IGNORED);
}
/***GetEntityAPI2_Post*************/
// sc_set_frags
void ServerActivate_Post(struct edict_s *, int, int)
{
gmsgScoreInfo = GET_USER_MSG_ID(PLID, "ScoreInfo", NULL);
RETURN_META(MRES_IGNORED);
}
/***GetEngineAPI*******************/
// sc_client_heal
void EmitSound(edict_t *pEntity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch)
{
if(g_healFwd == -1 || !UTIL_IsPlayer(pEntity) || channel != CHAN_WEAPON || strcmp(sample, "items/medshot4.wav") != 0)
RETURN_META(MRES_IGNORED);
Vector trStart = pEntity->v.origin;
if(pEntity->v.flags & FL_DUCKING) trStart.z += 12.0;
else trStart.z += 28.0;
Vector trEnd = trStart + gpGlobals->v_forward * 32;
TraceResult tr;
TRACE_LINE(trStart, trEnd, dont_ignore_monsters, pEntity, &tr);
if(tr.flFraction == 1.0)
TRACE_HULL(trStart, trEnd, dont_ignore_monsters, head_hull, pEntity, &tr);
if(!FNullEnt(tr.pHit))
{
float amount = tr.pHit->v.health - *((float *)tr.pHit->pvPrivateData + OFFSET_LAST_HEALTH);
if(UTIL_IsPlayer(tr.pHit))
MF_ExecuteForward(g_healFwd, ENTINDEX(pEntity), ENTINDEX(tr.pHit), amount, 1, 1);
else if(UTIL_IsMonster(tr.pHit))
MF_ExecuteForward(g_healFwd, ENTINDEX(pEntity), ENTINDEX(tr.pHit), amount, 0, *((int *)tr.pHit->pvPrivateData + OFFSET_MONSTER_ALLY));
}
RETURN_META(MRES_IGNORED);
}
/***GetEngineAPI_Post**************/
// sc_grenade_throw
void SetModel_Post(edict_t *pEntity, const char *model)
{
if(g_grenadeFwd == -1)
RETURN_META(MRES_IGNORED);
const char *classname = STRING(pEntity->v.classname);
if(!pEntity->v.owner && classname[0] == 'g' && classname[2] == 'e' && model[7] == 'g')
{
if(g_grenadeCount < sizeof g_grenadeList)
g_grenadeList[g_grenadeCount++] = pEntity;
}
RETURN_META(MRES_IGNORED);
}