static gentity_t *SpawnPodium( void ) { gentity_t *podium; vec3_t vec; vec3_t origin; podium = G_Spawn(); if ( !podium ) { return NULL; } podium->classname = "podium"; podium->s.eType = ET_GENERAL; podium->s.number = podium - g_entities; podium->clipmask = CONTENTS_SOLID; podium->r.contents = CONTENTS_SOLID; podium->s.modelindex = G_ModelIndex( SP_PODIUM_MODEL ); AngleVectors( level.intermission_angle, vec, NULL, NULL ); VectorMA( level.intermission_origin, Cvar_VariableIntegerValue( "g_podiumDist" ), vec, origin ); origin[2] -= Cvar_VariableIntegerValue( "g_podiumDrop" ); G_SetOrigin( podium, origin ); VectorSubtract( level.intermission_origin, podium->r.currentOrigin, vec ); podium->s.apos.trBase[YAW] = vectoyaw( vec ); SV_LinkEntity (podium); podium->think = PodiumPlacementThink; podium->nextthink = level.time + 100; return podium; }
/* =============== RespawnItem =============== */ void RespawnItem( GameEntity *ent ) { // randomly select from teamed entities if( ent->team_ ) { GameEntity *master; int count; int choice; if( !ent->teammaster_ ) Com_Error( ERR_DROP, "RespawnItem: bad teammaster"); master = ent->teammaster_; for( count = 0, ent = master; ent; ent = ent->teamchain_, count++ ) ; choice = rand() % count; for( count = 0, ent = master; count < choice; ent = ent->teamchain_, count++ ) ; } ent->r.contents = CONTENTS_TRIGGER; ent->s.eFlags &= ~EF_NODRAW; ent->r.svFlags &= ~SVF_NOCLIENT; SV_LinkEntity(ent); // play the normal respawn sound only to nearby clients G_AddEvent( ent, EV_ITEM_RESPAWN, 0, true ); ent->nextthink_ = 0; }
static gentity_t *SpawnModelOnVictoryPad( gentity_t *pad, vec3_t offset, gentity_t *ent, int place ) { gentity_t *body; vec3_t vec; vec3_t f, r, u; body = G_Spawn(); if ( !body ) { Com_Printf( S_COLOR_RED "ERROR: out of gentities\n" ); return NULL; } body->classname = ent->client->pers.netname; body->client = ent->client; body->s = ent->s; body->s.eType = ET_PLAYER; // could be ET_INVISIBLE body->s.eFlags = 0; // clear EF_TALK, etc body->s.powerups = 0; // clear powerups body->s.loopSound = 0; // clear lava burning body->s.number = body - g_entities; body->timestamp = level.time; body->physicsObject = qtrue; body->physicsBounce = 0; // don't bounce body->s.event = 0; body->s.pos.trType = TR_STATIONARY; body->s.groundEntityNum = ENTITYNUM_WORLD; body->s.legsAnim = LEGS_IDLE; body->s.torsoAnim = TORSO_STAND; body->s.weapon = WP_MELEE; body->s.event = 0; body->r.svFlags = ent->r.svFlags; VectorCopy (ent->r.mins, body->r.mins); VectorCopy (ent->r.maxs, body->r.maxs); VectorCopy (ent->r.absmin, body->r.absmin); VectorCopy (ent->r.absmax, body->r.absmax); body->clipmask = CONTENTS_SOLID | CONTENTS_PLAYERCLIP; body->r.contents = CONTENTS_BODY; body->r.ownerNum = ent->r.ownerNum; body->takedamage = qfalse; VectorSubtract( level.intermission_origin, pad->r.currentOrigin, vec ); vectoangles( vec, body->s.apos.trBase ); body->s.apos.trBase[PITCH] = 0; body->s.apos.trBase[ROLL] = 0; AngleVectors( body->s.apos.trBase, f, r, u ); VectorMA( pad->r.currentOrigin, offset[0], f, vec ); VectorMA( vec, offset[1], r, vec ); VectorMA( vec, offset[2], u, vec ); G_SetOrigin( body, vec ); SV_LinkEntity (body); body->count = place; return body; }
void setOrigin(gentity_s* ent, const vec3_t pos) { G_SetOrigin(ent, pos); if (ent->r.linked) { SV_LinkEntity(ent); } }
/*QUAKED misc_portal_camera (0 0 1) (-8 -8 -8) (8 8 8) slowrotate fastrotate The target for a misc_portal_director. You can set either angles or target another entity to determine the direction of view. "roll" an angle modifier to orient the camera around the target vector; */ void SP_misc_portal_camera( GameEntity* ent ) { float roll; VectorClear( ent->r.mins ); VectorClear( ent->r.maxs ); SV_LinkEntity( ent ); G_SpawnFloat( "roll", "0", &roll ); ent->s.clientNum = roll/360.0 * 256; }
/* ================ FinishSpawningItem Traces down to find where an item should rest, instead of letting them free fall from their spawn points ================ */ void GameItem::Think_FinishSpawningItem::execute() { trace_t tr; vec3_t dest; VectorSet( self_->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS ); VectorSet( self_->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS ); self_->s.eType = ET_ITEM; self_->s.modelindex = self_->item_ - bg_itemlist; // store item number in modelindex self_->s.modelindex2 = 0; // zero indicates this isn't a dropped item self_->r.contents = CONTENTS_TRIGGER; self_->setTouch(new Touch_ItemTouch); // useing an item causes it to respawn self_->setUse(new Use_ItemUse); if( self_->spawnflags_ & 1 ) { // suspended G_SetOrigin( self_, self_->s.origin ); } else { // drop to floor VectorSet( dest, self_->s.origin[0], self_->s.origin[1], self_->s.origin[2] - 4096 ); SV_Trace( &tr, self_->s.origin, self_->r.mins, self_->r.maxs, dest, self_->s.number, MASK_SOLID, false ); if( tr.startsolid ) { Com_Printf ("FinishSpawningItem: %s startsolid at %s\n", self_->classname_, vtos(self_->s.origin)); //theLevel.removeEntity(self_); self_->freeUp(); return; } // allow to ride movers self_->s.groundEntityNum = tr.entityNum; G_SetOrigin( self_, tr.endpos ); } // team slaves and targeted items aren't present at start if( ( self_->flags_ & FL_TEAMSLAVE ) || self_->targetname_ ) { self_->s.eFlags |= EF_NODRAW; self_->r.contents = 0; return; } SV_LinkEntity( self_ ); }
/* ================ LaunchItem Spawns an item and tosses it forward ================ */ GameEntity *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity ) { GameEntity *dropped; dropped = theLevel.spawnEntity(); dropped->s.eType = ET_ITEM; dropped->s.modelindex = item - bg_itemlist; // store item number in modelindex dropped->s.modelindex2 = 1; // This is non-zero is it's a dropped item dropped->classname_ = item->classname; dropped->item_ = item; VectorSet( dropped->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS ); VectorSet( dropped->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS ); dropped->r.contents = CONTENTS_TRIGGER; dropped->setTouch(new Touch_ItemTouch); G_SetOrigin( dropped, origin ); dropped->s.pos.trType = TR_GRAVITY; dropped->s.pos.trTime = theLevel.time_; VectorCopy( velocity, dropped->s.pos.trDelta ); dropped->s.eFlags |= EF_BOUNCE_HALF; if( g_gametype.integer == GT_CTF && item->giType == IT_TEAM) { // Special case for CTF flags dropped->setThink(new Think_Team_DroppedFlagThink); dropped->nextthink_ = theLevel.time_ + 180000; Team_CheckDroppedItem( dropped ); } else { // auto-remove after 30 seconds dropped->setThink(new GameEntity::EntityFunc_Free); dropped->nextthink_ = theLevel.time_ + 30000; } dropped->flags_ = FL_DROPPED_ITEM; SV_LinkEntity( dropped ); return dropped; }
void SP_target_speaker( GameEntity *ent ) { char buffer[MAX_QPATH]; char *s; G_SpawnFloat( "wait", "0", &ent->wait_ ); G_SpawnFloat( "random", "0", &ent->random_ ); if ( !G_SpawnString( "noise", "NOSOUND", &s ) ) Com_Error( ERR_DROP, "target_speaker without a noise key at %s", vtos( ent->s.origin ) ); // force all client reletive sounds to be "activator" speakers that // play on the entity that activates it if ( s[0] == '*' ) ent->spawnflags_ |= 8; if (!strstr( s, ".wav" )) Com_sprintf (buffer, sizeof(buffer), "%s.wav", s ); else Q_strncpyz( buffer, s, sizeof(buffer) ); ent->noise_index_ = G_SoundIndex(buffer); // a repeating speaker can be done completely client side ent->s.eType = ET_SPEAKER; ent->s.eventParm = ent->noise_index_; ent->s.frame = ent->wait_ * 10; ent->s.clientNum = ent->random_ * 10; // check for prestarted looping sound if( ent->spawnflags_ & 1 ) ent->s.loopSound = ent->noise_index_; ent->setUse(new Use_TargetSpeaker); if( ent->spawnflags_ & 4 ) ent->r.svFlags |= SVF_BROADCAST; VectorCopy( ent->s.origin, ent->s.pos.trBase ); // must link the entity so we get areas and clusters so // the server can determine who to send updates to SV_LinkEntity( ent ); }
/*QUAKED misc_portal_surface (0 0 1) (-8 -8 -8) (8 8 8) The portal surface nearest this entity will show a view from the targeted misc_portal_camera, or a mirror view if untargeted. This must be within 64 world units of the surface! */ void SP_misc_portal_surface( GameEntity *ent ) { VectorClear( ent->r.mins ); VectorClear( ent->r.maxs ); SV_LinkEntity( ent ); ent->r.svFlags = SVF_PORTAL; ent->s.eType = ET_PORTAL; if ( !ent->target_ ) { VectorCopy( ent->s.origin, ent->s.origin2 ); } else { ent->setThink(new Think_LocateCamera); ent->nextthink_ = theLevel.time_ + 100; } }
gentity_s* spawnTurret(uint16_t classname, const vec3_t origin, /*const vec3_t angles,*/ const char* weaponInfo) { //gentity_s* turret = G_SpawnStaticEntity(0x4E, 0x20, "turret"); //Scr_SetString(&turret->classname, classname); //VectorCopy(origin, turret->r.currentOrigin); //VectorCopy(angles, turret->r.currentAngles); //G_SpawnTurret(turret, weapon, 0); //turret->r.svFlags = 1; ////turret->takedamage = 4; // optional //SV_LinkEntity(turret); //Scr_AddEntity(SCRIPTINSTANCE_SERVER, turret); //return turret; gentity_s* turret = SpawnTurretInternal(classname, origin, weaponInfo); turret->takedamage = 1; turret->r.svFlags = 4; SV_LinkEntity(turret); return turret; }
/* ============= PhysicsEntitySetTransform ============= */ static void PhysicsEntitySetTransform ( const NewtonBody* body, const dFloat* matrix, int threadIndex ) { if(com_sv_running->integer) { sharedEntity_t *ent = (sharedEntity_t*)NewtonBodyGetUserData (body); vec3_t newPosition, angles, axis[3]; SV_UnlinkEntity (ent); newPosition[0] = matrix[12]; newPosition[1] = matrix[13]; newPosition[2] = matrix[14]; // update the origin. VectorScale (newPosition, METRES_PER_UNIT, newPosition); VectorCopy (newPosition, ent->s.pos.trBase); VectorCopy (newPosition, ent->r.currentOrigin); VectorCopy (newPosition, ent->s.origin); axis[0][0] = matrix[0]; axis[0][1] = matrix[1]; axis[0][2] = matrix[2]; axis[1][0] = matrix[4]; axis[1][1] = matrix[5]; axis[1][2] = matrix[6]; axis[2][0] = matrix[8]; axis[2][1] = matrix[9]; axis[2][2] = matrix[10]; AxisToAngles (axis, angles); VectorCopy (angles, ent->s.apos.trBase); VectorCopy (angles, ent->r.currentAngles); VectorCopy (angles, ent->s.angles); SV_LinkEntity (ent); #if defined(_DEBUG) Com_Printf ("PHYSICS: updating %d new position %s\n", ent->s.number, vtos (newPosition)); #endif } }
/* ================= SV_SetBrushModel sets mins and maxs for inline bmodels ================= */ void SV_SetBrushModel(sharedEntity_t * ent, const char *name) { clipHandle_t h; vec3_t mins, maxs; if(!name) { Com_Error(ERR_DROP, "SV_SetBrushModel: NULL"); } if(name[0] != '*') { Com_Error(ERR_DROP, "SV_SetBrushModel: %s isn't a brush model", name); } ent->s.modelindex = atoi(name + 1); h = CM_InlineModel(ent->s.modelindex); CM_ModelBounds(h, mins, maxs); VectorCopy(mins, ent->r.mins); VectorCopy(maxs, ent->r.maxs); ent->r.bmodel = true; ent->r.contents = -1; // we don't know exactly what is in the brushes SV_LinkEntity(ent); // FIXME: remove }
/* ==================== 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; }
void VehicleDeathImpl( GameEntity* self, GameEntity* inflictor, GameEntity* attacker, int damage, int meansOfDeath ) { GameEntity* ent; int contents; int killer; int i; char *killerName, *obit; if ( self->client_->ps_.pm_type == PM_DEAD ) return; if ( theLevel.intermissiontime_ ) return; if ( attacker ) { killer = attacker->s.number; if ( attacker->client_ ) killerName = attacker->client_->pers_.netname_; else killerName = "<non-client>"; } else { killer = ENTITYNUM_WORLD; killerName = "<world>"; } if ( killer < 1 || killer > MAX_CLIENTS ) { killer = ENTITYNUM_WORLD; killerName = "<world>"; } if ( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) obit = "<bad obituary>"; else obit = modNames[ meansOfDeath ]; G_LogPrintf( "Kill: %i %i %i: %s killed %s by %s\n", killer, self->s.number, meansOfDeath, killerName, self->client_->pers_.netname_, obit ); // broadcast the death event to everyone ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY ); ent->s.eventParm = meansOfDeath; ent->s.otherEntityNum = self->s.number; ent->s.otherEntityNum2 = killer; ent->r.svFlags = SVF_BROADCAST; // send to everyone self->enemy_ = attacker; self->client_->ps_.persistant[PERS_KILLED]++; if( attacker && attacker->client_ ) { attacker->client_->lastkilled_client_ = self->s.number; if ( attacker == self || OnSameTeam (self, attacker ) ) { AddScore( attacker, self->r.currentOrigin, -1 ); } else { if( attacker->r.svFlags & SVF_BOT ) { AddScore( attacker, self->r.currentOrigin, 1 ); } else { if( meansOfDeath != MOD_VEHICLEEXPLOSION && meansOfDeath != MOD_CRASH ) { AddScore( attacker, self->r.currentOrigin, 1 ); } // Easy way to prevent enemy from lossing score in collision as well cause he kills "himself" else { AddScore( attacker, self->r.currentOrigin, 1 ); } } attacker->client_->lastKillTime_ = theLevel.time_; } } else { AddScore( self, self->r.currentOrigin, -1 ); } // add team bonuses Team_FragBonuses(self, inflictor, attacker); // if I committed suicide, the flag does not fall, it returns. if (meansOfDeath == MOD_SUICIDE) { if ( self->client_->ps_.objectives & OB_REDFLAG ) { // only happens in standard CTF Team_ReturnFlag( ClientBase::TEAM_RED ); self->client_->ps_.objectives &= ~OB_REDFLAG; } else if ( self->client_->ps_.objectives & OB_BLUEFLAG ) { // only happens in standard CTF Team_ReturnFlag( ClientBase::TEAM_BLUE ); self->client_->ps_.objectives &= ~OB_BLUEFLAG; } } // if client is in a nodrop area, don't drop anything (but return CTF flags!) contents = SV_PointContents( self->r.currentOrigin, -1 ); if ( !( contents & CONTENTS_NODROP )) { if( g_gametype.integer == GT_CTF ) TossVehicleFlags( self ); } else { if ( contents & CONTENTS_NODROP ) { if ( self->client_->ps_.objectives & OB_REDFLAG ) // only happens in standard CTF Team_ReturnFlag( ClientBase::TEAM_RED ); else if ( self->client_->ps_.objectives & OB_BLUEFLAG ) // only happens in standard CTF Team_ReturnFlag( ClientBase::TEAM_BLUE ); } } // update scores Cmd_Score_f( self ); // send updated scores to any clients that are following this one, // or they would get stale scoreboards for( i = 1 ; i <= theLevel.maxclients_ ; i++ ) { GameClient* client = theLevel.getClient(i);// &level.clients[i]; if( !client || client->pers_.connected_ != GameClient::ClientPersistant::CON_CONNECTED ) continue; if( client->sess_.sessionTeam_ != ClientBase::TEAM_SPECTATOR ) continue; if( client->sess_.spectatorClient_ == self->s.number ) Cmd_Score_f( theLevel.getEntity(i) );// g_entities + i ); } self->takedamage_ = true; // can still be gibbed self->r.contents = CONTENTS_CORPSE; self->s.objectives = 0; self->s.loopSound = 0; self->r.maxs[2] = -8; // remove powerups /* memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) ); */ if( (self->ONOFF_ & OO_LANDED) && self->health_ > GIB_HEALTH ) self->health_ = GIB_HEALTH - 1; // always gib ground vehicles and lqms if( availableVehicles[self->client_->vehicle_].cat & CAT_GROUND ) self->health_ = GIB_HEALTH - 1; // Adjust gib for LQM's if( self->health_ < 0 && self->health_ > GIB_HEALTH+20 ) self->health_ = GIB_HEALTH+5; // to gib or not to gib? if ( self->health_ <= GIB_HEALTH ) /* && !(contents & CONTENTS_NODROP) ) // never gib in a nodrop */ { // create vehicle explosion ExplodeVehicle( self ); // create radius explosion damage G_RadiusDamage( self->r.currentOrigin, self, 150, 150, self, MOD_VEHICLEEXPLOSION, CAT_ANY ); } else if ( availableVehicles[self->client_->vehicle_].cat & CAT_LQM ) { self->setDie(new VehicleBase::VehicleDie); self->client_->respawnTime_ = theLevel.time_ + 3000; } else { // create a smaller vehicle explosion G_AddEvent( self, EV_VEHICLE_DIE, 0, true ); // wreck can be blown up (i.e on crash into ground) self->setDie(new VehicleBase::VehicleDie); // prevent early respawning during death anim (allows 30 seconds) self->client_->respawnTime_ = theLevel.time_ + 30000; } SV_LinkEntity( self ); }
/* ================ G_RunItem ================ */ void G_RunItem( GameEntity *ent ) { vec3_t origin; trace_t tr; int contents; int mask; // if groundentity has been set to -1, it may have been pushed off an edge if ( ent->s.groundEntityNum == -1 ) { if ( ent->s.pos.trType != TR_GRAVITY ) { ent->s.pos.trType = TR_GRAVITY; ent->s.pos.trTime = theLevel.time_; } } if ( ent->s.pos.trType == TR_STATIONARY ) { // check think function G_RunThink( ent ); return; } // get current position BG_EvaluateTrajectory( &ent->s.pos, theLevel.time_, origin ); // trace a line from the previous position to the current position if ( ent->clipmask_ ) mask = ent->clipmask_; else mask = MASK_PLAYERSOLID & ~CONTENTS_BODY;//MASK_SOLID; SV_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->r.ownerNum, mask, false ); VectorCopy( tr.endpos, ent->r.currentOrigin ); if ( tr.startsolid ) tr.fraction = 0; SV_LinkEntity( ent ); // FIXME: avoid this for stationary? // check think function G_RunThink( ent ); if ( tr.fraction == 1 ) return; // if it is in a nodrop volume, remove it contents = SV_PointContents( ent->r.currentOrigin, -1 ); if ( contents & CONTENTS_NODROP ) { if (ent->item_ && ent->item_->giType == IT_TEAM) Team_FreeEntity(ent); else ent->freeUp(); return; } G_BounceItem( ent, &tr ); }
virtual void execute( GameEntity *other, trace_t *trace ) { int respawn; bool predict; GameEntity* self = self_; // Since we may delete our current think() if( !other->client_ ) return; if( other->health_ < 1 ) return; // dead people can't pickup if( other->client_->ps_.pm_type == PM_SPECTATOR ) return; // the same pickup rules are used for client side and server side if ( !BG_CanItemBeGrabbed( g_gametype.integer, &self->s, &other->client_->ps_, other->client_->vehicle_ ) ) return; G_LogPrintf( "Item: %i %s\n", other->s.number, self->item_->classname ); predict = other->client_->pers_.predictItemPickup_; // call the item-specific pickup function switch( self->item_->giType ) { case IT_AMMO: respawn = Pickup_Ammo(self, other); break; case IT_HEALTH: respawn = Pickup_Health(self, other); break; case IT_FUEL: respawn = Pickup_Fuel(self, other); break; case IT_TEAM: respawn = Pickup_Team(self, other); break; default: return; } if ( !respawn ) return; // play the normal pickup sound if( predict ) G_AddPredictableEvent( other, EV_ITEM_PICKUP, self->s.modelindex ); else G_AddEvent( other, EV_ITEM_PICKUP, self->s.modelindex, true ); // powerup pickups are global broadcasts if( self->item_->giType == IT_TEAM) { // if we want the global sound to play if( !self->speed_ ) { GameEntity *te; te = G_TempEntity( self->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP ); te->s.eventParm = self->s.modelindex; te->r.svFlags |= SVF_BROADCAST; } else { GameEntity *te; te = G_TempEntity( self->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP ); te->s.eventParm = self->s.modelindex; // only send this temp entity to a single client te->r.svFlags |= SVF_SINGLECLIENT; te->r.singleClient = other->s.number; } } // fire item targets G_UseTargets (self, other); // wait of -1 will not respawn if( self->wait_ == -1 ) { self->r.svFlags |= SVF_NOCLIENT; self->s.eFlags |= EF_NODRAW; self->r.contents = 0; self->unlinkAfterEvent_ = true; return; } // non zero wait overrides respawn time if( self->wait_ ) respawn = self->wait_; // random can be used to vary the respawn time if( self->random_ ) { respawn += crandom() * self->random_; if ( respawn < 1 ) respawn = 1; } // dropped items will not respawn if( self->flags_ & FL_DROPPED_ITEM ) self->freeAfterEvent_ = true; // picked up items still stay around, they just don't // draw anything. This allows respawnable items // to be placed on movers. self->r.svFlags |= SVF_NOCLIENT; self->s.eFlags |= EF_NODRAW; self->r.contents = 0; // ZOID // A negative respawn times means to never respawn this item (but don't // delete it). This is used by items that are respawned by third party // events such as ctf flags if( respawn <= 0 ) { self->nextthink_ = 0; self->setThink(0); } else { self->nextthink_ = theLevel.time_ + respawn * 1000; self->setThink(new Think_RespawnItem); } SV_LinkEntity( self ); }