ai.qc (4580B)
1 //void() SUB_Remove = {remove(self);}; 2 3 //Search for targets 4 5 /* 6 ============= 7 range 8 9 returns the range categorization of an entity relative to self 10 0 melee range, will become hostile even if back is turned 11 1 visibility and infront, or visibility and show hostile 12 2 infront and show hostile 13 3 only triggered by damage 14 ============= 15 */ 16 float(entity targ) range = 17 { 18 local vector spot1, spot2; 19 local float r; 20 spot1 = self.origin + self.view_ofs; 21 spot2 = targ.origin + targ.view_ofs; 22 23 r = vlen (spot1 - spot2); 24 return r; 25 }; 26 27 /* 28 ============= 29 visible 30 31 returns 1 if the entity is visible to self, even if not infront () 32 ============= 33 */ 34 float (entity targ) visible = 35 { 36 local vector spot1, spot2; 37 38 spot1 = self.origin + self.view_ofs; 39 spot2 = targ.origin + targ.view_ofs; 40 traceline (spot1, spot2, TRUE, self); // see through other monsters 41 42 if (trace_inopen && trace_inwater) 43 return FALSE; // sight line crossed contents 44 45 if (trace_fraction == 1) 46 return TRUE; 47 return FALSE; 48 }; 49 50 51 /* 52 ============= 53 infront 54 55 returns 1 if the entity is in front (in sight) of self 56 ============= 57 */ 58 float(entity targ) infront = 59 { 60 local vector vec; 61 local float dot; 62 63 makevectors (self.angles); 64 vec = normalize (targ.origin - self.origin); 65 dot = vec * v_forward; 66 67 if ( dot > 0.3) 68 { 69 return TRUE; 70 } 71 return FALSE; 72 }; 73 74 75 //============================================================================ 76 77 /* 78 =========== 79 FindTarget 80 81 Self is currently not attacking anything, so try to find a target 82 83 Returns TRUE if an enemy was sighted 84 85 When a player fires a missile, the point of impact becomes a fakeplayer so 86 that monsters that see the impact will respond as if they had seen the 87 player. 88 89 To avoid spending too much time, only a single client (or fakeclient) is 90 checked each frame. This means multi player games will have slightly 91 slower noticing monsters. 92 ============ 93 */ 94 float() FindTarget = 95 { 96 local entity client; 97 local float r; 98 99 client = checkclient (); 100 if (!client) 101 return FALSE; // current check entity isn't in PVS 102 103 if (client == self.enemy) 104 return FALSE; 105 106 r = range (client); 107 if (r == 3) 108 return FALSE; 109 110 if (!visible (client)) 111 return FALSE; 112 113 if (r == 1) 114 { 115 if (/* client.show_hostile < time && */ !infront (client)) 116 return FALSE; 117 } 118 else if (r == 2) 119 { 120 if ( /* client.show_hostile < time || */ !infront (client)) 121 return FALSE; 122 } 123 124 // 125 // got one 126 // 127 self.enemy = client; 128 if (self.enemy.classname != "player") 129 { 130 self.enemy = self.enemy.enemy; 131 if (self.enemy.classname != "player") 132 { 133 self.enemy = world; 134 return FALSE; 135 } 136 } 137 self.goalentity = self.enemy; 138 self.think = self.th_run; 139 self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); 140 self.nextthink = time + 0.1; 141 // SUB_AttackFinished (1); // wait a while before first attack 142 143 return TRUE; 144 }; 145 146 //monster think functions 147 void () monster_think = 148 { 149 self.origin_z = self.origin_z + 1; 150 droptofloor(); 151 self.nextthink = time + 0.1; 152 FindTarget(); 153 } 154 155 156 void() monster_init = 157 { 158 //delay drop to floor 159 self.nextthink = time + 0.1; 160 self.think = monster_think; 161 } 162 163 void() ai_face = 164 { 165 self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); 166 ChangeYaw (); 167 }; 168 169 /* 170 ============= 171 ai_run 172 173 The monster has an enemy it is trying to kill 174 ============= 175 */ 176 void(float dist) ai_run = 177 { 178 // local vector delta; 179 // local float axis; 180 local float direct, ang_rint, ang_floor, ang_ceil; 181 local float enemy_vis, enemy_infront, enemy_range, enemy_yaw; 182 183 // movedist = dist; 184 // see if the enemy is dead 185 if (self.enemy.health <= 0) 186 { 187 self.enemy = world; 188 // FIXME: look all around for other targets 189 if (self.oldenemy.health > 0) 190 { 191 self.enemy = self.oldenemy; 192 // HuntTarget (); 193 } 194 else 195 { 196 // if (self.movetarget) 197 // self.th_walk (); 198 // else 199 // self.th_stand (); 200 // return; 201 } 202 } 203 204 // self.show_hostile = time + 1; // wake up other monsters 205 206 // check knowledge of enemy 207 enemy_vis = visible(self.enemy); 208 if (enemy_vis) 209 self.search_time = time + 5; 210 211 // look for other coop players 212 if (self.search_time < time) 213 { 214 if (FindTarget ()) 215 return; 216 } 217 218 enemy_infront = infront(self.enemy); 219 enemy_range = range(self.enemy); 220 enemy_yaw = vectoyaw(self.enemy.origin - self.origin); 221 222 self.ideal_yaw = enemy_yaw; 223 ChangeYaw (); 224 225 // head straight in 226 movetogoal (dist); // done in C code... 227 }; 228 229 void() ai_stand = 230 { 231 FindTarget (); 232 }