Is there any way to get at the code inside the invoke block on an item through code?
I'm trying to make UGW NPC's accept more usable items, but I don't want to manually add every single usable item as a unid check exception.
I would also need to change mentions (in the target item's invoke code) of gPlayerShip to gSource and objSendMessage to scrSetDesc, could I use string functions to do that?
EDIT: changed the title
get code from an invoke and scrSetListFilter
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
Hi, Bobby.
There is no way to get the contents of the Invoke block. What I would suggest you do is store the code you need to call in a function, or as DigDug suggested, inside a piece of staticdata on the item. After you have done this, it should be possible to get the code, and replace certain words in the function to make it work differently.
It is also possible to build lambdas as lists, and therefore manipulate them with the list functions. Something like this works fine
Please note, that I have not tested the above, but I have working code that uses a similar style, so it should work. If you want to look at some functions that use this, check out some of the DSF CommonFunctions
If you have more specific snippets I would like to help with them too, should the need arise :)
There is no way to get the contents of the Invoke block. What I would suggest you do is store the code you need to call in a function, or as DigDug suggested, inside a piece of staticdata on the item. After you have done this, it should be possible to get the code, and replace certain words in the function to make it work differently.
It is also possible to build lambdas as lists, and therefore manipulate them with the list functions. Something like this works fine
Code: Select all
;; build the lambda as a list
(setq func (list lambda (list arg1) (dbgLog "Arg1: " arg1)))
;; print the list, just for fun
(dbgLog func)
;; (lambda (arg1) (dbgLog "Arg1: " arg1))
;; to run the lambda, eval or apply it if you need to pass arguments
(apply func (list "Hello"))
;; prints: Arg1: Hello
If you have more specific snippets I would like to help with them too, should the need arise :)
Using staticdata would require overwriting all the usable items, which I don't think should be necessary.
I guess I'll just add the easy or "essential" stuff like field crystals and weapon enhancers to the list of things they can use. I already added field crystals, the weapon enhancers, optimizer roms, and shield enhancer rom.
I'm using a unid check and a function like this (it's in a switch on the use item action).
The new question is how would I filter the screen to show only the items that can be used. I have this so far, and all it does is show nothing at all.
I've never used scrSetListFilter before, what am I doing wrong?
I guess I'll just add the easy or "essential" stuff like field crystals and weapon enhancers to the list of things they can use. I already added field crystals, the weapon enhancers, optimizer roms, and shield enhancer rom.
I'm using a unid check and a function like this (it's in a switch on the use item action).
Code: Select all
<Action name="Use this" key="U" default="1">
(block (unid)
(setq gItem (scrGetItem gScreen))
(setq unid (itmGetUnid gItem))
;find what to do with the item
(switch
;item is an armor enhancing barrel, send it to the proper screen
(or (itmMatches gItem "uU +ArmorEnhance;")
; (eq unid &itSiliconArmorPatch;)
(eq unid &itDeconGel;)
(eq unid &itRadioactiveWaste;)
(eq unid &itOrganicAcid;)
)
(scrShowScreen gScreen "&UGW_dsUseArmorCoating;")
;item is for patching armor, send it to proper screen
(itmMatches gItem "uU +ArmorRepair;")
(scrShowScreen gScreen "&UGW_dsUseArmorPatch;")
;item is a longzhu sphere, send it to proper screen.
(eq unid &itLongzhuSphere;)
(scrShowScreen gScreen "&UGW_dsUSeLongzhuSphere;")
;item is a field crystal, see which it is and use it
(eq unid &itDiamondCrystal;)
(intFieldCrystalUseV 0x0100 "Your shields are more powerful")
(eq unid &itYellowEtheriumCrystal;)
(intFieldCrystalInstallV &itYellowEtheriumCrystal; (random 30000 40000))
(eq unid &itDecayedEtheriumCrystal;)
(intFieldCrystalUseV 0x834A "Your shields fade")
(eq unid &itBlueEtheriumCrystal;)
(intFieldCrystalInstallV &itBlueEtheriumCrystal; (random 30000 40000))
(eq unid &itMolbidiumCrystal;)
(intFieldCrystalUseV 0x0103 "Your shields are more powerful")
(eq unid &itGreenEtheriumCrystal;)
(intFieldCrystalInstallV &itGreenEtheriumCrystal; (random 30000 40000))
;item is a weapon enhancer, use it
(eq unid &itLaserAmplifier;)
(intEnhanceWeaponUsev 0x0100 0 "is more powerful")
(eq unid &itKineticUpgrade;)
(intEnhanceWeaponUsev 0x0100 1 "is more powerful")
(eq unid &itParticleUpgrade;)
(intEnhanceWeaponUsev 0x0100 2 "is more powerful")
(eq unid &itBlastUpgrade;)
(intEnhanceWeaponUsev 0x0100 3 "is more powerful")
(eq unid &itIonUpgrade;)
(intEnhanceWeaponUsev 0x0100 4 "is more powerful")
(eq unid &itThermoUpgrade;)
(intEnhanceWeaponUsev 0x0100 5 "is more powerful")
(eq unid &itWeaponSpeedROM;)
(intEnhanceWeaponUsev 0x1002 Nil "has an improved fire rate")
;item is a shield enhance rom, so use it
(eq unid &itEnhanceShieldsROM;)
(intEnhanceShieldUsev)
;item doesn't match any of our criteria, it cannot be used
(scrSetDesc gScreen "This item cannot be used.")
)
)
</Action>
The new question is how would I filter the screen to show only the items that can be used. I have this so far, and all it does is show nothing at all.
Code: Select all
(scrSetListFilter gScreen (or
(itmMatches gItem "uU +ArmorEnhance;")
(itmMatches gItem "uU +ArmorRepair;")
(eq (itmGetUnid gItem) &itLongzhuSphere;)
(itmMatches gItem "uU +FieldCrystal;")
))
Last edited by Bobby on Wed Jul 28, 2010 1:09 am, edited 1 time in total.
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
About the scrSetListFilter, it is hard for me to tell what can be wrong without more context.
The only thing I can think of is that it must be run inside the ListOptions element. It does nothing anywhere else.
The only thing I can think of is that it must be run inside the ListOptions element. It does nothing anywhere else.
I'll put up the whole screen as it is now. It seems to have no effect since I moved the scrSetListFilter from the initialize element, I'm still seeing the mnemonic cubes.
Code: Select all
<!--Use an item screen-->
<DockScreen UNID="&UGW_dsUseItem;"
name= "Ship's Interior"
type= "itemPicker"
backgroundID= "&rsItemListScreen;"
>
<ListOptions
dataFrom= "station"
list= "uU"
>
(scrSetListFilter gScreen (if (or
(itmMatches gItem "uU +ArmorEnhance;")
(itmMatches gItem "uU +ArmorRepair;")
(eq (itmGetUnid gItem) &itLongzhuSphere;)
(eq (itmGetUnid gItem) &itLaserAmplifier;)
(eq (itmGetUnid gItem) &itKineticUpgrade;)
(eq (itmGetUnid gItem) &itParticleUpgrade;)
(eq (itmGetUnid gItem) &itBlastUpgrade;)
(eq (itmGetUnid gItem) &itIonUpgrade;)
(eq (itmGetUnid gItem) &itThermoUpgrade;)
(eq (itmGetUnid gItem) &itWeaponSpeedROM;)
(eq (itmGetUnid gItem) &itEnhanceShieldsROM;)
(itmMatches gItem "uU +FieldCrystal;")
)) true false)
</ListOptions>
<Panes>
<Default>
<initialize>
(scrSetDesc gScreen "select an item to use")
</initialize>
<Actions>
<Action name="Use this" key="U" default="1">
(block (unid)
(setq gItem (scrGetItem gScreen))
(setq unid (itmGetUnid gItem))
;find what to do with the item
(switch
;item is an armor enhancing barrel, send it to the proper screen
(or (itmMatches gItem "uU +ArmorEnhance;")
; (eq unid &itSiliconArmorPatch;)
(eq unid &itDeconGel;)
(eq unid &itRadioactiveWaste;)
(eq unid &itOrganicAcid;)
)
(scrShowScreen gScreen "&UGW_dsUseArmorCoating;")
;item is for patching armor, send it to proper screen
(itmMatches gItem "uU +ArmorRepair;")
(scrShowScreen gScreen "&UGW_dsUseArmorPatch;")
;item is a longzhu sphere, send it to proper screen.
(eq unid &itLongzhuSphere;)
(scrShowScreen gScreen "&UGW_dsUSeLongzhuSphere;")
;item is a field crystal, see which it is and use it
(eq unid &itDiamondCrystal;)
(intFieldCrystalUseV 0x0100 "Your shields are more powerful")
(eq unid &itYellowEtheriumCrystal;)
(intFieldCrystalInstallV &itYellowEtheriumCrystal; (random 30000 40000))
(eq unid &itDecayedEtheriumCrystal;)
(intFieldCrystalUseV 0x834A "Your shields fade")
(eq unid &itBlueEtheriumCrystal;)
(intFieldCrystalInstallV &itBlueEtheriumCrystal; (random 30000 40000))
(eq unid &itMolbidiumCrystal;)
(intFieldCrystalUseV 0x0103 "Your shields are more powerful")
(eq unid &itGreenEtheriumCrystal;)
(intFieldCrystalInstallV &itGreenEtheriumCrystal; (random 30000 40000))
;item is a weapon enhancer, use it
(eq unid &itLaserAmplifier;)
(intEnhanceWeaponUsev 0x0100 0 "is more powerful")
(eq unid &itKineticUpgrade;)
(intEnhanceWeaponUsev 0x0100 1 "is more powerful")
(eq unid &itParticleUpgrade;)
(intEnhanceWeaponUsev 0x0100 2 "is more powerful")
(eq unid &itBlastUpgrade;)
(intEnhanceWeaponUsev 0x0100 3 "is more powerful")
(eq unid &itIonUpgrade;)
(intEnhanceWeaponUsev 0x0100 4 "is more powerful")
(eq unid &itThermoUpgrade;)
(intEnhanceWeaponUsev 0x0100 5 "is more powerful")
(eq unid &itWeaponSpeedROM;)
(intEnhanceWeaponUsev 0x1002 Nil "has an improved fire rate")
;item is a shield enhance rom
(eq unid &itEnhanceShieldsROM;)
(intEnhanceShieldUsev)
;item doesn't match any of our criteria, it cannot be used
(scrSetDesc gScreen "This item cannot be used.")
)
)
</Action>
<Action name="Cancel" key="C" cancel="1">
(scrShowScreen gScreen gPrevScreen gPrevPane)
</Action>
</Actions>
</Default>
</Panes>
</DockScreen>
false is true? that was unexpected.
EDIT: I got it. Thanks alterecco.
in listoptions:
in a globals (it doesn't work inside the scrSetListFilter):
Now only the items that can actually be used are shown, but I still have to add most of them manually.
EDIT: I got it. Thanks alterecco.
in listoptions:
Code: Select all
(scrSetListFilter gScreen ugwFilterUseItem)
Code: Select all
(setq ugwFilterUseItem (lambda (thisItem)
(if (or
(itmMatches thisItem "uU +ArmorEnhance;")
(itmMatches thisItem "uU +ArmorRepair;")
(itmMatches thisItem "uU +FieldCrystal;")
(eq (itmGetUnid thisItem) &itLongzhuSphere;)
(eq (itmGetUnid thisItem) &itLaserAmplifier;)
(eq (itmGetUnid thisItem) &itKineticUpgrade;)
(eq (itmGetUnid thisItem) &itParticleUpgrade;)
(eq (itmGetUnid thisItem) &itBlastUpgrade;)
(eq (itmGetUnid thisItem) &itIonUpgrade;)
(eq (itmGetUnid thisItem) &itThermoUpgrade;)
(eq (itmGetUnid thisItem) &itWeaponSpeedROM;)
(eq (itmGetUnid thisItem) &itEnhanceShieldsROM;)
)
True
Nil
)
))
- alterecco
- Fleet Officer
- Posts: 1658
- Joined: Wed Jan 14, 2009 3:08 am
- Location: Previously enslaved by the Iocrym
Glad you got it working... not sure about why you have to use a lambda though...
false is not a tscript keyword, so it evaluates to true in that context (as if it was a string or literal)
You should be able to strip out the entire if, and just use the inner or.
Regarding the adding of items, I am not sure I really understand what you are trying to do. I would like to try and help you find a solution, since adding items manually usually is a pain (no matter *what* you are trying to do :) Perhaps you would explain your task in a bit more detail?
Edit: Ohh, wait... you are trying to use the already existing code from a usable items invoke? That *is* an unsolvable problem i fear... will ponder it a bit
false is not a tscript keyword, so it evaluates to true in that context (as if it was a string or literal)
You should be able to strip out the entire if, and just use the inner or.
Regarding the adding of items, I am not sure I really understand what you are trying to do. I would like to try and help you find a solution, since adding items manually usually is a pain (no matter *what* you are trying to do :) Perhaps you would explain your task in a bit more detail?
Edit: Ohh, wait... you are trying to use the already existing code from a usable items invoke? That *is* an unsolvable problem i fear... will ponder it a bit
What about modifying the wingmen's ships to allow the player to take control, then any/all items are useable and you can use all the standard dockscreens. I have a ship change mod that is nearly complete if you'd like to collaborate on it.
Even if we could use typGetDataField or some new, similar function to access the <invoke> code you would still need to hack in and replace any gPlayerShip or plyMessage occurances. I would suggest placing the variant invoke code into staticData and evaluating it from the dockscreen, or build the script into the dockscreen itself.
Even if we could use typGetDataField or some new, similar function to access the <invoke> code you would still need to hack in and replace any gPlayerShip or plyMessage occurances. I would suggest placing the variant invoke code into staticData and evaluating it from the dockscreen, or build the script into the dockscreen itself.
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!
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!
That would be perfect, unfortunately my proof of concept mod doesn't work. the moment I press the "Let me fly" option in the dockscreen, it immediately locks up the computer forcing me to hold down the power button to turn it off... It goes unresponsive, and the hard drive activity light goes crazy.
My player guided missiles do the same thing now too, it used to work.
I think i'll need to see a working example of plyChangeShip.
debug log is no help.
The code in the dockscreen:
The code on the ship to be changed to
I just noticed the bug in the distance check, but that wouldn't cause an immediate freeze.
The entire mod is here, only Rama can be changed to.
My player guided missiles do the same thing now too, it used to work.
I think i'll need to see a working example of plyChangeShip.
debug log is no help.
Code: Select all
07/28/2010 11:24:11 Start logging session
07/28/2010 11:24:12 Transcendence 1.02
07/28/2010 11:24:14 Loading extension: Extensions\arm\zzarmors
07/28/2010 11:24:14 Loading extension: Extensions\devices\hook and lrs\active lrs
07/28/2010 11:24:14 Loading extension: Extensions\devices\repair droids\droids 1.0\repair droids 1.0
07/28/2010 11:24:14 Loading extension: Extensions\DockScreenFramework\CommonFunctions
07/28/2010 11:24:14 Loading extension: Extensions\DockScreenFramework\Framework
07/28/2010 11:24:14 Loading extension: Extensions\europa blow vault
07/28/2010 11:24:14 Loading extension: Extensions\G.O.D.Mod
07/28/2010 11:24:14 Loading extension: Extensions\global helpers
07/28/2010 11:24:14 Loading extension: Extensions\Mining\my ore scanner\Ore Scanner
07/28/2010 11:24:14 Loading extension: Extensions\Mining\packer\Packer Resources
07/28/2010 11:24:14 Loading extension: Extensions\Mining\packer\UGW Packer
07/28/2010 11:24:14 Loading extension: Extensions\NoDockNavBeacon
07/28/2010 11:24:14 Loading extension: Extensions\player guided missile
07/28/2010 11:24:14 Loading extension: Extensions\ships\Agauptera\Agauptera
07/28/2010 11:24:14 Loading extension: Extensions\ships\AsteroidsShip\Asteroidship
07/28/2010 11:24:14 Loading extension: Extensions\ships\badger\badger
07/28/2010 11:24:14 Loading extension: Extensions\ships\Cavendesh\Cavendesh
07/28/2010 11:24:14 Loading extension: Extensions\ships\ciaro\ciaro
07/28/2010 11:24:15 Loading extension: Extensions\ships\condor\condor
07/28/2010 11:24:15 Loading extension: Extensions\ships\Deemer\deemer
07/28/2010 11:24:15 Loading extension: Extensions\ships\Iliac\Iliac
07/28/2010 11:24:15 Loading extension: Extensions\ships\longhorn\longhorn
07/28/2010 11:24:15 Loading extension: Extensions\ships\omigm\omigm
07/28/2010 11:24:15 Loading extension: Extensions\ships\zork\zork
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\captain's log\Captain's log
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\cargo summary\Cargo summary
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\cargo summary\screen_cargo hold
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\cargo summary\screen_jettison
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\cargo summary\screen_loot
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\Cartography\Cartography
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\shipcomp\shipcomputer
07/28/2010 11:24:15 Loading extension: Extensions\shipscreen\shipcomp\SignatureMemoizer
07/28/2010 11:24:15 Loading extension: Extensions\UGW\08u auton\UGW 08U battle auton
07/28/2010 11:24:15 Loading extension: Extensions\UGW\UGWingmen base
07/28/2010 11:24:15 Loading extension: Extensions\UGW\UGWingmen mule
07/28/2010 11:24:15 Loading extension: Extensions\UGW\UGWingmen screens
07/28/2010 11:24:15 Loading extension: Extensions\UGW\UGWingmen wingmen
07/28/2010 11:27:17 ERROR
07/28/2010 11:27:42 ERROR
07/28/2010 11:27:43 ERROR
07/28/2010 11:27:44 ERROR
07/28/2010 11:27:44 ERROR
07/28/2010 11:27:45 ERROR
07/28/2010 11:27:46 ERROR
07/28/2010 11:27:48 ERROR
07/28/2010 11:27:49 ERROR
07/28/2010 11:27:49 ERROR
07/28/2010 11:27:50 ERROR
07/28/2010 11:27:50 ERROR
07/28/2010 11:27:51 ERROR
07/28/2010 11:27:51 ERROR
07/28/2010 11:27:52 ERROR
07/28/2010 11:27:52 ERROR
07/28/2010 11:27:53 ERROR
07/28/2010 11:27:54 ERROR
07/28/2010 11:27:54 ERROR
07/28/2010 11:27:54 ERROR
07/28/2010 11:27:55 ERROR
07/28/2010 11:27:56 ERROR
07/28/2010 11:27:56 ERROR
07/28/2010 11:27:56 ERROR
07/28/2010 11:27:56 ERROR
07/28/2010 11:27:56 ERROR
07/28/2010 11:27:57 ERROR
07/28/2010 11:27:57 ERROR
07/28/2010 11:27:57 ERROR
07/28/2010 11:27:57 ERROR
07/28/2010 11:27:57 ERROR
07/28/2010 11:27:58 ERROR
07/28/2010 11:27:58 ERROR
07/28/2010 11:27:58 ERROR
07/28/2010 11:27:58 ERROR
07/28/2010 11:27:58 ERROR
07/28/2010 11:27:59 ERROR
07/28/2010 11:32:16 --------------------------------------------------------------------------------
The code in the dockscreen:
Code: Select all
<Action name="Let me fly" key="F" >
(block Nil
; (shpCancelOrders gSource)
; (shpOrderHold gSource)
(if (isError (plyChangeShip gPlayer gSource))
(block Nil
(scrSetDesc gScreen "You can't fly my ship!")
; (shpCancelOrders gSource)
; (shpOrder gSource 'follow gPlayerShip (intGetFormPos))
)
)
)
</Action>
Code: Select all
<OnGlobalPlayerChangedShips>
(if (eq gPlayerShip gSource)
(block Nil
(shpCancelOrders aOldPlayerShip)
(shpOrderHold aOldPlayerShip)
(objRegisterForEvents gSource aOldPlayerShip)
;remember the player ship
(sysSetData "playerShipID" (objGetID aOldPlayerShip))
;start the proximity check event that switches back to the player's old ship
(sysAddObjRecurringTimerEvent 60 gSource "OnCloseToOldShip")
)
)
</OnGlobalPlayerChangedShips>
<OnCloseToOldShip>
(block oldPlayerShip
(setq oldplayership (objGetObjByID (sysGetData "playerShipID")))
(if (leq (objGetDistance gPlayer oldplayership))
(block Nil
(sysCancelTimerEvent gSource "OnCloseToOldShip")
(plyChangeShip gPlayer oldplayership)
(shpOrder gSource 'follow gPlayerShip (intGetFormPos))
)
)
)
</OnCloseToOldShip>
The entire mod is here, only Rama can be changed to.