mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-19 19:15:11 +01:00
5926589c16
* removes var/ inside all procs * . * ugh
225 lines
8.0 KiB
Plaintext
225 lines
8.0 KiB
Plaintext
#define PAI_DELAY_TIME 1 MINUTE
|
|
|
|
////////////////////////////////
|
|
//// Pai join and management subsystem
|
|
////////////////////////////////
|
|
SUBSYSTEM_DEF(pai)
|
|
name = "Pai"
|
|
wait = 4 SECONDS
|
|
dependencies = list(
|
|
/datum/controller/subsystem/atoms
|
|
)
|
|
VAR_PRIVATE/list/datum/pai_sprite/pai_chassis_sprites = list()
|
|
VAR_PRIVATE/list/current_run = list()
|
|
VAR_PRIVATE/list/pai_ghosts = list()
|
|
VAR_PRIVATE/list/asked = list()
|
|
|
|
/datum/controller/subsystem/pai/Initialize()
|
|
// Get all software setup
|
|
for(var/type in subtypesof(/datum/pai_software))
|
|
var/datum/pai_software/P = new type()
|
|
GLOB.pai_software_by_key[P.id] = P
|
|
if(P.default)
|
|
GLOB.default_pai_software[P.id] = P
|
|
|
|
// Get all valid chassis types
|
|
for(var/datum/pai_sprite/sprite as anything in subtypesof(/datum/pai_sprite))
|
|
if(!initial(sprite.sprite_icon) || initial(sprite.hidden))
|
|
continue
|
|
pai_chassis_sprites[initial(sprite.name)] = new sprite()
|
|
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/pai/stat_entry(msg)
|
|
msg = "C:[length(pai_ghosts)]"
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/pai/fire(resumed)
|
|
if(!resumed)
|
|
pai_ghosts.Cut()
|
|
current_run = GLOB.observer_mob_list.Copy()
|
|
|
|
while(length(current_run))
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
var/mob/observer/ghost = current_run[length(current_run)]
|
|
current_run.len--
|
|
if(!invite_valid(ghost))
|
|
continue
|
|
|
|
// Create candidate
|
|
pai_ghosts[REF(ghost)] = WEAKREF(ghost)
|
|
|
|
/datum/controller/subsystem/pai/proc/get_chassis_list()
|
|
RETURN_TYPE(/list/datum/pai_sprite)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
return pai_chassis_sprites
|
|
|
|
/datum/controller/subsystem/pai/proc/chassis_data(id_name)
|
|
RETURN_TYPE(/datum/pai_sprite)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
if(!(id_name in pai_chassis_sprites))
|
|
return pai_chassis_sprites[PAI_DEFAULT_CHASSIS]
|
|
return pai_chassis_sprites[id_name]
|
|
|
|
/datum/controller/subsystem/pai/proc/invite_valid(mob/user)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
if(!user.client?.prefs || !user.ckey)
|
|
return FALSE
|
|
if(!user.MayRespawn())
|
|
return FALSE
|
|
if(jobban_isbanned(user, "pAI"))
|
|
return FALSE
|
|
if(!(user.client.prefs.be_special & BE_PAI))
|
|
return FALSE
|
|
if(check_is_delayed(REF(user)))
|
|
return FALSE
|
|
if(check_is_already_pai(user.ckey))
|
|
return FALSE
|
|
if(user.client.prefs.read_preference(/datum/preference/text/pai_name) == PAI_UNSET) // Forbid unset name
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/datum/controller/subsystem/pai/proc/check_is_delayed(ghost_ref)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
if(ghost_ref in asked)
|
|
if(world.time < asked[ghost_ref] + PAI_DELAY_TIME)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/datum/controller/subsystem/pai/proc/check_is_already_pai(check_ckey)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
return (check_ckey in GLOB.paikeys)
|
|
|
|
/datum/controller/subsystem/pai/proc/get_ghost_from_ref(ghost_ref)
|
|
RETURN_TYPE(/mob/observer)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
PRIVATE_PROC(TRUE)
|
|
if(!ghost_ref)
|
|
return null
|
|
var/datum/weakref/WF = pai_ghosts[ghost_ref]
|
|
return WF?.resolve()
|
|
|
|
/datum/controller/subsystem/pai/proc/get_invite_list_data()
|
|
RETURN_TYPE(/list)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
|
|
var/list/data = list()
|
|
for(var/ghost_ref in pai_ghosts)
|
|
var/mob/observer/ghost = get_ghost_from_ref(ghost_ref)
|
|
if(!istype(ghost) || !ghost.client?.prefs)
|
|
continue
|
|
|
|
var/datum/preferences/pref = ghost.client.prefs
|
|
var/datum/asset/spritesheet_batched/pai_icons/spritesheet = get_asset_datum(/datum/asset/spritesheet_batched/pai_icons)
|
|
var/chassis = pref.read_preference(/datum/preference/text/pai_chassis)
|
|
var/datum/pai_sprite/sprite_datum = SSpai.chassis_data(chassis)
|
|
var/css_class = sanitize_css_class_name("[sprite_datum.type]")
|
|
UNTYPED_LIST_ADD(data, list(
|
|
"ref" = REF(ghost),
|
|
"name" = pref.read_preference(/datum/preference/text/pai_name),
|
|
"gender" = pref.read_preference(/datum/preference/choiced/gender/biological), // Cannot use identifying yet due to byond limits
|
|
"role" = TextPreview(pref.read_preference(/datum/preference/text/pai_role), 152),
|
|
"ad" = TextPreview(pref.read_preference(/datum/preference/text/pai_ad), 244),
|
|
"eyecolor" = pref.read_preference(/datum/preference/color/pai_eye_color),
|
|
"chassis" = chassis,
|
|
"emotion" = pref.read_preference(/datum/preference/text/pai_emotion),
|
|
"sprite_datum_class" = css_class,
|
|
"sprite_datum_size" = spritesheet.icon_size_id(css_class + "S"), // just get the south icon's size, the rest will be the same
|
|
))
|
|
return data
|
|
|
|
/datum/controller/subsystem/pai/proc/get_detailed_invite_data(ghost_ref)
|
|
RETURN_TYPE(/list)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
|
|
if(!(ghost_ref in pai_ghosts))
|
|
return null
|
|
|
|
var/datum/weakref/WF = pai_ghosts[ghost_ref]
|
|
var/mob/observer/ghost = WF?.resolve()
|
|
if(!istype(ghost) || !ghost.client?.prefs)
|
|
return null
|
|
|
|
var/datum/preferences/pref = ghost.client.prefs
|
|
var/datum/asset/spritesheet_batched/pai_icons/spritesheet = get_asset_datum(/datum/asset/spritesheet_batched/pai_icons)
|
|
var/chassis = pref.read_preference(/datum/preference/text/pai_chassis)
|
|
var/datum/pai_sprite/sprite_datum = SSpai.chassis_data(chassis)
|
|
var/css_class = sanitize_css_class_name("[sprite_datum.type]")
|
|
return list(
|
|
"ref" = ghost_ref,
|
|
"name" = pref.read_preference(/datum/preference/text/pai_name),
|
|
"gender" = pref.read_preference(/datum/preference/choiced/gender/biological), // Cannot use identifying yet due to byond limits
|
|
// Description
|
|
"role" = pref.read_preference(/datum/preference/text/pai_role),
|
|
"description" = pref.read_preference(/datum/preference/text/pai_description),
|
|
"ad" = pref.read_preference(/datum/preference/text/pai_ad),
|
|
"comments" = pref.read_preference(/datum/preference/text/pai_comments),
|
|
// Appearance
|
|
"eyecolor" = pref.read_preference(/datum/preference/color/pai_eye_color),
|
|
"chassis" = chassis,
|
|
"emotion" = pref.read_preference(/datum/preference/text/pai_emotion),
|
|
// Sprites
|
|
"sprite_datum_class" = css_class,
|
|
"sprite_datum_size" = spritesheet.icon_size_id(css_class + "S"), // just get the south icon's size, the rest will be the same
|
|
)
|
|
|
|
/datum/controller/subsystem/pai/proc/invite_ghost(mob/inquirer, ghost_ref, obj/item/paicard/card)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
// Is our card legal to inhabit?
|
|
if(QDELETED(card) || card.pai || card.is_damage_critical())
|
|
to_chat(inquirer, span_warning("This [card] can no longer be used to house a pAI."))
|
|
return
|
|
|
|
// Check if the ghost stopped existing
|
|
var/mob/observer/ghost = get_ghost_from_ref(ghost_ref)
|
|
if(!isobserver(ghost) || !ghost.client)
|
|
to_chat(inquirer, span_warning("This pAI has gone offline."))
|
|
return
|
|
|
|
// Time delay if the ghost cancels your invite.
|
|
if(check_is_delayed(REF(ghost)))
|
|
to_chat(inquirer, span_notice("This pAI is responding to a request, but may become available again shortly..."))
|
|
return
|
|
asked[REF(ghost)] = world.time
|
|
|
|
// Can't play, still respawning
|
|
var/time_till_respawn = ghost.time_till_respawn()
|
|
if(time_till_respawn == -1 || time_till_respawn)
|
|
to_chat(inquirer, span_warning("This pAI is still downloading..."))
|
|
return
|
|
|
|
// Send it!
|
|
to_chat(inquirer, span_info("A request has been sent!"))
|
|
var/client/target = ghost.client
|
|
var/response = tgui_alert(target, "[inquirer] is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", list("Yes", "No", "Never for this round"))
|
|
if(!response || !target || !isobserver(target.mob) || ghost != target.mob)
|
|
return // Nice try smartass
|
|
if(check_is_already_pai(target.ckey))
|
|
to_chat(inquirer, span_warning("This pAI has already been downloaded."))
|
|
return
|
|
if(QDELETED(card) || card.pai)
|
|
to_chat(inquirer, span_warning("This [card] can no longer be used to house a pAI."))
|
|
return
|
|
|
|
switch(response)
|
|
if("Yes")
|
|
var/new_pai = card.ghost_inhabit(target.mob, TRUE)
|
|
to_chat(inquirer, span_info("[new_pai] has accepted your pAI request!"))
|
|
return
|
|
if("Never for this round")
|
|
SSpai.block_pai_invites(REF(ghost))
|
|
|
|
to_chat(inquirer, span_warning("The pAI denied the request."))
|
|
|
|
/datum/controller/subsystem/pai/proc/block_pai_invites(ghost_ref)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
asked[ghost_ref] = world.time + 99 HOURS // We never want to be asked again
|
|
|
|
/datum/controller/subsystem/pai/proc/clear_pai_block_delay(ghost_ref)
|
|
SHOULD_NOT_OVERRIDE(TRUE)
|
|
asked -= ghost_ref
|
|
|
|
#undef PAI_DELAY_TIME
|