Health Bars: Enemy
by AkyV

THE PURPOSE:

When Lara is aiming at an enemy (any of them) then the enemy's health bar appears on the screen. Then she's aiming at another one (it doesn't matter who/what), so this new enemy's health bar will show now. (It's tested with automatic targeting adjusted.)

Like this:

Or like this:

(Note: now 'aiming' means when the weapon gets the target, and not when Lara tries to use the lasersight to find the target.)

WHAT IS NEEDED:

Not forgetting about that it's only an example, we need these rows in NG Center\Script:

ColorRGB= 1, 0, 0, 255
ColorRGB= 2, 0, 255, 0
Customize= CUST_BAR, BAR_CUSTOM1, FBAR_SHOW_BAR_NAME, >
280, 30, 120, 20, 1, 2, #0800
GlobalTrigger= 1, IGNORE, GT_CONDITION_GROUP, IGNORE, 1, 2, 3
TriggerGroup= 1, $2000, 244, $1371, $8000, 113, $129
TriggerGroup= 2, $2000, 271, $71, $2000, 351, $0, $2000, 245, $2FF, $2000, 256, $350, >
$2000, 118, $4, $2000, 245, $5450, $2000, 293, $950, >
$2000, 237, $40, $2000, 263, $FF, >
$2000, 287, $50, $2000, 256, $C50, $2000, 288, $50, $2000, 253, $64FF, >
$2000, 331, $4
TriggerGroup= 3, $2000, 332, $4
TriggerGroup= 4, $8000, 80, $128, $2000, 239, $200E, >
$8000+TGROUP_ELSE, 80, $228, $2000, 239, $200F
Parameters= PARAM_BIG_NUMBERS, 10000, 41, 106

And these strings in NG Center\Strings\ExtraNG:

14: grey robed Arabian
15: small scorpion
301: Life energy of #0020

(Note: you cannot choose other ID instead of 301.)

In our example, we have only two kinds of enemies in the level: BADDY_1 and SMALL_SCORPION.

The example is made by TRNG 1.2.2.6

DESCRIPTION (see more in NG Center\Reference and Variables demo project):

1. The look, the position and the contents of the bar

ColorRGB= 1, 0, 0, 255 ;color#1 of the bar
ColorRGB= 2, 0, 255, 0 ;color#2 of the bar
Customize= CUST_BAR, > ;type of customize
BAR_CUSTOM1,> ;ID of the bar
FBAR_SHOW_BAR_NAME, > ;to have a name of the bar (the text in ExtraNG string#301, under the bar)
280, 30, 120, 20, > ;coordinates of the bar
1, 2, > ;references to the ColorRGB's above
#0800 ;it's a numeric variable (Current Value, actually - see NG Center\Reference\Variable Placefolders), that contains the data that the bar shows (Now it's the actual health points of the enemy Lara's just aiming at.)

2. When will the bar appear?

GlobalTrigger= 1, IGNORE, GT_CONDITION_GROUP, IGNORE, 1, 2, 3

The first 1 is just the ID of the GlobalTrigger.
The GT_CONDITION_GROUP says that this GlobalTrigger works only with TriggerGroups.
The 1, 2, 3 are TriggerGroup ID's, and say: 'if TriggerGroup#1 is true, then TriggerGroup#2 (I mean, the appearance of the bar) will happen. If the condition (TriggerGroup#1) is not true, then TriggerGroup#3 will happen'.

3. The condition

TriggerGroup= 1, $2000, 244, $1371, $8000, 113, $129

; Exporting: TRIGGER(4977:0) for FLIPEFFECT(244)
; <#> : Variables. Memory. Copy to <&>Numeric Variable the (E)Savegame Memory value
; <&> : Local Long Beta
; (E) : System. Item Memory address of enemy aimed by Lara (Long)
; Values to add in script command: $2000, 244, $1371


This trigger says: 'if Lara's just aiming at somebody/something, then Local Long Beta=not 0, but some other (positive) number, or else it=0'.
(Attention! You can't use Local Long Beta for other purposes in this level, because it always gets 0 - because of this trigger - when Lara's not aiming at anything. So, even if there isn't any enemy around.)

; Exporting: CONDITION(41:60) for PARAMETER(112)
; <#> : Local Long Beta
; <&> : Variables. The <#>Numeric Variable is >= than (E)Value
; (E) : Value= 1
; Values to add in script command: $8000, 113, $129


This trigger examines if Local Long Beta=0 or more. If it's 0, then there's nobody/nothing aimed at, so there's no need TriggerGroup#2 to happen. (It means that TriggerGroup#3 will happen.) But if it's not 0, then TriggerGroup#2 will happen, the bar will appear.

4. The working of the health bar

TriggerGroup= 2, $2000, 271, $71, $2000, 351, $0, $2000, 245, $2FF, $2000, 256, $350, >
$2000, 118, $4, $2000, 245, $5450, $2000, 293, $950, >
$2000, 237, $40, $2000, 263, $FF, >
$2000, 287, $50, $2000, 256, $C50, $2000, 288, $50, $2000, 253, $64FF, >
$2000, 331, $4

1st block: how to identify object index and slot:

; Exporting: TRIGGER(112:0) for FLIPEFFECT(271)
; <#> : Variables. Numeric. Copy <&>Numeric Variable to CurrentValue
; <&> : Local Long Beta
; (E) :
; Values to add in script command: $2000, 271, $71


Next step we have to use Current Value with the value of Local Long Beta. So this trigger copies the value of Local Long Beta into Current Value.

; Exporting: TRIGGER(0:62) for FLIPEFFECT(351)
; <#> : Variables. Memory. Convert from item address to item index the value in Current Value variable
; <&> : Current Value
; (E) :
; Values to add in script command: $2000, 351, $0


This trigger converts the value of the Current Value. The solution is the index of the object Lara's just aiming at. (Not NGLE index, but the one that the game uses. These are not always the same.) - Now the game knows which enemy's health will be shown in the bar.

; Exporting: TRIGGER(767:62) for FLIPEFFECT(245)
; <#> : Variables. Memory. Copy from <&>Numeric Variable to (E)Savegame Memory
; <&> : Current Value
; (E) : TRNG Index. Item Index for Selected Item Memory (Short)
; Values to add in script command: $2000, 245, $2FF


This trigger uses Savegame Memory to define the object with that game index (the value of the Current Value) as the subject of Selected Item Memory.

; Exporting: TRIGGER(848:0) for FLIPEFFECT(256)
; <#> : Variables. Memory. Copy to <&> Numeric Variable the (E)Selected Item Memory
; <&> : Local Short Alfa1
; (E) : Slot Id (number of slot) (Short)
; Values to add in script command: $2000, 256, $350


This trigger uses Selected Item Memory to write the slot ID number (see NG Center\Reference\Slot Moveables) of the object with that game index into Local Short Alfa1 variable.

; Exporting: TRIGGER(4:0) for FLIPEFFECT(118)
; <#> : TriggerGroup. Perform <&>TriggerGroup from script.dat in (E)way
; <&> : TriggerGroup= 4
; (E) : Mutiple performing (to use when in TriggerGroup there is some condition)
; Values to add in script command: $2000, 118, $4


This trigger activates TriggerGroup#4 to use that slot ID number to define the name of the enemy in the name of the bar. (See more below.)

; Exporting: TRIGGER(21584:0) for FLIPEFFECT(245)
; <#> : Variables. Memory. Copy from <&>Numeric Variable to (E)Savegame Memory
; <&> : Local Short Alfa1
; (E) : TRNG Index. Slot Index for Selected Slot Memory (Short)
; Values to add in script command: $2000, 245, $5450


This trigger uses Savegame Memory to define that slot ID number (the value of Local Short Alfa1) as the subject of Selected Slot Memory.

; Exporting: TRIGGER(2384:0) for FLIPEFFECT(293)
; <#> : Variables. Memory. Copy from (E)Selected Slot Memory to <&>Numeric Variable
; <&> : Local Short Alfa1
; (E) : HP. Max Vitality at start (Short)
; Values to add in script command: $2000, 293, $950


This trigger uses Selected Slot Memory to give a new value to the Local Short Alfa1: the value of the maximal health points (MHP) of the slot with that ID number.
(It uses the new MHP, if we've adjusted it in Enemy script command.)

A problem

The maximum point of the custom bars is always at unit 100. Not more, not less. And this is the cause of the problem below:

Id est, if we have an enemy with 75 MHP, and it's just appeared, and it's still totally healthy, it'll look like as if that creature had injuries now. Because of the 'empty' (black) area between unit 75 and 100. (Just think about it: a creature with 12 MHP will have a huge black area when it's totally healthy. It's useless.)
Moreover:
If we have an enemy with 200 MHP, and it's just appeared, and it's still totally healthy, it won't look to be injured until it's half-healthy. Because of there won't be any black area, until it's healthier than 100 HP.

The solution is: let's use proportion.
I mean, we have to always show the actual MHP like it's at unit 100. For example, when the creature with 75 MHP appears, this 75 value will be shown at the very right edge of the bar, and there won't be any black area. 100/75=1,33, so if the creature is a bit injured (like, 70 HP), then we'll see this 70 HP in the bar at 70�1,33=unit 93. (Attention! We're talking about representation, not changing HP values. So, the 75 HP stays 75 HP, in spite of we'll see this at unit 100.)

But it's partially a theory. I mean, this speech has a wrong part. I'm talking about that the dividing operations, we will use, always use a whole value as a solution. So 100/75=1,33 will be 1. (For example, 100/55=1,82 would be also 1, and not 2.)

Then why do we care about 'proportion' at all? After all, if 100/75=1, then the 75 MHP will never be at unit 100 in the bar, this 75 will always be shown at unit 75. The further part of the description will reply to this question.

2nd block: how to show the health

; Exporting: TRIGGER(64:0) for FLIPEFFECT(237)
; <#> : Variables. Store. Copy <&>Store variable to CurrentValue
; <&> : Store Byte A1
; (E) :
; Values to add in script command: $2000, 237, $40


Let's suppose that we've never used Store Byte A1 in the game before. (So it has the default 0 value.) Or if we have, then choose another variable for this trigger. What matters is that that this variable has to be 0 value. And this 0 value will be copied into Current Value now, giving a new value to it. (This trigger is maybe not needed. But I sometimes realized that 'set' operations don't work well, if the variable that the operation uses, is not 0. And Current Value is not 0 now - see: $2000, 245, $2FF above -, meanwhile the next trigger is a 'set' operation, with Current Value.)

; Exporting: TRIGGER(255:0) for FLIPEFFECT(263)
; <#> : Variables. Numeric. Set in <&>Numeric Variable the (E)Big Number value
; <&> : Current Value
; (E) : Value of Parameters=PARAM_BIG_NUMBERS at index= 0
; Values to add in script command: $2000, 263, $FF


This trigger uses the position#0 of PARAM_BIG_NUMBERS. The value we'll find there is 10000. This trigger sets this value in Current Value, giving a new value to it.

; Exporting: TRIGGER(80:0) for FLIPEFFECT(287)
; <#> : Variables. Numeric. Divide CurrentValue by <&>Numeric Variable
; <&> : Local Short Alfa1
; (E) :
; Values to add in script command: $2000, 287, $50


This trigger divides value 10000 (the value of Current Value) by the MHP of the actual slot (the value of Local Short Alfa1), giving a new value to the Current Value. This is the point where we calculate the hundredfold of any proportion, for example, that 100/75=1,33 proportion: 10000/75=133.

(I think it will never happen, but I tell: MHP can never be bigger than this 10000.) 

; Exporting: TRIGGER(3152:0) for FLIPEFFECT(256)
; <#> : Variables. Memory. Copy to <&> Numeric Variable the (E)Selected Item Memory
; <&> : Local Short Alfa1
; (E) : HP (Current life level. $C000 = unkillable) (Short)
; Values to add in script command: $2000, 256, $C50


The object with that game index is still the subject of the Selected Item Memory. This trigger uses the Selected Item Memory to copy the actual HP of that object into the Local Short Alfa1, giving a new value to this variable.

; Exporting: TRIGGER(80:0) for FLIPEFFECT(288)
; <#> : Variables. Numeric. Multiply CurrentValue by <&>Numeric Variable
; <&> : Local Short Alfa1
; (E) :
; Values to add in script command: $2000, 288, $50


This trigger multiplies the value of Current Value by the Value of Local Short Alfa1, giving a new value to the Current Value.

For example, if the enemy with 75 MHP has 70 HP now, then the solution is 133�70=9310 now.

; Exporting: TRIGGER(25855:0) for FLIPEFFECT(253)
; <#> : Variables. Numeric. Divide <&>Numeric Variable by (E)Value
; <&> : Current Value
; (E) : Value 100
; Values to add in script command: $2000, 253, $64FF


This trigger divides Current Value by 100, giving a new value to this. The solution with that 70 HP: 9310/100=93,1, I mean 93. - And this 93 is the unit where the 70 HP will be seen in the bar.
(So, we can see now, using the hundredfold of the proportion, we could prevent the problem of "the solution of the dividing operation is a whole number" thing.
If we'll perhaps realize that this is still a bit unaccurate - because the appearance of the MHP is not at unit 100 but 98-99 -, and it bothers us, then let's increase on the proportion: not hundredfold, but thousandfold etc. But this time don't forget dividing by not 100, but 1000 etc.)

; Exporting: TRIGGER(516:0) for FLIPEFFECT(331)
; <#> : Custom Bar. Show the <&>Custom bar on screen for (E)Seconds
; <&> : BAR_CUSTOM1
; (E) : Forever (use other action/effect to disable it)
; Values to add in script command: $2000, 331, $4


This trigger puts (updates) the health bar on the screen. - So, if the former creature's actual HP is 70 now, then we'll see it at unit 93 in the bar. (Because the bar uses the Current Value to show - see Customize command above - and that is 93 now.)

5. Disappearing the bar

If the condition (TriggerGroup#1) is not true (i.e. Lara is not aiming at anybody/anything), then TriggerGroup#3 will be activated.

TriggerGroup= 3, $2000, 332, $4

; Exporting: TRIGGER(4:0) for FLIPEFFECT(332)
; <#> : Custom Bar. Hide the <&>Custom bar
; <&> : BAR_CUSTOM1
; (E) :
; Values to add in script command: $2000, 332, $4


This trigger can cause two things:

a, It makes the bar disappear off the screen, if Lara has just shot the enemy dead, or if the enemy that Lara's just been aiming at has escaped, and there's nobody/nothing else to aim at now.
b, There hasn't been any 'aiming and shooting event' lately, so there's no custom bar on the screen just now, so there isn't anything to disappear.

6. The name of the enemy

TriggerGroup= 4, $8000, 80, $128,$2000, 239, $200E, >
$8000+TGROUP_ELSE, 80, $228, $2000, 239, $200F

The name of the bar (ExtraNG String#301) will automatically appear and disappear with the bar together. This name is 'Life energy of #0020' now. #0020 is a text variable, Text1. This variable contains the name of the actual enemy. So when Lara's aiming at an enemy, the name of the enemy's health bar will show this enemy's name, too. (Not the enemy's slot name, because it could be lame enough sometimes, appearing on the screen. For example: 'Life energy of BADDY_1'???)

; Exporting: CONDITION(40:60) for PARAMETER(80)
; <#> : Local Short Alfa1
; <&> : Variables. The <#>Numeric Variable is = than (E)Big Number value
; (E) : Value of Parameters=PARAM_BIG_NUMBERS at index= 1
; Values to add in script command: $8000, 80, $128


This trigger uses the position#1 of PARAM_BIG_NUMBERS. The value we'll find there is 41 - this is one of the enemy slot ID's of our level. The slot ID of BADDY_1. The trigger examines the slot ID in Local Short Alfa1. (See: $2000, 256, $350 above.) If the variable equals with position#1, then this condition is true, because the enemy Lara's just aiming at is a BADDY_1.

; Exporting: TRIGGER(8202:0) for FLIPEFFECT(239)
; <#> : Variables. Text. Copy the <&>NG String to (E)Text Variable.
; <&> : 14: grey robed Arabian
; (E) : Text1 (79 characters)
; Values to add in script command: $2000, 239, $200E


Because the enemy Lara's just aiming at is a BADDY_1, this trigger gives #0020 (Text1) variable the value of ExtraNG String#14: 'grey robed Arabian'. So the actual name of the bar will be 'Life energy of grey robed Arabian' now.

; Exporting: CONDITION(40:58) for PARAMETER(80)
; <#> : Local Short Alfa1
; <&> : Variables. The <#>Numeric Variable is = than (E)Big Number value
; (E) : Value of Parameters=PARAM_BIG_NUMBERS at index= 2
; Values to add in script command: $8000, 80, $228


This trigger uses the position#2 of PARAM_BIG_NUMBERS. The value we'll find there is 106 - this is one of the enemy slot ID's of our level. The slot ID of SMALL_SCORPION. The trigger examines the slot ID in Local Short Alfa1. If the variable equals with position#2, then this condition is true, because the enemy Lara's just aiming at is a SMALL_SCORPION.

; Exporting: TRIGGER(8203:0) for FLIPEFFECT(239)
; <#> : Variables. Text. Copy the <&>NG String to (E)Text Variable.
; <&> : 15: small scorpion
; (E) : Text1 (79 characters)
; Values to add in script command: $2000, 239, $200F


Because the enemy Lara's just aiming at is a SMALL_SCORPION, this trigger gives #0020 (Text1) variable the value of ExtraNG String#15: 'small scorpion'. So the actual name of the bar will be 'Life energy of small scorpion' now.

7. New enemy

If you use the rows above in Script, then you'll automatically see any actual enemy's health bar of the level. So even the enemy that is not named in TriggerGroup#4. But if you have any other enemy in the level, not (only) BADDY_1 and SMALL_SCORPION of the example, then you have to do these things too see properly the name of the bar at this new type of enemy:

1. Write the enemy name you want to see in the name of the bar into a (any) string of ExtraNG - for example string#16.
2. Write this enemy's slot ID number into a position of PARAM_BIG_NUMBERS - for example position#3.
3. After the last trigger of the TriggerGroup#4, write a CONDITION (PARAMETER) trigger: "Variables. The <#>Numeric Variable is = than (E)Big Number value". #=Local Short Alfa1, E=PARAM_BIG_NUMBERS position#3. Don't forget using "TGROUP_ELSE" constant after the number $8000 of the trigger.
4. After the CONDITION you've just written, write a FLIPEFFECT TRIGGER: "Variables. Text. Copy the <&>NG String to (E)Text Variable". &=16, E=Text1.

8. Exceptions

So with those rows you'll see any actual enemy's health bar. But what if you don't want to see the health bar of the actual enemy when it belongs to some enemy type? Because you think it's unnecessary. For example the health bar of the invulnerable SPHINX or the SENTRY_GUN that is not a creature. - Do this:

1. Write this enemy's slot ID number into a position of PARAM_BIG_NUMBERS - for example position#4.
2. Between $2000, 256, $350 and $2000, 118, $4 triggers of TriggerGroup#2, write a CONDITION trigger: "Variables. The <#>Numeric Variable is = than (E)Big Number value". #=Local Short Alfa1, E=PARAM_BIG_NUMBERS position#4. Don't forget using "TGROUP_NOT" constant after the number $8000 of the trigger.