コード例 #1
0
ファイル: tv_relay_module.c プロジェクト: Clever-Boy/qfusion
static inline bool TV_Module_CM_AreasConnected( relay_t *relay, int area1, int area2 )
{
	if( !relay )
	{
		Com_Printf( "Error: TV_Module_CM_AreasConnected: Relay not set\n" );
		return false;
	}

	return CM_AreasConnected( relay->cms, area1, area2 );
}
コード例 #2
0
ファイル: sv_game.cpp プロジェクト: TheDushan/OpenWolf
/*
=================
SV_inPVS

Also checks portalareas so that doors block sight
=================
*/
bool SV_inPVS(const vec3_t p1, const vec3_t p2) {
	int             leafnum, cluster, area1, area2;
	byte           *mask;

	leafnum = CM_PointLeafnum(p1);
	cluster = CM_LeafCluster(leafnum);
	area1 = CM_LeafArea(leafnum);
	mask = CM_ClusterPVS(cluster);

	leafnum = CM_PointLeafnum(p2);
	cluster = CM_LeafCluster(leafnum);
	area2 = CM_LeafArea(leafnum);
	if(mask && (!(mask[cluster >> 3] & (1 << (cluster & 7))))) {
		return false;
	}
	if(!CM_AreasConnected(area1, area2)) {
		return false; // a door blocks sight
	}
	return true;
}
コード例 #3
0
ファイル: sv_game.cpp プロジェクト: TheDushan/OpenWolf
/*
====================
SV_GameSystemCalls

The module is making a system call
====================
*/
intptr_t SV_GameSystemCalls(intptr_t * args) {
	switch (args[0]) {
		case G_PRINT:
			Com_Printf("%s", (char *)VMA(1));
			return 0;
		case G_ERROR:
			Com_Error(ERR_DROP, "%s", (char *)VMA(1));
			return 0;
		case G_MILLISECONDS:
			return Sys_Milliseconds();
		case G_CVAR_REGISTER:
			Cvar_Register((vmCvar_t*)VMA(1), (char*)VMA(2), (char*)VMA(3), args[4]);
			return 0;
		case G_CVAR_UPDATE:
			Cvar_Update((vmCvar_t*)VMA(1));
			return 0;
		case G_CVAR_SET:
			Cvar_Set((const char *)VMA(1), (const char *)VMA(2));
			return 0;
		case G_CVAR_VARIABLE_INTEGER_VALUE:
			return Cvar_VariableIntegerValue((const char *)VMA(1));
		case G_CVAR_VARIABLE_STRING_BUFFER:
			Cvar_VariableStringBuffer((char *)VMA(1), (char*)VMA(2), args[3]);
			return 0;
		case G_CVAR_LATCHEDVARIABLESTRINGBUFFER:
			Cvar_LatchedVariableStringBuffer((char *)VMA(1), (char*)VMA(2), args[3]);
			return 0;
		case G_ARGC:
			return Cmd_Argc();
		case G_ARGV:
			Cmd_ArgvBuffer(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_SEND_CONSOLE_COMMAND:
			Cbuf_ExecuteText(args[1], (char *)VMA(2));
			return 0;
		case G_FS_FOPEN_FILE:
			return FS_FOpenFileByMode((char *)VMA(1), (fileHandle_t*)VMA(2), (fsMode_t)args[3]);
		case G_FS_READ:
			FS_Read2(VMA(1), args[2], args[3]);
			return 0;
		case G_FS_WRITE:
			return FS_Write(VMA(1), args[2], args[3]);
		case G_FS_RENAME:
			FS_Rename((char *)VMA(1), (char *)VMA(2));
			return 0;
		case G_FS_FCLOSE_FILE:
			FS_FCloseFile(args[1]);
			return 0;
		case G_FS_GETFILELIST:
			return FS_GetFileList((char *)VMA(1), (char *)VMA(2), (char*)VMA(3), args[4]);
		case G_LOCATE_GAME_DATA:
			SV_LocateGameData((sharedEntity_t*)VMA(1), args[2], args[3], (playerState_t*)VMA(4), args[5]);
			return 0;
		case G_DROP_CLIENT:
			SV_GameDropClient(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_SEND_SERVER_COMMAND:
			SV_GameSendServerCommand(args[1], (char*)VMA(2));
			return 0;
		case G_LINKENTITY:
			SV_LinkEntity((sharedEntity_t*)VMA(1));
			return 0;
		case G_UNLINKENTITY:
			SV_UnlinkEntity((sharedEntity_t*)VMA(1));
			return 0;
		case G_ENTITIES_IN_BOX:
			return SV_AreaEntities((float*)VMA(1), (float*)VMA(2), (int*)VMA(3), args[4]);
		case G_ENTITY_CONTACT:
			return SV_EntityContact((float*)VMA(1), (float*)VMA(2), (sharedEntity_t*)VMA(3), TT_AABB);
		case G_ENTITY_CONTACTCAPSULE:
			return SV_EntityContact((float*)VMA(1), (float*)VMA(2), (sharedEntity_t*)VMA(3), TT_CAPSULE);
		case G_TRACE:
			SV_Trace((trace_t*)VMA(1), (float*)VMA(2), (float*)VMA(3), (float*)VMA(4), (float*)VMA(5), args[6], args[7], TT_AABB);
			return 0;
		case G_TRACECAPSULE:
			SV_Trace((trace_t*)VMA(1), (float*)VMA(2), (float*)VMA(3), (float*)VMA(4), (float*)VMA(5), args[6], args[7], TT_CAPSULE);
			return 0;
		case G_POINT_CONTENTS:
			return SV_PointContents((float*)VMA(1), args[2]);
		case G_SET_BRUSH_MODEL:
			SV_SetBrushModel((sharedEntity_t*)VMA(1), (char*)VMA(2));
			return 0;
		case G_IN_PVS:
			return SV_inPVS((float*)VMA(1), (float*)VMA(2));
		case G_IN_PVS_IGNORE_PORTALS:
			return SV_inPVSIgnorePortals((float*)VMA(1), (float*)VMA(2));
		case G_SET_CONFIGSTRING:
			SV_SetConfigstring(args[1], (char*)VMA(2));
			return 0;
		case G_GET_CONFIGSTRING:
			SV_GetConfigstring(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_SET_CONFIGSTRING_RESTRICTIONS:
			SV_SetConfigstringRestrictions( args[1], (clientList_t*)VMA(2) );
			return 0;
		case G_SET_USERINFO:
			SV_SetUserinfo(args[1], (char*)VMA(2));
			return 0;
		case G_GET_USERINFO:
			SV_GetUserinfo(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_GET_SERVERINFO:
			SV_GetServerinfo((char*)VMA(1), args[2]);
			return 0;
		case G_ADJUST_AREA_PORTAL_STATE:
			SV_AdjustAreaPortalState((sharedEntity_t*)VMA(1),(bool)args[2]);
			return 0;
		case G_AREAS_CONNECTED:
			return CM_AreasConnected(args[1], args[2]);
		case G_UPDATE_SHARED_CONFIG:
			SV_UpdateSharedConfig( args[1], (char*)VMA(2) );
			return 0;
		case G_BOT_ALLOCATE_CLIENT:
			return SV_BotAllocateClient(args[1]);
		case G_BOT_FREE_CLIENT:
			SV_BotFreeClient(args[1]);
			return 0;
		case G_GET_USERCMD:
			SV_GetUsercmd(args[1], (usercmd_t*)VMA(2));
			return 0;
		case G_GET_ENTITY_TOKEN: {
			const char     *s;

			s = COM_Parse(&sv.entityParsePoint);
			Q_strncpyz((char*)VMA(1), s, args[2]);
			if(!sv.entityParsePoint && !s[0]) {
				return false;
			} else {
				return true;
			}
		}
		case G_DEBUG_POLYGON_CREATE:
			return BotImport_DebugPolygonCreate(args[1], args[2], (vec3_t*)VMA(3));
		case G_DEBUG_POLYGON_DELETE:
			BotImport_DebugPolygonDelete(args[1]);
			return 0;
		case G_REAL_TIME:
			return Com_RealTime((qtime_t*)VMA(1));
		case G_SNAPVECTOR:
			Q_SnapVector((float*)VMA(1));
			return 0;
		case G_SEND_GAMESTAT:
			SV_MasterGameStat( (char*)VMA(1) );
			return 0;
		case G_ADDCOMMAND:
			Cmd_AddCommand( (char*)VMA(1), NULL, (char*)VMA(3) );
			return 0;
		case G_REMOVECOMMAND:
			Cmd_RemoveCommand( (char*)VMA(1) );
			return 0;
		case G_GETTAG:
			return SV_GetTag(args[1], args[2], (char*)VMA(3), (orientation_t*)VMA(4));
		case G_REGISTERTAG:
			return SV_LoadTag((char*)VMA(1));
		case G_REGISTERSOUND:
			return S_RegisterSound((char*)VMA(1), (bool)args[2]);
		case G_GET_SOUND_LENGTH:
			return S_GetSoundLength(args[1]);
		case G_PARSE_ADD_GLOBAL_DEFINE:
			return Parse_AddGlobalDefine( (char*)VMA(1) );
		case G_PARSE_LOAD_SOURCE:
			return Parse_LoadSourceHandle( (char*)VMA(1) );
		case G_PARSE_FREE_SOURCE:
			return Parse_FreeSourceHandle( args[1] );
		case G_PARSE_READ_TOKEN:
			return Parse_ReadTokenHandle( args[1], (pc_token_t*)VMA(2) );
		case G_PARSE_SOURCE_FILE_AND_LINE:
			return Parse_SourceFileAndLine( args[1], (char*)VMA(2), (int*)VMA(3) );
		case BOTLIB_SETUP:
			return SV_BotLibSetup();
		case BOTLIB_SHUTDOWN:
			return SV_BotLibShutdown();
		case BOTLIB_LIBVAR_SET:
			return botlib_export->BotLibVarSet((char*)VMA(1), (char*)VMA(2));
		case BOTLIB_LIBVAR_GET:
			return botlib_export->BotLibVarGet((char*)VMA(1), (char*)VMA(2), args[3]);
		case BOTLIB_PC_ADD_GLOBAL_DEFINE:
			return Parse_AddGlobalDefine( (char*)VMA(1) );
		case BOTLIB_PC_LOAD_SOURCE:
			return Parse_LoadSourceHandle((char*)VMA(1));
		case BOTLIB_PC_FREE_SOURCE:
			return Parse_FreeSourceHandle(args[1]);
		case BOTLIB_PC_READ_TOKEN:
			return Parse_ReadTokenHandle(args[1], (pc_token_t*)VMA(2));
		case BOTLIB_PC_SOURCE_FILE_AND_LINE:
			return Parse_SourceFileAndLine(args[1], (char*)VMA(2), (int*)VMA(3));
		case BOTLIB_PC_UNREAD_TOKEN:
			Parse_UnreadLastTokenHandle(args[1]);
			return 0;
		case BOTLIB_START_FRAME:
			return botlib_export->BotLibStartFrame(VMF(1));
		case BOTLIB_LOAD_MAP:
			return botlib_export->BotLibLoadMap((char*)VMA(1));
		case BOTLIB_UPDATENTITY:
			return botlib_export->BotLibUpdateEntity(args[1], (bot_entitystate_t*)VMA(2));
		case BOTLIB_TEST:
			return botlib_export->Test( args[1], (char*)VMA(2), (float*)VMA(3), (float*)VMA(4) );
		case BOTLIB_GET_SNAPSHOT_ENTITY:
			return SV_BotGetSnapshotEntity(args[1], args[2]);
		case BOTLIB_GET_CONSOLE_MESSAGE:
			return SV_BotGetConsoleMessage(args[1], (char*)VMA(2), args[3]);
		case BOTLIB_USER_COMMAND:
			SV_ClientThink(&svs.clients[args[1]], (usercmd_t*)VMA(2));
			return 0;
		case BOTLIB_AAS_ENTITY_INFO:
			botlib_export->aas.AAS_EntityInfo(args[1], (aas_entityinfo_s*)VMA(2));
			return 0;
		case BOTLIB_AAS_INITIALIZED:
			return botlib_export->aas.AAS_Initialized();
		case BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX:
			botlib_export->aas.AAS_PresenceTypeBoundingBox( args[1], (float*)VMA(2), (float*)VMA(3) );
			return 0;
		case BOTLIB_AAS_TIME:
			return FloatAsInt(botlib_export->aas.AAS_Time());
		case BOTLIB_AAS_SETCURRENTWORLD:
			botlib_export->aas.AAS_SetCurrentWorld(args[1]);
			return 0;
		case BOTLIB_AAS_POINT_AREA_NUM:
			return botlib_export->aas.AAS_PointAreaNum( (float*)VMA(1) );
		case BOTLIB_AAS_TRACE_AREAS:
			return botlib_export->aas.AAS_TraceAreas( (float*)VMA(1), (float*)VMA(2), (int*)VMA(3), (vec3_t*)VMA(4), args[5] );
		case BOTLIB_AAS_BBOX_AREAS:
			return botlib_export->aas.AAS_BBoxAreas( (float*)VMA(1), (float*)VMA(2), (int*)VMA(3), args[4] );
		case BOTLIB_AAS_AREA_CENTER:
			botlib_export->aas.AAS_AreaCenter(args[1], (float*)VMA(2));
			return 0;
		case BOTLIB_AAS_AREA_WAYPOINT:
			return botlib_export->aas.AAS_AreaWaypoint(args[1], (float*)VMA(2));
		case BOTLIB_AAS_POINT_CONTENTS:
			return botlib_export->aas.AAS_PointContents((float*)VMA(1));
		case BOTLIB_AAS_NEXT_BSP_ENTITY:
			return botlib_export->aas.AAS_NextBSPEntity(args[1]);
		case BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_ValueForBSPEpairKey(args[1], (char*)VMA(2), (char*)VMA(3), args[4]);
		case BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_VectorForBSPEpairKey(args[1], (char*)VMA(2), (float*)VMA(3));
		case BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_FloatForBSPEpairKey(args[1], (char*)VMA(2), (float*)VMA(3));
		case BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY:
			return botlib_export->aas.AAS_IntForBSPEpairKey(args[1], (char*)VMA(2), (int*)VMA(3));
		case BOTLIB_AAS_AREA_REACHABILITY:
			return botlib_export->aas.AAS_AreaReachability(args[1]);
		case BOTLIB_AAS_AREA_LADDER:
			return botlib_export->aas.AAS_AreaLadder(args[1]);
		case BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA:
			return botlib_export->aas.AAS_AreaTravelTimeToGoalArea(args[1], (float*)VMA(2), args[3], args[4]);
		case BOTLIB_AAS_SWIMMING:
			return botlib_export->aas.AAS_Swimming((float*)VMA(1));
		case BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT:
			return botlib_export->aas.AAS_PredictClientMovement((aas_clientmove_s*)VMA(1), args[2], (float*)VMA(3), args[4], args[5], (float*)VMA(6), (float*)VMA(7), args[8], args[9], VMF(10), args[11], args[12], args[13]);
		case BOTLIB_AAS_RT_SHOWROUTE:
			botlib_export->aas.AAS_RT_ShowRoute((float*)VMA(1), args[2], args[3]);
			return 0;
		case BOTLIB_AAS_NEARESTHIDEAREA:
			return botlib_export->aas.AAS_NearestHideArea(args[1], (float*)VMA(2), args[3], args[4], (float*)VMA(5), args[6], args[7], VMF(8), (float*)VMA(9));
		case BOTLIB_AAS_LISTAREASINRANGE:
			return botlib_export->aas.AAS_ListAreasInRange((float*)VMA(1), args[2], VMF(3), args[4], (vec3_t*)VMA(5), args[6]);
		case BOTLIB_AAS_AVOIDDANGERAREA:
			return botlib_export->aas.AAS_AvoidDangerArea((float*)VMA(1), args[2], (float*)VMA(3), args[4], VMF(5), args[6]);
		case BOTLIB_AAS_RETREAT:
			return botlib_export->aas.AAS_Retreat((int*)VMA(1), args[2], (float*)VMA(3), args[4], (float*)VMA(5), args[6], VMF(7), VMF(8), args[9]);
		case BOTLIB_AAS_ALTROUTEGOALS:
			return botlib_export->aas.AAS_AlternativeRouteGoals((float*)VMA(1), (float*)VMA(2), args[3], (aas_altroutegoal_t*)VMA(4), args[5], args[6]);
		case BOTLIB_AAS_SETAASBLOCKINGENTITY:
			botlib_export->aas.AAS_SetAASBlockingEntity((float*)VMA(1), (float*)VMA(2), args[3]);
			return 0;
		case BOTLIB_AAS_RECORDTEAMDEATHAREA:
			botlib_export->aas.AAS_RecordTeamDeathArea((float*)VMA(1), args[2], args[3], args[4], args[5]);
			return 0;
		case BOTLIB_EA_SAY:
			botlib_export->ea.EA_Say(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_SAY_TEAM:
			botlib_export->ea.EA_SayTeam(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_USE_ITEM:
			botlib_export->ea.EA_UseItem(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_DROP_ITEM:
			botlib_export->ea.EA_DropItem(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_USE_INV:
			botlib_export->ea.EA_UseInv(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_DROP_INV:
			botlib_export->ea.EA_DropInv(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_GESTURE:
			botlib_export->ea.EA_Gesture(args[1]);
			return 0;
		case BOTLIB_EA_COMMAND:
			botlib_export->ea.EA_Command(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_EA_SELECT_WEAPON:
			botlib_export->ea.EA_SelectWeapon(args[1], args[2]);
			return 0;
		case BOTLIB_EA_TALK:
			botlib_export->ea.EA_Talk(args[1]);
			return 0;
		case BOTLIB_EA_ATTACK:
			botlib_export->ea.EA_Attack(args[1]);
			return 0;
		case BOTLIB_EA_RELOAD:
			botlib_export->ea.EA_Reload(args[1]);
			return 0;
		case BOTLIB_EA_USE:
			botlib_export->ea.EA_Use(args[1]);
			return 0;
		case BOTLIB_EA_RESPAWN:
			botlib_export->ea.EA_Respawn(args[1]);
			return 0;
		case BOTLIB_EA_JUMP:
			botlib_export->ea.EA_Jump(args[1]);
			return 0;
		case BOTLIB_EA_DELAYED_JUMP:
			botlib_export->ea.EA_DelayedJump(args[1]);
			return 0;
		case BOTLIB_EA_CROUCH:
			botlib_export->ea.EA_Crouch(args[1]);
			return 0;
		case BOTLIB_EA_WALK:
			botlib_export->ea.EA_Walk(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_UP:
			botlib_export->ea.EA_MoveUp(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_DOWN:
			botlib_export->ea.EA_MoveDown(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_FORWARD:
			botlib_export->ea.EA_MoveForward(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_BACK:
			botlib_export->ea.EA_MoveBack(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_LEFT:
			botlib_export->ea.EA_MoveLeft(args[1]);
			return 0;
		case BOTLIB_EA_MOVE_RIGHT:
			botlib_export->ea.EA_MoveRight(args[1]);
			return 0;
		case BOTLIB_EA_MOVE:
			botlib_export->ea.EA_Move(args[1], (float*)VMA(2), VMF(3));
			return 0;
		case BOTLIB_EA_VIEW:
			botlib_export->ea.EA_View(args[1], (float*)VMA(2));
			return 0;
		case BOTLIB_EA_PRONE:
			botlib_export->ea.EA_Prone(args[1]);
			return 0;
		case BOTLIB_EA_END_REGULAR:
			botlib_export->ea.EA_EndRegular(args[1], VMF(2));
			return 0;
		case BOTLIB_EA_GET_INPUT:
			botlib_export->ea.EA_GetInput(args[1], VMF(2), (bot_input_t*)VMA(3));
			return 0;
		case BOTLIB_EA_RESET_INPUT:
			botlib_export->ea.EA_ResetInput(args[1], (bot_input_t*)VMA(2));
			return 0;
		case BOTLIB_AI_LOAD_CHARACTER:
			return botlib_export->ai.BotLoadCharacter((char*)VMA(1), args[2]);
		case BOTLIB_AI_FREE_CHARACTER:
			botlib_export->ai.BotFreeCharacter(args[1]);
			return 0;
		case BOTLIB_AI_CHARACTERISTIC_FLOAT:
			return FloatAsInt(botlib_export->ai.Characteristic_Float(args[1], args[2]));
		case BOTLIB_AI_CHARACTERISTIC_BFLOAT:
			return FloatAsInt(botlib_export->ai.Characteristic_BFloat(args[1], args[2], VMF(3), VMF(4)));
		case BOTLIB_AI_CHARACTERISTIC_INTEGER:
			return botlib_export->ai.Characteristic_Integer(args[1], args[2]);
		case BOTLIB_AI_CHARACTERISTIC_BINTEGER:
			return botlib_export->ai.Characteristic_BInteger(args[1], args[2], args[3], args[4]);
		case BOTLIB_AI_CHARACTERISTIC_STRING:
			botlib_export->ai.Characteristic_String(args[1], args[2], (char*)VMA(3), args[4]);
			return 0;
		case BOTLIB_AI_ALLOC_CHAT_STATE:
			return botlib_export->ai.BotAllocChatState();
		case BOTLIB_AI_FREE_CHAT_STATE:
			botlib_export->ai.BotFreeChatState(args[1]);
			return 0;
		case BOTLIB_AI_QUEUE_CONSOLE_MESSAGE:
			botlib_export->ai.BotQueueConsoleMessage(args[1], args[2], (char*)VMA(3));
			return 0;
		case BOTLIB_AI_REMOVE_CONSOLE_MESSAGE:
			botlib_export->ai.BotRemoveConsoleMessage(args[1], args[2]);
			return 0;
		case BOTLIB_AI_NEXT_CONSOLE_MESSAGE:
			return botlib_export->ai.BotNextConsoleMessage(args[1], (bot_consolemessage_s*)VMA(2));
		case BOTLIB_AI_NUM_CONSOLE_MESSAGE:
			return botlib_export->ai.BotNumConsoleMessages(args[1]);
		case BOTLIB_AI_INITIAL_CHAT:
			botlib_export->ai.BotInitialChat(args[1], (char*)VMA(2), args[3], (char*)VMA(4), (char*)VMA(5), (char*)VMA(6), (char*)VMA(7), (char*)VMA(8), (char*)VMA(9), (char*)VMA(10), (char*)VMA(11));
			return 0;
		case BOTLIB_AI_NUM_INITIAL_CHATS:
			return botlib_export->ai.BotNumInitialChats(args[1], (char*)VMA(2));
		case BOTLIB_AI_REPLY_CHAT:
			return botlib_export->ai.BotReplyChat(args[1], (char*)VMA(2), args[3], args[4], (char*)VMA(5), (char*)VMA(6), (char*)VMA(7), (char*)VMA(8), (char*)VMA(9), (char*)VMA(10), (char*)VMA(11), (char*)VMA(12));
		case BOTLIB_AI_CHAT_LENGTH:
			return botlib_export->ai.BotChatLength(args[1]);
		case BOTLIB_AI_ENTER_CHAT:
			botlib_export->ai.BotEnterChat(args[1], args[2], args[3]);
			return 0;
		case BOTLIB_AI_GET_CHAT_MESSAGE:
			botlib_export->ai.BotGetChatMessage(args[1], (char*)VMA(2), args[3]);
			return 0;
		case BOTLIB_AI_STRING_CONTAINS:
			return botlib_export->ai.StringContains((char*)VMA(1), (char*)VMA(2), args[3]);
		case BOTLIB_AI_FIND_MATCH:
			return botlib_export->ai.BotFindMatch((char*)VMA(1), (bot_match_s*)VMA(2), args[3]);
		case BOTLIB_AI_MATCH_VARIABLE:
			botlib_export->ai.BotMatchVariable((bot_match_s*)VMA(1), args[2], (char*)VMA(3), args[4]);
			return 0;
		case BOTLIB_AI_UNIFY_WHITE_SPACES:
			botlib_export->ai.UnifyWhiteSpaces((char*)VMA(1));
			return 0;
		case BOTLIB_AI_REPLACE_SYNONYMS:
			botlib_export->ai.BotReplaceSynonyms((char*)VMA(1), args[2]);
			return 0;
		case BOTLIB_AI_LOAD_CHAT_FILE:
			return botlib_export->ai.BotLoadChatFile(args[1], (char*)VMA(2), (char*)VMA(3));
		case BOTLIB_AI_SET_CHAT_GENDER:
			botlib_export->ai.BotSetChatGender(args[1], args[2]);
			return 0;
		case BOTLIB_AI_SET_CHAT_NAME:
			botlib_export->ai.BotSetChatName(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_AI_RESET_GOAL_STATE:
			botlib_export->ai.BotResetGoalState(args[1]);
			return 0;
		case BOTLIB_AI_RESET_AVOID_GOALS:
			botlib_export->ai.BotResetAvoidGoals(args[1]);
			return 0;
		case BOTLIB_AI_REMOVE_FROM_AVOID_GOALS:
			botlib_export->ai.BotRemoveFromAvoidGoals(args[1], args[2]);
			return 0;
		case BOTLIB_AI_PUSH_GOAL:
			botlib_export->ai.BotPushGoal(args[1], (bot_goal_s*)VMA(2));
			return 0;
		case BOTLIB_AI_POP_GOAL:
			botlib_export->ai.BotPopGoal(args[1]);
			return 0;
		case BOTLIB_AI_EMPTY_GOAL_STACK:
			botlib_export->ai.BotEmptyGoalStack(args[1]);
			return 0;
		case BOTLIB_AI_DUMP_AVOID_GOALS:
			botlib_export->ai.BotDumpAvoidGoals(args[1]);
			return 0;
		case BOTLIB_AI_DUMP_GOAL_STACK:
			botlib_export->ai.BotDumpGoalStack(args[1]);
			return 0;
		case BOTLIB_AI_GOAL_NAME:
			botlib_export->ai.BotGoalName(args[1], (char*)VMA(2), args[3]);
			return 0;
		case BOTLIB_AI_GET_TOP_GOAL:
			return botlib_export->ai.BotGetTopGoal(args[1], (bot_goal_s*)VMA(2));
		case BOTLIB_AI_GET_SECOND_GOAL:
			return botlib_export->ai.BotGetSecondGoal(args[1], (bot_goal_s*)VMA(2));
		case BOTLIB_AI_CHOOSE_LTG_ITEM:
			return botlib_export->ai.BotChooseLTGItem(args[1], (float*)VMA(2), (int*)VMA(3), args[4]);
		case BOTLIB_AI_CHOOSE_NBG_ITEM:
			return botlib_export->ai.BotChooseNBGItem(args[1], (float*)VMA(2), (int*)VMA(3), args[4], (bot_goal_s*)VMA(5), VMF(6));
		case BOTLIB_AI_TOUCHING_GOAL:
			return botlib_export->ai.BotTouchingGoal((float*)VMA(1), (bot_goal_s*)VMA(2));
		case BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE:
			return botlib_export->ai.BotItemGoalInVisButNotVisible(args[1], (float*)VMA(2), (float*)VMA(3), (bot_goal_s*)VMA(4));
		case BOTLIB_AI_GET_LEVEL_ITEM_GOAL:
			return botlib_export->ai.BotGetLevelItemGoal(args[1], (char*)VMA(2), (bot_goal_s*)VMA(3));
		case BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL:
			return botlib_export->ai.BotGetNextCampSpotGoal(args[1], (bot_goal_s*)VMA(2));
		case BOTLIB_AI_GET_MAP_LOCATION_GOAL:
			return botlib_export->ai.BotGetMapLocationGoal((char*)VMA(1), (bot_goal_s*)VMA(2));
		case BOTLIB_AI_AVOID_GOAL_TIME:
			return FloatAsInt(botlib_export->ai.BotAvoidGoalTime(args[1], args[2]));
		case BOTLIB_AI_INIT_LEVEL_ITEMS:
			botlib_export->ai.BotInitLevelItems();
			return 0;
		case BOTLIB_AI_UPDATE_ENTITY_ITEMS:
			botlib_export->ai.BotUpdateEntityItems();
			return 0;
		case BOTLIB_AI_LOAD_ITEM_WEIGHTS:
			return botlib_export->ai.BotLoadItemWeights(args[1], (char*)VMA(2));
		case BOTLIB_AI_FREE_ITEM_WEIGHTS:
			botlib_export->ai.BotFreeItemWeights(args[1]);
			return 0;
		case BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC:
			botlib_export->ai.BotInterbreedGoalFuzzyLogic(args[1], args[2], args[3]);
			return 0;
		case BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC:
			botlib_export->ai.BotSaveGoalFuzzyLogic(args[1], (char*)VMA(2));
			return 0;
		case BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC:
			botlib_export->ai.BotMutateGoalFuzzyLogic(args[1], VMF(2));
			return 0;
		case BOTLIB_AI_ALLOC_GOAL_STATE:
			return botlib_export->ai.BotAllocGoalState(args[1]);
		case BOTLIB_AI_FREE_GOAL_STATE:
			botlib_export->ai.BotFreeGoalState(args[1]);
			return 0;
		case BOTLIB_AI_RESET_MOVE_STATE:
			botlib_export->ai.BotResetMoveState(args[1]);
			return 0;
		case BOTLIB_AI_MOVE_TO_GOAL:
			botlib_export->ai.BotMoveToGoal((bot_moveresult_s*)VMA(1), args[2], (bot_goal_s*)VMA(3), args[4]);
			return 0;
		case BOTLIB_AI_MOVE_IN_DIRECTION:
			return botlib_export->ai.BotMoveInDirection(args[1], (float*)VMA(2), VMF(3), args[4]);
		case BOTLIB_AI_RESET_AVOID_REACH:
			botlib_export->ai.BotResetAvoidReach(args[1]);
			return 0;
		case BOTLIB_AI_RESET_LAST_AVOID_REACH:
			botlib_export->ai.BotResetLastAvoidReach(args[1]);
			return 0;
		case BOTLIB_AI_REACHABILITY_AREA:
			return botlib_export->ai.BotReachabilityArea((float*)VMA(1), args[2]);
		case BOTLIB_AI_MOVEMENT_VIEW_TARGET:
			return botlib_export->ai.BotMovementViewTarget(args[1], (bot_goal_s*)VMA(2), args[3], VMF(4), (float*)VMA(5));
		case BOTLIB_AI_PREDICT_VISIBLE_POSITION:
			return botlib_export->ai.BotPredictVisiblePosition((float*)VMA(1), args[2], (bot_goal_s*)VMA(3), args[4], (vec_t*)VMA(5));
		case BOTLIB_AI_ALLOC_MOVE_STATE:
			return botlib_export->ai.BotAllocMoveState();
		case BOTLIB_AI_FREE_MOVE_STATE:
			botlib_export->ai.BotFreeMoveState(args[1]);
			return 0;
		case BOTLIB_AI_INIT_MOVE_STATE:
			botlib_export->ai.BotInitMoveState(args[1], (bot_initmove_s*)VMA(2));
			return 0;
		case BOTLIB_AI_INIT_AVOID_REACH:
			botlib_export->ai.BotInitAvoidReach(args[1]);
			return 0;
		case BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON:
			return botlib_export->ai.BotChooseBestFightWeapon(args[1], (int*)VMA(2));
		case BOTLIB_AI_GET_WEAPON_INFO:
			botlib_export->ai.BotGetWeaponInfo(args[1], args[2], (weaponinfo_s*)VMA(3));
			return 0;
		case BOTLIB_AI_LOAD_WEAPON_WEIGHTS:
			return botlib_export->ai.BotLoadWeaponWeights(args[1], (char*)VMA(2));
		case BOTLIB_AI_ALLOC_WEAPON_STATE:
			return botlib_export->ai.BotAllocWeaponState();
		case BOTLIB_AI_FREE_WEAPON_STATE:
			botlib_export->ai.BotFreeWeaponState(args[1]);
			return 0;
		case BOTLIB_AI_RESET_WEAPON_STATE:
			botlib_export->ai.BotResetWeaponState(args[1]);
			return 0;
		case BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION:
			return botlib_export->ai.GeneticParentsAndChildSelection(args[1], (float*)VMA(2), (int*)VMA(3), (int*)VMA(4), (int*)VMA(5));
		case G_ADD_PHYSICS_ENTITY:
#ifdef USE_PHYSICS
			CMod_PhysicsAddEntity((sharedEntity_t*)VMA(1));
#endif
			return 0;
		case G_ADD_PHYSICS_STATIC:
#ifdef USE_PHYSICS
			CMod_PhysicsAddStatic((sharedEntity_t*)VMA(1));
#endif
			return 0;
		case TRAP_MEMSET:
			memset(VMA(1), args[2], args[3]);
			return 0;
		case TRAP_MEMCPY:
			memcpy(VMA(1), VMA(2), args[3]);
			return 0;
		case TRAP_STRNCPY:
			return (intptr_t)strncpy( (char*)VMA( 1 ), (char*)VMA( 2 ), args[3] );
		case TRAP_SIN:
			return FloatAsInt(sin(VMF(1)));
		case TRAP_COS:
			return FloatAsInt(cos(VMF(1)));
		case TRAP_ATAN2:
			return FloatAsInt(atan2(VMF(1), VMF(2)));
		case TRAP_SQRT:
			return FloatAsInt(sqrt(VMF(1)));
		case TRAP_MATRIXMULTIPLY:
			AxisMultiply((vec3_t*)VMA(1), (vec3_t*)VMA(2), (vec3_t*)VMA(3));
			return 0;
		case TRAP_ANGLEVECTORS:
			AngleVectors((vec_t*)VMA(1), (vec_t*)VMA(2), (vec_t*)VMA(3), (vec_t*)VMA(4));
			return 0;
		case TRAP_PERPENDICULARVECTOR:
			PerpendicularVector((vec_t*)VMA(1), (vec_t*)VMA(2));
			return 0;
		case TRAP_FLOOR:
			return FloatAsInt(floor(VMF(1)));
		case TRAP_CEIL:
			return FloatAsInt(ceil(VMF(1)));
		case G_SENDMESSAGE:
			SV_SendBinaryMessage(args[1], (char*)VMA(2), args[3]);
			return 0;
		case G_MESSAGESTATUS:
			return SV_BinaryMessageStatus(args[1]);
#if defined(ET_MYSQL)
        case G_SQL_RUNQUERY:
                return OW_RunQuery( (char*)VMA(1) );
        case G_SQL_FINISHQUERY:
                OW_FinishQuery( args[1] );
                return 0;
        case G_SQL_NEXTROW:
                return OW_NextRow( args[1] );
        case G_SQL_ROWCOUNT:
                return OW_RowCount( args[1] );
        case G_SQL_GETFIELDBYID:
                OW_GetFieldByID( args[1], args[2], (char*)VMA(3), args[4]  );
                return 0;
        case G_SQL_GETFIELDBYNAME:
                OW_GetFieldByName( args[1], (char*)VMA(2), (char*)VMA(3), args[4] );
                return 0;
        case G_SQL_GETFIELDBYID_INT:
                return OW_GetFieldByID_int( args[1], args[2] );
        case G_SQL_GETFIELDBYNAME_INT:
                return OW_GetFieldByName_int( args[1], (char*)VMA(2) );
        case G_SQL_FIELDCOUNT:
                return OW_FieldCount( args[1] );
        case G_SQL_CLEANSTRING:
                OW_CleanString( (char*)VMA(1), (char*)VMA(2), args[3] );
                return 0;
#endif
		case G_RSA_GENMSG:
			return SV_RSAGenMsg( (char*)VMA(1), (char*)VMA(2), (char*)VMA(3) );
		default:
			Com_Error( ERR_DROP, "Bad game system trap: %ld", (long int) args[0] );
	}
	return -1;
}
コード例 #4
0
ファイル: sv_snapshot.cpp プロジェクト: GrangerHub/tremulous
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint(vec3_t origin, clientSnapshot_t *frame, snapshotEntityNumbers_t *eNums)
{
    int e, i;
    sharedEntity_t *ent;
    svEntity_t *svEnt;
    int l;
    int clientarea, clientcluster;
    int leafnum;
    byte *clientpvs;
    byte *bitvector;

    // during an error shutdown message we may need to transmit
    // the shutdown message after the server has shutdown, so
    // specfically check for it
    if (!sv.state)
    {
        return;
    }

    leafnum = CM_PointLeafnum(origin);
    clientarea = CM_LeafArea(leafnum);
    clientcluster = CM_LeafCluster(leafnum);

    // calculate the visible areas
    frame->areabytes = CM_WriteAreaBits(frame->areabits, clientarea);

    clientpvs = CM_ClusterPVS(clientcluster);

    for (e = 0; e < sv.num_entities; e++)
    {
        ent = SV_GentityNum(e);

        // never send entities that aren't linked in
        if (!ent->r.linked)
        {
            continue;
        }

        if (ent->s.number != e)
        {
            Com_DPrintf("FIXING ENT->S.NUMBER!!!\n");
            ent->s.number = e;
        }

        // entities can be flagged to explicitly not be sent to the client
        if (ent->r.svFlags & SVF_NOCLIENT)
        {
            continue;
        }

        // entities can be flagged to be sent to only one client
        if (ent->r.svFlags & SVF_SINGLECLIENT)
        {
            if (ent->r.singleClient != frame->ps.clientNum)
            {
                continue;
            }
        }
        // entities can be flagged to be sent to everyone but one client
        if (ent->r.svFlags & SVF_NOTSINGLECLIENT)
        {
            if (ent->r.singleClient == frame->ps.clientNum)
            {
                continue;
            }
        }
        // entities can be flagged to be sent to a given mask of clients
        if (ent->r.svFlags & SVF_CLIENTMASK)
        {
            if (frame->ps.clientNum >= 32)
            {
                if (~ent->r.hack.generic1 & (1 << (frame->ps.clientNum - 32))) continue;
            }
            else
            {
                if (~ent->r.singleClient & (1 << frame->ps.clientNum)) continue;
            }
        }

        svEnt = SV_SvEntityForGentity(ent);

        // don't double add an entity through portals
        if (svEnt->snapshotCounter == sv.snapshotCounter)
        {
            continue;
        }

        // broadcast entities are always sent
        if (ent->r.svFlags & SVF_BROADCAST)
        {
            SV_AddEntToSnapshot(svEnt, ent, eNums);
            continue;
        }

        // ignore if not touching a PV leaf
        // check area
        if (!CM_AreasConnected(clientarea, svEnt->areanum))
        {
            // doors can legally straddle two areas, so
            // we may need to check another one
            if (!CM_AreasConnected(clientarea, svEnt->areanum2))
            {
                continue;  // blocked by a door
            }
        }

        bitvector = clientpvs;

        // check individual leafs
        if (!svEnt->numClusters)
        {
            continue;
        }
        l = 0;
        for (i = 0; i < svEnt->numClusters; i++)
        {
            l = svEnt->clusternums[i];
            if (bitvector[l >> 3] & (1 << (l & 7)))
            {
                break;
            }
        }

        // if we haven't found it to be visible,
        // check overflow clusters that coudln't be stored
        if (i == svEnt->numClusters)
        {
            if (svEnt->lastCluster)
            {
                for (; l <= svEnt->lastCluster; l++)
                {
                    if (bitvector[l >> 3] & (1 << (l & 7)))
                    {
                        break;
                    }
                }
                if (l == svEnt->lastCluster)
                {
                    continue;  // not visible
                }
            }
            else
            {
                continue;
            }
        }

        // add it
        SV_AddEntToSnapshot(svEnt, ent, eNums);

        // if it's a portal entity, add everything visible from its camera position
        if (ent->r.svFlags & SVF_PORTAL)
        {
            if (ent->s.generic1)
            {
                vec3_t dir;
                VectorSubtract(ent->r.currentOrigin, origin, dir);
                if (VectorLengthSquared(dir) > (float)ent->s.generic1 * ent->s.generic1)
                {
                    continue;
                }
            }
            SV_AddEntitiesVisibleFromPoint(ent->s.origin2, frame, eNums);
        }
    }
コード例 #5
0
ファイル: sv_snapshot.cpp プロジェクト: TWal/Unvanquished
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame,
//                                  snapshotEntityNumbers_t *eNums, qboolean portal, clientSnapshot_t *oldframe, qboolean localClient ) {
//                                  snapshotEntityNumbers_t *eNums, qboolean portal ) {
    snapshotEntityNumbers_t *eNums /*, qboolean portal, qboolean localClient */ )
{
	int            e, i;
	sharedEntity_t *ent, *playerEnt;
	svEntity_t     *svEnt;
	int            l;
	int            clientarea, clientcluster;
	int            leafnum;
//	int             c_fullsend;
	byte           *clientpvs;
	byte           *bitvector;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state )
	{
		return;
	}

	leafnum = CM_PointLeafnum( origin );
	clientarea = CM_LeafArea( leafnum );
	clientcluster = CM_LeafCluster( leafnum );

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	clientpvs = CM_ClusterPVS( clientcluster );

//	c_fullsend = 0;

	playerEnt = SV_GentityNum( frame->ps.clientNum );

	if ( playerEnt->r.svFlags & SVF_SELF_PORTAL )
	{
		SV_AddEntitiesVisibleFromPoint( playerEnt->s.origin2, frame, eNums );
	}

	for ( e = 0; e < sv.num_entities; e++ )
	{
		ent = SV_GentityNum( e );

		// never send entities that aren't linked in
		if ( !ent->r.linked )
		{
			continue;
		}

		if ( ent->s.number != e )
		{
			Com_DPrintf( "FIXING ENT->S.NUMBER!!!\n" );
			ent->s.number = e;
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->r.svFlags & SVF_NOCLIENT )
		{
			continue;
		}

		// entities can be flagged to be sent to only one client
		if ( ent->r.svFlags & SVF_SINGLECLIENT )
		{
			if ( ent->r.singleClient != frame->ps.clientNum )
			{
				continue;
			}
		}

		// entities can be flagged to be sent to everyone but one client
		if ( ent->r.svFlags & SVF_NOTSINGLECLIENT )
		{
			if ( ent->r.singleClient == frame->ps.clientNum )
			{
				continue;
			}
		}

		// entities can be flagged to be sent to only a given mask of clients
		if ( ent->r.svFlags & SVF_CLIENTMASK )
		{
			if ( frame->ps.clientNum >= 32 )
			{
				if ( ~ent->r.hiMask & ( 1 << ( frame->ps.clientNum - 32 ) ) )
				{
					continue;
				}
			}
			else
			{
				if ( ~ent->r.loMask & ( 1 << frame->ps.clientNum ) )
				{
					continue;
				}
			}
		}

		svEnt = SV_SvEntityForGentity( ent );

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter )
		{
			continue;
		}

		// broadcast entities are always sent
		if ( ent->r.svFlags & SVF_BROADCAST )
		{
			SV_AddEntToSnapshot( playerEnt, svEnt, ent, eNums );
			continue;
		}

		// send entity if the client is in range
		if ( (ent->r.svFlags & SVF_CLIENTS_IN_RANGE) &&
		     Distance( ent->s.origin, playerEnt->s.origin ) <= ent->r.clientRadius )
		{
			SV_AddEntToSnapshot( playerEnt, svEnt, ent, eNums );
			continue;
		}

		bitvector = clientpvs;

		// Gordon: just check origin for being in pvs, ignore bmodel extents
		if ( ent->r.svFlags & SVF_IGNOREBMODELEXTENTS )
		{
			if ( bitvector[ ent->r.originCluster >> 3 ] & ( 1 << ( ent->r.originCluster & 7 ) ) )
			{
				SV_AddEntToSnapshot( playerEnt, svEnt, ent, eNums );
			}

			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, ent->r.areanum ) )
		{
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, ent->r.areanum2 ) )
			{
				continue;
			}
		}

		// check individual leafs
		if ( !ent->r.numClusters )
		{
			continue;
		}

		l = 0;

		for ( i = 0; i < ent->r.numClusters; i++ )
		{
			l = ent->r.clusternums[ i ];

			if ( bitvector[ l >> 3 ] & ( 1 << ( l & 7 ) ) )
			{
				break;
			}
		}

		// if we haven't found it to be visible,
		// check the overflow clusters that couldn't be stored
		if ( i == ent->r.numClusters )
		{
			if ( ent->r.lastCluster )
			{
				for ( ; l <= ent->r.lastCluster; l++ )
				{
					if ( bitvector[ l >> 3 ] & ( 1 << ( l & 7 ) ) )
					{
						break;
					}
				}

				if ( l == ent->r.lastCluster )
				{
					continue;
				}
			}
			else
			{
				continue;
			}
		}

		//----(SA) added "visibility dummies"
		if ( ent->r.svFlags & SVF_VISDUMMY )
		{
			sharedEntity_t *ment = 0;

			//find master;
			ment = SV_GentityNum( ent->s.otherEntityNum );

			if ( ment )
			{
				svEntity_t *master = 0;

				master = SV_SvEntityForGentity( ment );

				if ( master->snapshotCounter == sv.snapshotCounter || !ment->r.linked )
				{
					continue;
				}

				SV_AddEntToSnapshot( playerEnt, master, ment, eNums );
			}

			continue; // master needs to be added, but not this dummy ent
		}
		//----(SA) end
		else if ( ent->r.svFlags & SVF_VISDUMMY_MULTIPLE )
		{
			{
				int            h;
				sharedEntity_t *ment = 0;
				svEntity_t     *master = 0;

				for ( h = 0; h < sv.num_entities; h++ )
				{
					ment = SV_GentityNum( h );

					if ( ment == ent )
					{
						continue;
					}

					if ( ment )
					{
						master = SV_SvEntityForGentity( ment );
					}
					else
					{
						continue;
					}

					if ( !( ment->r.linked ) )
					{
						continue;
					}

					if ( ment->s.number != h )
					{
						Com_DPrintf( "FIXING vis dummy multiple ment->S.NUMBER!!!\n" );
						ment->s.number = h;
					}

					if ( ment->r.svFlags & SVF_NOCLIENT )
					{
						continue;
					}

					if ( master->snapshotCounter == sv.snapshotCounter )
					{
						continue;
					}

					if ( ment->s.otherEntityNum == ent->s.number )
					{
						SV_AddEntToSnapshot( playerEnt, master, ment, eNums );
					}
				}

				continue;
			}
		}

		// add it
		SV_AddEntToSnapshot( playerEnt, svEnt, ent, eNums );

		// if it's a portal entity, add everything visible from its camera position
		if ( ent->r.svFlags & SVF_PORTAL )
		{
			if ( ent->s.generic1 )
			{
				vec3_t dir;
				VectorSubtract( ent->s.origin, origin, dir );

				if ( VectorLengthSquared( dir ) > ( float ) ent->s.generic1 * ent->s.generic1 )
				{
					continue;
				}
			}

//          SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, oldframe, localClient );
			SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums /*, qtrue, localClient */ );
		}

		continue;
	}
コード例 #6
0
ファイル: sv_snapshot.cpp プロジェクト: DavidZeise/OpenJK
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame, 
									snapshotEntityNumbers_t *eNums, qboolean portal ) {
	int		e, i;
	sharedEntity_t *ent;
	svEntity_t	*svEnt;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	byte	*clientpvs;
	byte	*bitvector;
	vec3_t	difference;
	float	length, radius;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	leafnum = CM_PointLeafnum (origin);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	clientpvs = CM_ClusterPVS (clientcluster);

	for ( e = 0 ; e < sv.num_entities ; e++ ) {
		ent = SV_GentityNum(e);

		// never send entities that aren't linked in
		if ( !ent->r.linked ) {
			continue;
		}

		if (ent->s.eFlags & EF_PERMANENT)
		{	// he's permanent, so don't send him down!
			continue;
		}

		if (ent->s.number != e) {
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->r.svFlags & SVF_NOCLIENT ) {
			continue;
		}

		// entities can be flagged to be sent to only one client
		if ( ent->r.svFlags & SVF_SINGLECLIENT ) {
			if ( ent->r.singleClient != frame->ps.clientNum ) {
				continue;
			}
		}
		// entities can be flagged to be sent to everyone but one client
		if ( ent->r.svFlags & SVF_NOTSINGLECLIENT ) {
			if ( ent->r.singleClient == frame->ps.clientNum ) {
				continue;
			}
		}

		svEnt = SV_SvEntityForGentity( ent );

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
			continue;
		}

		// broadcast entities are always sent, and so is the main player so we don't see noclip weirdness
		if ( ent->r.svFlags & SVF_BROADCAST || (e == frame->ps.clientNum) || (ent->r.broadcastClients[frame->ps.clientNum/32] & (1<<(frame->ps.clientNum%32))))
		{
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		if (ent->s.isPortalEnt)
		{ //rww - portal entities are always sent as well
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		if (com_RMG && com_RMG->integer)
		{
			VectorAdd(ent->r.absmax, ent->r.absmin, difference);
			VectorScale(difference, 0.5f, difference);
			VectorSubtract(origin, difference, difference);
			length = VectorLength(difference);

			// calculate the diameter
			VectorSubtract(ent->r.absmax, ent->r.absmin, difference);
			radius = VectorLength(difference);
			if (length-radius < /*sv_RMGDistanceCull->integer*/5000.0f)
			{	// more of a diameter check
				SV_AddEntToSnapshot( svEnt, ent, eNums );
			}
		}
		else
		{
			// ignore if not touching a PV leaf
			// check area
			if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
				// doors can legally straddle two areas, so
				// we may need to check another one
				if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
					continue;		// blocked by a door
				}
			}

			bitvector = clientpvs;

			// check individual leafs
			if ( !svEnt->numClusters ) {
				continue;
			}
			l = 0;
			for ( i=0 ; i < svEnt->numClusters ; i++ ) {
				l = svEnt->clusternums[i];
				if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
					break;
				}
			}

			// if we haven't found it to be visible,
			// check overflow clusters that coudln't be stored
			if ( i == svEnt->numClusters ) {
				if ( svEnt->lastCluster ) {
					for ( ; l <= svEnt->lastCluster ; l++ ) {
						if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
							break;
						}
					}
					if ( l == svEnt->lastCluster ) {
						continue;	// not visible
					}
				} else {
					continue;
				}
			}

			if (g_svCullDist != -1.0f)
			{ //do a distance cull check
				VectorAdd(ent->r.absmax, ent->r.absmin, difference);
				VectorScale(difference, 0.5f, difference);
				VectorSubtract(origin, difference, difference);
				length = VectorLength(difference);

				// calculate the diameter
				VectorSubtract(ent->r.absmax, ent->r.absmin, difference);
				radius = VectorLength(difference);
				if (length-radius >= g_svCullDist)
				{ //then don't add it
					continue;
				}
			}

			// add it
			SV_AddEntToSnapshot( svEnt, ent, eNums );

			// if its a portal entity, add everything visible from its camera position
			if ( ent->r.svFlags & SVF_PORTAL ) {
				if ( ent->s.generic1 ) {
					vec3_t dir;
					VectorSubtract(ent->s.origin, origin, dir);
					if ( VectorLengthSquared(dir) > (float) ent->s.generic1 * ent->s.generic1 ) {
						continue;
					}
				}
				SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
			}
		}
	}
コード例 #7
0
ファイル: sv_snapshot.cpp プロジェクト: CairnTrenor/OpenJK
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame, 
									snapshotEntityNumbers_t *eNums, qboolean portal ) {
	int		e, i;
	gentity_t	*ent;
	svEntity_t	*svEnt;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	int		c_fullsend;
	byte	*clientpvs;
	byte	*bitvector;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	leafnum = CM_PointLeafnum (origin);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	clientpvs = CM_ClusterPVS (clientcluster);

	c_fullsend = 0;

	for ( e = 0 ; e < ge->num_entities ; e++ ) {
		ent = SV_GentityNum(e);

		if (!ent->inuse) {
			continue;
		}

		if (ent->s.number != e) {
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}

		// never send entities that aren't linked in
		if ( !ent->linked ) {
			continue;
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->svFlags & SVF_NOCLIENT ) {
			continue;
		}

		svEnt = SV_SvEntityForGentity( ent );

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
			continue;
		}

		// broadcast entities are always sent, and so is the main player so we don't see noclip weirdness
		if ( ent->svFlags & SVF_BROADCAST || !e) {
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
				continue;		// blocked by a door
			}
		}

		bitvector = clientpvs;

		// check individual leafs
		if ( !svEnt->numClusters ) {
			continue;
		}
		l = 0;
		for ( i=0 ; i < svEnt->numClusters ; i++ ) {
			l = svEnt->clusternums[i];
			if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
				break;
			}
		}

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
		if ( i == svEnt->numClusters ) {
			if ( svEnt->lastCluster ) {
				for ( ; l <= svEnt->lastCluster ; l++ ) {
					if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
						break;
					}
				}
				if ( l == svEnt->lastCluster ) {
					continue;		// not visible
				}
			} else {
				continue;
			}
		}

		// add it
		SV_AddEntToSnapshot( svEnt, ent, eNums );

		// if its a portal entity, add everything visible from its camera position
		if ( ent->svFlags & SVF_PORTAL ) {
			SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
		}

	}
コード例 #8
0
bool trap_AreasConnected(int area1, int area2)
{
	return CM_AreasConnected(area1, area2);
}
コード例 #9
0
ファイル: sv_snapshot.c プロジェクト: OADoctor/SmokinGuns
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame,
        snapshotEntityNumbers_t *eNums, qboolean portal ) {
    int		e, i;
    sharedEntity_t *ent;
    svEntity_t	*svEnt;
    int		l;
    int		clientarea, clientcluster;
    int		leafnum;
    byte	*clientpvs;
    byte	*bitvector;
    client_t	*cl;
    vec3_t diff;

    // during an error shutdown message we may need to transmit
    // the shutdown message after the server has shutdown, so
    // specfically check for it
    if ( !sv.state ) {
        return;
    }

    leafnum = CM_PointLeafnum (origin);
    clientarea = CM_LeafArea (leafnum);
    clientcluster = CM_LeafCluster (leafnum);

    // calculate the visible areas
    frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

    clientpvs = CM_ClusterPVS (clientcluster);

    for ( e = 0 ; e < sv.num_entities ; e++ ) {
        ent = SV_GentityNum(e);

        // never send entities that aren't linked in
        if ( !ent->r.linked ) {
            continue;
        }

        if (ent->s.number != e) {
            Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
            ent->s.number = e;
        }

        // entities can be flagged to explicitly not be sent to the client
        if ( ent->r.svFlags & SVF_NOCLIENT ) {
            continue;
        }

        // entities can be flagged to be sent to only one client
        if ( ent->r.svFlags & SVF_SINGLECLIENT ) {
            if ( ent->r.singleClient != frame->ps.clientNum ) {
                continue;
            }
        }
        // entities can be flagged to be sent to everyone but one client
        if ( ent->r.svFlags & SVF_NOTSINGLECLIENT ) {
            if ( ent->r.singleClient == frame->ps.clientNum ) {
                continue;
            }
        }
        // entities can be flagged to be sent to a given mask of clients
        if ( ent->r.svFlags & SVF_CLIENTMASK ) {
            if (frame->ps.clientNum >= 32)
                Com_Error( ERR_DROP, "SVF_CLIENTMASK: clientNum >= 32" );
            if (~ent->r.singleClient & (1 << frame->ps.clientNum))
                continue;
        }

        svEnt = SV_SvEntityForGentity( ent );

        // don't double add an entity through portals
        if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
            continue;
        }

        // broadcast entities are always sent
        cl = svs.clients+frame->ps.clientNum;
//		if ( ent->r.svFlags & SVF_BROADCAST ) {
        if ( ent->r.svFlags & SVF_BROADCAST && (ent->s.eType != ET_PLAYER || sv_antiwallhack->integer == 0 || recentlySeen(cl,ent->s.clientNum))) {// broadcast only non-players. Warning: in case sv_antiwallhack equals 1, bots will be disappearing on dm_train when touching doors, unless you compensate with "recentlySeen".
            SV_AddEntToSnapshot( svEnt, ent, eNums );
            continue;
        }

        //if (!(ent->r.svFlags & SVF_BOT)) {// if this entity is not a bot ... (compensation for the broadcast restriction to non-players)
        // ignore if not touching a PV leaf
        // check area
        if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
            // doors can legally straddle two areas, so
            // we may need to check another one
            if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
                continue;		// blocked by a door
            }
        }

        bitvector = clientpvs;

        // check individual leafs
        if ( !svEnt->numClusters ) {
            continue;
        }
        l = 0;
        for ( i=0 ; i < svEnt->numClusters ; i++ ) {
            l = svEnt->clusternums[i];
            if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
                break;
            }
        }

        // if we haven't found it to be visible,
        // check overflow clusters that coudln't be stored
        if ( i == svEnt->numClusters ) {
            if ( svEnt->lastCluster ) {
                for ( ; l <= svEnt->lastCluster ; l++ ) {
                    if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
                        break;
                    }
                }
                if ( l == svEnt->lastCluster ) {
                    continue;	// not visible
                }
            } else {
                continue;
            }
        }

        if (sv_antiwallhack->integer == 1 && (cl->netchan.remoteAddress.type != NA_BOT) && ent->s.eType == ET_PLAYER) {
            if (!SV_IsPlayerVisibleFromPoint(origin,frame,ent,diff)) {
                continue;

            }
        }

        // add it
        SV_AddEntToSnapshot( svEnt, ent, eNums );
        // reset ps.pm_type?

        // if it's a portal entity, add everything visible from its camera position
        if ( ent->r.svFlags & SVF_PORTAL ) {
            if ( ent->s.generic1 ) {
                vec3_t dir;
                VectorSubtract(ent->s.origin, origin, dir);
                if ( VectorLengthSquared(dir) > (float) ent->s.generic1 * ent->s.generic1 ) {
                    continue;
                }
            }
            SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
        }

    }
コード例 #10
0
ファイル: sv_snapshot.c プロジェクト: scenna/etlegacy
static void SV_AddEntitiesVisibleFromPoint(vec3_t origin, clientSnapshot_t *frame, snapshotEntityNumbers_t *eNums)
#endif
{
	int            e, i;
	sharedEntity_t *ent, *playerEnt, *ment;
#ifdef FEATURE_ANTICHEAT
	sharedEntity_t *client;
#endif
	svEntity_t *svEnt;
	int        l;
	int        clientarea, clientcluster;
	int        leafnum;
	byte       *clientpvs;
	byte       *bitvector;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if (!sv.state)
	{
		return;
	}

	leafnum       = CM_PointLeafnum(origin);
	clientarea    = CM_LeafArea(leafnum);
	clientcluster = CM_LeafCluster(leafnum);

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits(frame->areabits, clientarea);

	clientpvs = CM_ClusterPVS(clientcluster);

	playerEnt = SV_GentityNum(frame->ps.clientNum);
	if (playerEnt->r.svFlags & SVF_SELF_PORTAL)
	{
#ifdef FEATURE_ANTICHEAT
		SV_AddEntitiesVisibleFromPoint(playerEnt->s.origin2, frame, eNums, qtrue); //  portal qtrue?!
#else
		SV_AddEntitiesVisibleFromPoint(playerEnt->s.origin2, frame, eNums);
#endif
	}

	for (e = 0 ; e < sv.num_entities ; e++)
	{
		ent = SV_GentityNum(e);

		// never send entities that aren't linked in
		if (!ent->r.linked)
		{
			continue;
		}

		if (ent->s.number != e)
		{
			Com_DPrintf("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}

		// entities can be flagged to explicitly not be sent to the client
		if (ent->r.svFlags & SVF_NOCLIENT)
		{
			continue;
		}

		// entities can be flagged to be sent to only one client
		if (ent->r.svFlags & SVF_SINGLECLIENT)
		{
			if (ent->r.singleClient != frame->ps.clientNum)
			{
				continue;
			}
		}
		// entities can be flagged to be sent to everyone but one client
		if (ent->r.svFlags & SVF_NOTSINGLECLIENT)
		{
			if (ent->r.singleClient == frame->ps.clientNum)
			{
				continue;
			}
		}

		svEnt = SV_SvEntityForGentity(ent);

		// don't double add an entity through portals
		if (svEnt->snapshotCounter == sv.snapshotCounter)
		{
			continue;
		}

		// broadcast entities are always sent
		if (ent->r.svFlags & SVF_BROADCAST)
		{
			SV_AddEntToSnapshot(playerEnt, svEnt, ent, eNums);
			continue;
		}

		bitvector = clientpvs;

		// just check origin for being in pvs, ignore bmodel extents
		if (ent->r.svFlags & SVF_IGNOREBMODELEXTENTS)
		{
			if (bitvector[svEnt->originCluster >> 3] & (1 << (svEnt->originCluster & 7)))
			{
				SV_AddEntToSnapshot(playerEnt, svEnt, ent, eNums);
			}
			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if (!CM_AreasConnected(clientarea, svEnt->areanum))
		{
			// doors can legally straddle two areas, so
			// we may need to check another one
			if (!CM_AreasConnected(clientarea, svEnt->areanum2))
			{
				continue;
			}
		}

		// check individual leafs
		if (!svEnt->numClusters)
		{
			continue;
		}
		l = 0;
		for (i = 0 ; i < svEnt->numClusters ; i++)
		{
			l = svEnt->clusternums[i];
			if (bitvector[l >> 3] & (1 << (l & 7)))
			{
				break;
			}
		}

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
		if (i == svEnt->numClusters)
		{
			if (svEnt->lastCluster)
			{
				for ( ; l <= svEnt->lastCluster ; l++)
				{
					if (bitvector[l >> 3] & (1 << (l & 7)))
					{
						break;
					}
				}
				if (l == svEnt->lastCluster)
				{
					continue; // not visible
				}
			}
			else
			{
				continue;
			}
		}

		// added "visibility dummies"
		if (ent->r.svFlags & SVF_VISDUMMY)
		{
			// find master;
			ment = SV_GentityNum(ent->s.otherEntityNum);

			if (ment)
			{
				svEntity_t *master = 0;
				master = SV_SvEntityForGentity(ment);

				if (master->snapshotCounter == sv.snapshotCounter || !ment->r.linked)
				{
					continue;
				}

				SV_AddEntToSnapshot(playerEnt, master, ment, eNums);
			}
			continue;   // master needs to be added, but not this dummy ent
		}
		else if (ent->r.svFlags & SVF_VISDUMMY_MULTIPLE)
		{
			int            h;
			sharedEntity_t *ment   = 0;
			svEntity_t     *master = 0;

			for (h = 0; h < sv.num_entities; h++)
			{
				ment = SV_GentityNum(h);

				if (ment == ent)
				{
					continue;
				}

				if (ment)
				{
					master = SV_SvEntityForGentity(ment);
				}
				else
				{
					continue;
				}

				if (!(ment->r.linked))
				{
					continue;
				}

				if (ment->s.number != h)
				{
					Com_DPrintf("FIXING vis dummy multiple ment->S.NUMBER!!!\n");
					ment->s.number = h;
				}

				if (ment->r.svFlags & SVF_NOCLIENT)
				{
					continue;
				}

				if (master->snapshotCounter == sv.snapshotCounter)
				{
					continue;
				}

				if (ment->s.otherEntityNum == ent->s.number)
				{
					SV_AddEntToSnapshot(playerEnt, master, ment, eNums);
				}
			}
			continue;
		}

#ifdef FEATURE_ANTICHEAT
		if (sv_wh_active->integer > 0 && e < sv_maxclients->integer)     // client
		{
			// note: !r.linked is already exclused - see above

			if (e == frame->ps.clientNum)
			{
				continue;
			}

			client = SV_GentityNum(frame->ps.clientNum);

			// exclude bots and free flying specs
			if (!portal && !(client->r.svFlags & SVF_BOT) && (frame->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR) && !(frame->ps.pm_flags & PMF_FOLLOW))
			{
				if (!SV_CanSee(frame->ps.clientNum, e))
				{
					SV_RandomizePos(frame->ps.clientNum, e);
					SV_AddEntToSnapshot(client, svEnt, ent, eNums);
					continue;
				}
			}
		}
#endif

		// add it
		SV_AddEntToSnapshot(playerEnt, svEnt, ent, eNums);

		// if its a portal entity, add everything visible from its camera position
		if (ent->r.svFlags & SVF_PORTAL)
		{
#ifdef FEATURE_ANTICHEAT
			SV_AddEntitiesVisibleFromPoint(ent->s.origin2, frame, eNums, qtrue /*localClient*/);
#else
			SV_AddEntitiesVisibleFromPoint(ent->s.origin2, frame, eNums /*, qtrue, localClient*/);
#endif
		}

		continue;
	}
コード例 #11
0
ファイル: sv_snapshot.cpp プロジェクト: ataceyhun/jk2mv
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame,
									snapshotEntityNumbers_t *eNums, qboolean portal ) {
	int		e, i;
	sharedEntity_t *ent;
	svEntity_t	*svEnt;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	int		c_fullsend;
	byte	*clientpvs;
	byte	*bitvector;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	leafnum = CM_PointLeafnum (origin);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	clientpvs = CM_ClusterPVS (clientcluster);

	c_fullsend = 0;

	for ( e = 0 ; e < sv.num_entities ; e++ ) {
		ent = SV_GentityNum(e);

		// never send entities that aren't linked in
		if ( !ent->r.linked ) {
			continue;
		}

		if (ent->s.number != e) {
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}

		svEnt = SV_SvEntityForGentity( ent );

		if ( sv.gentitiesMV != NULL && sv.gentitySizeMV > 0 )
		{
			mvsharedEntity_t *mvEnt = MV_EntityNum(e);

			if ( VM_MVAPILevel( gvm ) >= 2 ) {
				// MV entities can be flagged to be sent only to
				// spectators or non-spectators
				if ( frame->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ||
					(frame->ps.pm_flags & PMF_FOLLOW) )
				{
					if ( mvEnt->mvFlags & MVF_NOSPEC )
						continue;
				}
				else
				{
					if ( mvEnt->mvFlags & MVF_SPECONLY )
						continue;
				}
			}

			// MV entities can be flagged to be sent only to specific
			// clients (can't filter following spectators this way)
			if ( mvEnt->snapshotIgnore[frame->ps.clientNum] ) continue;
			else if ( mvEnt->snapshotEnforce[frame->ps.clientNum] )
			{
				SV_AddEntToSnapshot( svEnt, ent, eNums );
				continue;
			}
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->r.svFlags & SVF_NOCLIENT ) {
			continue;
		}

		// entities can be flagged to be sent to only one client
		if ( ent->r.svFlags & SVF_SINGLECLIENT ) {
			if ( ent->r.singleClient != frame->ps.clientNum ) {
				continue;
			}
		}
		// entities can be flagged to be sent to everyone but one client
		if ( ent->r.svFlags & SVF_NOTSINGLECLIENT ) {
			if ( ent->r.singleClient == frame->ps.clientNum ) {
				continue;
			}
		}

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
			continue;
		}

		// broadcast entities are always sent, and so is the main player so we don't see noclip weirdness
		if ( ent->r.svFlags & SVF_BROADCAST || (e == frame->ps.clientNum) || (ent->r.broadcastClients[frame->ps.clientNum/32] & (1<<(frame->ps.clientNum%32))))
		{
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
				continue;		// blocked by a door
			}
		}

		bitvector = clientpvs;

		// check individual leafs
		if ( !svEnt->numClusters ) {
			continue;
		}
		l = 0;
		for ( i=0 ; i < svEnt->numClusters ; i++ ) {
			l = svEnt->clusternums[i];
			if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
				break;
			}
		}

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
		if ( i == svEnt->numClusters ) {
			if ( svEnt->lastCluster ) {
				for ( ; l <= svEnt->lastCluster ; l++ ) {
					if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
						break;
					}
				}
				if ( l == svEnt->lastCluster ) {
					continue;	// not visible
				}
			} else {
				continue;
			}
		}

		// add it
		SV_AddEntToSnapshot( svEnt, ent, eNums );

		// if its a portal entity, add everything visible from its camera position
		if ( ent->r.svFlags & SVF_PORTAL ) {
			if ( ent->s.generic1 ) {
				vec3_t dir;
				VectorSubtract(ent->s.origin, origin, dir);
				if ( VectorLengthSquared(dir) > (float) ent->s.generic1 * ent->s.generic1 ) {
					continue;
				}
			}
			SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
		}

	}
コード例 #12
0
ファイル: snapshot.cpp プロジェクト: janisl/jlquake
static void SVT3_AddEntitiesVisibleFromPoint( int clientNum, const vec3_t origin, q3clientSnapshot_t* frame,
	snapshotEntityNumbers_t* eNums, bool portal, bool localClient ) {
	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	int leafnum = CM_PointLeafnum( origin );
	int clientarea = CM_LeafArea( leafnum );
	int clientcluster = CM_LeafCluster( leafnum );

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	byte* clientpvs = CM_ClusterPVS( clientcluster );

	idEntity3* playerEnt = SVT3_EntityNum( clientNum );
	if ( playerEnt->GetSvFlagSelfPortal() ) {
		SVT3_AddEntitiesVisibleFromPoint( clientNum, playerEnt->GetOrigin2(), frame, eNums, portal, localClient );
	}

	int l;
	for ( int e = 0; e < sv.q3_num_entities; e++ ) {
		idEntity3* ent = SVT3_EntityNum( e );

		// never send entities that aren't linked in
		if ( !ent->GetLinked() ) {
			continue;
		}

		if ( ent->GetNumber() != e ) {
			common->DPrintf( "FIXING ENT->S.NUMBER!!!\n" );
			ent->SetNumber( e );
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->GetSvFlags() & Q3SVF_NOCLIENT ) {
			continue;
		}

		// entities can be flagged to be sent to only one client
		if ( ent->GetSvFlagSingleClient() ) {
			if ( ent->GetSingleClient() != clientNum ) {
				continue;
			}
		}
		// entities can be flagged to be sent to everyone but one client
		if ( ent->GetSvFlagNotSingleClient() ) {
			if ( ent->GetSingleClient() == clientNum ) {
				continue;
			}
		}
		// entities can be flagged to be sent to a given mask of clients
		if ( ent->GetSvFlagClientMask() ) {
			if ( clientNum >= 32 ) {
				common->Error( "Q3SVF_CLIENTMASK: cientNum > 32\n" );
			}
			if ( ~ent->GetSingleClient() & ( 1 << clientNum ) ) {
				continue;
			}
		}

		q3svEntity_t* svEnt = &sv.q3_svEntities[ e ];

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.q3_snapshotCounter ) {
			continue;
		}

		// if this client is viewing from a camera, only add ents visible from portal ents
		if ( playerEnt->GetEFlagViewingCamera() && !portal ) {
			if ( ent->GetSvFlags() & Q3SVF_PORTAL ) {
				SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
				SVT3_AddEntitiesVisibleFromPoint( clientNum, ent->GetOrigin2(), frame, eNums, true, localClient );
			}
			continue;
		}

		// broadcast entities are always sent
		if ( ent->GetSvFlags() & Q3SVF_BROADCAST ) {
			SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
			continue;
		}

		byte* bitvector = clientpvs;

		// Gordon: just check origin for being in pvs, ignore bmodel extents
		if ( ent->GetSvFlagIgnoreBModelExtents() ) {
			if ( bitvector[ svEnt->originCluster >> 3 ] & ( 1 << ( svEnt->originCluster & 7 ) ) ) {
				SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
			}
			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
				goto notVisible;	// blocked by a door
			}
		}

		// check individual leafs
		if ( !svEnt->numClusters ) {
			goto notVisible;
		}
		l = 0;
		int i;
		for ( i = 0; i < svEnt->numClusters; i++ ) {
			l = svEnt->clusternums[ i ];
			if ( bitvector[ l >> 3 ] & ( 1 << ( l & 7 ) ) ) {
				break;
			}
		}

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
		if ( i == svEnt->numClusters ) {
			if ( svEnt->lastCluster ) {
				for (; l <= svEnt->lastCluster; l++ ) {
					if ( bitvector[ l >> 3 ] & ( 1 << ( l & 7 ) ) ) {
						break;
					}
				}
				if ( l == svEnt->lastCluster ) {
					goto notVisible;	// not visible
				}
			} else {
				goto notVisible;
			}
		}

		//----(SA) added "visibility dummies"
		if ( ent->GetSvFlags() & WOLFSVF_VISDUMMY ) {
			//find master;
			idEntity3* ment = SVT3_EntityNum( ent->GetOtherEntityNum() );

			q3svEntity_t* master = &sv.q3_svEntities[ ent->GetOtherEntityNum() ];

			if ( master->snapshotCounter == sv.q3_snapshotCounter || !ment->GetLinked() ) {
				goto notVisible;
			}

			SVT3_AddEntToSnapshot( clientNum, master, ment, eNums );
			// master needs to be added, but not this dummy ent
			goto notVisible;
		} else if ( ent->GetSvFlags() & WOLFSVF_VISDUMMY_MULTIPLE ) {
			{
				for ( int h = 0; h < sv.q3_num_entities; h++ ) {
					idEntity3* ment = SVT3_EntityNum( h );

					if ( ment == ent ) {
						continue;
					}

					q3svEntity_t* master = &sv.q3_svEntities[ h ];

					if ( !ment->GetLinked() ) {
						continue;
					}

					if ( ment->GetNumber() != h ) {
						common->DPrintf( "FIXING vis dummy multiple ment->S.NUMBER!!!\n" );
						ment->SetNumber( h );
					}

					if ( ment->GetSvFlags() & Q3SVF_NOCLIENT ) {
						continue;
					}

					if ( master->snapshotCounter == sv.q3_snapshotCounter ) {
						continue;
					}

					if ( ment->GetOtherEntityNum() == ent->GetNumber() ) {
						SVT3_AddEntToSnapshot( clientNum, master, ment, eNums );
					}
				}
				goto notVisible;
			}
		}

		// add it
		SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );

		// if its a portal entity, add everything visible from its camera position
		if ( ent->GetSvFlags() & Q3SVF_PORTAL ) {
			if ( ent->GetGeneric1() ) {
				vec3_t dir;
				VectorSubtract( ent->GetOrigin(), origin, dir );
				if ( VectorLengthSquared( dir ) > ( float )ent->GetGeneric1() * ent->GetGeneric1() ) {
					continue;
				}
			}
			SVT3_AddEntitiesVisibleFromPoint( clientNum, ent->GetOrigin2(), frame, eNums, true, localClient );
		}

		continue;

notVisible:

		// Ridah, if this entity has changed events, then send it regardless of whether we can see it or not
		// DHM - Nerve :: not in multiplayer please
		if ( GGameType & ( GAME_WolfSP | GAME_WolfMP ) && svt3_gametype->integer == Q3GT_SINGLE_PLAYER && localClient ) {
			if ( ent->GetEventTime() == svs.q3_time ) {
				ent->SetEFlagNoDraw();		// don't draw, just process event
				SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
			} else if ( ent->GetEType() == Q3ET_PLAYER ) {
				// keep players around if they are alive and active (so sounds dont get messed up)
				if ( !ent->GetEFlagDead() ) {
					ent->SetEFlagNoDraw();		// don't draw, just process events and sounds
					SVT3_AddEntToSnapshot( clientNum, svEnt, ent, eNums );
				}
			}
		}
	}
コード例 #13
0
ファイル: sv_snapshot.c プロジェクト: mecwerks/spearmint-ios
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( int psIndex, int clientNum, vec3_t origin, clientSnapshot_t *frame, 
									snapshotEntityNumbers_t *eNums, qboolean portal ) {
	int		e, i;
	sharedEntity_t *ent;
	svEntity_t	*svEnt;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	byte	*clientpvs;
	byte	*bitvector;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	leafnum = CM_PointLeafnum (origin);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);

	// calculate the visible areas
	frame->areabytes[psIndex] = CM_WriteAreaBits( frame->areabits[psIndex], clientarea );

	clientpvs = CM_ClusterPVS (clientcluster);

	for ( e = 0 ; e < sv.num_entities ; e++ ) {
		ent = SV_GentityNum(e);

		// never send entities that aren't linked in
		if ( !ent->r.linked ) {
			continue;
		}

		if (ent->s.number != e) {
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->r.svFlags & SVF_NOCLIENT ) {
			continue;
		}

		// entities can be flagged to be sent to a given mask of clients
		if ( ent->r.svFlags & SVF_CLIENTMASK ) {
			if ( !Com_ClientListContains( &ent->r.sendClients, clientNum ) )
				continue;
		}

		svEnt = SV_SvEntityForGentity( ent );

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
			continue;
		}

		// limit based on distance
		if ( ent->r.cullDistance ) {
			vec3_t dir;
			VectorSubtract(ent->s.origin, origin, dir);
			if ( VectorLengthSquared(dir) > (float) ent->r.cullDistance * ent->r.cullDistance ) {
				continue;
			}
		}

		// broadcast entities are always sent
		if ( ent->r.svFlags & SVF_BROADCAST ) {
			SV_AddEntToSnapshot( frame, svEnt, ent, eNums );
			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
				continue;		// blocked by a door
			}
		}

		bitvector = clientpvs;

		// check individual leafs
		if ( !svEnt->numClusters ) {
			continue;
		}
		l = 0;
		for ( i=0 ; i < svEnt->numClusters ; i++ ) {
			l = svEnt->clusternums[i];
			if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
				break;
			}
		}

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
		if ( i == svEnt->numClusters ) {
			if ( svEnt->lastCluster ) {
				for ( ; l <= svEnt->lastCluster ; l++ ) {
					if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
						break;
					}
				}
				if ( l == svEnt->lastCluster ) {
					continue;	// not visible
				}
			} else {
				continue;
			}
		}

		// visibility dummies
		if ( ent->r.svFlags & SVF_VISDUMMY ) {
			sharedEntity_t *ment = NULL;

			// find master
			ment = SV_GentityNum( ent->r.visDummyNum );

			if ( ment ) {
				svEntity_t *master = NULL;
				master = SV_SvEntityForGentity( ment );

				if ( master->snapshotCounter == sv.snapshotCounter || !ment->r.linked ) {
					continue;
				}

				SV_AddEntToSnapshot( frame, master, ment, eNums );
			}

			// master needs to be added, but not this dummy ent
			continue;
		} else if ( ent->r.svFlags & SVF_VISDUMMY_MULTIPLE ) {
			int h;
			sharedEntity_t *ment = NULL;
			svEntity_t *master = NULL;

			for ( h = 0; h < sv.num_entities; h++ ) {
				ment = SV_GentityNum( h );

				if ( ment == ent ) {
					continue;
				}

				if ( ment ) {
					master = SV_SvEntityForGentity( ment );
				} else {
					continue;
				}

				if ( !ment->r.linked ) {
					continue;
				}

				if ( ment->s.number != h ) {
					Com_DPrintf( "FIXING vis dummy multiple ment->S.NUMBER!!!\n" );
					ment->s.number = h;
				}

				if ( ment->r.svFlags & SVF_NOCLIENT ) {
					continue;
				}

				if ( master->snapshotCounter == sv.snapshotCounter ) {
					continue;
				}

				if ( ment->r.visDummyNum == ent->s.number ) {
					SV_AddEntToSnapshot( frame, master, ment, eNums );
				}
			}

			// masters need to be added, but not this dummy ent
			continue;
		}

		// add it
		SV_AddEntToSnapshot( frame, svEnt, ent, eNums );

		// if it's a portal entity, add everything visible from its camera position
		if ( ent->r.svFlags & SVF_PORTAL ) {
			if ( ent->r.portalCullDistance ) {
				vec3_t dir;
				VectorSubtract(ent->s.origin, origin, dir);
				if ( VectorLengthSquared(dir) > (float) ent->r.portalCullDistance * ent->r.portalCullDistance ) {
					continue;
				}
			}
			SV_AddEntitiesVisibleFromPoint( psIndex, clientNum, ent->s.origin2, frame, eNums, qtrue );
		}

	}
コード例 #14
0
ファイル: sv_snapshot.c プロジェクト: JackalFrost/RTCW-WSGF
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame,
//									snapshotEntityNumbers_t *eNums, qboolean portal, clientSnapshot_t *oldframe, qboolean localClient ) {
//									snapshotEntityNumbers_t *eNums, qboolean portal ) {
											snapshotEntityNumbers_t *eNums, qboolean portal, qboolean localClient  ) {
	int e, i;
	sharedEntity_t *ent, *playerEnt;
	svEntity_t  *svEnt;
	int l;
	int clientarea, clientcluster;
	int leafnum;
	int c_fullsend;
	byte    *clientpvs;
	byte    *bitvector;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	leafnum = CM_PointLeafnum( origin );
	clientarea = CM_LeafArea( leafnum );
	clientcluster = CM_LeafCluster( leafnum );

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	clientpvs = CM_ClusterPVS( clientcluster );

	c_fullsend = 0;

	playerEnt = SV_GentityNum( frame->ps.clientNum );

	for ( e = 0 ; e < sv.num_entities ; e++ ) {
		ent = SV_GentityNum( e );

		// never send entities that aren't linked in
		if ( !ent->r.linked ) {
			continue;
		}

		if ( ent->s.number != e ) {
			Com_DPrintf( "FIXING ENT->S.NUMBER!!!\n" );
			ent->s.number = e;
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->r.svFlags & SVF_NOCLIENT ) {
			continue;
		}

		// entities can be flagged to be sent to only one client
		if ( ent->r.svFlags & SVF_SINGLECLIENT ) {
			if ( ent->r.singleClient != frame->ps.clientNum ) {
				continue;
			}
		}
		// entities can be flagged to be sent to everyone but one client
		if ( ent->r.svFlags & SVF_NOTSINGLECLIENT ) {
			if ( ent->r.singleClient == frame->ps.clientNum ) {
				continue;
			}
		}

		svEnt = SV_SvEntityForGentity( ent );

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
			continue;
		}

		// if this client is viewing from a camera, only add ents visible from portal ents
		if ( ( playerEnt->s.eFlags & EF_VIEWING_CAMERA ) && !portal ) {
			if ( ent->r.svFlags & SVF_PORTAL ) {
				SV_AddEntToSnapshot( svEnt, ent, eNums );
//				SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, oldframe, localClient );
				SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, localClient );
			}
			continue;
		}

		// broadcast entities are always sent
		if ( ent->r.svFlags & SVF_BROADCAST ) {
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
				goto notVisible;    // blocked by a door
			}
		}

		bitvector = clientpvs;

		// check individual leafs
		if ( !svEnt->numClusters ) {
			goto notVisible;
		}
		l = 0;
		for ( i = 0 ; i < svEnt->numClusters ; i++ ) {
			l = svEnt->clusternums[i];
			if ( bitvector[l >> 3] & ( 1 << ( l & 7 ) ) ) {
				break;
			}
		}

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
		if ( i == svEnt->numClusters ) {
			if ( svEnt->lastCluster ) {
				for ( ; l <= svEnt->lastCluster ; l++ ) {
					if ( bitvector[l >> 3] & ( 1 << ( l & 7 ) ) ) {
						break;
					}
				}
				if ( l == svEnt->lastCluster ) {
					goto notVisible;    // not visible
				}
			} else {
				goto notVisible;
			}
		}

		//----(SA) added "visibility dummies"
		if ( ent->r.svFlags & SVF_VISDUMMY ) {
			sharedEntity_t *ment = 0;

			//find master;
			ment = SV_GentityNum( ent->s.otherEntityNum );

			if ( ment ) {
				svEntity_t *master = 0;
				master = SV_SvEntityForGentity( ment );

				if ( master->snapshotCounter == sv.snapshotCounter || !ment->r.linked ) {
					goto notVisible;
					//continue;
				}

				SV_AddEntToSnapshot( master, ment, eNums );
			}
			goto notVisible;
			//continue;	// master needs to be added, but not this dummy ent
		}
		//----(SA) end
		else if ( ent->r.svFlags & SVF_VISDUMMY_MULTIPLE ) {
			{
				int h;
				sharedEntity_t *ment = 0;
				svEntity_t *master = 0;

				for ( h = 0; h < sv.num_entities; h++ )
				{
					ment = SV_GentityNum( h );

					if ( ment == ent ) {
						continue;
					}

					if ( ment ) {
						master = SV_SvEntityForGentity( ment );
					} else {
						continue;
					}

					if ( !( ment->r.linked ) ) {
						continue;
					}

					if ( ment->s.number != h ) {
						Com_DPrintf( "FIXING vis dummy multiple ment->S.NUMBER!!!\n" );
						ment->s.number = h;
					}

					if ( ment->r.svFlags & SVF_NOCLIENT ) {
						continue;
					}

					if ( master->snapshotCounter == sv.snapshotCounter ) {
						continue;
					}

					if ( ment->s.otherEntityNum == ent->s.number ) {
						SV_AddEntToSnapshot( master, ment, eNums );
					}
				}
				goto notVisible;
			}
		}

		// add it
		SV_AddEntToSnapshot( svEnt, ent, eNums );

		// if its a portal entity, add everything visible from its camera position
		if ( ent->r.svFlags & SVF_PORTAL ) {
//			SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, oldframe, localClient );
			SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue, localClient );
		}

		continue;

notVisible:

		// Ridah, if this entity has changed events, then send it regardless of whether we can see it or not
		// DHM - Nerve :: not in multiplayer please
		if ( sv_gametype->integer == GT_SINGLE_PLAYER && localClient ) {
			if ( ent->r.eventTime == svs.time ) {
				ent->s.eFlags |= EF_NODRAW;     // don't draw, just process event
				SV_AddEntToSnapshot( svEnt, ent, eNums );
			} else if ( ent->s.eType == ET_PLAYER ) {
				// keep players around if they are alive and active (so sounds dont get messed up)
				if ( !( ent->s.eFlags & EF_DEAD ) ) {
					ent->s.eFlags |= EF_NODRAW;     // don't draw, just process events and sounds
					SV_AddEntToSnapshot( svEnt, ent, eNums );
				}
			}
		}

	}
コード例 #15
0
ファイル: sv_game.c プロジェクト: Clever-Boy/qfusion
static inline bool PF_CM_AreasConnected( int area1, int area2 ) {
	return CM_AreasConnected( svs.cms, area1, area2 );
}
コード例 #16
0
/*
===============
SV_AddEntitiesVisibleFromPoint
===============
*/
static void SV_AddEntitiesVisibleFromPoint( vec3_t origin, clientSnapshot_t *frame, 
									snapshotEntityNumbers_t *eNums, qboolean portal ) {
	int		e, i;
	gentity_t	*ent;
	svEntity_t	*svEnt;
	int		l;
	int		clientarea, clientcluster;
	int		leafnum;
	int		c_fullsend;
	const byte *clientpvs;
	const byte *bitvector;
	qboolean sightOn = qfalse;

	// during an error shutdown message we may need to transmit
	// the shutdown message after the server has shutdown, so
	// specfically check for it
	if ( !sv.state ) {
		return;
	}

	leafnum = CM_PointLeafnum (origin);
	clientarea = CM_LeafArea (leafnum);
	clientcluster = CM_LeafCluster (leafnum);

	// calculate the visible areas
	frame->areabytes = CM_WriteAreaBits( frame->areabits, clientarea );

	clientpvs = CM_ClusterPVS (clientcluster);

	c_fullsend = 0;

	if ( !portal )
	{//not if this if through a portal...???  James said to do this...
		if ( (frame->ps.forcePowersActive&(1<<FP_SEE)) )
		{
			sightOn = qtrue;
		}
	}

	for ( e = 0 ; e < ge->num_entities ; e++ ) {
		ent = SV_GentityNum(e);

		if (!ent->inuse) {
			continue;
		}

		if (ent->s.eFlags & EF_PERMANENT)
		{	// he's permanent, so don't send him down!
			continue;
		}

		if (ent->s.number != e) {
			Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
			ent->s.number = e;
		}

		// never send entities that aren't linked in
		if ( !ent->linked ) {
			continue;
		}

		// entities can be flagged to explicitly not be sent to the client
		if ( ent->svFlags & SVF_NOCLIENT ) {
			continue;
		}

		svEnt = SV_SvEntityForGentity( ent );

		// don't double add an entity through portals
		if ( svEnt->snapshotCounter == sv.snapshotCounter ) {
			continue;
		}

		// broadcast entities are always sent, and so is the main player so we don't see noclip weirdness
		if ( ent->svFlags & SVF_BROADCAST || !e) {
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		if (ent->s.isPortalEnt)
		{ //rww - portal entities are always sent as well
			SV_AddEntToSnapshot( svEnt, ent, eNums );
			continue;
		}

		if ( sightOn )
		{//force sight is on, sees through portals, so draw them always if in radius
			if ( SV_PlayerCanSeeEnt( ent, frame->ps.forcePowerLevel[FP_SEE] ) )
			{//entity is visible
				SV_AddEntToSnapshot( svEnt, ent, eNums );
				continue;
			}
		}

		// ignore if not touching a PV leaf
		// check area
		if ( !CM_AreasConnected( clientarea, svEnt->areanum ) ) {
			// doors can legally straddle two areas, so
			// we may need to check another one
			if ( !CM_AreasConnected( clientarea, svEnt->areanum2 ) ) {
				continue;		// blocked by a door
			}
		}

		bitvector = clientpvs;

		// check individual leafs
		if ( !svEnt->numClusters ) {
			continue;
		}
		l = 0;
#ifdef _XBOX
		if(bitvector) {
#endif
		for ( i=0 ; i < svEnt->numClusters ; i++ ) {
			l = svEnt->clusternums[i];
			if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
				break;
			}
		}
#ifdef _XBOX
		}
#endif

		// if we haven't found it to be visible,
		// check overflow clusters that coudln't be stored
#ifdef _XBOX
		if ( bitvector && i == svEnt->numClusters ) {
#else
		if ( i == svEnt->numClusters ) {
#endif
			if ( svEnt->lastCluster ) {
				for ( ; l <= svEnt->lastCluster ; l++ ) {
					if ( bitvector[l >> 3] & (1 << (l&7) ) ) {
						break;
					}
				}
				if ( l == svEnt->lastCluster ) {
					continue;		// not visible
				}
			} else {
				continue;
			}
		}

		// add it
		SV_AddEntToSnapshot( svEnt, ent, eNums );

		// if its a portal entity, add everything visible from its camera position
		if ( ent->svFlags & SVF_PORTAL ) {
			SV_AddEntitiesVisibleFromPoint( ent->s.origin2, frame, eNums, qtrue );
#ifdef _XBOX
			//Must get clientpvs again since above call destroyed it.
		clientpvs = CM_ClusterPVS (clientcluster);
#endif
		}
	}
}