ID:141212
 
In my Pokemon game, you become the Pokemon when you send it out. But.. When your Pokemon goes off screen and dies, there is no way to return it without making return a world() verb, which could easily screw things up and would be very confusing. How can I make a "Switch" verb so that I can switch back and forth through Pokemon and Trainer.

Here are my Send Out and Return which I would guess switch would be a similar process... So you can use these to help with your example if you plan to give me one.

        SendOut(var/mob/M as mob in contents2)
set name="Send Out"
set category="Pokemon Commands"
if(usr.pokemonout==0)
if(M.Faint)
usr<< output("This Pokemon is fainted","default.BattleInfo")
else
M.loc = locate(usr.x,usr.y,usr.z)
view() << output("[src.key] says: Go, [M.name]","default.BattleInfo")
usr.icon = M.icon
usr.icon_state=M.icon_state
M.icon = src.Picon
contents2 -= M
usr.pokemonout=1
usr.HP = M.HP
usr.MHP = M.MHP
usr.Level = M.Level
usr.EXP = M.EXP
usr.NEXP = M.NEXP
usr.Attack = M.Attack
usr.Defense = M.Defense
usr.SAttack = M.SAttack
usr.SDefense = M.SDefense
usr.AttackName = M.AttackName
usr.AttackD = M.AttackD
usr.GoodS = M.GoodS
usr.BadS = M.BadS
usr.First=1
usr.Species = M.Species
usr.EvolutionLevel = M.EvolutionLevel
usr.EvolutionName = M.EvolutionName
usr.EvolutionSpecies = M.EvolutionSpecies
usr.EvolutionIcon = M.EvolutionIcon
usr.EvolutionEvolutionLevel = M.EvolutionEvolutionLevel
usr.EvolutionEvolutionName = M.EvolutionEvolutionName
usr.EvolutionEvolutionSpecies = M.EvolutionEvolutionSpecies
usr.EvolutionEvolutionIcon = M.EvolutionEvolutionIcon
usr.EvolutionAttackName = M.EvolutionAttackName
usr.EvolutionEvolutionAttackName = M.EvolutionEvolutionAttackName
usr.EvolutionAttackD = M.EvolutionAttackD
usr.EvolutionEvolutionAttackD = M.EvolutionEvolutionAttackD
usr.EvolutionEvolutionEvolutionLevel = M.EvolutionEvolutionEvolutionLevel
usr.EvolutionEvolutionAttackD2 = M.EvolutionEvolutionAttackD2
M.Rank2 = usr.Rank2
usr.TempName=M.name
usr.SentOut += M
usr.IsAPokemon="Yes"
src.verbs += typesof(/mob/Pokemon/verb)
if(usr.AttackName=="Thundershock")
src.verbs += typesof(/mob/Pikachu/Thundershock/verb)
if(usr.AttackName=="Absorb")
src.verbs += typesof(/mob/Oddish/Absorb/verb)
if(usr.AttackName=="Mega Drain")
src.verbs += typesof(/mob/Gloom/MegaDrain/verb)
if(usr.AttackName=="Giga Drain")
src.verbs += typesof(/mob/Vileplume/GigaDrain/verb)
if(usr.AttackName=="Leaf Storm")
src.verbs += typesof(/mob/Bellossom/LeafStorm/verb)
usr.AttackD = M.EvolutionEvolutionAttackD2
if(usr.AttackName=="Ember")
src.verbs += typesof(/mob/Charmander/Ember/verb)
if(usr.AttackName=="Flamethrower")
src.verbs += typesof(/mob/Charmeleon/Flamethrower/verb)
if(usr.AttackName=="Fire Blast")
src.verbs += typesof(/mob/Charizard/FireBlast/verb)
if(usr.AttackName=="Bubble")
src.verbs += typesof(/mob/Squirtle/Bubble/verb)
if(usr.AttackName=="Vine Whip")
src.verbs += typesof(/mob/Bulbasaur/VineWhip/verb)
if(usr.AttackName=="Water Gun")
src.verbs += typesof(/mob/Wartortle/WaterGun/verb)
if(usr.AttackName=="Razor Leaf")
src.verbs += typesof(/mob/Ivysaur/RazorLeaf/verb)
if(usr.AttackName=="Hydro Pump")
src.verbs += typesof(/mob/Blastoise/HydroPump/verb)
if(usr.AttackName=="Magical Leaf")
src.verbs += typesof(/mob/Venusaur/MagicalLeaf/verb)
if(usr.AttackName=="Rock Blast")
src.verbs += typesof(/mob/Rhyhorn/RockBlast/verb)
if(usr.AttackName=="Stone Edge")
if(usr.Species=="Rhydon")
src.verbs += typesof(/mob/Rhydon/StoneEdge/verb)
else
if(usr.Species=="Rampardos")
src.verbs += typesof(/mob/Rampardos/StoneEdge/verb)
if(usr.AttackName=="Ancientpower")
src.verbs += typesof(/mob/Aerodactyl/Ancientpower/verb)
if(usr.AttackName=="Rock Slide")
src.verbs += typesof(/mob/Cranidos/RockSlide/verb)
if(usr.AttackName=="Dark Pulse")
src.verbs += typesof(/mob/Lucario/DarkPulse/verb)
if(usr.AttackName=="Focus Blast")
if(usr.Species=="Riolu")
src.verbs += typesof(/mob/Riolu/FocusBlast/verb)
else
if(usr.Species=="Mankey")
src.verbs += typesof(/mob/Mankey/FocusBlast1/verb)
if(usr.AttackName=="Secret Power")
if(usr.Species=="Primeape")
src.verbs += typesof(/mob/Primeape/SecretPower/verb)
else
if(usr.Species=="Persian")
src.verbs += typesof(/mob/Persian/SecretPower/verb)
if(usr.AttackName=="RazorWind")
src.verbs += typesof(/mob/Absol/RazorWind/verb)
if(usr.AttackName=="Swift")
src.verbs += typesof(/mob/Meowth/Swift/verb)
if(usr.AttackName=="Discharge")
src.verbs += typesof(/mob/Magnemite/Discharge/verb)
if(usr.AttackName=="Zap Cannon")
src.verbs += typesof(/mob/Magneton/ZapCannon/verb)
if(usr.AttackName=="Magnet Bomb")
src.verbs += typesof(/mob/Magnezone/MagnetBomb/verb)
else
usr<< output("You can not have more than one Pokemon out at a time","default.BattleInfo")
return


        Return(var/mob/M as mob in world)
set name="Return Pokemon"
set category="Pokemon Commands"
if(M.owner != "[usr.name]")
usr<<"That is not your Pokemon"
else
usr.loc = locate(M.x,M.y,M.z)
M.icon = usr.icon
M.icon_state=usr.icon_state
usr.icon = src.Picon
usr.icon_state = ""
M.loc = null
contents2 += M
usr.pokemonout=0
usr<< output("[M.name] returned","default.BattleInfo")
M.HP = usr.HP
M.MHP = usr.MHP
M.Level = usr.Level
M.EXP = usr.EXP
M.NEXP = usr.NEXP
M.Attack = usr.Attack
M.Defense = usr.Defense
M.SAttack = usr.SAttack
M.Species = usr.Species
M.EvolutionLevel = usr.EvolutionLevel
M.EvolutionName = usr.EvolutionName
M.EvolutionSpecies = usr.EvolutionSpecies
M.EvolutionIcon = usr.EvolutionIcon
usr.EvolutionLevel=0
usr.EvolutionName=""
usr.EvolutionSpecies=""
usr.EvolutionIcon=""
M.EvolutionEvolutionLevel = usr.EvolutionEvolutionLevel
M.EvolutionEvolutionName = usr.EvolutionEvolutionName
M.EvolutionEvolutionSpecies = usr.EvolutionEvolutionSpecies
M.EvolutionEvolutionIcon = usr.EvolutionEvolutionIcon
M.EvolutionEvolutionAttackD2 = usr.EvolutionEvolutionAttackD2
usr.EvolutionEvolutionLevel=0
usr.EvolutionEvolutionName=""
usr.EvolutionEvolutionSpecies=""
usr.EvolutionEvolutionIcon=""
usr.EvolutionEvolutionAttackD2 = 0
M.EvolutionAttackName = usr.EvolutionAttackName
M.EvolutionEvolutionAttackName = usr.EvolutionEvolutionAttackName
M.EvolutionAttackD = usr.EvolutionAttackD
M.EvolutionEvolutionAttackD = usr.EvolutionEvolutionAttackD
M.EvolutionEvolutionEvolutionLevel=0
usr.EvolutionAttackName = ""
usr.EvolutionEvolutionAttackName = ""
usr.EvolutionAttackD = 0
usr.EvolutionEvolutionAttackD = 0
usr.EvolutionEvolutionEvolutionLevel=0
M.SDefense = usr.SDefense
M.AttackName = "[usr.AttackName]"
M.AttackD = usr.AttackD
usr.HP=0
usr.Level=0
usr.EXP=0
usr.NEXP=0
usr.Attack=0
usr.Defense=0
usr.SAttack=0
usr.SDefense=0
usr.AttackName=""
usr.AttackD=0
usr.GoodS=""
usr.BadS=""
usr.First=0
M.name = usr.TempName
M.Rank2="Pokemon"
usr.TempName=""
usr.SentOut -= M
usr.IsAPokemon="No"
src.verbs -= typesof(/mob/Pokemon/verb)
src.verbs -= typesof(/mob/Pikachu/Thundershock/verb)
src.verbs -= typesof(/mob/Oddish/Absorb/verb)
src.verbs -= typesof(/mob/Gloom/MegaDrain/verb)
src.verbs -= typesof(/mob/Vileplume/GigaDrain/verb)
src.verbs -= typesof(/mob/Bellossom/LeafStorm/verb)
src.verbs -= typesof(/mob/Charmander/Ember/verb)
src.verbs -= typesof(/mob/Charmeleon/Flamethrower/verb)
src.verbs -= typesof(/mob/Charizard/FireBlast/verb)
src.verbs -= typesof(/mob/Squirtle/Bubble/verb)
src.verbs -= typesof(/mob/Bulbasaur/VineWhip/verb)
src.verbs -= typesof(/mob/Wartortle/WaterGun/verb)
src.verbs -= typesof(/mob/Ivysaur/RazorLeaf/verb)
src.verbs -= typesof(/mob/Blastoise/HydroPump/verb)
src.verbs -= typesof(/mob/Venusaur/MagicalLeaf/verb)
src.verbs -= typesof(/mob/Rhyhorn/RockBlast/verb)
src.verbs -= typesof(/mob/Rhydon/StoneEdge/verb)
src.verbs -= typesof(/mob/Aerodactyl/Ancientpower/verb)
src.verbs -= typesof(/mob/Rampardos/StoneEdge/verb)
src.verbs -= typesof(/mob/Cranidos/RockSlide/verb)
src.verbs -= typesof(/mob/Lucario/DarkPulse/verb)
src.verbs -= typesof(/mob/Riolu/FocusBlast/verb)
src.verbs -= typesof(/mob/Mankey/FocusBlast1/verb)
src.verbs -= typesof(/mob/Primeape/SecretPower/verb)
src.verbs -= typesof(/mob/Absol/RazorWind/verb)
src.verbs -= typesof(/mob/Persian/SecretPower/verb)
src.verbs -= typesof(/mob/Meowth/Swift/verb)
src.verbs -= typesof(/mob/Magnemite/Discharge/verb)
src.verbs -= typesof(/mob/Magneton/ZapCannon/verb)
src.verbs -= typesof(/mob/Magnezone/MagnetBomb/verb)
src.SaveFile()

This isn't an answer to your question. Just so you know.

But I'm curious, your attacks are done like:
src.verbs += typesof(/mob/Pikachu/Thundershock/verb)
What about something like Voltorb, which also has the thundershock attack? If that's the case, you're doing a lot of repeat code there.

Have you considered separating attacks into separate datums that reflect what they are? There are no doubt other methods to do this as well. But just as food for thought:
thunder_attacks
verb
thundershock()
thunderwave()

water_attacks
verb
hydro_pump()
watergun()
splash()


Or if you you want to combine the datums even further, you could perhaps get away with something like this:
attacks
thunder
verb
thundershock()
thunderwave()

water
verb
watergun()
hyrdopump()
splash()

fire
verb
flamethrower()
ember()

normal
verb
scratch()
bite()

pokemon
parent_type = /mob
var
attribute_type

Pikachu
attribute_type = "thunder"

Squirtle
attribute_type = "water"

Charmander
attribute_type = "fire"

Mewoth
attribute_type = "normal"

mob
verb
SpawnPikachu()
var/pokemon/Pikachu/P = new
P.verbs += typesof("/attacks/[P.attribute_type]/verb")

world << "My Pikachu has the following attacks:"
for(var/i = 1; i < P.verbs.len; i++)
world << "\t[P.verbs[i]]"


No doubt there are even better methods out there to contain the element specific attacks. Just some food for thought.
In response to Tiberath
Thanks for the help, but that problem is dealt with, everything's fine how it is.
In response to Xyphon101
Xyphon101 wrote:
everything's fine how it is.

Unfortunately, that's only what you think. Everything's very horrible how it is, actually. But he was merely posting advice, you don't have to listen, of course, if you really prefer the tedious way and doing a lot of excessive pointless work...
In response to Kaioken
Yes, I do, because it's already implemented. I would rather like an answer to my initial question please.
In response to Xyphon101
Xyphon101 wrote:
Yes, I do, because it's already implemented.

The bad way you're doing it, you'll need to add in tons of code for every new Pokemon/attack/whatever you add. So please. Your amount of excess work is not done, sadly it will only accumulate. Additionally, being excess and wasting time is not the only disadvantage to it. It's also not robust, far less manageable, and less readable/comprehensible, as of course, it's much longer. Other than being trouble for people working on the code, it's trouble for anyone reading, like potential helpers on the forums.

I would rather like an answer to my initial question please.

Well, I'm not going to read your whole code for more relevance, but since you've said "please", :D I'll tell you how I would accomplish such a switch for the use it may have. It looks like what you're doing is (manually...) copying the vars of one mob to another. That method can't end well. Anyway, I'd probably just switch the player's control between the trainer and pokemon mobs by making him login into the other mob (you can do this by changing the player's client.mob to the mob you want him to log into). This way the player will control the Pokemon mob and also have access to any verbs on it, and you could put a verb there to switch control to the trainer, or send you (the pokemon) back and then switch control, or both - or whatever. But you need to realize you'll need to change some things in your existing code for such a setup to work; maybe a lot. Here's a very basic example of how the above may look (I haven't made a Pokemon game or thought out the complete design of one sometime, neither do I know what you have in mind for your Pokemon game, etc):
mob
trainer
var/list/pokemons //yeah, I think "Pokemon" is plural, but still
verb/Send_Out_Pokemon(mob/pokemon/M as null|mob in src.pokemons)
if(!(M && M in src.pokemons))
//validate arguments for safety
return
if(!M.Move(src.loc))
src << "You can't let out [M] here!"
return
//if the Pokemon was successfully moved...
if(M) //more safety check goodness
src.client.mob = M
M << "You're now controlling [M]."
verb/ ... //other stuff a trainer can do...
pokemon
var/mob/trainer/Trainer //assuming we've set this var to the Pokemon's trainers
verb/Return_to_trainer()
if(src.Trainer)
src.loc = null //remove the Pokemon from the map, do whatever...
src.client.mob = src.Trainer
src.Trainer << "You're now controlling [src.Trainer]."
else src << "You have no trainer."
verb/Attack() //other stuff a Pokemon can do...
In response to Kaioken
Kaioken wrote:
> mob
> trainer
> var/list/pokemons //yeah, I think "Pokemon" is plural, but still
> verb/Send_Out_Pokemon(mob/pokemon/M as null|mob in src.pokemons)
> if(!(M && M in src.pokemons))
> //validate arguments for safety
> return
> if(!M.Move(src.loc))
> src << "You can't let out [M] here!"
> return
> //if the Pokemon was successfully moved...
> if(M) //more safety check goodness
> src.client.mob = M
> M << "You're now controlling [M]."
> verb/ ... //other stuff a trainer can do...
> pokemon
> var/mob/trainer/Trainer //assuming we've set this var to the Pokemon's trainers
> verb/Return_to_trainer()
> if(src.Trainer)
> src.loc = null //remove the Pokemon from the map, do whatever...
> src.client.mob = src.Trainer
> src.Trainer << "You're now controlling [src.Trainer]."
> else src << "You have no trainer."
> verb/Attack() //other stuff a Pokemon can do...


It is probably better to use usr in these verbs rather than src, or to at least check if src.client is null, the reason being that in the (odd) chance that the verb is not called by the player in question (as verbs don't have to be), it could cause runtime errors using src.client (i.e. src.client.mob, though src.client may be null). For example:
mob
verb
Test1()
world << "[src.client.key]"

Test2()
var/mob/M = new
M.Test1() // error!


Though this type of setup is almost certainly a logic error, it should never mean a runtime error, and robust code should take this into consideration.
In response to Kuraudo
Kuraudo wrote:
It is probably better to use usr in these verbs rather than src, or to at least check if src.client is null

The first solution is pretty much a false one. usr could still potentially be a clientless mob, or it could be null, so you're not adding much robustness. Therefore, using src as usual is still preferred.

Though this type of setup is almost certainly a logic error,

Yes, and it is not my concern to take preemptive measures against such code, which can clearly cause problems and needs to be fixed itself anyway. There's no need to waste [also, processing] time trying to check for such situations requiring a programmer to specifically do something stupid and cause a breakage; rather, when programming them, one should take notice that he doesn't break anything, like the verb by calling it on an inapplicable mob.

it should never mean a runtime error, and robust code should take this into consideration.

Robust code doesn't need to take into consideration every single potential outside problem (nor is it possible). The verb should make sure it runs fine when it is ran properly, not when it isn't. Such a way of thinking would litter code everywhere with checks; not my thing, I don't find it necessary (but you might). Also, in cases like this I'd actually prefer the proc to crash and cause a runtime error rather than checking for the problem and failing silently, because if it does [crash] then it means something's not right and I need to be notified so I know I need to fix it (in this case the stupid code calling the verb) and the chain of events should be stopped, and the runtime error does that conveniently.
You can always find a potential problem, but that doesn't mean you need to bother accounting for it if it's unlikely enough and accounting for it alone won't solve much. Robustness is good, but as with anything don't go over the top. A problem of similar nature that you could have pointed out in my code is that the code will fail if, say, there's a verb named "Send_Out_Pokemon" declared under /mob/trainer somewhere else. That doesn't mean anything needs to be changed in the verb's code; in other words, it doesn't mean I need to change the verb to this:
      verb/Send_Out_Pokemon_blarghuniquenameXXXX()
set name = "Send Out Pokemon"

...in order to solve possible conflicts with other code. In such a case the problem is in the other code, the code that "needs to account for the problem" is fine itself, and what you need to go fix is the other code.
Ok im new to all this and this code dosnt work for me
In response to Ultima_Warrior
Welcome, Novice Programmer!

Best not to bump topics from any more than a month old, especially for a reason like this. Searching for code and copy/pasting it into your code files is definitely not the way to get anything done.
In response to Kaioken
i tried your code Kaioken and theres one error that just got annoying.