| 07-03-2007, 05:42 PM | #1 | |||
Description: Spell Description:
Background: The spell is made specifically for the Spell Session #8 on wc3c. The spell is fully multi-instanceable and requires vJass. It was based on the idea of creating a ward that interacted with mana by burning it; it sounded cool at the time. Requirements:
Spell Code://****************************************************************************** //* * //* Bluefire Ward * //* v1.7 * //* * //* By: Rising_Dusk * //* * //****************************************************************************** //************************************** //* LIBRARY REQUIREMENTS: //* - GroupUtils //* scope BluefireWard initializer Init globals //************************************************************* //* Configuration Constants //* Raw codes private constant integer WARD_ID = 'o000' private constant integer DUMMY_ID = 'h000' private constant integer SPELL_ID = 'A000' private constant integer FINGER_OF_DEATH_ID = 'A001' //* Spell data private constant real MANA_BURN_THRESHOLD = 5. //* System related private constant real TIMER_INTERVAL = 0.5 //* Dummy unit configuration private constant real DUMMY_UNIT_TIP_HEIGHT = 120. //* Damage properties private constant attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL //************************************************************* //* System Variables private unit TempUnit = null private timer Timer = CreateTimer() private integer Counter = 0 private integer array Wards private constant integer FINGER_OF_DEATH_ORDER = 852230 private boolexpr Checker = null endglobals private constant function ManaBurn takes integer lvl returns real //* This is how much mana is burned per second return 5.+(5.*lvl) endfunction private constant function Radius takes integer lvl returns real //* This is the ward's mana burning radius. return 400. endfunction private function Check takes nothing returns boolean //* This is to determine what units will be targeted for the mana burn. return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(TempUnit)) and GetUnitState(GetFilterUnit(), UNIT_STATE_MANA) > MANA_BURN_THRESHOLD and GetWidgetLife(GetFilterUnit()) > 0.405 and GetUnitAbilityLevel(GetFilterUnit(), 'Avul') <= 0 endfunction //***************************************************************** private struct ward unit Ward = null unit Dummy = null integer Level = 0 static method create takes unit u, unit d, integer lvl returns ward local ward w = ward.allocate() local real x = GetUnitX(d) local real y = GetUnitY(d) set w.Ward = d set w.Dummy = CreateUnit(GetOwningPlayer(u), DUMMY_ID, x, y, 0) set w.Level = lvl call UnitAddAbility(w.Dummy, FINGER_OF_DEATH_ID) call UnitAddAbility(w.Dummy, 'Amrf') call UnitRemoveAbility(w.Dummy, 'Amrf') call SetUnitFlyHeight(w.Dummy, DUMMY_UNIT_TIP_HEIGHT, 0.) call UnitRemoveAbility(w.Dummy, 'Amov') call SetUnitX(w.Dummy, x) call SetUnitY(w.Dummy, y) return w endmethod private method onDestroy takes nothing returns nothing call RemoveUnit(this.Dummy) endmethod endstruct private function Conditions takes nothing returns boolean return GetUnitTypeId(GetSummonedUnit()) == WARD_ID endfunction private function Callback takes nothing returns nothing local unit u = null local unit d = null local unit s = null local ward w = 0 local integer i = Counter - 1 local integer lvl = 0 local real m = 0. local real r = 0. local real x = 0. local real y = 0. loop exitwhen i < 0 set w = Wards[i] set u = w.Ward set d = w.Dummy set lvl = w.Level if GetWidgetLife(u) < 0.405 then call w.destroy() set Counter = Counter - 1 if Counter < 0 then set Counter = 0 else set Wards[i] = Wards[Counter] endif else set x = GetUnitX(u) set y = GetUnitY(u) set TempUnit = u call GroupEnumUnitsInRange(ENUM_GROUP, x, y, Radius(lvl), Checker) loop set s = FirstOfGroup(ENUM_GROUP) exitwhen s == null set r = ManaBurn(lvl)*TIMER_INTERVAL set m = GetUnitState(s, UNIT_STATE_MANA) if r > m then set r = m endif call SetUnitX(d, x) call SetUnitY(d, y) call SetUnitState(s, UNIT_STATE_MANA, m - r) call IssueTargetOrderById(d, FINGER_OF_DEATH_ORDER, s) call UnitDamageTarget(u, s, r, false, false, ATTACK_TYPE, DAMAGE_TYPE, null) call GroupRemoveUnit(ENUM_GROUP, s) endloop call GroupClear(ENUM_GROUP) endif set i = i - 1 endloop set u = null set d = null set s = null endfunction private function Actions takes nothing returns nothing local unit u = GetSummoningUnit() local unit d = GetSummonedUnit() local integer lvl = GetUnitAbilityLevel(u, SPELL_ID) local ward w = ward.create(u, d, lvl) if Counter == 0 then call TimerStart(Timer, TIMER_INTERVAL, true, function Callback) endif set Wards[Counter] = w set Counter = Counter + 1 set u = null set d = null endfunction private function Init takes nothing returns nothing local trigger trg = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SUMMON) call TriggerAddCondition(trg, Condition(function Conditions)) call TriggerAddAction(trg, function Actions) set Checker = Condition(function Check) set trg = null endfunction endscope Change Log: Quote:
Special Thanks: All credits to anything used in the spell are in the testmap, but I'll do it again here. Thanks to Vex for vJass and JESP and thanks to wc3c for another cool contest. Hope you all like it! |
| 07-03-2007, 06:30 PM | #2 |
Looks like green lightning to me. :/ |
| 07-03-2007, 06:33 PM | #3 |
Would you rather it spam your screen with little blue "-20"s? :p Besides, it's just a name. |
| 07-03-2007, 10:44 PM | #4 |
I'd rather the lightning be blue so that it matches the name... nice spell though... other than the colour, +Rep |
| 07-03-2007, 11:11 PM | #5 |
I DEMMAND to change the lightning color to blue, otherwise it will be graveyard'd at once!!! Just kidding, because I couldn't give my opinion in the contest about your spell, I'll take this opportunity to give a good review. Stay tunned. |
| 07-03-2007, 11:21 PM | #6 |
would have been a cooler mechanic if it hurt units casting a spell, like fairy dragons do. Still a verry nice usuable spell though, nothing too fancy. Luv. |
| 07-04-2007, 12:45 AM | #7 |
The ward is blue and on fire, not the lightning... think. |
| 07-04-2007, 01:17 AM | #8 | |
Quote:
|
| 07-07-2007, 05:00 PM | #10 | |
Quote:
|
| 07-07-2007, 11:36 PM | #11 | |
Quote:
Yea, It is easier, and it's in Dota :P |
| 07-08-2007, 12:18 AM | #12 |
Why not a manaburn that triggers when a unit is casting a spell - like a 250 manaburn when an enemy unit casts a spell. Manaflare (which is what the Faerie's have) actually doesn't burn any mana, it merely damages a unit based on the cost of a spell. |
| 07-12-2007, 02:47 AM | #13 |
Ok Dusk, here's my review: First of all I did some modifications to your demo map in order to give a full test.
I'll be pending for the bug fixes. |
| 07-12-2007, 03:38 AM | #14 | |
Destroying boolexprs isn't bad practice though. The same reason I clear groups before I destroy them, it's safe practice. That's how I code. Quote:
If there's an issue with the MUI, I must have merely overlooked something. I'll look into it though, thanks for the replay. EDIT: And actually, my method is as efficient as possible, structs here would be overkill. I run all castings of the spell for all players on a single timer. It's about as good as it gets. EDIT AGAIN: The spell indeed correctly works against heroes. The dummy FoD spell was set to be unable to target heroes though, which is the problem. If you pay close enough attention, it still burns mana correctly. And your replay shows nothing wrong with the MUI when I tried it. And I just tested it again, nothing seems to be going wrong. Could you elaborate upon the EXACT conditions that caused it to not be MUI? LAST EDIT: Just editted your testmap to include the very minor fix to make the dummy ability castable on anything. It uh, works perfectly as far as I can tell now. Your random bolts must have been the dummy units having a fit from being unable to cast on heroes. Attached it too. |
| 07-12-2007, 10:57 AM | #15 | ||||
Quote:
Quote:
Quote:
One more minor thing (optional): You use the BJ variable bj_ghoul[99], you can use this one instead bj_meleeNearestMine this one is only used at map initialization in melee maps and no more. Quote:
|
