Tomb Raider Forums  

Go Back   Tomb Raider Forums > Tomb Raider Level Editor and Modding > Tomb Raider Level Editor > Tutorials and Resources

Closed Thread
 
Thread Tools
Old 31-05-14, 14:38   #1
N.E.O
Inactive
 
Joined: May 2014
Posts: 4
Post TRNG - Portable Light System (PLS)

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= ...

Last edited by AkyV; 02-11-16 at 11:16.
N.E.O is offline  
Old 03-11-16, 14:35   #2
Titak
Moderator
 
Titak's Avatar
 
Joined: Jul 2003
Posts: 33,359
Default

Having problems with leveljumps when using a PLS?
This setup might help.



This works with the "endless battery" version of the PLS.
My script is for that version also includes a meshswap of Lara's upper body:
Code:
; ------------- PLS stuff ------------------- 
AddEffect= 1, ADD_LIGHT_FLAT, FADD_CONTINUE_EMIT, 7, -70, -100, 350, IGNORE, IGNORE, 13, IGNORE, MIST_COL_WHITE
; --- using the flare button for turning the PLS on and off.
GlobalTrigger=     2, FGT_SINGLE_SHOT_RESUMED, GT_CONDITION_GROUP, -1, 6, 4, -1
GlobalTrigger=     7, FGT_SINGLE_SHOT_RESUMED, GT_USED_INVENTORY_ITEM, PICKUP_ITEM1, -1, 4, -1
TriggerGroup=      6, $8000, 10, $10D  ; condition that [Use Flare] is pressed
TriggerGroup=      4, $8000, 8, $2C, > ;condition that bit 0 in GBD1 is set
                      $5000, X, $131, $2000, 71, $1F4E, $2000, 100, $807, $2000, 235, $8, $2000, 50, $138, >  ; disable AddEffect1 on Lara, Play sfx 334 pls_off, swap torsomesh back, clear bit0 in GBD1, add pickup-item1 to inventory 
                      TGROUP_ELSE + $5000, X, $130, $2000, 71, $1F4F, $2000, 100, $1007, $2000, 234, $8, $2000, 47, $38 
				; OR ELSE Activate AddEffect1 on Lara (objectID 0), Play sfx 335 pls_on, swap torsomesh to that of Lara-speach-head1, set bit0 in GBD1, 
				; remove pickup-item1 from inventory
X is the ID of the LARA you placed in your map.
The PLS object is in PICKUP_ITEM1 slot.
I remove it from the inventory when the player turns the PLS on, and it is added back to the inventory when the player turns it off.

Doing this helped me fix the crash I had with leveljumps.

Having a meshswapped mesh on Lara can cause the game to crash when leveljumping.
ResetHUB= can be used in these cases, but ResetHUB also resets any triggers that might have been activated on the first visit to a level.
So RestHUB is not recommended when Lara can go back and forth between levels.

The following script can help fix this crash:
Code:
; ---- keep PLS on during leveljumps
TriggerGroup=    163, $8000, 231, $1 ; condition that PICKUP_ITEM1 (PLS) is missing in the inventory 
TriggerGroup=    168, $5000, X, $130, $2000, 100, $1007, $2000, 234, $8     
				; Activate AddEffect1 on Lara, swap torsomesh to that of Lara-speach-head1, set bit0 in GBD1
GlobalTrigger=     56, FGT_SINGLE_SHOT_RESUMED, GT_CONDITION_GROUP, -1, 163, 168, -1

TriggerGroup=    171, $8000, 231, $2 ; condition that PICKUP_ITEM1 (PLS) is present in the inventory 
TriggerGroup=    172, $5000, X, $131, $2000, 100, $807, $2000, 235, $8     
				; disable AddEffect1 on Lara, swap torsomesh back to that of the LARA_SKIN, clear bit0 in GBD1
GlobalTrigger=     61, FGT_SINGLE_SHOT_RESUMED, GT_CONDITION_GROUP, -1, 171, 172, -1
This script makes sure that the meshswap does not cause the level to crash, it makes sure that the PLS is on/off according to whether it was on or off prior the leveljump, and it makes sure that the PLS works properly again after the leveljump.

No triggers needed in the map.
Titak is offline  
Closed Thread

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT. The time now is 17:52.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Tomb Raider Forums is not owned or operated by CDE Entertainment Ltd.
Lara Croft and Tomb Raider are trademarks of CDE Entertainment Ltd.