Skip to content

Commit

Permalink
[PORT] Some pAI ports (#2143)
Browse files Browse the repository at this point in the history
* Adds a frog pAI holoform (#78537)

## About The Pull Request
It has been over a year since we have got a new pAI holoform, so I
present to you, the fwog.

![image](https://github.com/tgstation/tgstation/assets/20053168/3e1a77f0-e7b6-4aed-8401-c510afbcd2c5)
More importantly, it can be worn on the head like a normal frog.

![image](https://github.com/tgstation/tgstation/assets/20053168/795dcfd2-d576-4722-ab6f-edbed5b8fb36)

All of the new icons

![image](https://github.com/tgstation/tgstation/assets/20053168/b84ceca5-ff27-4a3a-a023-1d350762148b)

## Why It's Good For The Game
More holoform variety for pAIs is nice, especially one that can be worn
as a hat.
## Changelog
:cl:
image: adds a frog holoform for pAIs
/:cl:

* three more pais (#83038)

## About The Pull Request

adds three pai skins, puppy / kitty / spider 

![Screenshot_002](https://github.com/tgstation/tgstation/assets/68376391/9c6a65b1-ae05-40a2-97a0-8083e81397d2)

![Screenshot_003](https://github.com/tgstation/tgstation/assets/68376391/2f45d0d2-218c-4caa-8529-26222254fc4f)

![Screenshot_004](https://github.com/tgstation/tgstation/assets/68376391/3b1a0bf7-81d5-465d-acfe-145252b4adb0)

![Screenshot_005](https://github.com/tgstation/tgstation/assets/68376391/b6bf75f9-bc60-4b11-8393-59ae2fed90b6)

![Screenshot_001](https://github.com/tgstation/tgstation/assets/68376391/a80cdf8b-85a1-4305-bcbf-333fe1a39bfc)

![Screenshot_007](https://github.com/tgstation/tgstation/assets/68376391/17c99793-0f95-4724-8a27-3b52449a1487)

![Screenshot_008](https://github.com/tgstation/tgstation/assets/68376391/83f23d0b-3fbf-455e-8181-e118c691eb38)

![Screenshot_009](https://github.com/tgstation/tgstation/assets/68376391/d8cb1bf0-4daa-491d-80d6-1e162302c5cf)

![Screenshot_010](https://github.com/tgstation/tgstation/assets/68376391/3cd34b0a-363b-4739-b30d-a934b3c68782)

![Screenshot_006](https://github.com/tgstation/tgstation/assets/68376391/1a310903-5e6a-496e-b32e-781fe9130c78)

## Why It's Good For The Game

bounty request downstream, thought i'd push it up here incase yall
wanted it too

## Changelog
:cl:
add: 'puppy' 'kitten' and 'spider' pai skins
/:cl:

* Kitten, Puppy, and Spider pAI holoforms do not have head sprites, so they shouldn't be able to be picked up.

* Fix: Allow PAI to wake up (#80541)

Fixes #66760
Fixes Skyrat-SS13/Skyrat-tg#25745

This PR fixes a bug which causes Personal AI cards to be unable to wake
up from sleep.

Currently, emotes such as "collapse" effectively cause PAI to go into a
coma, which I tested on both TG and Skyrat.

We noticed a similar issue was fixed in PR #77857 in a very direct way,
so I copied that fix.

- Allows PAI to safely get knocked-out and wake up.
- Allows PAI to safely emote knockout-applying emotes such as "collapse"
and "faint" without going into a coma.
- Successfully tested!

:cl: A.C.M.O.
fix: Fixed Personal AI cards, allowing them to wake up from sleep.
/:cl:

* Fix PAI health scanning (#80373)

Fixes #80370

Rather than just using the global `healthscan` proc, PAIs created a
health analyzer in their contents and called `attack` directly,

despite the fact that all health analyzer `attack` does is call the
global proc

- [ ] I tested this pr

:cl: Melbert
fix: Fixes PAI health scan software
/:cl:

---------

Co-authored-by: Zephyr <[email protected]>

* Fixes pAIs permanently blocking requests (#82900)

Removes pAI subsystem/card's reliance on clients and makes them
unstoppable, which didn't really make much sense for it to be this way
in the first place since it's something that has to always happen and is
something that isn't client-controlled.

Also removed case of ``usr`` use in ui act.

Closes tgstation/tgstation#70401

🆑
fix: pAI requests should no longer randomly permanently break in a
round.
/🆑

* Change the pAI display face selection to a radial (#83770)

## About The Pull Request
This PR changes the pAI's face display selection from a tgui input list,
to a radial menu, with the actual faces displayed on the radial.


![image](https://github.com/tgstation/tgstation/assets/1008889/c89c9cf4-c3f3-4be9-9b79-08c1176687b4)

This PR also removes part of the comment for
`/mob/living/silicon/pai/proc/change_image()` that is no longer
applicable.

## Why It's Good For The Game
The radial menu makes pAI face display selection clearer, because
players now see what the face looks like, rather than having to guess
what a face might look like from the... frankly, very vague names given.
Seriously, what is `Null` supposed to be? What is `Face` supposed to
be?!

## Changelog

:cl: MichiRecRoom
qol: Personal AI's face display selection is now a radial menu. As a
bonus, now you can see what the faces look like before selecting them.
/:cl:

---------

Co-authored-by: Alexis <[email protected]>
Co-authored-by: candle :) <[email protected]>
Co-authored-by: Dani Glore <[email protected]>
Co-authored-by: MrMelbert <[email protected]>
Co-authored-by: Zephyr <[email protected]>
Co-authored-by: John Willard <[email protected]>
  • Loading branch information
7 people authored Jun 8, 2024
1 parent 39a4b0b commit be9e1eb
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 46 deletions.
30 changes: 18 additions & 12 deletions code/controllers/subsystem/pai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ SUBSYSTEM_DEF(pai)
ui.open()
ui.set_autoupdate(FALSE)

/datum/controller/subsystem/pai/Recover()
. = ..()
candidates = SSpai.candidates
pai_card_list = SSpai.pai_card_list

/datum/controller/subsystem/pai/ui_state(mob/user)
return GLOB.observer_state

Expand All @@ -35,33 +40,34 @@ SUBSYSTEM_DEF(pai)
. = ..()
if(.)
return TRUE
var/datum/pai_candidate/candidate = candidates[usr.ckey]
if(is_banned_from(usr.ckey, ROLE_PAI))
to_chat(usr, span_warning("You are banned from playing pAI!"))
var/mob/user = ui.user
var/datum/pai_candidate/candidate = candidates[user.ckey]
if(is_banned_from(user.ckey, ROLE_PAI))
to_chat(user, span_warning("You are banned from playing pAI!"))
ui.close()
return FALSE
if(isnull(candidate))
to_chat(usr, span_warning("There was an error. Please resubmit."))
to_chat(user, span_warning("There was an error. Please resubmit."))
ui.close()
return FALSE
switch(action)
if("submit")
candidate.comments = trim(params["comments"], MAX_BROADCAST_LEN)
candidate.description = trim(params["description"], MAX_BROADCAST_LEN)
candidate.name = trim(params["name"], MAX_NAME_LEN)
candidate.ckey = usr.ckey
candidate.ckey = user.ckey
candidate.ready = TRUE
ui.close()
submit_alert()
submit_alert(user)
return TRUE
if("save")
candidate.comments = params["comments"]
candidate.description = params["description"]
candidate.name = params["name"]
candidate.savefile_save(usr)
candidate.savefile_save(user)
return TRUE
if("load")
candidate.savefile_load(usr)
candidate.savefile_load(user)
ui.send_full_update()
return TRUE
return FALSE
Expand All @@ -84,14 +90,14 @@ SUBSYSTEM_DEF(pai)
/**
* Pings all pAI cards on the station that new candidates are available.
*/
/datum/controller/subsystem/pai/proc/submit_alert()
/datum/controller/subsystem/pai/proc/submit_alert(mob/user)
if(submit_spam)
to_chat(usr, span_warning("Your candidacy has been submitted, but pAI cards have been alerted too recently."))
to_chat(user, span_warning("Your candidacy has been submitted, but pAI cards have been alerted too recently."))
return FALSE
submit_spam = TRUE
for(var/obj/item/pai_card/pai_card as anything in pai_card_list)
if(!pai_card.pai)
pai_card.alert_update()
to_chat(usr, span_notice("Your pAI candidacy has been submitted!"))
addtimer(VARSET_CALLBACK(src, submit_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_CLIENT_TIME | TIMER_DELETE_ME)
to_chat(user, span_notice("Your pAI candidacy has been submitted!"))
addtimer(VARSET_CALLBACK(src, submit_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE|TIMER_DELETE_ME)
return TRUE
2 changes: 1 addition & 1 deletion code/modules/pai/card.dm
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@
balloon_alert(user, "pAI assistance requested")
var/mutable_appearance/alert_overlay = mutable_appearance('icons/obj/aicards.dmi', "pai")
notify_ghosts("[user] is requesting a pAI companion! Use the pAI button to submit yourself as one.", source = user, alert_overlay = alert_overlay, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "pAI Request!", ignore_key = POLL_IGNORE_PAI)
addtimer(VARSET_CALLBACK(src, request_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_CLIENT_TIME | TIMER_DELETE_ME)
addtimer(VARSET_CALLBACK(src, request_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE|TIMER_DELETE_ME)
return TRUE

/**
Expand Down
1 change: 1 addition & 0 deletions code/modules/pai/hud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
if(LAZYACCESS(modifiers, RIGHT_CLICK))
pAI.host_scan(PAI_SCAN_MASTER)
return TRUE

/atom/movable/screen/pai/crew_manifest
name = "Crew Manifest"
icon_state = "manifest"
Expand Down
18 changes: 13 additions & 5 deletions code/modules/pai/pai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@
// Onboard Items
/// Atmospheric analyzer
var/obj/item/analyzer/atmos_analyzer
/// Health analyzer
var/obj/item/healthanalyzer/host_scan
/// GPS
var/obj/item/gps/pai/internal_gps
/// Music Synthesizer
Expand Down Expand Up @@ -115,12 +113,16 @@
"crow" = TRUE,
"duffel" = TRUE,
"fox" = FALSE,
"frog" = TRUE,
"hawk" = FALSE,
"lizard" = FALSE,
"monkey" = TRUE,
"mouse" = TRUE,
"rabbit" = TRUE,
"repairbot" = TRUE,
"kitten" = FALSE,
"puppy" = FALSE,
"spider" = FALSE,
)
/// List of all available card overlays.
var/static/list/possible_overlays = list(
Expand Down Expand Up @@ -157,7 +159,6 @@
QDEL_NULL(atmos_analyzer)
QDEL_NULL(camera)
QDEL_NULL(hacking_cable)
QDEL_NULL(host_scan)
QDEL_NULL(instrument)
QDEL_NULL(internal_gps)
QDEL_NULL(newscaster)
Expand Down Expand Up @@ -203,8 +204,6 @@
atmos_analyzer = null
if(deleting_atom == camera)
camera = null
if(deleting_atom == host_scan)
host_scan = null
if(deleting_atom == internal_gps)
internal_gps = null
if(deleting_atom == instrument)
Expand Down Expand Up @@ -264,6 +263,15 @@
update_stat()
SEND_SIGNAL(src, COMSIG_LIVING_HEALTH_UPDATE)

/mob/living/silicon/pai/set_stat(new_stat)
. = ..()
update_stat()

/mob/living/silicon/pai/on_knockedout_trait_loss(datum/source)
. = ..()
set_stat(CONSCIOUS)
update_stat()

/**
* Resolves the weakref of the pai's master.
* If the master has been deleted, calls reset_software().
Expand Down
58 changes: 30 additions & 28 deletions code/modules/pai/software.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
return TRUE
// Software related ui actions
if(available_software[action] && !installed_software.Find(action))
balloon_alert(usr, "software unavailable")
balloon_alert(ui.user, "software unavailable!")
return FALSE
switch(action)
if("Atmospheric Sensor")
Expand Down Expand Up @@ -116,8 +116,6 @@
atmos_analyzer = new(src)
if("Digital Messenger")
create_modularInterface()
if("Host Scan")
host_scan = new(src)
if("Internal GPS")
internal_gps = new(src)
if("Music Synthesizer")
Expand All @@ -133,12 +131,17 @@
/**
* Changes the image displayed on the pAI.
*
* @param {mob} user - The user who is changing the image.
*
* @returns {boolean} - TRUE if the image was changed, FALSE otherwise.
*/
/mob/living/silicon/pai/proc/change_image()
var/new_image = tgui_input_list(src, "Select your new display image", "Display Image", possible_overlays)
var/list/possible_choices = list()
for(var/face_option in possible_overlays)
var/datum/radial_menu_choice/choice = new
choice.name = face_option
choice.image = image(icon = card.icon, icon_state = "pai-[face_option]")
possible_choices[face_option] += choice
var/atom/anchor = get_atom_on_turf(src)
var/new_image = show_radial_menu(src, anchor, possible_choices, custom_check = CALLBACK(src, PROC_REF(check_menu), anchor), radius = 40, require_near = TRUE)
if(isnull(new_image))
return FALSE
card.emotion_icon = new_image
Expand Down Expand Up @@ -193,28 +196,27 @@
* @returns {boolean} - TRUE if the scan was successful, FALSE otherwise.
*/
/mob/living/silicon/pai/proc/host_scan(mode)
if(isnull(mode))
return FALSE
if(mode == PAI_SCAN_TARGET)
var/mob/living/target = get_holder()
if(!target || !isliving(target))
balloon_alert(src, "not being carried")
return FALSE
host_scan.attack(target, src)
return TRUE
if(mode == PAI_SCAN_MASTER)
if(!master_ref)
balloon_alert(src, "no master detected")
return FALSE
var/mob/living/resolved_master = find_master()
if(!resolved_master)
balloon_alert(src, "cannot locate master")
return FALSE
if(!is_valid_z_level(get_turf(src), get_turf(resolved_master)))
balloon_alert(src, "master out of range")
return FALSE
host_scan.attack(resolved_master, src)
return TRUE
switch(mode)
if(PAI_SCAN_TARGET)
var/mob/living/target = get_holder()
if(!isliving(target))
balloon_alert(src, "not being carried!")
return FALSE
healthscan(src, target)
return TRUE

if(PAI_SCAN_MASTER)
var/mob/living/resolved_master = find_master()
if(isnull(resolved_master))
balloon_alert(src, "no master detected!")
return FALSE
if(!is_valid_z_level(get_turf(src), get_turf(resolved_master)))
balloon_alert(src, "master out of range!")
return FALSE
healthscan(src, resolved_master)
return TRUE

stack_trace("Invalid mode passed to host scan: [mode || "null"]")
return FALSE

/**
Expand Down
Binary file modified icons/mob/clothing/head/pai_head.dmi
Binary file not shown.
Binary file modified icons/mob/silicon/pai.dmi
Binary file not shown.

0 comments on commit be9e1eb

Please sign in to comment.