Files
2020-02-16 19:40:21 -08:00

405 lines
14 KiB
Plaintext

/****************************************************************************************************************************************************************************************
________ ___ ___ _______ ________ ________ _____ ______ ________ ________ _________ _______ ________ ________ ________ _____ ________ *
|\ ____\|\ \|\ \|\ ___ \ |\ ____\ |\ ____\|\ _ \ _ \|\ __ \|\ ____\|\___ ___\\ ___ \ |\ __ \ |\ ____\ |\ ____\ / __ \|\_____ \ *
\ \ \___|\ \ \\\ \ \ __/|\ \ \___|_\ \ \___|\ \ \\\__\ \ \ \ \|\ \ \ \___|\|___ \ \_\ \ __/|\ \ \|\ \ \ \ \___|_\ \ \___|_|\/_|\ \|____|\ /_ *
\ \ \ \ \ __ \ \ \_|/_\ \_____ \\ \_____ \ \ \\|__| \ \ \ __ \ \_____ \ \ \ \ \ \ \_|/_\ \ _ _\ \ \_____ \\ \_____ \|/ \ \ \ \|\ \ *
\ \ \____\ \ \ \ \ \ \_|\ \|____|\ \\|____|\ \ \ \ \ \ \ \ \ \ \|____|\ \ \ \ \ \ \ \_|\ \ \ \\ \| __\|____|\ \\|____|\ \ \ \ \ __\_\ \ *
\ \_______\ \__\ \__\ \_______\____\_\ \ ____\_\ \ \__\ \ \__\ \__\ \__\____\_\ \ \ \__\ \ \_______\ \__\\ _\|\__\____\_\ \ ____\_\ \ \ \__\|\_______\ *
\|_______|\|__|\|__|\|_______|\_________\\_________\|__| \|__|\|__|\|__|\_________\ \|__| \|_______|\|__|\|__\|__|\_________\\_________\ \|__|\|_______| *
\|_________\|_________| \|_________| \|_________\|_________| *
*
________ ________ ________ ___ ___ ________ ___ ________ ___ ___ _________ _______ ________ ________ ________ ___ __ ________ ________ ________ *
|\ ____\|\ __ \|\ __ \|\ \ / /|\ __ \|\ \|\ ____\|\ \|\ \|\___ ___\ / ___ \|\ __ \|\ __ \|\ ____\ |\ \ |\ \|\ __ \|\ __ \|\ ____\ *
\ \ \___|\ \ \|\ \ \ \|\ \ \ \/ / | \ \|\ \ \ \ \ \___|\ \ \\\ \|___ \ \_| /__/|_/ /\ \ \|\ \ \ \|\ \ \ \___| \ \ \ \ \ \ \ \|\ \ \ \|\ \ \ \___| *
\ \ \ \ \ \\\ \ \ ____\ \ / / \ \ _ _\ \ \ \ \ __\ \ __ \ \ \ \ |__|// / /\ \ \\\ \ \ \\\ \ \ \____ \ \ \ __\ \ \ \ __ \ \ _ _\ \ \ *
\ \ \____\ \ \\\ \ \ \___|\/ / / \ \ \\ \\ \ \ \ \|\ \ \ \ \ \ \ \ \ ___ / /_/__\ \ \\\ \ \ \\\ \ \ ___ \ __\ \ \|\__\_\ \ \ \ \ \ \ \\ \\ \ \____ *
\ \_______\ \_______\ \__\ __/ / / \ \__\\ _\\ \__\ \_______\ \__\ \__\ \ \__\\__\\________\ \_______\ \_______\ \_______\\__\ \____________\ \__\ \__\ \__\\ _\\ \_______\ *
\|_______|\|_______|\|__||\___/ / \|__|\|__|\|__|\|_______|\|__|\|__| \|__\|__|\|_______|\|_______|\|_______|\|_______\|__|\|____________|\|__|\|__|\|__|\|__|\|_______| *
\|___|/ *
****************************************************************************************************************************************************************************************/
var/list/chessboard = list()
var/chess_enpassant = 0
var/chess_in_progress = 0
turf/simulated/floor/chess
var/obj/item/chesspiece/enpassant = null
New()
..()
chessboard += src
disposing()
chessboard -= src
..()
obj/chessbutton
name = "Chess Reset Button"
desc = "A button that clears the chessboard, then re-sets the pieces. Don't press it while you're playing"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "doorctrl0"
var/confirm = 0
attack_hand(mob/user as mob)
if(chess_in_progress && !confirm)
boutput(user, "<span style=\"color:red\">You are about to erase the board. Press again to confirm.</span>")
confirm = 1
else
logTheThing("admin", user, null, "has reset the chessboard. Hope nobody was playing chess.")
logTheThing("diary", user, null, "has reset the chessboard. Hope nobody was playing chess.", "admin")
for(var/turf/simulated/floor/chess/T in chessboard)
T.enpassant = null // almost forgot this, gotte get that sweet GC
for(var/obj/item/O in T)
qdel(O)
for(var/obj/landmark/chess/L in T)
L.lets_fuckin_start_this_party()
sleep(1)
chess_in_progress = 1
confirm = 0
obj/landmark/chess
proc/lets_fuckin_start_this_party()
switch(src.name)
if("pawn")
new /obj/item/chesspiece/pawn(src.loc)
if("king")
new /obj/item/chesspiece/king(src.loc)
if("queen")
new /obj/item/chesspiece/queen(src.loc)
if("rook")
new /obj/item/chesspiece/rook(src.loc)
if("bishop")
new /obj/item/chesspiece/bishop(src.loc)
if("knight")
new /obj/item/chesspiece/knight(src.loc)
if("b_pawn")
new /obj/item/chesspiece/pawn/black(src.loc)
if("b_king")
new /obj/item/chesspiece/king/black(src.loc)
if("b_queen")
new /obj/item/chesspiece/queen/black(src.loc)
if("b_rook")
new /obj/item/chesspiece/rook/black(src.loc)
if("b_bishop")
new /obj/item/chesspiece/bishop/black(src.loc)
if("b_knight")
new /obj/item/chesspiece/knight/black(src.loc)
obj/item/chesspiece
name = "chess piece"
desc = "a generic chess piece parent that you really shouldnt be seeing"
icon = 'icons/misc/chess.dmi'
icon_state = "pawn_black"
anchored = 1
var/chess_color = 0
var/isking = 0
New()
..()
name = "[chess_color ? "black" : "white" ] [name]"
MouseDrop(obj/over_object as obj, src_location, over_location, mob/user as mob)
..()
var/turf/Tb = get_turf(over_location)
var/turf/Ta = get_turf(src_location)
if(!Tb | !Ta)
return
else
if(istype(Tb,/turf/simulated/floor/chess) && validmove(Ta,Tb))
chessmove(Tb,user)
else
src.visible_message("<span style=\"color:red\">Invalid move dorkus.</span>") // seems USER here is not actually the mob, but the click proc itself, so im regressing to a visible message for now
proc/gib()
//do some gib stuff here
qdel(src)
proc/validmove(turf/start_pos, turf/end_pos)
return 1
proc/chessmove(turf/T, mob/user)
for(var/obj/item/chesspiece/C in T)
if(C.isking && (chess_color != C.chess_color))
src.visible_message("<span style=\"color:green\">[src] has captured the enemy Captain. The [chess_color ? "black" : "white" ] commander has defeated the [C.chess_color ? "black" : "white" ] crew.</span>")
C.gib()
chess_in_progress = 0
else if(chess_color == C.chess_color)
src.visible_message("<span style=\"color:red\">You really ought to fight the enemy pieces, [chess_color ? "black" : "white" ] commander.</span>")
return
else
src.visible_message("<span style=\"color:blue\">[src] has captured [C].</span>")
C.gib()
src.visible_message("<span style=\"color:blue\">The [chess_color ? "black" : "white" ] commander has moved [src].</span>")
src.loc = T
if(chess_enpassant)
for(var/turf/simulated/floor/chess/CB in chessboard)
CB.enpassant = null
chess_enpassant = 0
/* specific pieces go here, the major differences are just their validmove() procs. Some might override chessmove() too
_1____0_
_B____W_
so for real uhhhh some of these things are still being attrocious, not announcing their captures and shit. I dont know why
*/
obj/item/chesspiece/pawn
name = "chess assistant"
desc = "A pawn- peon. pon? pone. A chess greyshirt."
var/movdir = 0
var/opened = 0
var/promoteX = 0
var/turf/simulated/floor/chess/EP = null
black
chess_color = 1
New()
..()
icon_state = (chess_color ? "pawn_black" : "pawn_white")
movdir = chess_color ? 1 : -1
promoteX = src.x + 6*movdir
validmove(turf/start_pos, turf/end_pos)
if(!opened && (start_pos.y==end_pos.y)) // do we allow you to move two spots? yes. yes we do. I love you.
if((end_pos.x - start_pos.x) == 2*movdir)
for(var/obj/item/chesspiece/C in locate(start_pos.x+movdir,src.y,src.z)) // intermediate blocking
return 0
EP = locate(start_pos.x+movdir,src.y,src.z)
return 1
if(start_pos.y != end_pos.y)
if((abs(start_pos.y - end_pos.y) == 1) && (end_pos.x - start_pos.x) == movdir )
for(var/obj/item/chesspiece/C in end_pos)
return 1
var/turf/simulated/floor/chess/Tep = end_pos
if(Tep.enpassant)
qdel(Tep.enpassant)
src.visible_message("<span style=\"color:blue\">[src] has made a capture en passant.</span>")
return 1
return 0
else if((end_pos.x - start_pos.x) != movdir)
return 0
else
for(var/obj/item/chesspiece/C in end_pos)
return 0
return 1
chessmove()
opened = 1
..()
if(src.x == promoteX) // promote after youre done movin
if (src.chess_color)
new /obj/item/chesspiece/queen/black(src.loc)
else
new /obj/item/chesspiece/queen(src.loc)
src.visible_message("<span style=\"color:blue\">[src] has been promoted.</span>")
qdel(src)
if (EP)
EP.enpassant = src
chess_enpassant = 1
EP = null
obj/item/chesspiece/king
name = "king"
desc = "A vital target, fittingly useless in combat."
isking = 1
var/opened = 0
var/castling = 0
black
chess_color = 1
New()
..()
icon_state = (chess_color ? "king_black" : "king_white")
validmove(turf/start_pos, turf/end_pos)
if(get_dist(start_pos,end_pos) == 1)
return 1
else if (!opened)
for(var/obj/item/chesspiece/rook/C in end_pos)
if ((C.chess_color == chess_color) && (!C.opened))
var/start = min(start_pos.y,end_pos.y)
var/end = max(start_pos.y,end_pos.y)
var/i
for(i=start+1, i < end, i++)
for(var/obj/item/chesspiece/Cfuck in locate(start_pos.x,i,src.z))
return 0
src.visible_message("<span style=\"color:blue\">[src] has castled with [C].</span>")
if(start_pos.y>end_pos.y)
C.loc = locate(src.x,(src.y - 1),src.z)
src.loc = locate(src.x,(src.y - 2),src.z)
else
C.loc = locate(src.x,(src.y + 1),src.z)
src.loc = locate(src.x,(src.y + 2),src.z)
castling = 1 // this is a dirty way to do this but
return 1
return 0
chessmove()
opened = 1
if(!castling)
..()
else // i guess it should work?
castling = 0 // in theory
if(chess_enpassant)
for(var/turf/simulated/floor/chess/CB in chessboard)
CB.enpassant = null
chess_enpassant = 0
obj/item/chesspiece/rook
name = "rook"
desc = "Somewhat rigid, linear, but totally ready to start fires"
var/opened = 0
black
chess_color = 1
New()
..()
icon_state = (chess_color ? "rook_black" : "rook_white")
validmove(turf/start_pos, turf/end_pos)
var/start = 0
var/end = 0
if(start_pos.x == end_pos.x)
start = min(start_pos.y,end_pos.y)
end = max(start_pos.y,end_pos.y)
var/i
for(i=start+1, i < end, i++)
for(var/obj/item/chesspiece/C in locate(start_pos.x,i,src.z))
return 0
return 1
else if(start_pos.y == end_pos.y)
start = min(start_pos.x,end_pos.x)
end = max(start_pos.x,end_pos.x)
var/i
for(i=start+1, i < end, i++)
for(var/obj/item/chesspiece/C in locate(i,start_pos.y,src.z))
return 0
return 1
else return 0
chessmove()
opened = 1
..()
obj/item/chesspiece/queen
name = "queen"
desc = "Subordinate in name only."
black
chess_color = 1
New()
..()
icon_state = (chess_color ? "queen_black" : "queen_white")
validmove(turf/start_pos, turf/end_pos) // we need 4 cases here. two orthogonal, two diagonal.
var/minx = min(start_pos.x,end_pos.x)
var/miny = min(start_pos.y,end_pos.y)
var/maxx = max(start_pos.x,end_pos.x)
var/maxy = max(start_pos.y,end_pos.y)
if(start_pos.x == end_pos.x) // vertical movement
var/i
for(i=miny+1, i < maxy, i++)
for(var/obj/item/chesspiece/C in locate(start_pos.x,i,src.z))
return 0
return 1
else if(start_pos.y == end_pos.y) // horizontal movement
var/i
for(i=minx+1, i < maxx, i++)
for(var/obj/item/chesspiece/C in locate(i,start_pos.y,src.z))
return 0
return 1
else if((start_pos.x - end_pos.x) == (start_pos.y - end_pos.y)) // coaxial diagonal
var/i
for(i=1, i < (start_pos.x - end_pos.x), i++)
for(var/obj/item/chesspiece/C in locate(minx+i,miny+i,src.z))
return 0
return 1
else if((start_pos.x - end_pos.x) == -(start_pos.y - end_pos.y)) // the other one
var/i
for(i=1, i < (start_pos.x - end_pos.x), i++)
for(var/obj/item/chesspiece/C in locate(maxx-i,miny+i,src.z))
return 0
return 1
else return 0 // none of the 4 directions? too bad okay. Im annotating code that doesnt need notes just because I gotta look busy at work.
obj/item/chesspiece/bishop
name = "bishop"
desc = "Boneless queen"
black
chess_color = 1
New()
..()
icon_state = (chess_color ? "bishop_black" : "bishop_white")
validmove(turf/start_pos, turf/end_pos) // we need only 2 cases here. im copypasting from queen.
var/minx = min(start_pos.x,end_pos.x)
var/miny = min(start_pos.y,end_pos.y)
var/maxx = max(start_pos.x,end_pos.x)
if((start_pos.x - end_pos.x) == (start_pos.y - end_pos.y)) // coaxial diagonal
var/i
for(i=1, i < (start_pos.x - end_pos.x), i++)
for(var/obj/item/chesspiece/C in locate(minx+i,miny+i,src.z))
return 0
return 1
else if((start_pos.x - end_pos.x) == -(start_pos.y - end_pos.y)) // the other one
var/i
for(i=1, i < (start_pos.x - end_pos.x), i++)
for(var/obj/item/chesspiece/C in locate(maxx-i,miny+i,src.z))
return 0
return 1
else return 0 // pee pee poo poo
obj/item/chesspiece/knight
name = "knight"
desc = "Does anyone actually know why they move like that?"
black
chess_color = 1
New()
..()
icon_state = (chess_color ? "knight_black" : "knight_white")
if(prob(1))
name = "hoarse"
validmove(turf/start_pos, turf/end_pos) // this is weird
var/dispx = abs(start_pos.x - end_pos.x)
var/dispy = abs(start_pos.y - end_pos.y)
if(((dispx == 2) && (dispy == 1)) || ((dispx == 1) && (dispy == 2)))
return 1
else return 0