42 return 0.125 * (
int)x;
50 if (
other->takedamage) {
51 if (self->teammaster->owner)
52 attacker =
self->teammaster->owner;
54 attacker =
self->teammaster;
83 VectorMA(self->s.origin, self->move_origin[0], f, start);
84 VectorMA(start, self->move_origin[1], r, start);
85 VectorMA(start, self->move_origin[2], u, start);
87 damage = 100 +
random() * 50;
88 speed = 550 + 50 *
skill->value;
89 fire_rocket(self->teammaster->owner, start, f, damage, speed, 150, damage);
90 gi.positioned_sound(start,
self, CHAN_WEAPON,
gi.soundindex(
"weapons/rocklf1a.wav"), 1, ATTN_NORM, 0);
96 vec3_t current_angles;
99 VectorCopy(self->s.angles, current_angles);
103 if (self->move_angles[PITCH] > 180)
104 self->move_angles[PITCH] -= 360;
107 if (self->move_angles[PITCH] > self->pos1[PITCH])
108 self->move_angles[PITCH] =
self->pos1[PITCH];
109 else if (self->move_angles[PITCH] < self->pos2[PITCH])
110 self->move_angles[PITCH] =
self->pos2[PITCH];
112 if ((self->move_angles[YAW] < self->pos1[YAW]) || (self->move_angles[YAW] > self->pos2[YAW])) {
115 dmin = fabs(self->pos1[YAW] - self->move_angles[YAW]);
120 dmax = fabs(self->pos2[YAW] - self->move_angles[YAW]);
125 if (fabs(dmin) < fabs(dmax))
126 self->move_angles[YAW] =
self->pos1[YAW];
128 self->move_angles[YAW] =
self->pos2[YAW];
131 VectorSubtract(self->move_angles, current_angles, delta);
134 else if (delta[0] > 180)
138 else if (delta[1] > 180)
144 if (delta[0] < -1 * self->speed *
FRAMETIME)
148 if (delta[1] < -1 * self->speed *
FRAMETIME)
151 VectorScale(delta, 1.0 /
FRAMETIME, self->avelocity);
155 for (ent = self->teammaster; ent; ent = ent->teamchain)
156 ent->avelocity[1] =
self->avelocity[1];
167 self->owner->avelocity[0] =
self->avelocity[0];
168 self->owner->avelocity[1] =
self->avelocity[1];
171 angle =
self->s.angles[1] +
self->owner->move_origin[1];
172 angle *= (M_PI * 2 / 360);
173 target[0] =
SnapToEights(self->s.origin[0] + cos(angle) * self->owner->move_origin[0]);
174 target[1] =
SnapToEights(self->s.origin[1] + sin(angle) * self->owner->move_origin[0]);
175 target[2] =
self->owner->s.origin[2];
177 VectorSubtract(target, self->owner->s.origin, dir);
178 self->owner->velocity[0] = dir[0] * 1.0 /
FRAMETIME;
179 self->owner->velocity[1] = dir[1] * 1.0 /
FRAMETIME;
182 angle =
self->s.angles[PITCH] * (M_PI * 2 / 360);
183 target_z =
SnapToEights(self->s.origin[2] + self->owner->move_origin[0] * tan(angle) + self->owner->move_origin[2]);
185 diff = target_z -
self->owner->s.origin[2];
188 if (self->spawnflags & 65536) {
190 self->spawnflags &= ~65536;
199 gi.dprintf(
"%s at %s needs a target\n", self->classname,
vtos(self->s.origin));
202 VectorSubtract(self->target_ent->s.origin, self->s.origin, self->move_origin);
206 self->teammaster->dmg =
self->dmg;
213 self->solid = SOLID_BSP;
215 gi.setmodel(
self, self->model);
234 self->ideal_yaw =
self->s.angles[YAW];
235 self->move_angles[YAW] =
self->ideal_yaw;
252 self->solid = SOLID_BSP;
254 gi.setmodel(
self, self->model);
265 void infantry_die(edict_t *
self, edict_t *inflictor, edict_t *attacker,
int damage);
269 void turret_driver_die(edict_t *
self, edict_t *inflictor, edict_t *attacker,
int damage, vec3_t point)
274 self->target_ent->move_angles[0] = 0;
277 for (ent = self->target_ent->teammaster; ent->teamchain !=
self; ent = ent->teamchain)
279 ent->teamchain = NULL;
280 self->teammaster = NULL;
283 self->target_ent->owner = NULL;
284 self->target_ent->teammaster->owner = NULL;
299 if (self->enemy && (!self->enemy->inuse || self->enemy->health <= 0))
305 self->monsterinfo.trail_time =
level.
time;
308 if (
visible(
self, self->enemy)) {
310 self->monsterinfo.trail_time =
level.
time;
320 VectorCopy(self->enemy->s.origin, target);
321 target[2] +=
self->enemy->viewheight;
322 VectorSubtract(target, self->target_ent->s.origin, dir);
326 if (
level.
time < self->monsterinfo.attack_finished)
329 reaction_time = (3 -
skill->value) * 1.0;
330 if ((
level.
time - self->monsterinfo.trail_time) < reaction_time)
333 self->monsterinfo.attack_finished =
level.
time + reaction_time + 1.0;
335 self->target_ent->spawnflags |= 65536;
347 self->target_ent->owner =
self;
348 self->target_ent->teammaster->owner =
self;
349 VectorCopy(self->target_ent->s.angles, self->s.angles);
351 vec[0] =
self->target_ent->s.origin[0] -
self->s.origin[0];
352 vec[1] =
self->target_ent->s.origin[1] -
self->s.origin[1];
354 self->move_origin[0] = VectorLength(vec);
356 VectorSubtract(self->s.origin, self->target_ent->s.origin, vec);
359 self->move_origin[1] = vec[1];
361 self->move_origin[2] =
self->s.origin[2] -
self->target_ent->s.origin[2];
364 for (ent = self->target_ent->teammaster; ent->teamchain; ent = ent->teamchain)
366 ent->teamchain =
self;
367 self->teammaster =
self->target_ent->teammaster;
379 self->solid = SOLID_BBOX;
380 self->s.modelindex =
gi.modelindex(
"models/monsters/infantry/tris.md2");
381 VectorSet(self->mins, -16, -16, -24);
382 VectorSet(self->maxs, 16, 16, 32);
385 self->gib_health = 0;
387 self->viewheight = 24;
396 self->svflags |= SVF_MONSTER;
397 self->s.renderfx |= RF_FRAMELERP;
400 self->clipmask = MASK_MONSTERSOLID;
401 VectorCopy(self->s.origin, self->s.old_origin);
407 gi.dprintf(
"%s at %s has bad item: %s\n", self->classname,
vtos(self->s.origin),
st.
item);