Quake 2 Oop Conversion Project - Source Diff 3.05 vs 3.14 - p_client.c
diff -s -r q2_305/p_client.c q2_314/p_client.c
Left File < - 3.05/p_client.c
Right File > - 3.14/p_client.c
Back to Index
7a8,85
> //
> // Gross, ugly, disgustuing hack section
> //
>
> // this function is an ugly as hell hack to fix some map flaws
> //
> // the coop spawn spots on some maps are SNAFU. There are coop spots
> // with the wrong targetname as well as spots with no name at all
> //
> // we use carnal knowledge of the maps to fix the coop spot targetnames to match
> // that of the nearest named single player spot
>
> static void SP_FixCoopSpots (edict_t *self)
> {
> edict_t *spot;
> vec3_t d;
>
> spot = NULL;
>
> while(1)
> {
> spot = G_Find(spot, FOFS(classname), "info_player_start");
> if (!spot)
> return;
> if (!spot->targetname)
> continue;
> VectorSubtract(self->s.origin, spot->s.origin, d);
> if (VectorLength(d) < 384)
> {
> if ((!self->targetname) || stricmp(self->targetname, spot->targetname) != 0)
> {
> // gi.dprintf("FixCoopSpots changed %s at %s targetname from %s to %s\n", self->classname, vtos(self->s.origin), self->targetname, spot->targetname);
> self->targetname = spot->targetname;
> }
> return;
> }
> }
> }
>
> // now if that one wasn't ugly enough for you then try this one on for size
> // some maps don't have any coop spots at all, so we need to create them
> // where they should have been
>
> static void SP_CreateCoopSpots (edict_t *self)
> {
> edict_t *spot;
>
> if(stricmp(level.mapname, "security") == 0)
> {
> spot = G_Spawn();
> spot->classname = "info_player_coop";
> spot->s.origin[0] = 188 - 64;
> spot->s.origin[1] = -164;
> spot->s.origin[2] = 80;
> spot->targetname = "jail3";
> spot->s.angles[1] = 90;
>
> spot = G_Spawn();
> spot->classname = "info_player_coop";
> spot->s.origin[0] = 188 + 64;
> spot->s.origin[1] = -164;
> spot->s.origin[2] = 80;
> spot->targetname = "jail3";
> spot->s.angles[1] = 90;
>
> spot = G_Spawn();
> spot->classname = "info_player_coop";
> spot->s.origin[0] = 188 + 128;
> spot->s.origin[1] = -164;
> spot->s.origin[2] = 80;
> spot->targetname = "jail3";
> spot->s.angles[1] = 90;
>
> return;
> }
> }
>
>
11c89
< void SP_info_player_start(void)
---
> void SP_info_player_start(edict_t *self)
12a91,98
> if (!coop->value)
> return;
> if(stricmp(level.mapname, "security") == 0)
> {
> // invoke one of our gross, ugly, disgusting hacks
> self->think = SP_CreateCoopSpots;
> self->nextthink = level.time + FRAMETIME;
> }
30a117
>
33c120
< if ( 1) //!coop->value)
---
> if (!coop->value)
38c125,144
< // SP_misc_teleporter_dest (self);
---
>
> if((stricmp(level.mapname, "jail2") == 0) ||
> (stricmp(level.mapname, "jail4") == 0) ||
> (stricmp(level.mapname, "mine1") == 0) ||
> (stricmp(level.mapname, "mine2") == 0) ||
> (stricmp(level.mapname, "mine3") == 0) ||
> (stricmp(level.mapname, "mine4") == 0) ||
> (stricmp(level.mapname, "lab") == 0) ||
> (stricmp(level.mapname, "boss1") == 0) ||
> (stricmp(level.mapname, "fact3") == 0) ||
> (stricmp(level.mapname, "biggun") == 0) ||
> (stricmp(level.mapname, "space") == 0) ||
> (stricmp(level.mapname, "command") == 0) ||
> (stricmp(level.mapname, "power2") == 0) ||
> (stricmp(level.mapname, "strike") == 0))
> {
> // invoke one of our gross, ugly, disgusting hacks
> self->think = SP_FixCoopSpots;
> self->nextthink = level.time + FRAMETIME;
> }
51,60d156
<
< int SexedSoundIndex (edict_t *ent, char *base)
< {
< char buffer[MAX_QPATH];
<
< Com_sprintf (buffer, sizeof(buffer), "%s/%s.wav", ent->client->pers.sounddir, base);
<
< return gi.soundindex(buffer);
< }
<
69a166,179
> qboolean IsFemale (edict_t *ent)
> {
> char *info;
>
> if (!ent->client)
> return false;
>
> info = Info_ValueForKey (ent->client->pers.userinfo, "skin");
> if (info[0] == 'f' || info[0] == 'F')
> return true;
> return false;
> }
>
>
72,78c182,195
< if (attacker == self)
< {
< gi.bprintf (PRINT_MEDIUM,"%s killed self.\n", self->client->pers.netname);
< self->client->resp.score--;
< self->enemy = NULL;
< return;
< }
---
> int mod;
> char *message;
> char *message2;
> qboolean ff;
>
> if (coop->value && attacker->client)
> meansOfDeath |= MOD_FRIENDLY_FIRE;
>
> if (deathmatch->value || coop->value)
> {
> ff = meansOfDeath & MOD_FRIENDLY_FIRE;
> mod = meansOfDeath & ~MOD_FRIENDLY_FIRE;
> message = NULL;
> message2 = "";
80,85c197,362
< self->enemy = attacker;
< if (attacker && attacker->client)
< {
< gi.bprintf (PRINT_MEDIUM,"%s was killed by %s\n", self->client->pers.netname, attacker->client->pers.netname);
< attacker->client->resp.score++;
< return;
---
> switch (mod)
> {
> case MOD_SUICIDE:
> message = "suicides";
> break;
> case MOD_FALLING:
> message = "cratered";
> break;
> case MOD_CRUSH:
> message = "was squished";
> break;
> case MOD_WATER:
> message = "sank like a rock";
> break;
> case MOD_SLIME:
> message = "melted";
> break;
> case MOD_LAVA:
> message = "does a back flip into the lava";
> break;
> case MOD_EXPLOSIVE:
> case MOD_BARREL:
> message = "blew up";
> break;
> case MOD_EXIT:
> message = "found a way out";
> break;
> case MOD_TARGET_LASER:
> message = "saw the light";
> break;
> case MOD_TARGET_BLASTER:
> message = "got blasted";
> break;
> case MOD_BOMB:
> case MOD_SPLASH:
> case MOD_TRIGGER_HURT:
> message = "was in the wrong place";
> break;
> }
> if (attacker == self)
> {
> switch (mod)
> {
> case MOD_HELD_GRENADE:
> message = "tried to put the pin back in";
> break;
> case MOD_HG_SPLASH:
> case MOD_G_SPLASH:
> if (IsFemale(self))
> message = "tripped on her own grenade";
> else
> message = "tripped on his own grenade";
> break;
> case MOD_R_SPLASH:
> if (IsFemale(self))
> message = "blew herself up";
> else
> message = "blew himself up";
> break;
> case MOD_BFG_BLAST:
> message = "should have used a smaller gun";
> break;
> default:
> if (IsFemale(self))
> message = "killed herself";
> else
> message = "killed himself";
> break;
> }
> }
> if (message)
> {
> gi.bprintf (PRINT_MEDIUM, "%s %s.\n", self->client->pers.netname, message);
> if (deathmatch->value)
> self->client->resp.score--;
> self->enemy = NULL;
> return;
> }
>
> self->enemy = attacker;
> if (attacker && attacker->client)
> {
> switch (mod)
> {
> case MOD_BLASTER:
> message = "was blasted by";
> break;
> case MOD_SHOTGUN:
> message = "was gunned down by";
> break;
> case MOD_SSHOTGUN:
> message = "was blown away by";
> message2 = "'s super shotgun";
> break;
> case MOD_MACHINEGUN:
> message = "was machinegunned by";
> break;
> case MOD_CHAINGUN:
> message = "was cut in half by";
> message2 = "'s chaingun";
> break;
> case MOD_GRENADE:
> message = "was popped by";
> message2 = "'s grenade";
> break;
> case MOD_G_SPLASH:
> message = "was shredded by";
> message2 = "'s shrapnel";
> break;
> case MOD_ROCKET:
> message = "ate";
> message2 = "'s rocket";
> break;
> case MOD_R_SPLASH:
> message = "almost dodged";
> message2 = "'s rocket";
> break;
> case MOD_HYPERBLASTER:
> message = "was melted by";
> message2 = "'s hyperblaster";
> break;
> case MOD_RAILGUN:
> message = "was railed by";
> break;
> case MOD_BFG_LASER:
> message = "saw the pretty lights from";
> message2 = "'s BFG";
> break;
> case MOD_BFG_BLAST:
> message = "was disintegrated by";
> message2 = "'s BFG blast";
> break;
> case MOD_BFG_EFFECT:
> message = "couldn't hide from";
> message2 = "'s BFG";
> break;
> case MOD_HANDGRENADE:
> message = "caught";
> message2 = "'s handgrenade";
> break;
> case MOD_HG_SPLASH:
> message = "didn't see";
> message2 = "'s handgrenade";
> break;
> case MOD_HELD_GRENADE:
> message = "feels";
> message2 = "'s pain";
> break;
> case MOD_TELEFRAG:
> message = "tried to invade";
> message2 = "'s personal space";
> break;
> }
> if (message)
> {
> gi.bprintf (PRINT_MEDIUM,"%s %s %s%s\n", self->client->pers.netname, message, attacker->client->pers.netname, message2);
> if (deathmatch->value)
> {
> if (ff)
> attacker->client->resp.score--;
> else
> attacker->client->resp.score++;
> }
> return;
> }
> }
89c366,367
< self->client->resp.score--;
---
> if (deathmatch->value)
> self->client->resp.score--;
91a370,372
>
> void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
>
95a377,378
> qboolean quad;
> float spread;
98a382
>
100,101d383
< if (!item)
< return;
103,108c385,417
< return;
< if (!strcmp (item->pickup_name, "Blaster"))
< return;
< drop = Drop_Item (self, item);
< // let them have some ammo with it
< drop->spawnflags = DROPPED_PLAYER_ITEM;
---
> item = NULL;
> if (item && (strcmp (item->pickup_name, "Blaster") == 0))
> item = NULL;
>
> if (!((int)(dmflags->value) & DF_QUAD_DROP))
> quad = false;
> else
> quad = (self->client->quad_framenum > (level.framenum + 10));
>
> if (item && quad)
> spread = 22.5;
> else
> spread = 0.0;
>
> if (item)
> {
> self->client->v_angle[YAW] -= spread;
> drop = Drop_Item (self, item);
> self->client->v_angle[YAW] += spread;
> drop->spawnflags = DROPPED_PLAYER_ITEM;
> }
>
> if (quad)
> {
> self->client->v_angle[YAW] += spread;
> drop = Drop_Item (self, FindItemByClassname ("item_quad"));
> self->client->v_angle[YAW] -= spread;
> drop->spawnflags |= DROPPED_PLAYER_ITEM;
>
> drop->touch = Touch_Item;
> drop->nextthink = level.time + (self->client->quad_framenum - level.framenum) * FRAMETIME;
> drop->think = G_FreeEdict;
> }
110a420
>
144d453
< char sound[MAX_QPATH];
162c471,472
< self->solid = SOLID_NOT;
---
> // self->solid = SOLID_NOT;
> self->svflags |= SVF_DEADMONSTER;
173d482
< memset (self->client->pers.inventory, 0, sizeof(self->client->pers.inventory));
175a485,493
> // remove powerups
> self->client->quad_framenum = 0;
> self->client->invincible_framenum = 0;
> self->client->breather_framenum = 0;
> self->client->enviro_framenum = 0;
>
> // clear inventory
> memset(self->client->pers.inventory, 0, sizeof(self->client->pers.inventory));
>
214,215c532
< Com_sprintf(sound, sizeof(sound), "death%i", (rand()%4)+1);
< gi.sound (self, CHAN_VOICE, SexedSoundIndex(self,sound), 1, ATTN_NORM, 0);
---
> gi.sound (self, CHAN_VOICE, gi.soundindex(va("*death%i.wav", (rand()%4)+1)), 1, ATTN_NORM, 0);
219,220d535
< // FIXME once we have death frames
< // self->deadflag = DEAD_DYING;
256a572,573
>
> client->pers.connected = true;
263a581
> client->resp.coop_respawn = client->pers;
287a606,608
> game.clients[i].pers.powerArmorActive = (ent->flags & FL_POWER_ARMOR);
> if (coop->value)
> game.clients[i].pers.score = ent->client->resp.score;
294a616,619
> if (ent->client->pers.powerArmorActive)
> ent->flags |= FL_POWER_ARMOR;
> if (coop->value)
> ent->client->resp.score = ent->client->pers.score;
451c776
< edict_t *SelectCoopSpawnPoint (void)
---
> edict_t *SelectCoopSpawnPoint (edict_t *ent)
452a778
> int index;
453a780
> char *target;
455,458c782
< while ((spot = G_Find (spot, FOFS(classname), "info_player_coop")) != NULL)
< {
< if (!game.spawnpoint[0] && !spot->targetname)
< break;
---
> index = ent->client - game.clients;
460,461c784,786
< if (!game.spawnpoint[0] || !spot->targetname)
< continue;
---
> // player 0 starts in normal player spawn point
> if (!index)
> return NULL;
463,464c788,805
< if (Q_stricmp(game.spawnpoint, spot->targetname) == 0)
< break;
---
> spot = NULL;
>
> // assume there are four coop spots at each spawnpoint
> while (1)
> {
> spot = G_Find (spot, FOFS(classname), "info_player_coop");
> if (!spot)
> return NULL; // we didn't have enough...
>
> target = spot->targetname;
> if (!target)
> target = "";
> if ( Q_stricmp(game.spawnpoint, target) == 0 )
> { // this is a coop spawn point for one of the clients here
> index--;
> if (!index)
> return spot; // this is it
> }
465a807,808
>
>
477c820
< void SelectSpawnPoint (vec3_t origin, vec3_t angles)
---
> void SelectSpawnPoint (edict_t *ent, vec3_t origin, vec3_t angles)
483d825
< #if 0
485,486c827
< spot = SelectCoopSpawnPoint ();
< #endif
---
> spot = SelectCoopSpawnPoint (ent);
525,529c866
< edict_t *ent, *head;
<
< head = G_Spawn();
< head->chain = head;
< level.body_que = head;
---
> edict_t *ent;
531c868,869
< for (i=0 ; i<7 ; i++)
---
> level.body_que = 0;
> for (i=0; i<BODY_QUEUE_SIZE ; i++)
534,535c872,887
< ent->chain = head->chain;
< head->chain = ent;
---
> ent->classname = "bodyque";
> }
> }
>
> void body_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
> {
> int n;
>
> if (self->health < -40)
> {
> gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
> for (n= 0; n < 4; n++)
> ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC);
> self->s.origin[2] -= 48;
> ThrowClientHead (self, damage);
> self->takedamage = DAMAGE_NO;
544,545c896,897
< body = level.body_que;
< level.body_que = body->chain;
---
> body = &g_edicts[(int)maxclients->value + level.body_que + 1];
> level.body_que = (level.body_que + 1) % BODY_QUEUE_SIZE;
555c907,920
< // FIXME: make fall to ground?
---
> body->svflags = ent->svflags;
> VectorCopy (ent->mins, body->mins);
> VectorCopy (ent->maxs, body->maxs);
> VectorCopy (ent->absmin, body->absmin);
> VectorCopy (ent->absmax, body->absmax);
> VectorCopy (ent->size, body->size);
> body->solid = ent->solid;
> body->clipmask = ent->clipmask;
> body->owner = ent->owner;
> body->movetype = ent->movetype;
>
> body->die = body_die;
> body->takedamage = DAMAGE_YES;
>
562c927
< if (deathmatch->value /*|| coop->value */)
---
> if (deathmatch->value || coop->value)
564d928
< // FIXME: make bodyque objects obey gravity
572c936,940
< self->client->ps.pmove.teleport_time = 50;
---
> self->client->ps.pmove.pm_flags = PMF_TIME_TELEPORT;
> self->client->ps.pmove.pm_time = 14;
>
> self->client->respawn_time = level.time;
>
605c973
< SelectSpawnPoint (spawn_origin, spawn_angles);
---
> SelectSpawnPoint (ent, spawn_origin, spawn_angles);
615c983
< resp = ent->client->resp;
---
> resp = client->resp;
619a988,1005
> 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;
> }
620a1007
> {
621a1009
> }
626a1015,1016
> if (client->pers.health <= 0)
> InitClientPersistant(client);
650a1041
> ent->svflags &= ~SVF_DEADMONSTER;
663c1054,1066
< client->ps.fov = 90;
---
> 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;
> }
>
673a1077
> VectorCopy (ent->s.origin, ent->s.old_origin);
734c1138
< void ClientBegin (edict_t *ent, qboolean loadgame)
---
> void ClientBegin (edict_t *ent)
737a1142,1143
> ent->client = game.clients + (ent - g_edicts - 1);
>
744c1150,1152
< if (loadgame && ent->classname && !strcmp(ent->classname, "player") )
---
> // if there is already a body waiting for us (a loadgame), just
> // take it, otherwise spawn one from scratch
> if (ent->inuse == true)
746,750d1153
< // a loadgame will just use the entity exactly as it is
< // if more clients connect than were saved, they will be
< // spawned as normal
< ent->inuse = true;
<
760a1164,1165
> // except for the persistant data that was initialized at
> // ClientConnect() time
761a1167
> ent->classname = "player";
802a1209,1214
> // check for malformed or illegal info strings
> if (!Info_Validate(userinfo))
> {
> strcpy (userinfo, "\\name\\badinfo\\skin\\male/grunt");
> }
>
810,815d1221
< // decide sound directory
< if (s[0] == 'f' || s[0] == 'F')
< strcpy (ent->client->pers.sounddir, "player/female");
< else
< strcpy (ent->client->pers.sounddir, "player/male");
<
820a1227,1240
> // fov
> if (deathmatch->value && ((int)dmflags->value & DF_FIXED_FOV))
> {
> ent->client->ps.fov = 90;
> }
> else
> {
> ent->client->ps.fov = atoi(Info_ValueForKey(userinfo, "fov"));
> if (ent->client->ps.fov < 1)
> ent->client->ps.fov = 90;
> else if (ent->client->ps.fov > 160)
> ent->client->ps.fov = 160;
> }
>
841c1261,1262
< Changing levels will NOT cause this to be called again.
---
> Changing levels will NOT cause this to be called again, but
> loadgames will.
844c1265
< qboolean ClientConnect (edict_t *ent, char *userinfo, qboolean loadgame)
---
> qboolean ClientConnect (edict_t *ent, char *userinfo)
846c1267,1282
< if (!loadgame)
---
> char *value;
>
> // check to see if they are on the banned IP list
> value = Info_ValueForKey (userinfo, "ip");
>
> // check for a password
> value = Info_ValueForKey (userinfo, "password");
> if (strcmp(password->string, value) != 0)
> return false;
>
> // they can connect
> ent->client = game.clients + (ent - g_edicts - 1);
>
> // if there is already a body waiting for us (a loadgame), just
> // take it, otherwise spawn one from scratch
> if (ent->inuse == false)
850c1286,1287
< InitClientPersistant (ent->client);
---
> if (!game.autosaved || !ent->client->pers.weapon)
> InitClientPersistant (ent->client);
858c1295
< level.players++;
---
> ent->client->pers.connected = true;
866,867c1303,1304
< called when a player drops from the server
<
---
> Called when a player drops from the server.
> Will not be called between levels.
884a1322
> gi.unlinkentity (ent);
887,888d1324
< gi.linkentity (ent);
<
890,891c1326,1327
<
< level.players--;
---
> ent->classname = "disconnected";
> ent->client->pers.connected = false;
901,902d1336
< void respawn (edict_t *self);
<
1015c1449
< gi.sound(ent, CHAN_VOICE, SexedSoundIndex(ent, "jump1"), 1, ATTN_NORM, 0);
---
> gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
1091a1526
> int buttonMask;
1109c1544,1550
< if (client->latched_buttons ||
---
> // in deathmatch, only wait for attack button
> if (deathmatch->value)
> buttonMask = BUTTON_ATTACK;
> else
> buttonMask = -1;
>
> if ( ( client->latched_buttons & buttonMask ) ||