Request for some PRPL help.

Started by Exodus Legate, April 24, 2017, 08:09:31 AM

Previous topic - Next topic

Exodus Legate

So, has anyone got time to give some advice to someone who's never used PRPL before?

What I want is to set things up so that, once something in a specific part of the map has been claimed/destroyed (Ship blueprint, info cache, emitter destruction, any can be made to work), the mission failed on HQ loss condition is removed- so the existing HQ can be warped out and in again, etc.

It looks like there's this: http://knucklecracker.com/wiki/doku.php?id=prpl:setfailonhqloss on the wiki, which looks like what I'm after in terms of the effect, but, not entirely to my surprise, the script compiler doesn't like it in just that condition, (Something about a dot only being allowed in string literals and floating point numbers).
So there's that issue, and also I'm a bit stuck on the best way to set up the trigger condition- what's going to be the most efficient way of doing that?

GoodMorning

You have three things to do - find a target, check if it is atill theere, and change the HQ loss setting if it is gone.

These are actually in order of difficulty. Finding a unit is the hardest part, the others are trivial, with the latter being marginally simpler.




To find a target, there are a few options. The most PRPL-minimal is to use something like:

:destroyed
0 SetFailOnHQLoss


This will work if the Core it is attached to is the "Rift Inhibitor". Adding a decorative image or two could make this a pleasing addition.




A more complex (but more versatile) way allows any unit to be used, such as a cache, pickup, spawner or Emitter:

$Target:-1 #If you know the UID, use this
$TargetX:-1 #If you know the exact coordinates, use these
$TargetY:-1
#Otherwise, look at the same spot as this Core...

once
<-Target -1 eq if
<-TargetX -1 eq if
CurrentCoords 0 1 GetAllUnitsInRange ->Targets
else
<-TargetX <-TargetY 0 1 GetAllUnitsInRange ->Targets
endif
<-Targets GetListCount 0 do
<-Targets[I] Self neq if
<-Targets[I] ->Target
break
endif
loop
endif
endonce

<-Target -1 neq if
<-Target GetUnitIsDestroyed if
Self 0 DestroyUnit
endif
endif

:destroyed
1 "HQ JUMP ENABLED" AddGameEvent pop #If this line misbehaves, delete it. It's decorative.
0 SetFailOnHQLoss


Note that ships are not "units" but Doppels, Stunners and even cannon shots are. Particles are not "units" either. Energy mines are units, but so are sources (which are indestructible).

The wiki page you linked was based off source code. I've now written it up properly.

I hope this helps you. Feel free to ask further questions, but give it a go yourself first (you may surprise yourself). A good exercise would be to add a check to the above code that the unit is of a specified type (GetUnitType is useful for this).



Finally, a note to Stickman, FOXX, or planetfall: Could the wiki pages for the GameEvent functions be written up properly please? I haven't used the commands, and I believe you have. Certainly the "sudo rm lathe" scripts disagree with the wiki.
A narrative is a lightly-marked path to another reality.

Exodus Legate

That's working perfectly, thank you.

Now back to playtesting. :)

Nicant

I've looked at some examples of the AddGameEventAtCell Command and made the wiki page for it! Might need some tidying though.
https://knucklecracker.com/wiki/doku.php?id=prpl:addgameeventatcell
CW4 hype!!

Exodus Legate

Um... some more help?

# --Wormhole-- 8/17/2017 12:40:43 PM
$Target1:168 #168, 169 are the hidden emitter UID's. 169 is the blue, 168 is the red.
$Target2:169
$Conv1:"Wormhole Closed"
$Conv2:"AI Wormhole"

<-Target1 GetUnitIsDestroyed if #If the target object with the unique identifier equal to the value of "Target1" is destroyed, then:
<-Target2 0 DestroyUnit #Destroy the other hidden emitter, Target 2
<-Conv1 ShowConversation
Self 0 DestroyUnit #Destroy this core.
endif #Endif
<-Target2 GetUnitIsDestroyed if #If the target object with the unique identifier equal to the value of "Target2" is destroyed, then:
<-Target1 0 DestroyUnit #Destroy the other hidden emitter, Target 1
<-Conv2 ShowConversation
Self 0 DestroyUnit #Destroy this core.
endif #Endif




Okay, so: what I wanted to happen is, when either of a pair of emitters is destroyed, the other of the pair is destroyed as well, and a conversation is played, with which conversation depending on which of the pair was destroyed, and then the core cleans itself up. The emitters are indeed destroyed, and the core does indeed clean itself up. BUT.
What actually happens is that, if the red emitter is destroyed, Conv1 plays twice. If the blue emitter is destroyed, Conv1 plays once. Conv2 never plays.
My attempts to figure out why (I didn't) are in the spoiler if you want to read them for whatever reason.
Spoiler

I then wondered if the script was somehow interfering with itself (I couldn't see how, but nevermind), so I decided to try using two PRPL cores with half of the script each, inelegance aside:
# --Wormhole-- 8/17/2017 12:40:43 PM
$Target1:168 #168, 169 are the hidden emitter UID's. 169 is the blue, 168 is the red.
$Target2:169
$Conv1:"Wormhole Closed"

<-Target1 GetUnitIsDestroyed if #If the target object with the unique identifier equal to the value of "Target1" is destroyed, then:
<-Target2 0 DestroyUnit #Destroy the other hidden emitter, Target 2
<-Target3 0 DestroyUnit
<-Conv1 ShowConversation
Self 0 DestroyUnit #Destroy this core.
endif #Endif

# --WormholeBlueKilled-- 9/4/2017 5:39:50 PM

$Target1:168 #168, 169 are the hidden emitter UID's. 169 is the blue, 168 is the red, 422 is the wormhole core running the other half of the script.
$Target2:169
$Target3:422
$Conv2:"AI Wormhole"
#Endif
<-Target2 GetUnitIsDestroyed if #If the target object with the unique identifier equal to the value of "Target2" is destroyed, then:
<-Target1 0 DestroyUnit #Destroy the other hidden emitter, Target 1
<-Target3 0 DestroyUnit
<-Conv2 ShowConversation
Self 0 DestroyUnit #Destroy this core.
endif #Endif

Which produces exactly the same result, which would be consistent with the theory that the scripts were interfering somehow, which I sorta intended- that's why the core with the other script is killed second, so the other script is still around to see what happens. So what about if I kill the other core BEFORE the other emitter?
Nope. STILL the same result, despite the fact that the other script should be able to run. So is the other script still running, because it's core was only killed this frame and things have not yet updated? Let's try a wait command.
Nope. Still the same result.
[close]
So, why does it not work, and does anyone have any ideas on how I can get it to work?
So... help?

GoodMorning

The original looks good to me. To be absolutely certain, you have definitely saved the script and recompiled it? The behaviour you describe (no change after updates) is exactly what I'd expect if the script file hadn't been changed.

Failing that, it will be useful to put in a Trace at the top so you know what's destroyed or otherwise from the script POV.
A narrative is a lightly-marked path to another reality.

Exodus Legate

Right, finally managed to fix it.  :)

The trace suggestion was helpful, hadn't looked at that functionality in PRPL before.

GoodMorning

Generally the trace is the first response for debugging, rather than the last resort.

What was going wrong, if I may ask?
A narrative is a lightly-marked path to another reality.

Exodus Legate

Heh. Well, it was actually two issues. The first is that somehow, there was a second core running the same script hidden under something else in the map, so chalk that one up to my own absentmindedness combined with the fact that I've been doing this one and a couple of others at once for a while. That's why there was always one more of one message than expected, but seeing the two location sources on the debug while setting up the trace clued me into that.

The second issue was that, for some reason, the second conversation simply was not playing even when the command to do so was executed. I still have no idea why, since I checked VERY carefully that the names matched, so I just ended up changing both it's name and the name referenced in the script.  ???

Works now, anyway.