#define MINESWEEPER_GAME_MAIN_MENU 0 #define MINESWEEPER_GAME_PLAYING 1 #define MINESWEEPER_GAME_LOST 2 #define MINESWEEPER_GAME_WON 3 #define MINESWEEPERIMG(what) {""} //Basically bypassing asset.icon_tag() /obj/machinery/computer/arcade/minesweeper name = "Minesweeper" desc = "An arcade machine that generates grids. It seems that the machine sparks and screeches when a grid is generated, as if it cannot cope with the intensity of generating the grid." icon_state = "arcade" circuit = /obj/item/circuitboard/computer/arcade/minesweeper var/area var/difficulty = "" //To show what difficulty you are playing var/flag_text = "" var/flagging = FALSE var/game_status = MINESWEEPER_GAME_MAIN_MENU var/mine_limit = 0 var/mine_placed = 0 var/mine_sound = TRUE //So it doesn't get repeated when multiple mines are exposed var/randomcolour = 1 var/randomnumber = 1 //Random emagged game iteration number to be displayed, put here so it is persistent across one individual arcade machine var/safe_squares_revealed var/saved_web = "" //To display the web if you click on the arcade var/win_condition var/rows = 1 var/columns = 1 var/table[31][51] //Make the board boys, 30x50 board var/spark_spam = FALSE /obj/machinery/computer/arcade/minesweeper/interact(mob/user) var/emagged = CHECK_BITFIELD(obj_flags, EMAGGED) var/dat if(game_status == MINESWEEPER_GAME_MAIN_MENU) dat += "Minesweeper
Minesweeper[emagged ? " EXTREME EDITION: Iteration #[randomnumber]" : ""]
" //Different colour mix for every random number made dat += " [emagged ? "Explode in the game, explode in real life" : "Reveal all the squares without hitting a mine"]!
What difficulty do you want to play?



Easy (9x9 board, 10 mines)
Intermediate (16x16 board, 40 mines)
Hard (16x30 board, 99 mines)
Custom" else dat = saved_web user = usr var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper) assets.send(user) user << browse(dat,"window=minesweeper,size=400x500") add_fingerprint(user) . = ..() /obj/machinery/computer/arcade/minesweeper/proc/reset_spark_spam() spark_spam = FALSE /obj/machinery/computer/arcade/minesweeper/Topic(href, href_list) . = ..() if(.) return var/exploding_hell = FALSE //For emagged failures var/reset_board = FALSE var/mob/living/user = usr //To identify who the hell is using this window, this should also make things like aliens and monkeys able to use the machine!! var/web_difficulty_menu = " Reveal all the squares without hitting a mine!
What difficulty do you want to play?



Easy (9x9 board, 10 mines)
Intermediate (16x16 board, 40 mines)
Hard (16x30 board, 99 mines)
Custom" var/web = "Minesweeper
Minesweeper
" var/static_web = "Minesweeper
Minesweeper
" //When we need to revert to the main menu we set web as this web = static_web if(CHECK_BITFIELD(obj_flags, EMAGGED)) web = "Minesweeper
Minesweeper EXTREME EDITION: Iteration #[randomnumber]
" //Different colour mix for every random number made if(!spark_spam) do_sparks(5, 1, src) spark_spam = TRUE addtimer(CALLBACK(src, .proc/reset_spark_spam), 30) var/startup_sound = CHECK_BITFIELD(obj_flags, EMAGGED) ? 'sound/arcade/minesweeper_emag2.ogg' : 'sound/arcade/minesweeper_startup.ogg' if(href_list["Main_Menu"]) game_status = MINESWEEPER_GAME_MAIN_MENU mine_limit = 0 rows = 0 columns = 0 mine_placed = 0 if(href_list["Easy"]) playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) flag_text = "OFF" game_status = MINESWEEPER_GAME_PLAYING reset_board = TRUE difficulty = "Easy" rows = 10 //9x9 board columns = 10 mine_limit = 10 if(href_list["Intermediate"]) playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) flag_text = "OFF" game_status = MINESWEEPER_GAME_PLAYING reset_board = TRUE difficulty = "Intermediate" rows = 17 //16x16 board columns = 17 mine_limit = 40 if(href_list["Hard"]) playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) flag_text = "OFF" game_status = MINESWEEPER_GAME_PLAYING reset_board = TRUE difficulty = "Hard" rows = 17 //16x30 board columns = 31 mine_limit = 99 if(href_list["Custom"]) if(custom_generation(usr)) flag_text = "OFF" game_status = MINESWEEPER_GAME_PLAYING reset_board = TRUE difficulty = "Custom" playsound(loc, startup_sound, 50, 0, extrarange = -3, falloff = 10) if(href_list["Flag"]) playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10) if(!flagging) flagging = TRUE flag_text = "ON" else flagging = FALSE flag_text = "OFF" if(game_status == MINESWEEPER_GAME_MAIN_MENU) if(CHECK_BITFIELD(obj_flags, EMAGGED)) playsound(loc, 'sound/arcade/minesweeper_emag2.ogg', 50, 0, extrarange = -3, falloff = 10) web += "Explode in the game, explode in real life!
What difficulty do you want to play?



Easy (9x9 board, 10 mines)
Intermediate (16x16 board, 40 mines)
Hard (16x30 board, 99 mines)
Custom" else playsound(loc, 'sound/arcade/minesweeper_startup.ogg', 50, 0, extrarange = -3, falloff = 10) web += web_difficulty_menu if(game_status == MINESWEEPER_GAME_PLAYING) mine_sound = TRUE area = (rows-1)*(columns-1) if(reset_board) mine_placed = 0 var/reset_everything = TRUE make_mines(reset_everything) safe_squares_revealed = 0 win_condition = area-mine_placed if(game_status != MINESWEEPER_GAME_MAIN_MENU) for(var/y1=1;y1= 0) //Check that it's not already revealed, and stop flag removal if we're out of flag mode table[y1][x1] += 10 if(table[y1][x1] != 10) playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10) else if(game_status != MINESWEEPER_GAME_LOST && game_status != MINESWEEPER_GAME_WON) game_status = MINESWEEPER_GAME_LOST if(CHECK_BITFIELD(obj_flags, EMAGGED) && !exploding_hell) exploding_hell = TRUE explode_EVERYTHING() if(QDELETED(src)) return if(mine_sound) switch(rand(1,3)) //Play every time a mine is hit if(1) playsound(loc, 'sound/arcade/minesweeper_explosion1.ogg', 50, 0, extrarange = -3, falloff = 10) if(2) playsound(loc, 'sound/arcade/minesweeper_explosion2.ogg', 50, 0, extrarange = -3, falloff = 10) if(3) playsound(loc, 'sound/arcade/minesweeper_explosion3.ogg', 50, 0, extrarange = -3, falloff = 10) mine_sound = FALSE else playsound(loc, 'sound/arcade/minesweeper_boardpress.ogg', 50, 0, extrarange = -3, falloff = 10) if(table[y1][x1] >= 0) //Check that it's not already flagged table[y1][x1] -= 10 else if(table[y1][x1] < 0) //If flagged, remove the flag table[y1][x1] += 10 if(href_list["same_board"]) //Reset the board... kinda if(game_status != MINESWEEPER_GAME_PLAYING) game_status = MINESWEEPER_GAME_PLAYING if(table[y1][x1] >= 10) //If revealed, become unrevealed! playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) table[y1][x1] -= 10 if(table[y1][x1] > 10 && !reset_board) safe_squares_revealed += 1 var/y2 = y1 var/x2 = x1 work_squares(y2, x2) //Work squares while in this loop so there's less load reset_board = FALSE web += "" //Start setting up the html table web += "" for(var/y1=1;y1= win_condition && game_status == MINESWEEPER_GAME_PLAYING) game_status = MINESWEEPER_GAME_WON if(rows < 10 || columns < 10) //If less than easy difficulty playsound(loc, 'sound/arcade/minesweeper_winfail.ogg', 50, 0, extrarange = -3, falloff = 10) say("You cleared the board of all mines, but you picked too small of a board! Try again with at least a 9x9 board!") else playsound(loc, 'sound/arcade/minesweeper_win.ogg', 50, 0, extrarange = -3, falloff = 10) say("You cleared the board of all mines! Congratulations!") if(CHECK_BITFIELD(obj_flags, EMAGGED)) var/itemname switch(rand(1,3)) if(1) itemname = "a syndicate bomb beacon" new /obj/item/sbeacondrop/bomb(loc) if(2) itemname = "a rocket launcher" new /obj/item/gun/ballistic/rocketlauncher/unrestricted(loc) new /obj/item/ammo_casing/caseless/rocket(loc) new /obj/item/ammo_casing/caseless/rocket(loc) new /obj/item/ammo_casing/caseless/rocket(loc) if(3) itemname = "two bags of c4" new /obj/item/storage/backpack/duffelbag/syndie/c4(loc) new /obj/item/storage/backpack/duffelbag/syndie/x4(loc) message_admins("[key_name_admin(user)] won emagged Minesweeper and got [itemname]!") visible_message("[src] dispenses [itemname]!", "You hear a chime and a clunk.") DISABLE_BITFIELD(obj_flags, EMAGGED) else var/dope_prizes = (area >= 480) ? list(ARCADE_WEIGHT_RARE) : (area >= 256) ? list(ARCADE_WEIGHT_RARE, ARCADE_WEIGHT_TRICK) : null prizevend(user, dope_prizes) if(game_status == MINESWEEPER_GAME_WON) web += "[(rows < 10 || columns < 10) ? "You won, but your board was too small! Pick a bigger board next time!" : "Congratulations, you have won!"]
Want to play again?
Easy (9x9 board, 10 mines)
Intermediate (16x16 board, 40 mines)
Hard (16x30 board, 99 mines)
Custom

Play on the same board
Return to Main Menu
" if(game_status == MINESWEEPER_GAME_LOST) web += "You have lost!
Try again?
Easy (9x9 board, 10 mines)
Intermediate (16x16 board, 40 mines)
Hard (16x30 board, 99 mines)
Custom

Play on the same board
Return to Main Menu
" if(game_status == MINESWEEPER_GAME_PLAYING) web += "Return to Main Menu
" web += "
Difficulty: [difficulty]
Mines: [mine_placed]
Rows: [rows-1]
Columns: [columns-1]
Flagging mode: [flag_text]
" web += "" var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/minesweeper) saved_web = sheet.css_tag() saved_web += web updateDialog() return /obj/machinery/computer/arcade/minesweeper/emag_act(mob/user) . = ..() if(CHECK_BITFIELD(obj_flags, EMAGGED)) return desc = "An arcade machine that generates grids. It's clunking and sparking everywhere, almost as if threatening to explode at any moment!" do_sparks(5, 1, src) randomnumber = rand(1,255) randomcolour = rgb(randomnumber,randomnumber/2,randomnumber/3) ENABLE_BITFIELD(obj_flags, EMAGGED) if(game_status == MINESWEEPER_GAME_MAIN_MENU) to_chat(user, "An ominous tune plays from the arcade's speakers!") playsound(user, 'sound/arcade/minesweeper_emag1.ogg', 100, 0, extrarange = 3, falloff = 10) else //Can't let you do that, star fox! to_chat(user, "The machine buzzes and sparks... the game has been reset!") playsound(user, 'sound/machines/buzz-sigh.ogg', 100, 0, extrarange = 3, falloff = 10) //Loud buzz game_status = MINESWEEPER_GAME_MAIN_MENU return TRUE /obj/machinery/computer/arcade/minesweeper/proc/custom_generation(mob/user) playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) //Entered into the menu so ping sound var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num if(!new_rows || !user.canUseTopic(src, !hasSiliconAccessInArea(user))) return FALSE new_rows = clamp(new_rows + 1, 4, 30) playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num if(!new_columns || !user.canUseTopic(src, !hasSiliconAccessInArea(user))) return FALSE new_columns = clamp(new_columns + 1, 4, 50) playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) var/grid_area = (new_rows - 1) * (new_columns - 1) var/lower_limit = round(grid_area*0.156) var/upper_limit = round(grid_area*0.85) var/new_mine_limit = input(user, "How many mines do you want? (Minimum: [lower_limit], Maximum: [upper_limit])", "Minesweeper Mines") as null|num if(!new_mine_limit || !user.canUseTopic(src, !hasSiliconAccessInArea(user))) return FALSE playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, 0, extrarange = -3, falloff = 10) rows = new_rows columns = new_columns mine_limit = clamp(new_mine_limit, lower_limit, upper_limit) return TRUE /obj/machinery/computer/arcade/minesweeper/proc/make_mines(var/reset_everything) if(mine_placed < mine_limit) for(var/y1=1;y1 0 && x3 > 0) y2 = y3 x2 = x3 if(table[y2][x2] == 1) for(y3=y2-1;y3= rows || y3 < 1) continue for(x3=x2-1;x3= columns || x3 < 1) continue if(table[y3][x3] == 0) table[y2][x2] += 1 if(table[y2][x2] == 11) for(y3=y2-1;y3= rows || y3 < 1) continue for(x3=x2-1;x3= columns || x3 < 1) continue if(table[y3][x3] > 0 && table[y3][x3] < 10) table[y3][x3] += 10 work_squares(y3, x3) //Refresh so we check everything we might be missing /obj/machinery/computer/arcade/minesweeper/proc/explode_EVERYTHING() var/mob/living/user = usr to_chat(user, "You feel a great sense of dread wash over you, as if you just unleashed armageddon upon yourself!") var/row_limit = rows-1 var/column_limit = columns-1 var/mine_limit_v2 = mine_limit if(rows > 21) row_limit = 20 if(columns > 21) column_limit = 20 if(mine_limit > (rows*columns) * 0.25) mine_limit_v2 = 24 message_admins("[key_name_admin(user)] failed an emagged Minesweeper arcade and has unleashed an explosion armageddon of size [row_limit],[column_limit] around [ADMIN_LOOKUPFLW(user.loc)]!") if(mine_limit_v2 < 10) explosion(loc, 2, 5, 10, 15) //Thought you could survive by putting as few mines as possible, huh?? else explosion(loc, 1, 3, rand(1,5), rand(1,10)) var/list/targets = list() var/cur_y = y - round(row_limit * 0.5, 1) var/starting_row = 1 if(cur_y < 1) starting_row -= cur_y - 1 cur_y = 1 var/start_x = x - round(column_limit * 0.5, 1) var/starting_column = 1 if(start_x < 1) starting_column -= start_x - 1 start_x = 1 for(var/row in starting_row to length(table)) //translate the mines locations into actual turf coordinates. if(!locate(cur_y, start_x, z)) break var/cur_x = start_x for(var/column in starting_column to length(table[row])) var/coord_value = table[row][column] if(coord_value == 10 || coord_value == 0) //there is a mine in here. var/turf/T = locate(cur_y, cur_x, z) if(!T) break targets += T cur_x++ cur_y++ var/num_explosions = 0 for(var/T in shuffle(targets)) //Create a shitton of explosions in irl turfs if we lose, it will probably kill us addtimer(CALLBACK(GLOBAL_PROC, /proc/explosion, T, 0, rand(1,2),rand(1,5),rand(3,10), FALSE), 15 * ++num_explosions) if(num_explosions == mine_limit_v2) return #undef MINESWEEPERIMG #undef MINESWEEPER_GAME_MAIN_MENU #undef MINESWEEPER_GAME_PLAYING #undef MINESWEEPER_GAME_LOST #undef MINESWEEPER_GAME_WON