From 01c912ad701245abf31c98dd5f6ba7c8a9b30c8e Mon Sep 17 00:00:00 2001 From: Karolis Date: Mon, 15 Feb 2021 13:23:15 +0200 Subject: [PATCH] VueUI game board. (#11035) --- .../loadout/loadout_general.dm | 10 +- code/modules/games/boardgame.dm | 372 +++--------------- html/changelogs/vueui-chess.yml | 4 + icons/obj/pieces.dmi | Bin 1082 -> 266 bytes maps/aurora/aurora-3_sublevel.dmm | 2 +- maps/aurora/aurora-4_mainlevel.dmm | 2 +- vueui/src/components/view/misc/boardgame.vue | 250 ++++++++++++ 7 files changed, 310 insertions(+), 330 deletions(-) create mode 100644 html/changelogs/vueui-chess.yml create mode 100644 vueui/src/components/view/misc/boardgame.vue 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 += "
= 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 7b55092d2b01d9e5857a538b61507ba81cc7e27d..dc5b66d366b6f5543632cf8e372baed4e1e3969a 100644 GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4*8>L*q@DS%s%i!lFg7-J z6J+@YWHFWm`2{mLJiCzw=P@u;%n1%FC@TH_CAi?@*C$%u zx?1PXoDbd*YH-o`!6TjXKAI;Pih6o?SQrNxUpDqqnDc1Tkx3y6!J3-(8#P=zyNy*h zuaG!l{^XI5w$~Zo)(uldWB$e*IL5?aW+Wy2p*!sp&{7jm7sn8diOC5P?;HX+nG$Q9 zHR1y#wGvo@6@6Sqj~R#_3t&u7)-Y(~+OWf+k(t-V*OY-FLynjAr|#b$K>ZA!u6{1- HoD!M<%aK|6 literal 1082 zcmV-A1jYM_P)C0000mP)t-sz`($D zb#(v$0F4+JGcz-68X6=H4j>>PLKYTg%>N}NHuDe=&=(h$9UZ{Hz>+8>v}}E;00001 zbW%=J06^y0W&i*HyLwbubVOxyV{&P5bZKvH004NLjncgi!XOX_@EM+hw7cbk%A*k3K_M9ou zqYAn4K?aCr(JSZ;;H`Ve-V~e-8ht$9adt;JL9Tx^!mw&PCvjcPadTU-wcTuoijw5Vj!iOL!i(U0R`p&NLS|ZDKriL2bQ94tF*Eo7}?C9BUC@Y z0008FCK?^^29mz_uHYc)uj|t802;8) z2Uu4!FfD7qv^0kR1;8K3g&+oCJ&+5*?RLL^f3g~Jf+Ytr06xAEo?HlG0M;0S@LWUS zUgX1*)8S5mjq88H!-!um|*E;C>~tOhLUx34kF z+p{KQ4ahbbGJp#rxQW~OX8`zZ&h+n6p33p6H2`$;62;$Z)_|jdLCA{@NcpN=_y-K2 zUB>)@khjP{*F;p4iUu1%{kxbyGhyLMB#P$pDWg(A@y!)c`Ue+=P(F z$FOfA8f^ge_u;0Y@ugHE!WI$Z>*66DN)Okqs>pn8|GXRbeJm;N{VRr+tzdti! z;i#kWSReNH`+mOAFuu+K7h@@3Z=oBnP$+Wv2bEYlPZJ_}l>h($07*qoM6N<$g53%6 At^fc4 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 @@ + + + + +