From 317982ead0bbc9650112a23a63ab2f4d977ef131 Mon Sep 17 00:00:00 2001 From: Tk420634 Date: Wed, 15 Jan 2025 20:06:16 -0600 Subject: [PATCH] Dan rewrites special, part 1 --- code/__DEFINES/stats_and_skills.dm | 9 + .../hud/screen_objects/character_actions.dm | 14 +- .../subsystem/stats_attributes_skills.dm | 567 ++++++++++++++++++ code/modules/mob/living/living.dm | 3 + code/modules/mob/living/living_defines.dm | 1 + code/modules/mob/living/login.dm | 1 + code/modules/mob/living/skillcheck.dm | 478 +++------------ code/modules/mob/stats_n_skills.dm | 1 + icons/mob/screen_gen.dmi | Bin 131484 -> 131891 bytes modular_coyote/code/pmon_mob.dm | 1 + 10 files changed, 672 insertions(+), 403 deletions(-) create mode 100644 code/__DEFINES/stats_and_skills.dm create mode 100644 code/controllers/subsystem/stats_attributes_skills.dm create mode 100644 code/modules/mob/stats_n_skills.dm diff --git a/code/__DEFINES/stats_and_skills.dm b/code/__DEFINES/stats_and_skills.dm new file mode 100644 index 0000000000..3c336c0034 --- /dev/null +++ b/code/__DEFINES/stats_and_skills.dm @@ -0,0 +1,9 @@ +#define STAT_STR "Brawn" +#define STAT_PER "Awareness" +#define STAT_END "Toughness" +#define STAT_CHA "Moxie" +#define STAT_INT "Smarts" +#define STAT_AGI "Deftness" +#define STAT_LCK "Fate" +#define STAT_GEN "Flat Roll" +#define STAT_SUF "Crit" diff --git a/code/_onclick/hud/screen_objects/character_actions.dm b/code/_onclick/hud/screen_objects/character_actions.dm index e57721e5e8..d2cead1b12 100644 --- a/code/_onclick/hud/screen_objects/character_actions.dm +++ b/code/_onclick/hud/screen_objects/character_actions.dm @@ -291,13 +291,13 @@ /atom/movable/screen/roll_hud_button/Click(location,control,params,) // This stuff needs to be changed because it was directly lifted from clothing var/static/list/choices = list( - "Brawn" = image(icon = 'icons/obj/stationary.dmi', icon_state = "fitnessweight-w"), - "Awareness" = image(icon = 'icons/obj/status_display.dmi', icon_state = "ai_friend"), - "Toughness" = image(icon = 'modular_coyote/icons/objects/weapons.dmi', icon_state = "imperial_kite"), - "Moxie" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "mood9"), - "Smarts" = image(icon = 'modular_roguetown/items/books.dmi', icon_state = "ledger0"), - "Deftness" = image(icon = 'icons/obj/implants.dmi', icon_state = "warp"), - "Fate" = image(icon = 'icons/obj/economy.dmi', icon_state = "coin_iron_flip"), + "Brawn" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "brawn"), + "Awareness" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "awareness"), + "Toughness" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "toughness"), + "Moxie" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "moxie"), + "Smarts" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "smarts"), + "Deftness" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "deftness"), + "Fate" = image(icon = 'icons/mob/screen_gen.dmi', icon_state = "fate"), ) var/mob/user = usr var/choice = show_radial_menu(user, src, choices, radius = 32,) diff --git a/code/controllers/subsystem/stats_attributes_skills.dm b/code/controllers/subsystem/stats_attributes_skills.dm new file mode 100644 index 0000000000..dda0b13e87 --- /dev/null +++ b/code/controllers/subsystem/stats_attributes_skills.dm @@ -0,0 +1,567 @@ +/* + * File: stats_n_skills.dm + * Author: Bingfox + * + */ + +SUBSYSTEM_DEF(sas) + name = "SAS" + priority = FIRE_PRIORITY_MOBS + flags = SS_KEEP_TIMING | SS_NO_INIT + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + // master list of defaults + var/list/reference_stocks = list() + var/list/reference_stats = list() + var/list/reference_skills = list() + var/list/stat_invokers = list() + var/max_total_stats = 40 + // everyone's thingy! + var/list/sheets = list() + +/datum/controller/subsystem/sas/Initialize(start_timeofday) + build_statskills() + build_stocks() + . = ..() + +/datum/controller/subsystem/sas/proc/build_statskills() + for(var/skul in subtypesof(/datum/statskill)) + var/datum/statskill/S = new skul() + if(S.is_skill) + reference_skills[S.key] = S + if(S.is_stat) + reference_stats[S.key] = S + +/datum/controller/subsystem/sas/proc/build_stocks() + for(var/skul in subtypesof(/datum/stats_and_skills_holder)) + var/datum/stats_and_skills_holder/S = new skul() + reference_stocks[S.key] = S + +/datum/controller/subsystem/sas/proc/give_holder_to_player(someone) + var/p_quid = SSeconomy.extract_quid(someone) + if(LAZYACCESS(sheets, p_quid)) + return // already have their thing there! + var/mob/player = extract_mob(someone) + if(!player || player.sas_key == SAS_DEFAULT) + return + var/datum/stats_and_skills/SAS = new() + sheets["[p_quid]"] = SAS + SAS.set_player(p_quid) + SAS.load_stats() + player.sas_key = "[p_quid]" + +/datum/controller/subsystem/sas/proc/get_sas(someone) + var/mob/such = extract_mob(such) + if(!such) + return + var/datum/stats_and_skills/ses = LAZYACCESS(sheets, such.sas_key) + if(!ses) // invalid ses, give em a default (might be a player, that'll be fixed soon enuf) + such.sas_key = "default" + ses = LAZYACCESS(sheets, such.sas_key) + return ses + +/datum/controller/subsystem/sas/proc/get_stat(someone, which) + var/datum/stats_and_skills/ses = get_sas(someone) + return LAZYACCESS(ses.stats, which) + +/datum/controller/subsystem/sas/proc/do_roll(performer, stat, threshold, flags) + var/datum/stats_and_skills/doer_sass = get_sas(performer) + var/datum/roll_results/doer_roll = doer_sass.do_roll(stat, threshold, flags) + return doer_roll + +/datum/controller/subsystem/sas/proc/get_skills() + var/list/skullz = list() + for(var/skill in reference_skills) + var/datum/statskill/S = reference_skills[skill] + skullz += S.displayname + +/datum/controller/subsystem/sas/proc/get_stat_triggers() + var/list/skullz = list() + for(var/ivk in stat_invokers) + if(!islist(skullz[stat_invokers[ivk]])) + skullz[stat_invokers[ivk]] = list() + skullz[stat_invokers[ivk]] |= lowertext(ivk) + var/list/retmsg = list() + for(var/kind in skullz) + retmsg += "[kind]" + for(var/bingus in skullz[kind]) + retmsg += "[bingus]" + return retmsg.Join("\n") + +/datum/controller/subsystem/sas/proc/get_num_dice(dicetring) + var/list/splode = splode_dice(dicetring) + if(splode["bad"]) + return 1 + return numberfy(LAZYACCESS(splode, "DICE")) + +/datum/controller/subsystem/sas/proc/get_crit_success(dicetring) + var/list/splode = splode_dice(dicetring) + if(splode["bad"]) + return 20 + return numberfy(LAZYACCESS(splode, "SIDES")) + +/datum/controller/subsystem/sas/proc/get_crit_fail(dicetring) + return 1 + +/// Expects format: "NUMdNUM+NUM" +/datum/controller/subsystem/sas/proc/splode_dice(dicetring) + dicetring = lowertext(dicetring) + var/list/split1 = splittext(dicetring, "d") + var/numdice = LAZYACCESS(split1, 1) + if(numdice > 2) + return list("bad" = TRUE) + replacetext(LAZYACCESS(split1, 2), "+", "BBB") + replacetext(LAZYACCESS(split1, 2), "-", "BBB") + var/list/split2 = splittext(LAZYACCESS(split1, 2), "BBB") + if(LAZYLEN(split2) > 2) + return list("bad" = TRUE) + var/numsides = LAZYACCESS(split2, 1) + var/mod = LAZYACCESS(split2, 2) + . = list() + .["DICE"] = numdice || 0 + .["SIDES"] = numsides || 0, + .["MOD"] = mod || 0 + +/datum/stats_and_skills + var/stock_key + var/owner_quid + var/virgin = TRUE + var/list/stats = list( + STAT_STR = 5, + STAT_PER = 5, + STAT_END = 5, + STAT_CHA = 5, + STAT_INT = 5, + STAT_AGI = 5, + STAT_LCK = 5, + ) + var/list/skills = list() + var/max_total = 40 + +/datum/stats_and_skills/New() + . = ..() + var/list/nustats = list() + // first go through the stats and get our defaults + for(var/stat in SSsas.reference_stats) + var/datum/statskill/S = SSsas.reference_stats[stat] + var/datum/statskill/ours = new S.type() + if(stats[stat]) + ours.set_stat(stats[stat]) + nustats[ours.key] = ours + stats = nustats() + // now the skills + var/list/nuskills = list() + // first go through the stats and get our defaults + for(var/skill in SSsas.reference_skills) + var/datum/statskill/S = SSsas.reference_skills[skill] + var/datum/statskill/ours = new S.type() + if(skills[skill]) + ours.set_skill(skills[skill]) + nuskills[ours.key] = ours + skills = nuskills() + +/datum/stats_and_skills/proc/load_from_prefs() + if(!virgin) + return + virgin = FALSE + var/mob/plyr = extract_mob(smth) + if(!plyr) + return + var/datum/preferences/P = extract_prefs(plyr) + if(!P) + return + for(var/stat in stats) + var/datum/statskill/S = stats[stat] + S.load_from_prefs(P) + set_player(plyr) + if(hax()) // only applies to stats loaded from prefs + return + +/datum/stats_and_skills/proc/hax() + var/total = 0 + for(var/stat in stats) + var/datum/statskill/S = stats[stat] + total += S.current + if(total > SSsas.max_total_stats) + var/mob/master = get_owner() + if(master) + message_admins(span_alertalien("WEEOO WEEOO [master.name] ([master.ckey]) just spawned in with more than [max_total] stat points!!")) + master.gib() + return TRUE + +/datum/stats_and_skills/proc/set_player(mob/player) + owner_quid = SSeconomy.extract_quid(player) + +/datum/stats_and_skills/proc/do_roll(which, dice, threshold, flags = SAS_STAT | SAS_MODS) + if(!stats[which]) + return new /datum/roll_results() + if(!dice) + dice = "1d20" + var/datum/statskill/S = stats[which] + return S.rollstat(dice, threshold, flags) + +/datum/statskill // issue + var/key + var/is_skill = FALSE + var/is_stat = FALSE + var/displayname = "Stat" + var/default = 5 + var/maxval = 10 // only obeyed in the prefs menu! + var/minval = 1 + var/current = 1 + var/list/modifiers = list() + // hide from the prefs menu + var/hidden + /// rollmote stuff + var/list/rollmote_triggers = list() + var/list/rollmote_initial = list() + var/list/rollmote_success = list() + var/list/rollmote_success_crit = list( + "Ring-a-ding baby!", + "Wow!", + ) + var/list/rollmote_fail = list() + var/list/rollmote_fail_crit = list( + "OOF, what a spectacular failure!", + "The game was rigged from the start.", + ) + +/datum/statskill/New() + . = ..() + if(!SSsas.reference_stats[key]) + for(var/inv in rollmote_triggers) + SSsas.stat_invokers[lowertext(inv)] = key + SSsas.stat_invokers[key] = key // hue + SSsas.stat_invokers[lowertext(key)] = key // hue + SSsas.stat_invokers[displayname] = key // hue + SSsas.stat_invokers[lowertext(displayname)] = key // hue + +/datum/statskill/proc/set_stat(neval) + current = neval + +/datum/statskill/proc/rollstat(dice, threshold, flags) + dice = formattify_dice(dice) + var/datum/roll_return/RT = new() + var/mod = get_mofidiers() + // var/numdice = SSsas.get_num_dice(dice) + var/critsucc = SSsas.get_crit_success(dice) + var/critfail = SSsas.get_crit_fail(dice) + var/porm = mod >= 0 ? "+" : "-" + var/randroll = roll("[dice][porm][mod]") + RT.resultnum = randroll + RT.base = current + RT.mods = mod + RT.displayname = displayname + RT.pre_msg = formattify(safepick(rollmote_initial)) + if(!threshold || randroll >= threshold) + RT.passed = TRUE + RT.msg = formattify(safepick(rollmote_success)) + else + RT.passed = FALSE + RT.msg = formattify(safepick(rollmote_fail)) + if(randroll >= critsucc) + RT.crit_success = TRUE + RT.msg += " [formattify(safepick(rollmote_success_crit))]" + if(randroll <= critfail) + RT.crit_fail = TRUE + RT.msg += " [formattify(safepick(rollmote_success_fail))]" + return RT + +/datum/statskill/proc/formattify_dice(dice) + . = replacetext(dice, "$STATMODS", "[current + get_mods()]") + . = replacetext(dice, "$STAT", "[current]") + +/datum/statskill/proc/get_mods() + . = 0 + for(var/mod in modifiers) + . += modifiers[mod] + +/datum/statskill/strength + key = STAT_STR + displayname = "Strength" + is_stat = TRUE + rollmote_triggers = list( + "b" + "brn" + "brawn" + ) + rollmote_initial = list( + "%MOBNAME tests %MOBTHEIR brawn...", + "%MOBNAME flexes %MOBTHEIR arm(s)...", + "%MOBNAME prepares to lift...", + "%MOBNAME puts %MOBTHEIR back into it..." + ) + rollmote_success = list( + "%MOBNAME is strong!", + "%MOBNAME is beefy!", + "%MOBNAME has some serious guns!", + "%MOBNAME had some strength behind it!" + ) + rollmote_fail = list( + "%MOBNAME was too weak.", + "%MOBNAME was a little wet noodle.", + "%MOBNAME would loose an arm wrestling match with a mouse.", + "%MOBNAME has some serious atrophy. it's a wonder %MOBTHEY can move at all." + ) + +/datum/statskill/perception + key = STAT_PER + displayname = "Perception" + is_stat = TRUE + rollmote_triggers = list( + "a", + "aware", + "awareness", + ) + rollmote_initial = list( + "%MOBNAME takes a good, long look...", + "%MOBNAME squints...", + "%MOBNAME looks around...", + "%MOBNAME focuses in..." + ) + rollmote_success = list( + "%MOBNAME was perceptive!", + "%MOBNAME noticed things!", + "%MOBNAME has eyes like a hawk!", + "%MOBNAME could find Doc Mitchell's keys!", + "%MOBNAME noticed whatever %MOBTHEY were trying to see!" + ) + rollmote_fail = list( + "%MOBNAME was totally oblivious.", + "%MOBNAME forgot %MOBTHEIR glasses.", + "%MOBNAME didn't see anything." + ) + +/datum/statskill/endurance + key = STAT_END + displayname = "Endurance" + is_stat = TRUE + rollmote_triggers = list( + "tough", + "tuff", + "end", + "toughness", + ) + rollmote_initial = list( + "%MOBNAME tests %MOBTHEIR toughness...", + "%MOBNAME braces %MOBTHEMSELF..." + ) + rollmote_success = list( + "%MOBNAME was tough!", + "%MOBNAME was one tough cookie!", + "%MOBNAME doesn't even flinch!", + "%MOBNAME is solid as an oak!", + "%MOBNAME endured!" + ) + rollmote_fail = list( + "%MOBNAME is a floppy lil' noodle.", + "%MOBNAME is made of paper.", + "%MOBNAME would be torn to shreds by a light breeze.", + "%MOBNAME crumpled up and blew away." + ) + +/datum/statskill/charisma + key = STAT_CHA + displayname = "Charisma" + is_stat = TRUE + rollmote_triggers = list( + "mox", + "moxie", + "cha", + ) + rollmote_initial = list( + "%MOBNAME starts to be charismatic...", + "%MOBNAME puts on the charm..." + ) + rollmote_success = list( + "%MOBNAME was charismatic!", + "%MOBNAME is an absolute charmer!", + "%MOBNAME was good and charming!" + ) + rollmote_fail = list( + "%MOBNAME was totally uncharismatic.", + "%MOBNAME isn't fooling anyone.", + "%MOBNAME put %MOBTHEIR foot in %MOBTHEIR mouth.", + "%MOBNAME could hear a pin drop.", + "%MOBNAME's spaghetti is showing.", + "%MOBNAME had %MOBTHEIR charms fall flat." + ) + +/datum/statskill/intelligence + key = STAT_INT + displayname = "Intelligence" + is_stat = TRUE + rollmote_triggers = list( + "int", + "i", + "intelligence", + "inteligence", + "intelligance", + "inteligance", + "intel", + "intell", + "intelect", + "intellect", + "smart", + "smartness", + "nerd", + "nerdiness", + "dork", + "dorkiness", + "dweeb", + "dweebishness", + "smarts", + ) + rollmote_initial = list( + "%MOBNAME thinks hard...", + "%MOBNAME ponders hard...", + "%MOBNAME takes a moment to think...", + "%MOBNAME furrows %MOBTHEIR brow..." + ) + rollmote_success = list( + "%MOBNAME was clever!", + "%MOBNAME is a genius!", + "%MOBNAME has a mind sharp as a whip!", + "%MOBNAME had a thought!" + ) + rollmote_fail = list( + "%MOBNAME was dumb as a doornail.", + "%MOBNAME burned %MOBTHEIR last braincell years ago.", + "%MOBNAME is running low on braincells.", + "%MOBNAME is denser than a collapsed idiot." + ) + +/datum/statskill/agility + key = STAT_AGI + displayname = "Agility" + is_stat = TRUE + rollmote_triggers = list( + "agi", + "a", + "agility", + "agillity", + "quick", + "quickness", + "fast", + "fastness", + "dex", + "speed", + "speediness", + "initiative", + "athleticism", + "acrobatics", + "escape", + "dodge", + "evade", + "evasion", + "cat", + "deft", + "deftness", + ) + rollmote_initial = list( + "%MOBNAME tries to get agile...", + "%MOBNAME prepares %MOBTHEIR moves...", + "%MOBNAME starts to get limber..." + ) + rollmote_success = list( + "%MOBNAME was very flexible!", + "%MOBNAME had some excellent footwork!", + "%MOBNAME was in perfect control!", + "%MOBNAME was agile as a cat!", + "%MOBNAME was agile as a fox!" + ) + rollmote_fail = list( + "%MOBNAME fell flat on %MOBTHEIR face.", + "%MOBNAME fell flat on %MOBTHEIR back.", + "%MOBNAME triped over themself.", + "%MOBNAME has two left feet.", + "%MOBNAME was clumsy as a cat.", + "%MOBNAME was clumsy as a fox." + ) + +/datum/statskill/luck + key = STAT_LCK + displayname = "Luck" + is_stat = TRUE + rollmote_triggers = list( + "l", + "lck", + "luck", + "lick", + "lock", + "lunk", + "link", + "chance", + "fortune", + "dice", + "luk", + "luc", + "fat", + "fate", + ) + rollmote_initial = list( + "%MOBNAME tries %MOBTHEIR luck...", + "%MOBNAME takes a chance...", + "%MOBNAME puts it all on red..." + ) + rollmote_success = list( + "%MOBNAME lucked out!", + "%MOBNAME was the luckiest son-of-a-gun in the wasteland!", + "%MOBNAME could make a bullet turn right around and climb back into the gun!", + "%MOBNAME got lucky!" + ) + rollmote_fail = list( + "%MOBNAME was unlucky.", + "%MOBNAME realized %MOBTHEIR game was rigged from the start.", + "%MOBNAME showed that the house always wins." + ) + +/datum/statskill/basic + key = STAT_GEN + displayname = "Coinflip" + is_stat = TRUE + hidden = TRUE + rollmote_triggers = list( + "x", + "non", + "none", + "generic", + "something", + "else", + "smth", + "?", + "rand", + "huh", + "stuff", + "roll", + ) + rollmote_initial = list( + "%MOBNAME tests %MOBTHEIR skills...", + "%MOBNAME tries %MOBTHEIR skills...", + "%MOBNAME attempts to do a thing...", + "%MOBNAME puts %MOBTHEIR skills to the test..." + ) + rollmote_success = list( + "%MOBNAME succeeded!", + "%MOBNAME did it!" + ) + rollmote_fail = list( + "%MOBNAME was really bad at whatever they did.", + "%MOBNAME just really sucked.", + "%MOBNAME messed up real bad." + ) + +/datum/roll_return + var/base = 0 + var/crit_fail = FALSE + var/crit_success = FALSE + var/passed = FALSE + var/displayname = "Result" + var/mods = 0 + var/msg = "Something cool happened!" + var/resultnum = 0 + +///////////////////////////////////////////// +///////////////////////////////////////////// +/// our system of skills, attributes, and stats! +/mob/var/sas_key diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e84eb98fe8..aa342ee004 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -18,8 +18,10 @@ for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) diag_hud.add_to_hud(src) faction += "[REF(src)]" + init_SAS() GLOB.mob_living_list += src clienthud.add_hud_to(src) + if(coolshadow) add_filter("cool_shadow",10, list( "type"="drop_shadow", @@ -67,6 +69,7 @@ ranged_ability.remove_ranged_ability(src) if(buckled) buckled.unbuckle_mob(src,force=1) + QDEL_NULL(SAS) remove_from_all_data_huds() GLOB.mob_living_list -= src diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 49b2c6e674..876528130e 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -179,3 +179,4 @@ var/icon_resting var/coolshadow = TRUE + diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 3c7d8945fd..e1668395d9 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -31,3 +31,4 @@ hud_client_check() SSstatpanels.collect_horny_demographic(src) + SSsas. diff --git a/code/modules/mob/living/skillcheck.dm b/code/modules/mob/living/skillcheck.dm index fe0fdd95ff..a93d09605d 100644 --- a/code/modules/mob/living/skillcheck.dm +++ b/code/modules/mob/living/skillcheck.dm @@ -1,290 +1,51 @@ -#define EMOTE_SPECIAL_STR "Brawn" -#define EMOTE_SPECIAL_PER "Awareness" -#define EMOTE_SPECIAL_END "Toughness" -#define EMOTE_SPECIAL_CHA "Moxie" -#define EMOTE_SPECIAL_INT "Smarts" -#define EMOTE_SPECIAL_AGI "Deftness" -#define EMOTE_SPECIAL_LCK "Fate" -#define EMOTE_SPECIAL_GEN "Flat Roll" -#define EMOTE_SPECIAL_SUF "Crit" GLOBAL_LIST_INIT(special_skill_list, list( - EMOTE_SPECIAL_STR, - EMOTE_SPECIAL_PER, - EMOTE_SPECIAL_END, - EMOTE_SPECIAL_CHA, - EMOTE_SPECIAL_INT, - EMOTE_SPECIAL_AGI, - EMOTE_SPECIAL_LCK, - EMOTE_SPECIAL_GEN)) - -GLOBAL_LIST_INIT(special_triggers, list( - EMOTE_SPECIAL_STR = list( - "b", - "brn", - "brawn", - ), - EMOTE_SPECIAL_PER = list( - "a", - "aware", - "awareness", - ), - EMOTE_SPECIAL_END = list( - "tough", - "tuff", - "end", - "toughness", - ), - EMOTE_SPECIAL_CHA = list( - "mox", - "moxie", - "Cha", - ), - EMOTE_SPECIAL_INT = list( - "int", - "i", - "intelligence", - "inteligence", - "intelligance", - "inteligance", - "intel", - "intell", - "intelect", - "intellect", - "smart", - "smartness", - "nerd", - "nerdiness", - "dork", - "dorkiness", - "dweeb", - "dweebishness", - "smarts", - ), - EMOTE_SPECIAL_AGI = list( - "agi", - "a", - "agility", - "agillity", - "quick", - "quickness", - "fast", - "fastness", - "dex", - "speed", - "speediness", - "initiative", - "athleticism", - "acrobatics", - "escape", - "dodge", - "evade", - "evasion", - "cat", - "deft", - "deftness", - ), - EMOTE_SPECIAL_LCK = list( - "l", - "lck", - "luck", - "lick", - "lock", - "lunk", - "link", - "chance", - "fortune", - "dice", - "luk", - "luc", - "fat", - "fate", - ), - EMOTE_SPECIAL_GEN = list( - "x", - "non", - "none", - "generic", - "something", - "else", - "smth", - "?", - "rand", - "huh", - "stuff", - "roll"))) - -GLOBAL_LIST_INIT(special_phrases, list( - EMOTE_SPECIAL_STR = list( - "initial" = list( - "tests their brawn...", - "flexes their arm(s)...", - "prepares to lift...", - "puts their back into it..."), - "success" = list( - "is strong!", - "is beefy!", - "has some serious guns!", - "had some strength behind it!"), - "failure" = list( - "was too weak.", - "was a little wet noodle.", - "would loose an arm wrestling match with a mouse.", - "has some serious atrophy. it's a wonder they can move at all.")), - EMOTE_SPECIAL_PER = list( - "initial" = list( - "takes a good, long look...", - "squints...", - "looks around...", - "focuses in..."), - "success" = list( - "was perceptive!", - "noticed things!", - "has eyes like a hawk!", - "could find Doc Mitchell's keys!", - "noticed whatever they were trying to see!"), - "failure" = list( - "was totally oblivious.", - "forgot their glasses.", - "didn't see anything.")), - EMOTE_SPECIAL_END = list( - "initial" = list( - "tests their toughness...", - "braces themself..."), - "success" = list( - "was tough!", - "was one tough cookie!", - "doesn't even flinch!", - "is solid as an oak!", - "endured!"), - "failure" = list( - "is a floppy lil' noodle.", - "is made of paper.", - "would be torn to shreds by a light breeze.", - "crumpled up and blew away.")), - EMOTE_SPECIAL_CHA = list( - "initial" = list( - "starts to be charismatic...", - "puts on the charm..."), - "success" = list( - "was charismatic!", - "is an absolute charmer!", - "was good and charming!"), - "failure" = list( - "was totally uncharismatic.", - "isn't fooling anyone.", - "put their foot in their mouth.", - "could hear a pin drop.", - "miiiiight have some frontal lobe damage.", - "had their charms fall flat.")), - EMOTE_SPECIAL_INT = list( - "initial" = list( - "thinks hard...", - "ponders hard...", - "takes a moment to think...", - "furrows their brow..."), - "success" = list( - "was clever!", - "is a genius!", - "has a mind sharp as a whip!", - "had a thought!"), - "failure" = list( - "was dumb as a doornail.", - "burned their last braincell years ago.", - "is running low on braincells.", - "was dense as a brick.")), - EMOTE_SPECIAL_AGI = list( - "initial" = list( - "tries to get agile...", - "prepares their moves...", - "starts to get limber..."), - "success" = list( - "was very flexible!", - "had some excellent footwork!", - "was in perfect control!", - "was agile as a cat!", - "was agile as a fox!"), - "failure" = list( - "fell flat on their face.", - "fell flat on their back.", - "triped over themself.", - "has two left feet.", - "was clumsy as a cat.", - "was clumsy as a fox.")), - EMOTE_SPECIAL_LCK = list( - "initial" = list( - "tries their luck...", - "takes a chance...", - "puts it all on red..."), - "success" = list( - "lucked out!", - "was the luckiest son-of-a-gun in the wasteland!", - "could make a bullet turn right around and climb back into the gun!", - "got lucky!"), - "failure" = list( - "was unlucky.", - "realized their game was rigged from the start.", - "showed that the house always wins.")), - EMOTE_SPECIAL_GEN = list( - "initial" = list( - "tests their skills...", - "tries their skills...", - "attempts to do a thing...", - "puts their skills to the test..."), - "success" = list( - "succeeded!", - "did it!"), - "failure" = list( - "was really bad at whatever they did.", - "just really sucked.", - "messed up real bad.")), - EMOTE_SPECIAL_SUF = list( - "initial" = list( - "shouldnt see this lol"), - "success" = list( - "Ring-a-ding baby!", - "Wow!"), - "failure" = list( - "How could someone mess up so badly?", - "The game was rigged from the start.")))) - -/mob/living/verb/emote_special_str() + STAT_STR, + STAT_PER, + STAT_END, + STAT_CHA, + STAT_INT, + STAT_AGI, + STAT_LCK, + STAT_GEN)) + +/mob/living/verb/STAT_str() set name = "Roll Brawn" set desc = "Roll for bicep circumfrence." set category = "Roleplaying" emote("special_strength") -/mob/living/verb/emote_special_per() +/mob/living/verb/STAT_per() set name = "Roll Awareness" set desc = "Roll for eyeball circumfrence." set category = "Roleplaying" emote("special_perception") -/mob/living/verb/emote_special_end() +/mob/living/verb/STAT_end() set name = "Roll Toughness" set desc = "Roll for heart circumfrence." set category = "Roleplaying" emote("special_endurance") -/mob/living/verb/emote_special_cha() +/mob/living/verb/STAT_cha() set name = "Roll Moxie" set desc = "Roll for beauty circumfrence." set category = "Roleplaying" emote("special_charisma") -/mob/living/verb/emote_special_int() +/mob/living/verb/STAT_int() set name = "Roll Smarts" set desc = "Roll for brain circumfrence." set category = "Roleplaying" emote("special_intelligence") -/mob/living/verb/emote_special_agi() +/mob/living/verb/STAT_agi() set name = "Roll Deftness" set desc = "Roll for wiggly circumfrence." set category = "Roleplaying" emote("special_agility") -/mob/living/verb/emote_special_luc() +/mob/living/verb/STAT_luc() set name = "Roll Fate" set desc = "Roll for some sort of circumfrence." set category = "Roleplaying" @@ -302,31 +63,31 @@ GLOBAL_LIST_INIT(special_phrases, list( /datum/emote/living/special/s key = "special_strength" - special_override = EMOTE_SPECIAL_STR + special_override = STAT_STR /datum/emote/living/special/p key = "special_perception" - special_override = EMOTE_SPECIAL_PER + special_override = STAT_PER /datum/emote/living/special/e key = "special_endurance" - special_override = EMOTE_SPECIAL_END + special_override = STAT_END /datum/emote/living/special/c key = "special_charisma" - special_override = EMOTE_SPECIAL_CHA + special_override = STAT_CHA /datum/emote/living/special/i key = "special_intelligence" - special_override = EMOTE_SPECIAL_INT + special_override = STAT_INT /datum/emote/living/special/a key = "special_agility" - special_override = EMOTE_SPECIAL_AGI + special_override = STAT_AGI /datum/emote/living/special/l key = "special_luck" - special_override = EMOTE_SPECIAL_LCK + special_override = STAT_LCK /datum/emote/living/special/run_emote(mob/user, params, type_override, intentional = FALSE) if(!can_run_emote(user, TRUE, intentional)) @@ -338,54 +99,28 @@ GLOBAL_LIST_INIT(special_phrases, list( to_chat(user, "You cannot send IC messages (muted).") return FALSE - if(isnull(user.special_a)) - to_chat(user, span_phobia("You arent special.")) - to_chat(user, span_notice("Mainly because you're playing a mob withough any special skills. This is probably a bug~")) - return FALSE - - var/special_noun = null var/special_phrase_input = special_override ? lowertext(special_override) : lowertext(params) + var/datum/statskill/SK = SSsas.get_stat_by_trigger(special_phrase_input) - for(var/which_special in GLOB.special_skill_list) - /// if the thing we said after the emote is in one of these lists, pick the corresponding key - if(special_phrase_input in GLOB.special_triggers[which_special]) - special_noun = which_special - - if(!(special_noun in GLOB.special_skill_list) || !special_noun) - to_chat(user, span_alert("That's not a valid SPECIAL stat!")) + if(!SK) + to_chat(user, span_alert("That's not a valid stat!")) to_chat(user, span_notice("To use this emote, type '*special' followed by a SPECIAL stat. For instance, '*special luck' will do a (luck*10)% roll and say if you passed or not.")) - var/valid_specials - for(var/word in GLOB.special_triggers) - valid_specials += "[GLOB.special_triggers[word][1]], " - valid_specials += "[GLOB.special_triggers[word][2]]. " + var/valid_specials = SSsas.get_stat_triggers() to_chat(user, span_notice("Some of the valid SPECIAL keywords are:[valid_specials].")) return - - var/special_skill = null - switch(special_noun) - if(EMOTE_SPECIAL_STR) - special_skill = user.special_s - if(EMOTE_SPECIAL_PER) - special_skill = user.special_p - if(EMOTE_SPECIAL_END) - special_skill = user.special_e - if(EMOTE_SPECIAL_CHA) - special_skill = user.special_c - if(EMOTE_SPECIAL_INT) - special_skill = user.special_i - if(EMOTE_SPECIAL_AGI) - special_skill = user.special_a - if(EMOTE_SPECIAL_LCK) - special_skill = user.special_l - if(EMOTE_SPECIAL_GEN) // generic random 50% chance - special_skill = 5 - - var/first_phrase = pick(GLOB.special_phrases[special_noun]["initial"]) - var/message_first = span_notice("\[[special_noun], [special_skill]0%] [user] [first_phrase].") // [Luck, 100%] User tests their Luck. - - user.visible_message( + + var/init_message = SK.get_rollmote_initial_msg(user) + var/datum/roll_return/RT = SSsas.do_roll(user, SK.key, "1d20", 15) + var/modshow = "" + if(modshow > 0) + modshow = "+[RT.mods]" + if(modshow < 0) + modshow = "[RT.mods]" + var/message_first = span_notice("\[[SK.displayname], 1d20+[RT.base][modshow] DC 15] [user] [RT.pre_msg].") // [Luck, 100%] User tests their Luck. + var/turf/T = get_turf(user) + + T.visible_message( message = message_first, - self_message = message_first, blind_message = message_first) user.emote_for_ghost_sight(message_first) @@ -397,26 +132,20 @@ GLOBAL_LIST_INIT(special_phrases, list( if(!can_run_emote(user, TRUE,intentional)) return - var/message_second - if(prob(special_skill * 10)) - var/success_phrase = pick(GLOB.special_phrases[special_noun]["success"]) - if(prob(5)) // crit success! - success_phrase += " [pick(GLOB.special_phrases[EMOTE_SPECIAL_SUF]["success"])]" - message_second = span_green("\[Success\] [user] [success_phrase]") // [Success] User is pretty lucky! + var/message_second = RT.msg + if(RT.passed) + message_second = span_green(message_second) else - var/fail_phrase = pick(GLOB.special_phrases[special_noun]["failure"]) - if(prob(5)) // crit fail! - fail_phrase += " [pick(GLOB.special_phrases[EMOTE_SPECIAL_SUF]["failure"])]" - message_second = span_red("\[Failure\] [user] [fail_phrase]") // [Failure} User isn't very lucky... + message_second = span_red(span_green(message_second)) - user.visible_message( + T.visible_message( message = message_second, - self_message = message_second, blind_message = message_second) user.emote_for_ghost_sight(message_second) - +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// /datum/emote/living/rollfor key = "rollfor" @@ -438,47 +167,32 @@ GLOBAL_LIST_INIT(special_phrases, list( var/paramlist = splittext(params, " ") var/skill_name - for(var/which_special in GLOB.special_skill_list) - /// if the thing we said after the emote is in one of these lists, pick the corresponding key - if(paramlist[1] in GLOB.special_triggers[which_special]) - skill_name = which_special + var/special_phrase_input = LAZYACCESS(paramlist, 1) + var/datum/statskill/SK = SSsas.get_stat_by_trigger(special_phrase_input) - if(!(skill_name in GLOB.special_skill_list) || !skill_name) - to_chat(user, span_alert("That's not a valid SPECIAL stat!")) + if(!SK) + to_chat(user, span_alert("That's not a valid stat!")) to_chat(user, span_notice("To use this emote, type '*special' followed by a SPECIAL stat. For instance, '*special luck' will do a (luck*10)% roll and say if you passed or not.")) - var/valid_specials - for(var/word in GLOB.special_triggers) - valid_specials += "[GLOB.special_triggers[word][1]], " - valid_specials += "[GLOB.special_triggers[word][2]]. " - to_chat(user, span_notice("Some of the valid SPECIAL keywords are:[valid_specials].")) + var/valid_specials = SSsas.get_stat_triggers() + to_chat(user, span_notice("Some of the valid SPECIAL keywords are:\n[valid_specials].")) return - var/skill = null - switch(skill_name) - if(EMOTE_SPECIAL_STR) - skill = user.special_s - if(EMOTE_SPECIAL_PER) - skill = user.special_p - if(EMOTE_SPECIAL_END) - skill = user.special_e - if(EMOTE_SPECIAL_CHA) - skill = user.special_c - if(EMOTE_SPECIAL_INT) - skill = user.special_i - if(EMOTE_SPECIAL_AGI) - skill = user.special_a - if(EMOTE_SPECIAL_LCK) - skill = user.special_l - if(EMOTE_SPECIAL_GEN) // flat roll - skill = 0 - var/dice = paramlist[2] - if(!roll(dice)) + if(isnull(roll(dice))) return - var/first_phrase = pick(GLOB.special_phrases[skill_name]["initial"]) - var/message_first = span_notice("\[[skill_name], [dice]+[skill]\] [user] [first_phrase].") // [Luck, 1d20+5] Player tests their luck. - user.visible_message( + var/init_message = SK.get_rollmote_initial_msg(user) + var/datum/roll_return/RT = SSsas.do_roll(user, SK.key, dice) + var/first_phrase = RT.msg_pre + var/modshow = "" + if(modshow > 0) + modshow = "+[RT.mods]" + if(modshow < 0) + modshow = "[RT.mods]" + var/turf/T = get_turf(user) + + var/message_first = span_notice("\[[SK.displayname], [dice]+[RT.base][modshow]\] [user] [first_phrase].") // [Luck, 1d20+5] Player tests their luck. + T.visible_message( message = message_first, self_message = message_first, blind_message = message_first) @@ -492,17 +206,20 @@ GLOBAL_LIST_INIT(special_phrases, list( if(!can_run_emote(user, TRUE,intentional)) return - var/result_message = span_notice("[user] rolled [roll(dice)+skill]!") - user.visible_message( + var/result_message = span_notice("[user] rolled [RT.resultnum]!") + T.visible_message( message = result_message, self_message = result_message, blind_message = result_message) user.emote_for_ghost_sight(result_message) + +////////////////////////////////////////////////// +////////////////////////////////////////////////// /mob/living/verb/suggest_skillcheck(mob/living/target) set category = "Roleplaying" set name = "Suggest Skillcheck" - var/skill = input(usr, "Which skill?", "Skill Suggester 9000", null) as null|anything in GLOB.special_skill_list + var/skill = input(usr, "Which skill?", "Skill Suggester 9000", null) as null|anything in SSsas.get_skills() if(isnull(skill)) return to_chat(target, span_info("[usr.name] would like you to perform a [skill] check.")) @@ -511,13 +228,13 @@ GLOBAL_LIST_INIT(special_phrases, list( set category = "Roleplaying" set name = "Skill Contest" // decide skill - var/skill = input(usr, "Which skill?", "Skill Chooser 9001", null) as null|anything in GLOB.special_skill_list + var/skill = input(usr, "Which skill?", "Skill Chooser 9001", null) as null|anything in SSsas.get_skills() if(isnull(skill)) return // decide the contest var/dice = input(usr, "What kind of dice? (ex: 1d20) \nIf nothing happens, you probably typed this wrong.", null) as null|text - if(!roll(dice)) + if(isnull(roll(dice))) return // get consent var/consent = alert(target, "[usr.name] would like to compete in a [dice] [skill] contest.",, "Agree", "Deny") @@ -525,51 +242,20 @@ GLOBAL_LIST_INIT(special_phrases, list( to_chat(usr, span_info("[target.name] doesn't seem like they want to participate in a contest.")) return - // run contest - var/usr_skill = 0 - var/target_skill = 0 - switch(skill) - if(EMOTE_SPECIAL_STR) - usr_skill = usr.special_s - target_skill = target.special_s - if(EMOTE_SPECIAL_PER) - usr_skill = usr.special_p - target_skill = target.special_p - if(EMOTE_SPECIAL_END) - usr_skill = usr.special_e - target_skill = target.special_e - if(EMOTE_SPECIAL_CHA) - usr_skill = usr.special_c - target_skill = target.special_c - if(EMOTE_SPECIAL_INT) - usr_skill = usr.special_i - target_skill = target.special_i - if(EMOTE_SPECIAL_AGI) - usr_skill = usr.special_a - target_skill = target.special_a - if(EMOTE_SPECIAL_LCK) - usr_skill = usr.special_l - target_skill = target.special_l - - var/usr_result = roll(dice) + usr_skill - var/target_result = roll(dice) + target_skill - - - var/winner - var/winner_result - var/loser - var/loser_result - - if(usr_result > target_result) + var/datum/statskill/SK = SSsas.get_stat_by_trigger(skill) + var/datum/return_roll/my_roll = SSsas.do_roll(usr, SK.key, dice) + var/datum/return_roll/their_roll = SSsas.do_roll(target, SK.key, dice) + + if(my_roll.resultnum > their_roll.resultnum) winner = usr - winner_result = usr_result + winner_result = my_roll.resultnum loser = target - loser_result = target_result + loser_result = their_roll.resultnum else winner = target - winner_result = target_result + winner_result = their_roll.resultnum loser = usr - loser_result = usr_result + loser_result = my_roll.resultnum to_chat(winner, span_green("You won the [skill] contest! ([winner_result] vs [loser_result])")) to_chat(loser, span_alert("You lost the [skill] contest! ([loser_result] vs [winner_result])")) diff --git a/code/modules/mob/stats_n_skills.dm b/code/modules/mob/stats_n_skills.dm new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/code/modules/mob/stats_n_skills.dm @@ -0,0 +1 @@ + diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 2fd373ed59f670d35b3f3df379f87f0d4bc8c654..26a0fb8cd677251703043d7374690f8232860733 100644 GIT binary patch delta 21653 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 e1nI5hXFQlp5zfX8|h2VejbbRi5*WEMPn) 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

_ z64Du^E{iVFdhcc7x{S!8y>pA_JvfXmfyuIM8P-0?eLWbBYMSYNMG8rTXH`%B{t>Xw zFHd;6v3Daz0!uSX*a4^w&3J1tV4xtT?s`5c`@FjR;N5q!H`5N+luQvqmTDRPo<_5F zs>mHMYmKFVXcYyO3_z2@4M_m$uZxREhJ`RrW0iLC*>Omjoxlf{joXcr!NC+w3pB%K zSpalNf!+p}lCiw9a6a#1??q0(jZohg+&+WJ$c+mR<5{i z#D~+liDc`K!pPTy+bUfKn`Zq{7LE^8XS=A$Tk}1_25)>09QQ(e4_}kEQyW_IBssRc z=8jzgJz-?&%)?am>*B4z%=%XylD}i{2j3Z=@pBEBR|yjrFyJ?CzmrVWE0upvHP(Nf z$zY0i@?)o1SR|Dbl`>dvgX$BJ#cK4G%LR2aPrWo4X{@3g9Czm!g I>p4I9AD_GHDF6Tf diff --git a/modular_coyote/code/pmon_mob.dm b/modular_coyote/code/pmon_mob.dm index ca5be691ee..d2f63a3abf 100644 --- a/modular_coyote/code/pmon_mob.dm +++ b/modular_coyote/code/pmon_mob.dm @@ -38,6 +38,7 @@ dextrous_hud_type = /datum/hud/dextrous/drone //Need this to have the hands appear on the HUD held_items = list(null, null) + sas_key = null // prevent sassery ///The pokemon-types that this mob has. Used to auto-generate moves(abilities) and some other attributes. var/list/p_types = list() ///Moves that aren't automatically granted based on their type. Will be assigned during Initialize()