HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Gemstone Obelisk Tutorial

08-25-2002, 08:34 PM#1
Guest
I've been getting many emails from people asking about the gemstone obelisks in Tomb Raiders. So I've decided to put together a small tutorial. It should help in other areas besides handling gemstone obelisks.

First thing we need to be aware of is that we are dealing with a multithreaded environment, meaning there can be multiple instances of the same trigger running at the same time. For example a triger that checks if a hero targets an obelisk with a gem, the hero should take the gemstone. The problem is, if there is more than one hero selected by the player when the order is given, the trigger runs for each of them and they each get a gem. Originally one gem is on the obelisk, now each ordered hero has one.

On the other hand, if you want a hero to be able to place a gemstone onto an obelisk and multiple heroes are selected and issued the order, you will get multiple displays (one for each hero ordered).

Lets look at a scenario:

Hero Paladin has a Enchanted Gemstone
Hero Cleric has a Fire Gemstone
Hero Dwarf has a Lightning Gemstone

All three heroes are selected and an order is given by the player targetting an obelisk that wants the Fire Gem. You will see 3 messages:
"The Enchanted Gemstone doesnt fit"
"Your Cleric places the Fire Gemstone onto the obelisk"
"Your Dwarf takes the Fire Gemstone from the obelisk"

The trigger runs and displays a message for each of the heroes. Obviously this isn't the effect were after here. We want only one message to show. So we have the trigger temporarily disable itself when its first called. Now we get one message "The Enchanted Gemstone Doesn't Fit." The problem here is that one of the ordered heroes has the correct gemstone but the trigger doesnt know that, because it has been disabled.

So how do we solve this problem? An answer is in the use of arrays. We need to build an array of all of the heroes using the obelisk before we have the trigger check to see if any of the ordered heroes have the correct gemstone.

Variables used:
(integer) ObeliskOrderCount // initially set to -1 (array index)
(integer) ObeliskOrderMax // Number of heroes ordered (array size)
(unit array) ObeliskHeroArray // an array to hold ordered heroes
(boolean) ObeliskHasGem // True if obelisk has gem, False if no gem
(integer) NumPlayers // number of players (for wait)

Trigger:
Build Array of Heroes using Obelisk
Event:
Unit - A unit owned by Player 1 (red) is issued an order targetting an object
(and copy for each player side here)
Condition:
((Ordered unit) is a Hero) equal to True
Actions:
--- initialize the size of the array ---
if (ObeliskOrderCount equal to -1) then do (set ObeliskOrderMax = -1) else do (Do nothing)
--- Increment array index ---
set ObeliskOrderCount = (ObeliskOrderCount + 1)
--- Store Ordered Unit into the array ---
set ObeliskHeroArray [ObeliskOrderCount] = (ordered unit)
--- Keep track of how many entries in the array ---
if (ObeliskOrderCount Greater than ObeliskOrderMax) then do (set ObeliskOrderMax = ObeliskOrderCount) else do nothing
--- very small pause for each player to catch and record each instance---
for each (integer A) from 1 to NumPlayers, do (wait 0.10 seconds)
--- Decrement array index ---
set ObeliskOrderCount = (ObeliskOrderCount - 1)
--- Skip Here for all but the first instance of this trigger ---
if (ObeliskOrderCount Greater than -1) then do (skip remaining actions) else do (Do nothing)
--- ---
--- All multithreads should be done and now we are working with just the first instance ---
--- ---
--- At this point we have the following values in our variables: ---
--- ObeliskHeroArray[] contains all of the heroes ordered
--- ObeliskOrderMax contains the number of entries in that array.
--- ---

Now we have an array built of all heroes that have issued an order to the obelisk and we know how many heroes were ordered (size of the array). From here its a simple matter of just checking to see if the obelisk has a gem already and if it does we can give it to a hero. If the obelisk does not already have a gemstone, we can see if any of the heroes in the array has it to place and place it on the obelisk. If none of the heroes in the array has the correct gem, we can simply display a message saying the obelisk is missing its gemstone. Of course you will still have to apply "range checking" to see if any one hero is close enough to even access the obelisk.

The portion of the trigger above that builds the ObeliskHeroArray also "debounces" any multi-threading (multiple instances) so we wont have multiple messages or multiple items given. This idea can be used in many different ways.

I hate to do it, but its time for a shameless plug. I used a system based on this idea to handle the obelisks in my map, "Tomb Raiders" to get a better idea of its application, take a look at that map.

I hope this answers more questions than it creates. Please post any questions you still have, and I'll do my best to answer them.
08-30-2002, 04:46 PM#2
Guest
Ashe.. are you a mathimatition or something... just skimming over what you wrote up there gave me a head ache. hehe I thank ya again for you help with my door problem and I may end up using (one day) this for another map. We all appreciate everyones help to those of us who are... dense when it comes to understanding .... whatever you said up there. My problem is I want to understand why a variable is what it is and why it does what it does. I like simple staight to the point answers. The basic answer for what an array and variable doesn't answer my question well enough. Yes an array is a group of numbers... guess i'm over analyzing. /shrug

Unit - be mean to everyone except the player whos single digit hero's level is divisable by todays date.

But to get that effect in game you have to string this trigger and that trigger. While its heartwarming at the end when your hard work pays off.... the migrain it gives before that sucks! hehe
08-30-2002, 05:30 PM#3
Guest
LoL... I hear ya bro. This tutorial is definately a deep one. The concept of multithreading can tend to give one a headache. I'm sure many of us have experienced the multiple messages when triggers are set off with a group.

Thanks for the feedback. *GRIN*
08-30-2002, 10:23 PM#4
Guest
lol wow...that was a lot of crap lol...whenever i'm using a gemstone obelisk, i usually just have a boolean determining whether it has the gem or not, and if a hero comes within 512 of it, the gem is given to the triggering unit, the boolean is set to true or false (depending on weather true means it has the gem, or it means the gems been taken), and the obelisk is replaced with another that doesn't have a gem on it.
09-01-2002, 07:17 PM#5
Guest
Quote:
Originally posted by ankaa
lol wow...that was a lot of crap lol...whenever i'm using a gemstone obelisk, i usually just have a boolean determining whether it has the gem or not, and if a hero comes within 512 of it, the gem is given to the triggering unit, the boolean is set to true or false (depending on weather true means it has the gem, or it means the gems been taken), and the obelisk is replaced with another that doesn't have a gem on it.

Yeah, but there are issues with doing it that way... for example, as written above:

"...if you want a hero to be able to place a gemstone onto an obelisk and multiple heroes are selected and issued the order, you will get multiple displays (one for each hero ordered).

Lets look at a scenario:

Hero Paladin has a Enchanted Gemstone
Hero Cleric has a Fire Gemstone
Hero Dwarf has a Lightning Gemstone

All three heroes are selected and an order is given by the player targetting an obelisk that wants the Fire Gem. You will see 3 messages:
'The Enchanted Gemstone doesnt fit'
'Your Cleric places the Fire Gemstone onto the obelisk'
'Your Dwarf takes the Fire Gemstone from the obelisk'

The trigger runs and displays a message for each of the heroes. Obviously this isn't the effect were after here. We want only one message to show. So we have the trigger temporarily disable itself when its first called. Now we get one message 'The Enchanted Gemstone Doesn't Fit.' The problem here is that one of the ordered heroes has the correct gemstone but the trigger doesnt know that, because it has been disabled. ..."

With an array of obelisks (each requiring a different gemstone), the problem will quickly be apparent. I'm not one to settle on "forcing" the user to only select and use one hero to get things done in a map. This is just one way around that.
09-06-2002, 11:25 PM#6
Guest
How exactly do you set it to give a gemstone to an obelisk or take a gemstone from an obelisk? I don't really care about multiple heros yet I just want to get it working with one first :p
09-07-2002, 08:02 PM#7
Guest
You will need a boolean variable to store whether or not the obelisk actually has a gemstone on it or not, but to change the graphic you can simply use an animation:

(boolean) ObeliskHasGem

Show Gemstone:
Set ObeliskHasGem = TRUE
Animation - Play Obelisk <gen>'s Stand Animation

...

Remove Gemstone
Set ObeliskHasGem = FALSE
Animation - Play Obelisk <gen>'s Stand Second Animation


Just for future reference, you can look up the Animation "names" for each unit, in the World Edit. They will be listed above the graphic of the unit selected.
09-07-2002, 09:08 PM#8
Guest
thanks :)