ID:172685
 
I'm trying to make a card game (not like bridge, 31, or blackjack) thats like ummm.. those cards with monsters on them and they fight. Like Magic, Yugioh, or Pokemon. But I don't know where to start. I have my basic Idea, the icons, and the battle start code. But I don't know where to begin for drawing cards,playing cards, discarding cards, and ect.
If you have any ideas it would be greatly helpful. I'll post what I have right now just in-case you need to see it to help:
obj
table
marker
var/filled = 0
var/mob
P1
P2
var/turn = 1
Playingfield
var/mob
player1
player2
Click()
switch(alert("Would you like to have a card battle here?","Card Table","Yes","No"))
if("Yes")
if(src.player1 == null)
view(8)<<"[usr] sits down at the table"
src.player1 = usr
usr.waiting = 1
if(src.player1 != usr && src.player2 == null)
src.player2 = usr
usr.waiting = 1
usr.opponent = src.player1
src.player1.opponent = src.player2
view(8)<<"Let the battle begin!"
StartBattle(src.player1,src.player2)

mob
var
waiting = 0
mob/opponent
obj/list/deck = list()
obj/table/marker/battlefield
obj/draw/draw
Move()
if(src.waiting == 0)
..()

proc
StartBattle(mob/P1,mob/P2)
P1.loc = null
P2.loc = null
P1.battlefield = null
P2.battlefield = null
for(var/obj/table/marker/M in world)
if(M.filled == 0)
M.filled = 1
P1.battlefield = M
for(var/obj/table/marker/M in world)
if(M.filled == 0)
M.filled = 1
P2.battlefield = M
if(P1.battlefield && P2.battlefield)
Decide_Turns(P1,P2)
Decide_Turns(mob/P1,mob/P2)
var/first = 0
switch(alert(P1,"Heads or tails?","Turn order","Heads","Tails"))
if("Heads")
P2<<"[P1] calls heads!"
P1<<"You call heads!"
sleep(1)
var/side = rand(1,2)
if(side == 1)
P2<<"Heads! [P1] Goes first!"
P1<<"Heads! You go first!"
first = 1
if(side == 2)
P2<<"Tails! You go first!"
P1<<"Tails! [P2] Goes first!"
first = 2
if("Tails")
P2<<"[P1] calls Tails!"
P1<<"You call Tails!"
sleep(1)
var/side = rand(1,2)
if(side == 1)
P1<<"Heads! [P2] Goes first!"
P2<<"Heads! You go first!"
first = 2
if(side == 2)
P1<<"Tails! You go first!"
P2<<"Tails! [P1] Goes first!"
first = 1
if(first == 1)
setbattle(P1,P2)
if(first == 2)
setbattle(P2,P1)
setbattle(mob/P1,mob/P2)
P1.draw = new/obj/draw(locate(P1.battlefield.x+3,P1.battlefield.y-4,P1.battlefield.z))

//This is as far as I got...


All help is very appreiciated =D
Given the importance of card decks and card placement to such a system, I think those need to take priority over any kind of battle code. Right now you're putting the cart ahead of the horse.

Visualize for a moment what a playing area would look like. There would be particular places to put cards, including your draw deck and discard pile. Cards would often be stackable in most games, but in many they never overlap otherwise or always do so in a spread pattern (e.g. standard Klondike solitaire, Freecell). Sometimes you'd want to be able to orient cards a certain way.

So this gives us something to work with to start out. You need datums to represent each portion of the playing field, and to represent stacks of cards.
playbox
var/x1,y1,x2,y2 // the coordinate system you use is arbitrary
var/layout=0 // bit flags
var/const
LAYOUT_VERTICAL = 1 // place new stacks up/down before left/right
LAYOUT_RIGHT_TO_LEFT = 2
LAYOUT_BOTTOM_TO_TOP = 4
LAYOUT_CENTERED_X = 8 // center stacks horizontally
LAYOUT_CENTERED_Y = 8 // center stacks vertically
var/list/stacks

New(_x1,_y1,_x2,_y2,l)
x1=_x1;y1=_y1;x2=_x2;y2=_y2
layout = l

proc/IsEmpty()
return !stacks || !stacks.len

proc/AddStack(stack/S)
if(S in stacks) RemoveStack(S)
if(!stacks) stacks = new
stacks += S
S.box = src
...
// depending on layout, decide where to place new stacks
// and whether to adjust the position of others

proc/RemoveStack(stack/S)
if(S in stacks)
stacks -= S
if(!stacks.len) stacks = null // reclaim the empty list

// turfs in the /playbox field should pass along this message
proc/MouseDrop()

stack
var/playbox/box
var/stack/next // another stack underneath this one, oriented differently and/or offset
var/flags
var/const
STACK_FACEDOWN = 1
STACK_BOTTOMUP = 2
var/list/cards
var/x,y
var/orient = 0 // orientation

Del()
if(box) box.RemoveStack(src)
if(next) del(next)
..()

proc/AddCard(card/C, position = 0)
if(ispath(C)) C = new C()
if(!cards) cards = new
if(position && position > cards.len) position = 0
cards.Insert(position, C)

proc/AddCards(list/newcards, position = 0)
if(!istype(newcards))
return AddCard(newcards, position)
if(!cards) cards = new
if(position && position > cards.len) position = 0
newcards = newcards.Copy() // don't touch the original list
for(var/i in 1 to newcards.len)
var/card/C = newcards[i]
if(ispath(C)) newcards[i] = new C()
cards.Insert(position, newcards)

// this proc will take a list just as easily
proc/RemoveCard(card/C)
// don't necessarily delete the card datum
if(cards && cards.Remove(C))
if(!cards.len) del(src)

// these should be passed through from a display object
proc/Click()
proc/DblClick()
proc/MouseDrop()
That's a good foundation for now. Some of the stuff I left out would depend on the specifics of your game, I think. Maybe at some point I should make a library out of this.

Anyway, here's the plan: Any time you want to display cards on the table, you create a /stack datum and add those cards to it, and add that stack to the appropriate /playbox. (Usually you'd set up playboxes at the beginning of the game.) Whenever you use an obj (or more than one) to display a visible card, tell the obj(s) which stack that card belongs to. Any display objects should have a var telling them which stack they belong to, so Click() and DblClick() and such can be passed along.

Lummox JR
In response to Lummox JR (#1)
in your code you use card/c. should I make the cards thier own section then? right now I have them as /obj/cards.


Thanks for all help =D