|
1 | | -var __b__; |
2 | | -__b__ = action_if_number(obj_pnunit, 0, 2); |
3 | | -if __b__ |
4 | | -{ |
5 | | -{ |
6 | | - |
7 | | - |
8 | | - |
| 1 | +if (!instance_exists(obj_pnunit)) { |
| 2 | + exit; |
| 3 | +} |
9 | 4 |
|
10 | | -var leftest,charge=0,enemy2=0,chapter_fuck=1,unit; |
| 5 | +var leftest,charge=0,enemy2=0,target_unit_index=0,unit; |
11 | 6 |
|
12 | 7 | // with(obj_pnunit){if (x<-4000) or (defenses=1) then instance_deactivate_object(id);} |
13 | 8 |
|
@@ -41,174 +36,205 @@ else if (flank=1){ |
41 | 36 | } |
42 | 37 |
|
43 | 38 | //In melee check |
44 | | -engaged = point_distance(x,0,enemy.x,0)<=10 || !position_empty(x+flank?10:-10,y); |
| 39 | +engaged = collision_point(x-10, y, obj_pnunit, 0, 1) || collision_point(x+10, y, obj_pnunit, 0, 1); |
45 | 40 |
|
46 | | -//show_debug_message($"enemy is in melee {engaged}") |
| 41 | +// show_debug_message($"enemy is in melee {engaged}") |
| 42 | + |
| 43 | +if (!engaged){ // Shooting |
47 | 44 |
|
48 | | -if (!engaged){// Shooting |
49 | | - var i=0,dist=999,block=0; |
50 | | - dist=get_block_distance(enemy); |
51 | | - |
52 | | - var wall_exists=0; |
53 | | - if (instance_exists(obj_nfort)){ |
54 | | - wall_exists=1; |
55 | | - dist=2; |
56 | | - } |
57 | | - /*with(obj_pnunit){if (veh_type[1]="Defenses") then instance_create(x,y,obj_temp_inq);} |
58 | | - if (instance_exists(obj_temp_inq)){ |
59 | | - enemy=instance_nearest(obj_temp_inq.x,obj_temp_inq.y,obj_pnunit); |
60 | | - with(obj_temp_inq){instance_destroy();} |
61 | | - }*/ |
62 | 45 | if (!instance_exists(obj_pnunit)) then exit; |
63 | 46 |
|
64 | 47 | for (var i=0;i<array_length(wep);i++){ |
65 | | - if (wep[i]=="" || wep_num[i]==0) then continue; |
66 | | - chapter_fuck=1; |
67 | 48 | if (!instance_exists(obj_pnunit)) then exit; |
| 49 | + |
| 50 | + if (wep[i]=="" || wep_num[i]==0) { |
| 51 | + continue; |
| 52 | + } |
| 53 | + |
| 54 | + if ((range[i]==1) || (ammo[i]==0)) { |
| 55 | + // show_debug_message($"A melee or no ammo weapon was found! Weapon: {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}; Range: {range[i]}; Ammo: {ammo[i]}"); |
| 56 | + continue; |
| 57 | + } |
| 58 | + |
| 59 | + if ((range[i]==0)) { |
| 60 | + log_error($"{wep[i]} has broken range! This shouldn't happen! Range: {range[i]}; Ammo: {ammo[i]}; Owner: {wep_owner[i]}"); |
| 61 | + // show_debug_message($"A broken weapon was found! i:{i}; Weapon: {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}; Range: {range[i]}; Ammo: {ammo[i]}"); |
| 62 | + continue; |
| 63 | + } |
| 64 | + |
68 | 65 | if (!target_block_is_valid(enemy,obj_pnunit)){ |
69 | | - if (flank=0){ |
70 | | - enemy=get_rightmost(); |
71 | | - enemy2=enemy; |
72 | | - if (enemy=="none"){ |
73 | | - exit; |
74 | | - } |
75 | | - dist=get_block_distance(enemy); |
| 66 | + enemy = flank == 0 ? get_rightmost() : get_leftmost(); |
| 67 | + if (!target_block_is_valid(enemy,obj_pnunit)){ |
| 68 | + exit; |
76 | 69 | } |
77 | | - else if (flank=1){ |
78 | | - enemy=get_leftmost(); |
79 | | - enemy2=enemy; |
80 | | - if (enemy=="none"){ |
81 | | - exit; |
82 | | - } |
83 | | - dist=get_block_distance(enemy); |
84 | | - } |
85 | 70 | } |
86 | | - |
87 | | - if (target_block_is_valid(enemy,obj_pnunit)){ |
88 | | - block=0; |
89 | | - |
90 | | - if (instance_exists(obj_nfort)) and (obj_nfort.hp[1]>0){// Give the wall the melee D |
91 | | - enemy=instance_nearest(x,y,obj_nfort); |
92 | | - var bug1=instance_nearest(40,y,obj_enunit); |
93 | | - if (range[i]=1) and (bug1.id=self.id) then range[i]=2; |
94 | | - enemy2=enemy; |
95 | | - dist=2; |
96 | | - } |
| 71 | + |
| 72 | + dist=get_block_distance(enemy); |
| 73 | + target_unit_index=0; |
| 74 | + |
| 75 | + if (range[i] >= dist) { // The weapon is in range; |
| 76 | + var _target_vehicles = apa[i] > 0 ? true : false; // AP weapons target vehicles |
| 77 | + |
| 78 | + // if (string_count("Gauss",wep[i])>0) then _target_vehicles=true; |
| 79 | + // if (wep[i]="Missile Launcher") or (wep[i]="Rokkit Launcha") or (wep[i]="Kannon") then _target_vehicles=true; |
| 80 | + // if (wep[i]="Big Shoota") then _target_vehicles=false; |
| 81 | + // if (wep[i]="Devourer") then _target_vehicles=false; |
| 82 | + // if (wep[i]="Gauss Particle Cannon") or (wep[i]="Overcharged Gauss Cannon") or (wep[i]="Particle Whip") then _target_vehicles=true; |
97 | 83 |
|
98 | | - if (wep_num[i]>0) and (range[i]>=dist) and (range[i]!=1) and (combi[i]<2) and (ammo[i]!=0){// Weapon meets preliminary checks |
99 | | - |
100 | | - var _armour_piercing=0; |
101 | | - if (apa[i]>0) then _armour_piercing=1;// Determines if it is _armour_piercing or not |
102 | | - // if (string_count("Gauss",wep[i])>0) then _armour_piercing=1; |
103 | | - |
104 | | - // show_message(string(wep[i])+" is in range and _armour_piercing:"+string(_armour_piercing)); |
| 84 | + // Weird alpha strike mechanic, that changes target unit index to CM; |
| 85 | + if ((wep[i]="Power Fist") or (wep[i]="Bolter")) and (obj_ncombat.alpha_strike>0) and (wep_num[i]>5){ |
| 86 | + obj_ncombat.alpha_strike-=0.5; |
105 | 87 |
|
106 | | - if (wep[i]="Missile Launcher") or (wep[i]="Rokkit Launcha") or (wep[i]="Kannon") then _armour_piercing=1; |
107 | | - if (wep[i]="Big Shoota") then _armour_piercing=0; |
108 | | - if (wep[i]="Devourer") then _armour_piercing=0; |
109 | | - if (wep[i]="Gauss Particle Cannon") or (wep[i]="Overcharged Gauss Cannon") or (wep[i]="Particle Whip") then _armour_piercing=1; |
110 | | - |
111 | | - |
112 | | - |
113 | | - if ((wep[i]="Power Fist") or (wep[i]="Bolter")) and (obj_ncombat.alpha_strike>0) and (wep_num[i]>5){ |
114 | | - obj_ncombat.alpha_strike-=0.5; |
115 | | - |
116 | | - var cm_present = false; |
117 | | - var cm_index = -1; |
118 | | - var cm_block = false; |
119 | | - with(obj_pnunit){ |
120 | | - for (var u=0;u<array_length(unit_struct);u++){ |
121 | | - if (marine_type[u]="Chapter Master"){ |
122 | | - cm_present=true; |
123 | | - cm_index = u; |
124 | | - cm_block=id |
125 | | - } |
| 88 | + var cm_present = false; |
| 89 | + var cm_index = -1; |
| 90 | + var cm_block = false; |
| 91 | + with(obj_pnunit){ |
| 92 | + for (var u=0;u<array_length(unit_struct);u++){ |
| 93 | + if (marine_type[u]="Chapter Master"){ |
| 94 | + cm_present=true; |
| 95 | + cm_index = u; |
| 96 | + cm_block=id |
126 | 97 | } |
127 | 98 | } |
128 | | - if (cm_present){ |
129 | | - enemy=cm_block; |
130 | | - chapter_fuck=cm_index; |
131 | | - } |
132 | 99 | } |
133 | | - |
134 | | - |
135 | | - |
136 | | - if (_armour_piercing) and ((!instance_exists(obj_nfort)) or (flank)){// Check for vehicles |
137 | | - var enemy2,g=0,good=0; |
138 | | - |
| 100 | + if (cm_present){ |
| 101 | + enemy=cm_block; |
| 102 | + target_unit_index=cm_index; |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + |
| 107 | + // AP weapons attacking vehicles and forts; |
| 108 | + var _no_vehicles_present = false; |
| 109 | + if (_target_vehicles) { |
| 110 | + var _shot = false; |
| 111 | + if (!instance_exists(obj_nfort)) or (flank) { |
139 | 112 | if (block_has_armour(enemy)) or (enemy.veh_type[1]=="Defenses"){ |
140 | | - // good=scr_target(enemy,"veh");// First target has vehicles, blow it to hell |
141 | | - scr_shoot(i,enemy,chapter_fuck,"arp","ranged"); |
142 | | - } |
143 | | - if (!good) and (instance_number(obj_pnunit)>1) and (obj_ncombat.enemy!=7){// First target does not have vehicles, cycle through objects to find one that has vehicles |
| 113 | + scr_shoot(i,enemy,target_unit_index,"arp","ranged"); |
| 114 | + // show_debug_message($"I'm shooting at a vehicle! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 115 | + continue; |
| 116 | + } else if (instance_number(obj_pnunit)>1) and (obj_ncombat.enemy!=7) { |
144 | 117 | var x2=enemy.x; |
145 | 118 | repeat(instance_number(obj_pnunit)-1){ |
146 | | - if (good=0){ |
147 | | - if (flank=0) then x2-=10; |
148 | | - if (flank=1) then x2+=10; |
149 | | - enemy2=instance_nearest(x2,y,obj_pnunit); |
150 | | - if (enemy2.veh+enemy2.dreads>0) and (good=0){ |
151 | | - // good=scr_target(enemy2,"veh");// This target has vehicles, blow it to hell |
152 | | - scr_shoot(i,enemy2,chapter_fuck,"arp","ranged"); |
153 | | - } |
| 119 | + x2 += flank == 0 ? -10 : 10; |
| 120 | + var enemy2=instance_nearest(x2,y,obj_pnunit); |
| 121 | + if (!target_block_is_valid(enemy2, obj_pnunit)) { |
| 122 | + continue; |
| 123 | + } |
| 124 | + if (range[i] < get_block_distance(enemy2)) { |
| 125 | + break; |
| 126 | + } |
| 127 | + if (block_has_armour(enemy2)) { |
| 128 | + scr_shoot(i,enemy2,target_unit_index,"arp","ranged"); |
| 129 | + // show_debug_message($"I'm shooting at a vehicle in another row! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 130 | + _shot = true; |
| 131 | + break; |
154 | 132 | } |
155 | 133 | } |
| 134 | + if (!_shot) { |
| 135 | + _no_vehicles_present = true; |
| 136 | + _target_vehicles = false; |
| 137 | + } |
156 | 138 | } |
157 | | - if (good=0) then _armour_piercing=false;// Fuck it, shoot at infantry |
158 | | - } |
159 | | - if (_armour_piercing) and (instance_exists(obj_nfort)) and (!flank){// Huff and puff and blow the wall down |
| 139 | + } else { |
160 | 140 | enemy=instance_nearest(x,y,obj_nfort); |
161 | | - |
162 | | - scr_shoot(i,enemy,1,"arp","wall"); |
| 141 | + if (range[i] >= get_block_distance(enemy)) { |
| 142 | + scr_shoot(i,enemy,1,"arp","wall"); |
| 143 | + // show_debug_message($"I'm shooting at the fort! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 144 | + continue; |
| 145 | + } |
163 | 146 | } |
164 | | - |
165 | | - // if (wall_exists=0) or (flank=1) |
166 | | - |
167 | | - |
168 | | - if (string_count("Gauss",wep[i])) then _armour_piercing=false; |
169 | | - |
170 | | - // Shooting normal marines; |
171 | | - if ((!_armour_piercing) && ((!instance_exists(obj_nfort)) || flank) && instance_exists(obj_pnunit) && instance_exists(enemy)) { |
172 | | - if (enemy.men > 0) { |
173 | | - // There are marines in the first column; |
174 | | - if (target_block_is_valid(enemy, obj_pnunit)) { |
175 | | - scr_shoot(i, enemy, chapter_fuck, "att", "ranged"); |
| 147 | + } |
| 148 | + |
| 149 | + // Non-AP weapons attacking normal units; |
| 150 | + if ((!_target_vehicles) && ((!instance_exists(obj_nfort)) || flank)) { |
| 151 | + var _shot = false; |
| 152 | + if (enemy.men > 0) { |
| 153 | + // There are marines in the first column; |
| 154 | + scr_shoot(i, enemy, target_unit_index, "att", "ranged"); |
| 155 | + // show_debug_message($"I'm shooting at a normal unit! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 156 | + continue; |
| 157 | + } else if (instance_number(obj_pnunit) > 1) { |
| 158 | + // There were no marines in the first column, looking behind; |
| 159 | + var _column_size_value = (enemy.veh * 2.5) + (enemy.dreads * 2) + (enemy.men * 0.5); |
| 160 | + var x2 = enemy.x; |
| 161 | + |
| 162 | + repeat (instance_number(obj_pnunit) - 1) { |
| 163 | + x2 += !flank ? 10 : -10; |
| 164 | + var enemy2 = instance_nearest(x2, y, obj_pnunit); |
| 165 | + if (!target_block_is_valid(enemy2, obj_pnunit)) { |
| 166 | + // show_debug_message($"The block is invalid!"); |
176 | 167 | continue; |
177 | 168 | } |
178 | | - } else if (instance_number(obj_pnunit) > 1) { |
179 | | - if (enemy2.men > 0) { |
| 169 | + |
| 170 | + if (range[i] < get_block_distance(enemy2)) { |
| 171 | + // show_debug_message($"The range is bad!"); |
| 172 | + break; |
| 173 | + } |
| 174 | + |
| 175 | + var _back_column_size_value = (enemy2.veh * 2.5) + (enemy2.dreads * 2) + (enemy2.men * 0.5); |
| 176 | + if (_back_column_size_value < _column_size_value) { |
| 177 | + // show_debug_message($"Protection value is too big!"); |
180 | 178 | continue; |
| 179 | + } else { |
| 180 | + // Calculate chance of shots passing through to back row |
| 181 | + // Higher ratio of back column size to front column size increases pass-through chance |
| 182 | + // Maximum chance capped at 40% to ensure some protection remains |
| 183 | + var _pass_chance = ((_back_column_size_value / _column_size_value) - 1) * 100; |
| 184 | + if (irandom_range(1, 100) < min(_pass_chance, 80)) { |
| 185 | + // show_debug_message($"I failed the protection check!"); |
| 186 | + continue; |
| 187 | + } |
181 | 188 | } |
| 189 | + scr_shoot(i, enemy2, target_unit_index, "att", "ranged"); |
| 190 | + // show_debug_message($"I'm shooting at a normal unit in another row! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 191 | + _shot = true; |
| 192 | + break; |
| 193 | + } |
| 194 | + } |
182 | 195 |
|
183 | | - // There were no marines in the first column, looking behind; |
184 | | - var enemy2; |
185 | | - |
186 | | - var _column_size_value = (enemy.veh * 2.5) + (enemy.dreads * 2) + (enemy.men * 0.5); |
187 | | - var x2 = enemy.x; |
188 | | - x2 += !flank ? 10 : -10; |
189 | | - |
190 | | - repeat (instance_number(obj_pnunit) - 1) { |
191 | | - enemy2 = instance_nearest(x2, y, obj_pnunit); |
192 | | - |
193 | | - var _back_column_size_value = (enemy2.veh * 2.5) + (enemy2.dreads * 2) + (enemy2.men * 0.5); |
194 | | - if (_back_column_size_value < _column_size_value) { |
195 | | - continue; |
196 | | - } else { |
197 | | - // Calculate chance of shots passing through to back row |
198 | | - // Higher ratio of back column size to front column size increases pass-through chance |
199 | | - // Maximum chance capped at 60% to ensure some protection remains |
200 | | - var _pass_chance = ((_back_column_size_value / _column_size_value) - 1) * 100; |
201 | | - if (irandom_range(1, 100) > min(_pass_chance, 60)) { |
| 196 | + // We failed to find normal units to attack, attacking vehicles with a non-AP weapon; |
| 197 | + //TODO: All of these code blocks should be functions instead; |
| 198 | + if (!_shot && !_no_vehicles_present) { |
| 199 | + if (!instance_exists(obj_nfort)) or (flank) { |
| 200 | + if (block_has_armour(enemy)) or (enemy.veh_type[1]=="Defenses"){ |
| 201 | + scr_shoot(i,enemy,target_unit_index,"att","ranged"); |
| 202 | + // show_debug_message($"I'm shooting at a vehicle, because I can't find a normal unit! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 203 | + continue; |
| 204 | + } else if (instance_number(obj_pnunit)>1) and (obj_ncombat.enemy!=7) { |
| 205 | + var x2=enemy.x; |
| 206 | + repeat(instance_number(obj_pnunit)-1){ |
| 207 | + x2 += flank == 0 ? -10 : 10; |
| 208 | + var enemy2=instance_nearest(x2,y,obj_pnunit); |
| 209 | + if (!target_block_is_valid(enemy2, obj_pnunit)) { |
202 | 210 | continue; |
203 | 211 | } |
| 212 | + if (range[i] < get_block_distance(enemy2)) { |
| 213 | + break; |
| 214 | + } |
| 215 | + if (block_has_armour(enemy2)) { |
| 216 | + scr_shoot(i,enemy2,target_unit_index,"att","ranged"); |
| 217 | + // show_debug_message($"I'm shooting at a vehicle in another row, because I can't find a normal unit! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 218 | + break; |
| 219 | + } |
204 | 220 | } |
205 | | - |
206 | | - scr_shoot(i, enemy2, chapter_fuck, "att", "ranged"); |
| 221 | + } |
| 222 | + } else { |
| 223 | + enemy=instance_nearest(x,y,obj_nfort); |
| 224 | + if (range[i] >= get_block_distance(enemy)) { |
| 225 | + scr_shoot(i,enemy,1,"att","wall"); |
| 226 | + // show_debug_message($"I'm shooting at a fort, because I can't find a normal unit! {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
| 227 | + continue; |
207 | 228 | } |
208 | 229 | } |
209 | 230 | } |
210 | 231 | } |
| 232 | + } else { |
| 233 | + // show_debug_message($"I can't shoot, my range is too small! Weapon: {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}; Range: {range[i]}"); |
| 234 | + continue; |
211 | 235 | } |
| 236 | + log_error($"{wep[i]} didn't find a valid target! This shouldn't happen!"); |
| 237 | + // show_debug_message($"We didn't find a valid target! Weapon: {wep[i]}; Column ID: {id}; Enemy Unit: {wep_owner[i]}"); |
212 | 238 | } |
213 | 239 | } |
214 | 240 |
|
@@ -398,6 +424,4 @@ instance_activate_object(obj_pnunit); |
398 | 424 |
|
399 | 425 | /* */ |
400 | 426 | } |
401 | | -} |
402 | | -} |
403 | 427 | /* */ |
0 commit comments