Creating a single-shot missile: OnFireWeapon help?

Freeform discussion about anything related to modding Transcendence.
Post Reply
TheLastBrunnenG
Commonwealth Pilot
Commonwealth Pilot
Posts: 86
Joined: Fri Dec 04, 2009 1:46 am

Trying to make a version of the DM600 (itDisposableLauncher) that will uninstall and delete itself once its missiles are expended. I'm pretty good at causing a crash to desktop, that's for sure. What am I missing?

Code: Select all

<?xml version="1.0" ?>
<!DOCTYPE TranscendenceExtension
[

<!ENTITY unidExtension			"0xD001A499">

]>

<TranscendenceExtension UNID="&unidExtension;" version="0.99c">


	<!-- DM600 Missile Rack -->

	<ItemType UNID="&itDisposableLauncher;"
			name=				"DM600 disposable missile rack"
			level=				"1"
			value=				"360"
			mass=				"1000"
			frequency=			"uncommon"
			modifiers=			"MajorItem; NAMI"

			charges=			"16"
			valueCharges=		"true"

			description=		"This disposable weapon system is loaded with sixteen KM100 missiles. The weapon can be installed and uninstalled without the aid of a station."
			>

		<Image imageID="&rsItems1;" imageX="0" imageY="480" imageWidth="96" imageHeight="96"/>

		<Weapon
				type=				"missile"
				launcher=			"true"

				damage=				"blast:4d6; momentum4; WMD5"
				fireRate=			"30"
				hitPoints=			"15"
				lifetime=			"120"
				powerUse=			"2"
				charges=			"true"

				directional=		"true"
				missileSpeed=		"40"
				sound=				"&snMissileLauncher;"

				vaporTrailLength=	"16"
				vaporTrailWidth=	"110"
				vaporTrailWidthInc=	"5"
				vaporTrailColor=	"0xd0, 0xd0, 0xd0"
				>

			<Effect>
				<Image imageID="&rsMissiles2;" imageX="0" imageY="0" imageWidth="32" imageHeight="32" imageFrameCount="0" imageTicksPerFrame="0"/>
			</Effect>

			<HitEffect
					sound="&snArmorHit1;"
					>
				<Image imageID="&rsExplosionsAG48;"
						imageX="0"
						imageY="0"
						imageWidth="48"
						imageHeight="48"
						imageFrameCount="16"
						imageTicksPerFrame="2"/>
			</HitEffect>
		</Weapon>

		<Events>
			<OnFireWeapon>
				(if (leq (itmGetCharges gItem) 0)
					(block Nil
						(shpRemoveDevice gPlayerShip gItem)
						(objRemoveItem gPlayerShip (itmCreate &itDisposableLauncher; 1))
						)
					)
			</OnFireWeapon>
		</Events>

		<Invoke>
			(intAutoInstall gSource gItem)
		</Invoke>
	</ItemType>


</TranscendenceExtension>

And here's the CTD debug log:
Unable to continue due to program error

program state: updating object
obj class: CShip
obj name: Defiant-class gunship
obj pointer: 2c11800
CPlayerShipController
m_pStation: none
m_pTarget: none
m_pDestination: none
game state: in game
Ideas?
Last edited by TheLastBrunnenG on Sat Feb 13, 2010 5:29 am, edited 1 time in total.
Vaiyo A-O
A Home Va Ya Ray
Vaiyo A-Rah
Jerhume Brunnen G
ImageImage
User avatar
Atarlost
Fleet Admiral
Fleet Admiral
Posts: 2391
Joined: Tue Aug 26, 2008 12:02 am

I suspect it's simply impossible to uninstall gItem in onFireWeapon without crashing the game.
Bobby
Militia Captain
Militia Captain
Posts: 675
Joined: Wed Jul 25, 2007 7:39 pm

Try an onUpdate.
TheLastBrunnenG
Commonwealth Pilot
Commonwealth Pilot
Posts: 86
Joined: Fri Dec 04, 2009 1:46 am

Replacing OnFireWeapon with OnUpdate almost works. It will uninstall the now-empty launcher correctly. But the following line:

(objRemoveItem gPlayerShip (itmCreate &itDisposableLauncher; 1))

tries to remove all of the launchers, not just the empty one. Maybe I'm going about this the wrong way. If this worked, the ultimate goal was to create a single-shot missile. I figured if I could create a DM600 with only 1 charge, then it would work just as well.

I also tried creating an item then calling sysCreateWeaponFire from within the <Invoke> but it crashed every time.
Vaiyo A-O
A Home Va Ya Ray
Vaiyo A-Rah
Jerhume Brunnen G
ImageImage
Bobby
Militia Captain
Militia Captain
Posts: 675
Joined: Wed Jul 25, 2007 7:39 pm

Code: Select all

(objRemoveItem gPlayerShip (itmCreate &itDisposableLauncher; 1) 1) 
remove one of the item

the problem I see is how do you know it removes the empty one and not a charged one?

Code: Select all

 (objRemoveItem gPlayerShip (shpRemoveDevice gPlayerShip gItem))
the objRemovItem deletes the item placed in the cargo hold by shpRemoveDevice. Just a theory, it may or may not work.
User avatar
Prophet
Militia Captain
Militia Captain
Posts: 826
Joined: Tue Nov 18, 2008 6:09 pm

I think you'll need some code to iterate over all the installed weapons, find the proper disposable launcher that matches the unid, make sure it has 0 charges and then remove that one.

It's more code but then you will know for sure that you're removing the weapon that you intended to.
Coming soon: The Syrtian War adventure mod!
A Turret defense genre mod exploring the worst era in Earth's history.
Can you defend the Earth from the Syrtian invaders?
Stay tuned for updates!
User avatar
Xephyr
Militia Captain
Militia Captain
Posts: 857
Joined: Fri Dec 14, 2007 1:52 am
Location: Orion Arm, Milky Way
Contact:

God dammit. So I'm not the first to think if it.

*crumples XML file, throws in trash*

Welp, going to try to be original again, brb.
Project Renegade (Beta) : "The Poor Man's Corporate Command!"
Real programmers count from 0. And sometimes I do, too.
TheLastBrunnenG
Commonwealth Pilot
Commonwealth Pilot
Posts: 86
Joined: Fri Dec 04, 2009 1:46 am

Almost got it! Changed from a 1-charge version of the DM600 to an Invokeable item. Now it *almost* works:

Code: Select all

<!-- SSM2 -->

<ItemType UNID="&itSSM2;"
		name=				"single shot missile"
		level=				"3"
		value=				"200"
		mass=				"100"
		frequency=			"uncommon"
		modifiers=			"MajorItem"

		description=		"Single-shot missile test item ."
		>

	<Image imageID="&rsItems1;" imageX="0" imageY="192" imageWidth="96" imageHeight="96"/>

		<Invoke>
			(block (objVel)
				(setq objVel (objGetVel gSource))
				(sysCreateWeaponFire 
					&itLamplighter;
					gSource
					(objGetPos gSource)
					(sysVectorAngle objVel)
					60
					Nil
					)
				(objRemoveItem gSource gItem 1)
				)
		</Invoke>

</ItemType>
Problem is in the (sysVectorAngle objVel) bit. If you're traveling normally, it works great. But, if you're hit by even the slightest physical-weapon damage - ecen a Centauri Light Recoilless - your vector changes a tiny, tiny bit and THAT's the angle the shot fires from! Very annoying to use when under fire. I tried aFireAngle instead and got a "no binding" error. Any ideas?


Xephyr wrote:God dammit. So I'm not the first to think if it.
*crumples XML file, throws in trash*
Welp, going to try to be original again, brb.
Don't quit! Mine's not working yet, maybe you'll have more luck.
Vaiyo A-O
A Home Va Ya Ray
Vaiyo A-Rah
Jerhume Brunnen G
ImageImage
User avatar
Atarlost
Fleet Admiral
Fleet Admiral
Posts: 2391
Joined: Tue Aug 26, 2008 12:02 am

Use (objGetDir gSource) instead of (objGetVel gSource) for your fire angle, and use setq to store the shot so you can add the ship's vector seperately with objIncVel. It's far cleaner than doing it in one statement.
Post Reply