#include "g_local.h" #include "laser2.h" int laser_colour[] = { 0xf3f3f1f1, //0 blue 0xf2f2f0f0, //1 red // 0xf2f2f0f0, //0 red // 0xf3f3f1f1, //1 blue 0xf3f3f1f1, //2 blue // 0xd0d1d2d3, //2 green 0xdcdddedf, //3 yellow 0xe0e1e2e3, //4 bitty yellow strobe 0x80818283, //5 JR brownish purple I think 0x70717273, //6 JR light blue 0x90919293, //7 JR type of green 0xb0b1b2b3, //8 JR another purple 0x40414243, //9 JR a reddish color 0xe2e5e3e6, //10 JR another orange 0xd0f1d3f3, //11 JR mixture of color 0xf2f3f0f1, //12 JR red outer blue inner 0xf3f2f1f0, //13 JR blue outer red inner 0xdad0dcd2, //14 JR yellow outer green inner 0xd0dad2dc //15 JR green outer yellow inner }; //By setting the color for each, players can tell the difference #define LASER_DEFENSE_COLOR 4 #define LASER_TRIPBOMB_COLOR 12 /* ===================== Laser Defense ===================== */ void laser_cleanup(edict_t *self) { vec3_t origin; if (self->owner->client) PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT); T_RadiusDamage(self, self->owner, self->dmg, NULL, self->dmg_radius, MOD_LASER_DEFENSE); VectorMA (self->s.origin, -0.02, self->velocity, origin); gi.WriteByte (svc_temp_entity); if (self->waterlevel) { if (self->groundentity) gi.WriteByte (TE_GRENADE_EXPLOSION_WATER); else gi.WriteByte (TE_ROCKET_EXPLOSION_WATER); } else { if (self->groundentity) gi.WriteByte (TE_GRENADE_EXPLOSION); else gi.WriteByte (TE_ROCKET_EXPLOSION); } gi.WritePosition (origin); gi.multicast (self->s.origin, MULTICAST_PVS); //reduce # active laser defenses // TeT++ //Remove laser if (self->creator) G_FreeEdict (self->creator); // TeT-- //Remove grenade G_FreeEdict (self); } void laser_defense_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { // TeT++ if (self->creator) { self->creator->delay = level.time + 0.1; } // TeT-- laser_cleanup(self); } //Laser Defense // TeT++ void PlaceLaser (edict_t *ent) { edict_t *laser, *grenade; vec3_t forward, wallp, start, end; trace_t tr; trace_t endTrace; // valid ent ? if ((!ent->client) || (ent->health<=0)) return; // cells for laser ? if (ent->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] < CELLS_FOR_LASER) { safe_cprintf(ent, PRINT_HIGH, "Not enough cells for laser.\n"); return; } //Are there too many laser defense systems now? if (ent->client->pers.active_special[ITEM_SPECIAL_LASER_DEFENSE] >= MAX_SPECIAL_LASER_DEFENSE) { safe_cprintf(ent, PRINT_HIGH, "You can only have %d active Laser Defense Systems.\n",MAX_SPECIAL_LASER_DEFENSE ); 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; // Ok, lets stick one on then ... safe_cprintf (ent, PRINT_HIGH, "Laser attached.\n"); if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] -= CELLS_FOR_LASER; ++ent->client->pers.active_special[ITEM_SPECIAL_LASER_DEFENSE]; // get enties for both objects grenade = G_Spawn(); laser = G_Spawn(); grenade->special_index = ITEM_SPECIAL_LASER_DEFENSE; // setup the Grenade VectorClear (grenade->mins); VectorClear (grenade->maxs); VectorCopy (tr.endpos, grenade->s.origin); vectoangles(tr.plane.normal, grenade->s.angles); grenade->special_index = ITEM_SPECIAL_LASER_DEFENSE; grenade->wf_team = ent->wf_team; grenade -> movetype = MOVETYPE_NONE; grenade -> clipmask = MASK_SHOT; grenade->solid = SOLID_BBOX; VectorSet(grenade->mins, -3, -3, 0); VectorSet(grenade->maxs, 3, 3, 6); grenade -> takedamage = DAMAGE_YES; grenade -> die = laser_defense_die; grenade -> s.modelindex = gi.modelindex (GRNORMAL_MODEL); grenade -> owner = ent; grenade -> creator = laser; grenade -> monsterinfo.aiflags = AI_NOSTEP; grenade -> classname = "laser_defense_gr"; grenade -> nextthink = level.time + LASER_TIME; grenade -> think = laser_cleanup; grenade -> health = 10; grenade -> max_health = 10; // Now lets find the other end of the laser // by starting at the grenade position VectorCopy (grenade->s.origin, start); // setup laser movedir (projection of laser) G_SetMovedir (grenade->s.angles, laser->movedir); VectorMA (start, 2048, laser->movedir, end); endTrace = gi.trace (start, NULL, NULL, end, ent, MASK_SOLID); // ----------- // Setup laser // ----------- laser -> wf_team = ent->wf_team; laser -> movetype = MOVETYPE_NONE; laser -> solid = SOLID_NOT; laser -> s.renderfx = RF_BEAM|RF_TRANSLUCENT; laser -> s.modelindex = 1; // must be non-zero laser -> s.sound = gi.soundindex ("world/laser.wav"); laser -> classname = "laser_defense"; laser -> s.frame = 2; // beam diameter laser -> owner = NULL; laser -> s.skinnum = laser_colour[ent->wf_team]; laser -> dmg = LASER_DAMAGE; laser -> think = pre_target_laser_def_think; laser -> delay = level.time + LASER_TIME; laser -> creator = grenade; laser -> activator = ent; // start off ... target_laser_off (laser); VectorCopy (endTrace.endpos, laser->s.old_origin); // ... but make automatically come on laser -> nextthink = level.time + 2; // Set orgin of laser to point of contact with wall VectorCopy(endTrace.endpos,laser->s.origin); // convert normal at point of contact to laser angles vectoangles(tr.plane.normal,laser->s.angles); // setup laser movedir (projection of laser) G_SetMovedir (laser->s.angles, laser->movedir); VectorSet (laser->mins, -8, -8, -8); VectorSet (laser->maxs, 8, 8, 8); // link to world gi.linkentity (laser); gi.linkentity (grenade); } void pre_target_laser_def_think (edict_t *self) { target_laser_on (self); self->think = target_laser_def_think; } void pre_target_laser_think (edict_t *self) { target_laser_on (self); self->think = target_laser_think; } void pre_target_laserb_think (edict_t *self); /* =============== Laser Tripbombs =============== */ /* for them to work need some code I will do later */ void laser_trip_cleanup(edict_t *self) { //Remove laser if (self->owner) G_FreeEdict (self->owner); //Remove grenade G_FreeEdict (self); } void laser_tripbomb_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { self->owner->delay = level.time + 0.1; laser_trip_cleanup(self); } //Laser Tripbomb void PlaceLaserb (edict_t *ent) { edict_t *self, *grenade; vec3_t forward, wallp; trace_t tr; // valid ent ? if ((!ent->client) || (ent->health<=0)) return; // cells for laser ? if (ent->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] < 100) { safe_cprintf(ent, PRINT_HIGH, "Not enough cells for laser bomb.\n"); return; } //Are there too many laser defense systems now? if (ent->client->pers.active_special[ITEM_SPECIAL_TRIPBOMB] >= MAX_SPECIAL_TRIPBOMB) { safe_cprintf(ent, PRINT_HIGH, "You can only have %d active Trip Bombs.\n",MAX_SPECIAL_TRIPBOMB ); 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; // Ok, lets stick one on then ... safe_cprintf (ent, PRINT_HIGH, "Laser attached.\n"); if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) ) ent->client->pers.inventory[ITEM_INDEX(FindItem("Cells"))] -= 100; ++ent->client->pers.active_special[ITEM_SPECIAL_TRIPBOMB]; // ----------- // Setup laser // ----------- self = G_Spawn(); self->wf_team = ent->wf_team; self->special_index = ITEM_SPECIAL_TRIPBOMB; self -> movetype = MOVETYPE_NONE; self -> solid = SOLID_NOT; self -> s.renderfx = RF_BEAM|RF_TRANSLUCENT; self -> s.modelindex = 1; // must be non-zero self -> s.sound = gi.soundindex ("world/laser.wav"); self -> classname = "lb"; self -> s.frame = 2; // beam diameter self -> owner = ent; //GREGG // self -> s.skinnum = laser_colour[((int) (random() * 1000)) % 16]; self -> s.skinnum = laser_colour[LASER_TRIPBOMB_COLOR]; self -> dmg = LASER_DAMAGE; self -> think = pre_target_laserb_think; self -> delay = level.time + LASER_TIME; //add a laser to the amount // ent->LaserBomb++; // Set orgin of laser to point of contact with wall VectorCopy(tr.endpos,self->s.origin); // convert normal at point of contact to laser angles vectoangles(tr.plane.normal,self -> s.angles); // setup laser movedir (projection of laser) G_SetMovedir (self->s.angles, self->movedir); VectorSet (self->mins, -8, -8, -8); VectorSet (self->maxs, 8, 8, 8); // link to world gi.linkentity (self); // start off ... target_laser_off (self); // ... but make automatically come on self -> nextthink = level.time + 2; grenade = G_Spawn(); grenade->wf_team = ent->wf_team; VectorClear (grenade->mins); VectorClear (grenade->maxs); VectorCopy (tr.endpos, grenade->s.origin); vectoangles(tr.plane.normal,grenade -> s.angles); grenade -> movetype = MOVETYPE_NONE; grenade -> clipmask = MASK_SHOT; //grenade -> solid = SOLID_NOT; grenade->solid = SOLID_BBOX; VectorSet(grenade->mins, -3, -3, 0); VectorSet(grenade->maxs, 3, 3, 6); grenade->takedamage=DAMAGE_YES; grenade->die = laser_tripbomb_die; grenade -> s.modelindex = gi.modelindex (GRNORMAL_MODEL); grenade -> owner = self; grenade -> nextthink = level.time + LASER_TIME; grenade -> think = laser_trip_cleanup; grenade->health= 15; grenade->max_health =15; gi.linkentity (grenade); } void pre_target_laserb_think (edict_t *self) { target_laser_on (self); self->think = target_laser_think; } void cmd_LaserDefense(edict_t *ent) { // if (ent->LaserOrbs > MAX_LASERS -1) // safe_cprintf(ent, PRINT_HIGH, "Max Lasers Already Reached.\n"); // else PlaceLaser (ent); } void cmd_TripBomb(edict_t *ent) { // if (ent->LaserBomb > 4 -1) // safe_cprintf(ent, PRINT_HIGH, "Max Laser Trip Bombs Already Reached.\n"); // else PlaceLaserb (ent); } //Remove all laser defenses for this entity void cmd_RemoveLaserDefense(edict_t *ent) { edict_t *blip = NULL; while ((blip = findradius(blip, ent->s.origin, 1000)) != NULL) { if (!strcmp(blip->classname, "laser_defense_gr") && blip->owner == ent) { blip->think = laser_cleanup; blip->nextthink = level.time + .1; } } }