Walking Like Angel of Darkness
by AkyV
Download a project file illustrating this tutorial

I will show you in this tutorial how to use these two TR6 walking features in NGLE:

- If you hit SHIFT shortly, then you switch on/off the walking mode.
It means you don't need to hold SHIFT pushed down continuously to make Lara walk. (But you are still able to do that.)

- There's an 'I'll be walking and not running, if you use the cursor keys!' icon on the screen, when Lara will be walking with the cursor keys.

So, if you follow the tutorial you will able to do this:

1. The player hits left or right SHIFT (and holds it pushed down), so if (s)he uses the cursor keys Lara will be walking and not running. A 'walking person' icon shows up in the bottom right corner of the screen. - Then the player releases SHIFT so Lara will be running again with the cursor keys, and not walking. The icon disappears.

2. The player hits left or right SHIFT, then releases it at once. With that, the player switched on the walking mode. I.e. Lara will be walking if the player uses the cursor keys, either (s)he presses SHIFT continuously after the switching-on or not. The 'walking person' icon shows up.
To switch off the walking mode, the player must hit left or right SHIFT again, shortly. The icon disappears.

GETTING THE ICON

- First of all, you need that icon, of course. You can find it in your TR6 main folder, in Data\effects folder, in bar.tga. Cut it out to get that from the TGA:

The icon must be a 128x128 pixel sized BMP. The whole background was black, I made the magenta parts that will be transparent in the game. (I left some black area around the person, but we don't need that: you can make it more perfect, making the whole black area colored magenta.)

- You need a CUSTOM_SPRITES object in your WAD. (You can get it from Paolone's Miscellaneous II demo project.)

- Use NG Center\Tools\Sprite Editor: load your WAD, choose CUSTOM_SPRITES, then import the person icon picture, for example, into Texture0 slot. Click on 'Exit and Save WAD', save on the SWD of your WAD, then quit.

Using Image Script command you can use another method for the icon and not the method of a sprite.

This tutorial skips discussing Image version.

SETUPS

I'll show you two setups now.

The first setup is the easier one - it's recommended to beginners.
The second setup is the complicated one - it's recommended to advanced builders.

The differences between the two setups in the game:

1. In Setup#2 you will copy the exact procedure of TR6 method. I.e. the same key (left/right SHIFT) has three functions in Setup#2:

- short press: switching on the walking mode if it's switched off
- short press: switching off the walking mode if it's switched on
- continuous press: continuous walking

In Setup#1 you will use the three functions on three keys:

- hit key Z (near left SHIFT): switching on the walking mode
- hit key X (next to key Z): switching off the walking mode
- hit left/right SHIFT: walking until releasing this key

2. In TR4 engines you can use not only SHIFT to walk:

- press SHIFT+left arrow or DELETE to make Lara step left,
- press SHIFT+right arrow or PAGE DOWN to make Lara step right.

Unfortunately, we don't have a keyboard scancode either for DELETE or PAGE DOWN. (We have, if we're talking about DELETE or PAGE DOWN in NumPad, but that's not the same now.)
But we should have those scancodes to make Setup#2 work. That's why you have to modify your Control Configuration in the game, replacing the keys of 'Step Left' and 'Step Right' by any keys that have keyboard scancodes. (See the usable keyboard scancodes here: NG Center\Reference\Keyboard Scancodes List.)
In Setup#2 we use NumPad1(End) to step left and NumPad3(Page Down) to step right now - but feel free to choose other keys.

Attention:
The usage of SHIFT and the usage of Step Left/Right keys are not the same in Setup#2. That would be illogical if they did the same thing.
So, when you hit Step Left/Right key then the icon appears (except: the icon has placed on the screen before, i.e. the walking mode is just on), and if you release Step Left/Right key then the icon disappears (except: the icon remains on the screen now, because the walking mode is just on).

In Setup#1 Step Left/Right keys work the same way as in Setup#2, except Setup#1 works perfectly with the default DELETE and PAGE DOWN keys. (Because we don't use DELETE/PAGE DOWN scancodes in Setup#1.)

THE SETUP#1

Type these entries in the Script, in the [Level] block of your level:

GlobalTrigger= 1, IGNORE, GT_CONDITION_GROUP, IGNORE, 1, 2, 3
GlobalTrigger= 2, IGNORE, GT_KEYBOARD_CODE, 44, IGNORE, 4, IGNORE
GlobalTrigger= 3, IGNORE, GT_KEYBOARD_CODE, 45, IGNORE, 5, IGNORE
TriggerGroup= 1, $8000, 6, $10D
TriggerGroup= 2, $2000, 357, $1
TriggerGroup= 3, $2000, 358, $1
TriggerGroup= 4, $2000, 357, $1, $2000, 127, $1
TriggerGroup= 5, $2000, 358, $1, $2000, 128, $1
TriggerGroup= 6, $2000, 53, $7
Organizer= 1, FO_LOOP, IGNORE, 0, 6
Parameters= PARAM_SHOW_SPRITE, 1, IGNORE, 880, 860, 110, 110, CUSTOM_SPRITES, 0, IGNORE, >
IGNORE, IGNORE, IGNORE

This 'Parameters' command says the sprite (picture) in the Texture0 slot of CUSTOM_SPRITES (i.e. the person icon) will show up in the '880, 860, 110, 110' position on the screen if you call this PARAM_SHOW_SPRITE=1 entry in the game.
There are two methods to call that entry:

- First method: if Lara is ready to walk in the usual way (i.e. if the player is just holding pressed down left/right SHIFT) or if she's just walking by DELETE/PAGE DOWN.
- Second method: if the player has just switched on the walking mode by hitting key Z.

The first method uses GlobalTrigger#1: if the condition is true (i.e. if the player uses left/right SHIFT or DELETE/PAGE DOWN, see TriggerGroup#1) then the icon will appear (see TriggerGroup#2), or, if that's not true, then the icon will disappear (see TriggerGroup#3).

; Set Trigger Type - CONDITION 13
; Exporting: CONDITION(13:60) for PARAMETER(6)
; <#> : Walk (slowly)
; <&> : Keyboard. <#>Command game is currently (E)
; (E) : ACTIVE (Single shot for positive condition)
; Values to add in script command: $8000, 6, $10D

; Set Trigger Type - FLIPEFFECT 357
; Exporting: TRIGGER(1:0) for FLIPEFFECT(357)
; <#> : Sprite. Show sprite with data in <&>Parameters for (E)Durate
; <&> : Parameters=PARAM_SHOW_SPRITE, 1
; (E) : Forever (use other action/effect to disable it)
; Values to add in script command: $2000, 357, $1

; Set Trigger Type - FLIPEFFECT 358
; Exporting: TRIGGER(1:0) for FLIPEFFECT(358)
; <#> : Sprite. Remove from the screen the sprite with data in <&>Parameters
; <&> : Parameters=PARAM_SHOW_SPRITE, 1
; (E) : 
; Values to add in script command: $2000, 358, $1

The second method uses GlobalTrigger#2 and #3:

- GlobalTrigger#2 says if the keyboard code is 44 (i.e. key Z) then TriggerGroup#4 will be activated, placing the icon on the screen and starting Organizer#1:

; Set Trigger Type - FLIPEFFECT 127
; Exporting: TRIGGER(1:0) for FLIPEFFECT(127)
; <#> : Organizer. Enable <&>Organizer
; <&> : Organizer= 1
; (E) : 
; Values to add in script command: $2000, 127, $1

- GlobalTrigger#3 says if the keyboard code is 45 (i.e. key X) then TriggerGroup#5 will be activated, deleting the icon off the screen and stopping Organizer#1:

; Set Trigger Type - FLIPEFFECT 128
; Exporting: TRIGGER(1:0) for FLIPEFFECT(128)
; <#> : Organizer. Stop <&>Organizer
; <&> : Organizer= 1
; (E) : 
; Values to add in script command: $2000, 128, $1

If Organizer#1 starts then it starts TriggerGroup#6 at once (see: 0, 6):

; Set Trigger Type - FLIPEFFECT 53
; Exporting: TRIGGER(7:0) for FLIPEFFECT(53)
; <#> : Keyboard. Simulate receivement of <&>keyboard comand in (E) way
; <&> : Walk
; (E) : Single sending
; Values to add in script command: $2000, 53, $7

This trigger makes Lara walk if the player uses the cursor keys without SHIFT pressed.
Thanks to FO_LOOP in the Organizer, this command will be sent again and again (until the Organizer stops) so the walk will be continuous.


See more about the contents of the Script in NG Center\Reference.

THE SETUP#2

Notes:

1. I decided I'd use 1/6 second (i.e. 5 frames) as a border between 'short' and 'continuous' pushing. So, if the player holds SHIFT pushed down for more than 5 frames then it will be 'continuous'. If (s)he does that for maximum 5 frames, then it will be 'short'. (Feel free to use other border. To change the border, change the setup below.)

2. The icon will always show up if you use the keys to walk. So even when it's not logical: when Lara's climbing a ladder, swimming in water etc.
But it doesn't disturb the gameplay, moreover, it's helpful a bit: for example, if you see the icon (because you've switched on the walking mode) when Lara's swimming then you will know that Lara will be walking after she climbs out of the water, and not running.

But don't forget: Lara does special movements if SHIFT is just pressed. - For example, she doesn't perform a simple jumping forward but performs a swan dive if you also hit SHIFT with ALT+up cursor keys.
That's why, if you hit ALT+up, but the walking mode is on then Lara will perform a swan dive.

If those 'imperfections' bother you then you must modify the setup somehow. (If you are thinking about this kind of modifying then I must tell you Setup#2 isn't perfect in copying TR6. I mean in TR6, when the walking mode is on but player doesn't hold SHIFT down, then Lara will be turning when you hit left/right arrows, and not stepping left/right. - So Setup#2 ignores this special movement now.)

Type these entries in the Script, in the [Level] block of your level:

GlobalTrigger= 1, IGNORE, GT_CONDITION_GROUP, IGNORE, 1, 2, 3
TriggerGroup= 1, $8000, 42, $10C, $8000+TGROUP_OR, 54, $10C
TriggerGroup= 2, $2000, 231, $141, $2000, 357, $1
TriggerGroup= 3, $2000, 232, $41, >
$8000, 64, $12B, $2000, 127, $1, >
$8000+TGROUP_ELSE, 64, $22B, $2000, 128, $1, $2000, 358, $1, $2000, 233, $240, >
$8000+TGROUP_ELSE, 64, $32B, $2000, 358, $1, $2000, 233, $340, >
$8000+TGROUP_ELSE, 64, $42B, $2000, 233, $340
GlobalTrigger= 2, IGNORE, GT_CONDITION_GROUP, IGNORE, 4, 5, IGNORE
TriggerGroup= 4, $8000, 65, $12B
TriggerGroup= 5, $2000, 231, $140
GlobalTrigger= 3, IGNORE, GT_CONDITION_GROUP, IGNORE, 6, 7, IGNORE
TriggerGroup= 6, $8000, 65, $62B
TriggerGroup= 7, $2000, 231, $240
GlobalTrigger= 4, IGNORE, GT_CONDITION_GROUP, IGNORE, 8, 9, IGNORE
TriggerGroup= 8, $8000, 65, $82B
TriggerGroup= 9, $2000, 233, $141
Organizer= 1, FO_LOOP, IGNORE, 0, 10
TriggerGroup= 10, $2000, 53, $7
Parameters= PARAM_SHOW_SPRITE, 1, IGNORE, 880, 860, 110, 110, CUSTOM_SPRITES, 0, IGNORE, >
IGNORE, IGNORE, IGNORE
GlobalTrigger= 5, IGNORE, GT_CONDITION_GROUP, IGNORE, 11, 12, 13
TriggerGroup=11, $8000, 79, $10C, $8000+TGROUP_OR, 81, $10C
TriggerGroup= 12, $2000, 357, $2
TriggerGroup= 13, $2000, 358, $2
Parameters= PARAM_SHOW_SPRITE, 2, IGNORE, 880, 860, 110, 110, CUSTOM_SPRITES, 0, IGNORE, >
IGNORE, IGNORE, IGNORE

The setup works in two threads:

- Thread#1: if the player hits left/right SHIFT,
- Thread#2: if the player hits Step Left/Right keys.

Thread#1:

The thread uses two 'local byte' variables:

- Local Byte Alfa1: in this variable you define what the state of the walking will be when you release the just pressed SHIFT:

0: this is the default state: the SHIFT hasn't been pressed, the walking mode is off.
1: the walking mode switches on, because the SHIFT has been pressed shortly and the walking mode has just been off.
2: the walking mode switches off, because the SHIFT has been pressed shortly and the walking mode has just been on.
3: the SHIFT has been pressed continuously, but the walking mode is just off, so Lara will be running and not walking now if you hit the cursor keys.
4: the SHIFT has been pressed continuously, but the walking mode is just on, so Lara will be walking and not running now if you hit the cursor keys. - Naturally, it's a useless activity of the player: why does (s)he press SHIFT continuously when the walking mode is on? That pressing is absolutely senseless: Lara would walk without that long pressing, all the player should do is press the cursor keys now.

- Local Byte Alfa2: at each frame, number 1 will be added to this variable, while SHIFT is being pressed. - This is the way to count how long the SHIFT is being pressed. (No, Organizer can't be usable now. - I'd rather skip the details to tell why.)
All of this because we want to perform given things at some frames now:

The 'timer' starts from 0.
After 1 frame the game adds 1 to Local Byte Alfa1:

- If the walking mode is just off (so if Local Byte Alfa1=0 now) then Local Byte Alfa1 becomes 1 now. If the player releases SHIFT maximum after being pressed 5 frames, then the walking mode will switch on.
- If the walking mode is just on (so if Local Byte Alfa=1 now) then Local Byte Alfa1 becomes 2 now. If the player releases SHIFT maximum after being pressed 5 frames, then the walking mode will switch off.

After newer 5 frames the game adds 2 to Local Byte Alfa1 - this is the point when the SHIFT has been pressed for 6 frames, i.e. the point when the pushing becomes 'continuous' instead of 'short':

- If the walking mode is just off (so if Local Byte Alfa=1 now) then Local Byte Alfa1 becomes 3 now. If the player releases SHIFT now or later, then Lara will be running and not walking if the player hits the cursor keys.
- If the walking mode is just on (so if Local Byte Alfa=2 now) then Local Byte Alfa1 becomes 4 now. If the player releases SHIFT now or later, then Lara will be walking and not running if the player hits the cursor keys.

And now let's see what happens in the game exactly in Thread#1:

GlobalTrigger#1 activates TriggerGroup#2 if the condition in TriggerGroup#1 is true, or activates TriggerGroup#3 if that condition isn't true.
TriggerGroup#1 checks if left or right SHIFT is pressed:

; Set Trigger Type - CONDITION 12
; Exporting: CONDITION(12:60) for PARAMETER(42)
; <#> : SHIFT Left
; <&> : Keyboard. <#>keyboard scancode is currently (E)
; (E) : ACTIVE (Single shot for positive condition)
; Values to add in script command: $8000, 42, $10C

; Set Trigger Type - CONDITION 12
; Exporting: CONDITION(12:60) for PARAMETER(54)
; <#> : SHIFT_Right
; <&> : Keyboard. <#>keyboard scancode is currently (E)
; (E) : ACTIVE (Single shot for positive condition)
; Values to add in script command: $8000, 54, $10C

TriggerGroup#2 adds number 1 to Local Byte Alfa2 (at each frame while the condition is true, i.e. while left/right SHIFT is being pressed) and calls PARAM_SHOW_SPRITE=1 Script entry to put the icon on the screen:

; Set Trigger Type - FLIPEFFECT 231
; Exporting: TRIGGER(321:0) for FLIPEFFECT(231)
; <#> : Variables. Numeric. Add to <&>Variable the (E)value
; <&> : Local Byte Alfa2
; (E) : Value 1
; Values to add in script command: $2000, 231, $141

; Set Trigger Type - FLIPEFFECT 357
; Exporting: TRIGGER(1:0) for FLIPEFFECT(357)
; <#> : Sprite. Show sprite with data in <&>Parameters for (E)Durate
; <&> : Parameters=PARAM_SHOW_SPRITE, 1
; (E) : Forever (use other action/effect to disable it)
; Values to add in script command: $2000, 357, $1

TriggerGroup#3 does these things when the player releases left or right SHIFT:

- In every case, it puts the 'timer' (Local Byte Alfa2) into the default 0 value so that the timer will start from 0 when the player hits SHIFT next time:

; Set Trigger Type - FLIPEFFECT 232
; Exporting: TRIGGER(65:0) for FLIPEFFECT(232)
; <#> : Variables. Numeric. Set <&>Variable with (E)value
; <&> : Local Byte Alfa2
; (E) : Value 0
; Values to add in script command: $2000, 232, $41

- If Local Byte Alfa1=1 then the game starts Organizer#1:

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:60) for PARAMETER(64)
; <#> : Local Byte Alfa1
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 1
; Values to add in script command: $8000, 64, $12B

; Set Trigger Type - FLIPEFFECT 127
; Exporting: TRIGGER(1:0) for FLIPEFFECT(127)
; <#> : Organizer. Enable <&>Organizer
; <&> : Organizer= 1
; (E) : 
; Values to add in script command: $2000, 127, $1

If Organizer#1 starts then it starts TriggerGroup#10 at once (see: 0, 10):

; Set Trigger Type - FLIPEFFECT 53
; Exporting: TRIGGER(7:0) for FLIPEFFECT(53)
; <#> : Keyboard. Simulate receivement of <&>keyboard comand in (E) way
; <&> : Walk
; (E) : Single sending
; Values to add in script command: $2000, 53, $7

This trigger makes Lara walk if the player uses the cursor keys without SHIFT pressed.
Thanks to FO_LOOP in the Organizer, this command will be sent again and again (until the Organizer stops) so the walk will be continuous.

- If Local Byte Alfa1=2 then the game

a, stops Organizer#1 so Lara stops walking without SHIFT pressed, and
b, removes the icon off the screen, and
c, subtracts 2 from Local Byte Alfa1 that means 'Lara's not walking and SHIFT isn't pressed, because Local Byte Alfa1=0'.

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:58) for PARAMETER(64)
; <#> : Local Byte Alfa1
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 2
; Values to add in script command: $8000, 64, $22B

; Set Trigger Type - FLIPEFFECT 128
; Exporting: TRIGGER(1:0) for FLIPEFFECT(128)
; <#> : Organizer. Stop <&>Organizer
; <&> : Organizer= 1
; (E) : 
; Values to add in script command: $2000, 128, $1

; Set Trigger Type - FLIPEFFECT 358
; Exporting: TRIGGER(1:0) for FLIPEFFECT(358)
; <#> : Sprite. Remove from the screen the sprite with data in <&>Parameters
; <&> : Parameters=PARAM_SHOW_SPRITE, 1
; (E) : 
; Values to add in script command: $2000, 358, $1

; Set Trigger Type - FLIPEFFECT 233
; Exporting: TRIGGER(576:0) for FLIPEFFECT(233)
; <#> : Variables. Numeric. Substract from <&>Variable the (E)value
; <&> : Local Byte Alfa1
; (E) : Value 2
; Values to add in script command: $2000, 233, $240

- If Local Byte Alfa1=3 then the game

a, removes the icon off the screen (see $2000, 358, $1 above) and
b, subtracts 3 from Local Byte Alfa1 that means 'Lara's not walking and SHIFT isn't pressed, because Local Byte Alfa1=0'.

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:56) for PARAMETER(64)
; <#> : Local Byte Alfa1
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 3
; Values to add in script command: $8000, 64, $32B

; Set Trigger Type - FLIPEFFECT 233
; Exporting: TRIGGER(832:0) for FLIPEFFECT(233)
; <#> : Variables. Numeric. Substract from <&>Variable the (E)value
; <&> : Local Byte Alfa1
; (E) : Value 3
; Values to add in script command: $2000, 233, $340

- If Local Byte Alfa1=4 then the game subtracts 3 from Local Byte Alfa1 (see $2000, 233, $340 above) that means 'Lara's walking and SHIFT isn't pressed, because Local Byte Alfa1=1'.

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:54) for PARAMETER(64)
; <#> : Local Byte Alfa1
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 4
; Values to add in script command: $8000, 64, $42B

GlobalTrigger#2 activates TriggerGroup#5 if the condition in TriggerGroup#4 is true.
TriggerGroup#4 checks if Local Byte Alfa2=1:

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:60) for PARAMETER(65)
; <#> : Local Byte Alfa2
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 1
; Values to add in script command: $8000, 65, $12B

TriggerGroup#5 adds number 1 to Local Byte Alfa1:

; Set Trigger Type - FLIPEFFECT 231
; Exporting: TRIGGER(320:0) for FLIPEFFECT(231)
; <#> : Variables. Numeric. Add to <&>Variable the (E)value
; <&> : Local Byte Alfa1
; (E) : Value 1
; Values to add in script command: $2000, 231, $140

GlobalTrigger#3 activates TriggerGroup#7 if the condition in TriggerGroup#6 is true.
TriggerGroup#6 checks if Local Byte Alfa2=6:

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:50) for PARAMETER(65)
; <#> : Local Byte Alfa2
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 6
; Values to add in script command: $8000, 65, $62B

TriggerGroup#7 adds number 2 to Local Byte Alfa1:

; Set Trigger Type - FLIPEFFECT 231
; Exporting: TRIGGER(576:0) for FLIPEFFECT(231)
; <#> : Variables. Numeric. Add to <&>Variable the (E)value
; <&> : Local Byte Alfa1
; (E) : Value 2
; Values to add in script command: $2000, 231, $240

Local Byte Alfa2 is a 'byte type variable' that means the largest number in it is 255. So if the player holds SHIFT down continuously too long (255 frames=8,5 seconds) then the value in the variable will become 0 at the frame that just follows frame#255 and starts increasing again. Then will become 255 again, then 0 etc. (I.e. this cycle will be repeated: 0-255-0-255-0-255-0 etc.)

Of course, Setup#2 will be bothered if the variable value turns from 255 into 0. That's why we don't let GlobalTrigger#1 increase the value too high. No, it doesn't mean we'll stop the timer (because that disturbs the working of some conditions). Instead of that, we'll always subtract number 1 from Local Byte Alfa2 if GlobalTrigger#1 would like to step over a limit in Local Byte Alfa2.

I adjusted this limit as the frame#8. So, if the player holds SHIFT down at least until 8 frames, then the game subtracts number 1 from those 8 frames. Then the variable value will become 7. If SHIFT is still down then Globaltrigger#1 would give another frame to Local Byte Alfa2 to be 8. But it is 8 again, so the number 1 will be subtracted again, and the value will become 7 again. Etc.

Conclusion: if the player holds SHIFT down at least 8 frames long then Local Byte Alfa2 will become 7 continuously - until TriggerGroup#3 turns it into 0 when the player releases the SHIFT.

It is GlobalTrigger#4 that does that subtraction: if the Condition in TriggerGroup#8 is true (i.e. if Local Byte Alfa2=8) then the game will perform TriggerGroup#9 (i.e. subtracts 1 from Local Byte Alfa2).

; Set Trigger Type - CONDITION 43
; Exporting: CONDITION(43:46) for PARAMETER(65)
; <#> : Local Byte Alfa2
; <&> : Variables. The <#>Numeric Variable is = than (E)Value
; (E) : Value= 8
; Values to add in script command: $8000, 65, $82B

; Set Trigger Type - FLIPEFFECT 233
; Exporting: TRIGGER(321:0) for FLIPEFFECT(233)
; <#> : Variables. Numeric. Substract from <&>Variable the (E)value
; <&> : Local Byte Alfa2
; (E) : Value 1
; Values to add in script command: $2000, 233, $141

In fact, there are short and long type variables whose containers are bigger and much bigger than the container of byte type variables. But we have 3 local long variables, 6 local short variables and 12 local byte variables in the game for each level, and I'd rather used a smaller variable now, instead of wasting a valuable, rarer variable. (Anyway, the subtracting method works perfectly.)

See more about the variables in the Variables demo project of Paolone.

Thread#2:

In this thread, GlobalTrigger#5 activates TriggerGroup#12 if the condition in TriggerGroup#11 is true, or activates TriggerGroup#13 if that condition isn't true.
TriggerGroup#11 checks if Step Left or Step Right key is pressed:

; Set Trigger Type - CONDITION 12
; Exporting: CONDITION(12:60) for PARAMETER(79)
; <#> : END_PAD1
; <&> : Keyboard. <#>keyboard scancode is currently (E)
; (E) : ACTIVE (Single shot for positive condition)
; Values to add in script command: $8000, 79, $10C

; Set Trigger Type - CONDITION 12
; Exporting: CONDITION(12:60) for PARAMETER(81)
; <#> : PAGE_DOWN_PAD3
; <&> : Keyboard. <#>keyboard scancode is currently (E)
; (E) : ACTIVE (Single shot for positive condition)
; Values to add in script command: $8000, 81, $10C

This time we can't call PARAM_SHOW_SPRITE=1 Script entry to put the icon on the screen, because that would disturb the working of Thread#1.
Instead of that, we'll call PARAM_SHOW_SPRITE=2 Script entry to put the icon on the screen. This entry contains exactly the same data as PARAM_SHOW_SPRITE=1 contains. That's why PARAM_SHOW_SPRITE=2 also puts the 'walking person' icon of Texture0 slot on the screen, and also on the '880, 860, 110, 110' coordinates.
(So, if the walking mode is off, then the game puts the same icon in the same position as if the player hit SHIFT. - It is logical.
And, if the walking mode is on, then the game puts the icon on the other icon on the screen, overlapping them with each other. Because the two icons are the same, the player won't sense anything. - That is also logical.)

TriggerGroup#12 will call PARAM_SHOW_SPRITE=2 (if any of those keys is just pressed) and TriggerGroup#13 will remove the icon off the screen (if the player just releases any of those keys):

; Set Trigger Type - FLIPEFFECT 357
; Exporting: TRIGGER(2:0) for FLIPEFFECT(357)
; <#> : Sprite. Show sprite with data in <&>Parameters for (E)Durate
; <&> : Parameters=PARAM_SHOW_SPRITE, 2
; (E) : Forever (use other action/effect to disable it)
; Values to add in script command: $2000, 357, $2

; Set Trigger Type - FLIPEFFECT 358
; Exporting: TRIGGER(2:0) for FLIPEFFECT(358)
; <#> : Sprite. Remove from the screen the sprite with data in <&>Parameters
; <&> : Parameters=PARAM_SHOW_SPRITE, 2
; (E) : 
; Values to add in script command: $2000, 358, $2

(When walking mode is on, the player won't sense that the icon is being removed off the screen, because the other icon - overlapped with it so far - remains on the screen. - And that is also logical.)

Made using TRNG 1.2.2.6