Hi!
Though my pseudo is N.E.O, I'm actually Quasar, the Wreck of Blue Storm's author ("Quasar" is already used here). I made a tutorial for the PLS on Rouge's request.
Author: Quasar
Used version: v1.2.2.6 (works on v1.2.2.7)
Note: This tutorial is also hosted on my
Dropbox.
1) Introduction
To understand this tutorial, you should be familiar with these notions:
- TRNG Script, mainly the
GlobalTrigger / TriggerGroup / Organizer commands.
- Exporting triggers to script.
The tutorial's goal is to create the Tomb Raider Underworld Torch: the PLS (Portable Light System). Lara doesn't have to hold it, and she can turn it on/off on will.
In first versions of Wreck of the Blue Storm, I added a battery to the PLS, but I finally removed it. So the official PLS has an endless battery, but I will explain the two versions.
The PLS uses two SFX sounds, 307 and 308. You can download them
HERE. Obviously you can use other sounds!
To better understand, you can download the exported triggers files
HERE.
1) First version: endless battery
This first version simply enable/disable an AddEffect when the player hit the [Use Flare] key. First, let's set up the AddEffect. Add this in your script in a [Level] section:
Code:
Equipment= FLARE_ITEM, 0 ; Remove normal flares from inventory
AddEffect= 1, ADD_LIGHT_FLAT, FADD_CONTINUE_EMIT, JOINT_ABDOMEN, 0, -128, 175, -1, -1, 13, -1, MIST_COL_WHITE
-
ADD_LIGHT_FLAT adds a light with constant intensity
-
JOINT_ABDOMEN, 0, -128, 175 sets the mesh of origin and the effect's position
-
13 is the light's intensity
-
MIST_COL_WHITE is the light's color
Note: -1 equals IGNORE.
You are free to change the values. See NG_Center's reference for more infos.
Then we have to use a GlobalTrigger to enable/disable the AddEffect when the player hits [Use Flare]. But we also have to use a variable to know the current state of the PLS (on? off?). In this script, I use
Global Byte Alfa 1 (
GBA1).
Export the following triggers and add the below script.
Don't forget to adjust the commands ID if you have to!
{ EXPORT 1 }
; Set Trigger Type - ACTION 48
; Exporting: TRIGGER(304:0) for ACTION(...)
; <#> : LARA ID ... in sector ...
; <&> : Effect. Remove from <#> Enemy the (E) AddEffect from script.txt
; (E) : AddEffect= ...
{ EXPORT 2 }
; Set Trigger Type - ACTION 48
; Exporting: TRIGGER(304:0) for ACTION(...)
; <#> : LARA ID ... in sector ...
; <&> : Effect. Add to <#> Enemy the (E) AddEffect from script.txt
; (E) : AddEffect= ...
Code:
GlobalTrigger= 1, FGT_SINGLE_SHOT_RESUMED, GT_CONDITION_GROUP, -1, 1, 2, -1
TriggerGroup= 1, $8000, 10, $10D ; [Use Flare] is pressed
TriggerGroup= 2, $8000, 0, $2C, >
{ EXPORT 1 }, $2000, 71, $1F34, $2000, 235, $0, > ; effect OFF + sfx 308 + GBA1.b0 = 0
TGROUP_ELSE + { EXPORT 2 }, $2000, 71, $1F33, $2000, 234, $0 ; effect ON + sfx 307 + GBA1.b0 = 1
- If the player has just hit [Use Flare]
(GT1 + TG1), TG2 is performed.
- TG2 tests whether the 1st bit (bit 0) of GBA1 is set
($8000, 0, $2C).
- If it is, it means that the PLS is currently on. Then, AddEffect is disabled
(export 1), SFX 308 is played
($2000, 71, $1F34), and 1st bit of GBA1 is cleared
($2000, 235, $0).
- Else, AddEffect is enabled
(export 2), SFX 307 is played
($2000, 71, $1F33), and 1st bit if GBA1 is set.
($2000, 234, $0)
Build your script, and test in-game. Lara should now emit light when you hit [Use Flare]. It works!
So, this is the endless battery version. If you want the PLS to turn off automatically after some time, and recharge the battery, read the next part.
3) Second version: battery management
Note: This version uses the script of the previous section.
3.1) General settings
Here's how battery management works:
- While PLS is on, the battery discharges.
- If battery runs out of energy, then PLS turns off.
- While battery is not fully recharged, and PLS remains off, battery recharges.
Now we just have to translate these statements into script.
First, we have to use a custom bar to display the battery level. This value will be stored in
Global Byte Alfa2 (GBA2), which placeholder is
#0001. We use the
BAR_CUSTOM1.
Code:
ColorRGB= 1, 210, 210, 210
ColorRGB= 2, 0, 0, 0
Customize= CUST_BAR, BAR_CUSTOM1, -1, 18, 42, 75, 6, 2, 1, #0001
; GBA2 initialization
GlobalTrigger= 2, FGT_SINGLE_SHOT, GT_ALWAYS, -1, -1, 3, -1
TriggerGroup= 3, $2000, 232, $6401 ; GBA2 = 100
Obviously you are free to change the Customize and ColorRGB values. The important one is #0001, which means that the bar will display GBA2's value.
3.2) Discharging the battery
Discharging battery when PLS is on, means that
GBA2 decreases when
GBA1's first bit equals 1. So we have to modify the TG2 (used to turn on/off PLS) to trigger the discharge, and display the bar.
Code:
TriggerGroup= 2, [...]
TGROUP_ELSE + [...], $2000, 127, 1, $2000, 331, $4 ; effect ON + sfx 307 + GBA1.b0 = 1 + Enable Organizer 1 + BAR_CUSTOM1
Organizer= 1, FO_LOOP + FO_TICK_TIME, -1, 15, 4
TriggerGroup= 4, $8000, 0, $2C, $2000, 233, $101, TGROUP_ELSE + $2000, 128, 1 ; IF (GBA1.b0 = 1) THEN (GBA2--) ELSE (Disable Organizer 1)
- If GBA's bit 0 is set, TG2 now enables the Organizer 1
($2000, 127, 1).
- Organizer 1 loops
(FO_LOOP), and tests every half-second (15 frames) whether PLS is still on. If it is, then GBA2 is decremented
($2000, 233, $101). Else, the Organizer stops itself
($2000, 128, 1).
Red "1" in the above script match the Organizer ID. Adjust this ID if it's necessary!
If you want to change the battery's lifetime, you just have to change the "15" in the Organizer. This value is in frames (1 frame = 1/30 second).
If you test in-game right now, the bar should decrease only if PLS is on. But when bar is empty, PLS remains on. Let's fix it!
3.3) Turning off the PLS when battery is out
When battery is out, it simply means that GBA2 equals 0. So we have to create a new GlobalTrigger. To make the process simpler, we can simulate the [Use Flare] keystroke. Then, TG2 will be automatically performed.
Code:
GlobalTrigger= 3, -1, GT_CONDITION_GROUP, -1, 5, 6, -1
TriggerGroup= 5, $8000, 1, $12A ; IF (GBA2 < 1) ...
TriggerGroup= 6, $2000, 232, $101, $2000, 53, $B ; (GBA2 = 1) + Simulate [Use Flare]
Nothing to explain here, except that we also force GBA2 value to 1. If we don't, a bug may occur when the player tries to turn on the PLS again. Try it yourself if you're curious!
3.4) Recharging the battery
The recharge process is quite the same as the discharge. We have to modify the TG2 again so that he can enable an Organizer to recharge the battery.
To create the
"GBA2 >= 100" condition, we have to use the
Parameters= PARAM_BIG_NUMBERS command. Indeed, normal condition triggers can't test any value greater than 32. If you already have a Parameters command for your level, add 100 to the numbers list.
Export the following trigger.
Warning: the index for the first number in Parameters is 0!
{ EXPORT 3 }
; Set Trigger Type - CONDITION 38
; Exporting: CONDITION(38:62) for PARAMETER(...)
; <#> : Global Byte Alfa2
; <&> : Variables. The <#> Numeric Variable is >= than (E) Big Number value
; (E) : Value of Parameters=PARAM_BIG_NUMBERS at index= ...
Code:
Parameters= PARAM_BIG_NUMBERS, [...], 100
TriggerGroup= 2, $8000, 0, $2C, >
[...], $2000, 127, 2, > ; effect OFF + sfx 308 + GBA1.b0 = 0 + ORG2
TGROUP_ELSE + [...] ; effect ON + sfx 307 + GBA1.b0 = 1 + ORG1 + BAR_CUSTOM1
Organizer= 2, FO_LOOP + FO_TICK_TIME, -1, 10, 7
TriggerGroup= 7, $8000, 0, $2C, TGROUP_OR + { EXPORT 3 }, >
$2000, 128, 2, { EXPORT 3 }, $2000, 332, $4, >
TGROUP_ELSE + $2000, 231, $101
; IF (GBA1.b0 = 1 OR GBA2 >= 100) THEN
; Disable Organizer 2
; IF (GBA2 >= 100) THEN Hide BAR_CUSTOM1
; ELSE (GBA2++)
- With this new TG2, the recharge Organizer is performed as soon as PLS is turned off, whatever the cause.
- Organizer loops every 10 frames. He only stops if the player turned on the PLS or if battery is fully recharged. That's why it tests these conditions at first.
($8000, 0, $2C, TGROUP_OR + { EXPORT 3 })
- If one of the conditions is true, the Organizer stops
($2000, 128, 2). If the stop is due to the recharged battery (GBA2 >= 100), then we hide the bar
($2000, 332, $4).
- Else, we keep increasing GBA2
($2000, 231, $101).
Test in-game, and the PLS should be fully working!
4) Final script
This last part gives the whole script. I remind you its features:
- SFX: 307 and 308
- Used bar: BAR_CUSTOM1
- Used variables: Global Byte Alfa 1 and 2
If you want to use other sounds / bar / variables, you will have to reexport some triggers, and change some commands. The provided export files are here to help you.
Endless battery version
Code:
Equipment= FLARE_ITEM, 0 ; Remove normal flares from inventory
AddEffect= 1, ADD_LIGHT_FLAT, FADD_CONTINUE_EMIT, JOINT_ABDOMEN, 0, -128, 175, -1, -1, 13, -1, MIST_COL_WHITE
GlobalTrigger= 1, FGT_SINGLE_SHOT_RESUMED, GT_CONDITION_GROUP, -1, 1, 2, -1
TriggerGroup= 1, $8000, 10, $10D ; [Use Flare] pressed
TriggerGroup= 2, $8000, 0, $2C, >
{ EXPORT 1 }, $2000, 71, $1F34, $2000, 235, $0, > ; effect OFF + sfx 308 + GBA1.b0 = 0
TGROUP_ELSE + { EXPORT 2 }, $2000, 71, $1F33, $2000, 234, $0 ; effect ON + sfx 307 + GBA1.b0 = 1
Limited battery version
Code:
Equipment= FLARE_ITEM, 0 ; Remove normal flares from inventory
Parameters= PARAM_BIG_NUMBERS, [...], 100
; AddEffect + ON/OFF management
AddEffect= 1, ADD_LIGHT_FLAT, FADD_CONTINUE_EMIT, JOINT_ABDOMEN, 0, -128, 175, -1, -1, 13, -1, MIST_COL_WHITE
GlobalTrigger= 1, FGT_SINGLE_SHOT_RESUMED, GT_CONDITION_GROUP, -1, 1, 2, -1
TriggerGroup= 1, $8000, 10, $10D
TriggerGroup= 2, $8000, 0, $2C, >
{ EXPORT 1 }, $2000, 71, $1F34, $2000, 235, $0, $2000, 127, 2, >
TGROUP_ELSE + { EXPORT 2 }, $2000, 71, $1F33, $2000, 234, $0, $2000, 127, 1, $2000, 331, $4
; Battery bar
ColorRGB= 1, 210, 210, 210
ColorRGB= 2, 0, 0, 0
Customize= CUST_BAR, BAR_CUSTOM1, -1, 18, 42, 75, 6, 2, 1, #0001
GlobalTrigger= 2, FGT_SINGLE_SHOT, GT_ALWAYS, -1, -1, 3, -1
TriggerGroup= 3, $2000, 232, $6401
; Discharge
Organizer= 1, FO_LOOP + FO_TICK_TIME, -1, 15, 4
TriggerGroup= 4, $8000, 0, $2C, $2000, 233, $101, TGROUP_ELSE + $2000, 128, 1
GlobalTrigger= 3, -1, GT_CONDITION_GROUP, -1, 5, 6, -1
TriggerGroup= 5, $8000, 1, $12A
TriggerGroup= 6, $2000, 232, $101, $2000, 53, $B
; Recharge
Organizer= 2, FO_LOOP + FO_TICK_TIME, -1, 10, 7
TriggerGroup= 7, $8000, 0, $2C, TGROUP_OR + { EXPORT 3 }, >
$2000, 128, 2, { EXPORT 3 }, $2000, 332, $4, >
TGROUP_ELSE + $2000, 231, $101
{ EXPORT 1 }
; Set Trigger Type - ACTION 49
; Exporting: TRIGGER(305:0) for ACTION(...)
; <#> : LARA ID ... in sector ...
; <&> : Effect. Remove from <#> Enemy the (E) AddEffect from script.txt
; (E) : AddEffect= ...
{ EXPORT 2 }
; Set Trigger Type - ACTION 48
; Exporting: TRIGGER(304:0) for ACTION(...)
; <#> : LARA ID ... in sector ...
; <&> : Effect. Add to <#> Enemy the (E) AddEffect from script.txt
; (E) : AddEffect= ...
{ EXPORT 3 }
; Set Trigger Type - CONDITION 38
; Exporting: CONDITION(38:62) for PARAMETER(...)
; <#> : Global Byte Alfa2
; <&> : Variables. The <#> Numeric Variable is >= than (E) Big Number value
; (E) : Value of Parameters=PARAM_BIG_NUMBERS at index= ...