1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Spell - Attribute Scaling Summoning Spell

Discussion in 'Triggers & Scripts' started by rkemsley, Mar 1, 2019.

  1. rkemsley

    rkemsley

    Joined:
    Sep 25, 2018
    Messages:
    21
    Resources:
    0
    Resources:
    0
    I have been trying to create a spell which has a max number of summons based on your primary attribute.

    I have based it on Summon Water Elemental. So the stats of the summon are based on the level of the spell (e.g. level 1 summon has 500 health, 40 damage. level 2 summon has 600 health, 50 damage.).

    So basically, if you have 25 intelligence, you can only have one summon spawned at a time. If you have 50 intelligence, you can have 2 and so on.

    Just wondering how I would trigger this.

    Obviously if you go over the amount of summons you can have, the first one will die to make room for the new one.

    (I was also hoping to make the duration of the summons scale as well. That would be ideal)
     
  2. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    800
    Resources:
    2
    Spells:
    2
    Resources:
    2
    Triggered summons
    Unit - Set Expiration - ((Hero - Attribute Int) x 10)
    Unit - Set Classification - (Summoned)
    Unit - Set Max HP ((Hero - Attribute Int) x 20)
    Unit - Set Attack Damage ((Hero - Attribute Int) x 4)
    Etc

    As for limited number you need a variable that follows the specific unit, I would use Bribe's indexing that uses the custom unit value or hastables.

    I'll take a whack at making it but no promises.

    ETA: I wasn't able to limit the summons unfortunately, otherwise it fits the rest of your description.
     

    Attached Files:

    Last edited: Mar 2, 2019
  3. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,905
    Resources:
    1
    Spells:
    1
    Resources:
    1
    If only a few units on the map need to be able to cast this spell then you can keep track of them all with their own variables (or an array: see the Dynamic Indexing tutorial). Pretty easy to do as Devalut described above.
     
  4. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    800
    Resources:
    2
    Spells:
    2
    Resources:
    2
    Yes absolutely simple, I was just testing you...
    @Pyrogasm you should do an example case anyone doesn't fully understand.
    [​IMG]
     
  5. Tasyen

    Tasyen

    Joined:
    Jul 18, 2010
    Messages:
    1,304
    Resources:
    16
    Tools:
    2
    Maps:
    2
    Spells:
    7
    Tutorials:
    4
    JASS:
    1
    Resources:
    16
    Maybe this ones might help to archive the wanted summon limit.

    Option: Time Stamps
    For each summon the time elapsed since starting the game is saved. On summon get all the summoners summons, count them and if the limit was exceed remove the one with the lowest time stamp.

    Option: Linked List
    One saves all summons and their summoner in a linked list, by using a linked list the units are ordered they way they were added. On summon loop the list find summons of that unit and remember oldest, kill the oldest if the limit is exceed.
     
  6. rkemsley

    rkemsley

    Joined:
    Sep 25, 2018
    Messages:
    21
    Resources:
    0
    Resources:
    0
    Thanks guys for the response! I'll give that a shot and see how it comes out.
     
  7. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,905
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Linked list and dynamically allocated 2-D arrays were actually much harder to work with in GUI than I thought/remembered. Via PM to Devalut I wrote out this possible solution using a hashtable and timestamps as Tasyen suggested.

    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • -------- set up hashtable --------
      • -------- start a repeating countdown timer with max duration that you'll never stop --------


    • Events
      • Unit - A unit spawns a summoned unit
    • Conditions
      • -------- can filter by unit type of summon here --------
    • Actions
      • Set CasterKey = Key(Summoning Unit)
      • Set SummonKey = Key(Summoned Unit)
      • Set SummonTime = (Elapsed time for TIMER)
      • If (conditions) then (actions) else (actions)
        • If - Conditions
          • (Load boolean (CasterKey, 0) from HASH) equal to false //boolean for was it previously cast? no GUI way to check if the group is null
        • Then - Actions
          • Custom script: set udg_SummonGroup = CreateGroup() //note that these groups have to be initialized when a caster casts for the first time
            • Hashtable - Save SummonGroup as (CasterKey, 1) in HASH
            • Hashtable - Save true as (CasterKey, 0) in HASH
        • Else - Actions
          • Set SummonGroup = Load unit group handle (CasterKey, 1) from HASH
      • If (conditions) then (actions) else (actions)
        • If - Conditions
          • (Number of units in SummonGroup) greater than or equal to LIMIT //set the limit however you want
        • Then - Actions
          • -------- search for oldest and remove it --------
          • Set MaxDuration = 0.00
          • Unit Group - Pick every unit in SummonGroup and do (Actions)
            • Loop - Actions
              • Set TempReal = SummonTime - Load real handle (Key(Picked Unit), 1) in HASH
              • If (conditions) then (actions) else (actions)
                • If - Conditions
                  • TempReal Greater than MaxDuration
                • Then - Actions
                  • Set MaxDuration = TempReal
                  • Set TempUnit = (Picked Unit)
                • Else - Actions
          • Unit - Kill TempUnit //this runs cleanup in the third trigger so we don't have to do it here
        • Else - Actions
      • Unit Group - Add (Summoned Unit) to SummonGroup
      • Hashtable - Save CasterKey as (SummonKey, 0) in HASH //so we can figure out who the caster was that spawned a summoned unit that dies
      • Hashtable - Save SummonTime as (SummonKey, 1) in HASH


    • Events
      • Unit - A unit dies //god forbid if this doesn't run on summoned unit dispel or life expiration
    • Conditions
      • -------- don't actually need anything here --------
    • Actions
      • If (conditions) then (actions) else (actions)
        • If - Conditions
          • -------- check for summoned unit types here --------
        • Then - Actions
          • Set SummonKey = Key(Triggering Unit)
          • Set CasterKey = Load integer (SummonKey, 0) from HASH
          • Unit Group - Remove (Triggering Unit) from (Load group (CasterKey, 1)
          • Hashtable - Flush all children of SummonKey in HASH //data cleanup
        • Else - Actions
      • If (conditions) then (actions) else (actions)
        • If - Conditions
          • (Level of SPELL for (Triggering Unit)) greater than 0
        • Then - Actions
          • Set CasterKey = Key(Triggering Unit)
          • -------- what you do here is up to you, the group needs to be removed and the hashtable needs to have its caster stuff flushed --------
            • -------- you have to decide what to do with the extant summons: do they get killed? do they live out their lifetime? if the caster can be revived while some of them are still alive, what then? --------
              • -------- I'd say just kill them all, but in any case something like the following needs to be done at the right time if the same unit is not ever expected to create more summons --------
            • Set SummonGroup = Load group handle (CasterKey, 1) in HASH
            • Custom script: call DestroyGroup(udg_SummonGroup)
            • Hashtable - Flush all children of CasterKey in HASH
     
  8. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    2,905
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Just noticed this part. I wrote my example above presuming that you specifically wanted to spawn the summons with a summoning ability. With this in mind, however, it makes way more sense run a spellcast trigger (instead of a summoned unit trigger) and create the summons manually with that trigger. Then you can apply whatever duration timed life you want, just remember to also give the units the 'summoned' classification after you make them else they can't be dispelled.
     
  9. Uncle

    Uncle

    Joined:
    Aug 10, 2018
    Messages:
    438
    Resources:
    0
    Resources:
    0
    I was bored and this seemed like a fun challenge. I like Pyrogasm's method, but I figured why not so here's my take on it. Let me know how I can improve it if anyone sees anything.

    I store the Water Elementals using a Unit Indexer/Hashtable and then store them in the order in which they were summoned (I assume similar to like a Linked List as Taysen said). There's most likely a better way to do this but this way made the most sense to me :p

    Edit: Fixed some issues with Intelligence loss/gain breaking the Summon Limit.

    • Summon Water Ele MUI
      • Events
        • Unit - A unit Spawns a summoned unit
      • Conditions
        • Or - Any (Conditions) are true
          • Conditions
            • (Unit-type of (Summoned unit)) Equal to SummonType[1]
            • (Unit-type of (Summoned unit)) Equal to SummonType[2]
            • (Unit-type of (Summoned unit)) Equal to SummonType[3]
      • Actions
        • -------- Variables --------
        • -------- - --------
        • Set Spawn = (Summoned unit)
        • Set Caster = (Summoning unit)
        • Set CastingPlayer = (Owner of (Summoning unit))
        • Set Index = (Custom value of Caster)
        • -------- Set Ability Modifiers --------
        • -------- - --------
        • Set AbilityLevel = (Level of (Ability being cast) for Caster)
        • Set HeroInt = ((Intelligence of Caster (Include bonuses)) / 25)
        • Set Summon_Limit[Index] = (1 x (1 + HeroInt))
        • Unit - Add a ((Real(45)) + ((Real(15)) x (Real(HeroInt)))) second Water Elemental expiration timer to Spawn
        • -------- Set the summon order of the Water Elemental (Summon_Open represents which # the next Ele will be) --------
        • -------- - --------
        • Set Summon_Open[Index] = ((Number of units in Summon_UG[Index]) + 1)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • Summon_Open[Index] Greater than Summon_Limit[Index]
          • Then - Actions
            • Set Summon_Open[Index] = Summon_Limit[Index]
          • Else - Actions
        • -------- Kill extra Water Elementals if your Summon Limit has changed (Lost Intelligence for example) --------
        • -------- - --------
        • Set SummonCount = (Number of units in Summon_UG[Index])
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • SummonCount Greater than Summon_Limit[Index]
          • Then - Actions
            • Set TempInt = ((SummonCount + 1) - Summon_Limit[Index])
            • For each (Integer A) from 1 to TempInt, do (Actions)
              • Loop - Actions
                • Unit Group - Add (Load (Integer A) of Index in SummonHash) to SummonExcess
            • Unit Group - Pick every unit in SummonExcess and do (Actions)
              • Loop - Actions
                • Unit - Kill (Picked unit)
          • Else - Actions
        • -------- Replace Oldest Elemental (If new one is over the limit) --------
        • -------- - --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • SummonCount Equal to Summon_Limit[Index]
          • Then - Actions
            • Unit - Kill (Load 1 of Index in SummonHash)
          • Else - Actions
        • -------- Add the new Elemental to the UG and store it and the caster to the Hashtable --------
        • -------- - --------
        • Unit Group - Add Spawn to Summon_UG[Index]
        • Hashtable - Save Handle OfSpawn as Summon_Open[Index] of Index in SummonHash
        • Set SummonIndex = (Custom value of Spawn)
        • Hashtable - Save Handle OfCaster as Summon_Open[SummonIndex] of SummonIndex in SummonHash


    • Water Ele Death MUI
      • Events
        • Unit - A unit Dies
      • Conditions
        • Or - Any (Conditions) are true
          • Conditions
            • (Unit-type of (Triggering unit)) Equal to SummonType[1]
            • (Unit-type of (Triggering unit)) Equal to SummonType[2]
            • (Unit-type of (Triggering unit)) Equal to SummonType[3]
      • Actions
        • -------- - --------
        • -------- We get the Index (Custom Value) of the dying Summon and use that to find the Caster associated with it --------
        • -------- - --------
        • Set SummonIndex = (Custom value of (Triggering unit))
        • Set Index = (Custom value of (Load Summon_Open[SummonIndex] of SummonIndex in SummonHash))
        • Unit Group - Remove (Triggering unit) from Summon_UG[Index]
        • -------- - --------
        • -------- This first Loop is just to find which Water Ele died (1, 2, 3, etc...) --------
        • -------- - --------
        • For each (Integer A) from 1 to Summon_Limit[Index], do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Load (Integer A) of Index in SummonHash) Equal to (Triggering unit)
              • Then - Actions
                • Set SummonFind = (Integer A)
              • Else - Actions
        • -------- - --------
        • -------- All of the Water Elementals are stored in order as 1, 2, 3, 4, 5, etc... And this loop organizes -> --------
        • -------- the Water Elementals so that if #2 died for example, then 3 becomes 2, 4 becomes 3, 5 becomes 4, etc.... --------
        • -------- This is why we Kill Water Elemental #1 in our other trigger, because it's always going to be the Oldest one --------
        • -------- - --------
        • For each (Integer A) from SummonFind to Summon_Limit[Index], do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Load (Integer A) of Index in SummonHash) Not equal to No unit
                • ((Load (Integer A) of Index in SummonHash) is alive) Equal to True
                • (Integer A) Greater than SummonFind
              • Then - Actions
                • Hashtable - Save Handle Of(Load (Integer A) of Index in SummonHash) as ((Integer A) - 1) of Index in SummonHash
                • Set Summon_Open[Index] = (Integer A)
              • Else - Actions


    • Setup
      • Events
        • Time - Elapsed game time is 0.00 seconds
      • Conditions
      • Actions
        • Set SummonType[1] = Water Elemental (Level 1)
        • Set SummonType[2] = Water Elemental (Level 2)
        • Set SummonType[3] = Water Elemental (Level 3)
        • Hashtable - Create a hashtable
        • Set SummonHash = (Last created hashtable)
     

    Attached Files:

    Last edited: May 15, 2019
  10. Devalut

    Devalut

    Joined:
    Feb 9, 2009
    Messages:
    800
    Resources:
    2
    Spells:
    2
    Resources:
    2
    A linked list huh... This is awesome!
    Whats stopping you from uploading this to the spells or tutorial section?
     
  11. Uncle

    Uncle

    Joined:
    Aug 10, 2018
    Messages:
    438
    Resources:
    0
    Resources:
    0
    Thanks :) and i'm not sure if it's up to standards. Maybe I'll throw it up in the spell section.