mirror of
https://github.com/blendogames/thirtyflightsofloving.git
synced 2024-11-15 00:41:21 +00:00
Added blue and green hyperblaster modes to turret.
Fixed hyperblaster turret clipping against breach bmodel.
This commit is contained in:
parent
5a30bf4a96
commit
497a0c5a7b
2 changed files with 250 additions and 202 deletions
398
game/g_turret.c
398
game/g_turret.c
|
@ -74,7 +74,7 @@ edict_t *TurretTarget(edict_t *self)
|
|||
continue;
|
||||
VectorMA(who->absmin,0.5,who->size,end);
|
||||
tr = gi.trace (start, vec3_origin, vec3_origin, end, self, MASK_OPAQUE);
|
||||
if(tr.fraction < 1.0)
|
||||
if (tr.fraction < 1.0)
|
||||
continue;
|
||||
VectorSubtract(end, self->s.origin, dir);
|
||||
VectorNormalize(dir);
|
||||
|
@ -104,7 +104,7 @@ void turret_blocked(edict_t *self, edict_t *other)
|
|||
for (ent = self->teammaster; ent; ent = ent->teamchain)
|
||||
ent->avelocity[YAW] = 0;
|
||||
}
|
||||
if(self->owner)
|
||||
if (self->owner)
|
||||
self->owner->avelocity[YAW] = 0;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
|
@ -125,9 +125,11 @@ void turret_blocked(edict_t *self, edict_t *other)
|
|||
attacker = self->teammaster->owner;
|
||||
else
|
||||
attacker = self->teammaster;
|
||||
} else if(self->owner) {
|
||||
}
|
||||
else if (self->owner) {
|
||||
attacker = self->owner;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
attacker = self;
|
||||
}
|
||||
// give a big kickback to help prevent getting stuck
|
||||
|
@ -152,23 +154,23 @@ void hrocket_turret_fire (edict_t *self, edict_t *owner, vec3_t start, vec3_t di
|
|||
{
|
||||
if (self->moreflags & FL2_TURRET_DOUBLE_ALT_FIRING)
|
||||
{
|
||||
fire_rocket(owner, start2, dir2, damage, speed, 150, damage, home_target);
|
||||
fire_rocket (owner, start2, dir2, damage, speed,damage_radius, radius_damage, home_target);
|
||||
self->moreflags &= ~FL2_TURRET_DOUBLE_ALT_FIRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
fire_rocket(owner, start, dir, damage, speed, 150, damage, home_target);
|
||||
fire_rocket (owner, start, dir, damage, speed, damage_radius, radius_damage, home_target);
|
||||
self->moreflags |= FL2_TURRET_DOUBLE_ALT_FIRING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fire_rocket(owner, start, dir, damage, speed, 150, damage, home_target);
|
||||
fire_rocket(owner, start2, dir2, damage, speed, 150, damage, home_target);
|
||||
fire_rocket (owner, start, dir, damage, speed, damage_radius, radius_damage, home_target);
|
||||
fire_rocket (owner, start2, dir2, damage, speed, damage_radius, radius_damage, home_target);
|
||||
}
|
||||
}
|
||||
else
|
||||
fire_rocket(owner, start, dir, damage, speed, 150, damage, home_target);
|
||||
fire_rocket (owner, start, dir, damage, speed, damage_radius, radius_damage, home_target);
|
||||
}
|
||||
//CW--
|
||||
|
||||
|
@ -194,17 +196,17 @@ void turret_breach_fire (edict_t *self)
|
|||
//CW++
|
||||
if (self->moreflags & FL2_TURRET_DOUBLE)
|
||||
{
|
||||
AngleVectors(self->s.angles, forward2, right2, up2);
|
||||
VectorMA(self->s.origin, self->muzzle2[0], forward2, start2);
|
||||
VectorMA(start2, self->muzzle2[1], right2, start2);
|
||||
VectorMA(start2, self->muzzle2[2], up2, start2);
|
||||
AngleVectors (self->s.angles, forward2, right2, up2);
|
||||
VectorMA (self->s.origin, self->muzzle2[0], forward2, start2);
|
||||
VectorMA (start2, self->muzzle2[1], right2, start2);
|
||||
VectorMA (start2, self->muzzle2[2], up2, start2);
|
||||
}
|
||||
//CW--
|
||||
|
||||
speed = 550 + 50 * skill->value;
|
||||
|
||||
// DWH: automated turrets have no driver, so use self
|
||||
if(self->owner && !(self->owner->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER))
|
||||
if (self->owner && !(self->owner->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER))
|
||||
owner = self->owner;
|
||||
else
|
||||
owner = self;
|
||||
|
@ -213,9 +215,9 @@ void turret_breach_fire (edict_t *self)
|
|||
its been changed to self->owner incase anything weird happens.
|
||||
*/
|
||||
|
||||
//FIXME : only use the normal damages if self->owner (turret_driver) doesn't have one
|
||||
// FIXME : only use the normal damages if self->owner (turret_driver) doesn't have one
|
||||
|
||||
if(self->delay < level.time)
|
||||
if (self->delay < level.time)
|
||||
{
|
||||
switch (self->sounds)
|
||||
{
|
||||
|
@ -330,21 +332,26 @@ void turret_breach_fire (edict_t *self)
|
|||
case 4: // Homing rockets
|
||||
{
|
||||
damage = 100 + random() * 50;
|
||||
if (owner->target_ent == self || owner == self) {
|
||||
if (owner->target_ent == self || owner == self)
|
||||
{
|
||||
// monster-controlled or automated turret
|
||||
//fire_rocket (owner, start, forward, damage, speed, 150, damage, owner->enemy);
|
||||
hrocket_turret_fire(self, owner, start, forward, start2, forward2, damage, speed, 150, damage, owner->enemy); //CW
|
||||
} else if (self->spawnflags & SF_TURRET_PLAYER_CONTROLLABLE
|
||||
|| allow_player_use_abandoned_turret->value) {
|
||||
// fire_rocket (owner, start, forward, damage, speed, 150, damage, owner->enemy);
|
||||
hrocket_turret_fire (self, owner, start, forward, start2, forward2, damage, speed, 150, damage, owner->enemy); //CW
|
||||
}
|
||||
else if (self->spawnflags & SF_TURRET_PLAYER_CONTROLLABLE
|
||||
|| allow_player_use_abandoned_turret->value)
|
||||
{
|
||||
// what is player aiming at?
|
||||
edict_t *target;
|
||||
target = TurretTarget(self);
|
||||
//fire_rocket (owner, start, forward, damage, speed, 150, damage, target);
|
||||
hrocket_turret_fire(self, owner, start, forward, start2, forward2, damage, speed, 150, damage, target); //CW
|
||||
} else {
|
||||
// fire_rocket (owner, start, forward, damage, speed, 150, damage, target);
|
||||
hrocket_turret_fire (self, owner, start, forward, start2, forward2, damage, speed, 150, damage, target); //CW
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't be possible to get here
|
||||
//fire_rocket (owner, start, forward, damage, speed, 150, damage, NULL);
|
||||
hrocket_turret_fire(self, owner, start, forward, start2, forward2, damage, speed, 150, damage, NULL); //CW
|
||||
// fire_rocket (owner, start, forward, damage, speed, 150, damage, NULL);
|
||||
hrocket_turret_fire (self, owner, start, forward, start2, forward2, damage, speed, 150, damage, NULL); //CW
|
||||
}
|
||||
gi.positioned_sound (start, self, CHAN_WEAPON, gi.soundindex("weapons/rocklf1a.wav"), 1, ATTN_NORM, 0);
|
||||
|
||||
|
@ -388,8 +395,22 @@ void turret_breach_fire (edict_t *self)
|
|||
break;
|
||||
}
|
||||
case 6: // Hyperblaster
|
||||
case 8: // Blue Hyperblaster
|
||||
case 9: // Green Hyperblaster
|
||||
{
|
||||
unsigned int effect, color;
|
||||
if (self->sounds == 6)
|
||||
{ effect = EF_HYPERBLASTER; color = BLASTER_ORANGE; }
|
||||
if (self->sounds == 8)
|
||||
{ effect = EF_BLUEHYPERBLASTER; color = BLASTER_BLUE; }
|
||||
if (self->sounds == 9)
|
||||
{ effect = EF_HYPERBLASTER|EF_TRACKER; color = BLASTER_GREEN; }
|
||||
|
||||
HB_Shots++;
|
||||
|
||||
// FIXME: add forward vectors to starts to offset to prevent clipping issues
|
||||
VectorAdd (start, forward, start);
|
||||
VectorAdd (start2, forward2, start2);
|
||||
//CW++
|
||||
if (self->moreflags & FL2_TURRET_DOUBLE)
|
||||
{
|
||||
|
@ -397,25 +418,26 @@ void turret_breach_fire (edict_t *self)
|
|||
{
|
||||
if (self->moreflags & FL2_TURRET_DOUBLE_ALT_FIRING)
|
||||
{
|
||||
fire_blaster (owner, start2, forward2, self->wait, 1000, (!(HB_Shots % 4))?EF_HYPERBLASTER:0, true, BLASTER_ORANGE);
|
||||
fire_blaster (owner, start2, forward2, self->wait, 1000, (!(HB_Shots % 4))?effect:0, true, color);
|
||||
self->moreflags &= ~FL2_TURRET_DOUBLE_ALT_FIRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
fire_blaster (owner, start, forward, self->wait, 1000, (!(HB_Shots % 4))?EF_HYPERBLASTER:0, true, BLASTER_ORANGE);
|
||||
fire_blaster (owner, start, forward, self->wait, 1000, (!(HB_Shots % 4))?effect:0, true, color);
|
||||
self->moreflags |= FL2_TURRET_DOUBLE_ALT_FIRING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fire_blaster (owner, start, forward, self->wait, 1000, (!(HB_Shots % 4))?EF_HYPERBLASTER:0, true, BLASTER_ORANGE);
|
||||
fire_blaster (owner, start2, forward2, self->wait, 1000, 0, true, BLASTER_ORANGE);
|
||||
fire_blaster (owner, start, forward, self->wait, 1000, (!(HB_Shots % 4))?effect:0, true, color);
|
||||
fire_blaster (owner, start2, forward2, self->wait, 1000, 0, true, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
//CW--
|
||||
fire_blaster (owner, start, forward, self->wait, 1000, (!(HB_Shots % 4))?EF_HYPERBLASTER:0, true, BLASTER_ORANGE);
|
||||
gi.positioned_sound(start,self,CHAN_WEAPON,gi.soundindex("weapons/hyprbf1a.wav"),1,ATTN_NORM,0);
|
||||
fire_blaster (owner, start, forward, self->wait, 1000, (!(HB_Shots % 4))?effect:0, true, color);
|
||||
gi.positioned_sound (start, self,CHAN_WEAPON, gi.soundindex("weapons/hyprbf1a.wav"), 1, ATTN_NORM, 0);
|
||||
// gi.positioned_sound (start, self, CHAN_WEAPON, gi.soundindex("makron/blaster.wav"), 1, ATTN_NORM, 0);
|
||||
self->delay = level.time; // No delay
|
||||
break;
|
||||
}
|
||||
|
@ -538,11 +560,11 @@ void turret_turn (edict_t *self)
|
|||
VectorCopy (self->s.angles, current_angles);
|
||||
AnglesNormalize(current_angles);
|
||||
|
||||
if(self->viewer && self->viewer->client)
|
||||
if (self->viewer && self->viewer->client)
|
||||
{
|
||||
gclient_t *client = self->viewer->client;
|
||||
|
||||
if( (client->old_owner_angles[0] != client->ucmd.angles[0]) ||
|
||||
if ( (client->old_owner_angles[0] != client->ucmd.angles[0]) ||
|
||||
(client->old_owner_angles[1] != client->ucmd.angles[1]) )
|
||||
{
|
||||
// Give game a bit of time to catch up after player
|
||||
|
@ -551,30 +573,30 @@ void turret_turn (edict_t *self)
|
|||
// hasn't hit +lookup/+lookdown
|
||||
float delta;
|
||||
delta = level.time - self->touch_debounce_time;
|
||||
if( delta < 0 || delta > 1.0)
|
||||
if ( delta < 0 || delta > 1.0)
|
||||
{
|
||||
float delta_angle;
|
||||
float fastest = self->speed * FRAMETIME;
|
||||
|
||||
delta_angle = SHORT2ANGLE(client->ucmd.angles[0]-client->old_owner_angles[0]);
|
||||
if(delta_angle < -180)
|
||||
if (delta_angle < -180)
|
||||
delta_angle += 360;
|
||||
if(delta_angle > 180)
|
||||
if (delta_angle > 180)
|
||||
delta_angle -= 360;
|
||||
if(delta_angle > fastest)
|
||||
if (delta_angle > fastest)
|
||||
delta_angle = fastest;
|
||||
if(delta_angle < -fastest)
|
||||
if (delta_angle < -fastest)
|
||||
delta_angle = -fastest;
|
||||
self->move_angles[0] += delta_angle;
|
||||
|
||||
delta_angle = SHORT2ANGLE(client->ucmd.angles[1]-client->old_owner_angles[1]);
|
||||
if(delta_angle < -180)
|
||||
if (delta_angle < -180)
|
||||
delta_angle += 360;
|
||||
if(delta_angle > 180)
|
||||
if (delta_angle > 180)
|
||||
delta_angle -= 360;
|
||||
if(delta_angle > fastest)
|
||||
if (delta_angle > fastest)
|
||||
delta_angle = fastest;
|
||||
if(delta_angle < -fastest)
|
||||
if (delta_angle < -fastest)
|
||||
delta_angle = -fastest;
|
||||
self->move_angles[1] += delta_angle;
|
||||
|
||||
|
@ -605,10 +627,10 @@ void turret_turn (edict_t *self)
|
|||
float yaw_range;
|
||||
float yaw_base;
|
||||
yaw_range = self->pos2[YAW] - self->pos1[YAW];
|
||||
if(yaw_range < 0)
|
||||
if (yaw_range < 0)
|
||||
yaw_range += 360;
|
||||
yaw_base = self->move_angles[YAW] - self->pos1[YAW];
|
||||
if(yaw_base < 0)
|
||||
if (yaw_base < 0)
|
||||
yaw_base += 360;
|
||||
if (yaw_base > yaw_range)
|
||||
{
|
||||
|
@ -661,7 +683,7 @@ void turret_turn (edict_t *self)
|
|||
for (ent = self->teammaster; ent; ent = ent->teamchain)
|
||||
{
|
||||
ent->avelocity[1] = self->avelocity[1];
|
||||
if(ent->solid == SOLID_NOT)
|
||||
if (ent->solid == SOLID_NOT)
|
||||
ent->avelocity[0] = self->avelocity[0];
|
||||
}
|
||||
}
|
||||
|
@ -681,7 +703,7 @@ void turret_breach_think (edict_t *self)
|
|||
|
||||
turret_turn(self);
|
||||
yaw_r = self->pos2[YAW] - self->pos1[YAW];
|
||||
if(yaw_r < 0)
|
||||
if (yaw_r < 0)
|
||||
yaw_r += 360;
|
||||
|
||||
if (self->pos1[YAW] != 0 || self->pos2[YAW] != 360)
|
||||
|
@ -691,7 +713,7 @@ void turret_breach_think (edict_t *self)
|
|||
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
||||
if(self->deadflag == DEAD_DEAD) return;
|
||||
if (self->deadflag == DEAD_DEAD) return;
|
||||
|
||||
if ( (self->owner) && (self->owner->target_ent == self) &&
|
||||
(self->owner->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER))
|
||||
|
@ -699,15 +721,18 @@ void turret_breach_think (edict_t *self)
|
|||
else
|
||||
remote_monster = false;
|
||||
|
||||
if (self->owner || self->viewer) {
|
||||
if( !(self->spawnflags & SF_TURRET_MD2))
|
||||
if (self->owner || self->viewer)
|
||||
{
|
||||
if ( !(self->spawnflags & SF_TURRET_MD2))
|
||||
{
|
||||
self->s.effects &= ~EF_ANIM23;
|
||||
self->s.effects |= EF_ANIM01;
|
||||
}
|
||||
self->do_not_rotate = true;
|
||||
} else {
|
||||
if( !(self->spawnflags & SF_TURRET_MD2))
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !(self->spawnflags & SF_TURRET_MD2))
|
||||
{
|
||||
self->s.effects &= ~EF_ANIM01;
|
||||
self->s.effects |= EF_ANIM23;
|
||||
|
@ -716,9 +741,9 @@ void turret_breach_think (edict_t *self)
|
|||
}
|
||||
if (self->team) {
|
||||
for (ent = self->teammaster; ent; ent = ent->teamchain) {
|
||||
if(ent != self->owner)
|
||||
if (ent != self->owner)
|
||||
{
|
||||
if(ent->solid != SOLID_NOT)
|
||||
if (ent->solid != SOLID_NOT)
|
||||
ent->s.effects = self->s.effects;
|
||||
ent->do_not_rotate = self->do_not_rotate;
|
||||
}
|
||||
|
@ -846,7 +871,7 @@ void turret_breach_think (edict_t *self)
|
|||
float best_dist = WORLD_SIZE; // was 8192
|
||||
float dist;
|
||||
|
||||
if(self->viewer && level.time < self->touch_debounce_time)
|
||||
if (self->viewer && level.time < self->touch_debounce_time)
|
||||
return;
|
||||
|
||||
AngleVectors(self->s.angles, forward, right, up);
|
||||
|
@ -856,15 +881,19 @@ void turret_breach_think (edict_t *self)
|
|||
|
||||
self->oldenemy = self->enemy;
|
||||
|
||||
if(self->enemy) {
|
||||
if (self->enemy)
|
||||
{
|
||||
// check that current enemy is valid. if so, find
|
||||
// distance. don't switch enemies unless another
|
||||
// monster is at least 100 units closer to the camera
|
||||
if(self->enemy->inuse) {
|
||||
if((self->enemy->health > self->enemy->gib_health) &&
|
||||
if (self->enemy->inuse)
|
||||
{
|
||||
if ((self->enemy->health > self->enemy->gib_health) &&
|
||||
!(self->enemy->svflags & SVF_NOCLIENT) &&
|
||||
!(self->enemy->flags & FL_NOTARGET) ) {
|
||||
if(gi.inPVS(self->s.origin,self->enemy->s.origin)) {
|
||||
!(self->enemy->flags & FL_NOTARGET) )
|
||||
{
|
||||
if (gi.inPVS(self->s.origin,self->enemy->s.origin))
|
||||
{
|
||||
VectorMA(self->enemy->absmin,0.5,self->enemy->size,target);
|
||||
VectorSubtract(target,self->s.origin,dir);
|
||||
vectoangles(dir,angles);
|
||||
|
@ -872,50 +901,56 @@ void turret_breach_think (edict_t *self)
|
|||
if ( yaw_restrict )
|
||||
{
|
||||
yaw_0 = angles[YAW] - self->pos1[YAW];
|
||||
if(yaw_0 < 0)
|
||||
if (yaw_0 < 0)
|
||||
yaw_0 += 360;
|
||||
}
|
||||
if( (angles[PITCH] > self->pos1[PITCH]) || (angles[PITCH] < self->pos2[PITCH]) ||
|
||||
if ( (angles[PITCH] > self->pos1[PITCH]) || (angles[PITCH] < self->pos2[PITCH]) ||
|
||||
( yaw_restrict && (yaw_0 > yaw_r) ) ) {
|
||||
self->enemy = NULL;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(self->s.origin,t_start);
|
||||
VectorCopy(dir,f);
|
||||
VectorNormalize(f);
|
||||
VectorMA(t_start,self->teammaster->base_radius,f,t_start);
|
||||
tr = gi.trace(t_start,vec3_origin,vec3_origin,target,self,MASK_SHOT);
|
||||
if(tr.ent == self->enemy) {
|
||||
if (tr.ent == self->enemy) {
|
||||
VectorSubtract(target,self->s.origin,dir);
|
||||
best_dist = VectorLength(dir) - 100;
|
||||
} else
|
||||
}
|
||||
else
|
||||
self->enemy = NULL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
self->enemy = NULL;
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
self->enemy = NULL;
|
||||
} else
|
||||
}
|
||||
else
|
||||
self->enemy = NULL;
|
||||
}
|
||||
|
||||
// for GOODGUY weapon-firing turrets, if current enemy is a player or GOODGUY monster,
|
||||
// reset best_dist so that bad monsters will be selected if found, regardless of distance.
|
||||
if( (self->enemy) && (self->sounds >= 0) && (self->spawnflags & SF_TURRET_GOODGUY)) {
|
||||
if((self->enemy->client) || (self->enemy->monsterinfo.aiflags & AI_GOOD_GUY))
|
||||
if ( (self->enemy) && (self->sounds >= 0) && (self->spawnflags & SF_TURRET_GOODGUY)) {
|
||||
if ((self->enemy->client) || (self->enemy->monsterinfo.aiflags & AI_GOOD_GUY))
|
||||
best_dist = WORLD_SIZE; // was 8192
|
||||
}
|
||||
|
||||
// hunt for monster
|
||||
if(!remote_monster) {
|
||||
for(i=maxclients->value+1; i<globals.num_edicts; i++) {
|
||||
if (!remote_monster) {
|
||||
for (i=maxclients->value+1; i<globals.num_edicts; i++) {
|
||||
gomer = g_edicts + i;
|
||||
if(gomer == self->enemy) continue; // no need to re-check this guy
|
||||
if(!gomer->inuse) continue;
|
||||
if(!(gomer->svflags & SVF_MONSTER)) continue;
|
||||
if(gomer->health < gomer->gib_health) continue;
|
||||
if(gomer->svflags & SVF_NOCLIENT) continue;
|
||||
if(!gi.inPVS(self->s.origin,gomer->s.origin)) continue;
|
||||
if (gomer == self->enemy) continue; // no need to re-check this guy
|
||||
if (!gomer->inuse) continue;
|
||||
if (!(gomer->svflags & SVF_MONSTER)) continue;
|
||||
if (gomer->health < gomer->gib_health) continue;
|
||||
if (gomer->svflags & SVF_NOCLIENT) continue;
|
||||
if (!gi.inPVS(self->s.origin,gomer->s.origin)) continue;
|
||||
VectorMA(gomer->absmin,0.5,gomer->size,target);
|
||||
VectorCopy(self->s.origin,t_start);
|
||||
VectorSubtract(target,self->s.origin,dir);
|
||||
|
@ -923,20 +958,20 @@ void turret_breach_think (edict_t *self)
|
|||
VectorNormalize(f);
|
||||
VectorMA(t_start,self->teammaster->base_radius,f,t_start);
|
||||
tr = gi.trace(t_start,vec3_origin,vec3_origin,target,self,MASK_SHOT);
|
||||
if(tr.ent == gomer) {
|
||||
if (tr.ent == gomer) {
|
||||
vectoangles(dir,angles);
|
||||
AnglesNormalize(angles);
|
||||
if ( yaw_restrict )
|
||||
{
|
||||
yaw_0 = angles[YAW] - self->pos1[YAW];
|
||||
if(yaw_0 < 0)
|
||||
if (yaw_0 < 0)
|
||||
yaw_0 += 360;
|
||||
}
|
||||
if( (angles[PITCH] <= self->pos1[PITCH]) && (angles[PITCH] >= self->pos2[PITCH]) &&
|
||||
if ( (angles[PITCH] <= self->pos1[PITCH]) && (angles[PITCH] >= self->pos2[PITCH]) &&
|
||||
( !yaw_restrict || (yaw_0 <= yaw_r) )
|
||||
) {
|
||||
dist = VectorLength(dir);
|
||||
if(dist < best_dist) {
|
||||
if (dist < best_dist) {
|
||||
self->enemy = gomer;
|
||||
best_dist = dist;
|
||||
}
|
||||
|
@ -946,24 +981,24 @@ void turret_breach_think (edict_t *self)
|
|||
}
|
||||
// for weapon-firing turrets, if GOODGUY is set and we already have an enemy, we're
|
||||
// done.
|
||||
if( (self->sounds >= 0) && (self->spawnflags & SF_TURRET_GOODGUY) && self->enemy)
|
||||
if ( (self->sounds >= 0) && (self->spawnflags & SF_TURRET_GOODGUY) && self->enemy)
|
||||
goto good_enemy;
|
||||
|
||||
// for non-GOODGUY weapon-firing turrets, reset best_dist so that players will
|
||||
// ALWAYS be selected if found
|
||||
if( (self->sounds >= 0) && !(self->spawnflags & SF_TURRET_GOODGUY))
|
||||
if ( (self->sounds >= 0) && !(self->spawnflags & SF_TURRET_GOODGUY))
|
||||
best_dist = WORLD_SIZE; // was 8192
|
||||
|
||||
// hunt for closest player - hunt ALL entities since
|
||||
// we want to view fake players using camera
|
||||
for(i=1; i<globals.num_edicts; i++) {
|
||||
for (i=1; i<globals.num_edicts; i++) {
|
||||
gomer = g_edicts + i;
|
||||
if(!gomer->inuse) continue;
|
||||
if(!gomer->client) continue;
|
||||
if(gomer->svflags & SVF_NOCLIENT) continue;
|
||||
if(gomer->health < gomer->gib_health) continue;
|
||||
if(gomer->flags & FL_NOTARGET) continue;
|
||||
if(!gi.inPVS(self->s.origin,gomer->s.origin)) continue;
|
||||
if (!gomer->inuse) continue;
|
||||
if (!gomer->client) continue;
|
||||
if (gomer->svflags & SVF_NOCLIENT) continue;
|
||||
if (gomer->health < gomer->gib_health) continue;
|
||||
if (gomer->flags & FL_NOTARGET) continue;
|
||||
if (!gi.inPVS(self->s.origin,gomer->s.origin)) continue;
|
||||
VectorMA(gomer->absmin,0.5,gomer->size,target);
|
||||
|
||||
VectorCopy(self->s.origin,t_start);
|
||||
|
@ -972,19 +1007,19 @@ void turret_breach_think (edict_t *self)
|
|||
VectorNormalize(f);
|
||||
VectorMA(t_start,self->teammaster->base_radius,f,t_start);
|
||||
tr = gi.trace(t_start,vec3_origin,vec3_origin,target,self,MASK_SHOT);
|
||||
if(tr.ent == gomer) {
|
||||
if (tr.ent == gomer) {
|
||||
vectoangles(dir,angles);
|
||||
AnglesNormalize(angles);
|
||||
if ( yaw_restrict )
|
||||
{
|
||||
yaw_0 = angles[YAW] - self->pos1[YAW];
|
||||
if(yaw_0 < 0)
|
||||
if (yaw_0 < 0)
|
||||
yaw_0 += 360;
|
||||
}
|
||||
if( (angles[PITCH] <= self->pos1[PITCH]) && (angles[PITCH] >= self->pos2[PITCH]) &&
|
||||
if ( (angles[PITCH] <= self->pos1[PITCH]) && (angles[PITCH] >= self->pos2[PITCH]) &&
|
||||
( !yaw_restrict || (yaw_0 <= yaw_r) ) ) {
|
||||
dist = VectorLength(dir);
|
||||
if(dist < best_dist) {
|
||||
if (dist < best_dist) {
|
||||
self->enemy = gomer;
|
||||
best_dist = dist;
|
||||
}
|
||||
|
@ -993,16 +1028,16 @@ void turret_breach_think (edict_t *self)
|
|||
}
|
||||
|
||||
good_enemy:
|
||||
if(self->enemy)
|
||||
if (self->enemy)
|
||||
{
|
||||
if(self->enemy != self->oldenemy) {
|
||||
if (self->enemy != self->oldenemy) {
|
||||
self->monsterinfo.trail_time = level.time;
|
||||
self->monsterinfo.aiflags &= ~AI_LOST_SIGHT;
|
||||
}
|
||||
VectorCopy (self->enemy->s.origin, target);
|
||||
if(self->enemy->deadflag)
|
||||
if (self->enemy->deadflag)
|
||||
target[2] -= 16;
|
||||
if(skill->value >= 2)
|
||||
if (skill->value >= 2)
|
||||
{
|
||||
VectorMA(target,FRAMETIME,self->enemy->velocity,target);
|
||||
|
||||
|
@ -1010,7 +1045,7 @@ good_enemy:
|
|||
indistinguishable from skill 2 for most normal setups. Trouble is, it is sometimes
|
||||
EASIER than skill 2.
|
||||
|
||||
if(skill->value > 2)
|
||||
if (skill->value > 2)
|
||||
{
|
||||
float t;
|
||||
VectorSubtract(target,self->s.origin,dir);
|
||||
|
@ -1019,16 +1054,16 @@ good_enemy:
|
|||
VectorSubtract(dir,self->s.angles,dir);
|
||||
AnglesNormalize(dir);
|
||||
dir[2] = max( fabs(dir[0]), fabs(dir[1]) );
|
||||
if(dir[2] > 0)
|
||||
if (dir[2] > 0)
|
||||
{
|
||||
t = dir[2]/self->speed;
|
||||
VectorMA(target,t,self->enemy->velocity,target);
|
||||
}
|
||||
} */
|
||||
}
|
||||
if(self->sounds == 7)
|
||||
if (self->sounds == 7)
|
||||
{
|
||||
if(!AimGrenade (self, start, target, self->fog_far, dir))
|
||||
if (!AimGrenade (self, start, target, self->fog_far, dir))
|
||||
{
|
||||
// Can't get a grenade to target. Correct yaw but
|
||||
// not pitch
|
||||
|
@ -1036,7 +1071,7 @@ good_enemy:
|
|||
vec_t pitch = self->move_angles[PITCH];
|
||||
vectoangles (dir, self->move_angles);
|
||||
self->move_angles[PITCH] = pitch;
|
||||
if(skill->value > 0)
|
||||
if (skill->value > 0)
|
||||
turret_turn(self);
|
||||
return;
|
||||
}
|
||||
|
@ -1047,59 +1082,59 @@ good_enemy:
|
|||
vectoangles (dir, self->move_angles);
|
||||
// decide if we should shoot
|
||||
victim = NULL;
|
||||
if(self->spawnflags & SF_TURRET_GOODGUY)
|
||||
if (self->spawnflags & SF_TURRET_GOODGUY)
|
||||
{
|
||||
if((self->enemy->svflags & SVF_MONSTER) && !(self->enemy->monsterinfo.aiflags & AI_GOOD_GUY))
|
||||
if ((self->enemy->svflags & SVF_MONSTER) && !(self->enemy->monsterinfo.aiflags & AI_GOOD_GUY))
|
||||
victim = self->enemy;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(self->enemy->client)
|
||||
if (self->enemy->client)
|
||||
victim = self->enemy;
|
||||
}
|
||||
if(victim && self->sounds >= 0 && DotProduct(forward,dir) > 0.99)
|
||||
if (victim && self->sounds >= 0 && DotProduct(forward,dir) > 0.99)
|
||||
{
|
||||
// never automatically fire a turret remotely controlled by
|
||||
// a player
|
||||
if(!self->viewer || (self->viewer && !self->viewer->client))
|
||||
if (!self->viewer || (self->viewer && !self->viewer->client))
|
||||
{
|
||||
// don't fire rockets or homing rockets if remote turret_driver is
|
||||
// too close to target
|
||||
if(remote_monster)
|
||||
if (remote_monster)
|
||||
{
|
||||
vec3_t range;
|
||||
vec_t r;
|
||||
VectorSubtract(self->enemy->s.origin,self->owner->s.origin,range);
|
||||
r = VectorLength(range);
|
||||
if(r < 128) return;
|
||||
if (r < 128) return;
|
||||
}
|
||||
if (level.time < self->monsterinfo.attack_finished)
|
||||
{
|
||||
if(skill->value > 0)
|
||||
if (skill->value > 0)
|
||||
turret_turn(self);
|
||||
return;
|
||||
}
|
||||
if(self->sounds == 5 || self->sounds == 6)
|
||||
if (self->sounds == 5 || self->sounds == 6)
|
||||
reaction_time = 0;
|
||||
else
|
||||
reaction_time = max(0., 0.5*(2-skill->value));
|
||||
if ((level.time - self->monsterinfo.trail_time) < reaction_time)
|
||||
{
|
||||
if(skill->value > 0)
|
||||
if (skill->value > 0)
|
||||
turret_turn(self);
|
||||
return;
|
||||
}
|
||||
self->monsterinfo.attack_finished = level.time + reaction_time;
|
||||
if(self->sounds != 5 && self->sounds != 6)
|
||||
if (self->sounds != 5 && self->sounds != 6)
|
||||
self->monsterinfo.attack_finished += self->wait;
|
||||
turret_breach_fire(self);
|
||||
if(skill->value > 0)
|
||||
if (skill->value > 0)
|
||||
turret_turn(self);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(skill->value > 0)
|
||||
if (skill->value > 0)
|
||||
turret_turn(self);
|
||||
}
|
||||
}
|
||||
|
@ -1108,15 +1143,15 @@ good_enemy:
|
|||
// check for "followtarget"
|
||||
if ((!self->enemy) && ((!self->owner) || remote_monster))
|
||||
{
|
||||
if(self->followtarget)
|
||||
if (self->followtarget)
|
||||
{
|
||||
self->enemy = G_Find(NULL,FOFS(targetname),self->followtarget);
|
||||
if(self->enemy)
|
||||
if (self->enemy)
|
||||
{
|
||||
VectorMA (self->enemy->absmin, 0.5, self->enemy->size, target);
|
||||
VectorSubtract (target, self->s.origin, dir);
|
||||
vectoangles (dir, self->move_angles);
|
||||
if(skill->value > 0)
|
||||
if (skill->value > 0)
|
||||
turret_turn(self);
|
||||
}
|
||||
}
|
||||
|
@ -1133,14 +1168,15 @@ void turret_breach_finish_init (edict_t *self)
|
|||
else
|
||||
{
|
||||
self->target_ent = G_PickTarget (self->target);
|
||||
if(!self->target_ent)
|
||||
if (!self->target_ent)
|
||||
{
|
||||
gi.dprintf("%s at %s, target %s does not exist\n",
|
||||
self->classname,vtos(self->s.origin),self->target);
|
||||
self->classname, vtos(self->s.origin), self->target);
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
VectorSubtract (self->target_ent->s.origin, self->s.origin, self->move_origin);
|
||||
|
||||
G_FreeEdict(self->target_ent);
|
||||
|
||||
//CW++ Double-barrelled turrets.
|
||||
|
@ -1163,7 +1199,7 @@ void turret_breach_finish_init (edict_t *self)
|
|||
self->teammaster = self;
|
||||
self->teammaster->dmg = self->dmg;
|
||||
|
||||
if(!(self->spawnflags & (SF_TURRET_TRIGGER_SPAWN | SF_TURRET_GOODGUY | SF_TURRET_INACTIVE) )) {
|
||||
if (!(self->spawnflags & (SF_TURRET_TRIGGER_SPAWN | SF_TURRET_GOODGUY | SF_TURRET_INACTIVE) )) {
|
||||
self->think = turret_breach_think;
|
||||
self->think (self);
|
||||
}
|
||||
|
@ -1178,8 +1214,8 @@ void turret_die_temp_think(edict_t *self)
|
|||
{
|
||||
edict_t *target;
|
||||
target = G_Find(NULL,FOFS(targetname),self->destroytarget);
|
||||
while(target) {
|
||||
if(target && target->use)
|
||||
while (target) {
|
||||
if (target && target->use)
|
||||
target->use(target,self->target_ent,self->target_ent);
|
||||
target = G_Find(target,FOFS(targetname),self->destroytarget);
|
||||
}
|
||||
|
@ -1198,22 +1234,26 @@ void turret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
|
|||
// ensure turret_base stops rotating
|
||||
if (self->team) {
|
||||
for (ent = self->teammaster; ent; ent = ent->teamchain) {
|
||||
if(ent != self) {
|
||||
if (ent != self) {
|
||||
ent->avelocity[1] = 0;
|
||||
gi.linkentity(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(self->deadflag != DEAD_DEAD) {
|
||||
if (self->deadflag != DEAD_DEAD)
|
||||
{
|
||||
|
||||
// if turret has a driver, kill him too unless he's a "remote" driver
|
||||
if(self->owner && (self->owner->target_ent == self)) {
|
||||
if(self->owner->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER) {
|
||||
if (self->owner && (self->owner->target_ent == self))
|
||||
{
|
||||
if (self->owner->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)
|
||||
{
|
||||
// remote driver - remove and replace with normal infantry
|
||||
edict_t *monster;
|
||||
monster = self->owner->child;
|
||||
if(monster) {
|
||||
if (monster)
|
||||
{
|
||||
monster->health = self->owner->health;
|
||||
monster->enemy = self->owner->enemy;
|
||||
G_FreeEdict(self->owner);
|
||||
|
@ -1222,39 +1262,45 @@ void turret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
|
|||
monster->svflags &= ~SVF_NOCLIENT;
|
||||
monster_start_go (monster);
|
||||
gi.linkentity (monster);
|
||||
if(monster->enemy) FoundTarget(monster);
|
||||
if (monster->enemy) FoundTarget(monster);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
T_Damage(self->owner, inflictor, attacker, vec3_origin, self->owner->s.origin, vec3_origin, 100000, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
// if turret is being used as a camera by a player, turn camera off for that player
|
||||
for(i=0,player=g_edicts+1; i<maxclients->value; i++, player++) {
|
||||
if(player->client && player->client->spycam == self)
|
||||
for (i=0,player=g_edicts+1; i<maxclients->value; i++, player++) {
|
||||
if (player->client && player->client->spycam == self)
|
||||
camera_off(player);
|
||||
}
|
||||
if(self->deathtarget) {
|
||||
if (self->deathtarget) {
|
||||
edict_t *target;
|
||||
target = G_Find(NULL,FOFS(targetname),self->deathtarget);
|
||||
while(target) {
|
||||
if(target && target->use)
|
||||
while (target) {
|
||||
if (target && target->use)
|
||||
target->use(target,attacker,attacker);
|
||||
target = G_Find(target,FOFS(targetname),self->deathtarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(self->health <= self->gib_health) {
|
||||
if(self->destroytarget) {
|
||||
if(self->deadflag == DEAD_DEAD) {
|
||||
if (self->health <= self->gib_health)
|
||||
{
|
||||
if (self->destroytarget)
|
||||
{
|
||||
if (self->deadflag == DEAD_DEAD)
|
||||
{
|
||||
// we were already dead, so deathtarget has been fired
|
||||
edict_t *target;
|
||||
target = G_Find(NULL,FOFS(targetname),self->destroytarget);
|
||||
while(target) {
|
||||
if(target && target->use)
|
||||
while (target) {
|
||||
if (target && target->use)
|
||||
target->use(target,attacker,attacker);
|
||||
target = G_Find(target,FOFS(targetname),self->destroytarget);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// we were killed and gibbed in the same frame. postpone
|
||||
// destroytarget just a bit
|
||||
edict_t *temp;
|
||||
|
@ -1270,26 +1316,26 @@ void turret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damag
|
|||
self->nextthink = 0;
|
||||
gi.linkentity(self);
|
||||
}
|
||||
if(self->dmg > 0)
|
||||
if (self->dmg > 0)
|
||||
BecomeExplosion1(self);
|
||||
else
|
||||
G_FreeEdict(self);
|
||||
return;
|
||||
}
|
||||
if(self->deadflag == DEAD_DEAD)
|
||||
if (self->deadflag == DEAD_DEAD)
|
||||
return;
|
||||
self->deadflag = DEAD_DEAD;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
// slow turret down and level it... or for MD2 turrets set to minpitch
|
||||
self->speed /= 4;
|
||||
if(self->spawnflags & SF_TURRET_MD2)
|
||||
if (self->spawnflags & SF_TURRET_MD2)
|
||||
self->move_angles[0] = self->pos1[0];
|
||||
else
|
||||
self->move_angles[0] = 0;
|
||||
}
|
||||
void toggle_turret_breach (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if(!(self->spawnflags & SF_TURRET_INACTIVE))
|
||||
if (!(self->spawnflags & SF_TURRET_INACTIVE))
|
||||
{
|
||||
self->spawnflags |= SF_TURRET_INACTIVE;
|
||||
VectorCopy(self->s.angles,self->move_angles);
|
||||
|
@ -1314,11 +1360,11 @@ void toggle_turret_breach (edict_t *self, edict_t *other, edict_t *activator)
|
|||
|
||||
void use_turret_breach (edict_t *self, edict_t *other, edict_t *activator)
|
||||
{
|
||||
if(self->spawnflags & SF_TURRET_TRIGGER_SPAWN)
|
||||
if (self->spawnflags & SF_TURRET_TRIGGER_SPAWN)
|
||||
{
|
||||
self->spawnflags &= ~SF_TURRET_TRIGGER_SPAWN;
|
||||
self->svflags &= ~SVF_NOCLIENT;
|
||||
if(self->spawnflags & SF_TURRET_MD2)
|
||||
if (self->spawnflags & SF_TURRET_MD2)
|
||||
self->solid = SOLID_BBOX;
|
||||
else
|
||||
self->solid = SOLID_BSP;
|
||||
|
@ -1326,30 +1372,30 @@ void use_turret_breach (edict_t *self, edict_t *other, edict_t *activator)
|
|||
self->think(self);
|
||||
}
|
||||
}
|
||||
void turret_breach_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
void turret_breach_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
|
||||
{
|
||||
// This added for Lazarus to help prevent player from becoming stuck when
|
||||
// jumping onto a TRACK turret.
|
||||
|
||||
// We only care about TRACK turrets. For monster controlled turrets the angles
|
||||
// should of course be controlled by the monster.
|
||||
if(!(self->spawnflags & SF_TURRET_TRACKING))
|
||||
if (!(self->spawnflags & SF_TURRET_TRACKING))
|
||||
return;
|
||||
// We only care about players... everybody else knows better than to
|
||||
// get tangled up with turret :-)
|
||||
if(!other->client)
|
||||
if (!other->client)
|
||||
return;
|
||||
// Do nothing for turrets that already have an enemy
|
||||
if(self->enemy)
|
||||
if (self->enemy)
|
||||
return;
|
||||
if( (other->client) && (other->absmin[2] > self->s.origin[2]) ) {
|
||||
if( fabs(self->s.angles[PITCH] - self->pos1[PITCH]) <
|
||||
if ( (other->client) && (other->absmin[2] > self->s.origin[2]) ) {
|
||||
if ( fabs(self->s.angles[PITCH] - self->pos1[PITCH]) <
|
||||
fabs(self->s.angles[PITCH] - self->pos2[PITCH]) )
|
||||
self->move_angles[PITCH] = self->pos2[PITCH];
|
||||
else
|
||||
self->move_angles[PITCH] = self->pos1[PITCH];
|
||||
|
||||
if( fabs(self->s.angles[YAW] - self->pos1[YAW]) <
|
||||
if ( fabs(self->s.angles[YAW] - self->pos1[YAW]) <
|
||||
fabs(self->s.angles[YAW] - self->pos2[YAW]) )
|
||||
self->move_angles[YAW] = self->pos2[YAW];
|
||||
else
|
||||
|
@ -1362,7 +1408,7 @@ void SP_turret_breach (edict_t *self)
|
|||
self->class_id = ENTITY_TURRET_BREACH;
|
||||
|
||||
// Good guy turrets shoot at monsters, not players. Turn TRACK on if it ain't already
|
||||
if(self->spawnflags & SF_TURRET_GOODGUY)
|
||||
if (self->spawnflags & SF_TURRET_GOODGUY)
|
||||
self->spawnflags |= (SF_TURRET_TRACKING | SF_TURRET_INACTIVE);
|
||||
|
||||
if (self->spawnflags & SF_TURRET_MD2)
|
||||
|
@ -1400,7 +1446,7 @@ void SP_turret_breach (edict_t *self)
|
|||
else
|
||||
{
|
||||
self->solid = SOLID_BBOX;
|
||||
if(self->spawnflags & SF_TURRET_TRACKING)
|
||||
if (self->spawnflags & SF_TURRET_TRACKING)
|
||||
self->use = toggle_turret_breach;
|
||||
}
|
||||
}
|
||||
|
@ -1415,7 +1461,7 @@ void SP_turret_breach (edict_t *self)
|
|||
else
|
||||
{
|
||||
self->solid = SOLID_BSP;
|
||||
if(self->spawnflags & SF_TURRET_TRACKING)
|
||||
if (self->spawnflags & SF_TURRET_TRACKING)
|
||||
self->use = toggle_turret_breach;
|
||||
}
|
||||
gi.setmodel (self, self->model);
|
||||
|
@ -1443,10 +1489,11 @@ void SP_turret_breach (edict_t *self)
|
|||
if (!self->wait)
|
||||
self->wait = 2.0;
|
||||
|
||||
if(self->health) {
|
||||
if (self->health) {
|
||||
self->die = turret_die;
|
||||
self->takedamage = DAMAGE_YES;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
self->die = NULL;
|
||||
self->takedamage = DAMAGE_NO;
|
||||
}
|
||||
|
@ -1459,9 +1506,9 @@ void SP_turret_breach (edict_t *self)
|
|||
self->pos2[PITCH] = -1 * st.maxpitch;
|
||||
self->pos2[YAW] = st.maxyaw;
|
||||
|
||||
if(self->pos1[YAW] < 0)
|
||||
if (self->pos1[YAW] < 0)
|
||||
self->pos1[YAW] += 360;
|
||||
if(self->pos2[YAW] < 0)
|
||||
if (self->pos2[YAW] < 0)
|
||||
self->pos2[YAW] += 360;
|
||||
|
||||
self->ideal_yaw = self->s.angles[YAW];
|
||||
|
@ -1496,7 +1543,7 @@ void turret_base_finish(edict_t *self)
|
|||
{
|
||||
vec_t radius;
|
||||
|
||||
if(self->team) {
|
||||
if (self->team) {
|
||||
// should ALWAYS have a team, but we're being pessimistic here
|
||||
radius = (self->maxs[0] - self->mins[0])*(self->maxs[0] - self->mins[0]) +
|
||||
(self->maxs[1] - self->mins[1])*(self->maxs[1] - self->mins[1]) +
|
||||
|
@ -1514,11 +1561,12 @@ void SP_turret_base (edict_t *self)
|
|||
{
|
||||
self->class_id = ENTITY_TURRET_BASE;
|
||||
|
||||
if(self->spawnflags & SF_TURRET_TRIGGER_SPAWN) {
|
||||
if (self->spawnflags & SF_TURRET_TRIGGER_SPAWN) {
|
||||
self->svflags |= SVF_NOCLIENT;
|
||||
self->solid = SOLID_NOT;
|
||||
self->use = use_turret_base;
|
||||
} else
|
||||
}
|
||||
else
|
||||
self->solid = SOLID_BSP;
|
||||
|
||||
self->movetype = MOVETYPE_PUSH;
|
||||
|
@ -1546,12 +1594,12 @@ void turret_driver_die (edict_t *self, edict_t *inflictor, edict_t *attacker, in
|
|||
{
|
||||
edict_t *ent;
|
||||
|
||||
if(self->target_ent->inuse) {
|
||||
if (self->target_ent->inuse) {
|
||||
|
||||
// level the gun
|
||||
self->target_ent->move_angles[0] = 0;
|
||||
|
||||
if(self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)
|
||||
if (self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)
|
||||
// "remote" driver... turn off TRACK for turret
|
||||
self->target_ent->spawnflags &= ~SF_TURRET_TRACKING;
|
||||
else {
|
||||
|
@ -1616,10 +1664,10 @@ void turret_driver_think (edict_t *self)
|
|||
VectorCopy (self->enemy->s.origin, target);
|
||||
target[2] += self->enemy->viewheight;
|
||||
VectorSubtract (target, self->target_ent->s.origin, dir);
|
||||
if(self->target_ent->sounds == 7)
|
||||
if (self->target_ent->sounds == 7)
|
||||
{
|
||||
// grenade launcher
|
||||
if(!AimGrenade (self->target_ent, self->target_ent->s.origin, target, self->target_ent->fog_far, dir))
|
||||
if (!AimGrenade (self->target_ent, self->target_ent->s.origin, target, self->target_ent->fog_far, dir))
|
||||
{
|
||||
vectoangles (dir, self->target_ent->move_angles);
|
||||
return;
|
||||
|
@ -1631,14 +1679,14 @@ void turret_driver_think (edict_t *self)
|
|||
if (level.time < self->monsterinfo.attack_finished)
|
||||
return;
|
||||
|
||||
if(self->target_ent->sounds==5 || self->target_ent->sounds==6)
|
||||
if (self->target_ent->sounds==5 || self->target_ent->sounds==6)
|
||||
reaction_time = 0.;
|
||||
else
|
||||
reaction_time = max(0., (2-skill->value));
|
||||
if ((level.time - self->monsterinfo.trail_time) < reaction_time)
|
||||
return;
|
||||
|
||||
if(self->target_ent->sounds==5 || self->target_ent->sounds==6)
|
||||
if (self->target_ent->sounds==5 || self->target_ent->sounds==6)
|
||||
self->monsterinfo.attack_finished = level.time + FRAMETIME;
|
||||
else
|
||||
self->monsterinfo.attack_finished = level.time + reaction_time + 1.0;
|
||||
|
@ -1663,7 +1711,7 @@ void turret_driver_link (edict_t *self)
|
|||
}
|
||||
// DWH: REMOTE (=1) drivers aren't part of the turret team, and don't think
|
||||
// (the turret_breach thinks for them)
|
||||
if(!(self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)) {
|
||||
if (!(self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)) {
|
||||
self->think = turret_driver_think;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
self->target_ent->teammaster->owner = self;
|
||||
|
@ -1685,7 +1733,7 @@ void turret_driver_link (edict_t *self)
|
|||
// add the driver to the end of the team chain
|
||||
// DWH: REMOTE (=1) drivers don't move with turret, and the turret tracks
|
||||
// players
|
||||
if(self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)
|
||||
if (self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER)
|
||||
self->target_ent->spawnflags |= SF_TURRET_TRACKING;
|
||||
else {
|
||||
for (ent = self->target_ent->teammaster; ent->teamchain; ent = ent->teamchain)
|
||||
|
@ -1742,7 +1790,7 @@ void SP_turret_driver (edict_t *self)
|
|||
self->think = turret_driver_link;
|
||||
self->nextthink = level.time + FRAMETIME;
|
||||
|
||||
if(self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER) {
|
||||
if (self->spawnflags & SF_TURRETDRIVER_REMOTE_DRIVER) {
|
||||
// remote turret driver - go ahead and create his "real" infantry replacement
|
||||
// NOW so the switch won't be so time-consuming
|
||||
edict_t *infantry;
|
||||
|
|
|
@ -156,7 +156,7 @@ This is an internal support routine used for bullet/pellet based weapons.
|
|||
{
|
||||
vectoangles (aimdir, dir);
|
||||
AngleVectors (dir, forward, right, up);
|
||||
|
||||
|
||||
r = crandom()*hspread;
|
||||
u = crandom()*vspread;
|
||||
// Knightmare- adjust spread for expanded world size
|
||||
|
@ -254,8 +254,8 @@ This is an internal support routine used for bullet/pellet based weapons.
|
|||
gi.WriteDir (tr.plane.normal);
|
||||
gi.multicast (tr.endpos, MULTICAST_PVS);
|
||||
|
||||
if(level.num_reflectors)
|
||||
ReflectSparks(te_impact,tr.endpos,tr.plane.normal);
|
||||
if (level.num_reflectors)
|
||||
ReflectSparks (te_impact, tr.endpos, tr.plane.normal);
|
||||
|
||||
if (self->client)
|
||||
PlayerNoise(self, tr.endpos, PNOISE_IMPACT);
|
||||
|
@ -340,7 +340,7 @@ void blaster_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *
|
|||
return;
|
||||
}
|
||||
|
||||
if (self->owner->client)
|
||||
if (self->owner && self->owner->client)
|
||||
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
|
||||
|
||||
if (other->takedamage)
|
||||
|
@ -395,10 +395,10 @@ void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee
|
|||
edict_t *bolt;
|
||||
trace_t tr;
|
||||
|
||||
//Knightmare- only change color with blaster_color cvar if self is a player or actor
|
||||
qboolean color_changeable = false;
|
||||
if ( (self->client && !(self->flags & FL_TURRET_OWNER)) || !strcmp(self->classname, "target_actor"))
|
||||
color_changeable = true;
|
||||
// Knightmare- only change color with blaster_color cvar if self is a player or actor
|
||||
// qboolean color_changeable = false;
|
||||
// if ( (self->client && !(self->flags & FL_TURRET_OWNER)) || !strcmp(self->classname, "target_actor"))
|
||||
// color_changeable = true;
|
||||
|
||||
VectorNormalize (dir);
|
||||
|
||||
|
@ -417,17 +417,17 @@ void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee
|
|||
bolt->clipmask = MASK_SHOT;
|
||||
bolt->solid = SOLID_BBOX;
|
||||
bolt->s.effects |= effect;
|
||||
bolt->s.renderfx |= RF_NOSHADOW; //Knightmare- no shadow
|
||||
bolt->s.renderfx |= RF_NOSHADOW; // Knightmare- no shadow
|
||||
VectorClear (bolt->mins);
|
||||
VectorClear (bolt->maxs);
|
||||
|
||||
if (color == BLASTER_GREEN) //green
|
||||
if (color == BLASTER_GREEN) // green
|
||||
bolt->s.modelindex = gi.modelindex ("models/objects/laser2/tris.md2");
|
||||
else if (color == BLASTER_BLUE) //blue
|
||||
else if (color == BLASTER_BLUE) // blue
|
||||
bolt->s.modelindex = gi.modelindex ("models/objects/blaser/tris.md2");
|
||||
else if (color == BLASTER_RED) //red
|
||||
else if (color == BLASTER_RED) // red
|
||||
bolt->s.modelindex = gi.modelindex ("models/objects/rlaser/tris.md2");
|
||||
else //standard orange
|
||||
else // standard orange
|
||||
bolt->s.modelindex = gi.modelindex ("models/objects/laser/tris.md2");
|
||||
bolt->style = color;
|
||||
|
||||
|
@ -435,7 +435,7 @@ void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee
|
|||
|
||||
bolt->owner = self;
|
||||
bolt->touch = blaster_touch;
|
||||
bolt->nextthink = level.time + 2;
|
||||
bolt->nextthink = level.time + 4; // was 2
|
||||
bolt->think = G_FreeEdict;
|
||||
bolt->dmg = damage;
|
||||
bolt->classname = "bolt";
|
||||
|
@ -447,7 +447,7 @@ void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee
|
|||
check_dodge (self, bolt->s.origin, dir, speed);
|
||||
|
||||
tr = gi.trace (self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT);
|
||||
if (tr.fraction < 1.0)
|
||||
if (tr.fraction < 1.0 && !(self->flags & FL_TURRET_OWNER))
|
||||
{
|
||||
VectorMA (bolt->s.origin, -10, dir, bolt->s.origin);
|
||||
bolt->touch (bolt, tr.ent, NULL, NULL);
|
||||
|
@ -459,7 +459,7 @@ void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int spee
|
|||
// entities.
|
||||
void bolt_delayed_start (edict_t *bolt)
|
||||
{
|
||||
if(g_edicts[1].linkcount)
|
||||
if (g_edicts[1].linkcount)
|
||||
{
|
||||
VectorScale(bolt->movedir,bolt->moveinfo.speed,bolt->velocity);
|
||||
bolt->nextthink = level.time + 2;
|
||||
|
@ -505,27 +505,27 @@ void Grenade_Evade (edict_t *monster)
|
|||
// We assume on entry here that monster is alive and that he's not already
|
||||
// AI_CHASE_THING
|
||||
grenade = world->next_grenade;
|
||||
while(grenade)
|
||||
while (grenade)
|
||||
{
|
||||
// we only care about grenades on the ground
|
||||
if(grenade->inuse && grenade->groundentity)
|
||||
if (grenade->inuse && grenade->groundentity)
|
||||
{
|
||||
// if it ain't in the PVS, it can't hurt us (I think?)
|
||||
if(gi.inPVS(grenade->s.origin,monster->s.origin))
|
||||
if (gi.inPVS(grenade->s.origin,monster->s.origin))
|
||||
{
|
||||
VectorSubtract(grenade->s.origin,monster->s.origin,grenade_vec);
|
||||
grenade_dist = VectorNormalize(grenade_vec);
|
||||
if(grenade_dist <= grenade->dmg_radius)
|
||||
if (grenade_dist <= grenade->dmg_radius)
|
||||
break;
|
||||
}
|
||||
}
|
||||
grenade = grenade->next_grenade;
|
||||
}
|
||||
if(!grenade)
|
||||
if (!grenade)
|
||||
return;
|
||||
// Find best escape route.
|
||||
best_r = 9999;
|
||||
for(i=0; i<8; i++)
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
yaw = anglemod( i*45 );
|
||||
forward[0] = cos( DEG2RAD(yaw) );
|
||||
|
@ -533,18 +533,18 @@ void Grenade_Evade (edict_t *monster)
|
|||
forward[2] = 0;
|
||||
// Estimate of required distance to run. This is conservative.
|
||||
r = grenade->dmg_radius + grenade_dist*DotProduct(forward,grenade_vec) + monster->size[0] + 16;
|
||||
if( r < best_r )
|
||||
if ( r < best_r )
|
||||
{
|
||||
VectorMA(monster->s.origin,r,forward,pos);
|
||||
tr = gi.trace(monster->s.origin,monster->mins,monster->maxs,pos,monster,MASK_MONSTERSOLID);
|
||||
if(tr.fraction < 1.0)
|
||||
if (tr.fraction < 1.0)
|
||||
continue;
|
||||
best_r = r;
|
||||
best_yaw = yaw;
|
||||
VectorCopy(tr.endpos,best_pos);
|
||||
}
|
||||
}
|
||||
if(best_r < 9000)
|
||||
if (best_r < 9000)
|
||||
{
|
||||
edict_t *thing = SpawnThing();
|
||||
VectorCopy(best_pos,thing->s.origin);
|
||||
|
@ -1292,7 +1292,7 @@ void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick
|
|||
}
|
||||
else
|
||||
{
|
||||
// ZOID--added so rail goes through SOLID_BBOX entities (gibs, etc)
|
||||
//ZOID--added so rail goes through SOLID_BBOX entities (gibs, etc)
|
||||
if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client) ||
|
||||
(tr.ent->solid == SOLID_BBOX))
|
||||
ignore = tr.ent;
|
||||
|
@ -1422,7 +1422,7 @@ void bfg_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf
|
|||
gi.multicast (self->s.origin, MULTICAST_PVS);
|
||||
|
||||
if (level.num_reflectors)
|
||||
ReflectExplosion(TE_BFG_BIGEXPLOSION,self->s.origin);
|
||||
ReflectExplosion (TE_BFG_BIGEXPLOSION, self->s.origin);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue