amxmodx/dlls/tfc/tfcx/usermsg.cpp
2004-06-25 12:21:47 +00:00

330 lines
8.4 KiB
C++
Executable File

/*
* TFCX
* Copyright (c) 2004 Lukasz Wlasinski
*
*
* 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 "amxxmodule.h"
#include "tfcx.h"
int damage;
int TA;
int weapon;
int aim;
CPlayer *pAttacker;
edict_t* tempEnt;
int tempInt;
bool ignoreDamage = false;
void Client_ResetHUD(void* mValue){
if ( mPlayer ){
mPlayer->clearStats = gpGlobals->time + 0.25f;
}
}
/*
void Client_WeaponList(void* mValue){
static int wpnList;
static int iSlot;
static const char* wpnName;
switch (mState++) {
case 0:
wpnName = (const char*)mValue;
break;
case 1:
iSlot = *(int*)mValue;
break;
case 7:
int iId = *(int*)mValue;
if ( (iId < 0 || iId >= MAX_WEAPONS ) || ( wpnList & (1<<iId) ) )
break;
wpnList |= (1<<iId);
weaponData[iId].ammoSlot = iSlot;
strcpy(weaponData[iId].fullName, wpnName );
weaponData[iId].name = weaponData[iId].fullName;
char* wpnPrefix = strstr( weaponData[iId].fullName ,"tf_weapon_");
if ( wpnPrefix )
weaponData[iId].name = wpnPrefix + 10;
}
}
*/
void Client_Damage(void* mValue){
switch (mState++) {
case 1:
damage = *(int*)mValue;
break;
case 2:
edict_t* enemy;
if ( !mPlayer || !damage )
break;
enemy = mPlayer->pEdict->v.dmg_inflictor;
if ( FNullEnt( enemy ) )
break;
if (enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT) ) { // attacker is player and his active weapon
pAttacker = GET_PLAYER_POINTER(enemy);
aim = pAttacker->aiming;
weapon = pAttacker->current;
switch(weapon){
case TFC_WPN_SPANNER:
case TFC_WPN_AXE:
case TFC_WPN_KNIFE:
pAttacker->saveShot(weapon); // melee , save shot too
break;
case TFC_WPN_MEDIKIT:
if ( pAttacker->teamId == mPlayer->teamId ) // ???
ignoreDamage = true;
pAttacker->saveShot(weapon); // melee , save shot too
break;
}
pAttacker->saveHit( mPlayer , weapon , damage, aim);
}
else if ( !FNullEnt( enemy->v.owner ) ){
if ( enemy->v.owner->v.flags & (FL_CLIENT | FL_FAKECLIENT) ){ // caltrop, empgrenade, gasgrenade, napalmgrenade
pAttacker = GET_PLAYER_POINTER(enemy->v.owner);
const char *szClass = STRING(enemy->v.classname);
switch(szClass[10]){
case 'c':
weapon = TFC_WPN_CALTROP;
break;
case 'e':
weapon = TFC_WPN_EMPGRENADE;
break;
case 'g':
weapon = TFC_WPN_GASGRENADE;
break;
case 'm':
weapon = TFC_WPN_MEDIKIT;
if ( pAttacker->teamId == mPlayer->teamId ) // ???
ignoreDamage = true;
pAttacker->saveShot(weapon);
break;
case 'n':
weapon = TFC_WPN_NAPALMGRENADE;
break;
case 'a':
case 's':
case '_': // hmm...nailgun_nail, fastswitch and this one may not be true...
//PRINT_CONSOLE("Nail! Class:%d wpn:%d\n",pAttacker->classId,pAttacker->current);
weapon = pAttacker->current;
break;
case 'r':
weapon = TFC_WPN_FLAMETHROWER;
break;
}
if ( !weapon ) {
switch(szClass[3]){
case 'e':
weapon = TFC_WPN_TIMER; // TFC_WPN_MEDKIT ??
tempInt = *( (int*)mPlayer->pEdict->pvPrivateData + pdTimerOwner );
if (!tempInt)
break;
tempEnt = (edict_t*)tempInt;
pAttacker = GET_PLAYER_POINTER(tempEnt);
if ( pAttacker->teamId == mPlayer->teamId ) // ???
ignoreDamage = true;
pAttacker->saveShot(weapon); // ??? save shot too
break;
case 'f':
weapon = TFC_WPN_FLAMES; // tf_fire
break;
}
}
if ( weapon )
pAttacker->saveHit( mPlayer , weapon , damage, aim );
//else
// PRINT_CONSOLE("*** DMG! Att:%d Vic:%d unknown weapon %s\n",pAttacker->index,mPlayer->index,STRING(enemy->v.classname));
}
// nailgrenadenail->nailgrenade->player :))) I'm the best !
else if ( !FNullEnt(enemy->v.owner->v.owner) && enemy->v.owner->v.owner->v.flags & (FL_CLIENT | FL_FAKECLIENT ) ){
pAttacker = GET_PLAYER_POINTER(enemy->v.owner->v.owner);
weapon = TFC_WPN_NAILGRENADE;
pAttacker->saveHit( mPlayer , weapon , damage, aim );
}
}
else { // nailgrenade , mirvgrenade , normalgrenade , rockets
if ( strstr("sentrygun",STRING(enemy->v.classname)) ){
tempInt = *( (int*)enemy->pvPrivateData + pdSentryGunOwner );
if ( !tempInt )
break;
tempEnt = (edict_t*)tempInt;
pAttacker = GET_PLAYER_POINTER(tempEnt);
weapon = TFC_WPN_SENTRYGUN;
pAttacker->saveShot(weapon); // save shot too
pAttacker->saveHit( mPlayer , weapon , damage, aim );
}
else if( g_grenades.find(enemy , &pAttacker , &weapon ) ){
if ( weapon == TFC_WPN_RPG && pAttacker->classId == TFC_PC_PYRO ){
weapon = TFC_WPN_IC;
pAttacker->saveShot(weapon);
}
pAttacker->saveHit( mPlayer , weapon , damage, aim );
}
}
break;
}
}
void Client_Damage_End(void* mValue){
if ( !damage )
return;
if ( !pAttacker )
pAttacker = mPlayer;
if ( !ignoreDamage ){
TA = 0;
if ( (mPlayer->teamId == pAttacker->teamId) && (mPlayer != pAttacker) )
TA = 1;
MF_ExecuteForward ( iFDamage, pAttacker->index, mPlayer->index, damage, weapon, aim, TA );
if( !mPlayer->IsAlive() ){
pAttacker->saveKill(mPlayer,weapon,( aim == 1 ) ? 1:0 ,TA);
MF_ExecuteForward ( iFDeath, pAttacker->index, mPlayer->index, weapon, aim, TA );
}
}
damage = 0;
aim = 0;
weapon = 0;
pAttacker = NULL;
ignoreDamage = false;
}
void Client_CurWeapon(void* mValue){
static int iState;
static int iId;
switch (mState++){
case 0:
iState = *(int*)mValue;
break;
case 1:
if (!iState) break;
iId = *(int*)mValue;
break;
case 2:
if (!mPlayer || !iState ) break;
int iClip = *(int*)mValue;
if ((iClip > -1) && (iClip < mPlayer->weapons[iId].clip)){
mPlayer->saveShot(iId);
}
mPlayer->weapons[iId].clip = iClip;
mPlayer->current = iId;
}
}
void Client_AmmoX(void* mValue){
static int iAmmo;
switch (mState++){
case 0:
iAmmo = *(int*)mValue;
break;
case 1:
if (!mPlayer ) break;
// SniperRifle, AC and AutoRifle ...
if ( mPlayer->classId == TFC_PC_HWGUY ){
if ( mPlayer->current == TFC_WPN_AC && mPlayer->weapons[mPlayer->current].ammo > *(int*)mValue && iAmmo == weaponData[mPlayer->current].ammoSlot )
mPlayer->saveShot(mPlayer->current);
}
else if ( mPlayer->classId == TFC_PC_SNIPER ){
if ( (mPlayer->current == TFC_WPN_SNIPERRIFLE || mPlayer->current == TFC_WPN_AUTORIFLE) && mPlayer->weapons[mPlayer->current].ammo > *(int*)mValue && iAmmo == weaponData[mPlayer->current].ammoSlot )
mPlayer->saveShot(mPlayer->current);
}
//
for(int i = 1; i < MAX_WEAPONS ; ++i)
if (iAmmo == weaponData[i].ammoSlot)
mPlayer->weapons[i].ammo = *(int*)mValue;
}
}
void Client_AmmoPickup(void* mValue){
static int iSlot;
switch (mState++){
case 0:
iSlot = *(int*)mValue;
break;
case 1:
if (!mPlayer ) break;
for(int i = 1; i < MAX_WEAPONS ; ++i)
if (weaponData[i].ammoSlot == iSlot)
mPlayer->weapons[i].ammo += *(int*)mValue;
}
}
void Client_ScoreInfo(void* mValue){
static int iIndex;
static int iClass;
switch (mState++){
case 0:
iIndex = *(int*)mValue;
break;
case 3:
iClass = *(int*)mValue;
break;
case 4:
if ( iIndex > 0 && iIndex <= gpGlobals->maxClients ){
GET_PLAYER_POINTER_I( iIndex )->teamId = *(int*)mValue;
GET_PLAYER_POINTER_I( iIndex )->classId = iClass;
}
}
}