ubuntufreakdragon wrote: ↑Fri, 23. Nov 18, 12:47soll nee atf tm patr werden, was ist besonders ähnlich?
yaki !?
ubuntufreakdragon wrote: ↑Fri, 23. Nov 18, 12:47Hat vanilla ein vernünftiges kampfscript für m8?
ist immer das gleiche problem:
scripts können immer nur checken, ob ne missile ein gegner folgt oder nicht (missile = opfer -> find nearest missile aiming to me). oder du nimmst das ganze array und machst forschungsarbeiten daran ... was zu viel überflüssige arbeit ist, wenn es das "täter"-script macht
stell dir vor, 10 deiner M8 rechnen JEWEILS für 20 feinde arrays of missiles aus (gesamtschaden etwa). d.h. 200x loop über alle zufliegende raketen ... overkill (scripttechnisch).
MARS löst das gleiche problem bei seinem "attack-shields"-modus mut bullets, indem es n script auf opfer startet, welches den schaden sekündlich updated. läuft rund ... ähnliches ging für missiles auch, wenn sich ALLE schiffe ans "protokoll" halten (d.h. selbe fire-missile- @-target-script nutzen würden .. tun se aber nich
)
meine lösung (verbesserungswürdig), die ich mal gemacht hatte, kannst du dir ansehen ... kann dir schonmal sagen, dass sie aggro ist
das einzige, ums zu nutzen (in TC), ist, das gewöhnliche !turret.missileattack zu hooken, d.h. einfach unten stehendes script auf task xyz starten (wenn noch nicht gestartet) und loop-warten ... (aka nix tun, "idle"-n sozusagen)
Code: Select all
Script turret.missileattack.task
Version: 1
for Script Engine Version: 45
Description
Turret Missile Attack: controls all missile turrets of this ship
Arguments
Source Text
001
002 * --------------------------------------------------------------------------------
003
004 skip if [THIS] -> exists
005 |return null
006
007 skip if [THIS] -> is of class Moveable Ship
008 |return null
009
010 $No.Of.Launchers = 0
011 $Index.1 = [THIS] -> get number of turrets
012
013 while $Index.1 > 1
014 |dec $Index.1 =
015 |skip if [THIS] -> can turret $Index.1 fire missiles
016 ||continue
017 |$Index.2 = [THIS] -> get max. number of lasers in turret $Index.1
018 |$No.Of.Launchers = $No.Of.Launchers + $Index.2
019 end
020
021 skip if $No.Of.Launchers > 0
022 |return null
023
024 $Array.Compatible.Missiles = [THIS] -> get compatible missile array
025 skip if is datatype[ $Array.Compatible.Missiles ] == DATATYPE_ARRAY
026 |return null
027
028 $Index.1 = size of array $Array.Compatible.Missiles
029
030 while $Index.1 > 0
031 |dec $Index.1 =
032 |$Missile.Type = $Array.Compatible.Missiles[$Index.1]
033 |$Missile.Flags = get missile flags of $Missile.Type
034 |if [Missile.Dumbfire] == ( [Missile.Dumbfire] & $Missile.Flags )
035 ||remove element from array $Array.Compatible.Missiles at index $Index.1
036 |else if $Missile.Type == Boarding Pod
037 ||remove element from array $Array.Compatible.Missiles at index $Index.1
038 |end
039 end
040
041 $Index.1 = size of array $Array.Compatible.Missiles
042 skip if $Index.1 > 0
043 |return null
044
045 * --------------------------------------------------------------------------------
046
047 if $Index.1 > 1
048 |
049 |$Array.Sort.Values = array alloc: size=$Index.1
050 |
051 |while $Index.1 > 0
052 ||dec $Index.1 =
053 ||$Missile.Type = $Array.Compatible.Missiles[$Index.1]
054 ||$Missile.Range = get range of missile type $Missile.Type
055 ||$Array.Sort.Values[$Index.1] = $Missile.Range
056 |end
057 |
058 |$Array.Compatible.Missiles = sort array: data=$Array.Compatible.Missiles sort values=$Array.Sort.Values
059 |resize array $Array.Sort.Values to 0
060 |
061 end
062
063 $Array.Missiles.Defended = array alloc: size=0
064 $Array.Missiles.Timeout = array alloc: size=0
065
066 * --------------------------------------------------------------------------------
067
068 *$Index.1 = script engine version
069 *$Game.Is.X3AP = $Index.1 > 50
070
071 $Array.Missile.Turrets = array alloc: size=0
072 $Index.1 = [THIS] -> get number of turrets
073
074 while $Index.1 > 1
075 |dec $Index.1 =
076 |skip if [THIS] -> can turret $Index.1 fire missiles
077 ||continue
078 |skip if not [THIS] -> get max. number of lasers in turret $Index.1
079 ||append $Index.1 to array $Array.Missile.Turrets
080 end
081
082 $Time.Check.Scripts = -1
083 $Time.Check.Available.Missiles = -1
084
085 @ = wait 2000 ms
086
087 * --------------------------------------------------------------------------------
088
089 while not is a new script version available
090 |
091 |$Time = playing time
092 |gosub Check.Scripts
093 |
094 |if not [THIS] -> is in active sector
095 ||gosub Idle
096 ||continue
097 |else if [THIS] -> is docked
098 ||gosub Idle
099 ||continue
100 |end
101 |
102 |gosub Check.Available.Missiles
103 |if not $Missiles.Available
104 ||gosub Idle
105 ||continue
106 |end
107 |
108 |$Distance.Missile.Defence = 9999
109 |$Missile.Damage.Min = [THIS] -> get current shield strength
110 |$Missile.Damage.Min = ( $Missile.Damage.Min * 3 ) / 100
111 |$Missile.Defensive.Swarm.Allowed = [FALSE]
112 |$Missile.Count.Limit = 40
113 |
114 |$Missile = [THIS] -> find nearest missile aiming to me
115 |if $Missile -> exists
116 ||$Missile.Distance = get distance between $Missile and [THIS]
117 ||skip if not $Missile.Distance < $Distance.Missile.Defence
118 |||gosub Missile.Defence
119 |else
120 ||resize array $Array.Missiles.Defended to 0
121 ||resize array $Array.Missiles.Timeout to 0
122 |end
123 |
124 |$Scanner.Range = [THIS] -> get scanner range
125 |skip if not [THIS] -> find nearest enemy ship: max.dist=$Scanner.Range
126 ||gosub Attack.Enemies
127 |
128 @ |= wait randomly from 3000 to 7000 ms
129 |
130 end
131
132 return null
133
134 * --------------------------------------------------------------------------------
135
136 Check.Scripts:
137
138 skip if $Time > $Time.Check.Scripts
139 |endsub
140
141 $Index.1 = random value from 60 to 120 - 1
142 $Time.Check.Scripts = $Time + $Index.1
143
144 $Script = [FALSE]
145 $Index.1 = [THIS] -> get number of turrets
146
147 while $Index.1 > 1 AND ! $Script
148 @ |= wait 200 ms
149 |dec $Index.1 =
150 |skip if not [THIS] -> can turret $Index.1 fire missiles
151 ||$Script = [THIS] -> is script '!turret.missileattack' on stack of task=$Index.1
152 end
153
154 skip if $Script
155 |return null
156
157 endsub
158
159 * --------------------------------------------------------------------------------
160
161 Check.Available.Missiles:
162
163 if $Missiles.Available
164 |skip if $Time > $Time.Check.Available.Missiles
165 ||endsub
166 end
167
168 $Index.1 = random value from 60 to 120 - 1
169 $Time.Check.Available.Missiles = $Time + $Index.1
170
171 $Missiles.Available = [FALSE]
172 $Index.1 = size of array $Array.Compatible.Missiles
173
174 while $Index.1 > 0 AND ! $Missiles.Available
175 @ |= wait 200 ms
176 |dec $Index.1 =
177 |$Missile.Type = $Array.Compatible.Missiles[$Index.1]
178 |$Missiles.Available = [THIS] -> get amount of ware $Missile.Type in cargo bay
179 end
180
181 endsub
182
183 * --------------------------------------------------------------------------------
184
185 Idle:
186
187 @ = wait randomly from 10000 to 15000 ms
188
189 endsub
190
191 * --------------------------------------------------------------------------------
192
193 Missile.Defence:
194
195 $Missile.Defensive = null
196 $Array.Missiles.Incoming = [THIS] -> get array of missiles aiming to me
197 $Index.1 = size of array $Array.Missiles.Incoming
198
199 while $Index.1 > 0
200 @ |= wait 200 ms
201 |dec $Index.1 =
202 |
203 |$Missile = $Array.Missiles.Incoming[$Index.1]
204 |skip if $Missile -> exists
205 ||continue
206 |$Missile.Distance = get distance between $Missile and [THIS]
207 |skip if $Missile.Distance < $Distance.Missile.Defence
208 ||continue
209 |
210 |$Missile.Type = $Missile -> get ware type code of object
211 |$Missile.Damage = get missile max damage of $Missile.Type
212 |skip if $Missile.Damage > $Missile.Damage.Min
213 ||continue
214 |
215 |$Missile.Flags = get missile flags of $Missile.Type
216 |skip if [Missile.Dumbfire] != ( [Missile.Dumbfire] & $Missile.Flags )
217 ||continue
218 |
219 |if find $Missile in array: $Array.Missiles.Defended
220 ||$Time = playing time
221 ||$Index.2 = get index of $Missile in array $Array.Missiles.Defended offset=-1 + 1
222 ||$Time.Missile.Defended = $Array.Missiles.Timeout[$Index.2]
223 ||skip if $Time > $Time.Missile.Defended
224 |||continue
225 ||remove element from array $Array.Missiles.Defended at index $Index.2
226 ||remove element from array $Array.Missiles.Timeout at index $Index.2
227 |end
228 |
229 |if not $Missile.Defensive
230 ||gosub Select.Missile.Defensive
231 |else if not [THIS] -> get amount of ware $Missile.Defensive in cargo bay
232 ||gosub Select.Missile.Defensive
233 |end
234 |skip if $Missile.Defensive
235 ||continue
236 |
237 |if $Missile -> exists
238 ||$Index.2 = size of array $Array.Missile.Turrets
239 ||$Index.2 = random value from 0 to $Index.2 - 1
240 ||$Turret.ID = $Array.Missile.Turrets[$Index.2]
241 ||if [THIS] -> fire missile $Missile.Defensive from turret $Turret.ID on $Missile
242 |||$Time = playing time
243 |||$Index.2 = get bullet speed of laser $Missile.Defensive
244 |||$Missile.Type = $Missile -> get ware type code of object
245 |||$Missile.Speed = get bullet speed of laser $Missile.Type
246 |||$Missile.Speed = ( ( $Missile.Speed + $Index.2 ) * 90 ) / 100
247 |||$Missile.Distance = get distance between $Missile and [THIS]
248 |||$Time.Missile.Defended = $Time + 1 + $Missile.Distance / $Missile.Speed
249 |||append $Missile to array $Array.Missiles.Defended
250 |||append $Time.Missile.Defended to array $Array.Missiles.Timeout
251 ||end
252 |end
253 |
254 |skip if not $Missile.Defensive.Temporary
255 ||$Missile.Defensive = null
256 |
257 @ |= wait 200 ms
258 |
259 end
260
261 resize array $Array.Missiles.Incoming to 0
262
263 endsub
264
265 * --------------------------------------------------------------------------------
266
267 Select.Missile.Defensive:
268
269 $Missile.Defensive = null
270 $Best.Value = 999999999
271 $Index.2 = size of array $Array.Compatible.Missiles
272
273 while $Index.2 > 0
274 @ |= wait 200 ms
275 |dec $Index.2 =
276 |
277 |$Missile.Type = $Array.Compatible.Missiles[$Index.2]
278 |skip if [THIS] -> get amount of ware $Missile.Type in cargo bay
279 ||continue
280 |
281 |$Missile.Range = get range of missile type $Missile.Type
282 |skip if $Missile.Range > $Missile.Distance
283 ||break
284 |
285 |$Missile.Flags = get missile flags of $Missile.Type
286 |if not $Missile.Defensive.Swarm.Allowed
287 ||skip if [Missile.Swarm] != ( [Missile.Swarm] & $Missile.Flags )
288 |||continue
289 |end
290 |
291 |$Missile.Price = get average price of ware $Missile.Type
292 |skip if $Missile.Price < $Best.Value
293 ||continue
294 |
295 |$Best.Value = $Missile.Price
296 |$Missile.Defensive = $Missile.Type
297 |
298 end
299
300 skip if $Missile.Defensive
301 |endsub
302
303 $Missile.Range = get range of missile type $Missile.Defensive
304 $Missile.Defensive.Temporary = $Missile.Range < $Distance.Missile.Defence
305
306 endsub
307
308 * --------------------------------------------------------------------------------
309
310 Attack.Enemies:
311
312 $Find.Flags = [Find.Enemy] | [Find.Nearest] | [Find.Multiple]
313 $Array.Enemies = find ship: sector=[SECTOR] class or type=Moveable Ship race=null flags=$Find.Flags refobj=[THIS] maxdist=$Scanner.Range maxnum=10 refpos=null
314
315 skip if is datatype[ $Array.Enemies ] == DATATYPE_ARRAY
316 |endsub
317
318 $Index.1 = size of array $Array.Enemies
319
320 while $Index.1 > 0
321 @ |= wait 200 ms
322 |dec $Index.1 =
323 |
324 |$Enemy = $Array.Enemies[$Index.1]
325 |gosub Check.Enemy
326 |skip if $Enemy
327 ||continue
328 |
329 |$Enemy.Distance = get distance between $Enemy and [THIS]
330 |$Enemy.Speed = $Enemy -> get current max speed
331 |$Enemy.Shields = $Enemy -> get current shield strength
332 |$Enemy.Hull = $Enemy -> get hull
333 |$Enemy.Strength = $Enemy.Shields + $Enemy.Hull
334 |
335 |gosub Get.Missile.For.Target
336 |skip if $Missile.For.Enemy
337 ||continue
338 |
339 |$Missile.Count = $Missile.Count.Min + 1
340 |
341 |while $Missile.Count > 0
342 @ ||= wait 200 ms
343 ||dec $Missile.Count =
344 ||skip if $Enemy -> exists
345 |||break
346 ||skip if [THIS] -> is $Enemy a enemy
347 |||break
348 ||$Index.2 = size of array $Array.Missile.Turrets
349 ||$Index.2 = random value from 0 to $Index.2 - 1
350 ||$Turret.ID = $Array.Missile.Turrets[$Index.2]
351 ||skip if [THIS] -> fire missile $Missile.For.Enemy from turret $Turret.ID on $Enemy
352 |||break
353 |end
354 |
355 end
356
357 resize array $Array.Enemies to 0
358
359 endsub
360
361 * --------------------------------------------------------------------------------
362
363 Check.Enemy:
364
365 if not $Enemy -> exists
366 |$Enemy = null
367 else if not [THIS] -> is $Enemy a enemy
368 |$Enemy = null
369 else if not [THIS] -> has same environment as $Enemy
370 |$Enemy = null
371 else
372 |$Missile = $Enemy -> find nearest missile aiming to me
373 |skip if not $Missile -> exists
374 ||$Enemy = null
375 end
376
377 endsub
378
379 * --------------------------------------------------------------------------------
380
381 Get.Missile.For.Target:
382
383 $Missile.For.Enemy = null
384 $Missile.Count.Min = 999999999
385 $Best.Value = 999999999
386 $Index.2 = size of array $Array.Compatible.Missiles
387
388 while $Index.2 > 0
389 @ |= wait 200 ms
390 |dec $Index.2 =
391 |
392 |$Missile.Type = $Array.Compatible.Missiles[$Index.2]
393 |$Missile.Count.Available = [THIS] -> get amount of ware $Missile.Type in cargo bay
394 |skip if $Missile.Count.Available > 0
395 ||continue
396 |
397 |$Missile.Range = get range of missile type $Missile.Type
398 |skip if $Missile.Range > $Enemy.Distance
399 ||break
400 |
401 |$Missile.Speed = get bullet speed of laser $Missile.Type
402 |skip if $Missile.Speed > $Enemy.Speed
403 ||continue
404 |
405 |$Missile.Damage = get missile max damage of $Missile.Type
406 |$Missile.Flags = get missile flags of $Missile.Type
407 |skip if [Missile.Swarm] != ( [Missile.Swarm] & $Missile.Flags )
408 ||$Missile.Damage = $Missile.Damage * 8
409 |
410 |$Missile.Count = $Enemy.Strength / $Missile.Damage + 1
411 |skip if $Missile.Count < $Missile.Count.Limit
412 ||continue
413 |
414 |skip if $Missile.Count < $Missile.Count.Available
415 ||$Missile.Count = $Missile.Count.Available
416 |skip if $Missile.Count < $No.Of.Launchers
417 ||$Missile.Count = $No.Of.Launchers
418 |$Missile.Damage.Overkill = ( $Missile.Count * $Missile.Damage ) - $Enemy.Strength
419 |
420 |skip if $Missile.Count < $Missile.Count.Min
421 ||continue
422 |
423 |skip if $Missile.Damage.Overkill < $Best.Value
424 ||continue
425 |
426 |$Missile.Count.Min = $Missile.Count
427 |$Best.Value = $Missile.Damage.Overkill
428 |$Missile.For.Enemy = $Missile.Type
429 |
430 end
431
432 endsub
433
434 * --------------------------------------------------------------------------------
435
436 return null
das beste wär, n opfer-task auf jedem enemy zu starten, welchen in nem lokalen array schadenswerte, impact-zeitpunkte, konstant sagenwir mal alle 3-5 sekunden update-t, sodass das neue script (welches erst noch geschrieben werden müsst! geht aber in wenigen ingame-h) weiß, wieviel feuerkraft / missiles abzufeuern sind. meine erfahrung: bestmögliche ergebnisse erreicht man, indem man vordefinierte arrays mit "geeigneten" raketentypen für verschiedene feindtypen erstellt und dann je nach feind (klasse, schilde+hülle, speed, verteidigungs-turret-zahl etc) das vordefinierte array abarbeitet, d.h. ne rakete wählt, und dann loslgegt. (sind nämlich immer dieselben berechnungen, die bei der auswahl gemacht werden, warum also nicht global einmalig bei setup cache-n ?!
)
Vorteil: script-typ-unabhängig, funktioniert wie geplant ohne vanilla-scripts zu ändern
zu implementierende features:
-- raketenverteidigung (misquito?) als task
-- greife feinde an als task
-- zu-spam-attacke aller schiffe auf "endgegner" (raketen von all deinen schiffen) incl hotkey
-- menü für details, ggf zur manipulierung der globalen "preferenz-raketen-listen" usw (zu ignorierende feinde, umstände, enemy-class-filter)
-- opfer-task zählt incoming damage regelmäßig
-- ggf OOS-modus (weißt ja, OOS trifft missile immer)
-- AL-plugin zum tunen der feinde evtl noch ...
-- black-jack-kartenspiel ggf wenns langweilig wird ^^