Merge branch 'VOREStation:master' into tgui-update

This commit is contained in:
Selis
2022-05-22 21:01:46 +02:00
committed by GitHub
25 changed files with 152 additions and 1169 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
/datum/category_item/autolathe/devices/sleevecard
name = "sleevecard"
path =/obj/item/device/sleevecard
path =/obj/item/device/paicard/sleevecard
+2
View File
@@ -448,6 +448,8 @@ var/list/mob/living/forced_ambiance_list = new
return // Being buckled to something solid keeps you in place.
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.item_flags & NOSLIP))
return
if(H.incorporeal_move) // VOREstation edit - Phaseshifted beings should not be affected by gravity
return
if(H.m_intent == "run")
H.AdjustStunned(6)
@@ -11,7 +11,7 @@
/obj/item/clothing/under/rank/chief_engineer,
/obj/item/clothing/under/rank/chief_engineer/skirt,
/obj/item/clothing/head/hardhat/white,
/obj/item/clothing/head/welding,
///obj/item/clothing/head/welding, //VOREStation Removal: Locker bloat, grr. They get fancy goggles or can raid the welding supplies locker for one of these.
/obj/item/clothing/gloves/heavy_engineer, //VOREStation Edit: chief gets the good shit
/obj/item/clothing/shoes/brown,
/obj/item/weapon/cartridge/ce,
@@ -19,18 +19,19 @@
/obj/item/device/radio/headset/heads/ce/alt,
/obj/item/weapon/storage/toolbox/mechanical,
/obj/item/clothing/suit/storage/hazardvest,
/obj/item/clothing/mask/gas,
/obj/item/device/multitool,
///obj/item/clothing/mask/gas, //VOREStation Removal: Locker bloat, grr. The fancy one below functions as a mask & helmet combined.
/obj/item/clothing/head/hardhat/firefighter/chief, //VOREStation Add: replaces the bog-standard gas mask
///obj/item/device/multitool, //VOREStation Removal: The belt they get, both standard and the fancy one, both come with one already, why stick another in here too?
/obj/item/weapon/storage/belt/utility/chief/full,
/obj/item/device/flash,
/obj/item/device/t_scanner/upgraded,
/obj/item/taperoll/engineering,
/obj/item/clothing/suit/storage/hooded/wintercoat/engineering,
///obj/item/clothing/suit/storage/hooded/wintercoat/engineering, //VOREStation Removal: Locker bloat, grr. They can grab from the engi-clothes vendor if they want the standard one.
/obj/item/clothing/suit/storage/hooded/wintercoat/engineering/ce,
/obj/item/clothing/shoes/boots/winter/engineering,
///obj/item/clothing/shoes/boots/winter/engineering, //VOREStation Removal: Locker bloat, grr. As above.
/obj/item/clothing/head/beret/engineering/ce,
/obj/item/clothing/head/beret/engineering/ce/white,
/obj/item/weapon/tank/emergency/oxygen/engi,
/obj/item/weapon/tank/emergency/oxygen/double, //VOREStation Edit: chief gets the good shit
/obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add
/obj/structure/closet/secure_closet/engineering_chief/Initialize()
+3 -2
View File
@@ -19,7 +19,8 @@
icon_base = "flesh_floor"
/decl/flooring/grass/outdoors
flags = TURF_REMOVE_SHOVEL
flags = 0
build_type = null
/decl/flooring/grass/outdoors/forest
icon = 'icons/turf/outdoors.dmi'
@@ -102,7 +103,7 @@
/obj/item/stack/tile/floor/milspec/sterile
name = "sterile milspec floor tile"
/decl/flooring/tiling/milspec/raised
name = "raised milspec floor"
icon_base = "milspec_tcomms"
+1
View File
@@ -27,6 +27,7 @@
var/initial_flooring
var/decl/flooring/flooring
var/mineral = DEFAULT_WALL_MATERIAL
var/can_be_plated = TRUE // This is here for inheritance's sake. Override to FALSE for turfs you don't want someone to simply slap a plating over such as hazards.
thermal_conductivity = 0.040
heat_capacity = 10000
+18 -4
View File
@@ -72,9 +72,23 @@
to_chat(user, "<span class='warning'>You must remove the [flooring.descriptor] first.</span>")
return
else if(istype(C, /obj/item/stack/tile))
try_replace_tile(C, user)
return
if(try_replace_tile(C, user))
return
else if(istype(C, /obj/item/stack/tile/floor)) // While we're at it, let's see if this is a raw patch of natural sand, dirt, or whatever that you're trying to put a plating on.
if(!flooring.build_type && can_be_plated && !((flooring.flags & TURF_REMOVE_WRENCH) || (flooring.flags & TURF_REMOVE_CROWBAR) || (flooring.flags & TURF_REMOVE_SCREWDRIVER) || (flooring.flags & TURF_REMOVE_SHOVEL)))
for(var/obj/structure/P in contents)
if(istype(P, /obj/structure/flora))
to_chat(user, "<span class='warning'>The [P.name] is in the way, you'll have to get rid of it first.</span>")
return
var/obj/item/stack/tile/floor/S = C
if (S.get_amount() < 1)
return
S.use(1)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE)
return
// Floor is plating (or no flooring)
else
// Placing wires on plating
@@ -136,7 +150,7 @@
return
if(!can_remove_plating(user))
return
user.visible_message("<span class='warning'>[user] begins cutting through [src].</span>", "<span class='warning'>You begin cutting through [src].</span>")
// This is slow because it's a potentially hostile action to just cut through places into space in the middle of the bar and such
// Presumably also the structural floor is thick?
+1
View File
@@ -13,6 +13,7 @@
light_on = TRUE
movement_cost = 2
can_build_into_floor = TRUE
can_be_plated = FALSE
can_dirty = FALSE
initial_flooring = /decl/flooring/lava // Defining this in case someone DOES step on lava and survive. Somehow.
flags = TURF_ACID_IMMUNE
@@ -8,7 +8,7 @@ var/list/turf_edge_cache = list()
var/outdoors = OUTDOORS_AREA
/area
// If a turf's `outdoors` variable is set to `OUTDOORS_AREA`,
// If a turf's `outdoors` variable is set to `OUTDOORS_AREA`,
// it will decide if it's outdoors or not when being initialized based on this var.
var/outdoors = OUTDOORS_NO
@@ -1,7 +0,0 @@
// this code here enables people to dig up worms from certain tiles.
/turf/simulated/floor/outdoors/grass/attackby(obj/item/weapon/S as obj, mob/user as mob)
if(istype(S, /obj/item/stack/tile/floor))
ChangeTurf(/turf/simulated/floor, preserve_outdoors = TRUE)
return
. = ..()
@@ -51,6 +51,7 @@
icon_state = "ice"
desc = "Looks slippery."
edge_blending_priority = 0
can_be_plated = FALSE
/turf/simulated/floor/outdoors/ice/dark
name = "black ice"
+1
View File
@@ -8,6 +8,7 @@
var/under_state = "rock"
edge_blending_priority = -1
movement_cost = 4
can_be_plated = FALSE
outdoors = OUTDOORS_YES
flags = TURF_ACID_IMMUNE
@@ -82,19 +82,19 @@
path = /obj/item/clothing/head/fluff/fifi_hat
display_name = "Fifi's hat"
ckeywhitelist = list("allweek")
character_name = list("Fifi the Magnificent")
character_name = list("Fifi The Magnificent")
/datum/gear/fluff/fifi_jumpsuit
path = /obj/item/clothing/under/fluff/fifi_jumpsuit
display_name = "Fifi's jumpsuit"
ckeywhitelist = list("allweek")
character_name = list("Fifi the Magnificent")
character_name = list("Fifi The Magnificent")
/datum/gear/fluff/fifi_hat
path = /obj/item/clothing/shoes/fluff/fifi_socks
display_name = "Fifi's socks"
ckeywhitelist = list("allweek")
character_name = list("Fifi the Magnificent")
character_name = list("Fifi The Magnificent")
/datum/gear/fluff/lynn_penlight
path = /obj/item/device/flashlight/pen/fluff/lynn
@@ -1401,7 +1401,8 @@
character_name = list("Nehi Maximus")
/datum/gear/fluff/lucky_amour
path = /obj/item/device/modkit_conversion/crusader_luck
path = /obj/item/clothing/suit/armor/combat/crusader_costume/lucky
display_name = "Lucky's amour"
ckeywhitelist = list ("thedavestdave")
character_name = list("Lucky")
allowed_roles = "Chaplain"
@@ -94,5 +94,5 @@
/datum/gear/schnapsen
display_name = "schnapsen playing cards"
description = "French-suit playing cards! Pre-picked for 2-player mode."
description = "An ancient Austro-Hungarian suit of cards!"
path = /obj/item/weapon/deck/schnapsen
+1
View File
@@ -628,6 +628,7 @@
/obj/item/device/analyzer = 5,
/obj/item/device/t_scanner = 5,
/obj/item/weapon/tool/screwdriver = 5,
/obj/item/weapon/extinguisher/mini = 3,
/obj/item/device/flashlight/glowstick = 3,
/obj/item/device/flashlight/glowstick/red = 3,
/obj/item/device/flashlight/glowstick/blue = 3,
+6 -22
View File
@@ -403,30 +403,14 @@ var/list/mining_overlay_cache = list()
F.attackby(W,user)
return
else if(istype(W, /obj/item/stack/rods))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
return
var/obj/item/stack/rods/R = W
if (R.use(1))
to_chat(user, "<span class='notice'>Constructing support lattice ...</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
new /obj/structure/lattice(get_turf(src))
else if(istype(W, /obj/item/stack/tile/floor))
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/floor/S = W
if (S.get_amount() < 1)
return
qdel(L)
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ChangeTurf(/turf/simulated/floor)
S.use(1)
return
else
to_chat(user, "<span class='warning'>The plating is going to need some support.</span>")
var/obj/item/stack/tile/floor/S = W
if (S.get_amount() < 1)
return
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
ChangeTurf(/turf/simulated/floor)
S.use(1)
return
else
+17 -10
View File
@@ -84,7 +84,7 @@
handle_shock()
handle_pain()
handle_allergens()
handle_medical_side_effects()
@@ -607,11 +607,11 @@
apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, BP_HEAD, used_weapon = "Excessive Cold")
throw_alert("temp", /obj/screen/alert/cold, COLD_ALERT_SEVERITY_MAX)
else if(breath.temperature <= species.breath_cold_level_2)
apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, BP_HEAD, used_weapon = "Excessive Cold")
throw_alert("temp", /obj/screen/alert/cold, COLD_ALERT_SEVERITY_LOW)
else if(breath.temperature <= species.breath_cold_level_1)
apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, BP_HEAD, used_weapon = "Excessive Cold")
throw_alert("temp", /obj/screen/alert/cold, COLD_ALERT_SEVERITY_MODERATE)
else if(breath.temperature <= species.breath_cold_level_1)
apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, BP_HEAD, used_weapon = "Excessive Cold")
throw_alert("temp", /obj/screen/alert/cold, COLD_ALERT_SEVERITY_LOW)
else if(species.get_environment_discomfort(src, ENVIRONMENT_COMFORT_MARKER_COLD))
throw_alert("temp", /obj/screen/alert/chilly, COLD_ALERT_SEVERITY_LOW)
else
@@ -1621,32 +1621,39 @@
return 0
if(shock_stage == 10)
custom_pain("[pick("It hurts so much", "You really need some painkillers", "Dear god, the pain")]!", 40)
if(traumatic_shock >= 80)
custom_pain("[pick("It hurts so much", "You really need some painkillers", "Dear god, the pain")]!", 40)
if(shock_stage >= 30)
if(shock_stage == 30 && !isbelly(loc)) //VOREStation Edit
custom_emote(VISIBLE_MESSAGE, "is having trouble keeping their eyes open.")
eye_blurry = max(2, eye_blurry)
stuttering = max(stuttering, 5)
if(traumatic_shock >= 80)
stuttering = max(stuttering, 5)
if(shock_stage == 40)
to_chat(src, "<span class='danger'>[pick("The pain is excruciating", "Please&#44; just end the pain", "Your whole body is going numb")]!</span>")
if(traumatic_shock >= 80)
to_chat(src, "<span class='danger'>[pick("The pain is excruciating", "Please&#44; just end the pain", "Your whole body is going numb")]!</span>")
if (shock_stage >= 60)
if(shock_stage == 60 && !isbelly(loc)) //VOREStation Edit
custom_emote(VISIBLE_MESSAGE, "'s body becomes limp.")
if (prob(2))
to_chat(src, "<span class='danger'>[pick("The pain is excruciating", "Please&#44; just end the pain", "Your whole body is going numb")]!</span>")
if(traumatic_shock >= 80)
to_chat(src, "<span class='danger'>[pick("The pain is excruciating", "Please&#44; just end the pain", "Your whole body is going numb")]!</span>")
Weaken(20)
if(shock_stage >= 80)
if (prob(5))
to_chat(src, "<span class='danger'>[pick("The pain is excruciating", "Please&#44; just end the pain", "Your whole body is going numb")]!</span>")
if(traumatic_shock >= 80)
to_chat(src, "<span class='danger'>[pick("The pain is excruciating", "Please&#44; just end the pain", "Your whole body is going numb")]!</span>")
Weaken(20)
if(shock_stage >= 120)
if (prob(2))
to_chat(src, "<span class='danger'>[pick("You black out", "You feel like you could die any moment now", "You are about to lose consciousness")]!</span>")
if(traumatic_shock >= 80)
to_chat(src, "<span class='danger'>[pick("You black out", "You feel like you could die any moment now", "You are about to lose consciousness")]!</span>")
Paralyse(5)
if(shock_stage == 150)
-621
View File
@@ -1,621 +0,0 @@
var/list/infomorph_emotions = list(
"Happy" = 1,
"Cat" = 2,
"Extremely Happy" = 3,
"Face" = 4,
"Laugh" = 5,
"Off" = 6,
"Sad" = 7,
"Angry" = 8,
"What" = 9,
"Neutral" = 10,
"Silly" = 11,
"Nose" = 12,
"Smirk" = 13,
"Exclamation Points" = 14,
"Question Mark" = 15
)
/mob/living/silicon/infomorph
name = "sleevecard" //Has the same name as the card for consistency, but this is the MOB in the card.
icon = 'icons/mob/pai_vr.dmi' //Changed to the virgo icon, giving more sprite options.
icon_state = "pai-repairbot"
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
pass_flags = 1
mob_size = MOB_SMALL
can_pull_size = ITEMSIZE_SMALL
can_pull_mobs = MOB_PULL_SMALLER
idcard_type = /obj/item/weapon/card/id
var/idaccessible = 0
var/network = NETWORK_NORTHERN_STAR
var/obj/machinery/camera/current = null
var/ram = 30 // Used as currency to purchase different abilities
var/list/software = list()
var/obj/item/device/sleevecard/card // The card we inhabit
var/obj/item/device/radio/sleevecard/radio // Our primary radio
var/obj/item/device/universal_translator/translator
// This was ripped from PAI code, this is to fix the broken sprites for sleevecards and to give sleevecards the same options as PAIs for chassis
var/chassis = null // A record of your chosen chassis.
var/global/list/possible_chassis = list(
"Drone" = "pai-repairbot",
"Cat" = "pai-cat",
"Mouse" = "pai-mouse",
"Monkey" = "pai-monkey",
"Corgi" = "pai-borgi",
"Fox" = "pai-fox",
"Parrot" = "pai-parrot",
"Rabbit" = "pai-rabbit",
//VOREStation Addition Start
"Bear" = "pai-bear",
"Fennec" = "pai-fen",
"Type Zero" = "pai-typezero",
"Raccoon" = "pai-raccoon",
"Raptor" = "pai-raptor",
"Corgi" = "pai-corgi",
"Bat" = "pai-bat",
"Butterfly" = "pai-butterfly",
"Hawk" = "pai-hawk",
"Duffel" = "pai-duffel",
"Rat" = "rat",
"Panther" = "panther"
//VOREStation Addition End
)
var/global/list/possible_say_verbs = list(
"Robotic" = list("states","declares","queries"),
"Natural" = list("says","yells","asks"),
"Beep" = list("beeps","beeps loudly","boops"),
"Chirp" = list("chirps","chirrups","cheeps"),
"Feline" = list("purrs","yowls","meows"),
"Canine" = list("yaps","barks","woofs"),
"Rodent" = list("squeaks", "SQUEAKS", "sqiks") //VOREStation Edit
)
var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking
var/silence_time // Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded
var/db_key
// Various software-specific vars
var/temp // General error reporting text contained here will typically be shown once and cleared
var/screen // Which screen our main window displays
var/subscreen // Which specific function of the main screen is being displayed
var/arHUD = 0 // Toggles whether a civilian AR HUD is active or not
var/obj/machinery/door/hackdoor // The airlock being hacked
var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check
var/hack_aborted = 0
var/obj/item/radio/integrated/signal/sradio // AI's signaller
var/obj/item/device/communicator/integrated/communicator // Our integrated communicator.
var/obj/item/device/pda/ai/pai/pda // Our integrated PDA
var/medical_cannotfind = 0
var/datum/data/record/medicalActive1 // Datacore record declarations for record software
var/datum/data/record/medicalActive2
var/security_cannotfind = 0
var/datum/data/record/securityActive1 // Could probably just combine all these into one
var/datum/data/record/securityActive2
/mob/living/silicon/infomorph/New(var/obj/item/device/sleevecard/SC, var/name = "Unknown", var/db_key)
ASSERT(SC)
name = "[initial(name)] ([name])"
src.forceMove(SC)
card = SC
sradio = new(src)
translator = new(src)
communicator = new(src)
if(!card.radio)
card.radio = new (card)
radio = card.radio
src.db_key = db_key
//Default languages without universal translator software
add_language(LANGUAGE_EAL, 1)
add_language(LANGUAGE_SIGN, 0)
verbs += /mob/living/silicon/infomorph/proc/choose_verbs
verbs += /mob/living/proc/hide
verbs += /mob/living/silicon/infomorph/proc/fold_out
verbs += /mob/living/silicon/infomorph/proc/fold_in
software = default_infomorph_software.Copy()
//PDA
pda = new(src)
spawn(5)
pda.ownjob = "Sleevecard"
pda.owner = text("[]", src)
pda.name = pda.owner + " (" + pda.ownjob + ")"
var/datum/data/pda/app/messenger/M = pda.find_program(/datum/data/pda/app/messenger)
if(M)
M.toff = TRUE
..()
/mob/living/silicon/infomorph/Login()
..()
/////////// STAT PANEL
/mob/living/silicon/infomorph/Stat()
..()
statpanel("Status")
if (src.client.statpanel == "Status")
show_silenced()
// this function shows the information about being silenced as a pAI in the Status panel
/mob/living/silicon/infomorph/proc/show_silenced()
if(src.silence_time)
var/timeleft = round((silence_time - world.timeofday)/10 ,1)
stat(null, "Communications system reboot in -[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
/////////// CHECKERS
/mob/living/silicon/infomorph/check_eye(var/mob/user as mob)
if (!src.current)
return -1
return 0
/mob/living/silicon/infomorph/restrained()
if(istype(src.loc,/obj/item/device/sleevecard))
return 0
..()
/mob/living/silicon/infomorph/default_can_use_tgui_topic(var/src_object)
if(src_object in src)
return shared_tgui_interaction()
/////////// DAMAGES
/mob/living/silicon/infomorph/emp_act(severity)
// Silence for 2 minutes
// 20% chance to kill
src.silence_time = world.timeofday + 120 * 10 // Silence for 2 minutes
to_chat(src, "<font color=green><b>Communication circuit overload. Shutting down and reloading communication circuits - speech and messaging functionality will be unavailable until the reboot is complete.</b></font>")
if(prob(20))
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("<span class='warning'>A shower of sparks spray from \the [src]'s inner workings.</span>", 3, "<span class='warning'>You hear and smell the ozone hiss of electrical sparks being expelled violently.</span>", 2)
return src.death(0)
/mob/living/silicon/infomorph/death(gibbed,var/message = "beeps once, then goes offline.")
if(card)
card.infomorph = null
card.turnOff()
if(gibbed)
src.loc = get_turf(card)
qdel(card)
if(card in src)
card.forceMove(get_turf(src))
card = null
..(gibbed,message)
ghostize()
qdel(src)
///////////// CAMERAS AND RECORDS
/mob/living/silicon/infomorph/verb/reset_record_view()
set category = "Card Commands"
set name = "Reset Records Software"
securityActive1 = null
securityActive2 = null
security_cannotfind = 0
medicalActive1 = null
medicalActive2 = null
medical_cannotfind = 0
SStgui.update_uis(src)
to_chat(usr, "<span class='notice'>You reset your record-viewing software.</span>")
/*
/mob/living/silicon/infomorph/proc/switchCamera(var/obj/machinery/camera/C)
if (!C)
src.unset_machine()
src.reset_view(null)
return 0
if (stat == 2 || !C.status || !(src.network in C.network)) return 0
// ok, we're alive, camera is good and in our network...
src.set_machine(src)
src.current = C
src.reset_view(C)
return 1
/mob/living/silicon/infomorph/cancel_camera()
set category = "Card Commands"
set name = "Cancel Camera View"
src.reset_view(null)
src.unset_machine()
src.cameraFollow = null
*/
////////////// MOBILE CODE
/mob/living/silicon/infomorph/proc/fold_out()
set category = "Card Commands"
set name = "Chassis Open"
if(stat || sleeping || paralysis || weakened)
return
if(src.loc != card)
return
if(world.time <= last_special)
return
if(!chassis)
choose_chassis()
if(!chassis)
return
last_special = world.time + 100
if(istype(card.loc,/mob))
var/mob/holder = card.loc
if(ishuman(holder))
var/mob/living/carbon/human/H = holder
for(var/obj/item/organ/external/affecting in H.organs)
if(card in affecting.implants)
affecting.take_damage(rand(30,50))
affecting.implants -= card
H.visible_message("<span class='danger'>\The [src] explodes out of \the [H]'s [affecting.name] in shower of gore!</span>")
break
holder.drop_from_inventory(card)
/*
if(src.client)
src.client.perspective = EYE_PERSPECTIVE
src.client.eye = src
*/
src.forceMove(get_turf(card))
card.forceMove(src)
card.screen_loc = null
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> folds outwards, expanding into a mobile form.")
/mob/living/silicon/infomorph/proc/fold_in()
set category = "Card Commands"
set name = "Chassis Close"
if(stat || sleeping || paralysis || weakened)
return
if(src.loc == card)
return
if(world.time <= last_special)
return
close_up()
/mob/living/silicon/infomorph/proc/close_up()
last_special = world.time + 100
if(src.loc == card)
return
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> neatly folds inwards, compacting down to a rectangular card.")
src.stop_pulling()
/*
if(client)
client.perspective = EYE_PERSPECTIVE
client.eye = card
*/
//stop resting
resting = 0
// If we are being held, handle removing our holder from their inv.
var/obj/item/weapon/holder/H = loc
if(istype(H))
var/mob/living/M = H.loc
if(istype(M))
M.drop_from_inventory(H)
H.loc = get_turf(src)
src.loc = get_turf(H)
// Move us into the card and move the card to the ground.
src.loc = card
card.loc = get_turf(card)
src.forceMove(card)
card.forceMove(card.loc)
canmove = 1
resting = 0
icon_state = "[chassis]"
/mob/living/silicon/infomorph/proc/choose_chassis()
set category = "Card Commands"
set name = "Choose Chassis"
var/choice = tgui_input_list(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.", "Chassis Choice", possible_chassis)
if(!choice) return
icon_state = possible_chassis[choice]
chassis = possible_chassis[choice]
/mob/living/silicon/infomorph/proc/choose_verbs()
set category = "Card Commands"
set name = "Choose Speech Verbs"
var/choice = tgui_input_list(usr,"What theme would you like to use for your speech verbs? This decision can only be made once.", "Verb Choice", possible_say_verbs)
if(!choice) return
var/list/sayverbs = possible_say_verbs[choice]
speak_statement = sayverbs[1]
speak_exclamation = sayverbs[(sayverbs.len>1 ? 2 : sayverbs.len)]
speak_query = sayverbs[(sayverbs.len>2 ? 3 : sayverbs.len)]
verbs -= /mob/living/silicon/infomorph/proc/choose_verbs
/mob/living/silicon/infomorph/lay_down()
set name = "Rest"
set category = "IC"
resting = !resting
icon_state = resting ? "[chassis]_rest" : "[chassis]"
to_chat(src, "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>")
canmove = !resting
////////////////// ATTACKBY, HAND, SELF etc
/mob/living/silicon/infomorph/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.force)
visible_message("<span class='danger'>[user.name] attacks [src] with [W]!</span>")
src.adjustBruteLoss(W.force)
src.updatehealth()
else
visible_message("<span class='warning'>[user.name] bonks [src] harmlessly with [W].</span>")
spawn(1)
if(stat != 2) close_up()
return
/mob/living/silicon/infomorph/attack_hand(mob/user as mob)
visible_message("<span class='danger'>[user.name] boops [src] on the head.</span>")
close_up()
/mob/living/silicon/infomorph/attackby(obj/item/weapon/W as obj, mob/user as mob)
var/obj/item/weapon/card/id/ID = W.GetID()
if(ID)
if (idaccessible == 1)
switch(tgui_alert(user, "Do you wish to add access to [src] or remove access from [src]?","Modify Access",list("Add Access","Remove Access","Cancel")))
if("Add Access")
idcard.access |= ID.access
to_chat(user, "<span class='notice'>You add the access from the [W] to [src].</span>")
return
if("Remove Access")
idcard.access = null
to_chat(user, "<span class='notice'>You remove the access from [src].</span>")
return
if("Cancel")
return
else if (istype(W, /obj/item/weapon/card/id) && idaccessible == 0)
to_chat(user, "<span class='notice'>[src] is not accepting access modifcations at this time.</span>")
return
//////////////////// MISC VERBS
/mob/living/silicon/infomorph/verb/allowmodification()
set name = "Allow ID Updates"
set category = "Card Commands"
desc = "Allows people to modify your access or block people from modifying your access."
if(idaccessible == 0)
idaccessible = 1
to_chat(src, "<span class='notice'>You allow access modifications.</span>")
else
idaccessible = 0
to_chat(src, "<span class='notice'>You block access modfications.</span>")
/mob/living/silicon/infomorph/verb/wipe_software()
set name = "Suspend Self"
set category = "OOC"
set desc = "Wipe yourself from your hardware. This is functionally equivalent to cryo or robotic storage, freeing up your job slot."
// Make sure people don't kill themselves accidentally
if(tgui_alert(usr, "WARNING: This will immediately remove you from the round, and remove your mind backups from storage, similar to cryo. Are you entirely sure you want to do this?", "Suspend Self", list("No", "Yes")) != "Yes")
return
close_up()
//Resleeving 'cryo'
SStranscore.leave_round(src)
card.removePersonality()
clear_client()
//////////// COMMUNICATIONS
/mob/living/silicon/infomorph/verb/radiosettings()
set name = "Radio Settings"
set category = "Card Commands"
desc = "Modify the settings on your integrated radio."
if(radio)
radio.tgui_interact(src)
else
to_chat(src, "<span class='warning'>You don't have a radio!</span>")
/mob/living/silicon/infomorph/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
if(silence_time)
to_chat(src, "<font color=green>Communication circuits remain uninitialized.</font>")
else
..(message)
/mob/living/silicon/infomorph/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
switch(message_mode)
if("headset")
if(radio && istype(radio,/obj/item/device/radio))
var/obj/item/device/radio/R = radio
R.talk_into(src,message,null,verb,speaking)
used_radios += radio
// No binary for pAIs.
/mob/living/silicon/infomorph/binarycheck()
return 0
/////////////// SOFTWARE DOWNLOADS
var/global/list/infomorph_software_by_key = list()
var/global/list/default_infomorph_software = list()
/hook/startup/proc/populate_infomorph_software_list()
var/r = 1 // I would use ., but it'd sacrifice runtime detection
for(var/type in subtypesof(/datum/infomorph_software))
var/datum/infomorph_software/P = new type()
if(infomorph_software_by_key[P.id])
var/datum/infomorph_software/O = infomorph_software_by_key[P.id]
to_world("<span class='warning'>Infomorph software module [P.name] has the same key as [O.name]!</span>")
r = 0
continue
infomorph_software_by_key[P.id] = P
if(P.default)
default_infomorph_software[P.id] = P
return r
/mob/living/silicon/infomorph/verb/paiInterface()
set category = "Card Commands"
set name = "Software Interface"
tgui_interact(src)
/mob/living/silicon/infomorph/tgui_state(mob/user)
return GLOB.tgui_self_state
/mob/living/silicon/infomorph/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "pAIInterface", "Card Software Interface")
ui.open()
/mob/living/silicon/infomorph/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
// Software we have bought
var/list/bought_software = list()
// Software we have not bought
var/list/not_bought_software = list()
for(var/key in infomorph_software_by_key)
var/datum/infomorph_software/S = infomorph_software_by_key[key]
var/list/software_data = list()
software_data["name"] = S.name
software_data["id"] = S.id
if(key in software)
software_data["on"] = S.is_active(src)
bought_software.Add(list(software_data))
else
software_data["ram"] = S.ram_cost
not_bought_software.Add(list(software_data))
data["bought"] = bought_software
data["not_bought"] = not_bought_software
data["available_ram"] = ram
// Emotions
var/list/emotions = list()
for(var/name in infomorph_emotions)
var/list/emote = list()
emote["name"] = name
emote["id"] = infomorph_emotions[name]
emotions.Add(list(emote))
data["emotions"] = emotions
data["current_emotion"] = card.current_emotion
return data
/mob/living/silicon/infomorph/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("software")
var/soft = params["software"]
var/datum/infomorph_software/S = software[soft]
if(S.toggle)
S.toggle(src)
else
S.tgui_interact(src, parent_ui = ui)
return TRUE
if("purchase")
var/soft = params["purchase"]
var/datum/infomorph_software/S = infomorph_software_by_key[soft]
if(S && (ram >= S.ram_cost))
ram -= S.ram_cost
software[S.id] = S
return TRUE
if("image")
var/img = text2num(params["image"])
if(img)
card.setEmotion(img)
return TRUE
/mob/living/silicon/infomorph/examine(mob/user)
. = ..(user, infix = ", personal AI")
switch(src.stat)
if(CONSCIOUS)
if(!src.client) . += "It appears to be in stand-by mode." //afk
if(UNCONSCIOUS) . += "<span class='warning'>It doesn't seem to be responding.</span>"
if(DEAD) . += "<span class='deadsay'>It looks completely unsalvageable.</span>"
. += "*---------*"
if(print_flavor_text())
. += "[print_flavor_text()]"
if (pose)
if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
. += "It is [pose]"
/mob/living/silicon/infomorph/Life()
//We're dead or EMP'd or something.
if (src.stat == 2)
return
//Person was sleeved or otherwise moved away from us, become inert card.
if(!ckey || !key)
death(0)
return
//Clean up the cable if it leaves.
if(src.cable)
if(get_dist(src, src.cable) > 1)
var/turf/T = get_turf(src)
T.visible_message("<span class='warning'>\The [src]'s data cable rapidly retracts back into its spool.</span>")
qdel(src.cable)
cable = null
//Wipe all the huds, then readd them (of course...)
handle_regular_hud_updates()
//In response to EMPs, we can be silenced
if(silence_time)
if(world.timeofday >= silence_time)
silence_time = null
to_chat(src, "<font color=green>Communication circuit reinitialized. Speech and messaging functionality restored.</font>")
handle_statuses()
//Only every so often
if(air_master.current_cycle%30 == 1)
SStranscore.m_backup(mind, database_key = db_key)
if(health <= 0)
death(null,"gives one shrill beep before falling lifeless.")
/mob/living/silicon/infomorph/updatehealth()
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
else
health = 100 - getBruteLoss() - getFireLoss()
@@ -1,376 +0,0 @@
/datum/infomorph_software
// Name for the software. This is used as the button text when buying or opening/toggling the software
var/name = "infomorph software module"
// RAM cost; pAIs start with 100 RAM, spending it on programs
var/ram_cost = 0
// ID for the software. This must be unique
var/id = ""
// Whether this software is a toggle or not
// Toggled software should override toggle() and is_active()
// Non-toggled software should override on_ui_interact() and Topic()
var/toggle = 1
// Whether pAIs should automatically receive this module at no cost
var/default = 0
/datum/infomorph_software/tgui_state(mob/user)
return GLOB.tgui_always_state
/datum/infomorph_software/tgui_status(mob/user)
if(!istype(user, /mob/living/silicon/infomorph))
return STATUS_CLOSE
return ..()
/datum/infomorph_software/proc/toggle(mob/living/silicon/infomorph/user)
return
/datum/infomorph_software/proc/is_active(mob/living/silicon/infomorph/user)
return 0
/datum/infomorph_software/crew_manifest
name = "Crew Manifest"
ram_cost = 5
id = "manifest"
toggle = 0
/datum/infomorph_software/crew_manifest/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "CrewManifest", name, parent_ui)
ui.open()
/datum/infomorph_software/crew_manifest/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
if(data_core)
data_core.get_manifest_list()
data["manifest"] = PDA_Manifest
return data
/datum/infomorph_software/med_records
name = "Medical Records"
ram_cost = 15
id = "med_records"
toggle = 0
/datum/infomorph_software/med_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "pAIMedrecords", name, parent_ui)
ui.open()
/datum/infomorph_software/med_records/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
var/list/records = list()
for(var/datum/data/record/general in sortRecord(data_core.general))
var/list/record = list()
record["name"] = general.fields["name"]
record["ref"] = "\ref[general]"
records.Add(list(record))
data["records"] = records
var/datum/data/record/G = user.medicalActive1
var/datum/data/record/M = user.medicalActive2
data["general"] = G ? G.fields : null
data["medical"] = M ? M.fields : null
data["could_not_find"] = user.medical_cannotfind
return data
/datum/infomorph_software/med_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
. = ..()
var/mob/living/silicon/infomorph/P = usr
if(!istype(P))
return
if(action == "select")
var/datum/data/record/record = locate(params["select"])
if(record)
var/datum/data/record/R = record
var/datum/data/record/M = null
if (!( data_core.general.Find(R) ))
P.medical_cannotfind = 1
else
P.medical_cannotfind = 0
for(var/datum/data/record/E in data_core.medical)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
M = E
P.medicalActive1 = R
P.medicalActive2 = M
else
P.medical_cannotfind = 1
return 1
/datum/infomorph_software/sec_records
name = "Security Records"
ram_cost = 15
id = "sec_records"
toggle = 0
/datum/infomorph_software/sec_records/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "pAISecrecords", name, parent_ui)
ui.open()
/datum/infomorph_software/sec_records/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
var/list/records = list()
for(var/datum/data/record/general in sortRecord(data_core.general))
var/list/record = list()
record["name"] = general.fields["name"]
record["ref"] = "\ref[general]"
records.Add(list(record))
data["records"] = records
var/datum/data/record/G = user.securityActive1
var/datum/data/record/S = user.securityActive2
data["general"] = G ? G.fields : null
data["security"] = S ? S.fields : null
data["could_not_find"] = user.security_cannotfind
return data
/datum/infomorph_software/sec_records/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
. = ..()
var/mob/living/silicon/infomorph/P = usr
if(!istype(P))
return
if(action == "select")
var/datum/data/record/record = locate(params["select"])
if(record)
var/datum/data/record/R = record
var/datum/data/record/S = null
if (!( data_core.general.Find(R) ))
P.securityActive1 = null
P.securityActive2 = null
P.security_cannotfind = 1
else
P.security_cannotfind = 0
for(var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
S = E
P.securityActive1 = R
P.securityActive2 = S
else
P.securityActive1 = null
P.securityActive2 = null
P.security_cannotfind = 1
return TRUE
/datum/infomorph_software/door_jack
name = "Door Jack"
ram_cost = 30
id = "door_jack"
toggle = 0
/datum/infomorph_software/door_jack/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "pAIDoorjack", "Door Jack", parent_ui)
ui.open()
/datum/infomorph_software/door_jack/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["cable"] = user.cable != null
data["machine"] = user.cable && (user.cable.machine != null)
data["inprogress"] = user.hackdoor != null
data["progress_a"] = round(user.hackprogress / 10)
data["progress_b"] = user.hackprogress % 10
data["aborted"] = user.hack_aborted
return data
/datum/infomorph_software/door_jack/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
var/mob/living/silicon/infomorph/P = usr
if(!istype(P) || ..())
return TRUE
switch(action)
if("jack")
if(P.cable && P.cable.machine)
P.hackdoor = P.cable.machine
P.hackloop()
return 1
if("cancel")
P.hackdoor = null
return 1
if("cable")
var/turf/T = get_turf(P)
P.hack_aborted = 0
P.cable = new /obj/item/weapon/pai_cable(T)
for(var/mob/M in viewers(T))
M.show_message("<span class='warning'>A port on [P] opens to reveal [P.cable], which promptly falls to the floor.</span>", 3,
"<span class='warning'>You hear the soft click of something light and hard falling to the ground.</span>", 2)
return 1
/mob/living/silicon/infomorph/proc/hackloop()
var/turf/T = get_turf(src)
if(prob(20))
for(var/mob/living/silicon/ai/AI in player_list)
if(T.loc)
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress in [T.loc].</b></font>")
else
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location.</b></font>")
var/obj/machinery/door/D = cable.machine
if(!istype(D))
hack_aborted = 1
hackprogress = 0
cable.machine = null
hackdoor = null
return
while(hackprogress < 100)
//Still working
if(cable && cable.machine == D && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1)
hackprogress = min(hackprogress+rand(1, 3), 100)
//Something went wrong!
else
hack_aborted = 1
hackprogress = 0
//Success!
if(hackprogress >= 100)
hackprogress = 0
D.open()
sleep(10) // Update every second
T.visible_message("<span class='warning'>\The [cable] whips back into \the [src] from \the [hackdoor].</span>")
qdel(cable)
hackdoor = null
/datum/infomorph_software/atmosphere_sensor
name = "Atmosphere Sensor"
ram_cost = 5
id = "atmos_sense"
toggle = 0
/datum/infomorph_software/atmosphere_sensor/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "pAIAtmos", name, parent_ui)
ui.open()
/datum/infomorph_software/atmosphere_sensor/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
var/list/results = list()
var/turf/T = get_turf(user)
if(!isnull(T))
var/datum/gas_mixture/environment = T.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles
if (total_moles)
var/o2_level = environment.gas["oxygen"]/total_moles
var/n2_level = environment.gas["nitrogen"]/total_moles
var/co2_level = environment.gas["carbon_dioxide"]/total_moles
var/phoron_level = environment.gas["phoron"]/total_moles
var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
// entry is what the element is describing
// Type identifies which unit or other special characters to use
// Val is the information reported
// Bad_high/_low are the values outside of which the entry reports as dangerous
// Poor_high/_low are the values outside of which the entry reports as unideal
// Values were extracted from the template itself
results = list(
list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
list("entry" = "Temperature", "units" = "&deg;C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
)
if(isnull(results))
results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80))
data["aircontents"] = results
return data
/datum/infomorph_software/ar_hud
name = "AR HUD"
ram_cost = 15
id = "ar_hud"
/datum/infomorph_software/ar_hud/toggle(mob/living/silicon/infomorph/user)
user.arHUD = !user.arHUD
if(user.plane_holder)
user.plane_holder.set_vis(VIS_CH_ID,user.arHUD)
user.plane_holder.set_vis(VIS_CH_HEALTH_VR,user.arHUD)
/datum/infomorph_software/ar_hud/is_active(mob/living/silicon/infomorph/user)
return user.arHUD
/datum/infomorph_software/translator
name = "Universal Translator"
ram_cost = 15
id = "translator"
/datum/infomorph_software/translator/toggle(mob/living/silicon/infomorph/user)
user.translator.attack_self(user)
/datum/infomorph_software/translator/is_active(mob/living/silicon/infomorph/user)
return user.translator.listening
/datum/infomorph_software/signaller
name = "Remote Signaler"
ram_cost = 5
id = "signaller"
toggle = 0
/datum/infomorph_software/signaller/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Signaler", "Signaler", parent_ui)
ui.open()
/datum/infomorph_software/signaller/tgui_data(mob/living/silicon/infomorph/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
var/obj/item/radio/integrated/signal/R = user.sradio
data["frequency"] = R.frequency
data["minFrequency"] = RADIO_LOW_FREQ
data["maxFrequency"] = RADIO_HIGH_FREQ
data["code"] = R.code
return data
/datum/infomorph_software/signaller/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
var/mob/living/silicon/infomorph/user = usr
if(istype(user))
var/obj/item/radio/integrated/signal/R = user.sradio
switch(action)
if("signal")
spawn(0)
R.send_signal("ACTIVATE")
for(var/mob/O in hearers(1, R.loc))
O.show_message("[bicon(R)] *beep* *beep*", 3, "*beep* *beep*", 2)
if("freq")
var/frequency = unformat_frequency(params["freq"])
frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
R.set_frequency(frequency)
. = TRUE
if("code")
R.code = clamp(round(text2num(params["code"])), 1, 100)
. = TRUE
if("reset")
if(params["reset"] == "freq")
R.set_frequency(initial(R.frequency))
else
R.code = initial(R.code)
. = TRUE
+3 -3
View File
@@ -509,8 +509,8 @@
qdel(G)
src.updateUsrDialog()
return //Don't call up else we'll get attack messsages
if(istype(W, /obj/item/device/sleevecard))
var/obj/item/device/sleevecard/C = W
if(istype(W, /obj/item/device/paicard/sleevecard))
var/obj/item/device/paicard/sleevecard/C = W
user.unEquip(C)
C.removePersonality()
qdel(C)
@@ -556,7 +556,7 @@
return 0
if(mode == 2 && sleevecards) //Card sleeving
var/obj/item/device/sleevecard/card = new /obj/item/device/sleevecard(get_turf(src))
var/obj/item/device/paicard/sleevecard/card = new /obj/item/device/paicard/sleevecard(get_turf(src))
card.sleeveInto(MR, db_key = db_key)
sleevecards--
return 1
+78 -97
View File
@@ -1,60 +1,33 @@
/obj/item/device/radio/sleevecard
canhear_range = 0
/obj/item/device/radio/sleevecard/tgui_state(mob/user)
return GLOB.tgui_always_state
/obj/item/device/sleevecard
/obj/item/device/paicard/sleevecard
name = "sleevecard"
desc = "This KHI-upgraded pAI module has enough capacity to run a whole mind of human-level intelligence."
catalogue_data = list(/datum/category_item/catalogue/information/organization/khi,
/datum/category_item/catalogue/technology/resleeving)
icon = 'icons/obj/pda.dmi'
icon_state = "pai"
item_state = "electronic"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
origin_tech = list(TECH_DATA = 2)
show_messages = 0
var/obj/item/device/radio/sleevecard/radio
var/mob/living/silicon/infomorph/infomorph
var/current_emotion = 1
matter = list(MAT_STEEL = 4000, MAT_GLASS = 4000)
/obj/item/device/sleevecard/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.forced_move(direction, user)
/obj/item/device/paicard/sleevecard/attack_ghost(mob/user as mob)
return
/obj/item/device/sleevecard/New()
..()
add_overlay("pai-off")
radio = new(src)
/obj/item/device/paicard/sleevecard/attackby(var/obj/item/device/sleevemate/I as obj, mob/user as mob)
if(istype(I))
if(I.stored_mind && !pai)
var/datum/mind/M = I.stored_mind
var/datum/transcore_db/db = SStranscore.db_by_mind_name(M.name)
if(db)
to_chat(user, span_notice("You begin uploading [M.name] into \the [src]."))
if(do_after(user,8 SECONDS,src))
var/datum/transhuman/mind_record/record = db.backed_up[M.name]
to_chat(user, span_notice("You have successfully uploaded [M.name] into \the [src]"))
sleeveInto(record)
I.clear_mind()
else
to_chat(user, span_notice("Your sleevemate flashes an error, apparently this mind doesn't have a backup."))
/obj/item/device/sleevecard/Destroy()
if(!isnull(infomorph))
infomorph.death(0)
infomorph = null
QDEL_NULL(radio)
return ..()
/obj/item/device/sleevecard/attack_self(mob/user)
add_fingerprint(user)
if(!infomorph)
to_chat(user,"<span class='warning'>\The [src] does not have a mind in it!</span>")
else
to_chat(user,"<span class='notice'>\The [src] displays the name '[infomorph]'.</span>")
//This is a 'hard' proc, it does no permission checking, do that on the computer
/obj/item/device/sleevecard/proc/sleeveInto(var/datum/transhuman/mind_record/MR, var/db_key)
infomorph = new(src,MR.mindname,db_key=db_key)
/obj/item/device/paicard/sleevecard/proc/sleeveInto(var/datum/transhuman/mind_record/MR, var/db_key)
var/mob/living/silicon/pai/infomorph/infomorph = new(src,MR.mindname,db_key=db_key)
for(var/datum/language/L in MR.languages)
infomorph.add_language(L.name)
@@ -66,65 +39,73 @@
//Don't set 'real_name' because then we get a nice (as sleevecard) thing.
infomorph.name = "[initial(infomorph.name)] ([MR.mindname])"
name = "[initial(name)] ([MR.mindname])"
var/emoname = infomorph_emotions[1]
setEmotion(infomorph_emotions[emoname])
if(infomorph.client)
pai = infomorph
setEmotion(1)
return 1
return 0
/obj/item/device/sleevecard/proc/removePersonality()
if(infomorph)
infomorph.death(0)
/obj/item/device/paicard/sleevecard/attack_self(mob/user)
add_fingerprint(user)
turnOff()
/obj/item/device/sleevecard/proc/turnOff()
if(infomorph)
infomorph.close_up()
cut_overlays()
name = "[initial(name)]"
/obj/item/device/sleevecard/proc/setEmotion(var/emotion)
if(infomorph && emotion)
cut_overlays()
switch(emotion)
if(1) add_overlay("pai-happy")
if(2) add_overlay("pai-cat")
if(3) add_overlay("pai-extremely-happy")
if(4) add_overlay("pai-face")
if(5) add_overlay("pai-laugh")
if(6) add_overlay("pai-off")
if(7) add_overlay("pai-sad")
if(8) add_overlay("pai-angry")
if(9) add_overlay("pai-what")
if(10) add_overlay("pai-neutral")
if(11) add_overlay("pai-silly")
if(12) add_overlay("pai-nose")
if(13) add_overlay("pai-smirk")
if(14) add_overlay("pai-exclamation")
if(15) add_overlay("pai-question")
current_emotion = emotion
/obj/item/device/sleevecard/emp_act(severity)
for(var/mob/M in src)
M.emp_act(severity)
/obj/item/device/sleevecard/ex_act(severity)
if(infomorph)
infomorph.ex_act(severity)
if(!pai)
to_chat(user,"<span class='warning'>\The [src] does not have a mind in it!</span>")
else
qdel(src)
to_chat(user,"<span class='notice'>\The [src] displays the name '[pai]'.</span>")
/obj/item/device/sleevecard/see_emote(mob/living/M, text)
if(infomorph && infomorph.client && !infomorph.canmove)
var/rendered = "<span class='message'>[text]</span>"
infomorph.show_message(rendered, 2)
/mob/living/silicon/pai/infomorph
name = "sleevecard" //Has the same name as the card for consistency, but this is the MOB in the card.
ram = 35
/mob/living/silicon/pai/infomorph/New(var/obj/item/device/paicard/sleevecard/SC, var/name = "Unknown", var/db_key)
..()
/obj/item/device/sleevecard/show_message(msg, type, alt, alt_type)
if(infomorph && infomorph.client)
var/rendered = "<span class='message'>[msg]</span>"
infomorph.show_message(rendered, type)
..()
name = "[initial(name)] ([name])"
//PDA
pda.ownjob = "Sleevecard"
pda.owner = text("[]", src)
pda.name = pda.owner + " (" + pda.ownjob + ")"
/mob/living/silicon/pai/infomorph/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
// Software we have bought
var/list/bought_software = list()
// Software we have not bought
var/list/not_bought_software = list()
for(var/key in pai_software_by_key)
var/datum/pai_software/S = pai_software_by_key[key]
var/software_data[0]
if(istype(S, /datum/pai_software/directives))
continue
software_data["name"] = S.name
software_data["id"] = S.id
if(key in software)
software_data["on"] = S.is_active(src)
bought_software.Add(list(software_data))
else
software_data["ram"] = S.ram_cost
not_bought_software.Add(list(software_data))
data["bought"] = bought_software
data["not_bought"] = not_bought_software
data["available_ram"] = ram
// Emotions
var/list/emotions = list()
for(var/name in pai_emotions)
var/list/emote = list()
emote["name"] = name
emote["id"] = pai_emotions[name]
emotions.Add(list(emote))
data["emotions"] = emotions
data["current_emotion"] = card.current_emotion
return data
@@ -1449,7 +1449,7 @@
//thedavestdave Lucky
///I know this is pretty bodgey but if it stupid and it works it isn't stupid
/obj/item/clothing/suit/storage/hooded/explorer/lucky
/obj/item/clothing/suit/armor/combat/crusader_costume/lucky
icon = 'icons/vore/custom_clothes_vr.dmi'
icon_state = "luck"
icon_override = 'icons/vore/custom_clothes_vr.dmi'
@@ -1458,15 +1458,6 @@
desc = "A chain mail suit with a badly drawn one eared cat on the front."
/obj/item/device/modkit_conversion/crusader_luck
skip_content_check = TRUE
name = "Lucky's armor"
desc = "A chain mail suit with a badly drawn one eared cat on the front."
icon = 'icons/vore/custom_items_vr.dmi'
icon_state = "modkit"
from_suit = /obj/item/clothing/suit/storage/hooded/explorer
to_suit = /obj/item/clothing/suit/storage/hooded/explorer/lucky
//RevolverEloise - Revolver Eloise
/obj/item/weapon/sword/fluff/revolver
name = "Catnip"
@@ -1496,7 +1487,7 @@
icon = 'icons/vore/custom_items_vr.dmi'
icon_state = "lemonplush"
attack_verb = list("blorbled", "slimed", "absorbed", "glomped")
//Bricker98:Nettie Stough
/obj/item/modular_computer/tablet/preset/custom_loadout/nettie
name = "Remodeled Tablet"
+1
View File
@@ -76,6 +76,7 @@ VIRGO3B_TURF_CREATE(/turf/simulated/floor/outdoors/rocks)
desc = "Magnetic levitation tram tracks. Caution! Electrified!"
icon = 'icons/turf/flooring/maglevs.dmi'
icon_state = "maglevup"
can_be_plated = FALSE
var/area/shock_area = /area/centcom/terminal/tramfluff
@@ -10,6 +10,7 @@
desc = "Magnetic levitation tram tracks. Caution! Electrified!"
icon = 'icons/turf/flooring/maglevs.dmi'
icon_state = "maglevup"
can_be_plated = FALSE
var/area/shock_area = /area/tether/surfacebase/tram
+1
View File
@@ -145,6 +145,7 @@
desc = "Magnetic levitation tram tracks. Caution! Electrified!"
icon = 'icons/turf/flooring/maglevs.dmi'
icon_state = "maglevup"
can_be_plated = FALSE
var/area/shock_area = /area/tether/surfacebase/tram
-3
View File
@@ -1625,7 +1625,6 @@
#include "code\game\turfs\simulated\outdoors\grass.dm"
#include "code\game\turfs\simulated\outdoors\ironsand_vr.dm"
#include "code\game\turfs\simulated\outdoors\outdoors.dm"
#include "code\game\turfs\simulated\outdoors\outdoors_attackby.dm"
#include "code\game\turfs\simulated\outdoors\outdoors_vr.dm"
#include "code\game\turfs\simulated\outdoors\sky.dm"
#include "code\game\turfs\simulated\outdoors\snow.dm"
@@ -3745,8 +3744,6 @@
#include "code\modules\resleeving\documents.dm"
#include "code\modules\resleeving\implant.dm"
#include "code\modules\resleeving\infocore_records.dm"
#include "code\modules\resleeving\infomorph.dm"
#include "code\modules\resleeving\infomorph_software.dm"
#include "code\modules\resleeving\machine_subtypes.dm"
#include "code\modules\resleeving\machines.dm"
#include "code\modules\resleeving\resleeving_sickness.dm"