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.

Hero Contest #8 - Paired Artist & Coder

Discussion in 'Contest Archive' started by Kyrbi0, Jul 12, 2016.

Thread Status:
Not open for further replies.
  1. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    3,139
    Resources:
    1
    Spells:
    1
    Resources:
    1
    For context see my post in the matchmaking thread. If darkwulfv pops his head out of the sand like he's supposed to this hero will have some sick art, but at the moment this is where we're at. These names are mostly all terrible and will be changed.

    Spell Mana Cost Description Art/Details
    Fissure Strike Low Slams the ground with his weapon, creating a fissure that seeks out the nearest building, travelling a maximum of Z distance. Deals X damage to buildings, and all affected units are forced to attack the hero for Y seconds Spell slam effect + something like imaple spikes but a little less extreme shooting out towards the nearest enemy building. Also affects units in a small radius around the hero (note that non-structures do not take damage)

    Against All Odds None Hero and allied units with Z range gain from X-Y% attack speed based on how much more damage per second they are taking than they are dealing Passive aura. This has a minimum % increase so it will still be (less, but still) helpful even if you're out-DPS-ing the enemy.

    One by One Medium Marks an enemy , causing it to take minor damage over time for a longish duration. The caster is healed every X seconds for Y% of the damage taken by the unit since the last heal. If the unit dies under the effect of this spell, it will jump to the nearest enemy for a reduced duration. No limit to number of jumps, can do it until the duration is too short to kill a unit. May be cast on structures and will subsequently only jump to structures. Only one instance of this spell may be active at once, and I'm considering having it end prematurely the hero gets too far from the current target.

    Ultimate ? ? ?


    What is the purpose of this hero? Succinctly, he's slow but he gets your attention-- either by taunting you or forcing you to play around a debuffed unit.

    I wanted to create a neutral hero with some tools to damage buildings that was significantly different from the Tinker and Sea Witch. I'm not a huge melee player but as I understand both those heroes can be great first choices (instead of a regular race hero) because of their abilities, so I thought "What would make a neutral hero a good second or even third choice late into the game when you want to do something about buildings?" We're aiming for a hero that will enable you to take down an enemy expansion quickly when the time is right, and can do it with a smaller force than you might normally need if microed properly (for example, split off from your main force for a two-pronged attack).

    His attack damage will be disproportionately high and attack speed disproportionately low (LoL's Jhin is a reasonable comparison) so he benefits significantly from attack speed (which you can easily buy from shops late-game) through items and his own buff. I'm considering making him do siege damage (to differentiate from Tinker), but that could be OP/giving him too many special tools.

    Fissure strike - This should be spammable, so to do that it needs a lowish mana cost and a significant downside: only deals damage to buildings. The idea is that you are free to taunt units whenever you need in order to save your own guys, open up a priority target to an attack, or just force masses of melee units to follow you on an adventure. Using it too much (spamming to try to damage lots of buildings) or in the wrong situation will definitely get the hero killed. If you have a way to heal your hero this can be worth investing skill points in early, as at ranks 1&2 it only hits 1 building and then stops but at rank 3 it will seek out a second target after the first (and will try to reach it if it can).

    Against All Odds - Not much to this one other than it really helps him out when he taunts things. I just realized that the taunt makes this ability less effective on all of your units who are then no longer being attacked, so something might actually have to change about this ability. Orcs already have Endurance Aura, but if you wanna run Tauren without one this could be a substitute-- for other races this can be a big buff to their heaviest-hitting and frontline units.

    One By One - If you don't have access to healing, this ability may be what you need to invest in first. It encourages you to focus fire properly to ensure the units keep dying to keep the heal going, and you can use a well placed Fissure Strike to taunt a fleeing debuffed unit and ensure it dies near comrades to which the spell may then jump. This is pretty much the only thing keeping the hero alive while he's taunted half their army, so playing around it can be important-- remember that the healing happens in waves, not constantly over time. If you focus fire the hero inbetween pulses he won't heal it back up before he dies. The hero's slow attack speed kind of works well with this too-- since your damage comes in big chunks you can attack once, then run away and wait for the % heal, then come back in for another swing, etc., so you're not wasting time sitting around taking damage while trying to heal.

    Ultimate - Nothing really solidified yet.
     
  2. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,539
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    Any word on Artist/Coding judges as of yet?
     
  3. Jhotam_3Dcool&create

    Jhotam_3Dcool&create

    Joined:
    Aug 25, 2016
    Messages:
    33
    Resources:
    5
    Models:
    5
    Resources:
    5
    Hello, the reason for my arrival is by invitation of a partner to support him in this competition , participation is now uncertain , the model and this 100% , maybe can become involved . the elaboration of the model; MilkShape 50, % 45 % mdlvis, 5 % wc3modeleditor.

    Hero:

    Zul'jin


    Made animations and editing of rexxar .
     

    Attached Files:

    • 1.jpg
      1.jpg
      File size:
      34.9 KB
      Views:
      190
    • 2.jpg
      2.jpg
      File size:
      19.9 KB
      Views:
      105
    • 3.jpg
      3.jpg
      File size:
      38.8 KB
      Views:
      132
    • 4.jpg
      4.jpg
      File size:
      47.2 KB
      Views:
      157
    • 5.jpg
      5.jpg
      File size:
      44.9 KB
      Views:
      160
    • 6.jpg
      6.jpg
      File size:
      164 KB
      Views:
      150
    • 7.jpg
      7.jpg
      File size:
      69.5 KB
      Views:
      142
  4. Direfury

    Direfury

    Joined:
    Jun 17, 2007
    Messages:
    3,141
    Resources:
    153
    Models:
    140
    Icons:
    11
    Packs:
    1
    Spells:
    1
    Resources:
    153
    So, who is this partner, and you do know this is a contest for generic tavern heroes, not specific characters, right?
     
  5. Kyrbi0

    Kyrbi0

    Joined:
    Jul 29, 2008
    Messages:
    7,906
    Resources:
    1
    Models:
    1
    Resources:
    1
    I fail to see the reason for having all the entries up in multiple places. The Poll (which will be linked at the end of this Contest) is a fine place to keep it all; one place is all that's necessary.

    Yep, that works too.

    Sure, sure, no problem. Recolors are teh bomb (and a lot more likely to fit Warcraft's aesthetic). I can't speak to the Art grade, but it's no big deal.

    I will post more later when I can, but DANG, you work fast. Quite interested to see where it goes. : )

    Also, it's too complexyurgonnalosesuchaloserwow.

    So far the Art Judge is looking to be between MiniMage & Mr. Goblin, and Coding is between Bannar & Frotty. I am awaiting some replies on both ends.

    Jhotam, since I was unable to send you a Private Message, I have to respond here in the thread... So sorry for the somewhat-personal nature, as well as the length. Please refer to the Hidden block below.

    Response to Jhotam

    (I apologize in advance for the long message; I have a hard time being brief, but this is also a rather unprecedented situation, and I'm just trying to get everything important out there)

    ~~~

    Hey there. This is Kyrbi0, Host of the Hero Contest you just posted on. I will respond in the thread, but your... unique presentation seemed to require a more private conversation.

    First I want to make clear that, though unorthodox, your (extremely) late entry into this Contest is not forbidden and in fact I welcome some new faces. While there's several important things to take care of, you can certainly continue in this Contest, provided a few essential things are done and/or resolved.

    First off, I appreciate the effort you have made to translate your message into English (the language of the Hive); however, I'll admit I still had quite a bit of difficulty deciphering exactly your intent and your situation.

    Most people join Contests like these near the beginning, and do so starting with the first post (which contains all the Rules, Criteria, and other guidelines to follow; also it contains the Theme of the Contest, all that). The very next post in this thread is a "Team Matchmaking" thread, which is something you'll need to post on; not only you, but hopefully your (potential?) team-mate.

    Speaking of which... Who is your team-mate? This is a "Joint" Contest, so you should be looking for a Coder, someone to help you design & then code up the Hero and his abilities (also, they are usually the one who makes the map & all the object editor stuff).

    Also important: You do realize that the deadline is incredibly close, right? This coming Monday night (i.e. "midnight" (11:59:59pm) of August 29th, 2016 (depending on your time zone)) is the Deadline. Are you confident in your ability to finish (and your partners)?

    Secondly, in regards to your model Work In Progress (WIP) pictures (thanks for that, by the way)... It's important to remember that all your work was started after the official "start" of the Contest. Do you have any way to prove to me that you started this Troll Hero model sometime after July 11th of this year?

    Also on that note: unfortunately the user Direfury is right. This is not a Contest where the teams are making the unique, named Heroes of Warcraft (e.g. Thrall, Arthas, Illidan, etc), but rather a "generic" Hero Contest (e.g. the Far Seer, the Paladin, the Demon Hunter, etc), and specifically a generic "Neutral" Hero Contest (e.g. the Pandaren Brewmaster, the Goblin Tinker, the Beastmaster). Right now, what you have presented is an amazing & well-made Zul'jin the Forest Troll model... But it's hard to see it fitting in this Contest.

    ~~~

    Now, all of these problems are not insurmountable. I have a few suggestions/solutions for you to consider, if you still want to carry through being a participant in this Contest (this is assuming that your model was not made before the Contest's official start, & that you can finish "your part"):

    The Options
    Option 0: No matter which of the below you end up picking, recognize that your model must change at least a bit to be considered a "generic neutral" hero, a "mercenary" hero hireable at the Tavern. (This is not without precedent, though; user Stefan.K has made a "Medivh" model that he will be reworking to simply become a more generic "crow druid/mage" hero)
    Similarly here; if you change the name of your character, indicate him as a generic Hero (perhaps "Troll Barbarian" or "Troll Cultist" or "Troll Warleader" or something), that would help. Beyond that, perhaps changing the face a bit, or his weapon, or the fact that he has only one arm. Change some of the things that point him out as specifically Zul'jin, and you will have a decent shot at this.

    Option 1: You succeed in finishing, and succeed in having your partner show up & do his half. At that point, as long as you have done everything necessary (please read the first post all the way through for any important Rules & Guidelines & such), you can submit your entry to me right up until the deadline & be OK. ("submit" means "send me a PM with a link to the thread post or Pastebin that has your finished map attached")

    Option 2: You can turn in just the art as your submission, citing a failure of your team-mate to show up & complete his part of the submission. This has precedent (in fact, the user Pyrogasm is doing exactly that but with Code), and I would allow it if you wish. Of course, you would still have to do at least a minimal amount of World Editor/Object Editor/(Trigger Editor?) work; this isn't an Art Contest. If you at least throw together a quick custom Hero, maybe think up some interesting but simple/easy abilities... Well, you would certainly not win. You would probably get 0 for Coding and next-to-nothing for Design, but, you could still compete. See how good your art is, and have a good time.

    Option 3 (this one is a little weird): As I stated above, there is a user currently who is entering just with Code (& Design); his artist team-mate is absent it seems. You two seem to have two pretty different things going on (you can read his design WIP on the 7th page of the thread), but I can envision a way for it to work out; a way to "combine" your two ideas into one interesting Hero.

    This might work, if both of you agree to it & can work together quickly (which I believe you can, if you want), because if you think about it, you are already having to change your Hero model due to Option 0 above. Perhaps a bit of change in the direction of the Design that the user Pyrogasm is pursuing, and you two can mesh nicely.

    Also, if you do this, it increases both of your chances to actually be a competitive entry, since you will have all the Art & Code of a normal entry (rather than half each). I would love to offer advice in helping you combine, if you want.


    ~~~

    Whichever you choose, I appreciate you showing interest in the Contest, and your modeling is impressive. I look forward to your response.
     
  6. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,501
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    You make a table like how Tank-Commander did for the Zephyr Contest :3 you could also just put the team name down and hyperlink their name to their last update (which they should be sending you before the contest ends).
     
  7. HappyCockroach

    HappyCockroach

    Joined:
    Feb 4, 2009
    Messages:
    2,992
    Resources:
    70
    Models:
    32
    Icons:
    36
    Packs:
    1
    Tutorials:
    1
    Resources:
    70
    Well well... there might be a big rule inconsistency here, then. I mean, you said we aren't allowed to use icons from the icon section, but we're allowed to do recolors. So if we grab an icon from the icon section, change its color then, it's usable?

    That would sound utterly crazy. xD

    Or are we allowed to use recolors only from icons that are in the wc3 MPQ's? Please be clear with that x(

    EDIT: I ask such, because Freddyk said he couldn't do his icons by freehand, and according to our resource rules, custom icons must be freehand. I wouldn't be submitting myself to the torture of drawing custom icons as I am now, if I'm allowed to do non-freehand stuff out of non-wc3 material.
     
  8. Kyrbi0

    Kyrbi0

    Joined:
    Jul 29, 2008
    Messages:
    7,906
    Resources:
    1
    Models:
    1
    Resources:
    1
    Sorry, I thought that was clear. Yeah, recolors of existing in-game icons.

    Well, then again, what's crazy about recoloring custom icons? Whether recolor or hand-drawn, you are already signing yourself up for "Custom Icons" according to the Contest. Still would have to credit whoever made what. Eh?
     
  9. HappyCockroach

    HappyCockroach

    Joined:
    Feb 4, 2009
    Messages:
    2,992
    Resources:
    70
    Models:
    32
    Icons:
    36
    Packs:
    1
    Tutorials:
    1
    Resources:
    70
    Man... when asked about custom icons, you tolds us 'Every art used in the entry must be created by the artist of the team'. What do we understand? They must be drawn. Recoloring wouldn't mean creating. Really, if you're to add more rules you must put them very clearly. Deadline is in like 48 hours or so, and I couldn't get these guidelines right...

    What I say is crazy is not allowing custom icons directly, but allowing recolors of them. But well, recolors, only from MPQ material, as far as I understood. We could have that very clearly put right at the first post. :|
     
  10. Stefan.K

    Stefan.K

    Joined:
    Dec 29, 2014
    Messages:
    1,452
    Resources:
    85
    Models:
    85
    Resources:
    85
    JHOTAM'S ENTRY COULD ALWAYS BE USED AS A TROLL HERO. IF MY MEDIVH MODEL CAN, HIS CAN FOR SURE. COUNT IT AS A TROLL CREEP WARLORD/HERO. HE JUST NEED PARTNER.
     
  11. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,501
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    If you really want to recolor an ingame icon, you can and it wouldn't be considered by one of the art criterias.

    The judges shouldn't dock you for using an icon that doesn't completely match your spell. With that in mind, if you chose the 3 other art criterias, and not the icon one, I don't see what's wrong with letting people use custom icons from the icon section since they aren't being judged for that. That's just my opinion though.
     
  12. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    3,139
    Resources:
    1
    Spells:
    1
    Resources:
    1
    @Jhotam_3Dcool&create I waited a while for darkwulfv to resurface before posting in this thread because I didn't want to do so without a WIP, but at this point I think it's pretty safe to say he isn't gonna appear in the next two days. If your partner has disappeared and you'd like to work together, please check out my hero post-- I'm definitely down to work together if we can find a common theme. If you just bulked up that Zul'jin model (literally Incredible Hulk style probably), added a bigass hammer attached to his arm where it's chopped off, gave him a jump-slam animation with his weapon, and did something about the mask that model could definitely work for what I have in mind. Of course I'm also open to changing anything and everything to make a cohesive hero, too. Please send me a message!
     
  13. Dat-C3

    Dat-C3

    Joined:
    Mar 15, 2012
    Messages:
    2,469
    Resources:
    10
    Models:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    1
    Resources:
    10
    Here's a picture of what I am working on.
    Code WiP

    Click
    Clicking...
    http://imgur.com/oMR2LSw


    [​IMG]
     
  14. Pyrogasm

    Pyrogasm

    Joined:
    Feb 27, 2007
    Messages:
    3,139
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Well that's... helpful. Lol.

    Had a ridiculous thought for an ultimate:

    Annex Cooldown: pretty long Gain control of target building for X seconds. It retains its build queue and any units completed while under your control will be created permanently for you. If there are no enemy buildings within Y when the buff expires, the building becomes yours permanently. May not be cast on Town Halls, Hero Altars, or equivalent. This is probably waaaaay OP but perhaps super fun. Mostly against someone who's the same faction as you, since you won't be able to build any units with techtree requirements from the enemy building. But you can always steal extra towers and farms.

    The idea is to be able to quash an enemy 2nd expansion (by the time you're level 6 you won't be able to stop 1st expansions) and actually use their own resources against them.
     
    Last edited by a moderator: Aug 28, 2016
  15. Hayate

    Hayate

    Joined:
    Oct 20, 2010
    Messages:
    2,606
    Resources:
    65
    Models:
    50
    Icons:
    14
    Spells:
    1
    Resources:
    65
    Model is Pretty much Done (Just that It doesnt very fit into murloc swarm), but Trigger part, Im not sure :(

    Edit: By any chance I can Release the model before the contest end?
     
    Last edited: Aug 28, 2016
  16. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,539
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    HC8 - Team Special Ops Entry
    Artist: A.R.
    Coder: Tank-Commander
    Hero
    [​IMG] Proper Names: Ferl'piej the deranged, Kikidrill the hematophagous, Amorg'tik, Tremal the sanguine, Qilarid, Mutrali, Vourg the ruthless

    Silithid Devourer
    Warrior Hero, exceptional at disruptive spells and duelling other heroes. Can learn Rupturing Stab, Leech Life, Corpse Crusher, and Blood Boil.

    Attacks land units.

    Role: Disruptive Tank Theme: Bloody Silithid, violent & durable
    Playstyle
    Boasting high agility and strength the Silithid Devourer has a strong ability to duel with access to powerful single target damage and stun abilities as well as the ability to regenerate health and mana quickly. The cost of these high stats is a low max mana leading to a need to manage it carefully and difficulty in prolonged fights - The Devourer relies on consuming corpses of allies or enemies to regenerate its mana and keep up its onslaught.

    There are three distinct ways on how to play the Silithid Devourer based on what abiliies you pick:
    Sustained Offensive: Max Q then E; pick up W only if you want the utility, needs healing support hero (e.g. Shadow Hunter)
    Full Tank: Max W then E, pick up Q early on for damage and buff to W heal, low damage output
    All-Out Offensive: Max Q then W; do not pick up E, needs mana regen hero (e.g. archmage, bloodmage)

    Early Game: When first summoning the hero you will have the choice between single target damage (Q), single target drain & stun (W), or mana regen with a weak AOE damage/slow (E). Generally speaking your Q is the best option with W being a good option against opponents likely to use a melee hero to harass you as you can stun them and get some free hits with other units (possibly even bodyblock/force tp) at level 2 E will become necessary (use it to consume all the corpses of your creep camp to get the mana you spent back. When starting W do not use it when there is more than one enemy left in a creep camp the manacost is high (half your mana at level 1) and takes 2-3 corpses to regenerate the mana from your E (30 mana per corpse)

    Mid Game: By now you should have your second hero and you should have leveled your Q for damage or W/E for additional sustain depending on how you play, the Devourer does well with heroes which can regenerate either his health or mana and Heroes with access to other debuffs or buffs as they complement the melee nature of the Devourer. When engaging with the enemy his E is good for pursuing enemies and his W can secure a body-blocked or slowed straggler comfortably - catching a hero with it will lock it down for 4 seconds. At level 6 the ultimate (R) can be used to give a massive damage surge for 60 seconds but will beg the need for potions or a hero who can heal them due to the self-inflicted damage. The increased speed can also assist in making a game-winning capture of a hero but be careful as the damage cannot be cancelled and it adds up quickly (a total of 600 out of your max 1045 health at level 6 disregarding passive regen).

    Late Game: Towards the end of the game the Devourer really comes in to its own - at this point the mana issues will be all but nonexistent save for spamming your high level Q or low level W, the ability damage should make picking away at enemy armies easy providing more than enough corpses and using your R will be much safer making the damage spike potential much more threatening
    Tips
    Combos: The Devourer's abilities interact with each other to enhance its combat capabilities centering around their Q ability which applies a bleed effect on enemies hit. Using the W on a bleeding enemy regenerates extra health and extends the bleeding effect and using the E on them refunds the cost of casting it. In addition the R also applies bonuses making the Q and W deal additional damage and increasing the projectile speed of the E. Which allows you to use the following combos:
    - Q->W
    - Q->E->W
    - Q->W->E->Q
    - Q->W->E->W->Q (Bodyblocked Opponent)
    - Q->E->Q
    - R->Q->W->Chase->Q->E->W
    - R->Q->E->Q->Q->E->Q->Q->E->(etc.)
    - R->E->Q->W
    - R->E->W->Q

    Leeching Life: Your W is very expensive at low levels so it should be saved for when you direly need health or to disable priority targets (enemy heroes, boss mob in a creep camp) in addition it has the ability to whiff if your opponent gets too far away from you before you latch on (it won't cost you any mana if you miss but the ability will still go on cooldown), this necessitates that when chasing a fast enemy use your E to slow your target or to have body blocked them to give you time to grab them

    Manacost Nightmare: If you're struggling to manage the mana or simply need to boost the amount you can use spells pick up either mana potions, a mantle of intelligence + 3 (+45 mana) or other similar items. Alternatively train units or Heroes that can help with your mana issues (Archmage, Obsidian Statue or Bloodmage). Health Regeneration/Armour can also help with this by lowering the need to use your W to just the times you want to stun a unit for a long time (Shadow Hunter, Dreadlord, Lich, Paladin, Keeper of the Grove)

    Graverobber: your E can be used to interfere with necromancer centred undead play by consuming the corpses they would use to summon skeletons though they may also deny your mana regen by getting to them first. Similarly when playing undead or attacking an undead player the graveyard can be used as an easy means to regenerate mana as it periodically spawns corpses you can consume
    [​IMG] Model Information:
    - Race: Silithid
    - 242.4kb for all textures and models (main and portrait)
    - 19kb for all icons (BTN/DISBTN/Scorescreen)
    - 8 Limbs (4 arms/claws, 4 legs)
    - Stinger
    - Atrophied wings
    - Completely custom animations including unique ones for each ability
    - Attachment points on all limbs (Sprite first for stinger, second & third for extra claws)
    - Built-in Sound effects on spell throw and channel
    - Custom texture for the body and an animated texture for the abdomen
    - Team colour on the wings and abdomen
    Stats
    Stat Base Growth Max
    [​IMG] 22 3.00 49 Primary
    [​IMG] 19 2.00 37
    [​IMG] 11 1.00 20
    Abilities
    Icon Tooltip
    [​IMG] Q - Rupturing Stab Manacost: 30/45/60 Cooldown: 6 seconds
    The caster swings at the target with its stinger dealing damage and causing them to bleed for 4 seconds. Targetting bleeding enemies with other abilities applies bonuses.

    Level 1 - 50 initial damage, 30 bleed damage.
    Level 2 - 75 initial damage, 60 bleed damage.
    Level 3 - 100 initial damage, 90 bleed damage.
    [​IMG] W - Leech Life Manacost: 80/65/50 Cooldown: 8 seconds
    Latches on to enemy units pinning them and draining blood dealing damage and restoring health to the caster over 4 seconds bleeding enemies bleed for 4 more seconds and restores extra health to the caster.

    Level 1 - 75 damage dealt, 100 health restored, 35 extra restored.
    Level 2 - 85 damage dealt, 120 health restored, 70 extra restored.
    Level 3 - 95 damage dealt, 140 health restored, 105 extra restored.
    [​IMG] E - Corpse Crusher Manacost: 50 Cooldown: 18/16/14 seconds
    Allows the caster to passively consume corpses to regenerate mana, can be cast actively to launch a corpse at the target point that will deal 50 damage and slow enemies in an area for a duration. Hitting a bleeding enemy with the corpse refunds half the cost of the spell.

    Level 1 - 30 mana restored, weak slow, lasts 5 seconds.
    Level 2 - 45 mana restored, medium slow, lasts 6 seconds.
    Level 3 - 60 mana restored, strong slow, lasts 7 seconds.
    [​IMG] R - Blood Boil Manacost: 120 Cooldown: 120 seconds
    The caster's heart rate surges increasing their attack and movement speed substantially while also increasing mana regeneration at the cost of 10 health every second, additionally their abilities are enhanced. Lasts 60 seconds.

    Rupturing Stab - stab damage increased by 25 per level, bleed damage increased by 15 per level.
    Life Leech - damage increased by 50.
    Corpse Crusher - faster projectile.
    Showcases
    • GIF Code
      [​IMG]
      Code (vJASS):
      ////////////////////////////////////////////////////////////////////
      //                     RUPTURING STAB V1.00                       //
      //  Author: Tank-Commander                                        //
      //  Purpose: Simple Stab & Damage over time ability to use in     //
      //           combo with other abilities                           //
      //                                                                //
      //  Notes:                                                        //
      //    -  Read the readme before you try modifying the config      //
      //    -  Use the "Helpful files" to help you import the system    //
      //                                                                //
      //                                                                //
      //  If you have used this spell in your map, you are required     //
      //  to give credits to Tank-Commander for the creation of it      //
      //  If you would like to use snippets of code from this for       //
      //  whatever, getting permission and crediting the source/linking //
      //  would be much appreciated.                                    //
      ////////////////////////////////////////////////////////////////////

      ////////////////////////////////////////////////////////////////////
      //  README:                                                       //
      //    Before modifying this spell a few things need to be         //
      //    understood and read, this is one of those things, while     //
      //    most modification can be considered intuitive, it still     //
      //    helps to read through these intstructions, as they will     //
      //    inform you about how to configure this spell to your        //
      //    desire.                                                     //
      //----------------------------------------------------------------//
      //  Initial importing: The variable creator trigger can be        //
      //  imported first and if you have the correct settings (file,    //
      //  preferences, General, automatically create unknown variables  //
      //  checked, then when you paste in the variable creator it       //
      //  will automatically give you all the variables you need for    //
      //  this spell                                                    //
      //                                                                //
      //  While the remaining object editor based data is not required  //
      //  to function (provided they're replaced with equivelents)      //
      //  it's recommended that they are also imported, if their data   //
      //  value are not the same as listed in the configuration, those  //
      //  configurables will need to be changed to work correctly       //
      //----------------------------------------------------------------//
      //  TimerSpeed: This is the rate at which the loop timer of the   //
      //  ability runs the default value 0.03125 allows the loop        //
      //  function to run 32 times per second giving a smooth ability   //
      constant function RS_TimerSpeed takes nothing returns real
          return 0.031250000
      endfunction
      //----------------------------------------------------------------//
      //  Ability: This is the raw code for the ability used as a base  //
      //  to see raw data press ctrl + d in the object editor, do it    //
      //  again to revert to normal                                     //
      constant function RS_Ability takes nothing returns integer
          return 'A000'
      endfunction
      //----------------------------------------------------------------//
      //  BonusBuff: This is the raw code for the ability used to       //
      //  Apply damage bonuses to the ability (it can be either a       //
      //  regular ability or a specific buff which the caster can be    //
      //  afflicted with to give optionally temporary or permanent      //
      //  buffs to this ability                                         //
      constant function RS_BonusBuff takes nothing returns integer
          return 'B003'
      endfunction
      //----------------------------------------------------------------//
      //  BleedBuff: This is the raw code of the ability used to        //
      //  debuff units damaged by this ability, it should be based off  //
      //  slow aura                                                     //
      constant function RS_BleedBuff takes nothing returns integer
          return 'A001'
      endfunction
      //----------------------------------------------------------------//
      //  DrainBuff: This is the same as BuffAbility except used for    //
      //  extending the duration of BleedBuff based on the target of    //
      //  the ability having this buff applied to them                  //
      constant function RS_DrainBuff takes nothing returns integer
          return 'B001'
      endfunction
      //----------------------------------------------------------------//
      //  BleedDelay: This is the time in seconds between each bit of   //
      //  damage dealt to the target via bleeding                       //
      function RS_BleedDelay takes real level returns real
          return 0.312500000
      endfunction
      //----------------------------------------------------------------//
      //  BleedDuration: This is how long the target will bleed for in  //
      //  seconds
      function RS_BleedDuration takes real level returns real
          return 4.
      endfunction
      //----------------------------------------------------------------//
      //  BleedDamageHealth: This is the amount of damage the target    //
      //  takes over the duration of the bleeding                       //
      function RS_BleedDamageHealth takes real level returns real
          return 15 + 15 * level
      endfunction
      //----------------------------------------------------------------//
      //  BleedDamageMana: This is this is the amount of mana lost by   //
      //  the target over the duration of the bleeding                  //
      function RS_BleedDamageMana takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  BonusBleedDamageHealth: This is the extra bleed damage taken  //
      //  if the caster has BonusBuff applied to them when first        //
      //  stabbing                                                      //
      function RS_BonusBleedDamageHealth takes real level returns real
          return 15 * level
      endfunction
      //----------------------------------------------------------------//
      //  BonusBleedDamageMana: This is the extra bleed mana lost if    //
      //  the caster has BonusBuff applied to them when first stabbing  //
      function RS_BonusBleedDamageMana takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  StabDamageHealth: This is the amount of damage taken by the   //
      //  target when they are first stabbed                            //
      function RS_StabDamageHealth takes real level returns real
          return 25 + (25 * level)
      endfunction
      //----------------------------------------------------------------//
      //  StabDamageMana: This is the amount of mana lost by the target //
      //  when they are first stabbed                                   //
      function RS_StabDamageMana takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  BonusStabDamageHealth: This is the extra Stab damage taken if //
      // the caster has BonusBuff applied to them when first stabbing   //
      function RS_BonusStabDamageHealth takes real level returns real
          return 25 * level
      endfunction
      //----------------------------------------------------------------//
      //  BonusStabDamageMana: This is the extra Stab mana lost if the  //
      //  caster has BonusBuff applied to them when first stabbing      //
      function RS_BonusStabDamageMana takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  StabEffect: This is the effect played on the target when      //
      //  they are stabbed                                              //
      constant function RS_StabEffect takes nothing returns string
          return "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  BleedingEffect: This is the effect played on the target for   //
      //  the duration that they are bleeding                           //
      constant function RS_BleedingEffect takes nothing returns string
          return "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  BloodiedEffect: This is the effect played on the caster on    //
      //  the body part or weapon they used to stab the target          //
      constant function RS_BloodiedEffect takes nothing returns string
          return "Objects\\Spawnmodels\\Other\\HumanBloodCinematicEffect\\HumanBloodCinematicEffect.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  DrainCombinedEffect: This is the effect played to denote      //
      //  that the duration of the bleeding is being extended via the   //
      //  target having DrainBuff applied to them                       //
      constant function RS_DrainCombinedEffect takes nothing returns string
          return "Abilities\\Spells\\Undead\\CarrionSwarm\\CarrionSwarmDamage.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  StabAttachmentPoint: This is the location on the target that  //
      //  StabEffect is played on                                       //
      constant function RS_StabAttachmentPoint takes nothing returns string
          return "chest"
      endfunction
      //----------------------------------------------------------------//
      //  BleedingAttachmentPoint: This is the location on the target   //
      //  that BleedingEffect & DrainCombinedEffect are played on       //
      constant function RS_BleedingAttachmentPoint takes nothing returns string
          return "origin"
      endfunction
      //----------------------------------------------------------------//
      //  BloodiedAttachmentPoint: This is the location on the caster   //
      //  that BloodiedEffect is played on                              //
      constant function RS_BloodiedAttachmentPoint takes nothing returns string
          return "sprite first"
      endfunction
      //----------------------------------------------------------------//
      //  AttackType: This is the attack type used by the spell         //
      constant function RS_AttackType takes nothing returns attacktype
          return ATTACK_TYPE_NORMAL
      endfunction
      //----------------------------------------------------------------//
      //  DamageType: This is the damagetype used by the spell, armour  //
      //  reduces the damage based on this type                         //
      constant function RS_DamageType takes nothing returns damagetype
          return DAMAGE_TYPE_NORMAL
      endfunction
      //----------------------------------------------------------------//
      //  WeaponType: This is the weapontype used by the spell
      constant function RS_WeaponType takes nothing returns weapontype
          return null
      endfunction
      //----------------------------------------------------------------//
      //                      END OF CONFIGURATION                      //
      //----------------------------------------------------------------//
      ////////////////////////////////////////////////////////////////////

      ///////////////////////////////////////////////////////////////////
      //  Funtion used to search for units which are bleeding, used    //
      //  instead of a group variable in order to be slightly faster   //
      //  but also to reduce implementing extra lines to add/remove    //
      //  units from a group which would reduce processing speed       //
      ///////////////////////////////////////////////////////////////////
      function RS_IsNotBleeding takes unit u returns boolean
          local integer Node = 0

          loop
              set Node = udg_RS_NextNode[Node]
              exitwhen Node == 0

              if udg_RS_Unit[Node] == u then
                  return false
              endif

          endloop

          return true
      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to primarily deal Damage over time but also    //
      //  adds artificial delay to mimic warcraft mechanics for        //
      //  Damage over time while keeping in strict time with the       //
      //  duration of the ability                                      //
      ///////////////////////////////////////////////////////////////////
      function RS_Loop takes nothing returns nothing
          local integer Node = 0

          loop
              set Node = udg_RS_NextNode[Node]
              exitwhen Node == 0

              //Extend duration if the enemy is being leeched
              if GetUnitAbilityLevel(udg_RS_Unit[Node], RS_DrainBuff()) > 0 then
                  set udg_RS_Duration[Node] = udg_RS_Duration[Node] + RS_TimerSpeed()
                  call DestroyEffect(AddSpecialEffectTarget(RS_DrainCombinedEffect(), udg_RS_Unit[Node], RS_BleedingAttachmentPoint()))
              endif

              //Check if the spell is not finished
              if udg_RS_Duration[Node] > 0. then
                  set udg_RS_Duration[Node] = udg_RS_Duration[Node] - RS_TimerSpeed()
                  set udg_RS_DamageDelay[Node] = udg_RS_DamageDelay[Node] - RS_TimerSpeed()
         
                  //Check if it's time to deal damage again
                  if udg_RS_DamageDelay[Node] <= 0. then
                      //Deal damage
                      set udg_RS_DamageDelay[Node] = udg_RS_DamageDelayStart[Node]
                      call DestroyEffect(AddSpecialEffectTarget(RS_BleedingEffect(), udg_RS_Unit[Node], RS_BleedingAttachmentPoint()))
                      call UnitDamageTarget(udg_RS_Caster[Node], udg_RS_Unit[Node], udg_RS_BleedDamageHealth[Node], true, false, RS_AttackType(), RS_DamageType(), RS_WeaponType())
                      call SetUnitState(udg_RS_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_RS_Unit[Node], UNIT_STATE_MANA) - udg_RS_BleedDamageMana[Node])
                  endif
         
              else
                  call DestroyEffect(udg_RS_BloodiedEffect[Node])
         
                  //Recycle
                  set udg_RS_RecycleNodes[udg_RS_RecyclableNodes] = Node
                  set udg_RS_RecyclableNodes = udg_RS_RecyclableNodes + 1
                  set udg_RS_NextNode[udg_RS_PrevNode[Node]] = udg_RS_NextNode[Node]
                  set udg_RS_PrevNode[udg_RS_NextNode[Node]] = udg_RS_PrevNode[Node]
         
                  //Check if this is the last instance of this unit bleeding
                  if RS_IsNotBleeding(udg_RS_Unit[Node]) then
                      call UnitRemoveAbility(udg_RS_Unit[Node], RS_BleedBuff())

                      //Pause timer if this was the last instance
                      if (udg_RS_PrevNode[0] == 0) then
                          call PauseTimer(udg_RS_Timer)
                      endif
             
                  endif
         
              endif

          endloop

      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to deal damage from the ability and cause      //
      //  target units to start bleeding                               //
      ///////////////////////////////////////////////////////////////////
      function RS_Cast takes nothing returns boolean
          //Set up locals
          local integer Node
          local real level

          if (GetSpellAbilityId() == RS_Ability()) then
              //Set up Node
              if (udg_RS_RecyclableNodes == 0) then
                  set udg_RS_NodeNumber = udg_RS_NodeNumber + 1
                  set Node = udg_RS_NodeNumber
              else
                  set udg_RS_RecyclableNodes = udg_RS_RecyclableNodes - 1
                  set Node = udg_RS_RecycleNodes[udg_RS_RecyclableNodes]
              endif

              set udg_RS_NextNode[Node] = 0
              set udg_RS_NextNode[udg_RS_PrevNode[0]] = Node
              set udg_RS_PrevNode[Node] = udg_RS_PrevNode[0]
              set udg_RS_PrevNode[0] = Node

              //Start timer if this is the only instance
              if (udg_RS_PrevNode[Node] == 0) then
                  call TimerStart(udg_RS_Timer, RS_TimerSpeed(), true, function RS_Loop)
              endif

              //Apply Data
              set udg_RS_Unit[Node] = GetSpellTargetUnit()
              set udg_RS_Caster[Node] = GetTriggerUnit()
              set udg_RS_BloodiedEffect[Node] = AddSpecialEffectTarget(RS_BloodiedEffect(), udg_RS_Caster[Node], RS_BloodiedAttachmentPoint())
              set level = GetUnitAbilityLevel(udg_RS_Caster[Node], RS_Ability())
              set udg_RS_DamageDelayStart[Node] = RS_BleedDelay(level)
              set udg_RS_DamageDelay[Node] = udg_RS_DamageDelayStart[Node]
              set udg_RS_Duration[Node] = RS_BleedDuration(level)

              //Stab Effect
              call UnitAddAbility(udg_RS_Unit[Node], RS_BleedBuff())
              call DestroyEffect(AddSpecialEffectTarget(RS_StabEffect(), udg_RS_Unit[Node], RS_StabAttachmentPoint()))

              //Check for Blood Boil Bonuses
              if GetUnitAbilityLevel(udg_RS_Caster[Node], RS_BonusBuff()) > 0 then
                  set udg_RS_BleedDamageHealth[Node] = (RS_BleedDamageHealth(level) + RS_BonusBleedDamageHealth(level)) / (udg_RS_Duration[Node] / udg_RS_DamageDelay[Node])
                  set udg_RS_BleedDamageMana[Node] = (RS_BleedDamageMana(level) + RS_BonusBleedDamageMana(level)) / (udg_RS_Duration[Node] / udg_RS_DamageDelay[Node])
                  call UnitDamageTarget(udg_RS_Caster[Node], udg_RS_Unit[Node], RS_StabDamageHealth(level) + RS_BonusStabDamageHealth(level), true, false, RS_AttackType(), RS_DamageType(), RS_WeaponType())
                  call SetUnitState(udg_RS_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_RS_Unit[Node], UNIT_STATE_MANA) - (RS_StabDamageMana(level) + RS_BonusStabDamageMana(level)))
              else
                  set udg_RS_BleedDamageHealth[Node] = RS_BleedDamageHealth(level) / (udg_RS_Duration[Node] / udg_RS_DamageDelay[Node])
                  set udg_RS_BleedDamageMana[Node] = RS_BleedDamageMana(level) / (udg_RS_Duration[Node] / udg_RS_DamageDelay[Node])
                  call UnitDamageTarget(udg_RS_Caster[Node], udg_RS_Unit[Node], RS_StabDamageHealth(level), true, false, RS_AttackType(), RS_DamageType(), RS_WeaponType())
                  call SetUnitState(udg_RS_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_RS_Unit[Node], UNIT_STATE_MANA) - RS_StabDamageMana(level))
              endif

          endif

          return false
      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to initialise the event listeners of the spell //
      ///////////////////////////////////////////////////////////////////
      function InitTrig_Rupturing_Stab takes nothing returns nothing
          local trigger t = CreateTrigger()

          //Set up trigger
          call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
          call TriggerAddCondition(t, Condition(function RS_Cast))
      endfunction
      ///////////////////////////////////////////////////////////////////
      //  END OF THE SPELL                                             //
      ///////////////////////////////////////////////////////////////////
       
    • GIF Code
      [​IMG]
      Code (vJASS):
      ////////////////////////////////////////////////////////////////////
      //                       LEECH LIFE V1.00                         //
      //  Author: Tank-Commander                                        //
      //  Requires: Dummy.mdl                                           //
      //  Purpose: Stun and drain health from the target, useful to     //
      //           disable enemy heroes                                 //
      //                                                                //
      //  Credits: Vexorian (dummy.mdl)                                 //
      //                                                                //
      //  Notes:                                                        //
      //    -  Read the readme before you try modifying the config      //
      //    -  Use the "Helpful files" to help you import the system    //
      //                                                                //
      //                                                                //
      //  If you have used this spell in your map, you are required     //
      //  to give credits to Tank-Commander for the creation of it      //
      //  If you would like to use snippets of code from this for       //
      //  whatever, getting permission and crediting the source/linking //
      //  would be much appreciated.                                    //
      ////////////////////////////////////////////////////////////////////

      ////////////////////////////////////////////////////////////////////
      //  README:                                                       //
      //    Before modifying this spell a few things need to be         //
      //    understood and read, this is one of those things, while     //
      //    most modification can be considered intuitive, it still     //
      //    helps to read through these intstructions, as they will     //
      //    inform you about how to configure this spell to your        //
      //    desire.                                                     //
      //----------------------------------------------------------------//
      //  Initial importing: The variable creator trigger can be        //
      //  imported first and if you have the correct settings (file,    //
      //  preferences, General, automatically create unknown variables  //
      //  checked, then when you paste in the variable creator it       //
      //  will automatically give you all the variables you need for    //
      //  this spell                                                    //
      //                                                                //
      //  While the remaining object editor based data is not required  //
      //  to function (provided they're replaced with equivelents)      //
      //  it's recommended that they are also imported, if their data   //
      //  value are not the same as listed in the configuration, those  //
      //  configurables will need to be changed to work correctly       //
      //----------------------------------------------------------------//
      //  TimerSpeed: This is the rate at which the loop timer of the   //
      //  ability runs the default value 0.03125 allows the loop        //
      //  function to run 32 times per second giving a smooth ability   //
      constant function LL_TimerSpeed takes nothing returns real
          return 0.031250000
      endfunction
      //----------------------------------------------------------------//
      //  Ability: This is the raw code for the ability used as a base  //
      //  to see raw data press ctrl + d in the object editor, do it    //
      //  again to revert to normal                                     //
      constant function LL_Ability takes nothing returns integer
          return 'A002'
      endfunction
      //----------------------------------------------------------------//
      //  BonusBuff: This is the raw code for the ability used to       //
      //  Apply damage bonuses to the ability (it can be either a       //
      //  regular ability or a specific buff which the caster can be    //
      //  afflicted with to give optionally temporary or permanent      //
      //  buffs to this ability                                         //
      constant function LL_BonusBuff takes nothing returns integer
          return 'B003'
      endfunction
      //----------------------------------------------------------------//
      //  BleedBuff: This is the raw code of the ability used to        //
      //  debuff units damaged by this ability, it should be based off  //
      //  slow aura                                                     //
      constant function LL_BleedBuff takes nothing returns integer
          return 'B000'
      endfunction
      //----------------------------------------------------------------//
      //  DummyPlayer: This is the player who will own all dummy units  //
      //  created by this spell, it should be a neutral player as to    //
      //  not mess with scorescreens                                    //
      constant function LL_DummyPlayer takes nothing returns player
          return Player(14)
      endfunction
      //----------------------------------------------------------------//
      //  DummyUnit: This is the raw code for the unit used as a dummy  //
      //  by the ability, it should use dummy.mdl as its model or some  //
      //  other invisible model                                         //
      constant function LL_DummyUnit takes nothing returns integer
          return 'u000'
      endfunction
      //----------------------------------------------------------------//
      //  DummyStunAbility: This is the raw code of the ability used    //
      //  to stun targets of the ability and hold them in place         //
      constant function LL_DummyStunAbility takes nothing returns integer
          return 'A003'
      endfunction
      //----------------------------------------------------------------//
      //  DummyStunOrder: This is the OrderID to go with the stun       //
      //  ability in order ot get the dummy to use it, for stormbolt    //
      //  as a base ability this is 852095                              //
      constant function LL_DummyStunOrder takes nothing returns integer
          return 852095
      endfunction
      //----------------------------------------------------------------//
      //  Order: This is the OrderID to match the ability to make sure  //
      //  the caster is always channeling the spell, for drain this is  //
      //  852487                                                        //
      constant function LL_Order takes nothing returns integer
          return 852487
      endfunction
      //----------------------------------------------------------------//
      //  StopOrder: This is the OrderID to match the order the unit is //
      //  given when the unit escapes its range as to stop channeling   //
      //  the spell for "stop" this is 851972                           //
      constant function LL_StopOrder takes nothing returns integer
          return 851972
      endfunction
      //----------------------------------------------------------------//
      //  DeathAnimation: This is the animation name used if the unit   //
      //  is killed during the channel of the spell                     //
      constant function LL_DeathAnimation takes nothing returns string
          return "death"
      endfunction
      //----------------------------------------------------------------//
      //  LoopAnimation: The animation name used during the channel of  //
      //  the spell                                                     //
      constant function LL_LoopAnimation takes nothing returns string
          return "channel"
      endfunction
      //----------------------------------------------------------------//
      //  StopAnimation: This is the animation used when the spell      //
      //  ends once the channel has ended to reset the unit animations  //
      constant function LL_StopAnimation takes nothing returns string
          return "stand"
      endfunction
      //----------------------------------------------------------------//
      //  MaxRange: This is the maximum distance at which the unit is   //
      //  able to grab on to a unit, units leaving this radius (either  //
      //  from teleporting away or running) will stop the drain, the    //
      //  value is squared to make calculations faster                  //
      function LL_MaxRange takes nothing returns real
          return 62500. //this is 250 * 250
      endfunction
      //----------------------------------------------------------------//
      //  Delay: This is the time in seconds between damage dealt and   //
      //  life restored to the caster                                   //
      function LL_Delay takes real level returns real
          return 0.8
      endfunction
      //----------------------------------------------------------------//
      //  Duration: This is the time in seconds that the spell lasts    //
      //  for                                                           //
      function LL_Duration takes real level returns real
          return 4.05
      endfunction
      //----------------------------------------------------------------//
      //  HealthDamage: This is the amount of damage dealt to the       //
      //  target over the duration of life leech                        //
      function LL_HealthDamage takes real level returns real
          return 65 + (10 * level)
      endfunction
      //----------------------------------------------------------------//
      //  ManaDamage: This is the amount of mana lost by the target     //
      //  over the duration of life leech                               //
      function LL_ManaDamage takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  BonusHealthDamage: This is the extra damage taken if the      //
      //  caster has BonusBuff applied to them when first grabbing      //
      //  the target                                                    //
      function LL_BonusHealthDamage takes real level returns real
          return 50.
      endfunction
      //----------------------------------------------------------------//
      //  BonusManaDamage: This is the extra mana lost if the caster    //
      //  has BonusBuff applied to them when first grabbing the target  //
      function LL_BonusManaDamage takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  HealthHeal: This is the amount of health restored to the      //
      //  caster over the duration of life leech                        //
      function LL_HealthHeal takes real level returns real
          return 80 + (20 * level)
      endfunction
      //----------------------------------------------------------------//
      //  ManaHeal: This is the amount of mana restored to the caster   //
      //  over the duration of life leech                               //
      function LL_ManaHeal takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  BonusHealthHeal: This is the amount of extra health restored  //
      //  if the target has BleedBuff when first grabbed                //
      function LL_BonusHealthHeal takes real level returns real
          return 35 * level
      endfunction
      //----------------------------------------------------------------//
      //  BonusManaHeal: This is the amount of extra mana restored if   //
      //  the target has BleedBuff when first grabbed                   //
      function LL_BonusManaHeal takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  ManaRefund: The amount of mana given back to the caster when  //
      //  lifeleech misses (units avoid being grabbed entirely)         //
      function LL_ManaRefund takes real level returns real
          return 95. - (15. * level)
      endfunction
      //----------------------------------------------------------------//
      //  AttackType: This is the attack type used by the spell         //
      constant function LL_AttackType takes nothing returns attacktype
          return ATTACK_TYPE_NORMAL
      endfunction
      //----------------------------------------------------------------//
      //  DamageType: This is the damagetype used by the spell, armour  //
      //  reduces the damage based on this type                         //
      constant function LL_DamageType takes nothing returns damagetype
          return DAMAGE_TYPE_NORMAL
      endfunction
      //----------------------------------------------------------------//
      //  WeaponType: This is the weapon type used by the spell         //
      constant function LL_WeaponType takes nothing returns weapontype
          return null
      endfunction
      //----------------------------------------------------------------//
      //  StunDissapate: This is the time in seconds in takes for the   //
      //  stun dummy to be removed                                      //
      constant function LL_StunDissapate takes nothing returns real
          return 2.
      endfunction
      //----------------------------------------------------------------//
      //                      END OF CONFIGURATION                      //
      //----------------------------------------------------------------//
      ////////////////////////////////////////////////////////////////////

      ///////////////////////////////////////////////////////////////////
      //  Function used to deal damage delayed to mimic ingame         //
      //  mechanics, apply stun and control the animations of the      //
      //  caster to allow them to visually leech, also permits         //
      //  the caster to cancel the ability rather than relying on      //
      //  pausing them when the spell starts                           //
      ///////////////////////////////////////////////////////////////////
      function LL_Loop takes nothing returns nothing
          local integer Node = 0
          local integer tempNode
          local unit u
          local real dx
          local real dy

          loop
              set Node = udg_LL_NextNode[Node]
              exitwhen Node == 0
              set dx = GetUnitX(udg_LL_Unit[Node]) - GetUnitX(udg_LL_Caster[Node])
              set dy = GetUnitY(udg_LL_Unit[Node]) - GetUnitY(udg_LL_Caster[Node])

              if (udg_LL_Duration[Node] >= 0.) and (GetUnitCurrentOrder(udg_LL_Caster[Node]) == LL_Order()) and not(IsUnitType(udg_LL_Unit[Node],UNIT_TYPE_DEAD)) and (dx * dx + dy * dy < LL_MaxRange()) then
                  set udg_LL_Duration[Node] = udg_LL_Duration[Node] - LL_TimerSpeed()
                  set udg_LL_Delay[Node] = udg_LL_Delay[Node] - LL_TimerSpeed()
         
                  //Successfully grabbed, disable refund and queue animations
                  call QueueUnitAnimation(udg_LL_Caster[Node], LL_LoopAnimation())
                  if not (udg_LL_GrabbedTarget[Node]) then
                      set udg_LL_GrabbedTarget[Node] = true
                  endif
         
                  //Stun unit being leeched
                  set u = CreateUnit(LL_DummyPlayer(), LL_DummyUnit(), GetUnitX(udg_LL_Unit[Node]), GetUnitY(udg_LL_Unit[Node]), 0.)
                  call UnitAddAbility(u, LL_DummyStunAbility())
                  call IssueTargetOrderById(u, LL_DummyStunOrder(), udg_LL_Unit[Node])
                  call UnitApplyTimedLife(u, LL_BleedBuff(), LL_StunDissapate())
                  set u = null
         
                  //Drain life
                  if udg_LL_Delay[Node] <= 0. then
                      set udg_LL_Delay[Node] = udg_LL_DelayStart[Node]
                      call UnitDamageTarget(udg_LL_Caster[Node], udg_LL_Unit[Node], udg_LL_HealthDamage[Node], true, false, LL_AttackType(), LL_DamageType(), LL_WeaponType())
                      call SetWidgetLife(udg_LL_Caster[Node], GetWidgetLife(udg_LL_Caster[Node]) + udg_LL_HealthHeal[Node])
                      call SetUnitState(udg_LL_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_LL_Unit[Node], UNIT_STATE_MANA) - udg_LL_ManaDamage[Node])
                      call SetUnitState(udg_LL_Caster[Node], UNIT_STATE_MANA, GetUnitState(udg_LL_Caster[Node], UNIT_STATE_MANA) + udg_LL_ManaHeal[Node])
                  endif
         
              else
         
                  //In the event of the unit "dodging" stop the channel
                  if GetUnitCurrentOrder(udg_LL_Caster[Node]) == LL_Order() then
                      call IssueImmediateOrderById(udg_LL_Caster[Node], LL_StopOrder())
                  endif
         
                  //Refund manacost on whiff
                  if not(udg_LL_GrabbedTarget[Node]) then
                      call SetUnitState(udg_LL_Caster[Node], UNIT_STATE_MANA, GetUnitState(udg_LL_Caster[Node], UNIT_STATE_MANA) + udg_LL_ManaRefund[Node])
                  endif
         
                  call SetUnitPropWindow(udg_LL_Unit[Node], GetUnitDefaultPropWindow(udg_LL_Unit[Node]) * bj_DEGTORAD)
         
                  if IsUnitType(udg_LL_Caster[Node], UNIT_TYPE_DEAD) then
                      call SetUnitAnimation(udg_LL_Caster[Node], LL_DeathAnimation())
                  else
                      call SetUnitAnimation(udg_LL_Caster[Node], LL_StopAnimation())
                  endif
         
                  //Recycle
                  set udg_LL_RecycleNodes[udg_LL_RecyclableNodes] = Node
                  set udg_LL_RecyclableNodes = udg_LL_RecyclableNodes + 1
                  set udg_LL_NextNode[udg_LL_PrevNode[Node]] = udg_LL_NextNode[Node]
                  set udg_LL_PrevNode[udg_LL_NextNode[Node]] = udg_LL_PrevNode[Node]

                  //Pause timer if this was the last instance
                  if (udg_LL_PrevNode[0] == 0) then
                      call PauseTimer(udg_LL_Timer)
                  endif
         
              endif

          endloop

      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used when the ability is cast to set up spell data  //
      //  and to prevent the target from moving as well as work        //
      //  out any bonuses from bleeding buffs                          //
      ///////////////////////////////////////////////////////////////////
      function LL_Cast takes nothing returns boolean
          local integer Node
          local real level
          local real tempreal

          if (GetSpellAbilityId() == LL_Ability()) then
              //Set up Node
              if (udg_LL_RecyclableNodes == 0) then
                  set udg_LL_NodeNumber = udg_LL_NodeNumber + 1
                  set Node = udg_LL_NodeNumber
              else
                  set udg_LL_RecyclableNodes = udg_LL_RecyclableNodes - 1
                  set Node = udg_LL_RecycleNodes[udg_LL_RecyclableNodes]
              endif

              set udg_LL_NextNode[Node] = 0
              set udg_LL_NextNode[udg_LL_PrevNode[0]] = Node
              set udg_LL_PrevNode[Node] = udg_LL_PrevNode[0]
              set udg_LL_PrevNode[0] = Node

              //Start timer if this is the only instance
              if (udg_LL_PrevNode[Node] == 0) then
                  call TimerStart(udg_LL_Timer, LL_TimerSpeed(), true, function LL_Loop)
              endif

              //Set up date
              set udg_LL_Unit[Node] = GetSpellTargetUnit()
              set udg_LL_Caster[Node] = GetTriggerUnit()
              set level = GetUnitAbilityLevel(udg_LL_Caster[Node], LL_Ability())
              set udg_LL_Duration[Node] = LL_Duration(level)
              set udg_LL_DelayStart[Node] = LL_Delay(level)
              set udg_LL_Delay[Node] = udg_LL_DelayStart[Node]
              set udg_LL_GrabbedTarget[Node] = false
              set udg_LL_ManaRefund[Node] = LL_ManaRefund(level)
              set tempreal = udg_LL_Duration[Node] / udg_LL_Delay[Node]
              call SetUnitPropWindow(udg_LL_Unit[Node], 0)
              call SetUnitAnimation(udg_LL_Caster[Node], LL_LoopAnimation())

              //Apply bonuses
              if GetUnitAbilityLevel(udg_LL_Caster[Node], LL_BonusBuff()) > 0 then
                  set udg_LL_HealthDamage[Node] = (LL_HealthDamage(level) + LL_BonusHealthDamage(level)) / tempreal
                  set udg_LL_ManaDamage[Node] = (LL_ManaDamage(level) + LL_BonusManaDamage(level)) / tempreal
              else
                  set udg_LL_HealthDamage[Node] = LL_HealthDamage(level) / tempreal
                  set udg_LL_ManaDamage[Node] = LL_ManaDamage(level) / tempreal
              endif

              if GetUnitAbilityLevel(udg_LL_Unit[Node], LL_BleedBuff()) > 0 then
                  set udg_LL_HealthHeal[Node] = (LL_HealthHeal(level) + LL_BonusHealthHeal(level)) / tempreal
                  set udg_LL_ManaHeal[Node] = (LL_ManaHeal(level) + LL_BonusManaHeal(level)) / tempreal
              else
                  set udg_LL_HealthHeal[Node] = LL_HealthHeal(level) / tempreal
                  set udg_LL_ManaHeal[Node] = LL_ManaHeal(level) / tempreal
              endif

          endif

          return false
      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to initialise the event listeners of the spell //
      ///////////////////////////////////////////////////////////////////
      function InitTrig_Leech_Life takes nothing returns nothing
          local trigger t = CreateTrigger()

          //Set up trigger
          call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
          call TriggerAddCondition(t, Condition(function LL_Cast))
      endfunction
      ///////////////////////////////////////////////////////////////////
      //  END OF THE SPELL                                             //
      ///////////////////////////////////////////////////////////////////
       
    • GIF Code
      [​IMG]
      Code (vJASS):
      ////////////////////////////////////////////////////////////////////
      //                     CORPSE CRUSHER V1.00                       //
      //  Author: Tank-Commander                                        //
      //  Requires: Dummy.mdl                                           //
      //  Purpose: Sustain ability to convert corpses into health &     //
      //           mana, can also be used to slow units in an AOE       //
      //                                                                //
      //  Credits: Vexorian (dummy.mdl)                                 //
      //                                                                //
      //  Notes:                                                        //
      //    -  Read the readme before you try modifying the config      //
      //    -  Use the "Helpful files" to help you import the system    //
      //                                                                //
      //                                                                //
      //  If you have used this spell in your map, you are required     //
      //  to give credits to Tank-Commander for the creation of it      //
      //  If you would like to use snippets of code from this for       //
      //  whatever, getting permission and crediting the source/linking //
      //  would be much appreciated.                                    //
      ////////////////////////////////////////////////////////////////////

      ////////////////////////////////////////////////////////////////////
      //  README:                                                       //
      //    Before modifying this spell a few things need to be         //
      //    understood and read, this is one of those things, while     //
      //    most modification can be considered intuitive, it still     //
      //    helps to read through these intstructions, as they will     //
      //    inform you about how to configure this spell to your        //
      //    desire.                                                     //
      //----------------------------------------------------------------//
      //  Initial importing: The variable creator trigger can be        //
      //  imported first and if you have the correct settings (file,    //
      //  preferences, General, automatically create unknown variables  //
      //  checked, then when you paste in the variable creator it       //
      //  will automatically give you all the variables you need for    //
      //  this spell                                                    //
      //                                                                //
      //  While the remaining object editor based data is not required  //
      //  to function (provided they're replaced with equivelents)      //
      //  it's recommended that they are also imported, if their data   //
      //  value are not the same as listed in the configuration, those  //
      //  configurables will need to be changed to work correctly       //
      //----------------------------------------------------------------//
      //  TimerSpeed: This is the rate at which the loop timer of the   //
      //  ability runs the default value 0.03125 allows the loop        //
      //  function to run 32 times per second giving a smooth ability   //
      constant function CC_TimerSpeed takes nothing returns real
          return 0.031250000
      endfunction
      //----------------------------------------------------------------//
      //  CheckTimerRate: This is the time in seconds between each      //
      //  check for units that have been added to the map with the      //
      //  ability (use if units are trained or spawned throughout the   //
      //  map)                                                          //
      constant function CC_CheckTimerRate takes nothing returns real
          return 0.5
      endfunction
      //----------------------------------------------------------------//
      //  CheckTimerPeriodic: Set to true if units that have the        //
      //  ability aren't preplaced in the map but also don't learn      //
      //  the ability like heroes (trained units for example)           //
      constant function CC_CheckTimerPeriodic takes nothing returns boolean
          return false
      endfunction
      //----------------------------------------------------------------//
      //  AuraDelay: This is the time in seconds between slowing new    //
      //  units and removing it from ones whom have left the AOE        //
      constant function CC_AuraDelay takes nothing returns real
          return 0.25
      endfunction
      //----------------------------------------------------------------//
      //  Ability: This is the raw code for the ability used as a base  //
      //  to see raw data press ctrl + d in the object editor, do it    //
      //  again to revert to normal                                     //
      constant function CC_Ability takes nothing returns integer
          return 'A004'
      endfunction
      //----------------------------------------------------------------//
      //  SlowAbility: This is the raw code for the ability used to     //
      //  slow units in the blood pool, should be based off slow aura   //
      constant function CC_SlowAbility takes nothing returns integer
          return 'A007'
      endfunction
      //----------------------------------------------------------------//
      //  BonusBuff: This is the raw code for the ability used to       //
      //  Apply speed bonuses to the ability (it can be either a        //
      //  regular ability or a specific buff which the caster can be    //
      //  afflicted with to give optionally temporary or permanent      //
      //  buffs to this ability                                         //
      constant function CC_BonusBuff takes nothing returns integer
          return 'A005'
      endfunction
      //----------------------------------------------------------------//
      //  BleedBuff: This is the raw code of the ability used to        //
      //  restore mana to the caster if the target has this buff        //
      constant function CC_BleedBuff takes nothing returns integer
          return 'A001'
      endfunction
      //----------------------------------------------------------------//
      //  DummyPlayer: This is the player who will own all dummy units  //
      //  created by this spell, it should be a neutral player as to    //
      //  not mess with scorescreens                                    //
      constant function CC_DummyPlayer takes nothing returns player
          return Player(14)
      endfunction
      //----------------------------------------------------------------//
      //  DummyUnit: This is the raw code for the unit used as a dummy  //
      //  by the ability, it should use dummy.mdl as its model or some  //
      //  other invisible model                                         //
      constant function CC_DummyUnit takes nothing returns integer
          return 'u000'
      endfunction
      //----------------------------------------------------------------//
      //  AttachmentPoint: This is the location on the dummy model      //
      //  that effects are placed onto                                  //
      constant function CC_AttachmentPoint takes nothing returns string
          return "origin"
      endfunction
      //----------------------------------------------------------------//
      //  BloodEffect: This is the effect attached to the dummy once    //
      //  it lands at the target point                                  //
      constant function CC_BloodEffect takes nothing returns string
          return "Abilities\\Spells\\Other\\HowlOfTerror\\HowlCaster.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  BloodMiniEffect: This is the effect used to create the pool   //
      //  of blood marking the AOE of the ability                       //
      constant function CC_BloodMiniEffect takes nothing returns string
          return "Abilities\\Weapons\\SludgeMissile\\SludgeMissile.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  BleedHealEffect: This is the effect created when the ability  //
      //  hits a target affected by BleedBuff                           //
      constant function CC_BleedHealEffect takes nothing returns string
          return "Abilities\\Spells\\Items\\AIma\\AImaTarget.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  CorpseCrushEffect: This is the effect created when a corpse   //
      //  is consumed by the caster                                     //
      constant function CC_CorpseCrushEffect takes nothing returns string
          return "Objects\\Spawnmodels\\Orc\\OrcLargeDeathExplode\\OrcLargeDeathExplode.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  CorpseHealEffectL This is the effect created on the caster    //
      //  when they consume a corpse                                    //
      constant function CC_CorpseHealEffect takes nothing returns string
          return "Objects\\Spawnmodels\\Orc\\OrcSmallDeathExplode\\OrcSmallDeathExplode.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  CorpseLaunchEffect: This is the model used for the corpse     //
      //  launched toward the target point of the ability from the      //
      //  caster                                                        //
      constant function CC_CorpseLaunchEffect takes nothing returns string
          return "Abilities\\Weapons\\MeatwagonMissile\\MeatwagonMissile.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  SlowBloodScale: This is the size of the BloodEffect 1 = 100%  //
      //  scale or default size                                         //
      function CC_SlowBloodScale takes real level returns real
          return 1.5
      endfunction
      //----------------------------------------------------------------//
      //  SlowCorpseScale: This is the size of the CorpseLaunchEffect   //
      //  1 = 100% scale of default size                                //
      function CC_SlowCorpseScale takes real level returns real
          return 2.
      endfunction
      //----------------------------------------------------------------//
      //  SlowBloodMiniScale: This is the size of the BloodMiniEffect   //
      //  1 = 100% scale of default size                                //
      constant function CC_SlowBloodMiniScale takes nothing returns real
          return 1.5
      endfunction
      //----------------------------------------------------------------//
      //  SlowBloodMiniSpace: This is the amount of space taken up      //
      //  by each BloodMiniEffect - this allows for the models to make  //
      //  a seemless pool and should be adjusted to match each model    //
      //  try to use as few effects as possible                         //
      constant function CC_SlowBloodMiniSpace takes nothing returns real
          return 75.
      endfunction
      //----------------------------------------------------------------//
      //  SlowSpinSpeed: This is the degrees per second that each       //
      //  BloodMiniEffect moves around in the circle around the centre  //
      //  of the blood pool                                             //
      constant function CC_SlowSpinSpeed takes nothing returns real
          return 73.3385978 * CC_TimerSpeed() * bj_DEGTORAD
      endfunction
      //----------------------------------------------------------------//
      //  Gravity: This is the strength of gravity pulling the corpse   //
      //  thrown back into the ground, higher values lead to a sharper  //
      //  arc taken by the projectile                                   //
      constant function CC_Gravity takes nothing returns real
          return -60. * CC_TimerSpeed()
      endfunction
      //----------------------------------------------------------------//
      //  HeightLet: This is the fly height which is considered close   //
      //  enough to the ground to count as grounded (this is because    //
      //  fly heights when often set to 0 actually set to ~0.04 so      //
      //  comparisons for current fly height below 0 will not work)     //
      constant function CC_HeightLet takes nothing returns real
          return 5.
      endfunction
      //----------------------------------------------------------------//
      //  StartHeight: This is the starting fly height of the corpse    //
      constant function CC_StartHeight takes nothing returns real
          return 50.
      endfunction
      //----------------------------------------------------------------//
      //  CorpseAOE: This is the distance from a corpse to the caster   //
      //  for the caster to consume the corpse                          //
      function CC_CorpseAOE takes real level returns real
          return 150.
      endfunction
      //----------------------------------------------------------------//
      //  CorpseHealHealth: This is the health restored to the caster   //
      //  by consuming a corpse                                         //
      function CC_CorpseHealHealth takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  CorpseHealMana: This is the mana restored to the caster by    //
      //  consuming a corpse                                            //
      function CC_CorpseHealMana takes real level returns real
          return 30 + (10 * (level - 1))
      endfunction
      //----------------------------------------------------------------//
      //  SlowAOE: This is the distance from the centre of the blood    //
      //  pool that units within are affected by the slow of the pool   //
      function CC_SlowAOE takes real level returns real
          return 250.
      endfunction
      //----------------------------------------------------------------//
      //  SlowDuration: This is the duration that the slowing blood     //
      //  pool lasts for in seconds                                     //
      function CC_SlowDuration takes real level returns real
          return 4. + (1. * level)
      endfunction
      //----------------------------------------------------------------//
      //  SlowHealthDamage: This is the damage dealt to units hit by    //
      //  the launched corpse upon impact                               //
      function CC_SlowHealthDamage takes real level returns real
          return 50.
      endfunction
      //----------------------------------------------------------------//
      //  SlowManaDamage: This is the amount of mana lost by units hit  //
      //  by the launched corpse upon impact                            //
      function CC_SlowManaDamage takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  SlowSpeed: This is the speed of the launched corpse in        //
      //  distance per second                                           //
      function CC_SlowSpeed takes real level returns real
          return 1400. * CC_TimerSpeed()
      endfunction
      //----------------------------------------------------------------//
      //  SlowBonusSpeed: This is the bonus speed of the launched       //
      //  corpse in distance per second when the casted is affected by  //
      //  BonusBuff                                                     //
      function CC_SlowBonusSpeed takes real level returns real
          return 800. * CC_TimerSpeed()
      endfunction
      //----------------------------------------------------------------//
      //  BleedHealHealth: This is the amount of health restored to     //
      //  the caster if a target hit by the launched corpse is affected //
      //  by BleedBuff                                                  //
      function CC_BleedHealHealth takes real level returns real
          return 0.
      endfunction
      //----------------------------------------------------------------//
      //  BleedHealMana: This is the amount of mana restored to the     //
      //  caster if a target hit by the launched corpse is affected     //
      //  by BleedBuff                                                  //
      function CC_BleedHealMana takes real level returns real
          return 25.
      endfunction
      //----------------------------------------------------------------//
      //  AttackType: This is the attack type used by the spell         //
      constant function CC_AttackType takes nothing returns attacktype
          return ATTACK_TYPE_NORMAL
      endfunction
      //----------------------------------------------------------------//
      //  DamageType: This is the damagetype used by the spell, armour  //
      //  reduces the damage based on this type                         //
      constant function CC_DamageType takes nothing returns damagetype
          return DAMAGE_TYPE_NORMAL
      endfunction
      //----------------------------------------------------------------//
      //  WeaponType: This is the weapon type used by the spell         //
      constant function CC_WeaponType takes nothing returns weapontype
          return null
      endfunction
      //----------------------------------------------------------------//
      //                         READ ONLY                              //
      //----------------------------------------------------------------//
      //  CasterStageID: StageID used by casters in the spell           //
      constant function CC_CasterStageID takes nothing returns integer
          return 1
      endfunction
      //----------------------------------------------------------------//
      //  CorpseStageID: StageID used by launched corpses in the spell  //
      constant function CC_CorpseStageID takes nothing returns integer
          return 2
      endfunction
      //----------------------------------------------------------------//
      //  BloodPoolStageID: StageID used by the central dummy in the    //
      //  blood pool                                                    //
      constant function CC_BloodPoolStageID takes nothing returns integer
          return 3
      endfunction
      //----------------------------------------------------------------//
      //  BloodPoolMiniStageID: StageID used by the spinning effects    //
      //  within the AOE of the blood pool                              //
      constant function CC_BloodPoolMiniStageID takes nothing returns integer
          return 4
      endfunction
      //----------------------------------------------------------------//
      //  2PI: stores the value of 2 * PI in order to keep processing   //
      //  fast                                                          //
      constant function CC_2PI takes nothing returns real
          return 2 * bj_PI
      endfunction
      //----------------------------------------------------------------//
      //                      END OF CONFIGURATION                      //
      //----------------------------------------------------------------//
      ////////////////////////////////////////////////////////////////////

      ////////////////////////////////////////////////////////////////////
      //  Function used to distinguish what counts as a valid target    //
      //  for the slowing caused by the pool of blood                   //
      ////////////////////////////////////////////////////////////////////
      function CC_DamageFilter takes unit u, player pl returns boolean
          return IsUnitEnemy(u, pl) and not(IsUnitType(u, UNIT_TYPE_STRUCTURE) or IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(u, UNIT_TYPE_DEAD) or IsUnitType(u, UNIT_TYPE_FLYING) or GetUnitTypeId(u) == 0)
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  This function is used to distinguish what counts as a corpse  //
      //  to the ability (this stops heroes/structures and locusts      //
      //  being counted as a valid corpse)                              //
      ////////////////////////////////////////////////////////////////////
      function CC_CorpseFilter takes unit u returns boolean
          return IsUnitType(u, UNIT_TYPE_DEAD) and not(IsUnitType(u, UNIT_TYPE_HERO)) and not(IsUnitType(u, UNIT_TYPE_STRUCTURE)) and GetUnitAbilityLevel(u,'Aloc') == 0 and not(IsUnitType(u, UNIT_TYPE_SUMMONED)) and not(IsUnitType(u, UNIT_TYPE_MECHANICAL))
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Function used to update level data of a particular Node       //
      ////////////////////////////////////////////////////////////////////
      function CC_SetLevelData takes unit u, real level, integer Node returns nothing
          //Set up all the level data
          set udg_CC_Unit[Node] = u
          set udg_CC_CorpseAOE[Node] = CC_CorpseAOE(level)
          set udg_CC_CorpseHealHealth[Node] = CC_CorpseHealHealth(level)
          set udg_CC_CorpseHealMana[Node] = CC_CorpseHealMana(level)
          set udg_CC_SlowAOE[Node] = CC_SlowAOE(level)
          set udg_CC_SlowBloodScale[Node] = CC_SlowBloodScale(level)
          set udg_CC_SlowCorpseScale[Node] = CC_SlowCorpseScale(level)
          set udg_CC_SlowDuration[Node] = CC_SlowDuration(level)
          set udg_CC_SlowHealthDamage[Node] = CC_SlowHealthDamage(level)
          set udg_CC_SlowManaDamage[Node] = CC_SlowManaDamage(level)
          set udg_CC_SlowSpeed[Node] = CC_SlowSpeed(level)
          set udg_CC_SlowBonusSpeed[Node] = CC_SlowBonusSpeed(level)
          set udg_CC_BleedHealHealth[Node] = CC_BleedHealHealth(level)
          set udg_CC_BleedHealMana[Node] = CC_BleedHealMana(level)
          set udg_CC_Level[Node] = R2I(level)
          set udg_CC_StageID[Node] = CC_CasterStageID()
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Function used to get the Z height of various locations        //
      ////////////////////////////////////////////////////////////////////
      function CC_GetZ takes real x, real y returns real

          call MoveLocation(udg_CC_ZLoc, x, y)
          return GetLocationZ(udg_CC_ZLoc)

      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Function used to remove nodes from the linked list            //
      ////////////////////////////////////////////////////////////////////
      function CC_RecycleNode takes integer Node returns nothing
          //Recycle
          set udg_CC_RecycleNodes[udg_CC_RecyclableNodes] = Node
          set udg_CC_RecyclableNodes = udg_CC_RecyclableNodes + 1
          set udg_CC_NextNode[udg_CC_PrevNode[Node]] = udg_CC_NextNode[Node]
          set udg_CC_PrevNode[udg_CC_NextNode[Node]] = udg_CC_PrevNode[Node]

          //Pause timer if this was the last instance
          if (udg_CC_PrevNode[0] == 0) then
              call PauseTimer(udg_CC_Timer)
          endif
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Function used to add Nodes to the linked list                 //
      ////////////////////////////////////////////////////////////////////
      function CC_CreateNode takes nothing returns integer
          local integer Node
          //Set up Node
          if (udg_CC_RecyclableNodes == 0) then
              set udg_CC_NodeNumber = udg_CC_NodeNumber + 1
              set Node = udg_CC_NodeNumber
          else
              set udg_CC_RecyclableNodes = udg_CC_RecyclableNodes - 1
              set Node = udg_CC_RecycleNodes[udg_CC_RecyclableNodes]
          endif

          set udg_CC_NextNode[Node] = 0
          set udg_CC_NextNode[udg_CC_PrevNode[0]] = Node
          set udg_CC_PrevNode[Node] = udg_CC_PrevNode[0]
          set udg_CC_PrevNode[0] = Node

          return Node
      endfunction
      ////////////////////////////////////////////////////////////////////
      //  Function used to remove the aura from units that are no       //
      //  longer being affected by a blood pool                         //
      ////////////////////////////////////////////////////////////////////
      function CC_AuraRemove takes nothing returns nothing
          local unit u = GetEnumUnit()

          if not(IsUnitInGroup(u, udg_CC_TempGroup2)) then
              call UnitRemoveAbility(u, CC_SlowAbility())
              call GroupRemoveUnit(udg_CC_SlowedGroup, u)
          endif

          set u = null
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Main function used to handle all of the various aspects of    //
      //  the ability from consuming corpses to moving the projectile   //
      //  and managing units that are being affected by the blood pool  //
      ////////////////////////////////////////////////////////////////////
      function CC_Loop takes nothing returns nothing
          local integer Node = 0
          local integer tempNode
          local real dist
          local real angle
          local real angle2
          local real anglelet
          local real circ
          local unit u
          local real x
          local real y
          local boolean b

          loop
              set Node = udg_CC_NextNode[Node]
              exitwhen Node == 0

              if udg_CC_StageID[Node] == CC_CasterStageID() then
                  if not(GetUnitTypeId(udg_CC_Unit[Node]) == null) then
             
                      //Make sure the unit is alive and hasn't used a tome of retraining
                      if not(IsUnitType(udg_CC_Unit[Node], UNIT_TYPE_DEAD)) and GetUnitAbilityLevel(udg_CC_Unit[Node], CC_Ability()) > 0 then
                          //Find corpses
                          call GroupEnumUnitsInRange(udg_CC_TempGroup, GetUnitX(udg_CC_Unit[Node]), GetUnitY(udg_CC_Unit[Node]), udg_CC_CorpseAOE[Node], null)
             
                          loop
                              set u = FirstOfGroup(udg_CC_TempGroup)
                              exitwhen u == null
                              call GroupRemoveUnit(udg_CC_TempGroup, u)
                              if CC_CorpseFilter(u) then
                                  //Splatter corpse and heal the caster
                                  call DestroyEffect(AddSpecialEffect(CC_CorpseCrushEffect(), GetUnitX(u), GetUnitY(u)))
                                  call SetWidgetLife(udg_CC_Unit[Node], GetWidgetLife(udg_CC_Unit[Node]) + udg_CC_CorpseHealHealth[Node])
                                  call SetUnitState(udg_CC_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_CC_Unit[Node], UNIT_STATE_MANA) + udg_CC_CorpseHealMana[Node])
                                  call DestroyEffect(AddSpecialEffectTarget(CC_CorpseHealEffect(), udg_CC_Unit[Node], CC_AttachmentPoint()))
                                  call RemoveUnit(u)
                              endif
                     
                          endloop
                 
                      endif
             
                  else
                      call CC_RecycleNode(Node)
                  endif
         
              elseif udg_CC_StageID[Node] == CC_CorpseStageID() then
                  set x = GetUnitX(udg_CC_Unit[Node]) + udg_CC_XVel[Node]
                  set y = GetUnitY(udg_CC_Unit[Node]) + udg_CC_YVel[Node]
         
                  //Keep the unit inside the map bounds
                  if ((udg_CC_MapMinX <= x) and (x <= udg_CC_MapMaxX) and (udg_CC_MapMinY <= y)and (y <= udg_CC_MapMaxY)) then
                      call SetUnitX(udg_CC_Unit[Node], x)
                      call SetUnitY(udg_CC_Unit[Node], y)
                  endif
         
                  //Change fly height
                  set udg_CC_CurrentHeight[Node] = udg_CC_CurrentHeight[Node] + udg_CC_ZVel[Node]
                  set udg_CC_ZVel[Node] = udg_CC_ZVel[Node] + CC_Gravity()
                  call SetUnitFlyHeight(udg_CC_Unit[Node], udg_CC_CurrentHeight[Node] - CC_GetZ(x, y), 0.)
         
                  //Check for impact
                  if GetUnitFlyHeight(udg_CC_Unit[Node]) <= CC_HeightLet() then
                      set udg_CC_X[Node] = x
                      set udg_CC_Y[Node] = y
                      set udg_CC_ZVel[Node] = GetUnitFacing(udg_CC_Unit[Node]) * bj_RADTODEG
                      set udg_CC_StageID[Node] = CC_BloodPoolStageID()
                      call DestroyEffect(udg_CC_Effect[Node])
                      set udg_CC_Effect[Node] = AddSpecialEffectTarget(CC_BloodEffect(), udg_CC_Unit[Node], CC_AttachmentPoint())
                      call SetUnitScale(udg_CC_Unit[Node], udg_CC_SlowBloodScale[Node], 0., 0.)
             
                      //Damage
                      set b = false
                      call GroupEnumUnitsInRange(udg_CC_TempGroup, x, y, udg_CC_SlowAOE[Node], null)
             
                      loop
                          set u = FirstOfGroup(udg_CC_TempGroup)
                          exitwhen u == null
                          call GroupRemoveUnit(udg_CC_TempGroup, u)
                 
                          if CC_DamageFilter(u, udg_CC_Player[Node]) then
                              call UnitDamageTarget(udg_CC_Caster[Node], u, udg_CC_SlowHealthDamage[Node], true, true, CC_AttackType(), CC_DamageType(), CC_WeaponType())
                              call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - udg_CC_SlowManaDamage[Node])
                 
                              //Heal Bonuses
                              if not(b) and GetUnitAbilityLevel(u, CC_BleedBuff()) > 0 then
                                  set b = true
                                  call SetWidgetLife(udg_CC_Caster[Node], GetWidgetLife(udg_CC_Caster[Node]) + udg_CC_BleedHealHealth[Node])
                                  call SetUnitState(udg_CC_Caster[Node], UNIT_STATE_MANA, GetUnitState(udg_CC_Caster[Node], UNIT_STATE_MANA) + udg_CC_BleedHealMana[Node])
                                  call DestroyEffect(AddSpecialEffectTarget(CC_BleedHealEffect(), udg_CC_Caster[Node], CC_AttachmentPoint()))
                              endif
                     
                          endif
                 
                      endloop
             
                      //Creating the aura effect
                      set dist = CC_SlowBloodMiniSpace()
                      set b = false
             
                      loop
                          exitwhen dist > udg_CC_SlowAOE[Node]
                 
                          set angle2 = CC_2PI() / ((CC_2PI() * dist) / CC_SlowBloodMiniSpace())
                          set angle = angle2
                          set anglelet = CC_2PI() + (angle2 / 2)
                          if b then
                                  set b = false
                              else
                                  set b = true
                          endif
                 
                          loop
                              exitwhen angle > anglelet
                     
                              //Create new aura segment and apply effects
                              set x = udg_CC_X[Node] + dist * Cos(angle)
                              set y = udg_CC_Y[Node] + dist * Sin(angle)
                              set tempNode = CC_CreateNode()
                              set udg_CC_Unit[tempNode] = CreateUnit(CC_DummyPlayer(), CC_DummyUnit(), x, y, angle * bj_RADTODEG + 90)
                              set udg_CC_Effect[tempNode] = AddSpecialEffectTarget(CC_BloodMiniEffect(), udg_CC_Unit[tempNode], CC_AttachmentPoint())
                              call SetUnitScale(udg_CC_Unit[tempNode], CC_SlowBloodMiniScale(), 0., 0.)
                              call SetUnitFlyHeight(udg_CC_Unit[tempNode], 0., 0.)
                              set udg_CC_Direction[tempNode] = b
                              set udg_CC_HomeNode[tempNode] = Node
                              set udg_CC_X[tempNode] = dist
                              set udg_CC_ZVel[tempNode] = angle
                              set udg_CC_StageID[tempNode] = CC_BloodPoolMiniStageID()
                     
                              set angle = angle + angle2
                          endloop
                 
                          set dist = dist + CC_SlowBloodMiniSpace()
                      endloop
             
                  endif
         
              elseif udg_CC_StageID[Node] == CC_BloodPoolMiniStageID() then
         
                  //Check if the aura is still active
                  if IsUnitType(udg_CC_Unit[udg_CC_HomeNode[Node]], UNIT_TYPE_DEAD) or GetUnitTypeId(udg_CC_Unit[udg_CC_HomeNode[Node]]) == 0 then
                      call DestroyEffect(udg_CC_Effect[Node])
                      call SetWidgetLife(udg_CC_Unit[Node], 0.)
                      call CC_RecycleNode(Node)
                  else
         
                      //Update aura positions
                      if udg_CC_Direction[Node] then
                          set angle = udg_CC_ZVel[Node] + udg_CC_ZVel[udg_CC_HomeNode[Node]]
                      else
                          set angle = udg_CC_ZVel[Node] - udg_CC_ZVel[udg_CC_HomeNode[Node]]
                      endif
         
                      call SetUnitX(udg_CC_Unit[Node], udg_CC_X[udg_CC_HomeNode[Node]] + udg_CC_X[Node] * Cos(angle))
                      call SetUnitY(udg_CC_Unit[Node], udg_CC_Y[udg_CC_HomeNode[Node]] + udg_CC_X[Node] * Sin(angle))
                      call SetUnitFacing(udg_CC_Unit[Node], angle * bj_RADTODEG + 90)
                  endif
         
              elseif udg_CC_SlowDuration[Node] > 0 then
                  set udg_CC_SlowDuration[Node] = udg_CC_SlowDuration[Node] - CC_TimerSpeed()
                  set udg_CC_ZVel[Node] = udg_CC_ZVel[Node] + CC_SlowSpinSpeed()
                  //Slow units
                  call GroupEnumUnitsInRange(udg_CC_TempGroup, udg_CC_X[Node], udg_CC_Y[Node], udg_CC_SlowAOE[Node], null)
         
                  loop
                      set u = FirstOfGroup(udg_CC_TempGroup)
                      exitwhen u == null        
                      call GroupRemoveUnit(udg_CC_TempGroup, u)

                      if CC_DamageFilter(u, udg_CC_Player[Node]) then
                          call GroupAddUnit(udg_CC_TempGroup2, u)
             
                          if not(IsUnitInGroup(u, udg_CC_SlowedGroup)) then
                              call GroupAddUnit(udg_CC_SlowedGroup, u)
                          endif
             
                          call UnitAddAbility(u, CC_SlowAbility())
                          call SetUnitAbilityLevel(u, CC_SlowAbility(), udg_CC_Level[Node])        
                      endif
             
                  endloop
         
              else
                  //Remove dummy
                  call DestroyEffect(udg_CC_Effect[Node])
                  call SetWidgetLife(udg_CC_Unit[Node], 0.)
                  call CC_RecycleNode(Node)
              endif

          endloop

          //Clean up slowed units
          if udg_CC_AuraDelay < 0 then
              set udg_CC_AuraDelay = CC_AuraDelay()
              call ForGroup(udg_CC_SlowedGroup, function CC_AuraRemove)
              call GroupClear(udg_CC_TempGroup2)
          else
              set udg_CC_AuraDelay = udg_CC_AuraDelay - CC_TimerSpeed()
          endif

      endfunction

      ////////////////////////////////////////////////////////////////////
      //  This function is used to find the node of units registered    //
      //  in the system, it creates a node for the unit if no node      //
      //  can be found for it                                           //
      ////////////////////////////////////////////////////////////////////
      function CC_GetUnitNode takes unit u returns integer
          local integer Node = 0

          loop
              set Node = udg_CC_NextNode[Node]
              exitwhen Node == 0

              if udg_CC_Unit[Node] == u then
                  return Node
              endif

          endloop

          set Node = CC_CreateNode()

          //Start timer if this is the only instance
          if (udg_CC_PrevNode[Node] == 0) then
              call TimerStart(udg_CC_Timer, CC_TimerSpeed(), true, function CC_Loop)
          endif

          return Node
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Function used to create spell data used by the corpse in      //
      //  transit and the slow aura area upon landing                   //
      ////////////////////////////////////////////////////////////////////
      function CC_Cast takes nothing returns boolean
          local integer Node
          local integer tempNode
          local real speed
          local real angle
          local real x
          local real y
          local real x2
          local real y2

          if (GetSpellAbilityId() == CC_Ability()) then
              set Node = CC_CreateNode()
              set tempNode = CC_GetUnitNode(GetTriggerUnit())

              //Set up data
              set udg_CC_StageID[Node] = CC_CorpseStageID()
              set udg_CC_Caster[Node] = udg_CC_Unit[tempNode]

              set x = GetUnitX(udg_CC_Unit[tempNode])
              set y = GetUnitY(udg_CC_Unit[tempNode])
              set x2 = GetSpellTargetX()
              set y2 = GetSpellTargetY()
              set angle = Atan2(y2 - y, x2 - x)

              //Create unit and apply effects
              set udg_CC_Unit[Node] = CreateUnit(CC_DummyPlayer(), CC_DummyUnit(), x, y, angle * bj_RADTODEG)
              set udg_CC_Player[Node] = GetOwningPlayer(udg_CC_Unit[tempNode])
              call PauseUnit(udg_CC_Unit[Node], true)
              if UnitAddAbility(udg_CC_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_CC_Unit[Node], 'Amrf') then
              endif
              set udg_CC_Effect[Node] = AddSpecialEffectTarget(CC_CorpseLaunchEffect(), udg_CC_Unit[Node], CC_AttachmentPoint())
              call SetUnitScale(udg_CC_Unit[Node], udg_CC_SlowCorpseScale[tempNode], 0., 0.)

              if GetUnitAbilityLevel(udg_CC_Caster[Node], CC_BonusBuff()) > 0 then
                  set speed = udg_CC_SlowSpeed[tempNode] + udg_CC_SlowBonusSpeed[tempNode]
              else
                  set speed = udg_CC_SlowSpeed[tempNode]
              endif

              set udg_CC_SlowAOE[Node] = udg_CC_SlowAOE[tempNode]
              set udg_CC_XVel[Node] = speed * Cos(angle)
              set udg_CC_YVel[Node] = speed * Sin(angle)
              set speed = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)) / speed
              set udg_CC_CurrentHeight[Node] = CC_GetZ(x,y) + CC_StartHeight()
              set udg_CC_ZVel[Node] = ((CC_GetZ(x2, y2) - udg_CC_CurrentHeight[Node]) - (CC_Gravity() * speed * speed) / 2)  / speed
              //Duplicate data to prevent level up mid-flight affecting the ability
              set udg_CC_SlowHealthDamage[Node] = udg_CC_SlowHealthDamage[tempNode]
              set udg_CC_SlowManaDamage[Node] = udg_CC_SlowManaDamage[tempNode]
              set udg_CC_SlowBloodScale[Node] = udg_CC_SlowBloodScale[tempNode]
              set udg_CC_SlowDuration[Node] = udg_CC_SlowDuration[tempNode]
              set udg_CC_BleedHealHealth[Node] = udg_CC_BleedHealHealth[tempNode]
              set udg_CC_BleedHealMana[Node] = udg_CC_BleedHealMana[tempNode]
              set udg_CC_Level[Node] = udg_CC_Level[tempNode]
              call SetUnitFlyHeight(udg_CC_Unit[Node], CC_StartHeight(), 0.)
          endif

          return false
      endfunction

      ////////////////////////////////////////////////////////////////////
      //  Function used when a hero learns an ability to update their   //
      //  level data if they have a node (and create one for them if    //
      //  they don't)                                                   //
      ////////////////////////////////////////////////////////////////////
      function CC_Update takes nothing returns boolean
          local unit u

          if GetLearnedSkill() == CC_Ability() then
              set u = GetTriggerUnit()
              //Set up all data
              call CC_SetLevelData(u, GetUnitAbilityLevel(u, CC_Ability()), CC_GetUnitNode(u))
              set u = null
          endif

          return false
      endfunction


      ////////////////////////////////////////////////////////////////////
      //  This function's primary purpose is to add all preplaced units //
      //  with the aura on the map to the system, however it can also   //
      //  be utilised for units which are added at runtime with the     //
      //  aura so that they can function correctly despite not running  //
      //  the other trigger (the same goes with trained units)          //
      ////////////////////////////////////////////////////////////////////
      function CC_RegisterExisting takes nothing returns boolean
          //Sets up locals
          local unit u
          local real level

          //Adds all units on the map to a unit group
          call GroupEnumUnitsInRect(udg_CC_TempGroup, bj_mapInitialPlayableArea, null)

          //Scans through the unit group looking for units with the ability
          loop
              set u = FirstOfGroup(udg_CC_TempGroup)
              exitwhen u == null

              set level = GetUnitAbilityLevel(u, CC_Ability())
              //Checks that the selected unit has the ability
              if (level > 0) then
                  //Attempts to add the unit
                  call CC_SetLevelData(u, level, CC_GetUnitNode(u))
              endif

              call GroupRemoveUnit(udg_CC_TempGroup, u)
          endloop

          //Checks if this function will run constantly, if not then destroy the trigger
          if (not(CC_CheckTimerPeriodic())) then
              call DestroyTrigger(GetTriggeringTrigger())
          endif

          return false
      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to initialise the event listeners of the spell //
      ///////////////////////////////////////////////////////////////////
      function InitTrig_Corpse_Crusher takes nothing returns nothing
          local trigger t = CreateTrigger()

          //Set up cast trigger
          call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
          call TriggerAddCondition(t, Condition(function CC_Cast))
          //Set up learn trigger
          set t = CreateTrigger()
          call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
          call TriggerAddCondition(t, Condition(function CC_Update))
          //Set up initial hero enabling trigger
          set t = CreateTrigger()
          //Sets up the event listener, if the function is periodic, then it will run constantly instead of just at the start
          call TriggerRegisterTimerEvent(t, CC_CheckTimerRate(), CC_CheckTimerPeriodic())
          call TriggerAddCondition(t, Condition(function CC_RegisterExisting))

          set udg_CC_ZLoc = Location(0., 0.)
          set udg_CC_MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
          set udg_CC_MapMinX = GetRectMinX(bj_mapInitialPlayableArea)
          set udg_CC_MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
          set udg_CC_MapMinY = GetRectMinY(bj_mapInitialPlayableArea)
      endfunction
      ///////////////////////////////////////////////////////////////////
      //  END OF THE SPELL                                             //
      ///////////////////////////////////////////////////////////////////
    • GIF Code
      [​IMG]
      Code (vJASS):
      ////////////////////////////////////////////////////////////////////
      //                       BLOOD BOIL V1.00                         //
      //  Author: Tank-Commander                                        //
      //  Purpose: Ultimate buff ability which enhances other spells    //
      //                                                                //
      //  Notes:                                                        //
      //    -  Read the readme before you try modifying the config      //
      //    -  Use the "Helpful files" to help you import the system    //
      //                                                                //
      //                                                                //
      //  If you have used this spell in your map, you are required     //
      //  to give credits to Tank-Commander for the creation of it      //
      //  If you would like to use snippets of code from this for       //
      //  whatever, getting permission and crediting the source/linking //
      //  would be much appreciated.                                    //
      ////////////////////////////////////////////////////////////////////

      ////////////////////////////////////////////////////////////////////
      //  README:                                                       //
      //    Before modifying this spell a few things need to be         //
      //    understood and read, this is one of those things, while     //
      //    most modification can be considered intuitive, it still     //
      //    helps to read through these intstructions, as they will     //
      //    inform you about how to configure this spell to your        //
      //    desire.                                                     //
      //----------------------------------------------------------------//
      //  Initial importing: The variable creator trigger can be        //
      //  imported first and if you have the correct settings (file,    //
      //  preferences, General, automatically create unknown variables  //
      //  checked, then when you paste in the variable creator it       //
      //  will automatically give you all the variables you need for    //
      //  this spell                                                    //
      //                                                                //
      //  While the remaining object editor based data is not required  //
      //  to function (provided they're replaced with equivelents)      //
      //  it's recommended that they are also imported, if their data   //
      //  value are not the same as listed in the configuration, those  //
      //  configurables will need to be changed to work correctly       //
      //----------------------------------------------------------------//
      //  TimerSpeed: This is the rate at which the loop timer of the   //
      //  ability runs the default value 0.03125 allows the loop        //
      //  function to run 32 times per second giving a smooth ability   //
      constant function BB_TimerSpeed takes nothing returns real
          return 0.03125000
      endfunction
      //----------------------------------------------------------------//
      //  Ability: This is the raw code for the ability used as a base  //
      //  to see raw data press ctrl + d in the object editor, do it    //
      //  again to revert to normal                                     //
      constant function BB_Ability takes nothing returns integer
          return 'A006'
      endfunction
      //----------------------------------------------------------------//
      //  BuffAbility: This is the raw code for the ability used to     //
      //  apply the blood boil buff to the caster, it should be based   //
      //  off slow aura                                                 //
      constant function BB_BuffAbility takes nothing returns integer
          return 'A005'
      endfunction
      //----------------------------------------------------------------//
      //  Duration: This is how long in seconds the ability lasts for   //
      function BB_Duration takes real level returns real
          return 60.
      endfunction
      //----------------------------------------------------------------//
      //  DamageTick: This is how many seconds there are between each   //
      //  set of damage, this should evenly divide into the duration    //
      function BB_DamageTick takes real level returns real
          return 1.
      endfunction
      //----------------------------------------------------------------//
      //  HealthDamage: This is the total amount of health damage the   //
      //  caster takes over the duration of the spell, set this to a    //
      //  negative value to make it heal the caster instead             //
      function BB_HealthDamage takes real level returns real
          return 600.
      endfunction
      //----------------------------------------------------------------//
      //  ManaDamage: This is the total amount of mana damage the       //
      //  caster takes over the duration of the spell, set this to a    //
      //  negative value to make it heal the caster instead             //
      function BB_ManaDamage takes real level returns real
          return -60.
      endfunction
      //----------------------------------------------------------------//
      //  DamageEffect: This is the effect played on the caster when    //
      //  they take damage or are healed by the ability                 //
      constant function BB_DamageEffect takes nothing returns string
          return "Abilities\\Weapons\\HydraliskImpact\\HydraliskImpact.mdl"
      endfunction
      //----------------------------------------------------------------//
      //  DamageAttachmentPoint: This is the location on the hero that  //
      //  the DamageEffect is placed onto                               //
      constant function BB_DamageAttachmentPoint takes nothing returns string
          return "chest"
      endfunction
      //----------------------------------------------------------------//
      //  HueRed: This is how red the hero goes when they take damage   //
      constant function BB_HueRed takes nothing returns integer
          return 255
      endfunction
      //----------------------------------------------------------------//
      //  HueBlue: This is how blue the hero goes when they take damage
      constant function BB_HueBlue takes nothing returns integer
          return 120
      endfunction
      //----------------------------------------------------------------//
      //  HueGreen: This is how green the hero goes when they take      //
      //  damage                                                        //
      constant function BB_HueGreen takes nothing returns integer
          return 120
      endfunction
      //----------------------------------------------------------------//
      //  HueRecoverSpeed: This is how quickly the heroes colour is     //
      //  restored to normal (255/255/255) this runs at a rate of       //
      //  the TimerSpeed, so by default tihs runs 32 times per second   //
      //  (e.g. if HueBlue is set to 50 and this to 4  then after 1     //
      //  second the blue hue will now be 178                           //
      constant function BB_HueRecoverSpeed takes nothing returns integer
          return 4
      endfunction
      //----------------------------------------------------------------//
      //  UseHue: Set this to true to make the hero use the hue         //
      //  colours when castig the spell, don't use if the hero has a    //
      //  default colouration other than 255/255/255                    //
      constant function BB_UseHue takes nothing returns boolean
          return true
      endfunction
      //----------------------------------------------------------------//
      //                      END OF CONFIGURATION                      //
      //----------------------------------------------------------------//
      ////////////////////////////////////////////////////////////////////

      ///////////////////////////////////////////////////////////////////
      //  Function used to check if a unit currently has any remaining //
      //  blood boil buffs (this is relevent if the ability can be     //
      //  casted multiple times by the same unit)                      //
      ///////////////////////////////////////////////////////////////////
      function BB_IsNotBuffed takes unit u returns boolean
          local integer Node = 0

          loop
              set Node = udg_BB_NextNode[Node]
              exitwhen Node == 0

              if udg_BB_Unit[Node] == u then
                  return false
              endif

          endloop

          return true
      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to deal damage to units over time when they    //
      //  have the buff, delays it to match standard ingame mechanics  //
      ///////////////////////////////////////////////////////////////////
      function BB_Loop takes nothing returns nothing
          local integer Node = 0

          loop
              set Node = udg_BB_NextNode[Node]
              exitwhen Node == 0

              if udg_BB_Duration[Node] >= 0 then
                  set udg_BB_Duration[Node] = udg_BB_Duration[Node] - BB_TimerSpeed()
                  set udg_BB_DamageTickCurrent[Node] = udg_BB_DamageTickCurrent[Node] - BB_TimerSpeed()
         
                  if udg_BB_DamageTickCurrent[Node] <= 0 then
                      //Deal damage/heal
                      set udg_BB_DamageTickCurrent[Node] = udg_BB_DamageTick[Node]
                      call SetWidgetLife(udg_BB_Unit[Node], GetWidgetLife(udg_BB_Unit[Node]) - udg_BB_HealthDamage[Node])
                      call SetUnitState(udg_BB_Unit[Node], UNIT_STATE_MANA, GetUnitState(udg_BB_Unit[Node], UNIT_STATE_MANA) - udg_BB_ManaDamage[Node])
                      call DestroyEffect(AddSpecialEffectTarget(BB_DamageEffect(), udg_BB_Unit[Node], BB_DamageAttachmentPoint()))
             
                      //Reset Colours
                      if BB_UseHue() then
                          set udg_BB_Red[Node] = BB_HueRed()
                          set udg_BB_Blue[Node] = BB_HueBlue()
                          set udg_BB_Green[Node] = BB_HueGreen()
                      endif
             
                  //Apply Colour change
                  elseif BB_UseHue() then
                      set udg_BB_Red[Node] = udg_BB_Red[Node] + BB_HueRecoverSpeed()
                      set udg_BB_Blue[Node] = udg_BB_Blue[Node] + BB_HueRecoverSpeed()
                      set udg_BB_Green[Node] = udg_BB_Green[Node] + BB_HueRecoverSpeed()
                  endif
         
                  call SetUnitVertexColor(udg_BB_Unit[Node], udg_BB_Red[Node], udg_BB_Green[Node], udg_BB_Blue[Node], 255)
              else

                  //Recycle
                  set udg_BB_RecycleNodes[udg_BB_RecyclableNodes] = Node
                  set udg_BB_RecyclableNodes = udg_BB_RecyclableNodes + 1
                  set udg_BB_NextNode[udg_BB_PrevNode[Node]] = udg_BB_NextNode[Node]
                  set udg_BB_PrevNode[udg_BB_NextNode[Node]] = udg_BB_PrevNode[Node]

                  if BB_IsNotBuffed(udg_BB_Unit[Node]) then
                      call UnitRemoveAbility(udg_BB_Unit[Node], BB_BuffAbility())
             
                      //Reset colours
                      if BB_UseHue() then
                          call SetUnitVertexColor(udg_BB_Unit[Node], 255, 255, 255, 255)
                      endif
             
                      //Pause timer if this was the last instance
                      if (udg_BB_PrevNode[0] == 0) then
                          call PauseTimer(udg_BB_Timer)
                      endif
             
                  endif
              endif

          endloop

      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used when the spell is cast to apply the buff and   //
      //  set up unit data for the loop                                //
      ///////////////////////////////////////////////////////////////////
      function BB_Cast takes nothing returns boolean
          local integer Node
          local real level

          if (GetSpellAbilityId() == BB_Ability()) then
              //Set up Node
              if (udg_BB_RecyclableNodes == 0) then
                  set udg_BB_NodeNumber = udg_BB_NodeNumber + 1
                  set Node = udg_BB_NodeNumber
              else
                  set udg_BB_RecyclableNodes = udg_BB_RecyclableNodes - 1
                  set Node = udg_BB_RecycleNodes[udg_BB_RecyclableNodes]
              endif

              set udg_BB_NextNode[Node] = 0
              set udg_BB_NextNode[udg_BB_PrevNode[0]] = Node
              set udg_BB_PrevNode[Node] = udg_BB_PrevNode[0]
              set udg_BB_PrevNode[0] = Node

              //Start timer if this is the only instance
              if (udg_BB_PrevNode[Node] == 0) then
                  call TimerStart(udg_BB_Timer, BB_TimerSpeed(), true, function BB_Loop)
              endif

              //set up instance data
              set udg_BB_Unit[Node] = GetTriggerUnit()
              set level = GetUnitAbilityLevel(udg_LL_Caster[Node], LL_Ability())
              set udg_BB_Duration[Node] = BB_Duration(level)
              set udg_BB_DamageTick[Node] = BB_DamageTick(level)
              set udg_BB_DamageTickCurrent[Node] = udg_BB_DamageTick[Node]
              set udg_BB_HealthDamage[Node] = BB_HealthDamage(level) / udg_BB_Duration[Node]
              set udg_BB_ManaDamage[Node] = BB_ManaDamage(level) / udg_BB_Duration[Node]
              call UnitAddAbility(udg_BB_Unit[Node], BB_BuffAbility())
              call SetUnitAbilityLevel(udg_BB_Unit[Node], BB_BuffAbility(), R2I(level))

              if BB_UseHue() then
                  set udg_BB_Red[Node] = BB_HueRed()
                  set udg_BB_Blue[Node] = BB_HueBlue()
                  set udg_BB_Green[Node] = BB_HueGreen()
              endif

          endif

          return false
      endfunction

      ///////////////////////////////////////////////////////////////////
      //  Function used to initialise the event listeners of the spell //
      ///////////////////////////////////////////////////////////////////
      function InitTrig_Blood_Boil takes nothing returns nothing
          local trigger t = CreateTrigger()

          //Set up trigger
          call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
          call TriggerAddCondition(t, Condition(function BB_Cast))
      endfunction
      ///////////////////////////////////////////////////////////////////
      //  END OF THE SPELL                                             //
      ///////////////////////////////////////////////////////////////////
     

    Attached Files:

    Last edited: Aug 28, 2016
  17. Direfury

    Direfury

    Joined:
    Jun 17, 2007
    Messages:
    3,141
    Resources:
    153
    Models:
    140
    Icons:
    11
    Packs:
    1
    Spells:
    1
    Resources:
    153
    It looks great, but it seems more like a moba hero.

    Not that that's bad.
     
  18. Tank-Commander

    Tank-Commander

    Spell Reviewer

    Joined:
    May 26, 2009
    Messages:
    1,539
    Resources:
    44
    Packs:
    1
    Spells:
    41
    Tutorials:
    2
    Resources:
    44
    I'm sure most heroes could be adapted to fit a moba/AoS's, heck there are AoS's that have used melee heroes, any hero with abilities that can work together or combo-ed at all will seem that way (team this is not a team's entry could also easily have that said about it for this reason). The only way for that to not be the case would be if either none of the abilities work together that much or they're melee specific (i.e. charm as an ulti) - the blademaster for example could easily be modified only a little to be right at home in one.

    That said, I'd suggest trying out the hero in an actual melee game - moba-ish or otherwise it'd only be an issue if it felt out of place in a melee
     
  19. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,501
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20

    [​IMG]

    Mur'gul Warlock

    by THE FLAMING SKULL OF WADDLES
    a.k.a Direfury and KILLCIDE




    [​IMG] Noxious Cloud (On Cast)

    Fel acid is projected from the Warlock, creating a poisonous cloud at the target location. The cloud will deal damage over time and slow enemy unit's movement speed. A Noxious Cloud can be ignited by a Conflagrate missile, dealing area of effect damage to nearby enemy units.
    [​IMG] Conflagrate (On Cast / Nox Cloud Explosion)

    Releases a fel flame missile for a fixed distance, dealing damage to enemy units in a line. If the missile comes in contact with a Noxious Cloud, the cloud will explode and deal damage to nearby enemy units.
    [​IMG] Dark Respite (Preview)

    Whenever the Warlock lands a killing blow on a unit, the soul of the unit will be temporarily cached into a visible orb. If the Warlock walks over the orb, it will restore mana points.
    [​IMG] Fel Meteor (On Cast / Nox Cloud Explosion)

    Channels a Fel Meteor to fall from the sky for 2.25 seconds. If the Warlock channels for the full duration, the Meteor will plunge towards the target location, dealing 220 damage to nearby enemy units. Enemy unit's will also have their attack rate and movement speed reduced by 50% for 6 seconds. If there are any active Noxious Clouds within the vicinity, the Fel Meteor will ignite them.


    Make sure to click on the links next to the spell name for previews! Alternatively, you can just look down below :p
     

    Attached Files:

  20. Direfury

    Direfury

    Joined:
    Jun 17, 2007
    Messages:
    3,141
    Resources:
    153
    Models:
    140
    Icons:
    11
    Packs:
    1
    Spells:
    1
    Resources:
    153
    Personally, I wanted to go with some sneaky mind control, or curses.

    In the end, though, I really enjoy our "Destruction Warlock" theme.
     
Thread Status:
Not open for further replies.