Skip to content

Commit

Permalink
Adds Positronic Brains to Latejoin Menu (#11162)
Browse files Browse the repository at this point in the history
* Fixes Posi Created in null bug

And Dehardcode random PAI

* Adds Posibrain to Latejoin Menu

* Posi Job now subtype of cyborg. Failing to Spawn as Posi Kicks player back to lobby.

* No more Latejoin Cyborg

* Adds after_spawn_silicon per request

* Forgot Debug Code Comment

* Requested Changes

* Remove from Prefs

* Procify

* Remove Src

* Missed a Job

* Fix stupid problem that slipped testing

* Requested Changes. DM is weird.

* Update code/modules/mob/living/brain/posibrain.dm

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

* Update code/modules/mob/living/brain/posibrain.dm

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

* Update code/modules/mob/living/brain/posibrain.dm

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

* Revert "Fix stupid problem that slipped testing"

This reverts commit f3f1dd1.

* Revert "Fixes Posi Created in null bug"

This reverts commit 39d0309.

* Changes as requested by Bacon, refactored unused code.

* Whoops Forgot a Path

* Refactors Posibrain job back into own type and not subtype of cyborg

* Update Return

* Whoopsies forgot a debug comment out

* Requested changes

* Removed report to coders line, since posi's have known "fail" states

* Fix Spawning Logic

---------

Co-authored-by: PowerfulBacon <[email protected]>
Co-authored-by: Rukofamicom <[email protected]>
  • Loading branch information
3 people authored Sep 4, 2024
1 parent 2595f45 commit 85e0a61
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 10 deletions.
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -2849,6 +2849,7 @@
#include "code\modules\jobs\job_types\medical_doctor.dm"
#include "code\modules\jobs\job_types\mime.dm"
#include "code\modules\jobs\job_types\paramedic.dm"
#include "code\modules\jobs\job_types\posibrain.dm"
#include "code\modules\jobs\job_types\quartermaster.dm"
#include "code\modules\jobs\job_types\research_director.dm"
#include "code\modules\jobs\job_types\roboticist.dm"
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/jobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
// Silicon
#define JOB_NAME_AI "AI"
#define JOB_NAME_CYBORG "Cyborg"
#define JOB_NAME_POSIBRAIN "Positronic Brain"
#define JOB_NAME_PAI "Personal AI"

// ERTs
Expand Down
10 changes: 9 additions & 1 deletion code/controllers/subsystem/job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ SUBSYSTEM_DEF(job)
JOB_NAME_AI,
JOB_NAME_ASSISTANT,
JOB_NAME_CYBORG,
JOB_NAME_POSIBRAIN,
JOB_NAME_CAPTAIN,
JOB_NAME_HEADOFPERSONNEL,
JOB_NAME_HEADOFSECURITY,
Expand Down Expand Up @@ -553,7 +554,14 @@ SUBSYSTEM_DEF(job)
newplayer.new_character = living_mob
else
M = living_mob

else
if(!isnull(new_mob)) //Detect fail condition on equip
//if equip() is somehow able to fail, send them back to lobby
var/mob/dead/new_player/NP = new()
NP.ckey = M.client.ckey
qdel(M)
to_chat(M, "Error equipping [rank]. Returning to lobby.</b>")
return null
SSpersistence.antag_rep_change[M.client.ckey] += job.GetAntagRep()

if(M.client.holder)
Expand Down
1 change: 1 addition & 0 deletions code/modules/jobs/job_types/_job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
return antag_rep

//Don't override this unless the job transforms into a non-human (Silicons do this for example)
//Returning FALSE is considered a failure. A null or mob return is a successful equip.
/datum/job/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE, datum/outfit/outfit_override = null, client/preference_source)
if(!H)
return FALSE
Expand Down
2 changes: 1 addition & 1 deletion code/modules/jobs/job_types/cyborg.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
department_head_for_prefs = JOB_NAME_AI
auto_deadmin_role_flags = DEADMIN_POSITION_SILICON
faction = "Station"
total_positions = 1
total_positions = 0
spawn_positions = 1
supervisors = "your laws and the AI" //Nodrak
selection_color = "#ddffdd"
Expand Down
57 changes: 57 additions & 0 deletions code/modules/jobs/job_types/posibrain.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
GLOBAL_LIST_EMPTY(on_station_posis)

/datum/job/posibrain
title = JOB_NAME_POSIBRAIN
description = "Follow your AI's interpretation of your laws above all else, or your own interpretation if not connected to an AI. Choose one of many modules with different tools, ask robotics for maintenance and upgrades."
department_for_prefs = DEPT_BITFLAG_SILICON
department_head_for_prefs = JOB_NAME_AI
auto_deadmin_role_flags = DEADMIN_POSITION_SILICON
faction = "Station"
total_positions = 0
spawn_positions = 0
supervisors = "your laws" //No AI yet as you are just a cube
selection_color = "#ddffdd"
minimal_player_age = 21
exp_requirements = 120
exp_type = EXP_TYPE_CREW
random_spawns_possible = FALSE

display_order = JOB_DISPLAY_ORDER_CYBORG
departments = DEPT_BITFLAG_SILICON

show_in_prefs = FALSE //No reason to show in preferences

/datum/job/posibrain/equip(mob/living/carbon/human/H, visualsOnly = FALSE, announce = TRUE, latejoin = FALSE, datum/outfit/outfit_override = null, client/preference_source = null)

var/obj/item/mmi/posibrain/P = pick(GLOB.on_station_posis)

//Never show number of current posis
current_positions = 0

if(!P.activate(H)) //If we failed to activate a posi, kick them back to the lobby.
to_chat(H, "<span class='warning'>Failed to Late Join as a Posibrain. Look higher in chat for the reason.</span>")
return FALSE //Returning False is considered a failure, rather than null or a mob, which is a success.

qdel(H)
return P

/datum/job/posibrain/radio_help_message(mob/M)
to_chat(M, "<b>Prefix your message with :b to speak with other cyborgs and AI.</b>")

/datum/job/posibrain/proc/check_add_posi_slot(obj/item/mmi/posibrain/pb)
var/turf/currentturf = get_turf(pb)
if( is_station_level(currentturf.z) )
GLOB.on_station_posis |= pb

//Update Job Quantities
//We should never show a posibrain as a filled job, so just make number of current positions zero
current_positions = 0
total_positions = length(GLOB.on_station_posis)

/datum/job/posibrain/proc/remove_posi_slot(obj/item/mmi/posibrain/pb)
GLOB.on_station_posis -= pb

//Update Job Quantities
//We should never show a posibrain as a filled job, so just make number of current positions zero
current_positions = 0
total_positions = length(GLOB.on_station_posis)
1 change: 1 addition & 0 deletions code/modules/jobs/jobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ GLOBAL_LIST_INIT(security_lightup_areas, \
GLOBAL_LIST_INIT(nonhuman_positions, list(
JOB_NAME_AI,
JOB_NAME_CYBORG,
JOB_NAME_POSIBRAIN,
ROLE_PAI
))

Expand Down
56 changes: 48 additions & 8 deletions code/modules/mob/living/brain/posibrain.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,33 +85,38 @@ GLOBAL_VAR(posibrain_notify_cooldown)
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
/obj/item/mmi/posibrain/proc/activate(mob/user)
if(QDELETED(brainmob))
return
return FALSE
if(is_banned_from(user.ckey, ROLE_POSIBRAIN))
to_chat(user, "<span class='warning'>You are restricted from taking positronic brain spawns at this time.</span>")
return
return FALSE
if(user.client.get_exp_living(TRUE) <= MINUTES_REQUIRED_BASIC)
to_chat(user, "<span class='warning'>You aren't allowed to take positronic brain spawns yet.</span>")
return
return FALSE
if(is_occupied() || QDELETED(brainmob) || QDELETED(src) || QDELETED(user))
return
return FALSE
if(user.ckey in GLOB.posi_key_list)
to_chat(user, "<span class='warning'>Positronic brain spawns limited to 1 per round.</span>")
return
return FALSE
if(!(GLOB.ghost_role_flags & GHOSTROLE_SILICONS))
to_chat(user, "<span class='warning'>Central Command has temporarily outlawed posibrain sentience in this sector...</span>")
return
return FALSE
if(user.suiciding) //if they suicided, they're out forever.
to_chat(user, "<span class='warning'>[src] fizzles slightly. Sadly it doesn't take those who suicided!</span>")
return
return FALSE
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
if(posi_ask != "Yes" || QDELETED(src))
return
return FALSE
if(brainmob.suiciding) //clear suicide status if the old occupant suicided.
brainmob.set_suicide(FALSE)
var/ckey = user.ckey
if(transfer_personality(user))
GLOB.posi_key_list += ckey

var/datum/job/posibrain/pj = SSjob.GetJob(JOB_NAME_POSIBRAIN)
pj.remove_posi_slot(src)

return TRUE

/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/C)
name = "[initial(name)] ([C])"
brainmob.name = C.real_name
Expand Down Expand Up @@ -179,6 +184,11 @@ GLOBAL_VAR(posibrain_notify_cooldown)
brainmob.real_name = brainmob.name
brainmob.forceMove(src)
brainmob.container = src

//If we are on the station level, add it to the list of available posibrains.
var/datum/job/posibrain/pj = SSjob.GetJob(JOB_NAME_POSIBRAIN)
pj.check_add_posi_slot(src)

if(autoping)
ping_ghosts("created", TRUE)

Expand All @@ -195,3 +205,33 @@ GLOBAL_VAR(posibrain_notify_cooldown)
icon_state = "[initial(icon_state)]-occupied"
else
icon_state = initial(icon_state)

//This Proc triggers when the Z level changes. If the Posi enters the station level, add it to the Job list.
//If it leaves, remove it.
/obj/item/mmi/posibrain/onTransitZ(old_z, new_z)
. = ..()

if(is_station_level(old_z) == is_station_level(new_z))
//Early Return if we aren't entering or leaving station Z level.
return

if(is_occupied())
//No need to track occupied Posis
return

var/datum/job/posibrain/pj = SSjob.GetJob(JOB_NAME_POSIBRAIN)

//Posi was on station, now is not on station
if(is_station_level(new_z))
pj.check_add_posi_slot(src)
else
pj.remove_posi_slot(src)

/obj/item/mmi/posibrain/Destroy()
if(is_occupied())
//No need to track occupied Posis
return ..()

var/datum/job/posibrain/pj = SSjob.GetJob(JOB_NAME_POSIBRAIN)
pj.remove_posi_slot(src)
return ..()

0 comments on commit 85e0a61

Please sign in to comment.