/* ================= G_FreeEdict Marks the edict as free ================= */ void G_FreeEdict (edict_t *ed) { // Lazarus - if part of a movewith chain, remove from // the chain and repair broken links if(ed->movewith) { edict_t *e; edict_t *parent=NULL; int i; for(i=1; i<globals.num_edicts && !parent; i++) { e = g_edicts + i; if(e->movewith_next == ed) parent=e; } if(parent) parent->movewith_next = ed->movewith_next; } gi.unlinkentity (ed); // unlink from world // Lazarus: In SP we no longer reserve slots for bodyque's if (deathmatch->value || coop->value) { if ((ed - g_edicts) <= (maxclients->value + BODY_QUEUE_SIZE)) { // gi.dprintf("tried to free special edict\n"); return; } } else { if ((ed - g_edicts) <= maxclients->value) { return; } } // Lazarus: actor muzzle flash if (ed->flash) { memset (ed->flash, 0, sizeof(*ed)); ed->flash->classname = "freed"; ed->flash->freetime = level.time; ed->flash->inuse = false; } // Lazarus: reflections if (!(ed->flags & FL_REFLECT)) DeleteReflection(ed,-1); memset (ed, 0, sizeof(*ed)); ed->classname = "freed"; ed->freetime = level.time; ed->inuse = false; }
/* The ent is the owner of the chasecam */ void ChasecamStart (edict_t *ent) { /* This creates a tempory entity we can manipulate within this * function */ edict_t *chasecam; /* Don't work on a spectator! */ if (ent->client->resp.spectator) return; //Don't turn back on during intermission! if (level.intermissiontime) return; /* Tell everything that looks at the toggle that our chasecam is on * and working */ ent->client->chasetoggle = 1; /* Make our gun model "non-existent" so it's more realistic to the * player using the chasecam */ ent->client->ps.gunindex = 0; chasecam = G_Spawn (); chasecam->owner = ent; chasecam->solid = SOLID_NOT; chasecam->movetype = MOVETYPE_FLYMISSILE; ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; // this turns off Quake2's inclination to predict where the camera is going, // making a much smoother ride ent->svflags |= SVF_NOCLIENT; // this line tells Quake2 not to send the unnecessary info about the camera to other players /* Now, make the angles of the player model, (!NOT THE HUMAN VIEW!) be * copied to the same angle of the chasecam entity */ VectorCopy (ent->s.angles, chasecam->s.angles); /* Clear the size of the entity, so it DOES technically have a size, * but that of '0 0 0'-'0 0 0'. (xyz, xyz). mins = Minimum size, * maxs = Maximum size */ VectorClear (chasecam->mins); VectorClear (chasecam->maxs); /* Make the chasecam's origin (position) be the same as the player * entity's because as the camera starts, it will force itself out * slowly backwards from the player model */ VectorCopy (ent->s.origin, chasecam->s.origin); chasecam->classname = "chasecam"; chasecam->prethink = ChasecamTrack; // Lazarus: Need think??? chasecam->think = ChasecamTrack; ent->client->chasecam = chasecam; ent->client->oldplayer = G_Spawn(); CheckChasecam_Viewent(ent); //MakeFakeCrosshair(ent); // remove reflection of real player, if any DeleteReflection(ent,-1); }
void AddReflection (edict_t *ent) { gclient_t *cl; edict_t *mirror; float roll; int i, m; qboolean is_reflected; vec3_t forward; vec3_t org; for(i=0; i<6; i++) { is_reflected = false; for(m=0; m<level.num_reflectors && !is_reflected; m++) { mirror = g_mirror[m]; if(!mirror->inuse) continue; if(mirror->spawnflags & SF_REFLECT_OFF) continue; if(mirror->style != i) continue; VectorCopy(ent->s.origin,org); switch(i) { case 0: org[2] = 2*mirror->absmax[2] - ent->s.origin[2] - mirror->moveinfo.distance - 2; break; case 1: org[2] = 2*mirror->absmin[2] - ent->s.origin[2] + mirror->moveinfo.distance + 2; break; case 2: org[0] = 2*mirror->absmin[0] - ent->s.origin[0] + mirror->moveinfo.distance + 2; break; case 3: org[0] = 2*mirror->absmax[0] - ent->s.origin[0] - mirror->moveinfo.distance - 2; break; case 4: org[1] = 2*mirror->absmin[1] - ent->s.origin[1] + mirror->moveinfo.distance + 2; break; case 5: org[1] = 2*mirror->absmax[1] - ent->s.origin[1] - mirror->moveinfo.distance - 2; break; } if(org[0] < mirror->absmin[0]) continue; if(org[0] > mirror->absmax[0]) continue; if(org[1] < mirror->absmin[1]) continue; if(org[1] > mirror->absmax[1]) continue; if(org[2] < mirror->absmin[2]) continue; if(org[2] > mirror->absmax[2]) continue; is_reflected = true; } if(is_reflected) { if (!ent->reflection[i]) { ent->reflection[i] = G_Spawn(); if(ent->s.effects & EF_ROTATE) { ent->s.effects &= ~EF_ROTATE; gi.linkentity(ent); } ent->reflection[i]->movetype = MOVETYPE_NONE; ent->reflection[i]->solid = SOLID_NOT; ent->reflection[i]->classname = "reflection"; ent->reflection[i]->flags = FL_REFLECT; ent->reflection[i]->takedamage = DAMAGE_NO; } if (ent->client && !ent->reflection[i]->client) { cl = (gclient_t *)malloc(sizeof(gclient_t)); ent->reflection[i]->client = cl; } if (ent->client && ent->reflection[i]->client) { // Lazarus: Hmm.. this crashes when loading saved game. // Not sure what use pers is anyhow? // ent->reflection[i]->client->pers = ent->client->pers; ent->reflection[i]->s = ent->s; } ent->reflection[i]->s.number = ent->reflection[i] - g_edicts; ent->reflection[i]->s.modelindex = ent->s.modelindex; ent->reflection[i]->s.modelindex2 = ent->s.modelindex2; ent->reflection[i]->s.modelindex3 = ent->s.modelindex3; ent->reflection[i]->s.modelindex4 = ent->s.modelindex4; #ifdef KMQUAKE2_ENGINE_MOD ent->reflection[i]->s.modelindex5 = ent->s.modelindex5; ent->reflection[i]->s.modelindex6 = ent->s.modelindex6; ent->reflection[i]->s.modelindex7 = ent->s.modelindex7; ent->reflection[i]->s.modelindex8 = ent->s.modelindex8; ent->reflection[i]->s.alpha = ent->s.alpha; #endif ent->reflection[i]->s.skinnum = ent->s.skinnum; ent->reflection[i]->s.frame = ent->s.frame; ent->reflection[i]->s.effects = ent->s.effects; ent->reflection[i]->s.renderfx = ent->s.renderfx; ent->reflection[i]->s.renderfx &= ~RF_IR_VISIBLE; #ifdef KMQUAKE2_ENGINE_MOD // Don't flip if left handed player model // if ( !(ent->s.modelindex == (MAX_MODELS-1) && hand->value == 1) ) // ent->reflection[i]->s.renderfx |= RF_MIRRORMODEL; // Knightmare added- flip reflected models #endif VectorCopy (ent->s.angles, ent->reflection[i]->s.angles); switch(i) { case 0: case 1: ent->reflection[i]->s.angles[0]+=180; ent->reflection[i]->s.angles[1]+=180; ent->reflection[i]->s.angles[2]=360-ent->reflection[i]->s.angles[2]; break; case 2: case 3: AngleVectors(ent->reflection[i]->s.angles,forward,NULL,NULL); roll = ent->reflection[i]->s.angles[2]; forward[0] = -forward[0]; vectoangles(forward,ent->reflection[i]->s.angles); ent->reflection[i]->s.angles[2] = 360-roll; break; case 4: case 5: AngleVectors(ent->reflection[i]->s.angles,forward,NULL,NULL); roll = ent->reflection[i]->s.angles[2]; forward[1] = -forward[1]; vectoangles(forward,ent->reflection[i]->s.angles); ent->reflection[i]->s.angles[2] = 360-roll; } VectorCopy (org, ent->reflection[i]->s.origin); if(ent->s.renderfx & RF_BEAM) { vec3_t delta; VectorSubtract(ent->reflection[i]->s.origin,ent->s.origin,delta); VectorAdd(ent->s.old_origin,delta,ent->reflection[i]->s.old_origin); } else VectorCopy(ent->reflection[i]->s.origin, ent->reflection[i]->s.old_origin); gi.linkentity (ent->reflection[i]); } else if (ent->reflection[i]) { DeleteReflection(ent,i); } } }