NS/main/source/mod/AvHEntityHierarchy.cpp
XP-Cagey b918c731aa 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
2005-05-05 15:20:23 +00:00

322 lines
No EOL
9.3 KiB
C++

//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
//
// The copyright to the contents herein is the property of Charles G. Cleveland.
// The contents may be used and/or copied only with the written permission of
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: AvHEntityHierarchy.cpp $
// $Date: 2002/10/16 00:53:31 $
//
//-------------------------------------------------------------------------------
// $Log: AvHEntityHierarchy.cpp,v $
// Revision 1.10 2002/10/16 00:53:31 Flayra
// - Updated with new infinite loop data
//
// Revision 1.9 2002/07/25 16:57:59 flayra
// - Linux changes
//
// Revision 1.8 2002/07/24 21:16:36 Flayra
// - Linux issues
//
// Revision 1.7 2002/07/24 20:05:22 Flayra
// - Linux issues
//
// Revision 1.6 2002/07/24 19:44:05 Flayra
// - Linux issues
//
// Revision 1.5 2002/07/24 18:55:52 Flayra
// - Linux case sensitivity stuff
//
// Revision 1.4 2002/07/08 16:56:12 Flayra
// - Workaround to infinite loop encountered during playtest: look into this more
//
// Revision 1.3 2002/06/25 17:55:49 Flayra
// - Quick fix during playtesting...why is this happening?
//
//===============================================================================
#include "util/nowarnings.h"
#include "mod/AvHEntityHierarchy.h"
#include "mod/AvHNetworkMessages.h"
#ifdef AVH_SERVER
#include "dlls/extdll.h"
#include "dlls/util.h"
#include "mod/AvHPlayer.h"
#include "mod/AvHTeam.h"
#include "mod/AvHServerUtil.h"
#include "mod/AvHGamerules.h"
#include "mod/AvHMarineEquipment.h"
#include "mod/AvHSharedUtil.h"
#include "util/MathUtil.h"
#endif
#ifdef AVH_CLIENT
#include "cl_dll/chud.h"
#include "cl_dll/cl_util.h"
#endif
////////////
// Shared //
////////////
AvHEntityHierarchy::AvHEntityHierarchy()
{
this->Clear();
}
void AvHEntityHierarchy::Clear()
{
this->mEntityList.clear();
}
bool AvHEntityHierarchy::operator!=(const AvHEntityHierarchy& inHierarchy) const
{
return !this->operator==(inHierarchy);
}
bool AvHEntityHierarchy::operator==(const AvHEntityHierarchy& inHierarchy) const
{
bool theAreEqual = false;
// NOTE: This could cause problems if entity hierarchy is stored in a hash or something
if(this->mEntityList == inHierarchy.mEntityList)
{
theAreEqual = true;
}
return theAreEqual;
}
// Gets a list of all entity infos, with each one being a muxed entity index and flags
void AvHEntityHierarchy::GetEntityInfoList(MapEntityMap& outList) const
{
outList = mEntityList;
}
////////////////
// end shared //
////////////////
////////////
// Server //
////////////
#ifdef AVH_SERVER
int GetHotkeyGroupContainingPlayer(AvHPlayer* player)
{
AvHTeam* theTeam = player->GetTeamPointer();
if(theTeam)
{
for (int i = 0; i < kNumHotkeyGroups; ++i)
{
EntityListType theGroup = theTeam->GetGroup(i);
for (int j = 0; j < (signed)theGroup.size(); ++j)
{
if (theGroup[j] == player->entindex())
{
return i;
}
}
}
}
return -1;
}
void AvHEntityHierarchy::BuildFromTeam(const AvHTeam* inTeam, BaseEntityListType& inBaseEntityList)
{
this->Clear();
if (inTeam->GetTeamType() == AVH_CLASS_TYPE_MARINE ||
inTeam->GetTeamType() == AVH_CLASS_TYPE_ALIEN)
{
// Loop through all entities in the world
for(BaseEntityListType::iterator theIter = inBaseEntityList.begin(); theIter != inBaseEntityList.end(); theIter++)
{
CBaseEntity* theBaseEntity = *theIter;
int theEntityIndex = theBaseEntity->entindex();
bool theEntityIsVisible = (theBaseEntity->pev->team == (int)(inTeam->GetTeamNumber())) ||
GetHasUpgrade(theBaseEntity->pev->iuser4, MASK_VIS_SIGHTED);
bool theEntityIsDetected = GetHasUpgrade(theBaseEntity->pev->iuser4, MASK_VIS_DETECTED);
// Don't send ammo, health, weapons, or scans
bool theIsTransient = ((AvHUser3)(theBaseEntity->pev->iuser3) == AVH_USER3_MARINEITEM) || (theBaseEntity->pev->classname == MAKE_STRING(kwsScan));
MapEntity mapEntity;
mapEntity.mX = theBaseEntity->pev->origin.x;
mapEntity.mY = theBaseEntity->pev->origin.y;
mapEntity.mUser3 = (AvHUser3)(theBaseEntity->pev->iuser3);
// Don't draw detected blips as their real selves
if(!theEntityIsVisible && theEntityIsDetected)
mapEntity.mUser3 = AVH_USER3_UNKNOWN;
mapEntity.mAngle = theBaseEntity->pev->angles[1];
mapEntity.mTeam = (AvHTeamNumber)(theBaseEntity->pev->team);
mapEntity.mSquadNumber = 0;
bool sendEntity = false;
if (mapEntity.mUser3 == AVH_USER3_HIVE)
{
if (!theEntityIsVisible)
{
mapEntity.mTeam = TEAM_IND;
}
sendEntity = true;
}
else if (mapEntity.mUser3 == AVH_USER3_WELD)
{
vec3_t theEntityOrigin = AvHSHUGetRealLocation(theBaseEntity->pev->origin, theBaseEntity->pev->mins, theBaseEntity->pev->maxs);
mapEntity.mX = theEntityOrigin.x;
mapEntity.mY = theEntityOrigin.y;
sendEntity = true;
}
else if (mapEntity.mUser3 == AVH_USER3_FUNC_RESOURCE)
{
sendEntity = true;
}
else if ((theEntityIsVisible || theEntityIsDetected) && !(theBaseEntity->pev->effects & EF_NODRAW) && !theIsTransient)
{
AvHPlayer* thePlayer = dynamic_cast<AvHPlayer*>(theBaseEntity);
if (thePlayer)
{
ASSERT(theEntityIndex > 0);
ASSERT(theEntityIndex <= 32);
mapEntity.mSquadNumber = GetHotkeyGroupContainingPlayer(thePlayer) + 1;
if ((thePlayer->GetPlayMode() == PLAYMODE_PLAYING) && !thePlayer->GetIsSpectator())
{
sendEntity = true;
// If the player has the heavy armor upgrade switch the
// user3 to something that will let us reconstruct that later.
if (thePlayer->pev->iuser3 == AVH_USER3_MARINE_PLAYER &&
GetHasUpgrade(thePlayer->pev->iuser4, MASK_UPGRADE_13))
{
mapEntity.mUser3 = AVH_USER3_HEAVY;
}
}
}
else
{
if (mapEntity.mUser3 != AVH_USER3_HEAVY)
{
sendEntity = true;
}
}
}
if (sendEntity)
{
const AvHMapExtents& theMapExtents = GetGameRules()->GetMapExtents();
// 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;
mEntityList[theEntityIndex] = mapEntity;
}
}
}
}
// Returns true when something was sent
bool AvHEntityHierarchy::SendToNetworkStream(AvHEntityHierarchy& inClientHierarchy, entvars_t* inPlayer)
{
// Get iterators for both hierarchies
MapEntityMap::const_iterator clientIter = inClientHierarchy.mEntityList.begin();
MapEntityMap::const_iterator clientEnd = inClientHierarchy.mEntityList.end();
MapEntityMap::const_iterator serverIter = mEntityList.begin();
MapEntityMap::const_iterator serverEnd = mEntityList.end();
// Create maps for changes
MapEntityMap NewItems; //to be added or changed
EntityListType OldItems; //to be deleted
//TODO : replace OldItems with vector<int>
while (clientIter != clientEnd && serverIter != serverEnd)
{
if (serverIter->first < clientIter->first)
{
NewItems.insert( *serverIter );
++serverIter;
continue;
}
if (serverIter->first > clientIter->first)
{
OldItems.push_back( clientIter->first );
++clientIter;
continue;
}
if (clientIter->second != serverIter->second)
{
NewItems.insert( *serverIter );
}
++serverIter;
++clientIter;
}
while(serverIter != serverEnd)
{
NewItems.insert( *serverIter );
++serverIter;
}
while(clientIter != clientEnd)
{
OldItems.push_back( clientIter->first );
++clientIter;
}
NetMsg_UpdateEntityHierarchy( inPlayer, NewItems, OldItems );
return (!NewItems.empty() || !OldItems.empty());
}
#endif
////////////////
// end server //
////////////////
bool AvHEntityHierarchy::InsertEntity( const int inIndex, const MapEntity &inEntity )
{
this->mEntityList[inIndex] = inEntity;
return true;
}
bool AvHEntityHierarchy::DeleteEntity( const int inIndex )
{
MapEntityMap::iterator loc = this->mEntityList.find(inIndex);
if( loc == this->mEntityList.end() )
{ return false; }
this->mEntityList.erase(loc);
return true;
}