diff --git a/code/modules/client/preference_setup/loadout/loadout_general.dm b/code/modules/client/preference_setup/loadout/loadout_general.dm
index 2416e38de43..8351c8da170 100644
--- a/code/modules/client/preference_setup/loadout/loadout_general.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_general.dm
@@ -154,13 +154,9 @@
path = /obj/item/towel
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
-/datum/gear/checkers
- display_name = "checkers game kit"
- path = /obj/item/storage/box/checkers_kit
-
-/datum/gear/chess
- display_name = "chess game kit"
- path = /obj/item/storage/box/chess_kit
+/datum/gear/gameboard
+ display_name = "holo board game"
+ path = /obj/item/board
/datum/gear/battlemonsters
display_name = "battlemonsters starter deck"
diff --git a/code/modules/games/boardgame.dm b/code/modules/games/boardgame.dm
index 269a028a9bb..513cd307ded 100644
--- a/code/modules/games/boardgame.dm
+++ b/code/modules/games/boardgame.dm
@@ -1,337 +1,67 @@
+#define ALLOWED_BOARD_TYPES list("c", "c-k", "h-ki", "h-qe", "h-b", "h-k", "h-r", "h-p")
+#define ALLOWED_BOARD_FACTIONS list("red", "black")
+#define IS_VALID_BOARD_POSITION(p) (p >= 0 && p < 64)
+
/obj/item/board
- name = "board"
- desc = "A standard 16\" checkerboard. Well used."
+ name = "holo board"
+ desc = "A standard 16\" holo checkerboard."
icon = 'icons/obj/pieces.dmi'
icon_state = "board"
- var/num = 0
- var/board_icons = list()
- var/board = list()
- var/selected = -1
-
-/obj/item/board/MouseDrop(mob/user as mob)
- if((user == usr && (!use_check(user))) && (user.contents.Find(src) || in_range(src, user)))
- if(ishuman(usr))
- forceMove(get_turf(usr))
- usr.put_in_hands(src)
-
-/obj/item/board/examine(mob/user, var/distance = -1)
- if(in_range(user,src))
- user.set_machine(src)
- interact(user)
- return
- ..()
+ var/list/pieces = list()
+ var/list/lastAction = null
/obj/item/board/attack_hand(mob/living/carbon/human/M as mob)
if(!isturf(loc)) //so if you want to play the game, you need to put it down somewhere
..()
- if(M.machine == src)
- ..()
else
- src.examine(M)
+ if(ui_interact(M))
+ ..()
+
-/obj/item/board/attack_self(mob/user)
- var/choice = alert("Do you want to throw everything off the [src]?", null, "No", "Yes")
- if(choice == "Yes")
- for(var/obj/item/checker/c in src.contents)
- c.forceMove(get_turf(src.loc))
- num = 0
- board_icons = list()
- board = list()
- selected = -1
- src.updateDialog()
- interact(user)
- ..()
+/obj/item/board/ui_interact(mob/user, var/datum/topic_state/state = default_state)
+ var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
+ . = TRUE
+ if (!ui)
+ ui = new(user, src, "misc-boardgame", 450, 570, "Board", state = state)
+ . = FALSE
+ ui.open()
-/obj/item/board/attackby(obj/item/I as obj, mob/user as mob)
- if(istype(I, /obj/item/storage/box))
- var/obj/item/storage/box/h = I
- for(var/obj/item/checker/c in h.contents)
- addPiece(c,user)
- else if(!addPiece(I,user))
- ..()
-
-/obj/item/board/proc/addPiece(obj/item/I as obj, mob/user as mob, var/tile = 0)
- if(I.w_class != 1) //only small stuff
- user.show_message("\The [I] is too big to be used as a board piece.")
- return 0
- if(num == 64)
- user.show_message("\The [src] is already full!")
- return 0
- if(tile > 0 && board["[tile]"])
- user.show_message("That space is already filled!")
- return 0
- if(!user.Adjacent(src))
- return 0
-
- user.drop_from_inventory(I,src)
- num++
-
-
- if(!board_icons["[I.icon] [I.icon_state]"])
- board_icons["[I.icon] [I.icon_state]"] = new /icon(I.icon,I.icon_state)
-
- if(tile == 0)
- var i;
- for(i=0;i<64;i++)
- if(!board["[i]"])
- board["[i]"] = I
- break
- else
- board["[tile]"] = I
-
- src.updateDialog()
-
- return 1
-
-
-/obj/item/board/interact(mob/user as mob)
- if(user.is_physically_disabled() || (!isAI(user) && !user.Adjacent(src))) //can't see if you arent conscious. If you are not an AI you can't see it unless you are next to it, either.
- user << browse(null, "window=boardgame")
- user.unset_machine()
- return
-
- var/list/dat = list({"
-
- "})
- var i, stagger
- stagger = 0 //so we can have the checkerboard effect
- for(i=0, i<64, i++)
- if(i%8 == 0)
- dat += ""
- stagger = !stagger
- if(selected == i)
- dat += "| "
- else
- dat+= ">"
- if(!isobserver(user))
- dat += ""
- dat += " | "
-
- dat += "
"
-
- if(selected >= 0 && !isobserver(user))
- dat += "
Remove Selected Piece"
- user << browse(jointext(dat, null),"window=boardgame;size=430x500") // 50px * 8 squares + 30 margin)
- onclose(usr, "boardgame")
+/obj/item/board/vueui_data_change(list/data, mob/user, datum/vueui/ui)
+ data = data || list()
+ . = data
+ data["pieces"] = pieces
+ data["last"] = lastAction
/obj/item/board/Topic(href, href_list)
- if(!usr.Adjacent(src))
- usr.unset_machine()
- usr << browse(null, "window=boardgame")
- return
+
+ if(href_list["add"])
+ if(pieces.len > 64)
+ return
+ if(verifyPiece(href_list["add"]["piece"]))
+ pieces[++pieces.len] = href_list["add"]["piece"]
- if(!usr.incapacitated()) //you can't move pieces if you can't move
- if(href_list["select"])
- var/s = href_list["select"]
- var/obj/item/I = board["[s]"]
- if(selected >= 0)
- //check to see if clicked on tile is currently selected one
- if(text2num(s) == selected)
- selected = -1 //deselect it
- else
+ if(href_list["change"])
+ if(verifyPiece(href_list["change"]["piece"]) && isnum(href_list["change"]["index"]))
+ lastAction = pieces[href_list["change"]["index"]]
+ pieces[href_list["change"]["index"]] = href_list["change"]["piece"]
- if(I) //cant put items on other items.
- return
+
+ if(href_list["remove"] && isnum(href_list["remove"]["index"]))
+ lastAction = pieces[href_list["remove"]["index"]]
+ pieces -= list(pieces[href_list["remove"]["index"]])
+
+ SSvueui.check_uis_for_change(src)
- //put item in new spot.
- I = board["[selected]"]
- board["[selected]"] = null
- board -= "[selected]"
- board -= null
- board["[s]"] = I
- selected = -1
- else
- if(I)
- selected = text2num(s)
- else
- var/mob/living/carbon/human/H = locate(href_list["person"])
- if(!istype(H))
- return
- var/obj/item/O = H.get_active_hand()
- if(!O)
- return
- addPiece(O,H,text2num(s))
- if(href_list["remove"])
- var/obj/item/I = board["[selected]"]
- if(!I)
- return
- board["[selected]"] = null
- board -= "[selected]"
- board -= null
- I.forceMove(src.loc)
- num--
- selected = -1
- var j
- for(j=0;j<64;j++)
- if(board["[j]"])
- var/obj/item/K = board["[j]"]
- if(K.icon == I.icon && cmptext(K.icon_state,I.icon_state))
- src.updateDialog()
- return
- //Didn't find it in use, remove it and allow GC to delete it.
- board_icons["[I.icon] [I.icon_state]"] = null
- board_icons -= "[I.icon] [I.icon_state]"
- board_icons -= null
- src.updateDialog()
-
-//checkes
-/obj/item/checker
- name = "checker"
- desc = "It is plastic and shiny."
- icon = 'icons/obj/pieces.dmi'
- icon_state = "checker_black"
- w_class = ITEMSIZE_TINY
- var/piece_color ="black"
-
-/obj/item/checker/Initialize()
- . = ..()
- icon_state = "[name]_[piece_color]"
- name = "[piece_color] [name]"
-
-/obj/item/checker/red
- piece_color ="red"
-
-/obj/item/storage/box/checkers
- name = "checkers box"
- desc = "This box holds a nifty portion of checkers."
- icon_state = "checkers"
- max_storage_space = 24
- w_class = ITEMSIZE_TINY
- can_hold = list(/obj/item/checker)
-
-/obj/item/storage/box/checkers/fill()
- for(var/i = 0; i < 12; i++)
- new /obj/item/checker(src)
- new /obj/item/checker/red(src)
-
-//chess
-
-//Chess
-
-/obj/item/checker/pawn
- name = "pawn"
-
-/obj/item/checker/pawn/red
- piece_color ="red"
-
-/obj/item/checker/knight
- name = "knight"
-
-/obj/item/checker/knight/red
- piece_color ="red"
-
-/obj/item/checker/bishop
- name = "bishop"
-
-/obj/item/checker/bishop/red
- piece_color ="red"
-
-/obj/item/checker/rook
- name = "rook"
-
-/obj/item/checker/rook/red
- piece_color ="red"
-
-/obj/item/checker/queen
- name = "queen"
-
-/obj/item/checker/queen/red
- piece_color ="red"
-
-/obj/item/checker/king
- name = "king"
-
-/obj/item/checker/king/red
- piece_color ="red"
-
-/obj/item/checker/attackby(obj/item/I as obj, mob/user as mob)
- if(istype(I, /obj/item/storage/box/chess))
- var/obj/item/storage/box/chess/b = I
- var/turf/T = get_turf(src)
- if(T)
- for(var/obj/item/checker/c in T.contents)
- if(istype(I, /obj/item/storage/box/chess/red))
- if(c.piece_color == "red")
- c.forceMove(b)
- else
- continue
- else if(c.piece_color != "red")
- c.forceMove(b)
- to_chat(user, "You put all checker pieces into [b].")
- else
- ..()
-
-/obj/item/storage/box/chess
- name = "black chess box"
- desc = "This box holds all the pieces needed for the black side of the chess board."
- icon_state = "chess_b"
- max_storage_space = 24
- w_class = ITEMSIZE_SMALL
- can_hold = list(/obj/item/checker)
-
-/obj/item/storage/box/chess/fill()
- for(var/i = 0; i < 8; i++)
- new /obj/item/checker/pawn(src)
- new /obj/item/checker/knight (src)
- new /obj/item/checker/knight (src)
- new /obj/item/checker/bishop (src)
- new /obj/item/checker/bishop (src)
- new /obj/item/checker/rook (src)
- new /obj/item/checker/rook (src)
- new /obj/item/checker/queen (src)
- new /obj/item/checker/king (src)
-
-/obj/item/storage/box/chess/red
- name = "red chess box"
- desc = "This box holds all the pieces needed for the red side of the chess board."
- icon_state = "chess_r"
-
-/obj/item/storage/box/chess/red/fill()
- for(var/i = 0; i < 8; i++)
- new /obj/item/checker/pawn/red(src)
- new /obj/item/checker/knight/red (src)
- new /obj/item/checker/knight/red (src)
- new /obj/item/checker/bishop/red (src)
- new /obj/item/checker/bishop/red (src)
- new /obj/item/checker/rook/red (src)
- new /obj/item/checker/rook/red (src)
- new /obj/item/checker/queen/red (src)
- new /obj/item/checker/king/red (src)
-
-//game kits
-/obj/item/storage/box/checkers_kit
- name = "checkers game kit"
- desc = "This box holds all the parts needed for a game of checkers."
- icon_state = "largebox"
- max_storage_space = 8
- can_hold = list(/obj/item/board,
- /obj/item/storage/box/checkers)
-
-/obj/item/storage/box/checkers_kit/fill()
- new /obj/item/board (src)
- new /obj/item/storage/box/checkers (src)
-
-/obj/item/storage/box/chess_kit
- name = "chess game kit"
- desc = "This box holds all the parts needed for a game of chess."
- icon_state = "largebox"
- max_storage_space = 8
- can_hold = list(/obj/item/board,
- /obj/item/storage/box/chess)
-
-/obj/item/storage/box/chess_kit/fill()
- new /obj/item/board (src)
- new /obj/item/storage/box/chess (src)
- new /obj/item/storage/box/chess/red (src)
+/obj/item/board/proc/verifyPiece(var/list/piece)
+ if(!(piece["type"] in ALLOWED_BOARD_TYPES))
+ return FALSE
+ if(!(piece["faction"] in ALLOWED_BOARD_FACTIONS))
+ return FALSE
+ if(!(IS_VALID_BOARD_POSITION(piece["pos"])))
+ return FALSE
+ return TRUE
+
+#undef ALLOWED_BOARD_TYPES
+#undef ALLOWED_BOARD_FACTIONS
+#undef IS_VALID_BOARD_POSITION
diff --git a/html/changelogs/vueui-chess.yml b/html/changelogs/vueui-chess.yml
new file mode 100644
index 00000000000..981c51f5835
--- /dev/null
+++ b/html/changelogs/vueui-chess.yml
@@ -0,0 +1,4 @@
+author: Karolis2011
+delete-after: True
+changes:
+ - rscadd: "Reworked board games (checkers and chess) in to one holo board, that allows to play any game. Also it been ported to VueUI."
\ No newline at end of file
diff --git a/icons/obj/pieces.dmi b/icons/obj/pieces.dmi
index 7b55092d2b0..dc5b66d366b 100644
Binary files a/icons/obj/pieces.dmi and b/icons/obj/pieces.dmi differ
diff --git a/maps/aurora/aurora-3_sublevel.dmm b/maps/aurora/aurora-3_sublevel.dmm
index 276b09472c7..be108957a47 100644
--- a/maps/aurora/aurora-3_sublevel.dmm
+++ b/maps/aurora/aurora-3_sublevel.dmm
@@ -8968,7 +8968,7 @@
c_tag = "Medical - Patient Wing Library";
dir = 1
},
-/obj/item/storage/box/chess_kit,
+/obj/item/board,
/turf/simulated/floor/wood,
/area/medical/patient_wing_library)
"aqG" = (
diff --git a/maps/aurora/aurora-4_mainlevel.dmm b/maps/aurora/aurora-4_mainlevel.dmm
index b5e8b47dfdd..e1fc95a4cf1 100644
--- a/maps/aurora/aurora-4_mainlevel.dmm
+++ b/maps/aurora/aurora-4_mainlevel.dmm
@@ -63253,7 +63253,7 @@
/area/maintenance/vault)
"kAL" = (
/obj/structure/table/wood,
-/obj/item/storage/box/chess_kit,
+/obj/item/board,
/turf/simulated/floor/carpet,
/area/crew_quarters/bar)
"kAV" = (
diff --git a/vueui/src/components/view/misc/boardgame.vue b/vueui/src/components/view/misc/boardgame.vue
new file mode 100644
index 00000000000..fee8015ed83
--- /dev/null
+++ b/vueui/src/components/view/misc/boardgame.vue
@@ -0,0 +1,250 @@
+
+
+
Flip
+
+
+
+ Remove
+
+
+
+ Red: {{ t.n }}
+
+
+ Black: {{ t.n }}
+
+
+
+
+ Initialize checker board
+ Initialize chess board
+
+
+
+
+
+
+
+
+