mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 16:12:17 +00:00
[MIRROR] We love word games (#11552)
Co-authored-by: eghughguhhhhhh <Hawoogabooga@gmail.com>
This commit is contained in:
committed by
GitHub
parent
03653c4d73
commit
74d68be7e3
@@ -1,6 +1,7 @@
|
|||||||
///Protects a datum from being VV'd
|
///Protects a datum from being VV'd
|
||||||
#define GENERAL_PROTECT_DATUM(Path)\
|
#define GENERAL_PROTECT_DATUM(Path)\
|
||||||
##Path/can_vv_get(var_name){\
|
##Path/can_vv_get(var_name){\
|
||||||
|
.=..();\
|
||||||
return FALSE;\
|
return FALSE;\
|
||||||
}\
|
}\
|
||||||
##Path/vv_edit_var(var_name, var_value){\
|
##Path/vv_edit_var(var_name, var_value){\
|
||||||
|
|||||||
@@ -98,6 +98,19 @@ GLOBAL_LIST_EMPTY(refined_chems_sold)
|
|||||||
end_dols = FLOOR(end_dols * 100,1) / 100 // Truncate decimals
|
end_dols = FLOOR(end_dols * 100,1) / 100 // Truncate decimals
|
||||||
valid_stats_list.Add("For a total of: [points] points, or [end_dols] [end_dols > 1 ? "thalers" : "thaler"]!")
|
valid_stats_list.Add("For a total of: [points] points, or [end_dols] [end_dols > 1 ? "thalers" : "thaler"]!")
|
||||||
|
|
||||||
|
if(SSnerdle)
|
||||||
|
var/word_export = "This shift's nerdle Was: [SSnerdle.target_word]! <br>"
|
||||||
|
word_export += "There were [SSnerdle.total_players] players this shift!<br>"
|
||||||
|
var/list/splashes = list("We know what you are!", "That's how we do!", "Basically free!", "Hear them roar!", "The streak is alive!","Don't fall for them tricks!")
|
||||||
|
for(var/i in 1 to SSnerdle.player_attempts.len)
|
||||||
|
if(SSnerdle.player_attempts[i] > 0)
|
||||||
|
if(i < 7)
|
||||||
|
word_export += "There were [SSnerdle.player_attempts[i]] people who got it in [i]! [splashes[i]]<br>"
|
||||||
|
else
|
||||||
|
word_export += "And there were [SSnerdle.player_attempts[i]] losers who couldn't quite get it. You'll get em next time!<br>"
|
||||||
|
|
||||||
|
valid_stats_list.Add(word_export)
|
||||||
|
|
||||||
if(LAZYLEN(valid_stats_list))
|
if(LAZYLEN(valid_stats_list))
|
||||||
to_chat(world, span_world("Shift trivia!"))
|
to_chat(world, span_world("Shift trivia!"))
|
||||||
|
|
||||||
|
|||||||
29
code/controllers/subsystems/nerdle.dm
Normal file
29
code/controllers/subsystems/nerdle.dm
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//KEEP THE STREAK ALIVE
|
||||||
|
SUBSYSTEM_DEF(nerdle)
|
||||||
|
name = "nerdle"
|
||||||
|
priority = FIRE_PRIORITY_APPRECIATE
|
||||||
|
runlevels = RUNLEVEL_GAME
|
||||||
|
flags = SS_BACKGROUND | SS_NO_FIRE
|
||||||
|
var/target_word = "fuckd"
|
||||||
|
|
||||||
|
var/list/player_attempts = list(0,0,0,0,0,0,0)//serialized, index = count of people who win/lose with that many guesses, 7 is for all the losers
|
||||||
|
var/total_players = 0
|
||||||
|
|
||||||
|
/datum/controller/subsystem/nerdle/Initialize()
|
||||||
|
var/list/l = world.file2list("strings/nerdle_dict.txt")
|
||||||
|
target_word = pick(l)
|
||||||
|
l = null
|
||||||
|
return SS_INIT_SUCCESS
|
||||||
|
|
||||||
|
/datum/controller/subsystem/nerdle/proc/report_winner_or_loser(var/guesses, var/failure = FALSE)
|
||||||
|
guesses = clamp(guesses,1,7)
|
||||||
|
if(failure)
|
||||||
|
guesses = 7 //fail
|
||||||
|
|
||||||
|
player_attempts[guesses] = player_attempts[guesses]+1
|
||||||
|
total_players ++
|
||||||
|
|
||||||
|
/datum/controller/subsystem/nerdle/can_vv_get(var_name) //the sancity of nerdle shall not be infringed by man or any of the gods above them.
|
||||||
|
if(var_name == NAMEOF(src, target_word))
|
||||||
|
return FALSE
|
||||||
|
return ..()
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
/datum/proc/can_vv_get(var_name)
|
/datum/proc/can_vv_get(var_name)
|
||||||
|
SHOULD_CALL_PARENT(TRUE)
|
||||||
if(var_name == NAMEOF(src, vars))
|
if(var_name == NAMEOF(src, vars))
|
||||||
return FALSE
|
return FALSE
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
/client
|
/client
|
||||||
var/datum/managed_browser/feedback_form/feedback_form = null
|
var/datum/managed_browser/feedback_form/feedback_form = null
|
||||||
|
|
||||||
/client/can_vv_get(var_name)
|
/client/can_vv_get(var_name)//no snooping but doesn't break shit
|
||||||
return var_name != NAMEOF(src, feedback_form) // No snooping.
|
if(var_name == NAMEOF(src, feedback_form))
|
||||||
|
return FALSE
|
||||||
|
return ..()
|
||||||
|
|
||||||
GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
|
GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
|
||||||
|
|
||||||
|
|||||||
@@ -389,7 +389,7 @@
|
|||||||
|
|
||||||
/mob/living/carbon/human/can_fall()
|
/mob/living/carbon/human/can_fall()
|
||||||
if(..())
|
if(..())
|
||||||
return species.can_fall(src)
|
return species?.can_fall(src)
|
||||||
|
|
||||||
// Another check that we probably can just merge into can_fall exept for messing up overrides
|
// Another check that we probably can just merge into can_fall exept for messing up overrides
|
||||||
/atom/movable/proc/can_fall_to(turf/landing)
|
/atom/movable/proc/can_fall_to(turf/landing)
|
||||||
|
|||||||
114
code/modules/pda/nerdle.dm
Normal file
114
code/modules/pda/nerdle.dm
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#define NERDLE_NO 0
|
||||||
|
#define NERDLE_YES 1
|
||||||
|
#define NERDLE_CLOSE 2
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle
|
||||||
|
name = "Nerdle"
|
||||||
|
icon = "child-reaching" //yipee!
|
||||||
|
notify_icon = "child-combatant"
|
||||||
|
title = "Nerdle™️ V0.8"
|
||||||
|
template = "pda_nerdle"
|
||||||
|
|
||||||
|
var/target_word
|
||||||
|
var/list/guesses = list() //raw text input for guesses
|
||||||
|
|
||||||
|
var/list/serialized_guesses = list() //shortcut for tgui serialization
|
||||||
|
|
||||||
|
var/max_guesses = 6
|
||||||
|
|
||||||
|
var/completed = FALSE
|
||||||
|
var/failure = FALSE
|
||||||
|
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle/start()
|
||||||
|
. = ..()
|
||||||
|
target_word = SSnerdle.target_word
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle/proc/try_guess(var/guess)
|
||||||
|
if(completed)
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
if(LAZYLEN(guess) != 5)
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
var/actual_guess = lowertext(guess)
|
||||||
|
|
||||||
|
serialize_guess(actual_guess)
|
||||||
|
LAZYADD(guesses,actual_guess)
|
||||||
|
|
||||||
|
if(actual_guess == target_word)
|
||||||
|
pda.audible_message("[pda] says, \"congratulations! You WON! A real NERDLE™️ Champ!\"")
|
||||||
|
playsound(pda, 'sound/arcade/win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
|
||||||
|
report_guesses()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
if(LAZYLEN(guesses) >= max_guesses)
|
||||||
|
pda.audible_message("[pda] says, \"Sorry! You lose! Try again next shift!\"")
|
||||||
|
failure = TRUE
|
||||||
|
playsound(pda, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
|
||||||
|
report_guesses()
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle/proc/report_guesses()
|
||||||
|
SSnerdle.report_winner_or_loser(LAZYLEN(guesses),failure)
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle/proc/serialize_guess(var/guess)
|
||||||
|
// We assume that there's 5 letters here, both for the guess and the target word.
|
||||||
|
// If we're getting runtimes and someone forwarded "butt" to here I'm going to smite them down.
|
||||||
|
var/list/out[5]
|
||||||
|
var/list/letter_counts = list() // Track occurrences of each letter in the target word
|
||||||
|
|
||||||
|
// Count count of each letter in the target word
|
||||||
|
for(var/i in 1 to 5)
|
||||||
|
var/them = target_word[i]
|
||||||
|
letter_counts[them] = (letter_counts[them] || 0) + 1
|
||||||
|
|
||||||
|
// First pass: Mark exact matches (NERDLE_YES)
|
||||||
|
for(var/i in 1 to 5)
|
||||||
|
var/us = guess[i]
|
||||||
|
var/them = target_word[i]
|
||||||
|
|
||||||
|
if(us == them)
|
||||||
|
out[i] = NERDLE_YES
|
||||||
|
letter_counts[them] -= 1 // Reduce the count for this letter
|
||||||
|
|
||||||
|
// Second pass: Mark close matches (NERDLE_CLOSE) and invalid matches (NERDLE_NO)
|
||||||
|
for(var/i in 1 to 5)
|
||||||
|
if(out[i]) // Skip already marked letters
|
||||||
|
continue
|
||||||
|
|
||||||
|
var/us = guess[i]
|
||||||
|
|
||||||
|
if(letter_counts[us] && letter_counts[us] > 0)
|
||||||
|
out[i] = NERDLE_CLOSE
|
||||||
|
letter_counts[us] -= 1 // Reduce the count for this letter
|
||||||
|
else
|
||||||
|
out[i] = NERDLE_NO
|
||||||
|
|
||||||
|
LAZYADD(serialized_guesses, list(out)) // Wrap it in a list so it stays a list
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle/update_ui(mob/user as mob, list/data)
|
||||||
|
data["guesses"] = serialized_guesses
|
||||||
|
data["guesses_raw"] = guesses
|
||||||
|
data["max"] = max_guesses
|
||||||
|
data["used_guesses"] = LAZYLEN(guesses)
|
||||||
|
data["target_word"] = target_word //if people fuck around with tgui to cheat at nerdle then I can't really be assed enough to care. we'll know who you are.
|
||||||
|
|
||||||
|
/datum/data/pda/app/nerdle/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||||
|
if(..())
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
unnotify()
|
||||||
|
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
|
if(action == "guess")
|
||||||
|
var/guess = params["lastword"]
|
||||||
|
var/did_we_guess = try_guess(guess)
|
||||||
|
return did_we_guess
|
||||||
|
|
||||||
|
#undef NERDLE_YES
|
||||||
|
#undef NERDLE_NO
|
||||||
|
#undef NERDLE_CLOSE
|
||||||
@@ -47,6 +47,7 @@
|
|||||||
new/datum/data/pda/app/messenger,
|
new/datum/data/pda/app/messenger,
|
||||||
new/datum/data/pda/app/manifest,
|
new/datum/data/pda/app/manifest,
|
||||||
new/datum/data/pda/app/atmos_scanner,
|
new/datum/data/pda/app/atmos_scanner,
|
||||||
|
new/datum/data/pda/app/nerdle,
|
||||||
new/datum/data/pda/utility/scanmode/notes,
|
new/datum/data/pda/utility/scanmode/notes,
|
||||||
new/datum/data/pda/utility/flashlight)
|
new/datum/data/pda/utility/flashlight)
|
||||||
var/list/shortcut_cache = list()
|
var/list/shortcut_cache = list()
|
||||||
|
|||||||
2348
strings/nerdle_dict.txt
Normal file
2348
strings/nerdle_dict.txt
Normal file
File diff suppressed because it is too large
Load Diff
82
tgui/packages/tgui/interfaces/Pda/pda_screens/pda_nerdle.tsx
Normal file
82
tgui/packages/tgui/interfaces/Pda/pda_screens/pda_nerdle.tsx
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { useBackend } from 'tgui/backend';
|
||||||
|
import { Box, Input, Section, Stack } from 'tgui-core/components';
|
||||||
|
|
||||||
|
type Data = {
|
||||||
|
guesses: number[][]; // Serialized guesses (NERDLE_YES, NERDLE_CLOSE, NERDLE_NO)
|
||||||
|
guesses_raw: string[]; // Raw guesses (letters)
|
||||||
|
max: number; // Maximum number of guesses
|
||||||
|
used_guesses: number; // Number of guesses used
|
||||||
|
target_word: string; // Target word for debugging (optional)
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pda_nerdle = (props) => {
|
||||||
|
const { act, data } = useBackend<Data>();
|
||||||
|
|
||||||
|
const { guesses, guesses_raw, max, used_guesses, target_word } = data;
|
||||||
|
|
||||||
|
const gameOver = used_guesses >= max || guesses_raw.includes(target_word);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Section title="Nerdle V0.8 - A Bingle Collaboration Product">
|
||||||
|
<Box>
|
||||||
|
Guess the 5-letter word! You have {max - used_guesses} attempts left.
|
||||||
|
</Box>
|
||||||
|
{!gameOver && (
|
||||||
|
<Box>
|
||||||
|
<Input
|
||||||
|
placeholder="Enter your guess"
|
||||||
|
onEnter={(value) => act('guess', { lastword: value })}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{gameOver && (
|
||||||
|
<Box color="good" bold>
|
||||||
|
{guesses_raw.includes(target_word)
|
||||||
|
? 'You win!'
|
||||||
|
: `Nice try! Today's word was ${target_word}`}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Section>
|
||||||
|
<Section title="Guesses">
|
||||||
|
<Stack vertical align="center">
|
||||||
|
{guesses.length > 0 ? (
|
||||||
|
guesses.map((guess, index) => (
|
||||||
|
<Box key={index}>
|
||||||
|
<Stack.Item align="center">
|
||||||
|
<Stack width="100%">
|
||||||
|
{guess.map((result, i) => (
|
||||||
|
<Box
|
||||||
|
key={i}
|
||||||
|
color={
|
||||||
|
result === 1
|
||||||
|
? 'good'
|
||||||
|
: result === 2
|
||||||
|
? 'average'
|
||||||
|
: 'bad'
|
||||||
|
}
|
||||||
|
textAlign="center"
|
||||||
|
bold
|
||||||
|
backgroundColor={
|
||||||
|
result === 1
|
||||||
|
? 'rgba(0, 255, 0, 0.2)'
|
||||||
|
: result === 2
|
||||||
|
? 'rgba(255, 255, 0, 0.2)'
|
||||||
|
: 'rgba(255, 0, 0, 0.2)'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{guesses_raw[index][i]}
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
</Stack.Item>
|
||||||
|
</Box>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Box>No guesses yet!</Box>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
</Section>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -466,6 +466,7 @@
|
|||||||
#include "code\controllers\subsystems\media_tracks.dm"
|
#include "code\controllers\subsystems\media_tracks.dm"
|
||||||
#include "code\controllers\subsystems\mobs.dm"
|
#include "code\controllers\subsystems\mobs.dm"
|
||||||
#include "code\controllers\subsystems\motion_tracker.dm"
|
#include "code\controllers\subsystems\motion_tracker.dm"
|
||||||
|
#include "code\controllers\subsystems\nerdle.dm"
|
||||||
#include "code\controllers\subsystems\nightshift.dm"
|
#include "code\controllers\subsystems\nightshift.dm"
|
||||||
#include "code\controllers\subsystems\overlays_ch.dm"
|
#include "code\controllers\subsystems\overlays_ch.dm"
|
||||||
#include "code\controllers\subsystems\overmap_renamer_vr.dm"
|
#include "code\controllers\subsystems\overmap_renamer_vr.dm"
|
||||||
@@ -4085,6 +4086,7 @@
|
|||||||
#include "code\modules\pda\core_apps.dm"
|
#include "code\modules\pda\core_apps.dm"
|
||||||
#include "code\modules\pda\messenger.dm"
|
#include "code\modules\pda\messenger.dm"
|
||||||
#include "code\modules\pda\messenger_plugins.dm"
|
#include "code\modules\pda\messenger_plugins.dm"
|
||||||
|
#include "code\modules\pda\nerdle.dm"
|
||||||
#include "code\modules\pda\pda.dm"
|
#include "code\modules\pda\pda.dm"
|
||||||
#include "code\modules\pda\pda_subtypes.dm"
|
#include "code\modules\pda\pda_subtypes.dm"
|
||||||
#include "code\modules\pda\pda_tgui.dm"
|
#include "code\modules\pda\pda_tgui.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user