Ports a character customization option: Quirks (#28388)

* Makes the datum

* Initial Commit

* Gets TGUI menu not crashing

* Autodoc

* quirk menu bugged

* oh.

* Working menu + buttons

* trait defintes pt 1/?

* Moves traits around

* ACTUALLY START ON THE QUIRKS THEMSELVES

* TGUI Bundle Rebuild

* TGUI properly saves now

* Removes allergies for scope reasons, make foreigner work properly

* TGUI tweaks

* Reworks TGUI Menu

* quirks store the mob, not mind

* Adds asthma and mute

* minor tweaks

* Cloning re-adds quirks

* Adds functionality to frail

* Adds crafty

* TGUI fix

* Fixes a frail bug

* Makes sure the list is in the correct format

* TGUI size change

* Makes skittish work

* Adds glutton, removes unused traits

* Changes description and adds function to glutton

* Freerunner functioning

* Crafty buff

* Clear quirk list when changing species

* Forgot to remove light step

* Delete

* Refactor item-giving

* TGUI Bundle Rebuild

* whoops

* Apply quirks when changing species

* Removes some unneeded defines/paths

* Replaces improved charging cord with a bad charger

* coment

* Guard clause

* Changes how quirks add and remove organs

* unused var

* adding organs works, removing them doesn't yet

* oh that fixed it

* Hopefully finally once and for all fix the json issues

* Buffs asthma

* switches the processor to ssobj since it's slower

* actually spawns the items whoops

* maybe actually fixes json issues I really hope this doesn't come up again?

* moves sql to the right directory

* CULPRIT FOUND, JSON ISSUES ACTUALLY SOLVED

* adds admin tooling for quirks

* Ups the cost of lungs

* Adds removal for the drinking ones

* Fixes some duplicate code

* Removing foreigner works

* wops

* bumps sql version to 65

* prettier

* semicolon

* Foreigners can understand galcomm but not speak it, as per headmin request

* Different solution was agreed upon

* CC announcements now get auto-translated

* Apply suggestions from code review

Lewc quick suggestions

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* Move alcohol tolerance basetype

* accomodates for reset_styles

* Swap to species flags, and being dead is a universal process stopper

* adds a foreigner trait

* Xenos and the like can't understand CC's translated announcements

* TGUI Bundle Rebuild

* Lewc quick fixes

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>

* i forgor

* i forgor pt 2

* process properly returns true

* TGUI Bundle Rebuild

* sql update for fixing merge conflicts

* bundle changes

* actual sql fix

* Not test tiny in prod

* sql fix?

* tgui update, first pass

* Adds schema changes to main quirk branch

* persistent data works now

* TGUI Bundle Rebuild

* Fixes conflict with job assignment datumization

* TGUI Bundle Rebuild

* Adds pacifism by request, -3 points

* gives skittish a small cd

* Makes the lunch randomizer  I was thinking about doing

* GC returns a qdel hint now

* Removes hard refs

* SQL save fix

* Fixes admin tools

* Fixes wizards getting quirked up

* ragin too

* Lightweight is more lightweight

* Adds admin logging for when someone makes a languagesless character

* TGUI Bundle Rebuild

* Adds colorblind, hungry, and buffs asthma

* fixed vv post-merge conflict

* behold, my monster

* rebuild and merge master

* Adds more positive quirks, and makes monochrome give more points

* adds nearsighted, and no whispering

* sorry linter

* Adds the cool quirk, thanks to pumpkin312

* Oh dear that signal gets sent to everyone every time someone spawns in

* i forgot that slimes dont have eyes

* tgui fix

* bundle rebuild probably

* prettier

* prettier

* Skittish package fix

* force add bundle

* Makes plasmemes be unable to take foreigner

* Makes advanced lungs respect the owner's species

* makes breaking open wrapped crates/lockers a do_after_once

* Makes plasmeme/vox advanced lungs actually help

* You get glasses anyway whoops

* bundle rebuild

---------

Signed-off-by: BiancaWilkson <42818125+BiancaWilkson@users.noreply.github.com>
Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: warriorstar-orion <orion@snowfrost.garden>
This commit is contained in:
BiancaWilkson
2025-11-04 00:18:52 +00:00
committed by GitHub
co-authored by Luc Burzah warriorstar-orion
parent 99d57fd35d
commit d558a69583
49 changed files with 971 additions and 78 deletions
+41 -5
View File
@@ -110,6 +110,8 @@
var/runechat_color = "#FFFFFF"
/// The ringtone their PDA should start with
var/pda_ringtone
/// A list/JSON of the quirk datums to attach to the character
var/list/quirks = list()
// Fuckery to prevent null characters
/datum/character_save/New()
@@ -131,6 +133,8 @@
playertitlelist = list2params(player_alt_titles)
if(length(loadout_gear))
gearlist = json_encode(loadout_gear)
if(islist(quirks))
quirks = json_encode(quirks)
var/datum/db_query/firstquery = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey ORDER BY slot", list(
"ckey" = C.ckey
@@ -221,7 +225,8 @@
runechat_color=:runechat_color,
cyborg_brain_type=:cyborg_brain_type,
body_type=:body_type,
pda_ringtone=:pda_ringtone
pda_ringtone=:pda_ringtone,
quirks=:quirks
WHERE ckey=:ckey
AND slot=:slot"}, list(
// OH GOD SO MANY PARAMETERS
@@ -286,7 +291,8 @@
"cyborg_brain_type" = cyborg_brain_type,
"pda_ringtone" = pda_ringtone,
"ckey" = C.ckey,
"slot" = slot_number
"slot" = slot_number,
"quirks" = quirks
))
if(!query.warn_execute())
@@ -325,7 +331,7 @@
player_alt_titles,
disabilities, organ_data, rlimb_data, nanotrasen_relation, physique, height, speciesprefs,
socks, body_accessory, gear, autohiss,
hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type, pda_ringtone)
hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type, pda_ringtone, quirks)
VALUES
(:ckey, :slot, :metadata, :name, :be_random_name, :gender,
:age, :species, :language,
@@ -352,7 +358,7 @@
:playertitlelist,
:disabilities, :organ_list, :rlimb_list, :nanotrasen_relation, :physique, :height, :speciesprefs,
:socks, :body_accessory, :gearlist, :autohiss_mode,
:h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type, :pda_ringtone)
:h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type, :pda_ringtone, :quirks)
"}, list(
// This has too many params for anyone to look at this without going insae
"ckey" = C.ckey,
@@ -416,7 +422,8 @@
"custom_emotes" = json_encode(custom_emotes),
"runechat_color" = runechat_color,
"cyborg_brain_type" = cyborg_brain_type,
"pda_ringtone" = pda_ringtone
"pda_ringtone" = pda_ringtone,
"quirks" = quirks
))
if(!query.warn_execute())
@@ -512,6 +519,8 @@
body_type = query.item[60]
pda_ringtone = query.item[61]
quirks = query.item[62]
//Sanitize
var/datum/species/SP = GLOB.all_species[species]
if(!SP)
@@ -599,6 +608,7 @@
runechat_color = sanitize_hexcolor(runechat_color)
cyborg_brain_type = sanitize_inlist(cyborg_brain_type, GLOB.borg_brain_choices, initial(cyborg_brain_type))
pda_ringtone = sanitize_inlist(pda_ringtone, GLOB.pda_ringtone_choices, initial(pda_ringtone))
quirks = sanitize_json(quirks)
if(!player_alt_titles)
player_alt_titles = new()
if(!organ_data)
@@ -1885,6 +1895,11 @@
character.set_species(S.type, delay_icon_update = TRUE) // Yell at me if this causes everything to melt
if(be_random_name)
real_name = random_name(gender, species)
var/balance_check = rebuild_quirks()
for(var/datum/quirk/to_add in quirks)
to_add.apply_quirk_effects(character)
if(balance_check > 0)
log_debug("[src] spawned in with more quirks than they should have been able to. Quirk balance of [balance_check].")
character.add_language(language)
character.real_name = real_name
@@ -2135,6 +2150,9 @@
if(job.barred_by_disability(user.client))
html += "<del class='dark'>[rank]</del></td><td class='bad'><b> \[DISABILITY\]</b></td></tr>"
continue
if(job.barred_by_quirk(user.client))
html += "<del class='dark'>[rank]</del></td><td class='bad'><b> \[QUIRK\]</b></td></tr>"
continue
if(job.barred_by_missing_limbs(user.client))
html += "<del class='dark'>[rank]</del></td><td class='bad'><b> \[MISSING LIMBS\]</b></td></tr>"
continue
@@ -2274,3 +2292,21 @@
custom_emotes[custom_emote.name] = emote_text
return custom_emotes
/*
* This serves two purposes. It tallies up and returns the total quirk balance of the current loadout
* It also rebuilds then entire list of quirks, converting the JSON format it could be into a usable datum.
*/
/datum/character_save/proc/rebuild_quirks()
var/point_total = 0
if(!islist(quirks)) // If it's not a normal list then it has to be JSON. Or something went horribly wrong.
quirks = json_decode(quirks)
var/list/quirk_cache = quirks.Copy()
quirks.Cut()
for(var/quirk_name in quirk_cache)
var/datum/quirk/chosen_quirk = GLOB.quirk_paths["[quirk_name]"]
var/datum/quirk/quirk = new chosen_quirk.type // Don't want hard refs to the global list
if(!quirk)
continue
point_total += quirk.cost
quirks += quirk
return point_total