mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 07:57:00 +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
|
||||
#define GENERAL_PROTECT_DATUM(Path)\
|
||||
##Path/can_vv_get(var_name){\
|
||||
.=..();\
|
||||
return FALSE;\
|
||||
}\
|
||||
##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
|
||||
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))
|
||||
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
|
||||
|
||||
/datum/proc/can_vv_get(var_name)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(var_name == NAMEOF(src, vars))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/client
|
||||
var/datum/managed_browser/feedback_form/feedback_form = null
|
||||
|
||||
/client/can_vv_get(var_name)
|
||||
return var_name != NAMEOF(src, feedback_form) // No snooping.
|
||||
/client/can_vv_get(var_name)//no snooping but doesn't break shit
|
||||
if(var_name == NAMEOF(src, feedback_form))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
GENERAL_PROTECT_DATUM(/datum/managed_browser/feedback_form)
|
||||
|
||||
|
||||
@@ -389,7 +389,7 @@
|
||||
|
||||
/mob/living/carbon/human/can_fall()
|
||||
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
|
||||
/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/manifest,
|
||||
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/flashlight)
|
||||
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\mobs.dm"
|
||||
#include "code\controllers\subsystems\motion_tracker.dm"
|
||||
#include "code\controllers\subsystems\nerdle.dm"
|
||||
#include "code\controllers\subsystems\nightshift.dm"
|
||||
#include "code\controllers\subsystems\overlays_ch.dm"
|
||||
#include "code\controllers\subsystems\overmap_renamer_vr.dm"
|
||||
@@ -4085,6 +4086,7 @@
|
||||
#include "code\modules\pda\core_apps.dm"
|
||||
#include "code\modules\pda\messenger.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_subtypes.dm"
|
||||
#include "code\modules\pda\pda_tgui.dm"
|
||||
|
||||
Reference in New Issue
Block a user