qboolean medic_checkattack(edict_t * self) { if (self->monsterinfo.aiflags & AI_MEDIC) { medic_attack(self); return true; } return M_CheckAttack(self); }
qboolean parasite_checkattack (edict_t *self) { vec3_t f, r, offset, start, end; trace_t tr; qboolean retval; retval = M_CheckAttack (self); if (!retval) return false; AngleVectors (self->s.angles, f, r, NULL); VectorSet (offset, 24, 0, 6); G_ProjectSource (self->s.origin, offset, f, r, start); VectorCopy (self->enemy->s.origin, end); if (!parasite_drain_attack_ok(start, end)) { end[2] = self->enemy->s.origin[2] + self->enemy->maxs[2] - 8; if (!parasite_drain_attack_ok(start, end)) { end[2] = self->enemy->s.origin[2] + self->enemy->mins[2] + 8; if (!parasite_drain_attack_ok(start, end)) return false; } } VectorCopy (self->enemy->s.origin, end); tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT); if (tr.ent != self->enemy) { self->monsterinfo.aiflags |= AI_BLOCKED; if(self->monsterinfo.attack) self->monsterinfo.attack(self); self->monsterinfo.aiflags &= ~AI_BLOCKED; return true; } return true; // Knightmare- warning fix }
qboolean medic_checkattack (edict_t *self) { if (self->monsterinfo.aiflags & AI_MEDIC) { // if our target went away if ((!self->enemy) || (!self->enemy->inuse)) { // if (g_showlogic && g_showlogic->value) // gi.dprintf ("aborting heal target due to gib\n"); abortHeal (self, true, false, false); return false; } // if we ran out of time, give up if (self->timestamp < level.time) { // if (g_showlogic && g_showlogic->value) // gi.dprintf ("aborting heal target (%s) due to time\n", self->enemy->classname); abortHeal (self, true, false, true); self->timestamp = 0; return false; } if (realrange(self, self->enemy) < MEDIC_MAX_HEAL_DISTANCE+10) { medic_attack(self); return true; } else { self->monsterinfo.attack_state = AS_STRAIGHT; return false; } } if (self->enemy->client && !visible (self, self->enemy) && (self->monsterinfo.monster_slots > 2)) { self->monsterinfo.attack_state = AS_BLIND; return true; } // give a LARGE bias to spawning things when we have room // use AI_BLOCKED as a signal to attack to spawn if ((random() < 0.8) && (self->monsterinfo.monster_slots > 5) && (realrange(self, self->enemy) > 150)) { self->monsterinfo.aiflags |= AI_BLOCKED; self->monsterinfo.attack_state = AS_MISSILE; return true; } // ROGUE // since his idle animation looks kinda bad in combat, if we're not in easy mode, always attack // when he's on a combat point if (skill->value > 0) if (self->monsterinfo.aiflags & AI_STAND_GROUND) { self->monsterinfo.attack_state = AS_MISSILE; return true; } return M_CheckAttack (self); }
qboolean medic_checkattack (edict_t *self) { if (!(self->monsterinfo.aiflags & AI_MEDIC)) { if( medic_FindDeadMonster(self) ) return false; } if (self->monsterinfo.aiflags & AI_MEDIC) { float r; vec3_t forward, right, offset, start; trace_t tr; // if we have 5 seconds or less before a timeout, // look for a hint_path to the target if ( (self->timestamp < level.time + 5) && (self->monsterinfo.last_hint_time + 5 < level.time) ) { // check for hint_paths. self->monsterinfo.last_hint_time = level.time; if (hintcheck_monsterlost(self)) { if(developer->value) gi.dprintf("medic at %s using hint_paths to find %s\n", vtos(self->s.origin), self->enemy->classname); self->timestamp = level.time + MEDIC_TRY_TIME; return false; } } // if we ran out of time, give up if (self->timestamp < level.time) { //if(developer->value) // gi.dprintf("medic at %s timed out, abort heal\n",vtos(self->s.origin)); abortHeal (self, true); self->timestamp = 0; return false; } // if our target went away if ((!self->enemy) || (!self->enemy->inuse)) { abortHeal (self,false); return false; } // if target is embedded in a solid if (embedded(self->enemy)) { abortHeal (self,false); return false; } r = realrange(self,self->enemy); if (r > MEDIC_MAX_HEAL_DISTANCE+10) { self->monsterinfo.attack_state = AS_STRAIGHT; //abortHeal(self,false); return false; } else if(r < MEDIC_MIN_DISTANCE) { abortHeal(self,false); return false; } // Lazarus 1.6.2.3: if point-to-point vector from cable to // target is blocked by a solid AngleVectors (self->s.angles, forward, right, NULL); // Offset [8] has the largest displacement to the left... not a sure // thing but this one should be the most severe test. VectorCopy (medic_cable_offsets[8], offset); G_ProjectSource (self->s.origin, offset, forward, right, start); tr = gi.trace(start,NULL,NULL,self->enemy->s.origin,self,MASK_SHOT|MASK_WATER); if (tr.fraction < 1.0 && tr.ent != self->enemy) return false; medic_attack(self); return true; } // Lazarus: NEVER attack other monsters if ((self->enemy) && (self->enemy->svflags & SVF_MONSTER)) { self->enemy = self->oldenemy; self->oldenemy = NULL; if(self->enemy && self->enemy->inuse) { if(visible(self,self->enemy)) FoundTarget(self); else HuntTarget(self); } return false; } return M_CheckAttack (self); }