Bugfixes for mantis #1008, #1009

Rewrote WeaponsResource code so that uninitialized slots are no longer returned as valid weapons
Removed upp_* from command constants and console commands
Removed commented out entry from hl_baseentity.cpp
Shift in map data position is now performed by the network layer instead of at the time of creation
Deleted obsolete Util.vcproj
Replaced calls to fmax with calls to max in AvHEntities.cpp (Win32 compiler wasn't finding fmax command without explicit include)
Began implementation of client-to-server tunnel for Nexus


git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@94 67975925-1194-0748-b3d5-c16f83f1a3a1
This commit is contained in:
XP-Cagey 2005-05-05 15:20:23 +00:00
parent 8184bf4ccb
commit b918c731aa
19 changed files with 582 additions and 882 deletions

Binary file not shown.

View file

@ -43,17 +43,34 @@ int g_weaponselect = 0;
//Equivalent to DECLARE_COMMAND(lastinv,LastInv) except we use gWR instead of gHud
void __CmdFunc_LastInv(void)
{ gWR.UserCmd_LastInv(); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WeaponsResource::WeaponsResource(void) : lastWeapon(NULL), iOldWeaponBits(0) {}
WeaponsResource::~WeaponsResource(void) {}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::Init( void )
{
gWR.UserCmd_LastInv();
memset( rgWeapons, 0, sizeof(WEAPON)*MAX_WEAPONS );
Reset();
HOOK_COMMAND("lastinv",LastInv);
}
void WeaponsResource::Init(void)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::Reset( void )
{
memset( rgWeapons, 0, sizeof rgWeapons );
HOOK_COMMAND("lastinv",LastInv);
Reset();
lastWeapon = NULL;
iOldWeaponBits = 0;
memset( rgSlots, 0, sizeof(WEAPON*)*MAX_WEAPON_SLOTS*MAX_WEAPON_POSITIONS );
memset( riAmmo, 0, sizeof(int)*MAX_AMMO_TYPES );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource :: LoadAllWeaponSprites( void )
{
for (int i = 0; i < MAX_WEAPONS; i++)
@ -63,47 +80,25 @@ void WeaponsResource :: LoadAllWeaponSprites( void )
}
}
int WeaponsResource :: CountAmmo( int iId )
{
if ( iId < 0 )
return 0;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
return riAmmo[iId];
}
int WeaponsResource :: HasAmmo( WEAPON *p )
inline void LoadWeaponSprite( client_sprite_t* ptr, HSPRITE& sprite, wrect_t& bounds )
{
if ( !p )
return FALSE;
// weapons with no max ammo can always be selected
if ( p->iMax1 == -1 )
return TRUE;
return (p->iAmmoType == -1) || p->iClip > 0 || CountAmmo(p->iAmmoType)
|| CountAmmo(p->iAmmo2Type) || ( p->iFlags & WEAPON_FLAGS_SELECTONEMPTY );
}
int WeaponsResource::IsEnabled(WEAPON* p)
{
int theIsEnabled = FALSE;
// If weapon is enabled
if(HUD_GetWeaponEnabled(p->iId))
if( ptr )
{
theIsEnabled = this->HasAmmo(p);
string name( "sprites/" );
name.append( ptr->szSprite );
name.append( ".spr" );
sprite = Safe_SPR_Load(name.c_str());
bounds = ptr->rc;
}
else
{
sprite = NULL;
}
return theIsEnabled;
}
int WeaponsResource::IsSelectable(WEAPON* p)
{
int theIsSelectable = FALSE;
if( p != NULL && HUD_GetWeaponEnabled(p->iId))
{
theIsSelectable = TRUE;
}
return theIsSelectable;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
{
@ -137,158 +132,203 @@ void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon )
return;
}
client_sprite_t *p;
LoadWeaponSprite( GetSpriteList( pList, "crosshair", iRes, i ), pWeapon->hCrosshair, pWeapon->rcCrosshair );
LoadWeaponSprite( GetSpriteList( pList, "autoaim", iRes, i ), pWeapon->hAutoaim, pWeapon->rcAutoaim );
LoadWeaponSprite( GetSpriteList( pList, "zoom", iRes, i ), pWeapon->hZoomedCrosshair, pWeapon->rcZoomedCrosshair );
LoadWeaponSprite( GetSpriteList( pList, "zoom_autoaim", iRes, i ), pWeapon->hZoomedAutoaim, pWeapon->rcZoomedAutoaim );
LoadWeaponSprite( GetSpriteList( pList, "weapon", iRes, i ), pWeapon->hInactive, pWeapon->rcInactive );
LoadWeaponSprite( GetSpriteList( pList, "weapon_s", iRes, i ), pWeapon->hActive, pWeapon->rcActive );
LoadWeaponSprite( GetSpriteList( pList, "ammo", iRes, i ), pWeapon->hAmmo, pWeapon->rcAmmo );
LoadWeaponSprite( GetSpriteList( pList, "ammo2", iRes, i ), pWeapon->hAmmo2, pWeapon->rcAmmo2 );
p = GetSpriteList( pList, "crosshair", iRes, i );
if (p)
if( pWeapon->hZoomedCrosshair == NULL ) //default to non-zoomed crosshair
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hCrosshair = Safe_SPR_Load(sz);
pWeapon->rcCrosshair = p->rc;
}
else
pWeapon->hCrosshair = NULL;
p = GetSpriteList(pList, "autoaim", iRes, i);
if (p)
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hAutoaim = Safe_SPR_Load(sz);
pWeapon->rcAutoaim = p->rc;
}
else
pWeapon->hAutoaim = 0;
p = GetSpriteList( pList, "zoom", iRes, i );
if (p)
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hZoomedCrosshair = Safe_SPR_Load(sz);
pWeapon->rcZoomedCrosshair = p->rc;
}
else
{
pWeapon->hZoomedCrosshair = pWeapon->hCrosshair; //default to non-zoomed crosshair
pWeapon->hZoomedCrosshair = pWeapon->hCrosshair;
pWeapon->rcZoomedCrosshair = pWeapon->rcCrosshair;
}
p = GetSpriteList(pList, "zoom_autoaim", iRes, i);
if (p)
if( pWeapon->hAutoaim == NULL ) //default to non-autoaim crosshair
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hZoomedAutoaim = Safe_SPR_Load(sz);
pWeapon->rcZoomedAutoaim = p->rc;
pWeapon->hAutoaim = pWeapon->hCrosshair;
pWeapon->rcAutoaim = pWeapon->rcCrosshair;
}
else
if( pWeapon->hZoomedAutoaim == NULL ) //default to non-autoaim zoomed crosshair
{
pWeapon->hZoomedAutoaim = pWeapon->hZoomedCrosshair; //default to zoomed crosshair
pWeapon->hZoomedAutoaim = pWeapon->hZoomedCrosshair;
pWeapon->rcZoomedAutoaim = pWeapon->rcZoomedCrosshair;
}
p = GetSpriteList(pList, "weapon", iRes, i);
if (p)
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hInactive = Safe_SPR_Load(sz);
pWeapon->rcInactive = p->rc;
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
else
pWeapon->hInactive = 0;
p = GetSpriteList(pList, "weapon_s", iRes, i);
if (p)
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hActive = Safe_SPR_Load(sz);
pWeapon->rcActive = p->rc;
}
else
pWeapon->hActive = 0;
p = GetSpriteList(pList, "ammo", iRes, i);
if (p)
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hAmmo = Safe_SPR_Load(sz);
pWeapon->rcAmmo = p->rc;
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
else
pWeapon->hAmmo = 0;
p = GetSpriteList(pList, "ammo2", iRes, i);
if (p)
{
sprintf(sz, "sprites/%s.spr", p->szSprite);
pWeapon->hAmmo2 = Safe_SPR_Load(sz);
pWeapon->rcAmmo2 = p->rc;
gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
}
else
pWeapon->hAmmo2 = 0;
if( pWeapon->hActive || pWeapon->hInactive || pWeapon->hAmmo || pWeapon->hAmmo2 )
{ gHR.iHistoryGap = max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); }
}
// Returns the first weapon for a given slot.
WEAPON *WeaponsResource :: GetFirstPos( int iSlot )
{
WEAPON *pret = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (int i = 0; i < MAX_WEAPON_POSITIONS; i++)
WEAPON* WeaponsResource::GetWeapon( int iId ) { return rgWeapons[iId].iId ? &rgWeapons[iId] : NULL; }
WEAPON* WeaponsResource::GetWeaponSlot( int slot, int pos ) { return rgSlots[slot][pos]; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WEAPON* WeaponsResource::GetFirstPos( int iSlot )
{
WEAPON *returnVal = NULL;
ASSERT( iSlot < MAX_WEAPON_SLOTS && iSlot >= 0 );
for( int counter = 0; counter < MAX_WEAPON_POSITIONS; ++counter )
{
if (this->IsSelectable(rgSlots[iSlot][i]))
if( this->IsSelectable(rgSlots[iSlot][counter]) )
{
pret = rgSlots[iSlot][i];
returnVal = rgSlots[iSlot][counter];
break;
}
}
return pret;
return returnVal;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WEAPON* WeaponsResource :: GetNextActivePos( int iSlot, int iSlotPos )
WEAPON* WeaponsResource::GetNextActivePos( int iSlot, int iSlotPos )
{
if ( iSlotPos >= MAX_WEAPON_POSITIONS || iSlot >= MAX_WEAPON_SLOTS )
return NULL;
WEAPON* returnVal = NULL;
ASSERT( iSlot < MAX_WEAPON_SLOTS && iSlot >= 0 );
ASSERT( iSlotPos >= 0 );
WEAPON *p = gWR.rgSlots[ iSlot ][ iSlotPos+1 ];
if (!this->IsSelectable(p))
return GetNextActivePos( iSlot, iSlotPos + 1 );
for( int counter = iSlotPos+1; counter < MAX_WEAPON_POSITIONS; ++counter )
{
if( this->IsSelectable(rgSlots[iSlot][counter]) )
{
returnVal = rgSlots[iSlot][counter];
break;
}
}
return p;
return returnVal;
}
void WeaponsResource::SetCurrentWeapon(WEAPON* newWeapon)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool WeaponsResource::IsEnabled(WEAPON* p)
{
WEAPON* currentWeapon = this->GetWeapon(gHUD.GetCurrentWeaponID());
// puzl: 497 - Because weapon state can get out of sync, we should allow this even if the weapons are the same
// && newWeapon != currentWeapon
if( newWeapon != NULL )
{
if( newWeapon != currentWeapon )
{ lastWeapon = currentWeapon; }
ServerCmd(newWeapon->szName);
g_weaponselect = newWeapon->iId;
if( p == NULL ) { return false; }
return HUD_GetWeaponEnabled(p->iId) && this->HasAmmo(p);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool WeaponsResource::IsSelectable(WEAPON* p)
{
if( p == NULL ) { return false; }
return HUD_GetWeaponEnabled(p->iId);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool WeaponsResource::HasAmmo( WEAPON* p )
{
if( p == NULL) { return false; }
//note : if max ammo capacity is -1, this has always returned true in spite of not
// having actual ammo -- KGP
return (p->iAmmoType == -1) || (p->iMax1 == -1) || p->iClip > 0 || CountAmmo(p->iAmmoType)
|| CountAmmo(p->iAmmo2Type) || (p->iFlags & WEAPON_FLAGS_SELECTIONEMPTY );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int WeaponsResource::CountAmmo( int iId )
{
ASSERT( iId < MAX_AMMO_TYPES );
if( iId < 0 ) return 0;
return riAmmo[iId];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int WeaponsResource::GetAmmo( int iId )
{
ASSERT( iId < MAX_AMMO_TYPES && iId > -1 );
return riAmmo[iId];
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::SetAmmo( int iId, int iCount )
{
ASSERT( iId < MAX_AMMO_TYPES && iId > -1 );
riAmmo[iId] = iCount;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HSPRITE* WeaponsResource::GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect )
{
for ( int i = 0; i < MAX_WEAPONS; i++ )
{
if ( rgWeapons[i].iAmmoType == iAmmoId )
{
rect = rgWeapons[i].rcAmmo;
return &rgWeapons[i].hAmmo;
}
else if ( rgWeapons[i].iAmmo2Type == iAmmoId )
{
rect = rgWeapons[i].rcAmmo2;
return &rgWeapons[i].hAmmo2;
}
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::AddWeapon( WEAPON *wp )
{
rgWeapons[ wp->iId ] = *wp;
LoadWeaponSprites( &rgWeapons[ wp->iId ] );
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::PickupWeapon( WEAPON *wp )
{
rgSlots[ wp->iSlot ][ wp->iSlotPos ] = wp;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::DropWeapon( WEAPON *wp )
{
rgSlots[ wp->iSlot ][ wp->iSlotPos ] = NULL;
if(lastWeapon == wp) //dropped last weapon, remove it from the list
{ lastWeapon = NULL; }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::DropAllWeapons( void )
{
for ( int i = 0; i < MAX_WEAPONS; i++ )
{
if ( rgWeapons[i].iId )
DropWeapon( &rgWeapons[i] );
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::UserCmd_LastInv(void)
{
if(this->IsSelectable(this->lastWeapon) && this->lastWeapon != this->GetWeapon(gHUD.GetCurrentWeaponID()))
if(this->IsSelectable(this->lastWeapon))
{
this->SetCurrentWeapon(lastWeapon);
//voogru: Should a sound be played?
/*const char* theSound = AvHSHUGetCommonSoundName(gHUD.GetIsAlien(), WEAPON_SOUND_HUD_ON);
gHUD.PlayHUDSound(theSound, kHUDSoundVolume);*/
const char* theSound = AvHSHUGetCommonSoundName(gHUD.GetIsAlien(), WEAPON_SOUND_HUD_ON);
gHUD.PlayHUDSound(theSound, kHUDSoundVolume);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::SetValidWeapon(void)
{
WEAPON* p = this->GetFirstPos(0); //alien attack 1 or primary marine weapon
@ -318,6 +358,91 @@ void WeaponsResource::SetValidWeapon(void)
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource::SetCurrentWeapon(WEAPON* newWeapon)
{
WEAPON* currentWeapon = this->GetWeapon(gHUD.GetCurrentWeaponID());
// puzl: 497 - Because weapon state can get out of sync, we should allow this even if the weapons are the same
// && newWeapon != currentWeapon
if( newWeapon != NULL )
{
if( newWeapon != currentWeapon )
{ lastWeapon = currentWeapon; }
ServerCmd(newWeapon->szName);
g_weaponselect = newWeapon->iId;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection )
{
if ( gHUD.m_Menu.m_fMenuDisplayed && (fAdvance == FALSE) && (iDirection == 1) )
{ // menu is overriding slot use commands
gHUD.m_Menu.SelectMenuItem( iSlot + 1 ); // slots are one off the key numbers
return;
}
if ( iSlot >= MAX_WEAPON_SLOTS )
return;
if ( gHUD.m_fPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) )
return;
if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) //require suit
return;
if ( ! ( gHUD.m_iWeaponBits & ~(1<<(WEAPON_SUIT)) )) //require something besides suit
return;
WEAPON *p = NULL;
bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0;
if ((gpActiveSel == NULL) || (gpActiveSel == (WEAPON *)1) || (iSlot != gpActiveSel->iSlot))
{
p = GetFirstPos(iSlot);
const char* theSound = AvHSHUGetCommonSoundName(gHUD.GetIsAlien(), WEAPON_SOUND_HUD_ON);
gHUD.PlayHUDSound(theSound, kHUDSoundVolume);
if (this->IsSelectable(p) && fastSwitch) //check to see if we can use fastSwitch
{
WEAPON *p2 = GetNextActivePos( p->iSlot, p->iSlotPos );
if (!this->IsSelectable(p2)) //only one target in the bucket
{
this->SetCurrentWeapon(p);
return;
}
}
}
else
{
const char* theSound = AvHSHUGetCommonSoundName(gHUD.GetIsAlien(), WEAPON_SOUND_MOVE_SELECT);
gHUD.PlayHUDSound(theSound, kHUDSoundVolume);
if ( gpActiveSel )
p = GetNextActivePos( gpActiveSel->iSlot, gpActiveSel->iSlotPos );
if ( !p )
p = GetFirstPos( iSlot );
}
if (!this->IsSelectable(p)) // no valid selection found
{
// if fastSwitch is on, ignore, else turn on the menu
if ( !fastSwitch ) {
gpActiveSel = (WEAPON *)1;
}
else {
gpActiveSel = NULL;
}
}
else
{
gpActiveSel = p;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int giBucketHeight, giBucketWidth, giABHeight, giABWidth; // Ammo Bar width and height
HSPRITE ghsprBuckets; // Sprite for top row of weapons menu
@ -490,96 +615,6 @@ void CHudAmmo::Think(void)
}
}
//
// Helper function to return a Ammo pointer from id
//
HSPRITE* WeaponsResource :: GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect )
{
for ( int i = 0; i < MAX_WEAPONS; i++ )
{
if ( rgWeapons[i].iAmmoType == iAmmoId )
{
rect = rgWeapons[i].rcAmmo;
return &rgWeapons[i].hAmmo;
}
else if ( rgWeapons[i].iAmmo2Type == iAmmoId )
{
rect = rgWeapons[i].rcAmmo2;
return &rgWeapons[i].hAmmo2;
}
}
return NULL;
}
// Menu Selection Code
void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection )
{
if ( gHUD.m_Menu.m_fMenuDisplayed && (fAdvance == FALSE) && (iDirection == 1) )
{ // menu is overriding slot use commands
gHUD.m_Menu.SelectMenuItem( iSlot + 1 ); // slots are one off the key numbers
return;
}
if ( iSlot > MAX_WEAPON_SLOTS )
return;
if ( gHUD.m_fPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) )
return;
if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) //require suit
return;
if ( ! ( gHUD.m_iWeaponBits & ~(1<<(WEAPON_SUIT)) )) //require something besides suit
return;
WEAPON *p = NULL;
bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0;
if ((gpActiveSel == NULL) || (gpActiveSel == (WEAPON *)1) || (iSlot != gpActiveSel->iSlot))
{
p = GetFirstPos(iSlot);
const char* theSound = AvHSHUGetCommonSoundName(gHUD.GetIsAlien(), WEAPON_SOUND_HUD_ON);
gHUD.PlayHUDSound(theSound, kHUDSoundVolume);
if (this->IsSelectable(p) && fastSwitch) //check to see if we can use fastSwitch
{
WEAPON *p2 = GetNextActivePos( p->iSlot, p->iSlotPos );
if (!this->IsSelectable(p2)) //only one target in the bucket
{
this->SetCurrentWeapon(p);
return;
}
}
}
else
{
const char* theSound = AvHSHUGetCommonSoundName(gHUD.GetIsAlien(), WEAPON_SOUND_MOVE_SELECT);
gHUD.PlayHUDSound(theSound, kHUDSoundVolume);
if ( gpActiveSel )
p = GetNextActivePos( gpActiveSel->iSlot, gpActiveSel->iSlotPos );
if ( !p )
p = GetFirstPos( iSlot );
}
if (!this->IsSelectable(p)) // no valid selection found
{
// if fastSwitch is on, ignore, else turn on the menu
if ( !fastSwitch ) {
gpActiveSel = (WEAPON *)1;
}
else {
gpActiveSel = NULL;
}
}
else
{
gpActiveSel = p;
}
}
//------------------------------------------------------------------------
// Message Handlers
@ -729,6 +764,7 @@ int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf )
NetMsg_WeaponList( pbuf, iSize, weapon_data );
WEAPON Weapon;
memset( &Weapon, 0, sizeof(WEAPON) );
strcpy( Weapon.szName, weapon_data.weapon_name.c_str() );
Weapon.iAmmoType = weapon_data.ammo1_type;
@ -757,7 +793,7 @@ void CHudAmmo::SlotInput( int iSlot )
if ( gViewPort && gViewPort->SlotInput( iSlot ) )
return;
gWR.SelectSlot(iSlot, FALSE, 1);
gWR.SelectSlot( iSlot, FALSE, 1 );
}
void CHudAmmo::UserCmd_Slot1(void)

View file

@ -19,9 +19,7 @@
#define MAX_WEAPON_NAME 128
#define WEAPON_FLAGS_SELECTONEMPTY 1
#define WEAPON_IS_ONTARGET 0x40
#define WEAPON_FLAGS_SELECTIONEMPTY 1
struct WEAPON
{

View file

@ -67,29 +67,13 @@ void HistoryResource :: AddToHistory( int iType, const char *szName, int iCount
if ( iType != HISTSLOT_ITEM )
return;
if ( (((AMMO_PICKUP_GAP * iCurrentHistorySlot) + AMMO_PICKUP_PICK_HEIGHT) > AMMO_PICKUP_HEIGHT_MAX) || (iCurrentHistorySlot >= MAX_HISTORY) )
{ // the pic would have to be drawn too high
// so start from the bottom
iCurrentHistorySlot = 0;
}
HIST_ITEM *freeslot = &rgAmmoHistory[iCurrentHistorySlot++]; // default to just writing to the first slot
// I am really unhappy with all the code in this file
int i = gHUD.GetSpriteIndex( szName );
if ( i == -1 )
return; // unknown sprite name, don't add it to history
freeslot->iId = i;
freeslot->type = iType;
freeslot->iCount = iCount;
HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" );
freeslot->DisplayTime = gHUD.m_flTime + HISTORY_DRAW_TIME;
return this->AddToHistory( iType, i, iCount );
}
void HistoryResource :: CheckClearHistory( void )
{
for ( int i = 0; i < MAX_HISTORY; i++ )

View file

@ -28,90 +28,52 @@
//
// this is the max number of items in each bucket
//#define MAX_WEAPON_POSITIONS MAX_WEAPON_SLOTS
#define MAX_WEAPON_POSITIONS 10
class WeaponsResource
{
private:
// Information about weapons & ammo
WEAPON rgWeapons[MAX_WEAPONS]; // Weapons Array
// counts of weapons * ammo
WEAPON* rgSlots[MAX_WEAPON_SLOTS+1][MAX_WEAPON_POSITIONS+1]; // The slots currently in use by weapons. The value is a pointer to the weapon; if it's NULL, no weapon is there
int riAmmo[MAX_AMMO_TYPES]; // count of each ammo type
//client-side lastinv
WEAPON* lastWeapon;
public:
void Init(void);
void Reset( void )
{
iOldWeaponBits = 0;
memset( rgSlots, 0, sizeof rgSlots );
memset( riAmmo, 0, sizeof riAmmo );
lastWeapon = NULL;
}
///// WEAPON /////
int iOldWeaponBits;
WEAPON *GetWeapon( int iId ) { return &rgWeapons[iId]; }
void AddWeapon( WEAPON *wp )
{
rgWeapons[ wp->iId ] = *wp;
LoadWeaponSprites( &rgWeapons[ wp->iId ] );
}
void PickupWeapon( WEAPON *wp )
{
rgSlots[ wp->iSlot ][ wp->iSlotPos ] = wp;
}
void DropWeapon( WEAPON *wp )
{
rgSlots[ wp->iSlot ][ wp->iSlotPos ] = NULL;
if(lastWeapon == wp) //dropped last weapon, remove it from the list
{
lastWeapon = NULL;
}
}
void DropAllWeapons( void )
{
for ( int i = 0; i < MAX_WEAPONS; i++ )
{
if ( rgWeapons[i].iId )
DropWeapon( &rgWeapons[i] );
}
}
WEAPON* GetWeaponSlot( int slot, int pos ) { return rgSlots[slot][pos]; }
WeaponsResource( void );
~WeaponsResource( void );
void Init( void );
void Reset( void );
void LoadWeaponSprites( WEAPON* wp );
void LoadAllWeaponSprites( void );
WEAPON* GetWeapon( int iId );
WEAPON* GetWeaponSlot( int slot, int pos );
WEAPON* GetFirstPos( int iSlot );
void SelectSlot( int iSlot, int fAdvance, int iDirection );
WEAPON* GetNextActivePos( int iSlot, int iSlotPos );
void UserCmd_LastInv(void);
void SetValidWeapon(void);
void SetCurrentWeapon(WEAPON* wp);
int IsEnabled( WEAPON *p );
int IsSelectable(WEAPON *p);
int HasAmmo( WEAPON *p );
bool IsEnabled( WEAPON *p );
bool IsSelectable( WEAPON *p );
bool HasAmmo( WEAPON *p );
int CountAmmo( int iId );
int GetAmmo( int iId );
void SetAmmo( int iId, int iCount );
HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ); //TODO: fix bass-ackwards arrangement and store sprites with ammo types
///// AMMO /////
AMMO GetAmmo( int iId ) { return riAmmo[ iId ]; }
void AddWeapon( WEAPON* wp );
void PickupWeapon( WEAPON* wp );
void DropWeapon( WEAPON* wp );
void DropAllWeapons( void );
void SetAmmo( int iId, int iCount ) { riAmmo[ iId ] = iCount; }
//CONSIDER: Should the selection functions be in the menu with the selection variables?
void UserCmd_LastInv( void );
void SetValidWeapon( void );
void SetCurrentWeapon( WEAPON* wp );
void SelectSlot( int iSlot, int fAdvance, int iDirection );
int CountAmmo( int iId );
friend CHudAmmo; //for iOldWeaponBits access
private:
WEAPON rgWeapons[MAX_WEAPONS]; // current weapon state
WEAPON* rgSlots[MAX_WEAPON_SLOTS][MAX_WEAPON_POSITIONS]; // current weapon slot map
WEAPON* lastWeapon; // client-side lastinv
HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect );
int riAmmo[MAX_AMMO_TYPES]; // current ammo counts
int iOldWeaponBits;
};
extern WeaponsResource gWR;

View file

@ -68,8 +68,6 @@ int CBaseAnimating::Save( class CSave & ) { return 1; }
// DEBUG Stubs
edict_t *DBG_EntOfVars( const entvars_t *pev ) { return NULL; }
// Now in AvHAssert.cpp
//void DBG_AssertFunction(bool fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage) { }
// UTIL_* Stubs
void UTIL_PrecacheOther( const char *szClassname ) { }

View file

@ -101,9 +101,6 @@
#define kcHighSpeed "highspeed"
#define kcRoomType "roomtype"
#define kcDigest "digest"
#define kcUPPPing "upp_ping"
#define kcUPPToggle "upp_toggle"
#define kcUPPToggleProfiling "upp_toggle_profiling"
#define kcSetBalanceVar "setbalancevar"
#define kcNSChangeLevel "nschangelevel"
#define kcTournyMode "tournymode"

View file

@ -424,22 +424,6 @@ BOOL AvHGamerules::ClientCommand( CBasePlayer *pPlayer, const char *pcmd )
}
theSuccess = true;
}
else if(FStrEq(pcmd, kcUPPPing))
{
if(theIsDeveloper)
{
AvHNexus::performSpeedTest();
}
theSuccess = true;
}
else if(FStrEq(pcmd, kcUPPToggleProfiling))
{
if(theIsDeveloper)
{
AvHNexus::setGeneratePerformanceData(theAvHPlayer->edict(),!AvHNexus::getGeneratePerformanceData());
}
theSuccess = true;
}
#ifdef AVH_PLAYTEST_BUILD
else if(FStrEq(pcmd, kcTournyMode))
{

View file

@ -1211,17 +1211,17 @@ void TriggerPresence::KeyValue(KeyValueData* pkvd)
}
else if(FStrEq(pkvd->szKeyName, "timebeforeleave"))
{
this->mTimeBeforeLeave = fmax(atof(pkvd->szValue), 0.0f);
this->mTimeBeforeLeave = max(atof(pkvd->szValue), 0.0f);
pkvd->fHandled = TRUE;
}
else if(FStrEq(pkvd->szKeyName, "momentaryopentime"))
{
this->mMomentaryOpenTime = fmax(atof(pkvd->szValue), 0.01f);
this->mMomentaryOpenTime = max(atof(pkvd->szValue), 0.01f);
pkvd->fHandled = TRUE;
}
else if(FStrEq(pkvd->szKeyName, "momentaryclosetime"))
{
this->mMomentaryCloseTime = fmax(atof(pkvd->szValue), 0.01f);
this->mMomentaryCloseTime = max(atof(pkvd->szValue), 0.01f);
pkvd->fHandled = TRUE;
}
else if(FStrEq(pkvd->szKeyName, "spawnflags"))

View file

@ -231,11 +231,12 @@ void AvHEntityHierarchy::BuildFromTeam(const AvHTeam* inTeam, BaseEntityListType
{
const AvHMapExtents& theMapExtents = GetGameRules()->GetMapExtents();
float theMinMapX = theMapExtents.GetMinMapX();
float theMinMapY = theMapExtents.GetMinMapY();
// commented this out here, commented out corresponding shift in AvHOverviewMap::Draw at line 771
// float theMinMapX = theMapExtents.GetMinMapX();
// float theMinMapY = theMapExtents.GetMinMapY();
mapEntity.mX -= theMinMapX;
mapEntity.mY -= theMinMapY;
// mapEntity.mX -= theMinMapX;
// mapEntity.mY -= theMinMapY;
mEntityList[theEntityIndex] = mapEntity;

View file

@ -51,8 +51,11 @@ const int kUnseenEnemyBase = 14;
const int kVisibleEnemyBase = 15;
const int kNumStatusTypes = 15;
struct MapEntity
class MapEntity
{
public:
MapEntity(void) : mUser3(AVH_USER3_NONE), mTeam(TEAM_IND), mX(0.0f), mY(0.0f), mAngle(0.0f), mSquadNumber(0) {}
AvHUser3 mUser3;
AvHTeamNumber mTeam;
float mX;
@ -74,7 +77,6 @@ struct MapEntity
{
return !(*this == e);
}
};

View file

@ -4161,19 +4161,21 @@ void AvHHud::InitializeDemoRecording()
for(i = 0; i < MAX_WEAPONS; i++)
{
WEAPON* theWeapon = gWR.GetWeapon(i);
if( theWeapon )
{
theTotalSize = sizeof(theWeapon->szName) + sizeof(theWeapon->iAmmoType) + sizeof(theWeapon->iAmmo2Type) + sizeof(theWeapon->iMax1) + sizeof(theWeapon->iMax2) + sizeof(theWeapon->iSlot) + sizeof(theWeapon->iSlotPos) + sizeof(theWeapon->iFlags) + sizeof(theWeapon->iId) + sizeof(theWeapon->iClip) + sizeof(theWeapon->iCount);// + sizeof(int); // last one is for ammo
theCharArray = new unsigned char[theTotalSize];
theTotalSize = sizeof(theWeapon->szName) + sizeof(theWeapon->iAmmoType) + sizeof(theWeapon->iAmmo2Type) + sizeof(theWeapon->iMax1) + sizeof(theWeapon->iMax2) + sizeof(theWeapon->iSlot) + sizeof(theWeapon->iSlotPos) + sizeof(theWeapon->iFlags) + sizeof(theWeapon->iId) + sizeof(theWeapon->iClip) + sizeof(theWeapon->iCount);// + sizeof(int); // last one is for ammo
theCharArray = new unsigned char[theTotalSize];
int theWeaponCoreDataLength = theTotalSize;// - sizeof(int);
memcpy(theCharArray, theWeapon, theWeaponCoreDataLength); // Everything but ammo
//int theAmmo = gWR.GetAmmo(theWeapon->iId);
//memcpy(theCharArray + theWeaponCoreDataLength, &theAmmo, sizeof(int));
int theWeaponCoreDataLength = theTotalSize;// - sizeof(int);
memcpy(theCharArray, theWeapon, theWeaponCoreDataLength); // Everything but ammo
//int theAmmo = gWR.GetAmmo(theWeapon->iId);
//memcpy(theCharArray + theWeaponCoreDataLength, &theAmmo, sizeof(int));
Demo_WriteBuffer(TYPE_WEAPONINFO, theTotalSize, (unsigned char*)theWeapon);
Demo_WriteBuffer(TYPE_WEAPONINFO, theTotalSize, (unsigned char*)theWeapon);
delete [] theCharArray;
theCharArray = NULL;
delete [] theCharArray;
theCharArray = NULL;
}
}
}
@ -4188,7 +4190,7 @@ int AvHHud::InitializeWeaponInfoPlayback(int inSize, unsigned char* inBuffer)
if(theWeapon.iId)
{
gWR.AddWeapon( &theWeapon);
gWR.AddWeapon( &theWeapon );
//int theAmmo = 0;
//memcpy(&theAmmo, inBuffer + theWeaponCoreDataLength, sizeof(int));
//gWR.SetAmmo(theWeapon.iId, theAmmo);
@ -5160,13 +5162,16 @@ void AvHHud::UpdateEntityID(float inCurrentTime)
ASSERT(this->mSelectingWeaponID >= 0);
ASSERT(this->mSelectingWeaponID < 32);
WEAPON* theWeapon = gWR.GetWeapon(this->mSelectingWeaponID);
int theDamage = theWeapon->iMax2;
if( theWeapon )
{
int theDamage = theWeapon->iMax2;
char theHelpTextWithDamage[1024];
sprintf(theHelpTextWithDamage, theHelpText.c_str(), theDamage);
char theHelpTextWithDamage[1024];
sprintf(theHelpTextWithDamage, theHelpText.c_str(), theDamage);
this->SetHelpMessage(theHelpTextWithDamage);
theSetHelpMessage = true;
this->SetHelpMessage(theHelpTextWithDamage);
theSetHelpMessage = true;
}
}
}
else if(this->mTechHelpText != "")

View file

@ -1148,7 +1148,7 @@ union float_converter
// 5 bits for info (range 1-32, refers to player number)
// total is 40 bits = 5 bytes for friendly, 35 bits for foe.
// savings would be 37.5% for friendly bytes.
// blip precision is equal to double large minimap precision, with worst case of 4 unit X,Y separation for MT.
// blip precision would be equal to double large minimap precision, with worst case of 4 unit X,Y separation for MT.
// because maps are much smaller vertically than horizontally as a rule, the worst case of 16 unit Z separation
// will very rarely occur.
for( int counter = 0; counter < list.mNumBlips; counter++ )
@ -1899,72 +1899,112 @@ union float_converter
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const int kNumStatusBits = 6;
const int kStatusMask = 0x3F;
const int kNumTeamBits = 2;
const int kTeamMask = 0x03;
const int kNumPositionCoordinateBits = 12;
const int kNumPositionBits = kNumPositionCoordinateBits*2;
const int kPositionCoordinateMask = 0xFFF;
const int kPositionNetworkConstant = 25;
const int kNumStatusBits = 6;
const int kStatusMask = 0x3F;
const int kNumTeamBits = 2;
const int kTeamMask = 0x03;
const int kNumPositionCoordinateBits = 12;
const int kPositionCoordinateMask = 0xFFF;
const int kPositionCoordinateOffset = 4096;
const float kPositionCoordinateScale = 0.5f;
const int kNumPositionBits = kNumPositionCoordinateBits*2;
const int kNumSquadBits = 3;
const int kSquadMask = 0x07;
const int kNumAngleBits = 4;
const int kAngleMask = 0x0F;
const int kNumPlayerIndexBits = 6;
const int kPlayerIndexMask = 0x3F;
const int kNumIndexBits = 14;
const int kIndexMask = 0x3FFF;
const int kNumFlagBits = 2;
const int kFlagMask = 0x03;
const int kEntHierFlagPlayer = 0x01;
const int kEntHierFlagDeletion = 0x02;
#ifndef AVH_SERVER
//TODO : replace OldItems with vector<int>
void ReadEntHier( MapEntityMap& NewItems, EntityListType& OldItems );
void ReadEntHier( MapEntityMap& NewItems, EntityListType& OldItems, int short_data, int long_data );
float UnpackageCoord( const int packaged_coord );
void NetMsg_UpdateEntityHierarchy( void* const buffer, const int size, MapEntityMap& NewItems, EntityListType& OldItems )
{
NewItems.clear();
OldItems.clear();
int num_items = size / 6;
int amnt_read = 0;
int short_data, long_data;
BEGIN_READ( buffer, size );
for( int count = 0; count < num_items; count++ )
while( amnt_read < size )
{
ReadEntHier( NewItems, OldItems );
short_data = READ_SHORT();
amnt_read += 2;
if( (short_data & kEntHierFlagDeletion) == 0 )
{
long_data = READ_LONG();
amnt_read += 4;
}
ReadEntHier( NewItems, OldItems, short_data, long_data );
}
END_READ();
}
void ReadEntHier( MapEntityMap& NewItems, EntityListType& OldItems )
void ReadEntHier( MapEntityMap& NewItems, EntityListType& OldItems, int short_data, int long_data )
{
int short_data = READ_SHORT();
int long_data = READ_LONG();
MapEntity ent;
int flags = short_data & kFlagMask;
short_data >>= kNumFlagBits;
int index = short_data >> 1 & 31;
if( long_data == 0 )
if( (flags & kEntHierFlagDeletion) == kEntHierFlagDeletion ) // Deletion (player or otherwise)
{
OldItems.push_back( index );
OldItems.push_back( short_data & kIndexMask );
return;
}
MapEntity ent;
int index = 0;
ent.mUser3 = (AvHUser3)(long_data & kStatusMask);
long_data >>= kNumStatusBits;
ent.mTeam = (AvHTeamNumber)(long_data & kTeamMask);
long_data >>= kNumTeamBits;
ent.mY = (long_data & kPositionCoordinateMask)*kPositionNetworkConstant;
ent.mY = UnpackageCoord(long_data & kPositionCoordinateMask);
long_data >>= kNumPositionCoordinateBits;
ent.mX = (long_data & kPositionCoordinateMask)*kPositionNetworkConstant;
ent.mX = UnpackageCoord(long_data & kPositionCoordinateMask);
if (short_data & 0x1) // Player
if( (flags & kEntHierFlagPlayer) == kEntHierFlagPlayer ) // Player added/changed
{
ent.mSquadNumber = (short_data >> 10) & 7;
ent.mAngle = ((short_data >> 6) & 15) * 360.0f / 16.0f;
index = short_data & kPlayerIndexMask;
short_data >>= kNumPlayerIndexBits;
ent.mAngle = short_data & kAngleMask;
short_data >>= kNumAngleBits;
ent.mSquadNumber = short_data & kSquadMask;
}
else
else // Other item added/changed
{
index = short_data & kIndexMask;
ent.mSquadNumber = 0;
ent.mAngle = 0;
}
NewItems.insert( MapEntityMap::value_type( index, ent ) );
}
float UnpackageCoord( const int packaged_coord )
{
float returnVal = packaged_coord;
returnVal /= kPositionCoordinateScale;
returnVal -= kPositionCoordinateOffset;
return returnVal;
}
#else
void WriteEntHier( const int index, const MapEntity& ent, bool delete_flag, int& short_data, int& long_data );
int PackageCoord( const float coord );
void NetMsg_UpdateEntityHierarchy( entvars_t* const pev, const MapEntityMap& NewItems, const EntityListType& OldItems )
{
const int kMaxUpdatesPerPacket = 30;
if( NewItems.empty() && OldItems.empty() ) { return; } //nothing to send!
MapEntityMap::const_iterator new_current, new_end = NewItems.end();
MapEntity temp;
EntityListType::const_iterator old_current, old_end = OldItems.end();
int short_data, long_data, count = 1;
MESSAGE_BEGIN( MSG_ONE, g_msgUpdateEntityHierarchy, NULL, pev );
@ -1986,27 +2026,36 @@ const int kPositionNetworkConstant = 25;
MESSAGE_END();
MESSAGE_BEGIN( MSG_ONE, g_msgUpdateEntityHierarchy, NULL, pev );
}
WriteEntHier( new_current->first, new_current->second, true, short_data, long_data );
WriteEntHier( *old_current, temp, true, short_data, long_data );
WRITE_SHORT(short_data);
WRITE_LONG(long_data);
}
MESSAGE_END();
}
void WriteEntHier( const int index, const MapEntity& ent, bool delete_flag, int& short_data, int& long_data )
{
if( !delete_flag )
if( delete_flag )
{
long_data = ent.mX / kPositionNetworkConstant;
long_data <<= kNumPositionCoordinateBits;
long_data |= (int)(ent.mY / kPositionNetworkConstant);
long_data <<= kNumTeamBits;
long_data |= ent.mTeam;
long_data <<= kNumStatusBits;
long_data |= ent.mUser3;
ASSERT( (index & ~kIndexMask) == 0 );
short_data = index;
short_data <<= kNumFlagBits;
ASSERT( (short_data & kFlagMask) == 0 );
short_data |= kEntHierFlagDeletion;
return;
}
else
{ long_data = 0; }
long_data = PackageCoord(ent.mX);
long_data <<= kNumPositionCoordinateBits;
ASSERT((long_data & kPositionCoordinateMask) == 0);
long_data |= PackageCoord(ent.mY);
long_data <<= kNumTeamBits;
ASSERT((long_data & kTeamMask) == 0);
ASSERT((ent.mTeam & ~kTeamMask) == 0);
long_data |= ent.mTeam & kTeamMask;
long_data <<= kNumStatusBits;
ASSERT((long_data & kStatusMask) == 0);
ASSERT((ent.mUser3 & ~kStatusMask) == 0);
long_data |= ent.mUser3 & kStatusMask;
switch( ent.mUser3 )
{
@ -2016,12 +2065,39 @@ const int kPositionNetworkConstant = 25;
case AVH_USER3_ALIEN_PLAYER5: case AVH_USER3_ALIEN_EMBRYO:
case AVH_USER3_HEAVY:
{
int angle = (WrapFloat(ent.mAngle, 0, 360) / 360.0f) * 16;
short_data = (ent.mSquadNumber << 10) | (angle << 6) | (index << 1) | 1;
ASSERT( (ent.mSquadNumber & ~kSquadMask) == 0 );
short_data = ent.mSquadNumber;
short_data <<= kNumAngleBits;
int angle = WrapFloat(ent.mAngle,0,360);
angle /= 22.5f;
ASSERT( (short_data & kAngleMask) == 0);
ASSERT( (angle & ~kAngleMask) == 0);
short_data |= angle & kAngleMask;
short_data <<= kNumPlayerIndexBits;
ASSERT( ( short_data & kPlayerIndexMask ) == 0 );
ASSERT( ( index & ~kPlayerIndexMask ) == 0 );
short_data |= index & kIndexMask;
short_data <<= kNumFlagBits;
ASSERT( ( short_data & kFlagMask ) == 0 );
short_data |= kEntHierFlagPlayer;
break;
}
default:
short_data = (index << 1) | 0;
ASSERT( ( index & ~kIndexMask ) == 0 );
short_data = index & kIndexMask;
short_data <<= kNumFlagBits;
}
}
int PackageCoord( const float coord )
{
float adjustedCoord = coord;
adjustedCoord += kPositionCoordinateOffset;
adjustedCoord *= kPositionCoordinateScale;
int returnVal = adjustedCoord;
ASSERT( (returnVal & ~kPositionCoordinateMask) == 0);
returnVal &= kPositionCoordinateMask;
return returnVal;
}
#endif

View file

@ -1,7 +1,119 @@
#include <NexusClientInterface.h>
#include "AvHNexusClient.h"
#include "AvHNexusTunnelToServer.h"
#include "cl_dll/hud.h"
#include "cl_dll/cl_util.h"
string BASE64Encode(const byte_string& input);
int __MsgFunc_NexusData(const char *pszName, int iSize, void *pbuf);
bool AvHNexus::send(const unsigned char* data, const size_t length)
{
return false;
byte_string raw_data(data,length);
string cmdline("NexusData ");
cmdline += BASE64Encode(raw_data);
cmdline += "\n";
//ugliness due to pfnClientCmd wanting a non-const ptr
char* ptr = new char[cmdline.length()+1];
strncpy(ptr,cmdline.c_str(),cmdline.length());
ptr[cmdline.length()] = '\0';
gEngfuncs.pfnClientCmd(ptr);
delete[] ptr;
return true;
}
bool AvHNexus::recv(const unsigned char* data, const size_t length)
{
byte_string raw_data(data,length);
AvHNexus::TunnelToServer::getInstance()->insertMessage(raw_data);
return true;
}
void AvHNexus::startup(void)
{
gEngfuncs.pfnHookUserMsg("NexusBytes", __MsgFunc_NexusData);
// Nexus::setTunnelToServer(AvHNexus::TunnelToServer::getInstance());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Incominng message handler
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int __MsgFunc_NexusData(const char *pszName, int iSize, void *pbuf)
{
AvHNexus::recv((unsigned char*)pbuf, iSize);
return iSize;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Base 64 encoder
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
char Base64EncodeTable[65] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0- 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8-15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', //16-23
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', //24-31
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', //32-39
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', //40-47
'w', 'x', 'y', 'z', '0', '1', '2', '3', //48-55
'4', '5', '6', '7', '8', '9', '+', '/', //56-63
'=' }; //64 = padding
//debugged and working properly... do not disturb.
string BASE64Encode(const byte_string& input)
{
string output;
const byte* data = input.c_str();
size_t length = input.length();
int value, value2;
//handle input in 3 byte blocks
while( length > 2 )
{
value = data[0]; value >>= 2;
output.push_back(Base64EncodeTable[value]);
value = data[0]; value2 = data[1];
value &= 0x03; value <<= 4;
value2 &= 0xF0; value2 >>= 4; value |= value2;
output.push_back(Base64EncodeTable[value]);
value = data[1]; value2 = data[2];
value &= 0x0F; value <<= 2;
value2 &= 0xC0; value2 >>= 6; value |= value2;
output.push_back(Base64EncodeTable[value]);
value = data[2]; value &= 0x3F;
output.push_back(Base64EncodeTable[value]);
data += 3; length -= 3;
}
//handle remainder
switch(length)
{
case 0: //no remainder to process
break;
case 1: //process and pad with two =
value = data[0]; value >>= 2;
output.push_back(Base64EncodeTable[value]);
value = data[0]; value &= 0x03; value <<= 4;
output.push_back(Base64EncodeTable[value]);
output.push_back(Base64EncodeTable[64]);
output.push_back(Base64EncodeTable[64]);
break;
case 2: //process and pad with one =
value = data[0]; value >>= 2;
output.push_back(Base64EncodeTable[value]);
value = data[0]; value2 = data[1];
value &= 0x03; value <<= 4;
value2 &= 0xF0; value2 >>= 4; value |= value2;
output.push_back(Base64EncodeTable[value]);
value = data[1]; value &= 0x0F; value <<= 2;
output.push_back(Base64EncodeTable[value]);
output.push_back(Base64EncodeTable[64]);
break;
}
return output;
}

View file

@ -4,7 +4,7 @@
namespace AvHNexus
{
bool send(const unsigned char* data, const size_t length);
bool recv(const char* data, const size_t length);
bool recv(const unsigned char* data, const size_t length);
void startup(void);
void shutdown(void);

View file

@ -723,7 +723,7 @@ void AvHOverviewMap::Update(float inCurrentTime)
this->KillOldAlerts(inCurrentTime);
}
const float kPositionNetworkConstant = 0.25;
const float kPositionNetworkConstant = 2.0f;
void AvHOverviewMap::UpdateDrawData(float inCurrentTime)
{
@ -768,8 +768,9 @@ void AvHOverviewMap::UpdateDrawData(float inCurrentTime)
theDrawableEntity.mSquadNumber = theIter->second.mSquadNumber;
// Returns position relative to minimap, so add it back in
theDrawableEntity.mX += this->mMapExtents.GetMinMapX();
theDrawableEntity.mY += this->mMapExtents.GetMinMapY();
// commented this out here, commented out corresponding shift in AvHEntityHierarchy::BuildFromTeam at line 234
// theDrawableEntity.mX += this->mMapExtents.GetMinMapX();
// theDrawableEntity.mY += this->mMapExtents.GetMinMapY();
theDrawableEntity.mIsLocalPlayer = theIsLocalPlayer;
// Get additional information about the entity from the client state.
@ -836,7 +837,6 @@ void AvHOverviewMap::UpdateDrawData(float inCurrentTime)
}
std::sort(mDrawableEntityList.begin(), mDrawableEntityList.end(), DrawingOrderSort());
}
void AvHOverviewMap::UpdateOrders(const OrderListType& inOrderList, const EntityListType& inDrawPlayers)

View file

@ -3058,24 +3058,6 @@ bool AvHPlayer::GiveOrderToSelection(AvHOrderType inOrder, Vector inNormRay)
Vector theOrigin = this->GetVisualOrigin();
// #ifdef DEBUG
// vec3_t theStartPoint;
// VectorMA(theOrigin, kSelectionStartRange, inNormRay, theStartPoint);
//
// vec3_t theEndPoint;
// VectorMA(theOrigin, kSelectionEndRange, inNormRay, theEndPoint);
//
// vec3_t theValidOrigin;
// AvHSHUServerGetFirstNonSolidPoint(theStartPoint, theEndPoint, theValidOrigin);
//
// theValidOrigin.z -= BALANCE_VAR(kBiteDamage);
//
// CBaseEntity* pEnt = CBaseEntity::Create(kwsDebugEntity, theValidOrigin, Vector(0, 0, 0));
// ASSERT(pEnt);
// pEnt->pev->movetype = MOVETYPE_FLY;
// pEnt->pev->solid = SOLID_NOT;
// #endif
if(AvHCreateSpecificOrder((AvHTeamNumber)(this->pev->team), theOrigin, inOrder, inNormRay, theNewOrder))
{
this->GiveOrderToSelection(theNewOrder);
@ -7795,48 +7777,6 @@ void AvHPlayer::Spawn( void )
this->pev->iuser1 = 0;
}
//bool AvHPlayer::SpawnReinforcements(void)
//{
// bool theSuccess = false;
//
// // Does player have the points to do this?
// // Check first if someone bought you early, if so, is that person trying to come back in? Get him if possible.
// // For every player in the world
// edict_t* pent = FIND_ENTITY_BY_CLASSNAME(NULL, kAvHPlayerClassName);
// while (!FNullEnt(pent) && !theSuccess)
// {
// AvHPlayer* theFoundPlayer = dynamic_cast<AvHPlayer*>(CBaseEntity::Instance(pent));
// if(theFoundPlayer)
// {
// // Get team for calling player
// AvHTeamNumber theTeamNumber = this->GetTeam();
//
// // Make sure the player is a valid choice for reinforcements (the right playmode, hasn't observed this game, etc)
// if(theFoundPlayer->GetIsValidReinforcementFor(theTeamNumber))
// {
// // Join the team if you can
// if(GetGameRules()->AttemptToJoinTeam(theFoundPlayer, theTeamNumber))
// {
// theFoundPlayer->SetPlayMode(PLAYMODE_PLAYING);
// //theFoundPlayer->StopObserver();
//
// //ClientPrint(theFoundPlayer->pev, HUD_PRINTTALK, "You were called in as reinforcements!");
// theFoundPlayer->SendMessage(kYouReinforcement);
//
// // Decrement points of player issuing command
// // Send new player a message indicating who sent for them
// this->SendMessage(kYouCalledReinforcement);
//
// // Remember who bought you, next time you'll buy them if he exists
// theSuccess = true;
// }
// }
// }
// pent = FIND_ENTITY_BY_CLASSNAME(pent, kAvHPlayerClassName);
// }
// return theSuccess;
//}
void AvHPlayer::StartObservingIfNotAlready(void)
{
// Prevent this is the cvar is set
@ -8996,7 +8936,7 @@ void AvHPlayer::UpdateAlienUI()
}
}
// TODO: Update this less frequently than every tick or optimize so most blips are in PVS so their positions don't have to be sent down
// TODO: Send only changed blips, send only the changes for each blip.
void AvHPlayer::UpdateBlips()
{
if(this->mEnemyBlips != this->mClientEnemyBlips)

View file

@ -1149,7 +1149,7 @@ void AvHGetLineBounds(const Vector& vecStart, const Vector& vecEnd, Vector& outM
outMaxs[0] += kBoundingBoxPadding;
outMaxs[1] += kBoundingBoxPadding;
outMins[2] += kBoundingBoxPadding;
outMaxs[2] += kBoundingBoxPadding;
}

View file

@ -1,395 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="Util"
RootNamespace="Util"
SccProjectName=""
SccAuxPath=""
SccLocalPath=""
SccProvider="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)lib\$(ConfigurationName)/"
IntermediateDirectory="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="$(SolutionDir)"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/Util.pch"
AssemblerListingLocation="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
ObjectFile="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
ProgramDataBaseFileName="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(SolutionDir)\lib\$(ConfigurationName)\util.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)lib\$(ConfigurationName)/"
IntermediateDirectory="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="1"
AdditionalIncludeDirectories="$(SolutionDir)"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/Util.pch"
AssemblerListingLocation="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
ObjectFile="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
ProgramDataBaseFileName="$(SolutionDir)temp\$(ProjectName)\$(ConfigurationName)/"
WarningLevel="3"
WarnAsError="TRUE"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(SolutionDir)\lib\$(ConfigurationName)\util.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="Checksum.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="GammaTable.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="LinuxSupport.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="Mat3.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="MathUtil.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="Quat.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="Stacktrace.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="STLUtil.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="Tokenizer.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="Zassert.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath="ZassertTemplate.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="Checksum.h">
</File>
<File
RelativePath="CString.h">
</File>
<File
RelativePath="GammaTable.h">
</File>
<File
RelativePath="LinuxSupport.h">
</File>
<File
RelativePath="Mat3.h">
</File>
<File
RelativePath="MathUtil.h">
</File>
<File
RelativePath="nowarnings.h">
</File>
<File
RelativePath="Quat.h">
</File>
<File
RelativePath="Stacktrace.h">
</File>
<File
RelativePath="STLUtil.h">
</File>
<File
RelativePath="StringVector.h">
</File>
<File
RelativePath="Tokenizer.h">
</File>
<File
RelativePath="Zassert.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>