• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Creating Special Effect on building during training/research

Status
Not open for further replies.
Level 6
Joined
Jan 12, 2014
Messages
59
Hello !

I'm creating custom LOTR races for fun and i'd like to create special effects on active buildings to show that they are training something (because i used doodads and things like that)

I did something not very optimal. Basically, i check if the building has not an effect on him (by checking if variables are empty), if tha variable is empty : it takes it, if not, i check the next variable etc.
The issue is that many buildings of the same type must exist and each must have his OWN EFFECT so its own variable !

1686743058552.png

Here's the detection :
1686742985027.png


Then it creates the special effect
1686743018342.png



And finally it stops it and clear everything
1686743192825.png


BUT, i need to copy paste and create new variables as much as "this kind of the building" may be built... :/

I'm not a programmer , nor a very good logic-guy , i think i missed a clever and more simple solution !


PS : it doesnt work for researches ... how can i detect a unit training or research within 1 trigger ?

Thanks !
 

Attachments

  • 1686743034630.png
    1686743034630.png
    6.7 KB · Views: 5
Level 24
Joined
Feb 27, 2019
Messages
833
There is an option to turn a variable into an array. Imagine several regular variables being stacked on top of each other in a huge tower. The one furthest down is [0], the one on top of that is [1] and so on up to the one on the top which is at least [8191]. Instead of creating OrthancTraining1 and OrthancTraining2 one can simply create OrthancTraining as an array and use the index (the number put inside the brackets) to decide which stacked variable to change/use. The game only create the stacked variables when they are used and for most variables the array size can be left at 1. There are some variables that require that the array size is set beforehand to work inside the game and I dont remember all of them but unit groups and timers are two of them.

This next code will hopefully show how it can be useful and I am keeping it simple and not very good or effecient so its easier to understand.

OrthancMax = integer
OrthancUnit[] = unit array
OrthancEffect[] = special effect array
OrthancL = integer


A unit begins training a unit
set OrthancMax = OrthancMax + 1
set OrthancUnit[OrthancMax] = GetTriggerUnit()
create a special effect at position of unit
set OrthancEffect[OrthancMax] = GetLastCreatedEffectBJ()

A unit finishes training a unit
set OrthancL = 1
loop
exitwhen OrthancL > OrthancMax
if OrthancUnit[OrthancL] = GetTriggerUnit() then
destroy OrthancEffect[OrthancL]
set OrthancUnit[OrthancL] = null
return
endif
set OrthancL = OrthancL + 1
endloop

As you can see OrthancMax will keep increasing and the loop will become very big, maybe until it reaches the max size and the system breaks. There is a good recycling system called dynamic index that will keep the array size only as big as it has to be so you can look at it here Visualize: Dynamic Indexing
 
Level 6
Joined
Jan 12, 2014
Messages
59
There is an option to turn a variable into an array. Imagine several regular variables being stacked on top of each other in a huge tower. The one furthest down is [0], the one on top of that is [1] and so on up to the one on the top which is at least [8191]. Instead of creating OrthancTraining1 and OrthancTraining2 one can simply create OrthancTraining as an array and use the index (the number put inside the brackets) to decide which stacked variable to change/use. The game only create the stacked variables when they are used and for most variables the array size can be left at 1. There are some variables that require that the array size is set beforehand to work inside the game and I dont remember all of them but unit groups and timers are two of them.

This next code will hopefully show how it can be useful and I am keeping it simple and not very good or effecient so its easier to understand.

OrthancMax = integer
OrthancUnit[] = unit array
OrthancEffect[] = special effect array
OrthancL = integer


A unit begins training a unit
set OrthancMax = OrthancMax + 1
set OrthancUnit[OrthancMax] = GetTriggerUnit()
create a special effect at position of unit
set OrthancEffect[OrthancMax] = GetLastCreatedEffectBJ()

A unit finishes training a unit
set OrthancL = 1
loop
exitwhen OrthancL > OrthancMax
if OrthancUnit[OrthancL] = GetTriggerUnit() then
destroy OrthancEffect[OrthancL]
set OrthancUnit[OrthancL] = null
return
endif
set OrthancL = OrthancL + 1
endloop

As you can see OrthancMax will keep increasing and the loop will become very big, maybe until it reaches the max size and the system breaks. There is a good recycling system called dynamic index that will keep the array size only as big as it has to be so you can look at it here Visualize: Dynamic Indexing

Wow, thanks i think i get the idea, but putting it together is another problem haha

I tried to do as you said but the script has errors it says and i can't put the finger what it is !
1686765526720.png


My endif has an error too
1686765572459.png
 
Level 24
Joined
Feb 27, 2019
Messages
833
The return might be wrong. It can be removed or replaced with exitwhen true. exitwhen true means the loop will end when the if statement its inside of is true. return normally ends the entire function so I am not 100% sure.

It looks like you havnt enabled jasshelper. Without it youll get dumb errors and with it better hints on whats wrong. Make sure its ticked. Restart the editor afterwards.
Trigger editor > JassHelper > Enable JassHelper
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
You forgot an endloop and an endif in your OrthancEnd trigger.

When you use a loop:
  • Custom script: loop
It will loop all of the Actions placed below it UNTIL it detects an endloop telling it to stop:
  • Custom script: endloop
The endloop is a must!

The same goes for an if then statement:
  • Custom script: if 5 + 5 == 10 then
  • // put actions here
  • Custom script: endif
But why are you using this Custom Script in the first place? Seems a bit unnecessary, can't you just use the GUI alternatives?

Also, you don't need to "use JassHelper", it's just a debugging tool that needs to be enabled. It should really be enabled by default but the Blizzard dev(s) have no idea what they're doing.
 
Level 14
Joined
Jan 10, 2023
Messages
247
Also, Do Nothing does literally nothing, you don't ever need to use it (apparently it was necessary ages ago).
You 'need' it for GUI if/then/else (singular condition/action) if either the 'then' or 'else' is blank, or you could do an empty custom script, but I think they wanted something straightforward for people who don't know code.

I like the solution that has been given, but a small change that would allow for Upgrades/Research:
Use the order string.
When a unit is given a train/research order, the order string is the name of the trained unit/ upgrade.

You could use this to do both, instead of "A Unit Begins Training a Unit" or "A Unit Begins Researching an Upgrade", use "A Unit is issued an order with no target" and then use conditions to check the order string.
 
Status
Not open for further replies.
Top