| 01-27-2003, 03:52 PM | #1 |
As some of you might know, trying to enhance a spell with a trigger is a bit of a pain unless you want that spell to have unlimited range. Thats because the only way we have of detecting spells is by using an order string and an order can be issued from all the way across the map basically. So lets say that you have some cool idea for a spell that you cant do with simple spell editing. Lets say that you want holy bolt to pause a unit until some other unit casts death coil on it, lets say that you want purge to turn something into a seal for 30 seconds, lets say that you want mana burn to steal life instead of mana. All of these need to be done with triggers, and the only way that we can do that is by detecting an order string for "holybolt", "manaburn" and other spells like them. This process has one critical flaw, and thats the fact that an order can be issued outside the range of the target. Well after some careful thought, i came up with a trigger that will activate a function when a spell is cast, not when the order is issued. Heres what it does in a nutshell: 1) Check for range upon the issue of a specific order (holybolt) in this case. 2) If the range is right, run the spell enhancer, if its not, create a trigger (Unit - unit within range) on the fly with the targeted unit of the spell as its source. 3) Add a condition that the unit entering nearing the unit must be the caster of the spell 4) If the player hasnt issued any other orders (stop, move to another spot, anything to prevent the casting of the spell) the range trigger is destoryed to prevent any accidental effects. 5) When the activation occurrs there is a small synch delay to compensate for the tiny wait between ordering a cast and the cast itself. And thats it! Even with a 2 liter of mountain dew in me i can't cancel the order fast enough to break it. If anyone notices any flaws or knows of a better way to do this then your commentary will certianly be welcome. But for now im pretty sure that this will work. Note: All of this fits into one trigger, and you can even modify it to work for all of your custom spells with a crafty use of arrays. (i only have 3 spells that need this though so i havent gone haywire with the arrays yet). This trigger requires 2 global variables: trigger udg_HB_Locate boolean udg_HB_Cancel When making copies of this trigger, be sure to add a NEW trigger and boolean variable for each spell, otherwise if two are cast at the same time it will likely fail. Code:
//=============================================
// USER ACTIONS:
// This where you change the code of your actual spell
// Caster and Recipient are unit variables and all you need to facilitate
// any change.
// CHANGES: Add all your spell functionality here
//=============================================
function UserActions takes unit caster, unit recipient returns nothing
// All this enhancement does is dislay some text for verification.
call DisplayTextToForce(GetPlayersAll(), "HolyBolt Enhancer Activated." + "")
endfunction
//=============================================
// CASTER WITHIN RANGE (Condition)
// This condition is used for the event generated when the hero is beyond the
// range.
// CHANGES: Change gg_unit_Hpal_0000 to be the hero that will cast this spell
//=============================================
// This returns true when the unit approaching is the proper unit (ie the one casting the spell)
function CasterWithinRange takes nothing returns boolean
// This is where you need your reference to your hero
if GetTriggerUnit() == gg_unit_Hpal_0000 then
return true
endif
return false
endfunction
//=============================================
// ENHANCE SPELL:
// This adds a small delay to synch the spell effect with the actual casting
// of the spell.
// CHANGES: If you want to make an array of spells just change the "UserActions"
// function to a list of all your functions and determine the right
// one using a global variable of some sort (likely an int that you
// set in the actions trigger)
// CHANGES: Change udg_HB_Cancel to a unique boolean variable when adding
// additional spells.
//=============================================
function EnhanceSpell takes unit caster, unit recipient returns nothing
// Wait to
set udg_HB_Cancel = false
call TriggerSleepAction( .5 )
if not udg_HB_Cancel then
// This is a default set of actions to perform
call UserActions(caster, recipient)
endif
endfunction
//=============================================
// ENHANCE SPELL WRAPPER
// This is necessary to make the changes between unit issued order and unit within range
// CHANGES: Change gg_unit_Hpal_0000 to be the hero that will cast this spell
//=============================================
function EnhanceSpellWrapper takes nothing returns nothing
call EnhanceSpell( gg_unit_Hpal_0000, GetTriggerUnit() )
call DestroyTrigger( udg_HB_Locate )
endfunction
//=============================================
// HB ENHANCER ACTIONS
// This is necessary to make the changes between unit issued order and unit within range
// CHANGES: Change gg_unit_Hpal_0000 to be the hero that will cast this spell
// CHANGES: Change 800 to the range of your spell
// CHANGES: Change 880 to the range of your spell + 80
// CHANGES: Change all instances of udg_HB_Locate to a unique trigger when adding
// additional spells.
//=============================================
function Trig_HB_Enhancer_Actions takes nothing returns nothing
// If its not your designated caster, then return false
// (Leave this in, it will stop water elementals and summons from cancelling
// your spell once its cast)
if GetTriggerUnit() != gg_unit_Hpal_0000 then
return
endif
// Someone has issued an order besides holy bolt, so we cancel
if GetIssuedOrderIdBJ() != String2OrderIdBJ("holybolt") then
set udg_HB_Cancel = true
call DestroyTrigger( udg_HB_Locate )
return
endif
//**** UNWRAP THIS LINE, I CANT GET IT TO UNWRAP IN THE MESSAGE EDITOR
if DistanceBetweenPoints(GetUnitLoc(GetTriggerUnit()), GetUnitLoc(GetOrderTargetUnit())) < 800.00 then
//***
// We are within range, go ahead and enhance the cast
call DisplayTextToForce(GetPlayersAll(), "Within Range, Casting." + "")
call EnhanceSpell(GetTriggerUnit(), GetOrderTargetUnit())
else
// Create a new trigger for when we get in range
call DisplayTextToForce(GetPlayersAll(), "Out of range, setting up range trigger." + "")
set udg_HB_Locate = CreateTrigger()
call TriggerAddAction( udg_HB_Locate, function EnhanceSpellWrapper )
//call DisplayTextToForce(GetPlayersAll(), "Event Registered for: " + GetUnitName(GetOrderTargetUnit()))
call TriggerRegisterUnitInRangeSimple( udg_HB_Locate, 880.00, GetOrderTargetUnit())
call TriggerAddCondition( udg_HB_Locate, Condition( function CasterWithinRange ))
endif
endfunction
//=============================================
function InitTrig_TrigSpellEnhancer takes nothing returns nothing
set gg_trg_TrigSpellEnhancer = CreateTrigger( )
// Detect the 3 type of orders for our event
call TriggerRegisterPlayerUnitEventSimple( gg_trg_TrigSpellEnhancer, Player(0), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_TrigSpellEnhancer, Player(0), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
call TriggerRegisterPlayerUnitEventSimple( gg_trg_TrigSpellEnhancer, Player(0), EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddAction( gg_trg_TrigSpellEnhancer, function Trig_HB_Enhancer_Actions )
endfunctionThe map is also attached, try to break it if you can. (when the enhancer is activated it will display "HolyBolt Enhancer Activated.". If you can cast the spell without seeing that, or if you see that without casting a spell then something went wrong. Save a film and post please it if that happens. Otherwise i have no way of finding out what went wrong. And even if that does happen this is a first step into this immense problem and a solution is out there somewhere just waiting for us. Note: Feel free to use this thread to post any other methods you might use or know of. Sincerely FM_TertiaryEye |
| 01-27-2003, 03:56 PM | #2 |
Heres the actual map i used to test if you want to try it firsthand. |
| 01-28-2003, 06:46 PM | #3 |
i broke it... unfortuantely =o having same issue resolving my custom spells, ill let u know if i find a fix. your method is very clean though, GJ NOTE: add to the things that can cancel a spell that the caster dies the target dies or the caster is stunned (havnt found a solution for the last one yet) ?: do you need X coppies of this trigger for each spell where X is the number players that can own this hero? edit: one more thing, are you using the paladin unit as a global? |
| 01-29-2003, 07:50 AM | #4 |
========================== i broke it... unfortuantely =o having same issue resolving my custom spells, ill let u know if i find a fix. your method is very clean though, GJ ========================== Awww, well its a start at least. Do you have any idea of what migth have broken it? do you have a film perhaps? Which part broke? Did it display the message without casting the spell? or did casting the spell not display the message? ========================== NOTE: add to the things that can cancel a spell that the caster dies the target dies or the caster is stunned (havnt found a solution for the last one yet) ========================== Ahhh, good idea. I didnt think of caster death. Stunning.. Hmmm. lol why blizzard why! Well, if someone is stunned when they are unstunned they will issue an order, thus destroying the trigger, however if their target moves within range of them the damn thing will still activate.. BAH! ========================== ?: do you need X coppies of this trigger for each spell where X is the number players that can own this hero? ========================== Not at all, however, this is created for a system where the hero can be owned by only one player at a time. Which is what i think most people will use it for. It can be rigged for two of the same type of hero, the unit in range trigger would have to be changed to a unit type comparison. In fact doing that would place it better off than it is now i think. ========================== edit: one more thing, are you using the paladin unit as a global? ========================== Yes, now that i think more on that part, if each player is garaunteed to have just one of each hero, then its better to use a unit type comparison. Thanks! And thanks for responding! FM_TertiaryEye |
| 01-29-2003, 06:11 PM | #5 |
I sent you a PM on how i broke it, because after working on it some more i dont know if there is a fix for this, and its not something everyone needs to know. |
| 02-11-2003, 02:32 AM | #6 | |
Guest | SpellEnhancer v0.30 - Based off FM_TertiaryEye's holy bolt enhancer and modified by SID6.7 FM_TertiaryEye fixed a number of problems caused when using a custom trigger with a specific order (see above). Specifically, when a order is issued, his enhancer checked for range before running the custom trigger. If the unit was out of range, it created a temporary new trigger until the unit was in range again. My enhancer improves his method by adding multiplayer support, checking for death, checking for stun, checking for new orders, by allowing targets that are points, by working for any unit, by not allowing the multiple trigger exploit, by allowing multiple orders and by allowing multiple units of the same type to cast the same order. You'll find the Spell Enhancer and some examples of modified spells (stormbolt, holy light, blizzard) in the attached .w3m file. It's not always pretty, but it's solved most of the issues I across and should solve your problems with using triggers to enhance spells. I don't want to support this, so please don't PM me with questions. Custom text is a pain to support:) Quote:
|
