ID:151483
 
Okay guys, it's been a while since I've been around, but lately I've been contemplating making a Pokemon Trading Card Game.

I have in the past worked on such a project, however things got buried within themselves; the code getting more and more elaborate, and there was no easy way to accomplish anything. I'll make a second post with some of the code snippets, just to give an example of what I was going through.

Basically I want to start from scratch, since I know my code was inefficient, and that's one of my primary focuses is to learn to code efficiently with the project I'm not re-embarking on.

I'm not sure how to go about even planning what to do - should I get the turn system down? How should it handle all the complex options? I want to make a datum handle this that will make further changes easy and efficient. I want cards to be objects where the rest of the system is so well-built that adding new cards is like snapping my fingers.

Well, I'll add some snippets in the next posts, since they're not really necessary, and there's a lot of it, so it's for those who are interested. Really, I'm only posting it so you may get a vague idea of how I was trying to handle things.
I realize this is a lot of code, and I'm not looking for you to look through it all, just an example of what I've been doing with the duel handler:

//Once testing is complete, give player2 options

/***Note to self: When the cards are actually integrated and I'm not just setting up the basis, the card trees will
be changed to obj/card/basic, obj/card/evo1, obj/card/item etc. This will be used on the for loops and such
where it's checking for basic pokemon you can put on the bench, not just anything! Run down the code and look for
things that will need to be changed to a specific card tree.

***And just usev if statements to see if it is a
evo card, and if it is, check to see if there are any spots with the evo card and replace them with it.

***When a duel is started, I must remember to make a list to save the deck. The deck is the only thing where cards will
be sent to the discard, so when the duel ends I don't want to have to add cards from discard to hand, just want to delete
everything on the field and just give yourself the fresh saved deck!

Atimer will be added in later.

***list to keep track of cards placed on field in initial placement of bench and hand, so that the other player cannot see
your cards till they place their own.

***Will also need to make sure there are basic cards in hand, and if not, redraw.


*** = done
*/



mob/var/Duel_Handler
Duel_Handler
var

mob
player1
player2

list
table = new
maxprize = 1 //amount of prizes there will be.
timeperturn
juststarting



New(mob/challenger,mob/b,maxprizes,time) //maxprizes is the number input in the challenge for prizes.
player1=challenger
player2=b
player1.Duel_Handler=src
player2.Duel_Handler=src //Give each player the duel handle variable to reference
maxprize = maxprizes
timeperturn=time
var/obj/checker=new/obj/checker
checker.loc=player1.loc
step(checker,EAST)
step(checker,EAST)
step(checker,EAST)
step(checker,EAST)
step(checker,EAST)
for(var/obj/table/t in view(5,checker))
table += t
//for(var/obj/a in table)
// a.overlays += 'hightlight.dmi'
//now giving each player their variables for easy access later...
for(var/obj/table/play/p in table)
player1.playloc = p
for(var/obj/table/play2/p in table)
player2.playloc = p
for(var/obj/table/bench/p in table)
player1.benchloc += p
for(var/obj/table/bench2/p in table)
player2.benchloc += p
for(var/obj/table/discard/p in table)
player1.discardloc = p
for(var/obj/table/discard2/p in table)
player2.discardloc = p
for(var/obj/table/prize1/p in table)
player1.prizeloc = p
for(var/obj/table/prize2/p in table)
player2.prizeloc = p
player1.induel=1
player2.induel=1
Initial_Placement(player1,player2)




proc
Timer(timeperturn,mob/timed,mob/waiting)
var/minutes = timeperturn*600
spawn for()
if(timed.action_performed)
timed.action_performed = 0
break
if(minutes<1) //if minutes is 0 or less, the player has ran out of time.
if(juststarting) //if the player's are still setting up, then default AFK player.
Player_Defeated(timed,waiting,"[timed] ran out of time on start.")
else
Turn_Choice(waiting,timed)
if(minutes<600)
waiting << output("[timed] has 1 minute remaining to perform an action.","info")
timed << output("[timed] has 1 minute remaining to perform an action.","info")
if(minutes<300)
waiting << output("[timed] has 30 seconds remaining to perform an action.","info")
timed << output("[timed] has 30 seconds remaining to perform an action.","info")
if(minutes<100)
waiting << output("[timed] has 10 seconds remaining to perform an action.","info")
timed << output("[timed] has 10 seconds remaining to perform an action.","info")
sleep(10)
minutes -= 10


Status_Recover(mob/a,mob/b) //between turns, this is called to remove parlized etc
if(!a.client)
return
a << output("Between Turns.","info")
b << output("Between Turns.","info")
sleep(10)
for(var/obj/card/c in a.playloc.loc) //cures that apply to the person whose turn is starting
if(c.cant_be_attacked)
c.cant_be_attacked = 0
world<<"works on statrecov"
//ADD OTHER CONDITIONS HERE WHEN JASON LOOKS UP :)
//if(!b.client) return
world<<"If there are errors here, add if(!b.client) return"
for(var/obj/card/c in b.playloc.loc) //cures that apply to the person whose turn is ending
world<<"works on opponent's card too (good)"
if(c.paralized)
world<<"parlises should be removed here?"
a << output("[c] has been cured of paralizes.","info")
b << output("[c] has been cured of paralizes.","info")
sleep(20)
Remove_Paralize(c)


for(var/obj/card/c in a.playloc.loc&&b.playloc.loc) //cures that apply to both:
if(c.sleep)
a << output("Player's whose Pokemon who is asleep will now flip a coin.","info")
b << output("Player's whose Pokemon who is asleep will now flip a coin.","info")
sleep(20)
Remove_Sleep(c)
if(c.poisoned)
a << output("[c] receives 10 damage due to poison.")
a << output("[c] receives 10 damage due to poison.")
for(var/obj/table/center/t in table)
Onscreen_Numbers(t,10)
break
hpupdate(c,10) //does 10 damage
sleep(20)
//add poison effect
/*c.cant_be_attacked = 0
c.burned = 0
c.paralized = 0
//c.poisoned?
c.sleep = 0*/

Remove_Sleep(obj/card/c)
if(Coin_Toss_Basic())
player1 << output("[c] is cured of sleep.","info")
player2 << output("[c] is cured of sleep.","info")
new/obj/healed(c.loc)
sleep(25)
else
player1 << output("[c] was not cured of sleep.","info")
player2 << output("[c] was not cured of sleep.","info")
sleep(25)


Remove_Paralize(obj/card/c)
c.paralized = 0
new/obj/healed(c.loc)
for(var/obj/info/paralized/p in c.loc)
del p



Coin_Toss_Basic()
for(var/obj/table/center/c in table)
var/a =new/obj/coinflip(c.loc)
sleep(41)
del a

if(rand(1,2)==2)
for(var/obj/table/center/c in table)
var/n = new/obj/coinh(c.loc)
sleep(40)
del n
return 1

else
for(var/obj/table/center/c in table)
var/q = new/obj/coint(c.loc)
sleep(40)
del q
return 0

Coin_Toss()
player1<<output("<b>A coin will now be tossed. If \
heads, first turn goes to the challenger. Otherwise, the challengee.</b>"
,"info")
player2<<output("<b>A coin will now be tossed. If \
heads, first turn goes to the challenger. Otherwise, the challengee.</b>"
,"info")
for(var/obj/table/center/c in table)
var/a =new/obj/coinflip(c.loc)
sleep(41)
del a

if(rand(1,2)==2)
player1<<output("<b>The coin has landed on heads- You go first!</b>","info")
player2<<output("<b>The coin has landed on heads- You're opponent goes first.</b>","info")
for(var/obj/table/center/c in table)
var/n = new/obj/coinh(c.loc)
sleep(40)
del n
return 1

else
player1<<output("<b>The coin has landed on tails- Your opponent goes first.</b>","info")
player2<<output("<b>The coin has landed on tails- You go first!</b>","info")
for(var/obj/table/center/c in table)
var/q = new/obj/coint(c.loc)
sleep(40)
del q
return 0
Initial_Placement(mob/player1,mob/player2)
for(var/obj/card/a in player1.deck)
player1.cardsowned += a
a.owner = player1 //give each card a temporary owner.
for(var/obj/card/b in player2.deck)
player2.cardsowned += b
b.owner = player2

//deck shuffle
Shuffle_Deck(player1)
Shuffle_Deck(player2)
var/maxcount = maxprize
while(maxcount) //add prizes to the prize list
maxcount --
var/a = player1.deck[player1.deck.len]
player1.prizes += a
player1.deck -= a
Prize_Update(player1)
var/b = player2.deck[player2.deck.len]
player2.prizes += b
player2.deck -= b
Prize_Update(player2)

if(player1.client) winshow(player1,"infohand",1)
if(player2.client) winshow(player2,"infohand",1)
player1<<output("<b>Each player will now place [maxprize] card(s) prizes.</b>","info")
player2<<output("<b>Each player will now place [maxprize] card(s) prizes.</b>","info")
sleep(30)
player1<<output("<b>Each player will now draw 7 cards...</b>","info")
player2<<output("<b>Each player will now draw 7 cards...</b>","info")
spawn Start_Draw(player1) //skip this line for a moment so both players can draw at same time.
Start_Draw(player2)
Basic_Check(player1) //Basic Check makes sure there's at least one basic card\
in your hand before starting.

Basic_Check(player2)
player1<<output("<b>Select a card to place on the field.</b>","info")
player2<<output("<b>Select a card to place on the field.</b>","info")
var/p1con //used to confirm if a proper card has been placed in play.
var/p2con
while(!p1con||!p2con) //while both players haven't placed a card in play...
sleep(10)
if(!p1con)
if(playerplacement(player1)==1)
p1con=1
//Don't bother skipping this line, because both players need to have a pokemon in play anyways before we can startt benching.
if(!p2con)
if(playerplacement(player2)==1)
p2con=1
if(!p1con&&player1.client)
world<<"ERROR 34322"
return
if(!p2con&&player2.client)
world<<"ERROR 34322"
return



//bench coding below....

player1<<output("<b>Select up to 5 cards to place on your bench, or click cancel to stop.</b>","info")
player2<<output("<b>The opponent is now placing their bench cards.</b>","info")


playerbench(player1) //player 1 will place their bench now.


player2<<output("<b>Select up to 5 cards to place on your bench, or click cancel to stop.</b>","info")
player1<<output("<b>The opponent is now placing their bench cards.</b>","info")

playerbench(player2)





world<<"time to play!"
Card_Replace(player1)
Card_Replace(player2)
if(Coin_Toss()==1)
Turn_Choice(player1,player2)
else
Turn_Choice(player2,player1)









world<<"time to play!"
Card_Replace(player1)
Card_Replace(player2)
if(Coin_Toss()==1)
Turn_Choice(player1,player2)
else
Turn_Choice(player2,player1)



Shuffle_Deck(mob/m) //Used to shuffle the deck.
for(var/i=m.deck.len, i>1, --i)
m.deck.Swap(i, rand(1,i))

Start_Draw(mob/m) //The beginning draw of the game...
var/count=7
while(count--)
sleep(5)
Draw_Card(m)

Card_Replace(mob/a) //replaces all facedown cards on the field with theirr respective lists
if(!a.client) return
for(var/obj/table/t in a.benchloc)
for(var/obj/card/facedowncard/f in t.loc)
for(var/obj/card/c in a.card2bench) //find cards in the hidden bench
c.loc = f.loc
hpupdate(c)
a.card2bench -= c
del f
break
for(var/obj/card/facedowncard/f in a.playloc.loc)
a.card2play.loc = f.loc
hpupdate(a.card2play)
del f


Basic_Check(mob/m)
if(!m.client) return //stop procs like this for npc
var/basictrue //if this is one, then there is a basic card
for(var/obj/card/c in m.hand)
if(istype(c,/obj/card/BASIC))
basictrue = 1
if(!basictrue) //No basic cards in your hand, then they'll have to redraw...
if(m==player1)
player1<<output("<b>You did not draw a basic card- You will now redraw.</b>","info")
player2<<output("<b>Your opponent did not draw a basic card- They will now redraw.</b>","info")
else
player2<<output("<b>You did not draw a basic card- You will now redraw.</b>","info")
player1<<output("<b>Your opponent did not draw a basic card- They will now redraw.</b>","info")
for(var/obj/card/c in m.hand)
m.deck += c //add it back into the deck
m.hand -= c //removed it from the hand
m.Updategrids() //update the hand
Shuffle_Deck(m) //shuffle the deck.
Start_Draw(m) //Draw the start draw again.
Basic_Check(m) //Make sure they drew a basic card this time!


Draw_Card(mob/m)
if(!m.deck.len) //no cards left
world<<"[m] is out of cards!"
return
//Player_Defeated(,m)
m.hand += m.deck[m.deck.len]
m.deck -= m.deck[m.deck.len]
m.Updategrids()

Pokemon_Defeated(obj/card/attacker,obj/card/attacked)
world<<"The attacked owner is: [attacked.owner]"
if(attacked.health<1)
world<<"check 2"
if(attacked.owner == player1)
Prize_Draw(player2, player1)
var/list/options = new
attacked.loc = null
hpupdate(attacked)
attacked.owner.discard += attacked
for(var/obj/table/bench/b in table)
for(var/obj/card/c in b.loc)
options += c
if(!options.len)
Player_Defeated(player1,player2)
return
for()
player1<<output("<b>Select a card on your bench to put in to play.</b>","info")
if(!player1.client) //if it's an NPC, call npc bench switch
NPC_bench2play(player1,options)
break
var/obj/card/x = player1.GetClick()
if(!(x in options))
continue
//therefore x is in your options
for(var/obj/table/play/p in table)
x.loc = p.loc
break
if(attacked.owner == player2)
Prize_Draw(player1, player2)
var/list/options = new
attacked.loc = null
hpupdate(attacked)
attacked.owner.discard += attacked
for(var/obj/table/bench2/b in table)
for(var/obj/card/c in b.loc)
options += c
if(!options.len)
Player_Defeated(player2,player1)
return
for()
player2<<output("<b>Select a card on your bench to put in to play.</b>","info")
if(!player2.client) //if it's an NPC, call npc bench switch
NPC_bench2play(player2,options)
break
var/obj/card/x = player2.GetClick()
if(!(x in options))
continue
for(var/obj/table/play2/p in table)
x.loc = p.loc
break


Player_Defeated(mob/a,mob/b,reason)
world<<"[a] HAS BEEN DEFEATED BY [b]."
world<<"[reason]"

















playerplacement(mob/a)
if(!a.client) return 1 //stop procs like this for npc
var/obj/card/c=a.GetClick()
if(istype(c,/obj/card/)&&c in a.hand)
if(istype(c,/obj/card/ITEM)||istype(c,/obj/card/ENERGY))
player1<<"You can't play an energy or item right now."
return 0 //stop and see if they want to do something else, by continuing...
//if its a card, and it's in your hand, and it's not an item or energy...
for(var/obj/card/d in a.playloc.loc)
a<<"\red There is already a card in play."
return 1 //return true, there's already a card in play...
//if not though, we can add the card to play!
new/obj/card/facedowncard(a.playloc.loc)
a.card2play = c
a.hand -= c
a.Updategrids()
return 1


playerbench(mob/a)
if(!a.client) return //stop npc's
for()
var/obj/x = a.GetClick()
if(istype(x,/obj/cancel))
world<<"u select cancel fag."
return 0
else if(istype(x,/obj/card/)&&x in a.hand)
if(istype(x,/obj/card/ITEM)||istype(x,/obj/card/ENERGY))
world<<"You can't play an energy or item right now."
continue //stop and see if they want to do something else, by continuing...
//if its a card, and it's in your hand, and it's not an item or energy...
var/list/bench_pieces = new
for(var/obj/b in a.benchloc) //add all benches to the list
bench_pieces += b
for(var/obj/table/t in bench_pieces) //looking through bench pieces...
for(var/obj/card/c in t.loc) //find peices of the bench with a card already in it...
bench_pieces -= t //remove that from the list of available slots.
var/ifit
for(var/b in bench_pieces)
ifit=1
if(!ifit) //there aren't still available selects
a<<"\red Your bench is full."
return 0 //end the proc
else //else, if there is available slots...
for(var/obj/table/t in bench_pieces) //pick one in the available
new/obj/card/facedowncard(t.loc)
a.card2bench += x
a.hand -= x
a.Updategrids()
break //break this and see if you want to place more cards :)
else //something that you shouldn't click.
continue //repeat it all lol


Card2Hand(obj/card/c,mob/m)
hpupdate(c)
c.loc = null
m.hand += c
m.Updategrids()





Energy_Onscreen(obj/card/pokemon,obj/card/energy) //used to show the icons of the energies attached to a paticular pokemon


Prize_Update(mob/a)
var/count = 0
if(maxprize>=5)
for(var/obj/card/c in a.prizes)
count ++
for(var/obj/o in a.prizeloc.loc)
if(o == a.prizeloc) continue //dont delete itself...
del o
if(count == 0)
new/obj/prize/prize0(a.prizeloc.loc)
if(count == 1)
new/obj/prize/prize1(a.prizeloc.loc)
if(count == 2)
new/obj/prize/prize2(a.prizeloc.loc)
if(count == 3)
new/obj/prize/prize3(a.prizeloc.loc)
if(count == 4)
new/obj/prize/prize4(a.prizeloc.loc)
if(count == 5)
new/obj/prize/prize5(a.prizeloc.loc)
if(count == 6)
new/obj/prize/prize6(a.prizeloc.loc)
if(count == 7)
new/obj/prize/prize7(a.prizeloc.loc)
if(count == 8)
new/obj/prize/prize8(a.prizeloc.loc)
if(maxprize<=4)
for(var/obj/card/c in a.prizes)
count ++
if(count == 0)
new/obj/prize/prize40(a.prizeloc.loc)
if(count == 1)
new/obj/prize/prize41(a.prizeloc.loc)
if(count == 2)
new/obj/prize/prize42(a.prizeloc.loc)
if(count == 3)
new/obj/prize/prize43(a.prizeloc.loc)
if(count == 4)
new/obj/prize/prize44(a.prizeloc.loc)
Prize_Draw(mob/winner,mob/loser)
var/list/select = new
var/count = 0
for(var/obj/card/c in winner.prizes)
count ++
select += "prize [count]"
if(count<=1)
Player_Defeated(loser,winner)
return
var/q = input("Select a prize to draw.","Select") in select
if(!q) return
var/n = pick(winner.prizes)
winner.hand += n
winner.prizes -= n
Prize_Update(winner)
winner.Updategrids()
if(!winner.prizes.len)
Player_Defeated(loser,winner)
Energy_Update(obj/card/c) //the card having it's energy icon's updated.

hpupdate(obj/card/c,q,remove)
if(c.health <= 0||remove)
for(var/obj/n in c.hplist)
del n
return
c.health -= q
Pokemon_Defeated(,c)
world<<"HPUPDATE"
for(var/obj/n in c.hplist)
del n

if(c.health<1) return
var/obj/target = c.loc
if(player2 == c.owner) //if the card's owner is player 2
target = get_step(target,WEST)
else //if it's player one
target = get_step(target,EAST)
var/onhp = new/obj/onscreenhp(target)
c.hplist += onhp
var/damage = num2text(c.health)
world << damage
var/first_char
var/second_char
var/third_char
var/fourth_char
var/obj/hp_num/first
var/obj/hp_num/second
var/obj/hp_num/third
var/obj/hp_num/fourth
if(lentext(damage) == 1)
first_char = copytext(damage,1,2)
first = new
if(lentext(damage) == 2)
second_char = copytext(damage,1,2)
second = new
first_char = copytext(damage,2,3)
first = new

if(lentext(damage) == 3)
third_char = copytext(damage,1,2)
third = new
second_char = copytext(damage,2,3)
second = new
first_char = copytext(damage,3,4)
first = new

if(lentext(damage) == 4)
fourth_char = copytext(damage,1,2)
fourth = new
third_char = copytext(damage,2,3)
third = new
second_char = copytext(damage,3,4)
second = new
first_char = copytext(damage,4,5)
first = new
if(first) first.loc = target
if(second) second.loc = target
if(third) third.loc = target
if(fourth) fourth.loc = target
if(first)
first.pixel_y += 20
c.hplist += first
first.icon_state = "---[first_char]"
if(second)
second.pixel_y += 20
c.hplist += second
second.icon_state = "--[second_char]-"
if(third)
third.pixel_y += 20
c.hplist += third
third.icon_state = "-[third_char]--"
if(fourth)
fourth.pixel_y += 20
c.hplist += fourth
fourth.icon_state = "[fourth_char]---"


There's more too, but I want to keep things organized, so next post.
Here's the actual turn system handling - which is much shorter than the previous code, just for an example of how I was handling that.

mob
var
energy_used //keeps track of if the player has already used an energy card that turn.


Duel_Handler
proc
Turn_Choice(mob/first,mob/second)
Status_Recover(first,second)
if(!first.client) //an npc
Turn_Choice(second,first) //other person's turn
return

Draw_Card(first)
first.energy_used = 0 //they can play another energy now.
second<<output("<b>It is your opponents turn.</b>","info")
for()
first<<output("<b>Click on cards in your hand or on the field to interact with them.</b>","info")
var/obj/x = first.GetClick() //await input from the player of a card, end option, or cancel...
if(istype(x,/obj/card)) //if its a card, check it out.
if(x in first.cardsowned) //If it is in the saved list of cards for player one (meaning he owns them)
//then we can provide options for these cards here:
if(x in first.hand) //if it's in the hand...
//var/i = input("play card on field/play?") in list("ya","na")
//if statements here will also check if it's an evolution card or basic or item, etc...
if(istype(x,/obj/card/ENERGY)&&x in first.hand)
first<<output("<b>Select a pokemon on your bench or play to attach [x] to.</b>","info")
var/obj/card/y = first.GetClick()
if(y in first.hand) //if the card you're trying to attach to is in your hand
first<<output("<b>You can't attach an energy to something in your hand.</b>","info")
sleep(30)
continue
if((istype(y,/obj/card/BASIC)&&y.owner==first)||(istype(y,/obj/card/EVOLUTION)&&y.owner==first)) //if the energy card is being attached to a pokemon\
and you own the card...

if(first.energy_used)
first<<output("<b>You cannot attach more than one energy per turn.</b>","info")
sleep(30)
continue
first.energy_used = 1
y.energies += x
Energy_Onscreen(y,x)
first.hand -= x
first.Updategrids()
continue //since we've exhausted all options with energies, go back to the top!

if(istype(x,/obj/card/ITEM))
//item's
world<<"ITEM"
continue
if(istype(x,/obj/card/EVOLUTION)) //if it's an evolution card in your hand
first<<output("<b>Select a card on the bench, or in play to evolve.</b>","info")
var/obj/card/w = first.GetClick()
if(!(w in first.hand)&&x:evolves_from == w.type) //if x's evolve from matches up with the other card... and other card\
not in your hand...

var/confirm = input(first,"Evolve [w] in to [x]?") in list("Yes","No")
if(confirm=="Yes")
x.loc = w.loc
x:energies = w.energies
w.energies = null
hpupdate(w,,1)
hpupdate(x)
first.hand -= x
first.Updategrids()
first.discard += w
w.loc = null
continue //allow them more options.
if(w in first.hand)
first<<output("<b>You can't evolve a card in your hand.</b>","info")
sleep(15)

if(istype(x,/obj/card/BASIC))//if you're just playing a basic card from the hand
var/list/available_slots = new //an available list of slots on the bench
var/play_slot //if there's a card in play or not, this takes priority.
for(var/obj/card/c in first.playloc.loc)
play_slot = 1 //this spot is already filled, so ignore it.
if(!play_slot) //if no card was found in play
var/confirm = input("Place [x] in play?") in list("Yes","No")
if(confirm == "Yes")
first.hand -= x
first.Updategrids()
x.loc = first.playloc.loc //place the card in play!
hpupdate(x)

continue //let them do other stuff
else //if there was a card in the play slot, check to see if they have empty space to\
play it on their bench

for(var/obj/b in first.benchloc)
available_slots += b
for(var/obj/card/c in b.loc) //for cards in each of player's benchs
available_slots -= b //remove b because it already has card on it
if(available_slots.len) //if there's any slots left...
for(var/obj/a in available_slots)
var/confirm = input("Place [x] on the bench?") in list("Yes","No")
if(confirm == "No")
break //end the inner loop
x.loc = a.loc
hpupdate(x)
first.hand -= x
first.Updategrids()
break //we've placed the card, time to end this inner for loop
continue //give the player more options
else //if there's no slots available, let them know!
first<<output("<b>There's no room on your bench or play to place a card!</b>","info")
sleep(30)
continue //let them have more options then.
//var/l = input(`select option``) in x.options - something like that.



else if(!(x in first.hand)) //if x isn't in the person's hand (on field)
world<<"it isnt in hand"
world<<"[first.playloc]"
if(x in first.playloc.loc) //if the card is in play
world<<"3"
//attack, retreat, and pokemon power options go here.
var/list/verb_options = new
verb_options.Add("Attack", "Retreat", "Pokepower", "Cancel")
var/options = input(first,"Select an option:","Select") in verb_options

if(options=="Attack")
var/obj/card/opponent_card
for(var/obj/card/c in second.playloc.loc)
//find a card in the opponents play area to pass on to the attacks
world << c
opponent_card = c
if(!opponent_card)
world<<"<b>\red ERROR: NO CARD ON OPPONENTS SIDE OF FIELD TO ATTACK"
continue
call(x,"attack") (opponent_card)
world<<"The opponent's card is [opponent_card]"
Pokemon_Defeated(x,opponent_card) //check to see if the opponent was defeated
Pokemon_Defeated(opponent_card,x) //check to see if you was defeated
if(x:end_turn) //if the card did indeed do something to end the turn ex attack
x:end_turn = 0
Turn_Choice(second,first) //end their turn!
break
if(options=="Retreat")
var/list/bench_list = new
var/list/cards = new
for(var/obj/q in first.benchloc)
bench_list += q //find your bench peices, add them to bench list.
for(var/obj/e in bench_list) //for pieces in your bench list...
for(var/obj/card/c in e.loc) //for cards in the piece's location
cards += c
if(!cards) //if no cards on bench...
alert(first, "There are no cards on your bench to switch with.")
continue
call(x,"retreat") (cards) //pass on the cards list to the retreat.
if(options=="Pokepower")
var/list/bench_list2 = new
var/list/bench_list3 = new
var/list/yourcards = new
var/list/theircards = new
for(var/obj/q in first.benchloc)
bench_list2 += q //find your bench peices, add them to bench list.
for(var/obj/e in bench_list2) //for pieces in your bench list...
for(var/obj/card/c in e.loc) //for cards in the piece's location
yourcards += c
for(var/obj/q in second.benchloc)
bench_list3 += q //find your bench peices, add them to bench list.
for(var/obj/e in bench_list3) //for pieces in your bench list...
for(var/obj/card/c in e.loc) //for cards in the piece's location
theircards += c
call(x,"pokepower") (yourcards, theircards)
continue //if none of the options were chosen, give them new options.\
without the continue, it would give attacking pokemon bench options aswell.




if(istype(x.loc,text2path("[first.discardloc.type]"))) //change to "discard2" for player 2...
world<<"yes, this is your discard pile"
//discard_show()
continue
var/benchyes
for(var/obj/a in first.benchloc)
for(var/obj/card/c in a.loc)
benchyes = 1
if(benchyes) //x was found in the player's bench
var/q = input(first,"Use pokepower or examine card?") in list("Check","Pokepower")
if(q=="Pokepower")
var/list/bench_list2 = new
var/list/bench_list3 = new
var/list/yourcards = new
var/list/theircards = new
for(var/obj/w in first.benchloc)
bench_list2 += w //find your bench peices, add them to bench list.
for(var/obj/e in bench_list2) //for pieces in your bench list...
for(var/obj/card/c in e.loc) //for cards in the piece's location
yourcards += c
for(var/obj/w in second.benchloc)
bench_list3 += w //find your bench peices, add them to bench list.
for(var/obj/e in bench_list3) //for pieces in your bench list...
for(var/obj/card/c in e.loc) //for cards in the piece's location
theircards += c
call(x,"pokepower") (yourcards, theircards)
else //if it wasn't any of yours, show data of opponents card...
world<<"info goes here"


else //if x isn't in player 1's cards, then we display it's data:
world<<"Data for the opponents card would go here."
//insert same options as player one gets here, except change variable values so they don't collide,\
and change pplay to play2 etc.

..()
continue //regardless, let them make more options.

if(istype(x,/obj/cancel))
switch(input(first,"End your turn?") in list("Yes","No"))
if("Yes")
Turn_Choice(second,first)
break
//if it is none of these, the for loop should go through it again.
And finally, how I was trying to handle the actual card creation so it was as easy as setting variables:

obj
card
var/mob/owner
var/list/options = new
var/list/energies = new
var/list/hplist = new //keeps track on hp icons attached to a pokemon.


EVOLUTION
ITEM
BASIC
ENERGY
icon = 'energy.dmi'
Lightning
Fire
Fighting
Water
Psychic
Grass



obj
card
var
damage = 0 //damage of a pokemon will be applied through this, to allow for super effectiveness etc.
attacks = list("No attacks")
health = 10
pokepowers = list("No Pokepowers")
evolves_from = null
retreat_cost = 1 //usually always costs one.
element = "normal" //the type of card
end_turn = 0 //make this var = 1 for verbs and such that end turn.
paralized = 0
sleep = 0
burned = 0
confused = 0
poisoned = 0
cant_be_attacked = 0 //ex: agility flip coin, if heads the pokemon can't be touched!
weakness = "none"
resistance = "none"
number = 1 //the card number
set_name = "none" //the card set it comes from. (ex: base, jungle, etc.)
lastdamage


proc
attack(obj/card/opponent)
var/q = input("Select an attack")as null|anything in attacks
if(!q) return //cancel
if(!hascall(src,q)) //if the verb doesn't exist, just stop the proc.
return
call(src,q) (opponent)





retreat(list/cards)
if(paralized)
owner << output("[src] is paralized and cannot retreat!","info")
sleep(20)
return
var/list/copyenergies = new //backup incase they cancel
copyenergies += energies
var/tempcost = retreat_cost //to not mess around with the real retreat cost of the card...
var/list/cards_to_discard = new //if they cancel, we can remove these cards from the discard.
while(tempcost)
var/q = input("Select [retreat_cost] energie(s) from [src] to retreat.") as null|anything in energies
if(!q) //if they cancelled, or there were no options
owner<<output("<b>Not enough energies to retreat.</b>","info")
sleep(15)
energies = copyenergies //return to original state
for(var/n in cards_to_discard)
owner.discard -= n //remove those cards from the discard.
return
owner.discard += q
cards_to_discard += q
energies -= q
tempcost --
//if they removed the energies required,
if(src.confused)
src.owner << output("[owner] flips a coin to see if [src] can retreat.","info")
sleep(20)
if(src.owner.Duel_Handler:Coin_Toss_Basic()==0) //if tails
src.owner << output("[src] failed to retreat!","info")
sleep(20)
return //they lose their energy cards too!
var/obj/card/choice = input("Select a card on the bench to switch with your active Pokemon.")as null|anything in cards
if(!choice)
energies = copyenergies //return to original state
for(var/n in cards_to_discard)
owner.discard -= n //remove those cards from the discard.
return
var/choice_loc=choice.loc
choice.loc = loc
choice.owner.Duel_Handler:hpupdate(choice)
loc = choice_loc
src.owner.Duel_Handler:hpupdate(src)
Remove_Conditions() //cards going to the bench are removed of all conditions...




pokepower(list/yourcards,list/theircards) //a list of your bench cards and your opponents bench cards are\
passed on as arguments.

var/q = input("Select a Pokepower")as null|anything in pokepowers
if(!q) return //cancel
if(!hascall(src,q)) //if the verb doesn't exist, just stop the proc.
return
call(src,q) (yourcards, theircards)
return //be default pokepower does absolutely nothing!


obj
card
proc
Damage(obj/card/c,d,chance,effect,effectdamage) //card, opponent, damage, chance (a flip a coin to see if the effect\
happens or not. , effect (with paraze etc)

var
xdamage //changes to the base "damage"
damage = d //regular damage from the card
if(paralized)
owner<<output("<b>[src] is paralized and cannot attack.</b>","info")
return
if(sleep)
owner<<output("<b>[src] is asleep and cannot attack.</b>","info")
return
if(confused)
owner<<output("<b>Flip a coin to see if [src] attacks or hurts itself due to confusion.</b>","info")
if(owner.Duel_Handler:Coin_Toss_Basic()==0)
owner<<output("<b>[src] hurts itself due to confusion.</b>","info")
c.owner<<output("<b>[src] hurts itself due to confusion.</b>","info")
Damage(src,20)
end_turn = 1
return
if(c.resistance == element) //if the opponent's resistance is your type
new/obj/info/resist(c.loc)
xdamage -= 30
if(c.weakness == element) //if the opponent's weakness is your type
new/obj/info/weakness(c.loc)
xdamage = damage*2 //double the damage if it's a weakness.
if(chance&&effect)

owner<<output("<b>[owner] flips a coin to see if [src]'s effect is activated.</b>","info")
c.owner<<output("<b>[owner] flips a coin to see if [src]'s effect is activated.</b>","info")
if(owner.Duel_Handler:Coin_Toss_Basic()==1)
effect_card(src,c,effect,effectdamage)

if(!chance)
effect_card(src,c,effect,effectdamage)
var/finaldamage = damage + xdamage
if(!(finaldamage<=0)) //if the damage us NOT less than zero
for(var/obj/table/center/t in owner.Duel_Handler:table)
Onscreen_Numbers(t,finaldamage)
c.health -= finaldamage
c.lastdamage = finaldamage //remembers damage for moves like mirror move
else
owner<<output("<b>[src] did no damage!</b>","info")


Remove_Conditions()
world<<"conditions removed."
for(var/obj/info/a in loc)
del a
cant_be_attacked = 0
burned = 0
confused = 0
paralized = 0
poisoned = 0
sleep = 0

obj
card
proc
effect_card(obj/card/attacker,obj/card/defender,effect,effectdamage)
if(!effect) world<<"ERROR NO EFFECT 534532"

if(effect == "poison") //add icons to let the player know of the effect...
new/obj/info/poison(defender.loc)
defender.poisoned = 1
if(effect == "paralize")
new/obj/info/paralized(defender.loc)
defender.paralized = 1
defender.confused = 0
defender.sleep = 0
if(effect == "burned")
new/obj/info/burned(defender.loc)
defender.burned = 1
if(effect == "confused")
new/obj/info/confused(defender.loc)
defender.confused = 1
defender.sleep = 0
defender.paralized = 0
if(effect == "sleep")
new/obj/info/sleep(defender.loc)
defender.sleep = 1
defender.paralized = 0
defender.confused = 0
if(effect == "cantbeattacked")
new/obj/info/cantbeattacked(attacker.loc)
attacker.cant_be_attacked = 1
if(effect == "switch")
var/list/select = new
for(var/obj/table/t in defender.owner.benchloc)
for(var/obj/card/c in t.loc)
select += c
if(!select.len) return
var/obj/card/selection = input(defender.owner,"Select a card to switch with the active Pokemon") in select
var/locat = defender.loc
defender.loc = selection.loc
selection.loc = locat
if(effect == "recoil")
Damage(src,effectdamage,null,null)


obj
info //these objects will be used to show that damage has been reduced. ex: a shield for resistance, or status changes.
resist
New()
..()
spawn(30)
del src
icon = 'resist.dmi'
weakness
icon = 'weakness.dmi'
New()
..()
spawn(30)
del src
icon = 'resist.dmi'
poison
icon = 'poison.dmi'
paralized
icon = 'paralized.dmi'
confused
icon = 'confused.dmi'
sleep
icon = 'sleep.dmi'
cantbeattacked
icon = 'cantbeattacked.dmi'
burned
obj
card
proc
ENERGY_CHECK(type,amount)
world<<"[src] is owned by: [src.owner]"
if(!energycheck(src.energies, type, amount)) //if this doesn't return true
src.owner << output("<b>You don't have the energies required to perform this action.</b>","info")
sleep(20)
return 0
return 1 //itherwise return true!











proc
energycheck(list/L, type, amount) //*format* 1. the list where energies are stored, usually always "energies"\
2. the type of energy using type path (ex: /obj/card/ENERGY/Fire)\
3. the amount of energies needed for it to return true.


if(!(L&&type)) //if not all these statements are true, stop immediatley.
world<<"Energy check statements not true."
return 0
var/true_count = 0
for(var/obj/card/ENERGY/s in L)
if(istype(s,type))
true_count ++
if(true_count >= amount)
return 1

proc
Onscreen_Numbers(obj/o,dam)
var/damage = num2text(dam)
var/first_char
var/second_char
var/third_char
var/fourth_char
var/obj/_num/first
var/obj/_num/second
var/obj/_num/third
var/obj/_num/fourth
if(lentext(damage) == 1)
first_char = copytext(damage,1,2)
first = new

if(lentext(damage) == 2)
second_char = copytext(damage,1,2)
second = new
first_char = copytext(damage,2,3)
first = new

if(lentext(damage) == 3)
third_char = copytext(damage,1,2)
third = new
second_char = copytext(damage,2,3)
second = new
first_char = copytext(damage,3,4)
first = new

if(lentext(damage) == 4)
fourth_char = copytext(damage,1,2)
fourth = new
third_char = copytext(damage,2,3)
third = new
second_char = copytext(damage,3,4)
second = new
first_char = copytext(damage,4,5)
first = new
var/target = o.loc
if(first) first.loc = target
if(second) second.loc = target
if(third) third.loc = target
if(fourth) fourth.loc = target

if(first)
first.icon_state = "---[first_char]"
if(second)
second.icon_state = "--[second_char]-"
if(third)
third.icon_state = "-[third_char]--"
if(fourth)
fourth.icon_state = "[fourth_char]---"

spawn(12)
if(first) del(first)
if(second) del(second)
if(third) del(third)
if(fourth) del(fourth)