| 09-27-2009, 06:33 PM | #1 |
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 JASS:
struct hero
unit u
real hp
method SetHp takes real newValue returns nothing
endstruct
struct warrior extends hero
real rage
method SetRage takes real newValue returns nothing
static method create takes unit u returns warrior
local warrior w = warrior.allocate()
set w.u = u
call AttachStruct(u)
return w
endmethod
endstruct
struct mage extends hero
real mana
method SetMana takes real newValue returns nothing
static method create takes unit u returns mage
local mage m = mage.allocate()
set m.u = u
call AttachStruct(u)
return m
endmethod
endstruct
struct priest extends hero
real mana
method SetMana takes real newValue returns nothing
static method create takes unit u returns priest
local priest p = priest.allocate()
set p.u = u
call AttachStruct(u)
return p
endmethod
endstruct
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. JASS:
function Action takes nothing returns nothing
local unit u = GetTriggerUnit()
local warrior/mage wm = GetAttachedStruct(u)
if IsUnitMage(u) then
call wm.SetMana(500)
elseif IsUnitWarrior(u) then
call wm.SetRage(300)
endif
endfunction
JASS:
function Action takes nothing returns nothing
local unit u = GetTriggerUnit()
local hero h = GetAttachedStruct(u)
if IsUnitMage(u) then
call h.SetMana(500)
elseif IsUnitWarrior(u) then
call h.SetRage(300)
endif
endfunction
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" JASS:
function Action takes nothing returns nothing
local unit u = GetTriggerUnit()
local hero h = GetAttachedStruct(u)
local warrior w
local mage m
if IsUnitMage(u) then
set m = h
call w.SetMana(500)
elseif IsUnitWarrior(u) then
set w = h
call w.SetRage(300)
endif
endfunction
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 |
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 |
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 |
@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. 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. JASS:
struct hero
unit u
real hp
method SetHp takes real newValue returns nothing
stub method SetMana takes real newValue returns nothing
endmethod
stub method SetRage takes real newValue returns nothing
endmethod
endstruct
struct warrior extends hero
real rage
method SetRage takes real newValue returns nothing
//Set units rage...
endmethod
static method create takes unit u returns warrior
local warrior w = warrior.allocate()
set w.u = u
call AttachStruct(u)
return w
endmethod
endstruct
struct mage extends hero
real mana
method SetMana takes real newValue returns nothing
//Set units mana...
endmethod
static method create takes unit u returns mage
local mage m = mage.allocate()
set m.u = u
call AttachStruct(u)
return m
endmethod
endstruct
struct priest extends hero
real mana
method SetMana takes real newValue returns nothing
//Set units mana...
endmethod
static method create takes unit u returns priest
local priest p = priest.allocate()
set p.u = u
call AttachStruct(u)
return p
endmethod
endstruct
function Action takes nothing returns nothing
local unit u = GetTriggerUnit()
local hero h = GetAttachedStruct(u)
call wm.SetMana(500)
call wm.SetRage(300)
endfunction
|
| 09-28-2009, 11:10 AM | #5 |
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 |
why not that way... much easier to use stub methods: 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
|
