mirror of
https://github.com/ENSL/NS.git
synced 2024-11-14 17:01:29 +00:00
b918c731aa
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
322 lines
No EOL
9.3 KiB
C++
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;
|
|
} |