290 lines
7.4 KiB
C
290 lines
7.4 KiB
C
#include "g_local.h"
|
|
void T_Radius2Damage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int kickback, int mod);
|
|
|
|
//ent = the remote camera
|
|
void remote_remove(edict_t *ent)
|
|
{
|
|
if (!ent) return;
|
|
|
|
ent->takedamage = DAMAGE_NO;
|
|
|
|
//Should it blow up?
|
|
if (ent->dmg)
|
|
{
|
|
T_Radius2Damage(ent, ent->owner, ent->dmg, NULL, 200, 30, MOD_CAMERA);
|
|
|
|
gi.WriteByte (svc_temp_entity);
|
|
gi.WriteByte (TE_ROCKET_EXPLOSION);
|
|
gi.WritePosition (ent->s.origin);
|
|
gi.multicast (ent->s.origin, MULTICAST_PVS);
|
|
|
|
}
|
|
|
|
if ((ent->owner) && (ent->owner->client))
|
|
{
|
|
ent->owner->client->remotetoggle = 0;
|
|
ent->owner->remotecam = NULL;
|
|
}
|
|
|
|
//Remove camera
|
|
G_FreeEdict (ent);
|
|
}
|
|
|
|
void remote_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
|
|
{
|
|
|
|
if (wfdebug) gi.dprintf("remote_die\n");
|
|
// T_RadiusDamage (self, self->owner, 20, NULL, 10,0);
|
|
|
|
// BANG !
|
|
gi.WriteByte (svc_temp_entity);
|
|
gi.WriteByte (TE_EXPLOSION1);
|
|
gi.WritePosition(self->s.origin);
|
|
gi.multicast (self->s.origin, MULTICAST_PVS);
|
|
|
|
self->takedamage = DAMAGE_NO;
|
|
self->nextthink = level.time + .1;
|
|
self->think = remote_remove;
|
|
}
|
|
|
|
void remotecam_think(edict_t *ent)
|
|
{
|
|
if(ent->owner->client->remotetoggle)
|
|
{
|
|
/* Remove cell requirements for now - GAR
|
|
if (ent->owner->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] < 1)
|
|
{
|
|
safe_cprintf(ent->owner, PRINT_HIGH, "Not enough cells for the Remote Camera to stay\n");
|
|
|
|
T_RadiusDamage (ent, ent->owner, 10, NULL, 10,0);
|
|
|
|
// BANG !
|
|
gi.WriteByte (svc_temp_entity);
|
|
gi.WriteByte (TE_EXPLOSION1);
|
|
gi.WritePosition(ent->s.origin);
|
|
gi.multicast (ent->s.origin, MULTICAST_PVS);
|
|
|
|
remote_remove(ent);
|
|
return;
|
|
}
|
|
*/
|
|
}
|
|
/* Remove cell requirements for now - GAR
|
|
if(ent->owner->client->remotetoggle)
|
|
ent->owner->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] -= 1;
|
|
*/
|
|
ent->nextthink = level.time + 0.5;
|
|
}
|
|
|
|
void place_remotecam (edict_t *ent)
|
|
{
|
|
|
|
vec3_t forward,
|
|
wallp, offset;
|
|
|
|
trace_t tr;
|
|
|
|
// valid ent ?
|
|
if ((!ent->client) || (ent->health<=0))
|
|
return;
|
|
|
|
//If there already is a camera, remove it
|
|
if (ent->remotecam)
|
|
{
|
|
//If damage is set to zero, just remove it
|
|
if (ent->remotecam->dmg == 0)
|
|
{
|
|
remote_remove(ent->remotecam);
|
|
safe_cprintf (ent, PRINT_HIGH, "Camera removed.\n");
|
|
return;
|
|
}
|
|
|
|
//Otherwise, detonate it
|
|
if (ent->remotecam->delay > level.time)
|
|
{
|
|
safe_cprintf (ent, PRINT_HIGH, "You can't blow up camera for another %d seconds.\n",
|
|
(int)(ent->remotecam->delay - level.time));
|
|
return;
|
|
}
|
|
safe_cprintf (ent, PRINT_HIGH, "Remote cam will detonate in 5 seconds.\n");
|
|
ent->remotecam->dmg = 400;
|
|
ent->remotecam->s.sound = gi.soundindex("weapons/hgrenc1b.wav");
|
|
ent->remotecam->think = remote_remove;
|
|
ent->remotecam->nextthink = level.time + 5;
|
|
//remote_remove(ent->remotecam);
|
|
return;
|
|
}
|
|
|
|
// cells for camera
|
|
if (ent->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] < 25)
|
|
{
|
|
safe_cprintf(ent, PRINT_HIGH, "You need 25 cells to place camera\n");
|
|
return;
|
|
}
|
|
|
|
// Setup "little look" to close wall
|
|
VectorCopy(ent->s.origin,wallp);
|
|
|
|
// Cast along view angle
|
|
AngleVectors (ent->client->v_angle, forward, NULL, NULL);
|
|
|
|
// Setup end point
|
|
wallp[0]=ent->s.origin[0]+forward[0]*50;
|
|
wallp[1]=ent->s.origin[1]+forward[1]*50;
|
|
wallp[2]=ent->s.origin[2]+forward[2]*50;
|
|
|
|
// trace
|
|
tr = gi.trace (ent->s.origin, NULL, NULL, wallp, ent, MASK_SOLID);
|
|
|
|
// Line complete ? (ie. no collision)
|
|
if (tr.fraction == 1.0)
|
|
{
|
|
safe_cprintf (ent, PRINT_HIGH, "Too far from wall.\n");
|
|
return;
|
|
}
|
|
|
|
// Hit sky ?
|
|
if (tr.surface)
|
|
{
|
|
if (tr.surface->flags & SURF_SKY)
|
|
return;
|
|
}
|
|
|
|
ent->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] -= 25;
|
|
|
|
if (ent->remotecam)
|
|
{
|
|
safe_cprintf (ent, PRINT_HIGH, "Remote cam off.\n");
|
|
remote_remove(ent->remotecam);
|
|
return;
|
|
}
|
|
|
|
safe_cprintf (ent, PRINT_HIGH, "Remote cam on.\n");
|
|
|
|
ent->remotecam = G_Spawn();
|
|
VectorClear (ent->remotecam->mins);
|
|
VectorClear (ent->remotecam->maxs);
|
|
VectorCopy (tr.endpos, ent->remotecam->s.origin);
|
|
vectoangles(tr.plane.normal,ent->remotecam -> s.angles);
|
|
ent->remotecam -> movetype = MOVETYPE_NONE;
|
|
ent->remotecam -> clipmask = MASK_SHOT;
|
|
//grenade -> solid = SOLID_NOT;
|
|
ent->remotecam->solid = SOLID_BBOX;
|
|
VectorSet(ent->remotecam->mins, -3, -3, 0);
|
|
VectorSet(ent->remotecam->maxs, 3, 3, 6);
|
|
ent->remotecam->classname="camera";
|
|
ent->remotecam->takedamage=DAMAGE_YES;
|
|
ent->remotecam -> s.modelindex = gi.modelindex ("models/objects/camera/tris.md2");
|
|
ent->remotecam -> owner = ent;
|
|
ent->remotecam->think = remotecam_think;
|
|
ent->remotecam->nextthink = level.time + 0.5;
|
|
ent->remotecam->die = remote_die;
|
|
ent->remotecam->health= 60;
|
|
ent->remotecam->max_health = 60;
|
|
ent->remotecam->mass = 2;
|
|
ent->remotecam->delay = level.time + 10; //can't blow up for this many seconds
|
|
ent->remotecam->dmg = 20;
|
|
offset[0]=forward[0]*-10;
|
|
offset[1]=forward[1]*-10;
|
|
offset[2]=forward[2]*-10;
|
|
VectorAdd(offset,tr.endpos,offset);
|
|
VectorCopy(offset,ent->remotecam->camposition);
|
|
gi.linkentity (ent->remotecam);
|
|
|
|
/*db if(ent->client->remotetoggle)
|
|
{
|
|
ent->client->oldplayer = G_Spawn();
|
|
ent->client->oldplayer->s.frame = ent->s.frame;
|
|
VectorCopy (ent->s.origin, ent->client->oldplayer->s.origin);
|
|
VectorCopy (ent->velocity, ent->client->oldplayer->velocity);
|
|
VectorCopy (ent->s.angles, ent->client->oldplayer->s.angles);
|
|
ent->client->oldplayer->s.modelindex = ent->s.modelindex;
|
|
ent->client->oldplayer->s.modelindex2 = ent->s.modelindex2;
|
|
gi.linkentity (ent->client->oldplayer);
|
|
}*/
|
|
}
|
|
|
|
//Remote Camera Commands
|
|
void cmd_CameraPlace(edict_t *ent)
|
|
{
|
|
place_remotecam (ent);
|
|
}
|
|
|
|
void cmd_CameraToggle(edict_t *ent)
|
|
{
|
|
if (ent->remotecam == NULL)
|
|
{
|
|
safe_cprintf (ent, PRINT_HIGH, "Remote camera does not exist!\n");
|
|
return;
|
|
}
|
|
|
|
if (ent->client->remotetoggle)
|
|
{
|
|
ent->client->remotetoggle = 0;
|
|
//db G_FreeEdict(ent->client->oldplayer);
|
|
}
|
|
else
|
|
{
|
|
ent->client->remotetoggle =1;
|
|
/*db ent->client->oldplayer = G_Spawn();
|
|
ent->client->oldplayer->s.frame = ent->s.frame;
|
|
VectorCopy (ent->s.origin, ent->client->oldplayer->s.origin);
|
|
VectorCopy (ent->velocity, ent->client->oldplayer->velocity);
|
|
VectorCopy (ent->s.angles, ent->client->oldplayer->s.angles);
|
|
ent->client->oldplayer->s.modelindex = ent->s.modelindex;
|
|
ent->client->oldplayer->s.modelindex2 = ent->s.modelindex2;
|
|
gi.linkentity (ent->client->oldplayer);*/
|
|
}
|
|
}
|
|
|
|
// Command line handling for camera
|
|
void cmd_Camera(edict_t *ent)
|
|
{
|
|
char *string;
|
|
int time = 0;
|
|
|
|
string = gi.args();
|
|
|
|
if (!ent->client) return;
|
|
|
|
//argument = "build", "detonate", "remove", "toggle"
|
|
if (Q_stricmp ( string, "build") == 0)
|
|
{
|
|
if (ent->remotecam)
|
|
safe_cprintf(ent, PRINT_HIGH, "You already have an active camera\n");
|
|
else
|
|
place_remotecam (ent);
|
|
}
|
|
else if (Q_stricmp ( string, "toggle") == 0)
|
|
{
|
|
if (!ent->remotecam)
|
|
safe_cprintf(ent, PRINT_HIGH, "You don't have an active camera!\n");
|
|
else
|
|
cmd_CameraToggle(ent);
|
|
}
|
|
else if (Q_stricmp ( string, "detonate") == 0)
|
|
{
|
|
if (!ent->remotecam)
|
|
safe_cprintf(ent, PRINT_HIGH, "You don't have an active camera!\n");
|
|
else
|
|
place_remotecam (ent);
|
|
}
|
|
else if (Q_stricmp ( string, "remove") == 0)
|
|
{
|
|
if (!ent->remotecam)
|
|
safe_cprintf(ent, PRINT_HIGH, "You don't have an active camera!\n");
|
|
else
|
|
{
|
|
ent->remotecam->dmg = 0;
|
|
place_remotecam (ent);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
safe_cprintf(ent->owner, PRINT_HIGH, "Incomplete command: add BUILD, DETONATE, REMOVE or TOGGLE\n");
|
|
}
|
|
|
|
}
|
|
|