• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[General] Improvement Tips? Learning spells without a "learn" ability thingie

Status
Not open for further replies.
Level 5
Joined
Feb 5, 2021
Messages
89
Hello everybody

I made this thing and it works in a sense, as in it does what its supposed to, but what bothers me is that everytime i press the "buy" button, the screen freezes for about 0.2 - 0.5 seconds, which in itself is not a big deal but considering it could happen a couple thousand times in a session if played through and maybe with a couple probable respecs.

What it should essentially do:
Hero has 10 Lumber and a "Learn" tome costs 1 Lumber
Hero buys "Learn Fire Javelin" -> trigger is checked -> Fire Javelin (Ability) is then added to the hero if he doesnt have it, and it is increased in level if he does have it

In itself i dont feel like it should be an issue?

I have about 10 spells applied this way at the moment, could that be a problem as i expect about 200+ spells when im done?

  • Learn Fire Javelin
    • Events
      • Unit - A unit Acquires an item
    • Conditions
      • (Item-type of (Item being manipulated)) Equal to Learn Fire Javelin
      • ((Hero manipulating item) is A Hero) Equal to True
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Fire Javelin for (Hero manipulating item)) Greater than or equal to 1
          • (Level of Fire Javelin for (Hero manipulating item)) Less than 100
        • Then - Actions
          • Unit - Increase level of Fire Javelin for (Hero manipulating item)
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Fire Javelin for (Hero manipulating item)) Equal to 100
            • Then - Actions
              • Player - Add 1 to (Triggering player).Current lumber
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Fire Javelin for (Hero manipulating item)) Less than 1
                • Then - Actions
                  • Unit - Add Fire Javelin to (Hero manipulating item)
                • Else - Actions
 
Level 39
Joined
Feb 27, 2007
Messages
5,019
I have about 10 spells applied this way at the moment, could that be a problem as i expect about 200+ spells when im done?
What you've written is inefficient and improvable, but even with 20 different triggers of this same kind there's no real reason it should cause a lag blip like that. My intuition is that some OTHER trigger dealing with items is getting caught in an infinite loop until it hits the Op limit and the thread breaks.

If you really are planning to have a bunch of buyable spells like this, it will be in your interest to reduce the total number of triggers and operations being performed, which you can do by setting up a data set (in this case some basic parallel arrays) of all the buyable skill items and which skills they should level up to what maximum level. You would set up your data like this:
  • Data
    • Events
      • Time - Elapsed game-time is 0.50 seconds
      • -------- Don't use the map init event, it can cause map init to hit the op limit if too many things use that event --------
    • Conditions
    • Actions
      • -------- presuming BuyableSpellsCount starts at 0 --------
      • Set BuyableSpellsCount = (BuyableSpellsCount + 1)
      • Set BSItem[BuyableSpellsCount] = Learn Fire Javelin //this is an item-type array
      • Set BSSpell[BuyableSpellsCount] = Fire Javelin //this is an ability code array
      • Set BSMaxL[BuyableSpellsCount] = 100 //maybe they're all 100 and this data is unnecessary to store
      • -------- --------
      • Set BuyableSpellsCount = (BuyableSpellsCount + 1)
      • Set BSItem[BuyableSpellsCount] = Learn Lightning Spear
      • Set BSSpell[BuyableSpellsCount] = Lightning Spear
      • Set BSMaxL[BuyableSpellsCount] = 100
      • -------- --------
      • Set BuyableSpellsCount = (BuyableSpellsCount + 1)
      • Set BSItem[BuyableSpellsCount] = Learn Some Holy Spell
      • Set BSSpell[BuyableSpellsCount] = Holy Spell
      • Set BSMaxL[BuyableSpellsCount] = 100
      • -------- --------
      • Set BuyableSpellsCount = (BuyableSpellsCount + 1)
      • Set BSItem[BuyableSpellsCount] = Learn UBER DEATH SPELL
      • Set BSSpell[BuyableSpellsCount] = ULTIMATE DEATH
      • Set BSMaxL[BuyableSpellsCount] = 5
Cool. Now your trigger can loop through all this data in an Integer A loop and check against all of this data with one trigger rather than a trigger per spell:
  • BSItemPickup
    • Events
      • Unit - A unit acquires an item
    • Conditions
      • -------- Oops, can't filter by item-type here any more, but maybe you can filter by item class if all buyable spells are the same class of item (see below) --------
    • Actions
      • Set BSUnit = (Triggering Unit)
      • Set BSItemType = (Item-type of (Item being manipulated))
      • Set BSIndex = 0
      • For each (Integer A) from 1 to BuyableSpellsCount do (Actions)
        • Loop - Actions
          • If (All conditions are true) then do (Then actions) else do (Else actions)
            • If - Conditions
              • BSItemType equal to BSItem[(Integer A)]
            • Then - Actions
              • Set BSIndex = (Integer A)
              • Custom script: exitwhen true //this leaves the loop early since we found what we were looking for
            • Else - Actions
      • If (All conditions are true) then do (Then actions) else do (Else actions)
        • If - Conditions
          • BSIndex Greater than 0 //if we found a match above we can act on it, if not we should do nothing
        • Then - Actions
          • Set BSLevel = (Level of BSSpell[BSIndex] for BSUnit)
          • If (All conditions are true) then do (Then actions) else do (Else actions)
            • If - Conditions
              • BSLevel equal to 0
            • Then - Actions
              • Unit - Add BSSpell[BSIndex] to BSUnit
              • Custom script: call UnitMakeAbilityPermanent(udg_BSUnit, true, udg_BSSpell[udg_BSIndex]) //makes the new ability persist even if this unit morphs into something else; while not strictly necessary, you probably SHOULD do this so abilities don't randomly disappear
            • Else - Actions
              • If (All conditions are true) then do (Then actions) else do (Else actions)
                • If - Conditions
                  • BSLevel greater than or equal to BSMaxL[BSIndex]
                • Then - Actions
                  • Player - Add 1 to (Owner of BSUnit) Current Lumber
                • Else - Actions
                  • Unit - Set level of BSSpell[BSIndex] for BSUnit to (BSLevel + 1)
        • Else - Actions
Since I don't see any attempt to remove the item from the unit after it has been bought, I'm presuming that these are tomes being sold. If you do not use any other tomes in your map (unlikely, I'd guess) then you can filter out non-buyablespell-related-item-acquisition-events by checking the item-class of the manipulated item. You might be able to reclassify OTHER tomes as something else and still use this comparison, or classify your spell tomes as something like Miscellaneous, etc.
  • Conditions
    • (Item-class of (Item being manipulated)) equal to Powerup
I presume you have some special shop unit-types that sell these ability tomes in your map rather than players just finding them randomly dropped from enemies or having some shops sell a specific spell here and there, so if that's the case then another possible solution would be to change the event to "Unit sells an item (from shop)" and then check the unit-type of the selling unit to see if it's an ability shop:
  • BSItemPickup
    • Events
      • Unit - A unit sells an item (from shop)
    • Conditions
      • Or - Any Conditions are true
        • Conditions
          • (Unit-type of (Selling unit)) equal to FIRE SPELL SHOP
          • (Unit-type of (Selling unit)) equal to LIGHTNING SPELL SHOP
          • (Unit-type of (Selling unit)) equal to HOLY SPELL SHOP
          • (Unit-type of (Selling unit)) equal to DEATH SPELL SHOP
    • Actions
      • Set BSUnit = (Buying Unit)
      • Set BSItemType = (Item-type of Sold Item)
      • -------- everything else the same --------
 
Last edited:
Level 5
Joined
Feb 5, 2021
Messages
89
I have No Words, that is so well detailed and explained that i think i got it reading through it just once and IT looks perfect i cant wait to try and implement it, you hit the mail right on the head, much obliged! :D
 
Level 39
Joined
Feb 27, 2007
Messages
5,019
Glad to help! In general if you find yourself making many versions of the same trigger or kind of trigger, it might be possible to apply an approach like I have done with parallel arrays of data to reduce the redundancy of your triggers. Do be careful of the additional conditional problems that might arise, like in the example above.

I also made an error in my custom script call, which I've fixed now.
 
Level 5
Joined
Feb 5, 2021
Messages
89
Just implemented, works like a charm! wish i could double +rep you for the massive help! it was a pain in the ass to implement a spell in my own way, but this, adding 4 lines for the variables and then it handles everything itself is amazing!
 
It still happens but now only at the first level, or rather the adding the spell part, so that wont be and issue as far as in concerned yet :D
Sounds like a preloading is in order.
 
Level 5
Joined
Feb 5, 2021
Messages
89
D
Sounds like a preloading is in order.
It does sound an aweful lot like that, thanks! Ill look into that as soon as i have time! :D

EDIT:
Found time quite fast, it seems like preloads are only possible from imorted files or .bat files?, how would i preload triggers i have already put in with GUI? :)
 
Last edited:
Status
Not open for further replies.
Top