| 03-14-2007, 06:23 PM | #1 |
Well, I'm kind of new to this website, so lets start by saying hi. Secondly, I'm also pretty new to using JASS (I've used GUI for quite a while though), and I ran into a problem today. I'm trying to make a pretty simple spell, where you basicly just target a unit, and a dummy unit will cast a shockwave-like spell infront of the target unit, and in addition the targeted unit will just die instantly. So I just made this script with JassCraft: JASS:function Trig_Blind_MageClaw_of_Vengeance_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A072' endfunction function Vengeance takes unit u, unit Cast, player p returns nothing local real face = GetUnitFacing(u) local location dumTar = PolarProjectionBJ(GetUnitLoc(u), 200.0, face) local location dumLoc = PolarProjectionBJ(GetUnitLoc(u), -100.0, face) call CreateUnitAtLoc(p, 'h002', dumLoc, face)//h002 is the ID of my dummy caster. call Message(GetUnitName(GetLastCreatedUnit())+" is the name of the last created unit.", p) //Is in my main map script, because I use it more often to check stuff. call UnitAddAbility(GetLastCreatedUnit(), 'A001')//A001 is the ID of my shockwave like ability. call SetUnitAbilityLevel(GetLastCreatedUnit(), 'A001', GetUnitAbilityLevelSwapped('A072', Cast)) call IssuePointOrderLoc(GetLastCreatedUnit(), "shockwave", dumTar) call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 2.00) call UnitDamageTargetBJ(Cast, u, 99999.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL) call RemoveLocation(dumTar) call RemoveLocation(dumLoc) endfunction function Trig_Blind_MageClaw_of_Vengeance_Actions takes nothing returns nothing local unit Targ = GetSpellTargetUnit() local unit Cast = GetSpellAbilityUnit() local player ownCast = GetOwningPlayer(Cast) call Vengeance(Targ, Cast, ownCast) endfunction //=========================================================================== function InitTrig_Blind_MageClaw_of_Vengeance takes nothing returns nothing set gg_trg_Blind_MageClaw_of_Vengeance = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Blind_MageClaw_of_Vengeance, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Blind_MageClaw_of_Vengeance, Condition( function Trig_Blind_MageClaw_of_Vengeance_Conditions ) ) call TriggerAddAction( gg_trg_Blind_MageClaw_of_Vengeance, function Trig_Blind_MageClaw_of_Vengeance_Actions ) endfunction The only error JassCraft gives is that "gg_trg_Blind_MageClaw_of_Vengeance" is an undeclared variable. So my own assumption is that the problem is with GetLastCreatedUnit(), because the dummy unit does get created, but doesn't get an expiration timer, doesn't get the spell, and doesn't cast the spell. And the message I used to check what the name of the last created unit was, it just said " is the name of the last created unit.". So yeah.. I have no idea whats wrong with it, and I refuse to use GUI because that won't make me learn JASS, so please someone help me. PS. Yes I know I could do it in 1 function too, but this just makes it look a lot easier to me, which is why I make it in 2 =\. |
| 03-14-2007, 06:37 PM | #2 |
I've checked you trigger, and I think there won't be any syntax issues when you pass the code to WE. gg_trg_Blind_MageClaw_of_Vengeance is the name of the global variable created internally by the World editor to make reference to this trigger in particular. If you plan to call this trigger in GUI using actions like: You will need this global variable and you can't change the InitTrig_Blind_MageClaw_of_Vengeance. If you only need the function to be activated by the event, you can modify the InitTrig_Blind_MageClaw_of_Vengeance function in this way: JASS:function InitTrig_Blind_MageClaw_of_Vengeance takes nothing returns nothing local trigger t = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( t, Condition( function Trig_Blind_MageClaw_of_Vengeance_Conditions ) ) call TriggerAddAction( t, function Trig_Blind_MageClaw_of_Vengeance_Actions ) set t = null endfunction With this change, JASSCRAFT only will show the message error. |
| 03-14-2007, 06:49 PM | #3 |
Well, that actually only gets rid of the error message in JassCraft =p, in game it still doesn't add a timer to my dummy, nor add the spell, and it doesn't make it cast either :S . |
| 03-14-2007, 07:02 PM | #4 |
Got it!!! CreateUnitAtLoc doesn't set the lastcreatedunit() function. I did some changes in your spell. Test them and tell me if they work (I'm at the office right now :P). JASS:constant function Trig_Blind_MageClaw_of_Vengeance_SpellID takes nothing returns integer return 'A072' endfunction function Trig_Blind_MageClaw_of_Vengeance_Conditions takes nothing returns boolean return GetSpellAbilityId() == Trig_Blind_MageClaw_of_Vengeance_SpellID() endfunction function Vengeance takes unit u, unit Cast, player p returns nothing local real face = GetUnitFacing(u) local location dumTar = PolarProjectionBJ(GetUnitLoc(u), 200.0, face) local location dumLoc = PolarProjectionBJ(GetUnitLoc(u), -100.0, face) local unit d = CreateUnitAtLoc(p, 'h002', dumLoc, face)//h002 is the ID of my dummy caster. call Message(GetUnitName(d)+" is the name of the last created unit.", p) //Is in my main map script, because I use it more often to check stuff. call UnitAddAbility(d, 'A001')//A001 is the ID of my shockwave like ability. call SetUnitAbilityLevel(d, 'A001', GetUnitAbilityLevel(Trig_Blind_MageClaw_of_Vengeance_SpellID, Cast)) call IssuePointOrderLoc(d, "shockwave", dumTar) call UnitApplyTimedLife(d, 'BTLF', 2.00) call UnitDamageTargetBJ(Cast, u, 99999.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL) call RemoveLocation(dumTar) call RemoveLocation(dumLoc) set dumTar = null set dumLoc = null set d = null endfunction function Trig_Blind_MageClaw_of_Vengeance_Actions takes nothing returns nothing local unit Targ = GetSpellTargetUnit() local unit Cast = GetSpellAbilityUnit() local player ownCast = GetOwningPlayer(Cast) call Vengeance(Targ, Cast, ownCast) endfunction //=========================================================================== function InitTrig_Blind_MageClaw_of_Vengeance takes nothing returns nothing set gg_trg_Blind_MageClaw_of_Vengeance = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Blind_MageClaw_of_Vengeance, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Blind_MageClaw_of_Vengeance, Condition( function Trig_Blind_MageClaw_of_Vengeance_Conditions ) ) call TriggerAddAction( gg_trg_Blind_MageClaw_of_Vengeance, function Trig_Blind_MageClaw_of_Vengeance_Actions ) endfunction |
| 03-14-2007, 08:28 PM | #5 |
Ah thanks! I didn't knew you could create a unit and set it to a local immediatly ^^. Just 1 flaw, this should be the other way around =p: JASS:GetUnitAbilityLevel(Trig_Blind_MageClaw_of_Vengeance_SpellID, Cast)) //=========================================================================== native GetUnitAbilityLevel takes unit whichUnit, integer abilcode returns integer Oh, and I'm still pretty much of a newbie, so I'm wondering what the use of this is: JASS:constant function Trig_Blind_MageClaw_of_Vengeance_SpellID takes nothing returns integer return 'A072' endfunction function Trig_Blind_MageClaw_of_Vengeance_Conditions takes nothing returns boolean return GetSpellAbilityId() == Trig_Blind_MageClaw_of_Vengeance_SpellID() endfunction Was there something wrong with the one I used previously? (see code below) JASS:function Trig_Blind_MageClaw_of_Vengeance_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A072' endfunction |
| 03-14-2007, 10:24 PM | #6 |
The way Moyack has set it up allows for easy spell implementation. Take, for instanc, Spell X, in which you need to reference the Id of the spell being cast 3 times. Someone who needed to edit the spell (to change the ability codes correctly) would now have to look through the whole spell and find every refernce of 'A072' without knowing how many there were. There is a very large possibility that the would screw something up, cause an error, or miss a reference, which would cause problems. By adding functions such as the one Moyack has made as "configuration" sections of your spells and replacing the appropriate areas with YourFunction(), someone planning on implementing it (or you yourself) can be confident they've done it correctly. Constant functions are useful for other things besides just spell Ids. Want a configurable radius for your spell? Do something like this: JASS:constant function Your_Spell_Radius takes nothing returns real return 547.75 endfunction function Your_Spell takes nothing returns nothing local group G = CreateGroup local real X = GetUnitX(GetTriggerUnit()) local real Y = GetUnitY(GetTriggerUnit()) //... call GroupEnumUnitsInRange(G, X, Y, Your_Spell_Radius(), null) //... endfunction |
| 03-14-2007, 10:32 PM | #7 |
Oh ok, thanks a lot, I'll add such a configuration section next time I create a spell ^^. |
| 03-14-2007, 11:53 PM | #8 |
Yes because it returns the created unit: JASS:native CreateUnitAtLoc takes player id, integer unitid, location whichLocation, real face returns unit As a suggestion, try to avoid locations, you can use these functions instead: JASS:local unit u local real ux local real uy //**************************************************************** set u = CreateUnit( playerVar, unit_ID, real_X, real_Y, real_Face) // creates a unit set ux = GetUnitX(YourUnit) // gets the X coordinate of the unit location set uy = GetUnitY(YourUnit) // gets the Y coordinate of the unit location call IssuePointOrder(YourUnit, "Your Order", TargetX, TargetY) // Makes the unit to apply the order to the X, Y coordinates |
| 03-15-2007, 01:01 AM | #9 |
I would like it to be noted that functions that move units to locations instead of X, Y coordinates force the unit to go to somewhere where it can fit and is pathable. |
| 03-15-2007, 04:32 PM | #10 |
Yep, setting a units location will take pathing into mind, if you try to move a unit onto another unit it will get moved out of collision range. If you want to aviod this, you can set a units coordinate, using SetUnitX(SomeUnit,X) and SetUnitY(SomeUnit,Y). Setting a units position also stops casting and resets animation, using the SetUnitX/Y natives does not. Sometimes its useful to set position, sometimes its not. |
| 03-15-2007, 04:39 PM | #11 |
Aren't SetUnit_() also significantly faster then the location based movement functions? |
| 03-15-2007, 04:57 PM | #12 | |
Quote:
No. There are two functions that ignore pathing etc (and are thus faster), which are SetUnitX/Y. You can still use X/Y coords with SetUnitPosition and it will move to a pathable position etc. |
