First attempt at making a struct spell.

chovynz

We are all noobs! in different states of Noobism!
Reaction score
130
I'm converting this into a struct'ed spell. This works as is but could be better.
Heads up from the first post. I'll probably end up doing alot of double posts.

Edit: I'm going to convert the below into structs. I haven't done so yet.
JASS:
//-------Mine Spells Integer Block
constant function ProxRawCode takes nothing returns integer
    return 'A00Z' //Proximity Mine Spell
endfunction
constant function FoFRawCode takes nothing returns integer
    return 'A011' //FoF Mine Spell
endfunction
constant function HomeRawCode takes nothing returns integer
    return 'A012' //Homing Mine Spell
endfunction
constant function StealthRawCode takes nothing returns integer
    return 'A014' //Stealth Mine Spell
endfunction
constant function AcidRawCode takes nothing returns integer
    return 'A015' //Acid Mine Spell
endfunction

function Trig_CreateProximityMineJass2_Conditions takes nothing returns boolean
    if ((GetSpellAbilityId()==ProxRawCode())) then
        set udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] = 1
        return GetSpellAbilityId()==ProxRawCode()
    endif
    if ((GetSpellAbilityId()==FoFRawCode())) then
        set udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] = 2
        return GetSpellAbilityId() == FoFRawCode()
    endif
    if ((GetSpellAbilityId()==HomeRawCode())) then
        set udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] = 3
        return GetSpellAbilityId()==HomeRawCode()
    endif
    if ((GetSpellAbilityId()==StealthRawCode())) then
        set udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] = 4
        return GetSpellAbilityId()==StealthRawCode()
    endif
    if ((GetSpellAbilityId()==AcidRawCode())) then
        set udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))] = 5
        return GetSpellAbilityId()==AcidRawCode()
    endif
    return false
endfunction

//--------Mine Units 
function MineID takes nothing returns integer
    if (udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]) == 1 then
        return 'n003'  //Proximity Mine Spell
    endif
    if (udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]) == 2 then
        return 'n005'  //FoF Mine Spell
    endif
    if (udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]) == 3 then
        return 'n002'  //Homing Mine Spell
    endif
    if (udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]) == 4 then
        return 'n000'  //Stealth Mine Spell
    endif
    if (udg_LastMine[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]) == 5 then
        return 'n004'  //Acid Mine Spell
    endif
return 0
endfunction

//-------Generic Mine stuff
constant function MineFuse takes nothing returns real
    return 6.
endfunction

constant function MineBlastRadius takes nothing returns real
    return 200. //Mine Blast Radius
endfunction

constant function MineDamage takes nothing returns real
    return 300. //Proximity Mine Damage
endfunction

function Trig_CreateProximityMineJass2_Actions takes nothing returns nothing
   local unit Caster = GetTriggerUnit()
   local real CasterX = GetUnitX(Caster)
   local real CasterY = GetUnitY(Caster)
   local real CasterFace = GetUnitFacing(Caster)
   local unit Mine
   local unit Explosion

   set Mine = CreateUnit(GetOwningPlayer(Caster), MineID(), CasterX, CasterY, bj_UNIT_FACING)
   call UnitApplyTimedLife(Mine ,'BTLF', MineFuse())
   call TriggerSleepAction(MineFuse())

   set Explosion = CreateUnit(GetOwningPlayer(Caster),'h00Q',GetUnitX(Mine),GetUnitY(Mine),bj_UNIT_FACING)
   call UnitDamagePoint(Mine, 0, MineBlastRadius(), GetUnitX(Mine), GetUnitY(Mine), MineDamage(), true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
   call UnitApplyTimedLife(Explosion, 'BTLF', 2)
   
   set Caster            = null
   set Mine              = null
   set Explosion         = null
   
endfunction

//===========================================================================
function InitTrig_CreateProximityMineJass2 takes nothing returns nothing
    set gg_trg_CreateProximityMineJass2 = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_CreateProximityMineJass2, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_CreateProximityMineJass2, Condition( function Trig_CreateProximityMineJass2_Conditions ) )
    call TriggerAddAction( gg_trg_CreateProximityMineJass2, function Trig_CreateProximityMineJass2_Actions )
endfunction

I will start by analyzing the spell that I want. The intention is to create a mine that blows up based on the ability clicked. I have 5 different mines. Any player can use it so it needs to be fully MUI and PUI.

All mines have the same actions with some slight differences that can be allowed for with "if/thens" or some other way. The action is as follows:

1. player clicks 1 of 5 mine abilities
2. Mine is created
2a. Mine is activated after a few seconds to allow the triggering unit to move away.
3. Mine will blow up after a certain amount of time - irrespective of type.
3a. Mine can be destroyed and will blow up.
3b. If a hero comes near the mine it will blow up.
4a. Mine Options. Proximity blows up at any hero approach. Homing mine will move slowly towards the nearest hero(including self). Friend or Foe will not blow up at Friendly approach (beware of enemy coming close at this time.) Stealth will be invisible. Acid has extreme damage.
5. Kills need to be counted from Mine kills, but not when a mine destroys another mine. Kills only get counted on heros, so this might not come into the equation.

First Question: Am I being too complicated?
 
i didn't get it where are the structs? (did i miss them in your trigger or something?)
 
I haven't done them yet. This is an open journey. :) I'll be posting them up and asking if im doing it right. The first post is what I'm converting from.

My first thought is that I need to make structs for each type of mine. So...

JASS:
struct prox
    integer delay = 2
    integer fuse = 6     
    integer damage = 300
    real x
    real y

    method rawcode takes nothing returns integer
       return 'A00Z' //Proximity Mine Spell
    endmethod

endstruct


Is this a good start?
 
Why do you want to use structs here in the first place? You don't seem to have the need for attaching anything and there is overall no place where they're really needed.

But anyway...don't use methods that way. They are quite slow compared to standard functions, only use them if you need to do something with the parent struct's members or need something that can be called from anywhere (or both).
Some other things you should consider about the spell the way it is now:
-TriggerSleepAction should always be avoided when it comes to spells, especially with longer waits, if you must then use PolledWait
-you have a lot of calls in some functions such as Trig_CreateProximityMineJass2_Conditions, it's a much better idea to store GetSpellAbilityId and GetTriggerUnit to variables so that you only need to call them once in that function
-another example is MineID where the whole GetPlayerId(GetOwningPlayer(GetTriggerUnit())) can be one variable
-you can use constant globals instead of constant functions for raw codes and similar setup
 
Ok. Answer me this then. Why would I use structs? Maybe this is my problem. What is attachment?
I need to move my homing mine (like a slide but using x,y to target). Is that where I would attach?
 
For instance, you might want to use a struct where you need to move a unit with a periodic timer and
attach its starting coordinates, facing etc. to the timer and retrieve the data in the "move" function.
 
You use structs when you need to put more than one value in one variable (there are other purposes, but this is the most notable).
Say you need to attach three variables using some system. You can just put them all in one struct and then attach the struct itself as an integer - almost three times faster than attaching each of the variables separately.
Yes, using it for sliding is a good idea.
 
Well... when you think about it, ideally all mines should have periodic timer dont you think?

TriggerSleepAction has been causing me some problems. That's why i want to move to structs or something else. I'm going to be having a LOT of movement on my map. I'm going to need things as optimized as possible.

I understood structs would help me do that. Handle Vars feels clunky.
What do you think i should do? I can make 5 different spells for each mine if thats what it takes, but i dont see the point when i can do one or two functions with conditions instead of 10+ functions.
 
if you want something to be accurate, then yes, use a timer, alternative a periodic trigger.
 
Then that is why I need to use structs. All the mines are having two timers (one for action delay and one for death time). At the moment TriggerSleepAction is the only way I know of doing a wait (except for HandleVars which I want to move away from. It is going to be too slow for what I have in mind.)
 
If you are looking for how to use structs to move objects there is a really nice example spell in ABC demo map for that.
 
I know. I saw that. That was cool and very good to see that its possible to do that sort of thing. I didn't understand it enough to be able to use it though. Thats what these last two threads have been about. Heading down that struct path.

Is there a problem in my thinking?

I thinking from create unit --timedelay--> damage area --->destroy unit
Do I need to think a different way with structs / attachment?
 
Actually the best way to make a proximity mine is to register area event trigger for that mine, and then to attach struct to that trigger.
 
. . .

elucidate please.

Is that unit comes in range? And how would I attach to that trigger?

SetTriggerStructA(trigger, struct)?
 
exactly like that.

call TriggerRegisterUnitInRangeSimple( trigger, range, unit )

For range you put 200 for example,
unit is your mine of course.

If it is a tracking mine (spider mine from starcraft) you can order unit to kaboom on unit that enters region.

I would love to make an example of this, but I have to go now.
Maybe tomorrow.

EDIT:
starcraft heh.
Well if noone beats me to it I will submit a starcraft spider mine spell tomorrow.
 
Is this the spell data I need? And is it correct syntax?
JASS:
scope ProximitySpell
    struct Proxdata
       unit caster
       unit target
       integer minetype = 'n003'
       integer ID = 'A00Z'
       real delay = 2.
       real fuse = 6.  
       real blast = 200.
       real damage = 300.
    endstruct
endscope
 
unit types and ability ID's should be constant globals, not struct variables

JASS:



scope ProximitySpell

globals
       constant integer minetype = 'n003'
       constant integer ID = 'A00Z'
endglobals

    struct Proxdata
       unit caster
       unit target
       real delay = 2.
       real fuse = 6.  
       real blast = 200.
       real damage = 300.
    endstruct
endscope
 
Why exactly do you need any of that inside a struct? If you want movement then you just need two reals for X and Y and a unit you're moving. The rest (delay, fuse, blast, damage) can all be constant globals.

> what's a constant global?
Isn't it self-explanatory? It's a global with a constant value, something that never changes. Kind of like using constant functions.
 
Any constant value in your spell should be put inside a constant global. Constant globals are just a cool way to store a constant value (what you would otherwise store in a constant function, probably).
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    News portal has been retired. Main page of site goes to Headline News forum now
  • The Helper The Helper:
    I am working on getting access to the old news portal under a different URL for those that would rather use that for news before we get a different news view.
  • Ghan Ghan:
    Easily done
    +1
  • The Helper The Helper:
    https://www.thehelper.net/pages/news/ is a link to the old news portal - i will integrate it into the interface somewhere when i figure it out
  • Ghan Ghan:
    Need to try something
  • Ghan Ghan:
    Hopefully this won't cause problems.
  • Ghan Ghan:
    Hmm
  • Ghan Ghan:
    I have converted the Headline News forum to an Article type forum. It will now show the top 20 threads with more detail of each thread.
  • Ghan Ghan:
    See how we like that.
  • The Helper The Helper:
    I do not see a way to go past the 1st page of posts on the forum though
  • The Helper The Helper:
    It is OK though for the main page to open up on the forum in the view it was before. As long as the portal has its own URL so it can be viewed that way I do want to try it as a regular forum view for a while
  • Ghan Ghan:
    Yeah I'm not sure what the deal is with the pagination.
  • Ghan Ghan:
    It SHOULD be there so I think it might just be an artifact of having an older style.
  • Ghan Ghan:
    I switched it to a "Standard" article forum. This will show the thread list like normal, but the threads themselves will have the first post set up above the rest of the "comments"
  • The Helper The Helper:
    I don't really get that article forum but I think it is because I have never really seen it used on a multi post thread
  • Ghan Ghan:
    RpNation makes more use of it right now as an example: https://www.rpnation.com/news/
  • The Helper The Helper:
  • The Helper The Helper:
    What do you think Tom?
  • tom_mai78101 tom_mai78101:
    I will have to get used to this.
  • tom_mai78101 tom_mai78101:
    The latest news feed looks good
  • The Helper The Helper:
    I would like to see it again like Ghan had it the first time with pagination though - without the pagination that view will not work but with pagination it just might...
  • The Helper The Helper:
    This drink recipe I have had more than a few times back in the day! Mind Eraser https://www.thehelper.net/threads/cocktail-mind-eraser.194720/

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top