void DBall_BallRespawn (edict_t *self) { edict_t *start; // do the splash effect gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_DBALL_GOAL); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); // move the ball and stop it start = PickBallStart(self); if(start) { VectorCopy(start->s.origin, self->s.origin); VectorCopy(start->s.origin, self->s.old_origin); } VectorClear(self->s.angles); VectorClear(self->velocity); VectorClear(self->avelocity); self->solid = SOLID_BBOX; self->s.modelindex = gi.modelindex ("models/objects/dball/tris.md2"); self->s.event = EV_PLAYER_TELEPORT; self->groundentity = NULL; // kill anything at the destination KillBox (self); gi.linkentity (self); }
bool HoldableItemTransporter::use( void ) { Entity *spawnPoint; if ( _owner ) { if ( !_owner->isSubclassOf( Player ) ) return false; Player *player; player = (Player *)_owner; if ( multiplayerManager.inMultiplayer() ) { spawnPoint = multiplayerManager.getSpawnPoint( player ); if ( spawnPoint ) { if ( _modelToSpawn.length() > 0 ) { SpawnEffect( _modelToSpawn, player->origin, vec_zero, 1.0f ); } player->WarpToPoint( spawnPoint ); KillBox( player ); return true; } } } return false; }
/* * G_TeleportPlayer */ void G_TeleportPlayer( edict_t *player, edict_t *dest ) { int i; vec3_t velocity; mat3_t axis; float speed; gclient_t *client = player->r.client; if( !dest ) { return; } if( !client ) { return; } // draw the teleport entering effect G_TeleportEffect( player, false ); // // teleport the player // // from racesow - use old pmove velocity VectorCopy( client->old_pmove.velocity, velocity ); velocity[2] = 0; // ignore vertical velocity speed = VectorLengthFast( velocity ); AnglesToAxis( dest->s.angles, axis ); VectorScale( &axis[AXIS_FORWARD], speed, client->ps.pmove.velocity ); VectorCopy( dest->s.angles, client->ps.viewangles ); VectorCopy( dest->s.origin, client->ps.pmove.origin ); // set the delta angle for ( i = 0; i < 3; i++ ) client->ps.pmove.delta_angles[i] = ANGLE2SHORT( client->ps.viewangles[i] ) - client->ucmd.angles[i]; client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; client->ps.pmove.pm_time = 1; // force the minimum no control delay player->s.teleported = true; // update the entity from the pmove VectorCopy( client->ps.viewangles, player->s.angles ); VectorCopy( client->ps.pmove.origin, player->s.origin ); VectorCopy( client->ps.pmove.origin, player->s.old_origin ); VectorCopy( client->ps.pmove.origin, player->olds.origin ); VectorCopy( client->ps.pmove.velocity, player->velocity ); // unlink to make sure it can't possibly interfere with KillBox GClip_UnlinkEntity( player ); // kill anything at the destination KillBox( player ); GClip_LinkEntity( player ); // add the teleport effect at the destination G_TeleportEffect( player, true ); }
void monster_triggered_spawn(edict_t *self) { self->s.origin[2] += 1; KillBox(self); self->solid = SOLID_BBOX; self->movetype = MOVETYPE_STEP; self->svflags &= ~SVF_NOCLIENT; self->air_finished = level.time + 12; gi.linkentity(self); monster_start_go(self); if (self->enemy && !(self->spawnflags & SF_MONSTER_SIGHT) && !(self->enemy->flags & FL_NOTARGET)) { if (!(self->enemy->flags & FL_DISGUISED)) { FoundTarget(self); } else { self->enemy = NULL; } } else { self->enemy = NULL; } }
static void func_explosive_spawn( edict_t *self, edict_t *other, edict_t *activator ) { self->r.solid = SOLID_YES; self->r.svflags &= ~SVF_NOCLIENT; self->use = NULL; KillBox( self ); GClip_LinkEntity( self ); }
void func_object_use (edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; self->use = NULL; KillBox (self); func_object_release (self); }
void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; self->use = NULL; KillBox (self); gi.linkentity (self); }
//========================================== // BOT_DMClass_JoinGame // put the bot into the game. //========================================== void BOT_DMClass_JoinGame (edict_t *ent, char *team_name) { char *s; //int rnd = CLASS_PALADIN; if ( !BOT_JoinCTFTeam(ent, team_name) ) gi.bprintf (PRINT_HIGH, "[BOT] %s joined the game.\n", ent->client->pers.netname); ent->think = AI_Think; ent->nextthink = level.time + FRAMETIME; // az: Vortex stuff disableAbilities(ent); ent->myskills.level = AveragePlayerLevel(); ent->myskills.speciality_points = ent->myskills.level * 2; s = Info_ValueForKey (ent->client->pers.userinfo, "skin"); /*while (1) // except the knight, any class. { rnd = GetRandom(1, CLASS_MAX); if (rnd != CLASS_PALADIN && rnd != CLASS_POLTERGEIST) break; } ent->myskills.class_num = rnd;*/ ent->myskills.class_num = CLASS_SOLDIER; ent->myskills.respawn_weapon = GetRandom(1, 11); ent->client->pers.spectator = false; ent->client->resp.spectator = false; vrx_add_respawn_items(ent); vrx_add_respawn_weapon(ent, ent->myskills.respawn_weapon); vrx_assign_abilities(ent); vrx_set_talents(ent); ent->myskills.streak = 0; BOT_VortexAssignSkills(ent); //join game ent->movetype = MOVETYPE_WALK; ent->solid = SOLID_BBOX; ent->svflags &= ~SVF_NOCLIENT; ent->client->ps.gunindex = 0; PutClientInServer(ent); if (!KillBox (ent)) { // could't spawn in? } gi.linkentity (ent); }
void teleporter_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *dest; int i; if (!other->client) { return; } dest = G_Find(NULL, FOFS(targetname), self->target); if (!dest) { gi.dprintf("Couldn't find destination\n"); return; } CTFPlayerResetGrapple(other); /* unlink to make sure it can't possibly interfere with KillBox */ gi.unlinkentity(other); VectorCopy(dest->s.origin, other->s.origin); VectorCopy(dest->s.origin, other->s.old_origin); other->s.origin[2] += 10; /* clear the velocity and hold them in place briefly */ VectorClear(other->velocity); other->client->ps.pmove.pm_time = 160 >> 3; /* hold time */ other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; /* draw the teleport splash at source and on the player */ self->owner->s.event = EV_PLAYER_TELEPORT; other->s.event = EV_PLAYER_TELEPORT; /* set angles */ for (i = 0; i < 3; i++) { other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); } VectorClear(other->s.angles); VectorClear(other->client->ps.viewangles); VectorClear(other->client->v_angle); /* kill anything at the destination */ KillBox(other); gi.linkentity(other); }
static void Summon(edict_t *ent, edict_t *other) { vec3_t offset, forward, right, start; trace_t tr; if (other->client->blinky_client.nosummon) return; VectorSet(offset, 40, 0, ent->viewheight-8); AngleVectors (ent->client->v_angle, forward, right, NULL); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); // code mostly copied from KillBox // unlink to make sure it can't possibly interfere with KillBox gi.unlinkentity (other); tr = gi.trace (start, other->mins, other->maxs, start, NULL, MASK_PLAYERSOLID); if (tr.fraction < 1.0) { gi.linkentity (other); return; } VectorCopy (start, other->s.origin); VectorCopy (start, other->s.old_origin); other->s.origin[2] += 10; // clear the velocity and hold them in place briefly VectorClear (other->velocity); other->client->ps.pmove.pm_time = 160>>3; // hold time other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; // draw the teleport splash at source and on the player other->s.event = EV_PLAYER_TELEPORT; // set angles MoveToAngles(other, ent->s.angles); VectorClear (other->s.angles); VectorClear (other->client->ps.viewangles); VectorClear (other->client->v_angle); // kill anything at the destination KillBox (other); gi.linkentity (other); }
void func_wall_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->solid == SOLID_NOT) { self->solid = SOLID_BSP; self->svflags &= ~SVF_NOCLIENT; KillBox(self); } else { self->solid = SOLID_NOT; self->svflags |= SVF_NOCLIENT; } gi.linkentity(self); if (!(self->spawnflags & 2)) self->use = NULL; }
void use_target_spawner (edict_t *self, edict_t *other, edict_t *activator) { edict_t *ent; ent = G_Spawn(); ent->classname = self->target; VectorCopy (self->s.origin, ent->s.origin); VectorCopy (self->s.angles, ent->s.angles); ED_CallSpawn (ent); gi.unlinkentity (ent); KillBox (ent); gi.linkentity (ent); if (self->speed) VectorCopy (self->movedir, ent->velocity); }
static void func_wall_use( edict_t *self, edict_t *other, edict_t *activator ) { if( self->r.solid == SOLID_NOT ) { self->r.solid = SOLID_YES; self->r.svflags &= ~SVF_NOCLIENT; KillBox( self ); } else { self->r.solid = SOLID_NOT; self->r.svflags |= SVF_NOCLIENT; } GClip_LinkEntity( self ); if( !( self->spawnflags & 2 ) ) self->use = NULL; }
//========================================== // BOT_DMClass_JoinGame // put the bot into the game. //========================================== void BOT_DMClass_JoinGame (edict_t *ent, char *team_name) { if ( !BOT_JoinCTFTeam(ent, team_name) ) Com_Printf ( "%s joined the game.\n", ent->client->pers.netname); ent->think = AI_Think; ent->nextthink = level.time + FRAMETIME; //join game ent->movetype = MOVETYPE_WALK; ent->solid = SOLID_BBOX; ent->svflags &= ~SVF_NOCLIENT; ent->client->ps.gunindex = 0; if (!KillBox (ent)) { // could't spawn in? } gi.linkentity (ent); }
/////////////////////////////////////////////////////////////////////// // Called by PutClient in Server to actually release the bot into the game // Keep from killin' each other when all spawned at once /////////////////////////////////////////////////////////////////////// void ACESP_HoldSpawn(edict_t *self) { if (!KillBox(self)) { // could't spawn in? } gi.linkentity(self); self->think = ACEAI_Think; self->nextthink = level.time + FRAMETIME; // send effect gi.WriteByte(svc_muzzleflash); gi.WriteShort(self-g_edicts); gi.WriteByte(MZ_LOGIN); gi.multicast(self->s.origin, MULTICAST_PVS); if (ctf->value) safe_bprintf(PRINT_MEDIUM, "%s joined the %s team.\n", self->client->pers.netname, CTFTeamName(self->client->resp.ctf_team)); else safe_bprintf(PRINT_MEDIUM, "%s entered the game\n", self->client->pers.netname); }
/////////////////////////////////////////////////////////////////////// // Modified version of id's code /////////////////////////////////////////////////////////////////////// void ACESP_PutClientInServer(edict_t *bot, qboolean respawn, int team) { vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; int index; vec3_t spawn_origin, spawn_angles; gclient_t *client; client_persistant_t saved; client_respawn_t resp; char *s; int spawn_style; int spawn_health; // find a spawn point // do it before setting health back up, so farthest // ranging doesn't count this client SelectSpawnPoint (bot, spawn_origin, spawn_angles, &spawn_style, &spawn_health); index = bot-g_edicts-1; client = bot->client; // deathmatch wipes most client data every spawn if (deathmatch->value) { char userinfo[MAX_INFO_STRING]; resp = bot->client->resp; memcpy (userinfo, client->pers.userinfo, sizeof(userinfo)); InitClientPersistant (client, spawn_style); ClientUserinfoChanged (bot, userinfo); } else memset(&resp, 0, sizeof(resp)); // clear everything but the persistant data saved = client->pers; memset(client, 0, sizeof(*client)); client->pers = saved; client->resp = resp; // copy some data from the client to the entity FetchClientEntData (bot); // clear entity values bot->groundentity = NULL; bot->client = &game.clients[index]; bot->takedamage = DAMAGE_AIM; bot->movetype = MOVETYPE_WALK; bot->viewheight = 24; bot->classname = "bot"; bot->mass = 200; bot->solid = SOLID_BBOX; bot->deadflag = DEAD_NO; bot->air_finished = level.time + 12; bot->clipmask = MASK_PLAYERSOLID; bot->model = "players/male/tris.md2"; bot->pain = player_pain; bot->die = player_die; bot->waterlevel = 0; bot->watertype = 0; bot->flags &= ~FL_NO_KNOCKBACK; bot->svflags &= ~SVF_DEADMONSTER; bot->is_jumping = false; if (ctf->value) { client->resp.ctf_team = team; client->resp.ctf_state = CTF_STATE_START; s = Info_ValueForKey(client->pers.userinfo, "skin"); CTFAssignSkin(bot, s); } VectorCopy(mins, bot->mins); VectorCopy(maxs, bot->maxs); VectorClear(bot->velocity); // clear playerstate values memset(&bot->client->ps, 0, sizeof(client->ps)); client->ps.pmove.origin[0] = spawn_origin[0]*8; client->ps.pmove.origin[1] = spawn_origin[1]*8; client->ps.pmove.origin[2] = spawn_origin[2]*8; //ZOID client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; //ZOID if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV)) { client->ps.fov = 90; } else { client->ps.fov = atoi(Info_ValueForKey(client->pers.userinfo, "fov")); if (client->ps.fov < 1) client->ps.fov = 90; else if (client->ps.fov > 160) client->ps.fov = 160; } // Knightmare- fix for null model? if (client->pers.weapon && client->pers.weapon->view_model) client->ps.gunindex = gi.modelindex(client->pers.weapon->view_model); // clear entity state values bot->s.effects = 0; bot->s.skinnum = bot - g_edicts - 1; bot->s.modelindex = MAX_MODELS-1; // will use the skin specified model bot->s.modelindex2 = MAX_MODELS-1; // custom gun model bot->s.frame = 0; VectorCopy(spawn_origin, bot->s.origin); bot->s.origin[2] += 1; // make sure off ground // set the delta angle for (int i = 0; i < 3; i++) client->ps.pmove.delta_angles[i] = ANGLE2SHORT(spawn_angles[i] - client->resp.cmd_angles[i]); bot->s.angles[PITCH] = 0; bot->s.angles[YAW] = spawn_angles[YAW]; bot->s.angles[ROLL] = 0; VectorCopy(bot->s.angles, client->ps.viewangles); VectorCopy(bot->s.angles, client->v_angle); // force the current weapon up client->newweapon = client->pers.weapon; ChangeWeapon (bot); bot->enemy = NULL; bot->movetarget = NULL; bot->state = STATE_MOVE; // Set the current node bot->current_node = ACEND_FindClosestReachableNode(bot,NODE_DENSITY, NODE_ALL); bot->goal_node = bot->current_node; bot->next_node = bot->current_node; bot->next_move_time = level.time; bot->suicide_timeout = level.time + 15.0; // If we are not respawning hold off for up to three seconds before releasing into game if (!respawn) { bot->think = ACESP_HoldSpawn; //bot->nextthink = level.time + 0.1; //mxd bot->nextthink = level.time + random()*3.0f; // up to three seconds } else { if (!KillBox(bot)) { // could't spawn in? } gi.linkentity(bot); bot->think = ACEAI_Think; bot->nextthink = level.time + FRAMETIME; // send effect gi.WriteByte(svc_muzzleflash); gi.WriteShort(bot-g_edicts); gi.WriteByte(MZ_LOGIN); gi.multicast(bot->s.origin, MULTICAST_PVS); } }
void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *dest; int i; vec3_t nodeo; if (!other->client) return; dest = G_Find (NULL, FOFS(targetname), self->target); if (!dest) { gi.dprintf(DEVELOPER_MSG_GAME, "Couldn't find destination\n"); return; } if (!Bot_FindNode(self, 120, TELEPORT_NODE) && dntg->value) { //start node VectorCopy (other->s.origin, nodeo); if (!(other->client->ps.pmove.pm_flags & PMF_DUCKED)) { nodeo[2] += 5; Bot_PlaceNode(nodeo, TELEPORT_NODE, 0); } else Bot_PlaceNode(nodeo, TELEPORT_NODE, 1); Bot_CalcNode(other, numnodes); //dest node VectorCopy (dest->s.origin, nodeo); nodeo[2] += 20; Bot_PlaceNode(nodeo, NORMAL_NODE, 0); Bot_CalcNode(other, numnodes); //connection nodes[numnodes-1].dist[numnodes] = 1; nprintf(PRINT_HIGH, "Teleporter nodes placed and connected!\n"); } // unlink to make sure it can't possibly interfere with KillBox gi.unlinkentity (other); VectorCopy (dest->s.origin, other->s.origin); VectorCopy (dest->s.origin, other->s.old_origin); other->s.origin[2] += 10; // clear the velocity and hold them in place briefly VectorClear (other->velocity); other->client->ps.pmove.pm_time = 160>>3; // hold time other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; // draw the teleport splash at source and on the player self->owner->s.event = EV_PLAYER_TELEPORT; other->s.event = EV_PLAYER_TELEPORT; // set angles for (i=0 ; i<3 ; i++) other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); VectorClear (other->s.angles); VectorClear (other->client->ps.viewangles); VectorClear (other->client->v_angle); // kill anything at the destination KillBox (other); gi.linkentity (other); }
/* =========== PutClientInServer Called when a player connects to a server or respawns in a deathmatch. ============ */ void PutClientInServer (edict_t *ent) { vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; int index; vec3_t spawn_origin, spawn_angles; gclient_t *client; int i; client_persistant_t saved; client_respawn_t resp; // find a spawn point // do it before setting health back up, so farthest // ranging doesn't count this client SelectSpawnPoint (ent, spawn_origin, spawn_angles); index = ent-g_edicts-1; client = ent->client; // deathmatch wipes most client data every spawn if (deathmatch->value) { char userinfo[MAX_INFO_STRING]; resp = client->resp; memcpy (userinfo, client->pers.userinfo, sizeof(userinfo)); InitClientPersistant (client); ClientUserinfoChanged (ent, userinfo); } else if (coop->value) { int n; char userinfo[MAX_INFO_STRING]; resp = client->resp; memcpy (userinfo, client->pers.userinfo, sizeof(userinfo)); // this is kind of ugly, but it's how we want to handle keys in coop for (n = 0; n < MAX_ITEMS; n++) { if (itemlist[n].flags & IT_KEY) resp.coop_respawn.inventory[n] = client->pers.inventory[n]; } client->pers = resp.coop_respawn; ClientUserinfoChanged (ent, userinfo); if (resp.score > client->pers.score) client->pers.score = resp.score; } else { memset (&resp, 0, sizeof(resp)); } // clear everything but the persistant data saved = client->pers; memset (client, 0, sizeof(*client)); client->pers = saved; if (client->pers.health <= 0) InitClientPersistant(client); else if (Q_stricmp(level.mapname, "zboss") == 0) { char userinfo[MAX_INFO_STRING]; int health = client->pers.health; memcpy (userinfo, client->pers.userinfo, sizeof(userinfo)); InitClientPersistant(client); ClientUserinfoChanged (ent, userinfo); client->pers.health = health; } client->resp = resp; // copy some data from the client to the entity FetchClientEntData (ent); // clear entity values ent->groundentity = NULL; ent->client = &game.clients[index]; ent->takedamage = DAMAGE_AIM; ent->movetype = MOVETYPE_WALK; ent->viewheight = 22; ent->inuse = true; ent->classname = "player"; ent->mass = 200; ent->solid = SOLID_BBOX; ent->deadflag = DEAD_NO; ent->air_finished = level.time + 12; ent->clipmask = MASK_PLAYERSOLID; ent->model = "players/male/tris.md2"; ent->pain = player_pain; ent->die = player_die; ent->waterlevel = 0; ent->watertype = 0; ent->flags &= ~FL_NO_KNOCKBACK; ent->svflags &= ~SVF_DEADMONSTER; #ifdef WITH_ACEBOT // ACEBOT_ADD ent->is_bot = false; ent->last_node = -1; ent->is_jumping = false; // ACEBOT_END #endif VectorCopy (mins, ent->mins); VectorCopy (maxs, ent->maxs); VectorClear (ent->velocity); // clear playerstate values memset (&ent->client->ps, 0, sizeof(client->ps)); client->ps.pmove.origin[0] = spawn_origin[0]*8; client->ps.pmove.origin[1] = spawn_origin[1]*8; client->ps.pmove.origin[2] = spawn_origin[2]*8; if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV)) { client->ps.fov = 90; } else { client->ps.fov = atoi(Info_ValueForKey(client->pers.userinfo, "fov")); if (client->ps.fov < 1) client->ps.fov = 90; else if (client->ps.fov > 160) client->ps.fov = 160; } client->ps.gunindex = gi.modelindex(client->pers.weapon->view_model); // clear entity state values ent->s.effects = 0; ent->s.skinnum = ent - g_edicts - 1; ent->s.modelindex = 255; // will use the skin specified model ent->s.modelindex2 = 255; // custom gun model ent->s.frame = 0; #ifdef WITH_ACEBOT //botchat> ent->last_insult = level.time; ent->last_taunt = level.time; ent->last_chat = level.time; //<botchat #endif VectorCopy (spawn_origin, ent->s.origin); ent->s.origin[2] += 1; // make sure off ground VectorCopy (ent->s.origin, ent->s.old_origin); // set the delta angle for (i=0 ; i<3 ; i++) client->ps.pmove.delta_angles[i] = ANGLE2SHORT(spawn_angles[i] - client->resp.cmd_angles[i]); ent->s.angles[PITCH] = 0; ent->s.angles[YAW] = spawn_angles[YAW]; ent->s.angles[ROLL] = 0; VectorCopy (ent->s.angles, client->ps.viewangles); VectorCopy (ent->s.angles, client->v_angle); if (!KillBox (ent)) { // could't spawn in? } gi.linkentity (ent); // force the current weapon up client->newweapon = client->pers.weapon; ChangeWeapon (ent); }
void M_default_Spawn (void) { edict_t *ent; vec3_t spawn_origin, spawn_angles;//spawn at a spawnpoint vec3_t mins = {-15, -15, -24}; vec3_t maxs = {15, 15, 32}; ent = G_Spawn(); G_SpawnAI (ent); //jabot092(2) //spawn at a spawnpoint SelectSpawnPoint (ent, spawn_origin, spawn_angles); spawn_origin[2] += 8; //------------------------------------------------- // clear entity values ent->groundentity = NULL; ent->takedamage = DAMAGE_AIM; ent->movetype = MOVETYPE_WALK; ent->viewheight = 22; ent->inuse = true; ent->classname = "monster"; ent->mass = 200; ent->solid = SOLID_BBOX; ent->deadflag = DEAD_NO; ent->air_finished = level.time + 12; ent->clipmask = MASK_MONSTERSOLID; //ent->model = "models/monsters/infantry/tris.md2";//jalfixme ent->waterlevel = 0; ent->watertype = 0; ent->flags &= ~FL_NO_KNOCKBACK; ent->pain = M_default_pain; ent->die = M_default_die; VectorCopy (mins, ent->mins); VectorCopy (maxs, ent->maxs); VectorClear (ent->velocity); ent->s.modelindex = gi.modelindex("models/monsters/infantry/tris.md2"); // clear entity state values ent->s.effects = 0; ent->s.frame = 0; VectorCopy (spawn_origin, ent->s.origin); VectorCopy (ent->s.origin, ent->s.old_origin); ent->s.angles[PITCH] = 0; ent->s.angles[YAW] = spawn_angles[YAW]; ent->s.angles[ROLL] = 0; if (!KillBox (ent)) { // could't spawn in? } gi.linkentity (ent); //finish M_default_Start(ent); }
static void old_teleporter_touch( edict_t *self, edict_t *other, cplane_t *plane, int surfFlags ) { edict_t *dest; int i; vec3_t velocity, angles; mat3_t axis; float speed; vec3_t org; if( !other->r.client ) return; if( self->s.team && self->s.team != other->s.team ) return; if( other->r.client->ps.pmove.pm_type > PM_SPECTATOR ) return; if( self->spawnflags & 1 && other->r.client->ps.pmove.pm_type != PM_SPECTATOR ) return; // match countdown if( GS_MatchState() == MATCH_STATE_COUNTDOWN ) return; // wait delay if( self->timeStamp > level.time ) return; self->timeStamp = level.time + ( self->wait * 1000 ); dest = G_Find( NULL, FOFS( targetname ), self->target ); if( !dest ) { if( developer->integer ) G_Printf( "Couldn't find destination.\n" ); return; } if( self->s.modelindex ) { org[0] = self->s.origin[0] + 0.5 * ( self->r.mins[0] + self->r.maxs[0] ); org[1] = self->s.origin[1] + 0.5 * ( self->r.mins[1] + self->r.maxs[1] ); org[2] = self->s.origin[2] + 0.5 * ( self->r.mins[2] + self->r.maxs[2] ); } else VectorCopy( self->s.origin, org ); // play custom sound if any (played from the teleporter entrance) if( self->noise_index ) G_PositionedSound( org, CHAN_AUTO, self->noise_index, ATTN_NORM ); // draw the teleport entering effect G_TeleportEffect( other, false ); // // teleport the player // VectorCopy( other->r.client->ps.pmove.velocity, velocity ); velocity[2] = 0; // ignore vertical velocity speed = VectorLengthFast( velocity ); // if someone enters a portal backwards, inverse the destination YAW angle #if 0 VectorCopy( other->s.angles, angles ); angles[PITCH] = 0; AngleVectors( angles, axis[0], NULL, NULL ); VectorSubtract( org, other->s.origin, org ); VectorCopy( dest->s.angles, angles ); if( DotProduct( org, axis[0] ) < 0 ) angles[YAW] = anglemod( angles[YAW] - 180 ); #else VectorCopy( dest->s.angles, angles ); #endif AnglesToAxis( dest->s.angles, axis ); VectorScale( &axis[AXIS_FORWARD], speed, other->r.client->ps.pmove.velocity ); VectorCopy( angles, other->r.client->ps.viewangles ); VectorCopy( dest->s.origin, other->r.client->ps.pmove.origin ); // set the delta angle for( i = 0; i < 3; i++ ) other->r.client->ps.pmove.delta_angles[i] = ANGLE2SHORT( other->r.client->ps.viewangles[i] ) - other->r.client->ucmd.angles[i]; other->r.client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; other->s.teleported = qtrue; other->r.client->ps.pmove.pm_time = 1; // force the minimum no control delay // update the entity from the pmove VectorCopy( other->r.client->ps.viewangles, other->s.angles ); VectorCopy( other->r.client->ps.pmove.origin, other->s.origin ); VectorCopy( other->r.client->ps.pmove.origin, other->s.old_origin ); VectorCopy( other->r.client->ps.pmove.origin, other->olds.origin ); VectorCopy( other->r.client->ps.pmove.velocity, other->velocity ); // unlink to make sure it can't possibly interfere with KillBox GClip_UnlinkEntity( other ); // kill anything at the destination if( !KillBox( other ) ) { } GClip_LinkEntity( other ); // add the teleport effect at the destination G_TeleportEffect( other, true ); }
/* * Called when a player connects to * a server or respawns in a deathmatch. */ void PutClientInServer(edict_t *ent) { char userinfo[MAX_INFO_STRING]; if (!ent) { return; } vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; int index; vec3_t spawn_origin, spawn_angles; gclient_t *client; int i; client_persistant_t saved; client_respawn_t resp; /* find a spawn point do it before setting health back up, so farthest ranging doesn't count this client */ SelectSpawnPoint(ent, spawn_origin, spawn_angles); index = ent - g_edicts - 1; client = ent->client; /* deathmatch wipes most client data every spawn */ if (deathmatch->value) { resp = client->resp; memcpy(userinfo, client->pers.userinfo, sizeof(userinfo)); InitClientPersistant(client); ClientUserinfoChanged(ent, userinfo); } else if (coop->value) { resp = client->resp; memcpy(userinfo, client->pers.userinfo, sizeof(userinfo)); resp.coop_respawn.game_helpchanged = client->pers.game_helpchanged; resp.coop_respawn.helpchanged = client->pers.helpchanged; client->pers = resp.coop_respawn; ClientUserinfoChanged(ent, userinfo); if (resp.score > client->pers.score) { client->pers.score = resp.score; } } else { memset(&resp, 0, sizeof(resp)); } memcpy(userinfo, client->pers.userinfo, sizeof(userinfo)); ClientUserinfoChanged(ent, userinfo); /* clear everything but the persistant data */ saved = client->pers; memset(client, 0, sizeof(*client)); client->pers = saved; if (client->pers.health <= 0) { InitClientPersistant(client); } client->resp = resp; /* copy some data from the client to the entity */ FetchClientEntData(ent); /* clear entity values */ ent->groundentity = NULL; ent->client = &game.clients[index]; ent->takedamage = DAMAGE_AIM; ent->movetype = MOVETYPE_WALK; ent->viewheight = 22; ent->inuse = true; ent->classname = "player"; ent->mass = 200; ent->solid = SOLID_BBOX; ent->deadflag = DEAD_NO; ent->air_finished = level.time + 12; ent->clipmask = MASK_PLAYERSOLID; ent->model = "players/male/tris.md2"; ent->pain = player_pain; ent->die = player_die; ent->waterlevel = 0; ent->watertype = 0; ent->flags &= ~FL_NO_KNOCKBACK; ent->svflags = 0; VectorCopy(mins, ent->mins); VectorCopy(maxs, ent->maxs); VectorClear(ent->velocity); /* clear playerstate values */ memset(&ent->client->ps, 0, sizeof(client->ps)); client->ps.pmove.origin[0] = spawn_origin[0] * 8; client->ps.pmove.origin[1] = spawn_origin[1] * 8; client->ps.pmove.origin[2] = spawn_origin[2] * 8; if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV)) { client->ps.fov = 90; } else { client->ps.fov = (int)strtol(Info_ValueForKey(client->pers.userinfo, "fov"), (char **)NULL, 10); if (client->ps.fov < 1) { client->ps.fov = 90; } else if (client->ps.fov > 160) { client->ps.fov = 160; } } client->ps.gunindex = gi.modelindex(client->pers.weapon->view_model); /* clear entity state values */ ent->s.effects = 0; ent->s.modelindex = 255; /* will use the skin specified model */ ent->s.modelindex2 = 255; /* custom gun model */ /* sknum is player num and weapon number weapon number will be added in changeweapon */ ent->s.skinnum = ent - g_edicts - 1; ent->s.frame = 0; VectorCopy(spawn_origin, ent->s.origin); ent->s.origin[2] += 1; /* make sure off ground */ VectorCopy(ent->s.origin, ent->s.old_origin); /* set the delta angle */ for (i = 0; i < 3; i++) { client->ps.pmove.delta_angles[i] = ANGLE2SHORT( spawn_angles[i] - client->resp.cmd_angles[i]); } ent->s.angles[PITCH] = 0; ent->s.angles[YAW] = spawn_angles[YAW]; ent->s.angles[ROLL] = 0; VectorCopy(ent->s.angles, client->ps.viewangles); VectorCopy(ent->s.angles, client->v_angle); /* spawn a spectator */ if (client->pers.spectator) { client->chase_target = NULL; client->resp.spectator = true; ent->movetype = MOVETYPE_NOCLIP; ent->solid = SOLID_NOT; ent->svflags |= SVF_NOCLIENT; ent->client->ps.gunindex = 0; gi.linkentity(ent); return; } else { client->resp.spectator = false; } if (!KillBox(ent)) { /* could't spawn in? */ } gi.linkentity(ent); /* force the current weapon up */ client->newweapon = client->pers.weapon; ChangeWeapon(ent); }
/*QUAKED func_killbox (1 0 0) ? Kills everything inside when fired, irrespective of protection. */ void use_killbox (edict_t *self, edict_t *other, edict_t *activator) { KillBox (self); }
/* * G_ClientRespawn */ void G_ClientRespawn( edict_t *self, bool ghost ) { int i; edict_t *spawnpoint; vec3_t hull_mins, hull_maxs; vec3_t spawn_origin, spawn_angles; gclient_t *client; int old_team; G_DeathAwards( self ); G_SpawnQueue_RemoveClient( self ); self->r.svflags &= ~SVF_NOCLIENT; //if invalid be spectator if( self->r.client->team < 0 || self->r.client->team >= GS_MAX_TEAMS ) self->r.client->team = TEAM_SPECTATOR; // force ghost always to true when in spectator team if( self->r.client->team == TEAM_SPECTATOR ) ghost = true; old_team = self->s.team; if( self->r.client->teamstate.is_coach ) ghost = true; GClip_UnlinkEntity( self ); client = self->r.client; memset( &client->resp, 0, sizeof( client->resp ) ); memset( &client->ps, 0, sizeof( client->ps ) ); client->resp.timeStamp = level.time; client->ps.playerNum = PLAYERNUM( self ); // clear entity values memset( &self->snap, 0, sizeof( self->snap ) ); memset( &self->s, 0, sizeof( self->s ) ); memset( &self->olds, 0, sizeof( self->olds ) ); memset( &self->invpak, 0, sizeof( self->invpak ) ); self->s.number = self->olds.number = ENTNUM( self ); // relink client struct self->r.client = &game.clients[PLAYERNUM( self )]; // update team self->s.team = client->team; self->deadflag = DEAD_NO; self->s.type = ET_PLAYER; self->groundentity = NULL; self->takedamage = DAMAGE_AIM; self->think = player_think; self->pain = player_pain; self->die = player_die; self->viewheight = playerbox_stand_viewheight; self->r.inuse = true; self->mass = PLAYER_MASS; self->air_finished = level.time + ( 12 * 1000 ); self->r.clipmask = MASK_PLAYERSOLID; self->waterlevel = 0; self->watertype = 0; self->flags &= ~FL_NO_KNOCKBACK; self->r.svflags &= ~SVF_CORPSE; self->enemy = NULL; self->r.owner = NULL; self->max_health = 100; self->health = self->max_health; if( AI_GetType( self->ai ) == AI_ISBOT ) { self->think = NULL; self->classname = "bot"; } else if( self->r.svflags & SVF_FAKECLIENT ) self->classname = "fakeclient"; else self->classname = "player"; VectorCopy( playerbox_stand_mins, self->r.mins ); VectorCopy( playerbox_stand_maxs, self->r.maxs ); VectorClear( self->velocity ); VectorClear( self->avelocity ); VectorCopy( self->r.mins, hull_mins ); VectorCopy( self->r.maxs, hull_maxs ); trap_CM_RoundUpToHullSize( hull_mins, hull_maxs, NULL ); if( self->r.maxs[2] > hull_maxs[2] ) self->viewheight -= (self->r.maxs[2] - hull_maxs[2]); client->ps.POVnum = ENTNUM( self ); // set movement info client->ps.pmove.stats[PM_STAT_MAXSPEED] = (short)DEFAULT_PLAYERSPEED; client->ps.pmove.stats[PM_STAT_JUMPSPEED] = (short)DEFAULT_JUMPSPEED; client->ps.pmove.stats[PM_STAT_DASHSPEED] = (short)DEFAULT_DASHSPEED; if( ghost ) { self->r.solid = SOLID_NOT; self->movetype = MOVETYPE_NOCLIP; if( self->s.team == TEAM_SPECTATOR ) self->r.svflags |= SVF_NOCLIENT; } else { self->r.client->resp.takeStun = true; self->r.solid = SOLID_YES; self->movetype = MOVETYPE_PLAYER; client->ps.pmove.stats[PM_STAT_FEATURES] = static_cast<unsigned short>(PMFEAT_DEFAULT); if( !g_allow_bunny->integer ) client->ps.pmove.stats[PM_STAT_FEATURES] &= ~( PMFEAT_AIRCONTROL|PMFEAT_FWDBUNNY ); } ClientUserinfoChanged( self, client->userinfo ); if( old_team != self->s.team ) G_Teams_UpdateMembersList(); SelectSpawnPoint( self, &spawnpoint, spawn_origin, spawn_angles ); VectorCopy( spawn_origin, client->ps.pmove.origin ); VectorCopy( spawn_origin, self->s.origin ); VectorCopy( self->s.origin, self->s.old_origin ); // set angles self->s.angles[PITCH] = 0; self->s.angles[YAW] = anglemod( spawn_angles[YAW] ); self->s.angles[ROLL] = 0; VectorCopy( self->s.angles, client->ps.viewangles ); // set the delta angle for( i = 0; i < 3; i++ ) client->ps.pmove.delta_angles[i] = ANGLE2SHORT( client->ps.viewangles[i] ) - client->ucmd.angles[i]; // don't put spectators in the game if( !ghost ) { if( KillBox( self ) ) { } } self->s.attenuation = ATTN_NORM; self->s.teleported = true; // hold in place briefly client->ps.pmove.pm_flags = PMF_TIME_TELEPORT; client->ps.pmove.pm_time = 14; client->ps.pmove.stats[PM_STAT_NOUSERCONTROL] = CLIENT_RESPAWN_FREEZE_DELAY; client->ps.pmove.stats[PM_STAT_NOAUTOATTACK] = 1000; // set race stats to invisible client->ps.stats[STAT_TIME_SELF] = STAT_NOTSET; client->ps.stats[STAT_TIME_BEST] = STAT_NOTSET; client->ps.stats[STAT_TIME_RECORD] = STAT_NOTSET; client->ps.stats[STAT_TIME_ALPHA] = STAT_NOTSET; client->ps.stats[STAT_TIME_BETA] = STAT_NOTSET; BOT_Respawn( self ); self->r.client->level.respawnCount++; G_UseTargets( spawnpoint, self ); GClip_LinkEntity( self ); // let the gametypes perform their changes if( game.asEngine != NULL ) GT_asCallPlayerRespawn( self, old_team, self->s.team ); else G_Gametype_GENERIC_ClientRespawn( self, old_team, self->s.team ); }