Made for those who want a weapon like the Dragonfly missile system, but has functional multitargeting.
Code: Select all
<?xml version="1.0" ?>
<!DOCTYPE TranscendenceExtension
[
<!ENTITY unid912Multitarget "0xd912fffe">
<!ENTITY it912Multitarget "0xd912ffff">
]>
; Made for Transcendence v1.6.2 or later.
<TranscendenceExtension UNID="&unid912Multitarget;"
apiVersion="28"
name="Multitargeting Shotgun Tutorial"
credits="PM"
>
; Since we are using resources from the standard game, we need to include this library!
; Including libraries is the first thing we need to do before anything else in this file.
<Library unid="&unidHumanSpaceLibrary;"/>
; This weapon is a heavily modified version of the Dragonfly missile system.
; The weapon will be given for free at the start of a game.
; Value will be zero so that the player cannot sell for quick cash.
; We do not want this weapon to appear anywhere else.
; Frequency is notrandom, and attribute includes CannotOrder.
<ItemType UNID="&it912Multitarget;"
name= "multitargeting shotgun"
attributes= "cannotOrder, majorItem"
level= "5"
frequency= "notrandom"
value= "0"
mass= "2000"
description= "This weapon acquires a list of targets then fires up to five seekers at them."
>
<Image imageID="&rsItemsEI2;" imageX="96" imageY="288" imageWidth="96" imageHeight="96"/>
<Weapon
autoAcquireTarget= "true"
type= "missile"
damage= "blast:1d6+1; momentum:1; WMD:3"
fireRate= "40"
missilespeed= "50"
lifetime= "60"
maneuverRate= "12"
powerUse= "20"
sound= "&snRecoillessCannon;"
>
; Fires five times, needed to display (x5) in our stats.
<Configuration aimTolerance="5">
<Shot/> <Shot/> <Shot/> <Shot/> <Shot/>
</Configuration>
; Our missile appears as defined here.
<Effect>
<ParticleJet fixedPos="true" emitRate="20" tangentSpeed="3d3-2" particleLifetime="3-9" XformTime="10">
<ParticleEffect> <Particle style="plain" minWidth="1" maxWidth="3" primaryColor="#effeff" secondaryColor="#5b777a"/>
</ParticleEffect> </ParticleJet>
<Ray style="smooth" shape="diamond" primaryColor="#feffa1" secondaryColor="#f76e24" length="30" width="12" intensity="30"/>
</Effect>
</Weapon>
<Events>
; Called every time we fire our weapon.
<OnFireWeapon>
(block (shotCount)
; If not used previously, this will probably be Nil.
(setq shotCount (objGetData gSource "d912_Count"))
; ...if so, make it zero!
(if (not shotCount) (setq shotCount 0))
; Increment for the next shot in configuration, or roll over to zero after the fifth shot.
(objSetData gSource "d912_Count" (modulo (add shotCount 1) 5) )
; Check if we should fire our salvo.
(if (eq shotCount 0)
; YES: Fire all missiles. This happens at configuration's first shot.
(block (shotType theAttacker allTargets theSpeed objVel angleList missiles maxIndex)
; Remember who is the attacker. Here gSource is the attacker.
(setq theAttacker gSource)
; We will use this weapon's stats.
(setq shotType aWeaponType)
; Get our list of targets.
(if (and (eq gSource gPlayerShip) (objGetTarget gSource))
; YES: Playership may focus-fire all missiles at selected target.
; We do this by putting only the selected target on the list.
(setq allTargets (list (objGetTarget gSource)))
; NO: Find all nearby targets.
(block (theTarget)
; Our maximum missile range is 60. Look for enemies up to range 50.
; We filter our list because there is a bug that includes miners as enemies
; even if they do not appear to be angry.
(setq allTargets (filter
(sysFindObject gSource "s T A N:50 P S:d;")
thisOne
(or (objIsEnemy theAttacker thisOne)
(and (objIsAngryAt thisOne theAttacker) (neq (shpGetOrder thisOne) 'mine))
)
))
; Move primary target to the head of the hitlist.
(if (setq theTarget aTargetObj)
(setq allTargets (append
(list theTarget)
(filter allTargets thisTarget (neq thisTarget theTarget))
))
)
)
)
; Lookup missile speed once for reference so we don't need to do it each time we loop below.
(setq theSpeed (typGetProperty aWeaponType "speed"))
; Ditto for velocity.
(setq objVel (objGetVel gSource))
; List of angles, missiles begin at the center, then left, right, left, and right.
(setq angleList (list 0 15 345 30 330))
; Maximum number of shots per salvo.
(setq missiles (count angleList))
; We need this to ascend 'angleList' instead of descending it.
(setq maxIndex (subtract missiles 1))
; Launch all missiles.
(loop (gr missiles 0)
(if allTargets
; YES: Fire at our targets!
; We fire at least one missile, possibly up to the maximum of five, here!
; enumwhile ends when we use all targets or missiles, whichever comes first.
(enumwhile allTargets (gr missiles 0) who
(block (theFireAngle)
; Advance missile loop.
(setq missiles (subtract missiles 1))
; Get direction to aim at.
(setq theFireAngle (modulo 'degrees (add (@ angleList (subtract maxIndex missiles)) aFireAngle) 360) )
; Fire one missile at our target. Remember to inherit attacker's velocity.
(objIncVel (sysCreateWeaponFire shotType gSource aFirePos theFireAngle theSpeed who Nil aWeaponBonus) objVel)
)
)
; NO: No targets, fire one missile.
(block (theFireAngle)
; Comments above apply here too.
(setq missiles (subtract missiles 1))
(setq theFireAngle (modulo 'degrees (add (@ angleList (subtract maxIndex missiles)) aFireAngle) 360) )
(objIncVel (sysCreateWeaponFire shotType gSource aFirePos theFireAngle theSpeed aTargetObj Nil aWeaponBonus) objVel)
)
)
)
)
; NO: Do nothing now. This is configuration's shot two, three, four, and five!
)
; Either fired all missiles already or did nothing above, so return not-Nil.
0
)
</OnFireWeapon>
; Called when we start a new game, after ship select.
<OnGlobalUniverseCreated>
(block (newItem)
; Create our gift.
(setq newItem (itmCreate &it912Multitarget; 1))
; Add the new weapon to ship's cargo hold.
(objAddItem gPlayerShip newItem)
; Install the weapon.
(shpInstallDevice gPlayerShip newItem)
)
</OnGlobalUniverseCreated>
</Events>
</ItemType>
</TranscendenceExtension>