From 8b644530b79a70d3963d396f8b442e3248fe17eb Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 18 Oct 2023 01:35:18 +0200 Subject: [PATCH] [MIRROR] Revenants can use spirit boards [MDB IGNORE] (#24403) * Revenants can use spirit boards (#79029) ## About The Pull Request Allows Revenants to use Ouija boards. Cleans up some code of Ouija boards in general. Default Ouija boards now have some more options to select. Admins can now VV Ouija board options. Adds a 1% chance for a Ouija board to be called Luigi board. ## Why It's Good For The Game Revenants being excluded from spirit board fun is kinda messed up, even though they're telepaths. ## Changelog :cl: Melbert add: Revenants can now use Ouija Boards add: Ouija Boards now have more options to select from by default (and admins can VV it to even more options) fix: Blind people are now worse at using Ouija Boards /:cl: * Revenants can use spirit boards --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/game/objects/structures/spirit_board.dm | 113 +++++++++++------- .../basic/space_fauna/revenant/_revenant.dm | 12 ++ 2 files changed, 81 insertions(+), 44 deletions(-) diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm index d30e1363052..2e6a2bd9a07 100644 --- a/code/game/objects/structures/spirit_board.dm +++ b/code/game/objects/structures/spirit_board.dm @@ -6,77 +6,102 @@ resistance_flags = FLAMMABLE density = TRUE anchored = FALSE + /// Whether no one has moved the planchette yet. var/virgin = TRUE //applies especially to admins - var/next_use = 0 - var/planchette = "A" + /// How long between planchette movements. + COOLDOWN_DECLARE(next_use) + /// Where the planchette is currently pointing. + var/planchette + /// Ckey of last mob to use the board. var/lastuser = null + /// List of options ghosts (or people) can pick from. + var/list/ghosty_options = list( + "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z", + "1","2","3","4","5","6","7","8","9","0", + "Yes","No", + ) + /// Number of living, willing mobs adjacent to the board required for a seance to occur. + var/required_user_count = 2 + +/obj/structure/spirit_board/Initialize(mapload) + . = ..() + if(prob(1)) + name = "luigi board" + planchette = ghosty_options[1] /obj/structure/spirit_board/examine() - desc = "[initial(desc)] The planchette is sitting at \"[planchette]\"." . = ..() + if(planchette) + . += span_notice("The planchette is currently at the letter \"[planchette]\".") + else + . += span_notice("The planchette is in the middle of the board on no particular letter.") /obj/structure/spirit_board/attack_hand(mob/user, list/modifiers) . = ..() if(.) - return + return . spirit_board_pick_letter(user) + return TRUE - -//ATTACK GHOST IGNORING PARENT RETURN VALUE /obj/structure/spirit_board/attack_ghost(mob/dead/observer/user) + . = ..() + if(.) + return . spirit_board_pick_letter(user) - return ..() + return TRUE -/obj/structure/spirit_board/proc/spirit_board_pick_letter(mob/M) - if(!spirit_board_checks(M)) - return FALSE +/obj/structure/spirit_board/proc/spirit_board_pick_letter(mob/ghost) + if(!spirit_board_checks(ghost)) + return if(virgin) virgin = FALSE - notify_ghosts("Someone has begun playing with a [src.name] in [get_area(src)]!", source = src, header = "Spirit board") + notify_ghosts("Someone has begun playing with \a [src] in [get_area(src)]!", source = src, header = "Spirit board") - planchette = tgui_input_list(M, "Choose the letter.", "Seance!", list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")) - if(isnull(planchette)) + var/new_planchette = tgui_input_list(ghost, "Choose the letter.", "Seance!", ghosty_options) + if(isnull(new_planchette)) return - if(!Adjacent(M) || next_use > world.time) + if(!Adjacent(ghost) || !COOLDOWN_FINISHED(src, next_use)) return - M.log_message("picked a letter on [src], which was \"[planchette]\".", LOG_GAME) - next_use = world.time + rand(30,50) - lastuser = M.ckey - //blind message is the same because not everyone brings night vision to seances - var/msg = span_notice("The planchette slowly moves... and stops at the letter \"[planchette]\".") - visible_message(msg,"",msg) + planchette = new_planchette + ghost.log_message("picked a letter on [src], which was \"[planchette]\".", LOG_GAME) + COOLDOWN_START(src, next_use, rand(3 SECONDS, 5 SECONDS)) + lastuser = ghost.ckey + for(var/mob/viewer in range(2, src)) + if(isnull(viewer.client)) + continue + if(viewer.stat != CONSCIOUS && viewer.stat != DEAD) // You gotta be awake or dead to pay the toll + continue + if(viewer.is_blind()) + to_chat(viewer, span_hear("You hear a scraping sound...")) + else + to_chat(viewer, span_notice("The planchette slowly moves... and stops at the letter \"[planchette]\".")) -/obj/structure/spirit_board/proc/spirit_board_checks(mob/M) - //cooldown - var/bonus = 0 - if(M.ckey == lastuser) - bonus = 10 //Give some other people a chance, hog. +/obj/structure/spirit_board/proc/spirit_board_checks(mob/ghost) + var/cd_penalty = (ghost.ckey == lastuser) ? 1 SECONDS : 0 SECONDS //Give some other people a chance, hog. - if(next_use - bonus > world.time ) + if(next_use - cd_penalty > world.time) return FALSE //No feedback here, hiding the cooldown a little makes it harder to tell who's really picking letters. - //lighting check - var/light_amount = 0 - var/turf/T = get_turf(src) - light_amount = T.get_lumcount() + var/turf/play_turf = get_turf(src) + if(play_turf?.get_lumcount() > 0.2) + to_chat(ghost, span_warning("It's too bright here to use [src]!")) + return FALSE + if(required_user_count > 0) + var/users_in_range = 0 + for(var/mob/living/player in orange(1, src)) + if(isnull(player.ckey) || isnull(player.client)) + continue - if(light_amount > 0.2) - to_chat(M, span_warning("It's too bright here to use [src.name]!")) - return FALSE + if(player.client?.is_afk() || player.stat != CONSCIOUS || HAS_TRAIT(player, TRAIT_HANDS_BLOCKED))//no playing with braindeads or corpses or handcuffed dudes. + to_chat(ghost, span_warning("[player] doesn't seem to be paying attention...")) + continue - //mobs in range check - var/users_in_range = 0 - for(var/mob/living/L in orange(1,src)) - if(L.ckey && L.client) - if((world.time - L.client.inactivity) < (world.time - 300) || L.stat != CONSCIOUS || HAS_TRAIT(L, TRAIT_HANDS_BLOCKED))//no playing with braindeads or corpses or handcuffed dudes. - to_chat(M, span_warning("[L] doesn't seem to be paying attention...")) - else - users_in_range++ + users_in_range++ - if(users_in_range < 2) - to_chat(M, span_warning("There aren't enough people to use the [src.name]!")) - return FALSE + if(users_in_range < required_user_count) + to_chat(ghost, span_warning("There aren't enough people around to use [src]!")) + return FALSE return TRUE diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm index b3c6935c92e..526d268df03 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -202,6 +202,18 @@ if(ishuman(A) && in_range(src, A)) attempt_harvest(A) + return + + // This is probably the most cringe place I could put this but whatever - + // Revenants can click on spirit boards for seances like ghosts + if(istype(A, /obj/structure/spirit_board) \ + && !HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) \ + && !HAS_TRAIT(src, TRAIT_NO_TRANSFORM) \ + && !HAS_TRAIT(src, TRAIT_REVENANT_INHIBITED)) + + var/obj/structure/spirit_board/board = A + board.spirit_board_pick_letter(src) + return /mob/living/basic/revenant/ranged_secondary_attack(atom/target, modifiers) if(HAS_TRAIT(src, TRAIT_REVENANT_INHIBITED) || HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM) || !Adjacent(target) || !incorporeal_move_check(target))