ID:149969
 
ok.. after spending several hours pondering how to do using daedron's char. handling, i can get it to ask race and class but i cannot get the race to show up on the stat panel, but the class will show up like i want it to.. here is what i got:

race = input(src,"What would you like your race to be?","Human") in list("Human","Elf")
switch(race)
if ("Human") race =new /mob/pc/race/Human()
if ("Elf") race = "Elf"

class = input(src,"What would you like your class to be?","Fighter") in list("Barbarian", "Fighter")
switch(class)
if ("Barbarian") new_mob = new /mob/pc/Barbarian()
if ("Fighter") new_mob = new /mob/pc/Fighter()
new_mob.name = char_name

// Now switch the player client over to the new mob and delete myself since I'm no longer needed.
src.client.mob = new_mob
var/turf/first_location = locate(1, 1, 1)
new_mob.Move(first_location)
del(src)
mob/pc/Barbarian
class = "Barbarian"
mob/pc/Fighter
class = "Fighter"
mob/pc/race/Human
race = "Human"
mob/pc/race/Elf
race = "Elf"



now what im assuming is the src from the class is overwriting the race, if that is the case, how would i fix it to where the race would not be overwritten (has a feelin it has somethin to do w/ .txt files) i apologize if it is somethin stupid i ended up missing and lord of water's Demo to it the link was broken which i dun think would have helped me with my question anyhow :D

o yes.. and by chance if your wonderin.. here is code for statpanel heh

 if (statpanel("Stats"))
stat("Race: ",usr:race)
stat("Class: ",usr:class)
Darien41 wrote:
ok.. after spending several hours pondering how to do using daedron's char. handling, i can get it to ask race and class but i cannot get the race to show up on the stat panel, but the class will show up like i want it to.. here is what i got:

race = input(src,"What would you like your race to be?","Human") in list("Human","Elf")
> switch(race)
> if ("Human") race =new /mob/pc/race/Human()

(forgot to mention here i wasnt sure which one to pick)

> if ("Elf") race = "Elf"
>
> class = input(src,"What would you like your class to be?","Fighter") in list("Barbarian", "Fighter")
> switch(class)
> if ("Barbarian") new_mob = new /mob/pc/Barbarian()
> if ("Fighter") new_mob = new /mob/pc/Fighter()
> new_mob.name = char_name
>
> // Now switch the player client over to the new mob and delete myself since I'm no longer needed.
> src.client.mob = new_mob
> var/turf/first_location = locate(1, 1, 1)
> new_mob.Move(first_location)
> del(src)
> mob/pc/Barbarian
> class = "Barbarian"
> mob/pc/Fighter
> class = "Fighter"
> mob/pc/race/Human
> race = "Human"
> mob/pc/race/Elf
> race = "Elf"

now what im assuming is the src from the class is overwriting the race, if that is the case, how would i fix it to where the race would not be overwritten (has a feelin it has somethin to do w/ .txt files) i apologize if it is somethin stupid i ended up missing and lord of water's Demo to it the link was broken which i dun think would have helped me with my question anyhow :D

o yes.. and by chance if your wonderin.. here is code for statpanel heh

 if (statpanel("Stats"))
> stat("Race: ",usr:race)
> stat("Class: ",usr:class)
Take a look at this:

race = input(src,"What would you like your race to be?","Human") in list("Human","Elf")
switch(race)
if ("Human") race =new /mob/pc/race/Human()
if ("Elf") race = "Elf"


class = input(src,"What would you like your class to be?","Fighter") in list("Barbarian", "Fighter")
switch(class)
if ("Barbarian") new_mob = new /mob/pc/Barbarian()
if ("Fighter") new_mob = new /mob/pc/Fighter()



If the player chooses Human, the variable of race for the current mob is set to equal a newly created human mob. If they choose Elf, the variable race belonging to the current mob is set to equal the word "Elf". Why a mob in one case and a word in the other?

Then, you ask the player to choose a class. Based on the class, you create a new mob of the appropriate type, then switch the player's control to that mob. Note that this is a new mob. You even named it "new_mob", and created it with the command "new." Hence, it is, in fact, a new mob. It has absolutely nothing to do with any previous mobs, such as the mob whose race variable you have set or the mob that race variable might've been set equal to.

There is no easy or good way to set a character's beginning stats and abilities by having them choose a series of mobs... in the end, unless you're making some kind of complicated army/conquest game, they're only going to be controlling one of them. You're probably better off having race as a text variable, as in race = "Human" or race = "Elf", and checking that variable whenever you need to apply a racial modifier, like

if (race == "Elf")
src.ear_height += 3

Since you prefer to ask race before class, just add this line in after the player has chosen their class:

new_mob.race = src.race

since it is src.race that you've set.
I won't help you because of that bump you made, but here's a little tip to go along with Lexy's wisdom, using the : operator can have some bad effects error-wise, stick with the . operator and you'll be much better off.
In response to Darien41
ok thanks Lexy that will be the answer i seek :D Nadrew, 1st off, i made that as u put it "bump" right AFTER i sent my 1st message, notice the time sent on em.. and also, it wouldnt let me use the . operator, had to use the : operator, if im not mistaken the . operator goes for the code applied under that i guess tree is the word im looking for and : is a global operator, course i might be wrong (wont be first time) :)
In response to Lesbian Assassin
I bow to thee oh wise one ^_^
In response to Darien41
I have found in 50% of my code, I MUST use the : operator instead of the . because my player is of mob type mob/player, and src assumes a generic, non-special mob, so if you say:
mob
var/HP
var/MHP

mob
player
var/MP
var/MP


and you have a proc such as DeathCheck(mob/Attacker, mob/Defender) listed under the default mob, you'll be stuck using : instead of . (You can't stepcify either mob as /player/ because it also checks if NPCs attack, which would bug if I did specify a mob type)
In response to Dreq
Dreq wrote:
I have found in 50% of my code, I MUST use the : operator instead of the . because my player is of mob type mob/player, and src assumes a generic, non-special mob, so if you say:
mob
> var/HP
> var/MHP
>
> mob
> player
> var/MP
> var/MP

and you have a proc such as DeathCheck(mob/Attacker, mob/Defender) listed under the default mob, you'll be stuck using : instead of . (You can't stepcify either mob as /player/ because it also checks if NPCs attack, which would bug if I did specify a mob type)

The reason we say that it's bad to use the : operator is because a) you should never use it unless you have to, and b) you should never have to use it. If you find yourself forced to use it, it represents a weakness in your code that could lead to ugly run-time errors. The . operator tells the compiler "Check for me, and make sure that this function will never, ever be called, unless all the parameters involved are valid." The : operator says, "Don't bother." If the compiler won't let you proceed with the . operator, that's telling you that the code could be called in an invalid circumstance.

If HP and MP are defined under mob rather than mob/player (and if both npcs and pcs have HP and MP, it should be defined under mob rather than mob/player and mob/npc, unless there's some third branch of mobs that don't have HP and MP), then you'll be fine using the . operator... practically speaking, you should never have a situation where you need to define a proc under a broad class if that proc access variables and procs that aren't present in all members of that class.

In your example, you define HP under mob and then you redefine it under mob/player... this is unnecessary. Anything defined under mob belongs to mob and all subclasses of mob.
In response to Lesbian Assassin
That was a very generic example, although a bad one ^_^. I find myself doing it when dealing with my stats modifier variables, which are ONLY used in player mobs (it's a waist of memory to have them in NPCs since they don't use them), so I do find places where : is needed.
In response to Dreq
Dreq wrote:
so I do find places where : is needed.

As Lexy said, it's never needed. There are plenty of places where it's an easy shortcut, but that will get you into trouble later when the compiler doesn't catch existing errors for you. Consider a situation where mobs have a strength stat. NPCs have only strength, while live players have strength plus fortitude. Let's say I want to put something in the Bump() proc that checks the relative strengths of mobs that bump each other and do something as a result. Here's my first attempt at such a code:
mob
var
strength = 100

player
var
fortitude = 100

Bump(B)
if ((src.strength + src:fortitude) > (B:strength + B:fortitude))
// do something, run him over, whatever

This ought to compile just fine, but you'll get all kinds of runtime errors. In fact, the only time it will work is if a player bumps another player. If a player bumps something that isn't a mob (a wall, for example), then both B:strength and B:fortitude will be undefined. If the player bumps an NPC, then B:fortitude will be undefined. If an NPC bumps anything, src:fortitude will be undefined. Yikes, bad situation! And the compiler didn't check any of that for me.

This is much better:
mob
var
strength = 100

player
var
fortitude = 100

Bump(B)
var/mystrength = src.strength
var/bstrength = 0
if (istype(src, /mob/player))
var/mob/player/myself = src
mystrength += myself.fortitude
if (istype(B, /mob))
var/mob/bmob = B
bstrength = bmob.strength
if (istype(B, /mob/player))
var/mob/player/pmob = B
bstrength += pmob.fortitude
if (mystrength > bstrength)
// do something, run him over, whatever

So this is a little more work, but it makes the compiler do the work of type checking for me. Of course, the whole thing would be better done using a GetStrength() proc for atoms and overriding that for /mob and /mob/player, but that's another topic altogether.
In response to Dreq
If you define the variable but don't use it, the memory waste is negligible. More to the point, it makes the code more flexible. Say that in the future, you make stat modifiers affect NPCs as well as PCs (so you can beef up charm monsters, or enslaved zombies, or whatever, to use a few common fantasy examples).

Or say you want to make a mind control ability that allows you to take direct control of an NPC, making the NPC your mob for the duration. All of a sudden, all of those obj.verbs you wrote with usr:insert_stat_modifier here are going to be generating runtime errors! If you A) defined stat_modifier for NPC or B) laid out your proc in such a way that : is not necessary, this wouldn't be a problem. Air Mapster gave a couple of good examples of how to avoid :ing, here's another.

obj/var/weight
mob/var/strength
mob/pc/var/lifting_skill
obj/verb/get()
set src in view(0)
if (!istype(usr,/mob/player)) return //We don't want no stinking NPCS!
var/mob/player/p = usr
if (p.strength + p.lifting_skill > weight && src.Move(usr))
oview() << "[p] gets [src]!"
p << "You get [src]!"

usr is just mob, p is specifically mob/player.

Now, if you're absolutely sure that a) players will never, ever, even briefly have control of NPCs, b) that you'll never write such a thing as an NPC scripting code or have NPCs whose AI proc will cause them to execute verbs on objects around them, and, most importantly, c) you can accurately predict each and every future circumstance that will occur in your game... then yeah, go ahead and use :. But it's still sloppy programming.
In response to Air Mapster
Thank u o omnipotent one Lexy :D learn somethin new everyday, slowly startin to understand codin more (very slowly) heh
In response to Air Mapster
>   Bump(B)
> var/mystrength = src.strength
> var/bstrength = 0
> if (istype(src, /mob/player))
> var/mob/player/myself = src
> mystrength += myself.fortitude
>


I think on the "mystrength += myself.fortitude" line it would have been better to use a colon atleast in earlier versions since the colon first checks to see if that variable even exsists for that object. The period on the other hand just trys to get memory at the suspected location w/o any checks that happin at runtime so if you made an error an you actually didn't have the right object it would crash the dream seeker. I found this out when I was working on CTF1 a long time ago while on my anti-colon crusade :). I haven't tried recently so I don't know if new checks where added in.

[Edit]
Well I just did a quick test and both the colon and cast method produce the same error if the variable is not there. So the colon could be used for convenience and the period could be used if you want to be explicit. But whatever makes your code most readable should always be the selection you make.
In response to Theodis
Theodis wrote:
Well I just did a quick test and both the colon and cast method produce the same error if the variable is not there. So the colon could be used for convenience and the period could be used if you want to be explicit. But whatever makes your code most readable should always be the selection you make.

Hmm, I'm not sure what problems you may have had long ago in much earlier versions of BYOND, but now there should be no disadvantage to using the period operator. The whole point of this was that colon operations are not checked at compile time while period operations are. Thus by using the period, you save yourself potential runtime errors because the compiler will always flag them before you even get to runtime. If the variable isn't there, with a colon it won't be apparent until runtime when the proc crashes (and possibly screws up the state of the game), whereas with the period, it's apparent (and must be fixed) at compile time.

The colon is there for convenience, but using it except in extreme situations can be a very bad habit. ;-)
In response to Theodis
At compile time, the colon checks if the variable could exist for the object, not if it necessarily would. The period makes sure that it does.

Two examples:

mob
player/var/hp

proc/hurt(amount)
src:hp -= amount

The period won't work in this first example... any mob.hurt can be called, and the compiler knows that not all mobs have hp. The compiler errors are secondary to run time errors, though... if you write your code this way, because of the carelessness here, you're going to have to be extra careful every where else... make sure non-combatant mobs don't blunder into energy fields, make damage effects screen by mob type, and so on. In the end, you have more work to do than if you simply defined hp for all mobs and overwrote the hurt() proc for unhurtable ones.

mob
var/hp
proc/hurt(amount)
src.hp -= amount


In this example, all mobs have a hp variable, so the compiler allows you to use the period operator.