| 01-22-2010, 09:35 PM | #1 |
JASS:scope Rikujyou initializer Init_Rikujyou globals private constant integer RIKUJYOU = 'A04D' private constant string MESSAGE = "Bakudou 61, Rikujyou Kourou!" private xecast cast endglobals private function setRikujyou takes nothing returns nothing //: In this function, set cast = xecast.create() // we do some basic setup set cast.abilityid = 'A048' //The ability Id for our dummy ability set cast.orderid = 852095 //The order id. endfunction function Rikujyou_Conditions takes nothing returns boolean return (GetSpellAbilityId() == RIKUJYOU) endfunction function Rikujyou_Actions takes nothing returns nothing //local xecast xc = xecast.createA() local unit caster = GetTriggerUnit() local timer t call DisplayText(caster, MESSAGE, 1) set cast.owningplayer = GetOwningPlayer(caster) set cast.level = GetUnitAbilityLevel(caster, RIKUJYOU) call cast.castOnTarget(GetSpellTargetUnit()) call BJDebugMsg(GetUnitName(caster)) call BJDebugMsg(GetUnitName(GetSpellTargetUnit())) call BJDebugMsg(I2S(GetUnitAbilityLevel(caster, RIKUJYOU))) call BJDebugMsg("-----") call BJDebugMsg(I2S(cast.level)) call BJDebugMsg(I2S(GetPlayerId(cast.owningplayer))) set caster = null endfunction //=========================================================================== function Init_Rikujyou takes nothing returns nothing local trigger trg_Rikujyou = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(trg_Rikujyou, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(trg_Rikujyou, Condition(function Rikujyou_Conditions)) call TriggerAddAction(trg_Rikujyou, function Rikujyou_Actions ) call setRikujyou() set trg_Rikujyou = null endfunction endscope The line [//local xecast xc = xecast.createA()] is commented because I couldn't find any difference on letting it run or not. What happens, on the first cast, the target is stunned, it displays: MyCasterName (null) 1 ----- 1 0 After that any cast will show: MyCasterName MyTargetName 1 ----- 1 0 And will not work anymore. Thanks in advance for any help! |
| 01-22-2010, 11:38 PM | #2 |
When I had the same problem as you, I moved all the xecast-stuff into the action (from xecast.create to xecast.destroy). This sort of destroys a bit of the beauty of xe, but hell, it worked. (I suppose you have set up the casting unit and the ability right. You know, the routine stuff. Cooldown, mana cost, range, etc) |
| 01-22-2010, 11:42 PM | #3 |
Well, this is the example vex gave of xe.cast: JASS://********************************************** //* Rune of Illusions //* //* A quick sample for xecast //* //* //I003 : rune of illusion //A009 : Illusions (dummy) //---------------------------------------------- scope IllusionRune initializer init private function itemIdMatch takes nothing returns boolean //If the id of the pickup item return ( GetItemTypeId(GetManipulatedItem()) == 'I003' ) //matches I003 ... endfunction // //==================================================== //: This time we'll use a single xecast instance for //: all the cases the rune is used. It is recommended //: to do this since it is more efficient. // globals // :We begin by actually declaring our cast global private xecast cast // variable endglobals // private function setItUp takes nothing returns nothing //: In this function, set cast = xecast.create() // we do some basic setup set cast.abilityid = 'A009' //The ability Id for our dummy illusions ability set cast.orderid = 852274 //The order id. //: The illusions ability is a special case since it does not have an orderstring // so we are just going to use its order id, every active ability has one, // I got the id using a detector trigger, but most people would prefer to use // the order id guide: [url]http://www.wc3campaigns.net/tools/weu/ORDERIDS.xls[/url] // // // endfunction private function onItemPick takes nothing returns nothing local xecast xc = xecast.createA() //CreateA so we don't have to destroy the object after the cast. local unit u = GetTriggerUnit() set cast.owningplayer = GetOwningPlayer(u) //* The owning player, determines who will own the illusion. call cast.castOnTarget( u ) //Let's call the castOnTarget method on the Triggering unit. set u=null endfunction private function init takes nothing returns nothing local trigger t=CreateTrigger() //The usual Trigger registering call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_PICKUP_ITEM) //: Unit pickups item call TriggerAddCondition(t, Condition(function itemIdMatch)) //: call TriggerAddAction(t, function onItemPick) call setItUp() //call our xecast setup function... endfunction endscope And the cast documentation: JASS:xecast ------ This one solves typical problems that require dummy casters. Things like the AOE sleep, targetted warstomp, etc. It is object oriented, this just means that you'll actually not just call functions but deal with xecast objects, change their attributes and then order them to cast. It deals with the dirty things like recycling and dealing with timing, etc. implementation -------------- Just copy the xecast trigger to your map. xecast object ------------- __________________________________________________________________________________________________ static method create takes nothing returns nothing - ------ This is the create method, it will make a new xecast object for you to use: set somevariable = xecast.create() _________________________________________________________________________________________________ static method createBasic takes integer abilityID, integer orderid, player owner returns xecast - - - - - - - - - - - - An abbreviated constructor, allows you to quickly set the basic attributes abilityID: the rawcode of the ability to cast. Example: 'AHbz' orderid : the orderid (integer) of the ability to cast. Example: OrderId("blizzard") owner : the owning player for this cast object (The one that gets credit for damage) Example: ( GetOwningPlayer(GetTriggerUnit() )) _________________________________________________________________________________________________ method destroy takes nothing returns nothing - Call destroy() on instances you are not going to use anymore, to prevent struct leaks that would break your map. A simple use for xecast is to just keep one instance per dummy spell to prevent having to care about destroying them. Another possibility is to use the A constructors. Example: call somevariable.destroy() __________________________________________________________________________________________________ static method createA takes nothing returns nothing static method createBasicA takes integer abilityID, integer orderid, player owner returns xecast - These do the same as create and createBasic , the only difference is that the object is destroyed automatically after every call to a cast method (See bellow). _____________________________________________________________________________________________________ method castOnTarget takes widget target returns nothing - Tells the xecast object to cast its spell on the target. target may be unit, item or destructable. _____________________________________________________________________________________________________ method castOnPoint takes real x, real y returns nothing method castOnLoc takes location loc returns nothing method castInPoint takes real x, real y returns nothing method castInLoc takes location loc returns nothing - ----------------------------------------------- Instead of casting on a target unit/item/destructable these ones cast on a target point. OnPoint is used for point-targeteable spells, while InPoint is used for spells that have no target. The Loc versions allow you to use locations. Locations are useless most of the times, but if you want to use them you can use the Loc versions. Example: call somevar.castOnPoint( spellx, spelly ) _____________________________________________________________________________________________________ method castOnAOE takes real x, real y, real radius returns nothing method castOnAOELoc takes location loc,real radius returns nothing method castOnGroup takes group g returns nothing - --------------------------------------------------- Methods to cast the spell on multiple units, AOE takes a circle's center and radius, while Group takes a unit group, notice that the unit group will get cleaned after calling this function, which means it will be an empty unit group, no, it does not destroy the group automatically, just empties it * List of attributes * ________________________________________________________________________________ integer abilityid ---- This one holds the ability to cast's ability Id. Example: set somevar.abilityid='AHbz' ________________________________________________________________________________ integer level ---- The level of the ability to cast. Example: set somevar.level = GetUnitAbilityLevel(u, spellid) ________________________________________________________________________________ real recycledelay ---- The recycle delay is the time to wait before recycling the dummy caster, if it is 0.0 the ability will be considered instant. A proper recycle delay is important since when a dummy caster is recycled its owner becomes player passive. Every damage done by the casted spell will not credit the correct player. Some other spells need some time in order to cast correctly. Not to mention the channeling ones that require the caster to last during that situation. Example: set somevar.recycledelay=10.0 ________________________________________________________________________________ player owningplayer ---- The player that owns the spell (Who gets credited for it) Example: set somevar.owningplayer = Player(2) ________________________________________________________________________________ integer orderid (write-only) ---- The ability to cast's order id. eg 858029 or OrderId("blizzard") ________________________________________________________________________________ string orderstring (write-only) ---- The ability to cast's order string (eg "blizzard") ________________________________________________________________________________ boolean customsource ---- false by default, determines if you want the dummy caster to be placed at a specific point when casting, this allows you to exploit blizz spell's eye candy. Once customsource is true, you need to set sourcex,sourcey and sourcez. ________________________________________________________________________________ real sourcex, sourcey, sourcez ---- The coordinates where you want to place the dummy caster, z is height and is 0.0 by default. These are ignored if customsource is set to false. ________________________________________________________________________________ method setSourcePoint takes real x, real y, real z returns nothing method setSourceLoc takes location loc, real z returns nothing ---- In case setting all that stuff manually takes too much lines for your taste you can use these methods to set those values, they will automatically set customsource to true. Well, if I was to put the xe.cast things on the trigger, I would just do createunit and make it cast D: |
| 01-22-2010, 11:51 PM | #4 | |
Quote:
Yes, I know. You've done everything right it would seem. I think this is an oddity with xe. I've been scanning the xe-thread. They mention recycledelay. What happens if you add the following to your setup? JASS:set cast.recycledelay = 1 |
| 01-23-2010, 12:24 AM | #5 |
It worked! Thank you! (Don't know why it worked on the first call anyway) Sir, I would call you a genius if you could solve what this line does: [local xecast xc = xecast.createA()] I found it odd, since the dummy that casts it is never destroyed, as seen in the setItUp function. |
| 01-23-2010, 12:54 AM | #6 | ||
Quote:
Well, it appears to be a mistake made by copying the spell samples. I believe Rune of Illusions was copied from Sheep Staff (also from xe sample map), and that Vexorian simply has forgotten to remove createA from Rune of Illusions. I think Sheep Staff shows the real usage of createA: (that is, the struct instance will auto-destroy after calling a cast-function)
|
| 01-23-2010, 01:51 AM | #7 |
Thanks you again, all questions solved! ^^ |
