Skip to content

Commit

Permalink
[MIRROR] Revenants can use spirit boards [MDB IGNORE] (#24403)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
2 people authored and FFMirrorBot committed Oct 17, 2023
1 parent 12ea013 commit 8b64453
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 44 deletions.
113 changes: 69 additions & 44 deletions code/game/objects/structures/spirit_board.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 12 additions & 0 deletions code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit 8b64453

Please sign in to comment.