*** empty log message ***

This commit is contained in:
Twilight Suzuka 2005-12-11 18:42:19 +00:00
parent 6aaf11f2a3
commit e50151343b
12 changed files with 1098 additions and 206 deletions

View File

@ -36,7 +36,8 @@
// class CPlayer
// *****************************************************
void CPlayer::Disconnect(){
void CPlayer::Disconnect()
{
if ( ignoreBots(pEdict) || !isModuleActive() ) // ignore if he is bot and bots rank is disabled or module is paused
return;
rank->updatePosition( &life );

View File

@ -36,11 +36,13 @@
// *****************************************************
// class Stats
// *****************************************************
Stats::Stats(){
Stats::Stats()
{
hits = shots = damage = hs = tks = kills = deaths = 0;
memset( bodyHits , 0 ,sizeof( bodyHits ) );
}
void Stats::commit(Stats* a){
void Stats::commit(Stats* a)
{
hits += a->hits;
shots += a->shots;
damage += a->damage;
@ -48,14 +50,14 @@ void Stats::commit(Stats* a){
tks += a->tks;
kills += a->kills;
deaths += a->deaths;
for(int i = 1; i < 8; ++i)
bodyHits[i] += a->bodyHits[i];
for(int i = 1; i < 8; ++i) bodyHits[i] += a->bodyHits[i];
}
// *****************************************************
// class RankSystem
// *****************************************************
RankSystem::RankStats::RankStats( const char* uu, const char* nn, RankSystem* pp ) {
RankSystem::RankStats::RankStats( const char* uu, const char* nn, RankSystem* pp )
{
name = 0;
namelen = 0;
unique = 0;
@ -67,77 +69,92 @@ RankSystem::RankStats::RankStats( const char* uu, const char* nn, RankSystem* pp
setName( nn );
setUnique( uu );
}
RankSystem::RankStats::~RankStats() {
delete[] name;
delete[] unique;
RankSystem::RankStats::~RankStats()
{
delete name;
delete unique;
--parent->rankNum;
}
void RankSystem::RankStats::setName( const char* nn ) {
void RankSystem::RankStats::setName( const char* nn )
{
delete[] name;
namelen = strlen(nn) + 1;
name = new char[namelen];
if ( name )
strcpy( name , nn );
else
namelen = 0;
if ( name ) strcpy( name , nn );
else namelen = 0;
}
void RankSystem::RankStats::setUnique( const char* nn ) {
delete[] unique;
void RankSystem::RankStats::setUnique( const char* nn )
{
delete unique;
uniquelen = strlen(nn) + 1;
unique = new char[uniquelen];
if ( unique )
strcpy( unique , nn );
else
uniquelen = 0;
if ( unique ) strcpy( unique , nn );
else uniquelen = 0;
}
RankSystem::RankSystem() {
RankSystem::RankSystem()
{
head = 0;
tail = 0;
rankNum = 0;
calc.code = 0;
}
RankSystem::~RankSystem() {
RankSystem::~RankSystem()
{
clear();
}
void RankSystem::put_before( RankStats* a, RankStats* ptr ){
void RankSystem::put_before( RankStats* a, RankStats* ptr )
{
a->next = ptr;
if ( ptr ){
if ( ptr )
{
a->prev = ptr->prev;
ptr->prev = a;
}
else{
else
{
a->prev = head;
head = a;
}
if ( a->prev ) a->prev->next = a;
else tail = a;
}
void RankSystem::put_after( RankStats* a, RankStats* ptr ) {
void RankSystem::put_after( RankStats* a, RankStats* ptr )
{
a->prev = ptr;
if ( ptr ){
if ( ptr )
{
a->next = ptr->next;
ptr->next = a;
}
else{
else
{
a->next = tail;
tail = a;
}
if ( a->next ) a->next->prev = a;
else head = a;
}
void RankSystem::unlink( RankStats* ptr ){
void RankSystem::unlink( RankStats* ptr )
{
if (ptr->prev) ptr->prev->next = ptr->next;
else tail = ptr->next;
if (ptr->next) ptr->next->prev = ptr->prev;
else head = ptr->prev;
}
void RankSystem::clear(){
while( tail ){
void RankSystem::clear()
{
while( tail )
{
head = tail->next;
delete tail;
tail = head;
@ -149,7 +166,8 @@ bool RankSystem::loadCalc(const char* filename, char* error)
if ((MF_LoadAmxScript(&calc.amx,&calc.code,filename,error,0)!=AMX_ERR_NONE)||
(MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr1, &calc.physAddr1)!=AMX_ERR_NONE)||
(MF_AmxAllot(&calc.amx, 8 , &calc.amxAddr2, &calc.physAddr2)!=AMX_ERR_NONE)||
(MF_AmxFindPublic(&calc.amx,"get_score",&calc.func)!=AMX_ERR_NONE)){
(MF_AmxFindPublic(&calc.amx,"get_score",&calc.func)!=AMX_ERR_NONE))
{
MF_PrintSrvConsole("Couldn't load plugin (file \"%s\")",filename);
MF_UnloadAmxScript(&calc.amx, &calc.code);
return false;
@ -167,14 +185,16 @@ RankSystem::RankStats* RankSystem::findEntryInRank(const char* unique, const cha
while ( a )
{
if ( strcmp( a->getUnique() ,unique ) == 0 )
return a;
if ( strcmp( a->getUnique() ,unique ) == 0 ) return a;
a = a->prev;
}
a = new RankStats( unique ,name,this );
if ( a == 0 ) return 0;
put_after( a , 0 );
return a;
}
@ -182,7 +202,8 @@ void RankSystem::updatePos( RankStats* rr , Stats* s )
{
rr->addStats( s );
if ( calc.code ) {
if ( calc.code )
{
calc.physAddr1[0] = rr->kills;
calc.physAddr1[1] = rr->deaths;
calc.physAddr1[2] = rr->hs;
@ -190,20 +211,25 @@ void RankSystem::updatePos( RankStats* rr , Stats* s )
calc.physAddr1[4] = rr->shots;
calc.physAddr1[5] = rr->hits;
calc.physAddr1[6] = rr->damage;
for(int i = 1; i < 8; ++i)
calc.physAddr2[i] = rr->bodyHits[i];
for(int i = 1; i < 8; ++i) calc.physAddr2[i] = rr->bodyHits[i];
cell result = 0;
int err;
MF_AmxPush(&calc.amx, calc.amxAddr2);
MF_AmxPush(&calc.amx, calc.amxAddr1);
if ((err = MF_AmxExec(&calc.amx,&result, calc.func)) != AMX_ERR_NONE)
MF_LogError(&calc.amx, err, "Fatal error calculating stats");
rr->score = result;
}
else rr->score = rr->kills - rr->deaths;
RankStats* aa = rr->next;
while ( aa && (aa->score <= rr->score) ) { // try to nominate
while ( aa && (aa->score <= rr->score) )
{ // try to nominate
rr->goUp();
aa->goDown();
aa = aa->next; // go to next rank
@ -216,12 +242,14 @@ void RankSystem::updatePos( RankStats* rr , Stats* s )
else
{
aa = rr->prev;
while ( aa && (aa->score > rr->score) ) { // go down
while ( aa && (aa->score > rr->score) )
{ // go down
rr->goDown();
aa->goUp();
aa = aa->prev; // go to prev rank
}
if ( aa != rr->prev ){
if ( aa != rr->prev )
{
unlink( rr );
put_after( rr, aa );
}

276
dlls/ts/tsx/MsgFunc.h Normal file
View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2003-2005 Twilight Suzuka
*
* This file is part of TSXMod.
*
* TS XMod 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.
*
* TS XMod 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 TS XMod; 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 "tsx.h"
void Client_ResetHUD_End(void* mValue)
{
if ( mPlayer->IsAlive() )
{
mPlayer->clearStats = gpGlobals->time + 0.25f;
}
else
{
mPlayer->items = 0;
mPlayer->is_specialist = 0;
mPlayer->killingSpree = 0;
mPlayer->killFlags = 0;
mPlayer->frags = (int)mPlayer->pEdict->v.frags;
}
}
void Client_ScoreInfo(void* mValue)
{
static int iId;
switch(mState++)
{
case 0:
iId = *(int*)mValue;
break;
case 4:
if ( iId && (iId < 33) )
{
GET_PLAYER_POINTER_I(iId)->teamId = *(int*)mValue;
}
break;
}
}
void Client_WeaponInfo(void* mValue)
{
static int wpn;
switch(mState++)
{
case 0:
wpn = *(int*)mValue;
if ( !wpn ) wpn = 36; // kung fu
mPlayer->current = wpn;
break;
case 1:
mPlayer->weapons[wpn].clip = *(int*)mValue;
break;
case 2:
mPlayer->weapons[wpn].ammo = *(int*)mValue;
break;
case 3:
mPlayer->weapons[wpn].mode = *(int*)mValue;
break;
case 4:
mPlayer->weapons[wpn].attach = *(int*)mValue;
break;
}
}
void Client_ClipInfo(void* mValue)
{
int iValue = *(int*)mValue;
if ( iValue < mPlayer->weapons[mPlayer->current].clip )
{
mPlayer->saveShot(mPlayer->current);
}
mPlayer->weapons[mPlayer->current].clip = iValue;
}
void Client_TSHealth_End(void* mValue)
{
edict_t *enemy = mPlayer->pEdict->v.dmg_inflictor;
int damage = (int)mPlayer->pEdict->v.dmg_take;
if ( !damage || !enemy ) return;
int aim = 0;
int weapon = 0;
mPlayer->pEdict->v.dmg_take = 0.0;
CPlayer* pAttacker = NULL;
if ( enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT) )
{
pAttacker = GET_PLAYER_POINTER(enemy);
weapon = pAttacker->current;
aim = pAttacker->aiming;
pAttacker->saveHit( mPlayer , weapon , damage, aim );
}
else
{
char szCName[16];
strcpy( szCName,STRING(enemy->v.classname) );
if ( szCName[0] == 'g' )
{
if ( enemy->v.owner && enemy->v.owner->v.flags & (FL_CLIENT | FL_FAKECLIENT) )
{
pAttacker = GET_PLAYER_POINTER(enemy->v.owner);
weapon = 24; // grenade
if ( pAttacker != mPlayer ) pAttacker->saveHit( mPlayer , weapon , damage, 0 );
}
}
else if ( szCName[0] == 'k' )
{
int pOwner = *( (int*)enemy->pvPrivateData + gKnifeOffset );
if ( FNullEnt( (edict_t*)pOwner) ) return;
pAttacker = GET_PLAYER_POINTER( (edict_t*)pOwner );
weapon = 37; // throwing knife
aim = pAttacker->aiming;
pAttacker->saveHit( mPlayer , weapon , damage, aim );
}
}
if ( !pAttacker ) pAttacker = mPlayer;
int TA = 0;
if ( mPlayer->teamId || is_theonemode )
{
if ( (mPlayer->teamId == pAttacker->teamId ) && (mPlayer != pAttacker) ) TA = 1;
}
if ( weaponData[weapon].melee ) pAttacker->saveShot(weapon);
MF_ExecuteForward(g_damage_info, pAttacker->index, mPlayer->index, damage, weapon, aim, TA );
if ( mPlayer->IsAlive() ) return;
// death
if ( (int)pAttacker->pEdict->v.frags - pAttacker->frags == 0 ) pAttacker = mPlayer;
int killFlags = 0;
if ( !TA && mPlayer!=pAttacker )
{
int sflags = pAttacker->pEdict->v.iuser4;
int stuntKill = 0;
int slpos = 0;
if ( weapon == 24 );
else if ( sflags == 20 || sflags == 1028 || sflags == 2052 ) stuntKill = 1;
else if ( sflags == 36) slpos = 1;
int doubleKill = 0;
if ( gpGlobals->time - pAttacker->lastKill < 1.0 ) doubleKill = 1;
if ( stuntKill ) killFlags |= TSKF_STUNTKILL;
pAttacker->lastKill = gpGlobals->time;
pAttacker->killingSpree++;
if ( pAttacker->killingSpree == 10 ) pAttacker->is_specialist = 1;
pAttacker->lastFrag = weaponData[weapon].bonus + 2*stuntKill;
if ( doubleKill )
{
pAttacker->lastFrag *= 2;
killFlags |= TSKF_DOUBLEKILL;
}
if ( pAttacker->is_specialist )
{
pAttacker->lastFrag *= 2;
killFlags |= TSKF_ISSPEC;
}
if ( mPlayer->is_specialist )
{
pAttacker->lastFrag += 5;
killFlags |= TSKF_KILLEDSPEC;
}
pAttacker->frags += pAttacker->lastFrag;
if ( pAttacker->frags != pAttacker->pEdict->v.frags )
{
if ( slpos ) killFlags |= TSKF_SLIDINGKILL;
else weapon = 36;
pAttacker->lastFrag += (int)pAttacker->pEdict->v.frags - pAttacker->frags;
pAttacker->frags = (int)pAttacker->pEdict->v.frags;
}
}
pAttacker->killFlags = killFlags;
pAttacker->saveKill(mPlayer,weapon,( aim == 1 ) ? 1:0 ,TA);
MF_ExecuteForward(g_death_info, pAttacker->index, mPlayer->index, weapon, aim, TA );
}
void Client_WStatus(void* mValue)
{
switch(mState++)
{
case 1:
if ( !*(int*)mValue )
{
mPlayer->current = 36; // fix dla wytraconej broni
}
break;
}
}
void Client_TSCash(void* mValue)
{
mPlayer->money = *(int*)mValue;
}
void Client_TSSpace(void* mValue)
{
mPlayer->space = *(int*)mValue;
}
void Client_PwUp(void* mValue)
{
static int iPwType;
switch(mState++){
case 0:
iPwType = *(int*)mValue;
switch(iPwType)
{
case TSPWUP_KUNGFU :
mPlayer->items |= TSITEM_KUNGFU;
break;
case TSPWUP_SJUMP:
mPlayer->items |= TSITEM_SUPERJUMP;
break;
default: mPlayer->PwUp = iPwType;
}
break;
case 1:
if ( iPwType != TSPWUP_KUNGFU && iPwType != TSPWUP_SJUMP ) mPlayer->PwUpValue = *(int*)mValue;
break;
}
}

336
dlls/ts/tsx/StatsNatives.h Normal file
View File

@ -0,0 +1,336 @@
/*
* TSX
* Copyright (c) 2005 Twilight Suzuka
*
*
* 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 "tsx.h"
static cell AMX_NATIVE_CALL get_user_astats(AMX *amx, cell *params) /* 6 param */
{
int index = params[1];
CHECK_PLAYERRANGE(index);
int attacker = params[2];
CHECK_PLAYERRANGE(attacker);
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->attackers[attacker].hits){
cell *cpStats = MF_GetAmxAddr(amx,params[3]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[4]);
CPlayer::PlayerWeapon* stats = &pPlayer->attackers[attacker];
cpStats[0] = stats->kills;
cpStats[1] = stats->deaths;
cpStats[2] = stats->hs;
cpStats[3] = stats->tks;
cpStats[4] = stats->shots;
cpStats[5] = stats->hits;
cpStats[6] = stats->damage;
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = stats->bodyHits[i];
if (params[6] && attacker && stats->name )
MF_SetAmxString(amx,params[5],stats->name,params[6]);
return 1;
}
return 0;
}
static cell AMX_NATIVE_CALL get_user_vstats(AMX *amx, cell *params) /* 6 param */
{
int index = params[1];
CHECK_PLAYERRANGE(index);
int victim = params[2];
CHECK_PLAYERRANGE(victim);
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->victims[victim].hits){
cell *cpStats = MF_GetAmxAddr(amx,params[3]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[4]);
CPlayer::PlayerWeapon* stats = &pPlayer->victims[victim];
cpStats[0] = stats->kills;
cpStats[1] = stats->deaths;
cpStats[2] = stats->hs;
cpStats[3] = stats->tks;
cpStats[4] = stats->shots;
cpStats[5] = stats->hits;
cpStats[6] = stats->damage;
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = stats->bodyHits[i];
if (params[6] && victim && stats->name)
MF_SetAmxString(amx,params[5],stats->name,params[6]);
return 1;
}
return 0;
}
static cell AMX_NATIVE_CALL get_user_wrstats(AMX *amx, cell *params) /* 4 param */ // DEC-Weapon (round) stats (end)
{
int index = params[1];
CHECK_PLAYERRANGE(index);
int weapon = params[2];
if (weapon<0||weapon>=TSMAX_WEAPONS){
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", weapon);
return 0;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->weaponsRnd[weapon].shots){
cell *cpStats = MF_GetAmxAddr(amx,params[3]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[4]);
Stats* stats = &pPlayer->weaponsRnd[weapon];
cpStats[0] = stats->kills;
cpStats[1] = stats->deaths;
cpStats[2] = stats->hs;
cpStats[3] = stats->tks;
cpStats[4] = stats->shots;
cpStats[5] = stats->hits;
cpStats[6] = stats->damage;
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = stats->bodyHits[i];
return 1;
}
return 0;
}
static cell AMX_NATIVE_CALL get_user_wstats(AMX *amx, cell *params) /* 4 param */
{
int index = params[1];
CHECK_PLAYERRANGE(index);
int weapon = params[2];
if (weapon<0||weapon>=TSMAX_WEAPONS){
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", weapon);
return 0;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->weapons[weapon].shots){
cell *cpStats = MF_GetAmxAddr(amx,params[3]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[4]);
CPlayer::PlayerWeapon* stats = &pPlayer->weapons[weapon];
cpStats[0] = stats->kills;
cpStats[1] = stats->deaths;
cpStats[2] = stats->hs;
cpStats[3] = stats->tks;
cpStats[4] = stats->shots;
cpStats[5] = stats->hits;
cpStats[6] = stats->damage;
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = stats->bodyHits[i];
return 1;
}
return 0;
}
static cell AMX_NATIVE_CALL reset_user_wstats(AMX *amx, cell *params) /* 6 param */
{
int index = params[1];
CHECK_PLAYERRANGE(index);
GET_PLAYER_POINTER_I(index)->restartStats();
return 1;
}
static cell AMX_NATIVE_CALL get_user_stats(AMX *amx, cell *params) /* 3 param */
{
int index = params[1];
CHECK_PLAYERRANGE(index);
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if ( pPlayer->rank ){
cell *cpStats = MF_GetAmxAddr(amx,params[2]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[3]);
cpStats[0] = pPlayer->rank->kills;
cpStats[1] = pPlayer->rank->deaths;
cpStats[2] = pPlayer->rank->hs;
cpStats[3] = pPlayer->rank->tks;
cpStats[4] = pPlayer->rank->shots;
cpStats[5] = pPlayer->rank->hits;
cpStats[6] = pPlayer->rank->damage;
cpStats[7] = pPlayer->rank->getPosition();
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = pPlayer->rank->bodyHits[i];
return pPlayer->rank->getPosition();
}
return 0;
}
static cell AMX_NATIVE_CALL get_user_rstats(AMX *amx, cell *params) /* 3 param */
{
int index = params[1];
CHECK_PLAYERRANGE(index);
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->rank){
cell *cpStats = MF_GetAmxAddr(amx,params[2]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[3]);
cpStats[0] = pPlayer->life.kills;
cpStats[1] = pPlayer->life.deaths;
cpStats[2] = pPlayer->life.hs;
cpStats[3] = pPlayer->life.tks;
cpStats[4] = pPlayer->life.shots;
cpStats[5] = pPlayer->life.hits;
cpStats[6] = pPlayer->life.damage;
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = pPlayer->life.bodyHits[i];
return 1;
}
return 0;
}
static cell AMX_NATIVE_CALL get_stats(AMX *amx, cell *params) /* 3 param */
{
int index = params[1] + 1;
for(RankSystem::iterator a = g_rank.front(); a ;--a){
if ((*a).getPosition() == index) {
cell *cpStats = MF_GetAmxAddr(amx,params[2]);
cell *cpBodyHits = MF_GetAmxAddr(amx,params[3]);
cpStats[0] = (*a).kills;
cpStats[1] = (*a).deaths;
cpStats[2] = (*a).hs;
cpStats[3] = (*a).tks;
cpStats[4] = (*a).shots;
cpStats[5] = (*a).hits;
cpStats[6] = (*a).damage;
cpStats[7] = (*a).getPosition();
MF_SetAmxString(amx,params[4],(*a).getName(),params[5]);
for(int i = 1; i < 8; ++i)
cpBodyHits[i] = (*a).bodyHits[i];
return --a ? index : 0;
}
}
return 0;
}
static cell AMX_NATIVE_CALL get_statsnum(AMX *amx, cell *params)
{
return g_rank.getRankNum();
}
static cell AMX_NATIVE_CALL register_cwpn(AMX *amx, cell *params){ // name,logname,melee=0
int i;
bool bFree = false;
for ( i=TSMAX_WEAPONS-TSMAX_CUSTOMWPNS;i<TSMAX_WEAPONS;i++){
if ( !weaponData[i].custom ){
bFree = true;
break;
}
}
if ( !bFree )
return 0;
int iLen;
char *szName = MF_GetAmxString(amx, params[1], 0, &iLen);
strcpy(weaponData[i].name,szName);
weaponData[i].custom = true;
weaponData[i].melee = params[2] ? true:false;
return i;
}
static cell AMX_NATIVE_CALL cwpn_dmg(AMX *amx, cell *params){ // wid,att,vic,dmg,hp=0
int weapon = params[1];
if ( weapon < TSMAX_WEAPONS-TSMAX_CUSTOMWPNS ){ // only for custom weapons
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid custom weapon id %d", weapon);
return 0;
}
int att = params[2];
CHECK_PLAYERRANGE(att);
int vic = params[3];
CHECK_PLAYERRANGE(vic);
int dmg = params[4];
if ( dmg<1 ){
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid damage %d", dmg);
return 0;
}
int aim = params[5];
if ( aim < 0 || aim > 7 ){
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid aim %d", aim);
return 0;
}
CPlayer* pAtt = GET_PLAYER_POINTER_I(att);
CPlayer* pVic = GET_PLAYER_POINTER_I(vic);
pVic->pEdict->v.dmg_inflictor = NULL;
pAtt->saveHit( pVic , weapon , dmg, aim );
if ( !pAtt ) pAtt = pVic;
int TA = 0;
if ( (pVic->pEdict->v.team == pAtt->pEdict->v.team ) && ( pVic != pAtt) )
TA = 1;
MF_ExecuteForward(g_damage_info, pAtt->index, pVic->index, dmg, weapon, aim, TA );
if ( pVic->IsAlive() )
return 1;
pAtt->saveKill(pVic,weapon,( aim == 1 ) ? 1:0 ,TA);
MF_ExecuteForward(g_death_info, pAtt->index, pVic->index, weapon, aim, TA );
return 1;
}
static cell AMX_NATIVE_CALL cwpn_shot(AMX *amx, cell *params){ // player,wid
int index = params[2];
CHECK_PLAYERRANGE(index);
int weapon = params[1];
if ( weapon < TSMAX_WEAPONS-TSMAX_CUSTOMWPNS ){
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid custom weapon id %d", weapon);
return 0;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
pPlayer->saveShot(weapon);
return 1;
}
AMX_NATIVE_INFO stats_Natives[] = {
{ "get_stats", get_stats},
{ "get_statsnum", get_statsnum},
{ "get_user_astats", get_user_astats },
{ "get_user_rstats", get_user_rstats },
{ "get_user_lstats", get_user_rstats }, // for backward compatibility
{ "get_user_stats", get_user_stats },
{ "get_user_vstats", get_user_vstats },
{ "get_user_wrstats", get_user_wrstats}, // DEC-Weapon(Round) Stats
{ "get_user_wstats", get_user_wstats},
{ "reset_user_wstats", reset_user_wstats },
// Custom Weapon Support
{ "custom_weapon_add", register_cwpn },
{ "custom_weapon_dmg", cwpn_dmg },
{ "custom_weapon_shot", cwpn_shot },
{ NULL, NULL }
};

68
dlls/ts/tsx/UserMsg.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2003-2005 Twilight Suzuka
*
* This file is part of TSXMod.
*
* TS XMod 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.
*
* TS XMod 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 TS XMod; 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 "tsx.h"
#include "MsgFunc.h"
int gmsgResetHUD;
int gmsgWeaponInfo;
int gmsgClipInfo;
int gmsgScoreInfo;
int gmsgTSHealth;
int gmsgWStatus;
int gmsgTSCash;
int gmsgTSSpace;
int gmsgPwUp;
struct sUserMsg
{
const char* name;
int* id;
funEventCall func;
bool endmsg;
}
g_user_msg[] =
{
{ "ResetHUD",&gmsgResetHUD,Client_ResetHUD_End,true },
{ "WeaponInfo",&gmsgWeaponInfo,Client_WeaponInfo,false },
{ "ClipInfo",&gmsgClipInfo,Client_ClipInfo,false },
{ "ScoreInfo",&gmsgScoreInfo,Client_ScoreInfo,false },
{ "TSHealth",&gmsgTSHealth,Client_TSHealth_End,true },
{ "WStatus",&gmsgWStatus,Client_WStatus,false },
{ "TSCash",&gmsgTSCash,Client_TSCash,false },
{ "TSSpace",&gmsgTSSpace,Client_TSSpace,false },
{ "PwUp",&gmsgPwUp,Client_PwUp,false},
{ 0,0,0,false }
};

View File

@ -1,6 +1,6 @@
/*
* TFCX
* Copyright (c) 2004 Lukasz Wlasinski
* TSX
* Copyright (c) 2005 Melanie Maye
*
*
* This program is free software; you can redistribute it and/or modify it
@ -73,15 +73,3 @@ weapon_t weaponData[] = {
{ 1,"Throwing Knife","throwing_knife",2 }, // new id 37
{ 0,"breakable", "breakable", 1 },
};
bool ignoreBots (edict_t *pEnt, edict_t *pOther){
if ( !rankBots && ( pEnt->v.flags & FL_FAKECLIENT || ( pOther && pOther->v.flags & FL_FAKECLIENT ) ) )
return true;
return false;
}
bool isModuleActive(){
if ( !(int)CVAR_GET_FLOAT("tsstats_pause") )
return true;
return false;
}

View File

@ -2502,8 +2502,6 @@ PFN_FORMAT g_fn_Format;
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
PFN_REQ_FNPTR g_fn_RequestFunction;
PFN_AMX_PUSH g_fn_AmxPush;
PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
// *** Exports ***
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
@ -2613,8 +2611,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
REQFUNC("SetPlayerTeamInfo", g_fn_SetTeamInfo, PFN_SET_TEAM_INFO);
REQFUNC("PlayerPropAddr", g_fn_PlayerPropAddr, PFN_PLAYER_PROP_ADDR);
#ifdef MEMORY_TEST
// Memory
@ -2737,8 +2733,6 @@ void ValidateMacros_DontCallThis_Smiley()
MF_GetPlayerEdict(0);
MF_Format("", 4, "str");
MF_RegisterFunction(NULL, "");
MF_SetPlayerTeamInfo(0, 0, "");
MF_PlayerPropAddr(0, 0);
}
#endif
@ -2918,20 +2912,20 @@ void operator delete[](void *reportedAddress)
#else
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
void * operator new(size_t size) {
void * ::operator new(size_t size) {
return(calloc(1, size));
}
void * operator new[](size_t size) {
void * ::operator new[](size_t size) {
return(calloc(1, size));
}
void operator delete(void * ptr) {
void ::operator delete(void * ptr) {
if(ptr)
free(ptr);
}
void operator delete[](void * ptr) {
void ::operator delete[](void * ptr) {
if(ptr)
free(ptr);
}

View File

@ -1927,28 +1927,6 @@ enum ForwardParam
FP_ARRAY, // array; use the return value of prepareArray.
};
enum PlayerProp
{
Player_Name, //String
Player_Ip, //String
Player_Team, //String
Player_Ingame, //bool
Player_Authorized, //bool
Player_Vgui, //bool
Player_Time, //float
Player_Playtime, //float
Player_MenuExpire, //float
Player_Weapons, //struct{int,int}[32]
Player_CurrentWeapon, //int
Player_TeamID, //int
Player_Deaths, //int
Player_Aiming, //int
Player_Menu, //int
Player_Keys, //int
Player_Flags, //int[32]
Player_Newmenu, //int
Player_NewmenuPage, //int
};
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
@ -2000,7 +1978,6 @@ typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#else
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#endif
typedef void * (*PFN_PLAYER_PROP_ADDR) (int /*id*/, int /*prop*/);
#ifdef MEMORY_TEST
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
@ -2026,7 +2003,6 @@ typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char */*name */);
extern PFN_ADD_NATIVES g_fn_AddNatives;
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
@ -2090,8 +2066,6 @@ extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
extern PFN_REQ_FNPTR g_fn_RequestFunction;
extern PFN_AMX_PUSH g_fn_AmxPush;
extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
#ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems
@ -2152,8 +2126,6 @@ void MF_RegisterFunction (void *pfn, const char *description) { }
void * MF_RequestFunction (const char *description) { }
int MF_AmxPush (AMX *amx, cell *params) { }
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
void * MF_PlayerPropAddr (int id, int prop) { }
#endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives
@ -2219,8 +2191,6 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_RegisterFunction g_fn_RegisterFunction
#define MF_RequestFunction g_fn_RequestFunction;
#define MF_AmxPush g_fn_AmxPush
#define MF_SetPlayerTeamInfo g_fn_SetTeamInfo
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
#ifdef MEMORY_TEST
/*** Memory ***/

View File

@ -6,7 +6,7 @@
// Module info
#define MODULE_NAME "TSX"
#define MODULE_VERSION "1.65"
#define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_AUTHOR "Twilight Suzuka"
#define MODULE_URL "http://www.amxmodx.org"
#define MODULE_LOGTAG "TSX"
// If you want the module not to be reloaded on mapchange, remove / comment out the next line

View File

@ -215,92 +215,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\moduleconfig.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;tsx_amxx_EXPORTS;$(NoInherit)"
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="tsx_amxx_EXPORTS;$(NoInherit)"
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\NBase.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;tsx_amxx_EXPORTS;$(NoInherit)"
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="tsx_amxx_EXPORTS;$(NoInherit)"
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\NRank.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;tsx_amxx_EXPORTS;$(NoInherit)"
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="tsx_amxx_EXPORTS;$(NoInherit)"
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\usermsg.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;tsx_amxx_EXPORTS;$(NoInherit)"
BasicRuntimeChecks="3"
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="tsx_amxx_EXPORTS;$(NoInherit)"
BrowseInformation="1"/>
</FileConfiguration>
RelativePath="..\tsx.cpp">
</File>
<File
RelativePath="..\Utils.cpp">
@ -340,9 +255,18 @@
<File
RelativePath="..\moduleconfig.h">
</File>
<File
RelativePath="..\MsgFunc.h">
</File>
<File
RelativePath="..\StatsNatives.h">
</File>
<File
RelativePath="..\tsx.h">
</File>
<File
RelativePath="..\UserMsg.h">
</File>
</Filter>
<Filter
Name="Resource Files"

320
dlls/ts/tsx/tsx.cpp Normal file
View File

@ -0,0 +1,320 @@
/*
* Copyright (c) 2003-2004 Lukasz Wlasinski
*
* This file is part of TS XMod.
*
* TS XMod 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.
*
* TS XMod 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 TS XMod; 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 "tsx.h"
#include "StatsNatives.h"
#include "UserMsg.h"
funEventCall modMsgsEnd[MAX_REG_MSGS];
funEventCall modMsgs[MAX_REG_MSGS];
void (*function)(void*);
void (*endfunction)(void*);
CPlayer* mPlayer;
int mPlayerIndex;
int mState;
CPlayer players[33];
bool is_theonemode;
bool rankBots;
int g_death_info;
int g_damage_info;
int gKnifeOffset;
RankSystem g_rank;
cvar_t init_tsstats_maxsize ={"tsstats_maxsize","3500", 0 , 3500.0 };
cvar_t init_tsstats_reset ={"tsstats_reset","0"};
cvar_t init_tsstats_rank ={"tsstats_rank","0"};
cvar_t *tsstats_rankbots;
cvar_t *tsstats_pause;
cvar_t init_tsstats_rankbots ={"tsstats_rankbots","1"};
cvar_t init_tsstats_pause = {"tsstats_pause","0"};
cvar_t *tsstats_maxsize;
cvar_t *tsstats_reset;
cvar_t *tsstats_rank;
const char* get_localinfo( const char* name , const char* def = 0 )
{
const char* b = LOCALINFO( (char*)name );
if (((b==0)||(*b==0)) && def )
SET_LOCALINFO((char*)name,(char*)(b = def) );
return b;
}
int RegUserMsg_Post(const char *pszName, int iSize)
{
for (int i = 0; g_user_msg[ i ].name; ++i )
{
if ( !*g_user_msg[i].id && strcmp( g_user_msg[ i ].name , pszName ) == 0 )
{
int id = META_RESULT_ORIG_RET( int );
*g_user_msg[ i ].id = id;
if ( g_user_msg[ i ].endmsg ) modMsgsEnd[ id ] = g_user_msg[ i ].func;
else modMsgs[ id ] = g_user_msg[ i ].func;
break;
}
}
RETURN_META_VALUE(MRES_IGNORED, 0);
}
void ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax )
{
is_theonemode = (int)CVAR_GET_FLOAT("mp_theonemode") ? true:false;
rankBots = (int)tsstats_rankbots->value ? true:false;
for( int i = 1; i <= gpGlobals->maxClients; ++i )
GET_PLAYER_POINTER_I(i)->Init( i , pEdictList + i );
RETURN_META(MRES_IGNORED);
}
void PlayerPreThink_Post( edict_t *pEntity )
{
if ( !isModuleActive() ) // stats only
return;
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
if (pPlayer->clearStats && pPlayer->clearStats < gpGlobals->time && pPlayer->ingame)
{
pPlayer->clearStats = 0.0f;
pPlayer->rank->updatePosition( &pPlayer->life );
pPlayer->restartStats(false);
}
RETURN_META(MRES_IGNORED);
}
void ServerDeactivate()
{
int i;
for(i = 1;i<=gpGlobals->maxClients; ++i)
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->rank) pPlayer->Disconnect();
}
if ( (g_rank.getRankNum() >= (int)tsstats_maxsize->value) || ((int)tsstats_reset->value == 1) )
{
CVAR_SET_FLOAT("tsstats_reset",0.0);
g_rank.clear();
}
g_rank.saveRank( MF_BuildPathname("%s",get_localinfo("tsstats") ) );
// clear custom weapons info
for ( i=TSMAX_WEAPONS-TSMAX_CUSTOMWPNS;i<TSMAX_WEAPONS;i++)
weaponData[i].custom = false;
g_rank.clear();
g_rank.unloadCalc();
RETURN_META(MRES_IGNORED);
}
BOOL ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
{
GET_PLAYER_POINTER(pEntity)->Connect(pszAddress);
RETURN_META_VALUE(MRES_IGNORED, TRUE);
}
void ClientDisconnect( edict_t *pEntity )
{
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
if (pPlayer->ingame) pPlayer->Disconnect();
RETURN_META(MRES_IGNORED);
}
void ClientPutInServer_Post( edict_t *pEntity )
{
GET_PLAYER_POINTER(pEntity)->PutInServer();
RETURN_META(MRES_IGNORED);
}
void ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer )
{
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
const char* name = INFOKEY_VALUE(infobuffer,"name");
const char* oldname = STRING(pEntity->v.netname);
if ( pPlayer->ingame )
{
if ( strcmp(oldname,name) )
{
if (!tsstats_rank->value)
pPlayer->rank = g_rank.findEntryInRank( name, name );
else
pPlayer->rank->setName( name );
}
}
else if ( pPlayer->IsBot() )
{
pPlayer->PutInServer();
}
RETURN_META(MRES_IGNORED);
}
void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
{
if (ed)
{
mPlayerIndex = ENTINDEX(ed);
mPlayer = GET_PLAYER_POINTER_I(mPlayerIndex);
}
else
{
mPlayerIndex = 0;
mPlayer = NULL;
}
mState = 0;
if ( msg_type < 0 || msg_type >= MAX_REG_MSGS ) msg_type = 0;
function=modMsgs[msg_type];
endfunction=modMsgsEnd[msg_type];
RETURN_META(MRES_IGNORED);
}
void MessageEnd_Post(void)
{
if (endfunction) (*endfunction)(NULL);
RETURN_META(MRES_IGNORED);
}
void WriteByte_Post(int iValue)
{
if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED);
}
void WriteChar_Post(int iValue)
{
if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED);
}
void WriteShort_Post(int iValue)
{
if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED);
}
void WriteLong_Post(int iValue)
{
if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED);
}
void WriteAngle_Post(float flValue)
{
if (function) (*function)((void *)&flValue);
RETURN_META(MRES_IGNORED);
}
void WriteCoord_Post(float flValue)
{
if (function) (*function)((void *)&flValue);
RETURN_META(MRES_IGNORED);
}
void WriteString_Post(const char *sz)
{
if (function) (*function)((void *)sz);
RETURN_META(MRES_IGNORED);
}
void WriteEntity_Post(int iValue)
{
if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED);
}
void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *e, TraceResult *ptr)
{
if (ptr->pHit&&(ptr->pHit->v.flags& (FL_CLIENT | FL_FAKECLIENT) )&&
e&&(e->v.flags& (FL_CLIENT | FL_FAKECLIENT) ))
{
GET_PLAYER_POINTER(e)->aiming = ptr->iHitgroup;
}
RETURN_META(MRES_IGNORED);
}
void OnMetaAttach() {
CVAR_REGISTER (&init_tsstats_maxsize);
CVAR_REGISTER (&init_tsstats_reset);
CVAR_REGISTER (&init_tsstats_rank);
tsstats_maxsize=CVAR_GET_POINTER(init_tsstats_maxsize.name);
tsstats_reset=CVAR_GET_POINTER(init_tsstats_reset.name);
tsstats_rank=CVAR_GET_POINTER(init_tsstats_rank.name);
CVAR_REGISTER (&init_tsstats_rankbots);
CVAR_REGISTER (&init_tsstats_pause);
tsstats_rankbots = CVAR_GET_POINTER(init_tsstats_rankbots.name);
tsstats_pause = CVAR_GET_POINTER(init_tsstats_pause.name);
}
void OnAmxxAttach() {
gKnifeOffset = TSKNIFE_OFFSET;
MF_AddNatives( stats_Natives );
//TSFun does these now
//MF_AddNatives( base_Natives );
const char* path = get_localinfo("tsstats_score","addons/amxmodx/data/tsstats.amxx");
if ( path && *path )
{
char error[128];
g_rank.loadCalc( MF_BuildPathname("%s",path) , error );
}
if ( !g_rank.begin() )
{
g_rank.loadRank( MF_BuildPathname("%s",get_localinfo("tsstats","addons/amxmodx/data/tsstats.dat") ) );
}
}
void OnPluginsLoaded()
{
g_damage_info = MF_RegisterForward("client_damage", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
g_death_info = MF_RegisterForward("client_death", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
}

View File

@ -45,31 +45,9 @@
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#endif
extern AMX_NATIVE_INFO stats_Natives[];
//extern AMX_NATIVE_INFO stats_Natives[];
extern AMX_NATIVE_INFO base_Natives[];
extern int gmsgResetHUD;
extern int gmsgWeaponInfo;
extern int gmsgClipInfo;
extern int gmsgScoreInfo;
extern int gmsgTSHealth;
extern int gmsgWStatus;
extern int gmsgTSCash;
extern int gmsgTSSpace;
extern int gmsgPwUp;
void Client_ResetHUD_End(void*);
void Client_WeaponInfo(void*);
void Client_ClipInfo(void*);
void Client_ScoreInfo(void*);
void Client_TSHealth_End(void*);
void Client_WStatus(void* mValue);
void Client_TSCash(void* mValue);
void Client_TSSpace(void* mValue);
void Client_PwUp(void* mValue);
typedef void (*funEventCall)(void*);
extern funEventCall modMsgsEnd[MAX_REG_MSGS];
extern funEventCall modMsgs[MAX_REG_MSGS];
@ -105,8 +83,17 @@ extern int gKnifeOffset;
extern weapon_t weaponData[TSMAX_WEAPONS];
bool isModuleActive();
bool ignoreBots (edict_t *pEnt, edict_t *pOther = NULL);
inline bool ignoreBots (edict_t *pEnt, edict_t *pOther = NULL)
{
if ( !rankBots && ( pEnt->v.flags & FL_FAKECLIENT || ( pOther && pOther->v.flags & FL_FAKECLIENT ) ) ) return true;
return false;
}
inline bool isModuleActive()
{
if ( !(int)CVAR_GET_FLOAT("tsstats_pause") ) return true;
return false;
}
#define CHECK_ENTITY(x) \
if (x < 0 || x > gpGlobals->maxEntities) { \