change extended type

BlitzMax Forums/BlitzMax Programming/change extended type

slenkar(Posted 2007) [#1]
If I setup a main character type

type character

end type


Then extend it with warrior and wizard
type warrior extends character
end type
type wizard extends character
end type


what if a wizard wants to change classes into a warrior?
also is there a way of printing the name of the type?

like for example printing the name "Warrior" or "Wizard" from the type name. (Without putting in a field called 'character type' into the type)


grable(Posted 2007) [#2]
You cant.

In a case like this, youd be better off making a single "player" type, and having sub "roles" instead.

Its almost the same as a "character type" as you call it, but at least you can extend the "roles" all you want.

edit: about the name part, you could use an abstract method returning a string, or even Reflection.


slenkar(Posted 2007) [#3]
thanks for the quick reply

you mean with no extending of types? just normal usage like you would use in blitz basic?


EDIT= hmm another idea

What If I created a character type

and then created extra types that contain the "AI"

like this

type character

end type


type warrior
method attack
end method
end type

type wizard
method attack
end method
end type


How could I get a 'character' to use the method attack depending on what kind of character he was?


grable(Posted 2007) [#4]
I was thinking something like this:
Type TPlayer
  Field Class:TClass

  Method Attack()
     Class.Attack()
  EndMethod
EndType

Type TClass
    Method Attack() Abstract
EndType

Type TWizard Extends TClass
  Method Attack()
  EndMethod
EndType


If you keep all player critical stuff out of the Class types, you could swap them at will.

edit: Yep, seems like you had it all figured out already =)


slenkar(Posted 2007) [#5]
thanks for your help

where would the TWarrior fit into the above example?
like this?
type TWarrior extends TClass
 method attack()
end method
end type


so how would you actually create a warrior and a wizard?
(using the NEW command)


I tried doing this but it said 'attack' is not recognized

Graphics 640,480


charlist:TList=CreateList()


w:wizard=New wizard
i:warrior=New warrior

c:char=New char
c.class=w:wizard
c.name="Harry"
ListAddLast charlist,c
c:char=New char
c.class=i:warrior
c.name="Fred"
ListAddLast charlist,c


While Not KeyHit(key_escape)

For c:char=EachIn charlist
attack
Next
End
Flip
Cls
Wend
End

Type Char
Field name$
  Field Class:TClass

  Method attack()
     Class.attack()
  EndMethod
EndType

Type TClass
    Method attack() Abstract
EndType

Type warrior Extends TClass
  Method attack()
Print "swing sword"
  EndMethod
EndType

Type wizard Extends TClass
Method attack()
Print "cast spell"
End Method
End Type


EDIT-duh I forgot to put c. before 'attack'


Czar Flavius(Posted 2007) [#6]
If you will be swapping roles often perhaps consider each player simply has a list (not in the tlist meaning) of legal abilities and actions, and some fields containing their class name/appearance etc.

Then not only can you change easily you can also customize abilities. If you want there to be "concrete" class types and not allow the player customization (too much customization can be a bad thing!) then simply be very strict about what abilities can be used with which and the player will never know there aren't distinct class types running under the hood.

In my opinion you should extend types when they have very different natures and behaviours. Wizard and warrior might sound different but they are both player types with the ability to walk etc. As an example of what I mean, extending an enemy type into goblin, mage etc wouldn't be a good idea in my opinion. Extending into walkingmonster, flyingmonster etc would.


slenkar(Posted 2007) [#7]
true, I am very new to OO programming having only used B3D so far.
So all advice is welcome


FlameDuck(Posted 2007) [#8]
Or you could just have a "toWarrior()" method on your Wizard class (and vice versa) which returns a new warrior object and do something like this (myCharacter is of type character, currently representing a wizard instance):
myCharacter = myCharacter.toWarrior()
Now myCharacter is of type character, but it represents a warrior instead.

Whether this is feasible (or even desirable) depends entirely on how your data is modeled - but in the absence of duck typing / dynamic typing, there isn't really much you can do about it.


slenkar(Posted 2007) [#9]
hmm not sure how that works


Czar Flavius(Posted 2007) [#10]
Type TDOB 'date of birth
  Field day:Int, month:Int, year:Int
  Method toAge:TAge()
    Local age:TAge = New TAge
    'code here to convert dob into an age in years
    Return age
  End Method
End Type

Type TAge 'age in years
  Field years:Float 'the years will need to be stored as decimal to get an accurate dob
  Method toDOB:TDOB()
    Local dob:TDOB = New TDOB
    'code here to convert years into dob
    Return dob
  End Method
End Type

Local age:TAge = New TAge
age.years = 20
Local dob:TDOB = age.toDOB()


Not tested but should show the point, even if it's a trivial example. (Notice a New is not required for the last line).


Leon Drake(Posted 2007) [#11]
i hate classes in rpg style game. GURPS says everything


Czar Flavius(Posted 2007) [#12]
Hm I'm not against the idea of classes as such, but with the same old ones, they do get a bit cliché :)


slenkar(Posted 2007) [#13]
Czar,
the last line:

Local dob:TDOB = age.toDOB()

dob is a local 'type pointer' but toDOB() function returns a number doesnt it?

so it will return an integer which will be incompatible and cause it to not compile?


Grey Alien(Posted 2007) [#14]
I agree with Czar Flavius. That's how I'd do it.


Czar Flavius(Posted 2007) [#15]
Look at the method declaration. The toDOB function is of type TDOB, so the function returns a TDOB object.

I forgot some () which I will now put in.
Method toDOB:TDOB()


If it returned and integer it would be
Method toDOB:Int()



But in terms of your game I don't think this kind of type conversion would be the best idea.