HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

struct extends struct

09-27-2009, 06:33 PM#1
Thunder_Eye
I've got a problem regarding structs which I'll try to explain here. I couldn't find a solution in the manual when scimming through it.
Naturally I'd like to make a parent struct called "hero", and then let the child structs "warrior", "mage", and "priest" derive from it.

So let's start like this

Expand JASS:

Now let's say I've created a warrior and a mage and I'd like to change the mages mana, and the warriors rage when they use an ability called "Restore", this is an ability that both the warrior and the mage possesses.

My problem is I'm unsure how to create a local of the structs since I'm unsure of who triggers the event.

Expand JASS:
What I'd prefer.
Expand JASS:

I found some things about .getType() and .getTypeId() on the forum, however those won't help me at the declaration stage.

I hope you understand what I'm asking

EDIT:
I read through the Typecast section again and found a possible "solution"
Expand JASS:
However, I don't like this one for lots of reasons, and I hope someone knows any better solution.

EDIT2:
Continued reading and found a lot better solution which gives about the same I was hoping to use from the start. So at the moment I'm just wondering if there is an even better way to do this, or if I should use this:
call warrior(h).SetRage(300)
09-28-2009, 01:55 AM#2
Fledermaus
Collapse JASS:
    function Action takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer h = GetAttachedStruct(u)
        
        if IsUnitMage(u) then
            call mage(h).SetMana(500)
        elseif IsUnitWarrior(u) then
            call warrior(h).SetRage(300)
        endif
    endfunction
09-28-2009, 04:44 AM#3
fX_
Collapse JASS:
    struct Hero

        public static method operator [] takes unit u returns Hero
            return GetHeroInstanceOfUnit(u)
        endmethod

        readonly unit u

        public static method create takes unit u returns Hero
            local Hero new = Hero.allocate()

            set new.u = u

            call SetHeroInstanceOfUnit(u, new)

            return new
        endmethod

        private method onDestroy takes nothing returns nothing
            call FlushHeroInstanceOfUnit(.u)

            set .u = null
        endmethod

        public stub method restore takes nothing returns nothing
        endmethod

    endstruct

    struct Mage extends Hero

        public static method create takes unit u returns Warrior
            return Hero.allocate(u)
        endmethod

        public method restore takes nothing returns nothing
            call RestoreUnitMana(.u, MANA_RESTORED)
        endmethod

    endstruct

    struct Warrior extends Hero

        readonly real rage = INITIAL_RAGE

        public static method create takes unit u returns Warrior
            return Hero.allocate(u)
        endmethod

        public method restore takes nothing returns nothing
            call RestoreUnitRage(.u, RAGE_RESTORED)
        endmethod

    endstruct

    //------------------------------------------------------------------------------------------------------------------------//

    private function Condition takes nothing returns boolean
        return IsUnitHero(GetTriggerUnit())
    endfunction

    private function Action takes nothing returns nothing
        call Hero[GetTriggerUnit()].restore()
    endfunction


you can treat all your hero types as heroes and say "i want to restore the 'primary attribute' of this hero".

edit: fixed something
also maybe you can use AutoData module (part of AutoIndex library) for 'instantiation' or w/e the word is.
09-28-2009, 10:13 AM#4
Thunder_Eye
@Fledermaus
I'll assume you didn't read the last part of the post where I mentioned that, thanks for the suggestion anyway.

@fX_
I see, interesting.
What would happen if say the warrior struct didn't have an restore function? I'd get an error from JassHelper?

The most optimal thing for me would be something like this, where I don't have to worry about the struct type.

Collapse JASS:
function Action takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local hero h = GetAttachedStruct(u)

        call h.SetMana(500)
    endfunction

Where lets say GetAttachedStruct() checks what unittype u is and returns the appropriate structtype. And in the case it'd be a warrior it'd just run a empty stub method in the warrior struct called SetMana.

Would this be possible? And if so what is prefered cpu-wise?
fX_'s solution -vs- IsUnitType()+structtype(h).SetMana() -vs- GetAttachedStruct()+h.SetMana()

EDIT:
I got the GetAttachedStruct()+h.SetMana() part working, here's the example.

Expand JASS:
Note that here I could merge the functions SetMana() and SetRage() to a single method called SetPower() or similiar.
09-28-2009, 11:10 AM#5
fX_
the method i presented lets you treat the thing as the generic type, calling for some generic action (restoration, here) on the unit as a generic type, which will end up with a peculiar action on the unit according to the nature of the particular type of the unit.

with this method you dotn need to care what particular type the unti is - whether it is a mage or a warrior etc. all you consider is that it is a hero and you restore its 'main property', the type of property-to-be-restored and the manner in which this is done depending on what type of hero it is.
in the order of that function Action, you dont seem to care what class the hero is; only that the hero gets its 'primary property' restored.

there is a note on 'stubs' in the vjass manual (www.wc3c.net/vexorian/jasshelpermanual.html).
you dont need to make correspondent methods of stubs. if the former dont exist then the stub method will be called.
09-28-2009, 04:00 PM#6
xD.Schurke
why not that way... much easier to use stub methods:

Collapse JASS:
    struct hero
        unit u
        real hp
        
        method SetHp takes real newValue returns nothing

        stub method setValue takes real newValue returns nothing
    endstruct
    
    struct warrior extends hero
        real rage
        method setValue takes real newValue returns nothing
               set this.rage = newValue
        endmethod
     endstruct
     //same for mage