Paicontroller subsystem port (#19165)

* to subsystem

* wip subsystem pain

* some big recoding

* seperated

* oop

* fucking lua

* working on tgui foundation

* compile fixes

* nice and clean

* type

* inviting works

* unit testing

* agony

* test good

* typo

* that should be the basics

* Complete recode of pai saving

* restore fluff text

* migration

* pai notification automation

* swap

* length

* more fixes

* pai sprite datums

* type 13 uses all four directions

* eye handling

* use accessors

* working on icontests

* fix

* hologram eye test

* oop

* wait that doesn't work at all

* text

* eye colors and holo eyes

* lots of fixes

* fix those up

* organized

* belly cap

* that too

* death sprites

* resting eyes

* resting flag

* bad check here

* fixing icon files

* proper file

* garble

* fix some states

* pai death

* collapse pai files into single file

* allow some restricted pai interactions

* lamp

* block invites button

* collapse in remaining vr file

* this is actually needed

* documenting and organizing

* update to TGprefs

* remove gun toggle verb on pai

* forbid default name joins

* pai cable retraction

* various pai fixes

* icon forge pai

* pai eyes

* type 13 iconstate

* directionless

* small fix

* pai dir fix

* missing icon

* no fresh pais

* oops

* fixed pai join

* fixed change chassis

* pai UI

* .

* .

* reuse

* .

* .

* .

* push that

* Horro rmasks

* pai invite data change

* splitting

* use refs

* initial

* with PAI

* soem more

* .

* .

* .

* .

* ugh

* next

* pai invite

* only preview

* that

* use from char pref

* fixed pai invite not working

* small tgui fixes

* remove temp code

* .

* pai comments properly sent

* ooc

* horror

* need to use this for now

* .

* fix

* lol

* raw mob spawn fix

* pai software

* push

---------

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
Will
2026-03-03 17:59:27 -05:00
committed by GitHub
parent f5240f6c38
commit 7c84aaee4b
95 changed files with 4051 additions and 2442 deletions
@@ -2,12 +2,6 @@
name = "Basic"
sort_order = 7
var/datum/paiCandidate/candidate
/datum/category_item/player_setup_item/general/basic_antagonism/New()
. = ..()
candidate = new()
/datum/category_item/player_setup_item/general/basic_antagonism/load_character(list/save_data)
pref.exploit_record = save_data["exploit_record"]
pref.antag_faction = save_data["antag_faction"]
@@ -19,29 +13,18 @@
save_data["antag_vis"] = pref.antag_vis
/datum/category_item/player_setup_item/general/basic_antagonism/load_preferences(datum/json_savefile/savefile)
if(!candidate)
candidate = new()
var/preference_mob = preference_mob()
if(!preference_mob)// No preference mob - this happens when we're called from client/New() before it calls ..() (via datum/preferences/New())
spawn()
preference_mob = preference_mob()
if(!preference_mob)
return
candidate.savefile_load(preference_mob)
return
candidate.savefile_load(preference_mob)
/datum/category_item/player_setup_item/general/basic_antagonism/save_preferences(datum/json_savefile/savefile)
if(!candidate)
return
if(!preference_mob())
return
candidate.savefile_save(preference_mob())
/datum/category_item/player_setup_item/general/basic_antagonism/sanitize_character()
if(!pref.antag_faction) pref.antag_faction = "None"
if(!pref.antag_vis) pref.antag_vis = "Hidden"
@@ -62,13 +45,23 @@
if(!jobban_isbanned(user, "Records"))
data["exploitable_record"] = TextPreview(pref.exploit_record, 40)
if(!candidate)
CRASH("[user] pAI prefs have a null candidate var.")
data["pai_name"] = pref.read_preference(/datum/preference/text/pai_name)
data["pai_desc"] = pref.read_preference(/datum/preference/text/pai_description)
data["pai_role"] = pref.read_preference(/datum/preference/text/pai_role)
data["pai_ad"] = pref.read_preference(/datum/preference/text/pai_ad)
data["pai_comments"] = pref.read_preference(/datum/preference/text/pai_comments)
data["pai_eyecolor"] = pref.read_preference(/datum/preference/color/pai_eye_color)
var/pai_chassis = pref.read_preference(/datum/preference/text/pai_chassis)
data["pai_chassis"] = pai_chassis
data["pai_chassises"] = SSpai.get_chassis_list()
data["pai_emotion"] = pref.read_preference(/datum/preference/text/pai_emotion)
data["pai_emotions"] = GLOB.pai_emotions
data["pai_name"] = candidate.name ? candidate.name : "None Set"
data["pai_desc"] = candidate.description ? TextPreview(candidate.description, 40) : "None Set"
data["pai_role"] = candidate.role ? TextPreview(candidate.role, 40) : "None Set"
data["pai_comments"] = candidate.comments ? TextPreview(candidate.comments, 40) : "None Set"
var/datum/pai_sprite/sprite_datum = SSpai.chassis_data(pai_chassis)
if(sprite_datum)
var/datum/asset/spritesheet_batched/pai_icons/spritesheet = get_asset_datum(/datum/asset/spritesheet_batched/pai_icons)
data["pai_sprite_datum_class"] = sanitize_css_class_name("[sprite_datum.type]")
data["pai_sprite_datum_size"] = spritesheet.icon_size_id(data["pai_sprite_datum_class"] + "S") // just get the south icon's size, the rest will be the same
return data
@@ -111,23 +104,39 @@
pref.antag_vis = choice
return TOPIC_REFRESH
if("option")
if("pai_option")
var/t
switch(params["option"])
switch(params["pai_option"])
if("name")
t = sanitizeName(tgui_input_text(user, "Enter a name for your pAI", "Global Preference", candidate.name, MAX_NAME_LEN), MAX_NAME_LEN, 1)
t = sanitizeName(params["name"], MAX_NAME_LEN, TRUE)
if(t && CanUseTopic(user))
candidate.name = t
pref.update_preference_by_type(/datum/preference/text/pai_name, t)
if("desc")
t = tgui_input_text(user, "Enter a description for your pAI", "Global Preference", html_decode(candidate.description), multiline = TRUE, prevent_enter = TRUE)
t = sanitize(params["desc"], MAX_MESSAGE_LEN * 4)
if(!isnull(t) && CanUseTopic(user))
candidate.description = sanitize(t)
pref.update_preference_by_type(/datum/preference/text/pai_description, sanitize(t))
if("ad")
t = sanitize(params["ad"])
if(!isnull(t) && CanUseTopic(user))
pref.update_preference_by_type(/datum/preference/text/pai_ad, sanitize(t))
if("role")
t = tgui_input_text(user, "Enter a role for your pAI", "Global Preference", html_decode(candidate.role))
t = sanitize(params["role"])
if(!isnull(t) && CanUseTopic(user))
candidate.role = sanitize(t)
pref.update_preference_by_type(/datum/preference/text/pai_role, sanitize(t))
if("ooc")
t = tgui_input_text(user, "Enter any OOC comments", "Global Preference", html_decode(candidate.comments), multiline = TRUE, prevent_enter = TRUE)
t = sanitize(params["ooc"])
if(!isnull(t) && CanUseTopic(user))
candidate.comments = sanitize(t)
pref.update_preference_by_type(/datum/preference/text/pai_comments, sanitize(t))
if("color")
var/new_color = sanitize_hexcolor(params["color"])
if(new_color && CanUseTopic(user))
pref.update_preference_by_type(/datum/preference/color/pai_eye_color, new_color)
if("chassis")
var/new_chassis = params["chassis"]
if(new_chassis && CanUseTopic(user) && (new_chassis in SSpai.get_chassis_list()))
pref.update_preference_by_type(/datum/preference/text/pai_chassis, new_chassis)
if("emotion")
var/new_emotion = params["emotion"]
if(new_emotion && CanUseTopic(user) && (new_emotion in GLOB.pai_emotions))
pref.update_preference_by_type(/datum/preference/text/pai_emotion, new_emotion)
return TOPIC_REFRESH