diff --git a/code/__defines/span_vr.dm b/code/__defines/span_vr.dm
index 618fd52b3d1..737d1a81ada 100644
--- a/code/__defines/span_vr.dm
+++ b/code/__defines/span_vr.dm
@@ -40,7 +40,7 @@
#define span_danger(str) ("" + str + "")
#define span_warning(str) ("" + str + "")
#define span_rose(str) ("" + str + "")
-#define span_info(str) ("" + str + ""
+#define span_info(str) ("" + str + "")
#define span_notice(str) ("" + str + "")
#define span_alium(str) ("" + str + "")
#define span_cult(str) ("" + str + "")
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index f110251a17c..23df9d8ab1a 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -360,3 +360,40 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
var/rendered = "[msg]"
pai.show_message(rendered, type)
..()
+
+
+// VoreEdit: Living Machine Stuff after this.
+// This adds a var and proc for all machines to take a pAI. (The pAI can't control anything, it's just for RP.)
+// You need to add usage of the proc to each machine to actually add support. For an example of this, see code\modules\food\kitchen\microwave.dm
+/obj/machinery
+ var/obj/item/device/paicard/paicard = null
+
+/obj/machinery/proc/insertpai(mob/user, obj/item/device/paicard/card)
+ //var/obj/item/paicard/card = I
+ var/mob/living/silicon/pai/AI = card.pai
+ if(paicard)
+ to_chat(user, span_notice("This bot is already under PAI Control!"))
+ return
+ if(!istype(card)) // TODO: Add sleevecard support.
+ return
+ if(!card.pai)
+ to_chat(user, span_notice("This card does not currently have a personality!"))
+ return
+ paicard = card
+ user.unEquip(card)
+ card.forceMove(src)
+ AI.client.eye = src
+ to_chat(AI, span_notice("Your location is [card.loc].")) // DEBUG. TODO: Make unfolding the chassis trigger an eject.
+ name = AI.name
+ to_chat(AI, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)]."))
+
+/obj/machinery/proc/ejectpai(mob/user)
+ if(paicard)
+ var/mob/living/silicon/pai/AI = paicard.pai
+ paicard.forceMove(src.loc)
+ AI.client.eye = AI
+ paicard = null
+ name = initial(src.name)
+ to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)]."))
+ if(user)
+ to_chat(user, span_notice("You eject the card from \the [initial(src.name)]."))
\ No newline at end of file
diff --git a/code/modules/food/kitchen/microwave.dm b/code/modules/food/kitchen/microwave.dm
index bab265f004b..b149aef9d2e 100644
--- a/code/modules/food/kitchen/microwave.dm
+++ b/code/modules/food/kitchen/microwave.dm
@@ -22,7 +22,7 @@
var/global/list/acceptable_items // List of the items you can put in
var/global/list/available_recipes // List of the recipes you can use
var/global/list/acceptable_reagents // List of the reagents you can put in
-
+
var/global/max_n_of_items = 20
var/appliancetype = MICROWAVE
var/datum/looping_sound/microwave/soundloop
@@ -36,7 +36,7 @@
/obj/machinery/microwave/Initialize()
. = ..()
-
+
reagents = new/datum/reagents(100)
reagents.my_atom = src
@@ -47,7 +47,7 @@
for(var/datum/recipe/typepath as anything in subtypesof(/datum/recipe))
if((initial(typepath.appliance) & appliancetype))
available_recipes += new typepath
-
+
acceptable_items = new
acceptable_reagents = new
for (var/datum/recipe/recipe in available_recipes)
@@ -66,6 +66,8 @@
soundloop = new(list(src), FALSE)
/obj/machinery/microwave/Destroy()
+ if(paicard)
+ ejectpai() // Lets not delete the pAI.
QDEL_NULL(soundloop)
return ..()
@@ -125,7 +127,8 @@
to_chat(user, "It's dirty!")
return 1
else if(is_type_in_list(O,acceptable_items))
- if(contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var.
+ var/list/workingList = cookingContents()
+ if(workingList.len>=(max_n_of_items + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var.
to_chat(user, "This [src] is full of ingredients, you cannot put more.")
return 1
if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it
@@ -180,6 +183,9 @@
to_chat(user, "You decide not to do that.")
else if(default_part_replacement(user, O))
return
+ else if(istype(O, /obj/item/device/paicard))
+ if(!paicard)
+ insertpai(user, O)
else
to_chat(user, "You have no idea what you can cook with this [O].")
..()
@@ -192,6 +198,10 @@
attack_hand(user)
/obj/machinery/microwave/attack_hand(mob/user as mob)
+ if(user.a_intent == I_GRAB)
+ if(paicard)
+ ejectpai(user)
+ return
user.set_machine(src)
tgui_interact(user)
@@ -211,7 +221,7 @@
data["operating"] = operating
data["dirty"] = dirty == 100
data["items"] = get_items_list()
-
+
return data
/obj/machinery/microwave/proc/get_items_list()
@@ -220,7 +230,8 @@
var/list/items_counts = list()
var/list/items_measures = list()
var/list/items_measures_p = list()
- for(var/obj/O in ((contents - component_parts) - circuit))
+ //for(var/obj/O in ((contents - component_parts) - circuit))
+ for(var/obj/O in cookingContents())
var/display_name = O.name
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg))
items_measures[display_name] = "egg"
@@ -283,7 +294,7 @@
if("dispose")
dispose()
return TRUE
-/*
+/*
/obj/machinery/microwave/interact(mob/user as mob) // The microwave Menu
var/dat = ""
if(src.broken > 0)
@@ -355,7 +366,7 @@
if(stat & (NOPOWER|BROKEN))
return
start()
- if(reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run
+ if(reagents.total_volume==0 && !(locate(/obj) in cookingContents())) //dry run
if(!wzhzhzh(16)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 5)
abort()
return
@@ -390,7 +401,7 @@
cooked = fail()
cooked.forceMove(src.loc)
return
-
+
//Making multiple copies of a recipe
var/halftime = round(recipe.time*4/10/2) // VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was round(recipe.time/20/2))
if(!wzhzhzh(halftime))
@@ -451,7 +462,7 @@
/obj/machinery/microwave/proc/has_extra_item() //- coded to have different microwaves be able to handle different items
if(item_level == 0)
- for (var/obj/O in ((contents - component_parts) - circuit))
+ for (var/obj/O in cookingContents())
if ( \
!istype(O,/obj/item/weapon/reagent_containers/food) && \
!istype(O, /obj/item/weapon/grown) \
@@ -459,7 +470,7 @@
return 1
return 0
if(item_level == 1)
- for (var/obj/O in ((contents - component_parts) - circuit))
+ for (var/obj/O in cookingContents())
if ( \
!istype(O, /obj/item/weapon/reagent_containers/food) && \
!istype(O, /obj/item/weapon/grown) && \
@@ -483,7 +494,7 @@
icon_state = "mw"
SStgui.update_uis(src)
soundloop.stop()
-
+
/obj/machinery/microwave/proc/stop()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
operating = FALSE // Turn it off again aferwards
@@ -493,7 +504,7 @@
soundloop.stop()
/obj/machinery/microwave/proc/dispose(var/message = 1)
- for (var/atom/movable/A in ((contents-component_parts)-circuit))
+ for (var/atom/movable/A in cookingContents())
A.forceMove(loc)
if (src.reagents.total_volume)
src.dirty++
@@ -527,11 +538,12 @@
src.operating = 0 // Turn it off again aferwards
SStgui.update_uis(src)
soundloop.stop()
+ src.ejectpai() // If it broke, time to yeet the PAI.
/obj/machinery/microwave/proc/fail()
var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
var/amount = 0
- for (var/obj/O in (((contents - ffuu) - component_parts) - circuit))
+ for (var/obj/O in cookingContents())
amount++
if(O.reagents)
var/id = O.reagents.get_master_reagent_id()
@@ -558,14 +570,14 @@
if(!do_after(usr, 1 SECONDS, target = src))
return
-
+
if(operating)
to_chat(usr, "You can't do that, [src] door is locked!")
return
usr.visible_message(
- "[usr] opened [src] and has taken out [english_list(((contents-component_parts)-circuit))]." ,
- "You have opened [src] and taken out [english_list(((contents-component_parts)-circuit))]."
+ "[usr] opened [src] and has taken out [english_list(cookingContents())]." ,
+ "You have opened [src] and taken out [english_list(cookingContents())]."
)
dispose()
@@ -594,7 +606,7 @@
/obj/item/weapon/holder
)
result = /obj/effect/decal/cleanable/blood/gibs
-
+
/datum/recipe/splat/before_cook(obj/container)
if(istype(container, /obj/machinery/microwave))
var/obj/machinery/microwave/M = container
@@ -617,3 +629,14 @@
var/obj/machinery/microwave/M = container
M.muck_finish()
. = ..()
+
+/obj/machinery/microwave/proc/cookingContents() //VOREEdit, this is a better way to deal with the contents of a microwave, since the previous method is stupid.
+ var/list/workingList = contents.Copy() // Using the copy proc because otherwise the two lists seem to become soul bonded.
+ workingList -= component_parts
+ workingList -= circuit
+ if(paicard)
+ workingList -= paicard
+ for(var/M in workingList)
+ if(istype(M, circuit)) // Yes, we remove circuit twice. Yes, it's necessary. Yes, it's stupid.
+ workingList -= M
+ return workingList
\ No newline at end of file
diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm
index 2bc63f1bfea..206d9f0321b 100644
--- a/code/modules/mob/living/bot/bot.dm
+++ b/code/modules/mob/living/bot/bot.dm
@@ -17,7 +17,7 @@
var/emagged = 0
var/light_strength = 3
var/busy = 0
-
+ var/obj/item/device/paicard/paicard = null
var/obj/access_scanner = null
var/list/req_access = list()
var/list/req_one_access = list()
@@ -72,10 +72,27 @@
SetStunned(0)
SetParalysis(0)
- if(on && !client && !busy)
+ if(on && !client && !busy && !paicard)
spawn(0)
handleAI()
-
+/*
+/mob/living/bot/examine(mob/user)
+ . = ..()
+ if(health < maxHealth)
+ if(health > maxHealth/3)
+ . += "[src]'s parts look loose."
+ else
+ . += "[src]'s parts look very loose!"
+ else
+ . += "[src] is in pristine condition."
+ . += span_notice("Its maintenance panel is [open ? "open" : "closed"].")
+ . += span_info("You can use a screwdriver to [open ? "close" : "open"] it.")
+ . += span_notice("Its control panel is [locked ? "locked" : "unlocked"].")
+ if(paicard)
+ . += span_notice("It has a pAI device installed.")
+ if(open)
+ . += span_info("You can use a crowbar to remove it.")
+*/
/mob/living/bot/updatehealth()
if(status_flags & GODMODE)
health = getMaxHealth()
@@ -138,6 +155,17 @@
qdel(O)
else
to_chat(user, "Unable to repair with the maintenance panel closed.")
+ else if(istype(O, /obj/item/device/paicard))
+ if(open)
+ insertpai(user, O)
+ to_chat(user, span_notice("You slot the card into \the [initial(src.name)]."))
+ else
+ to_chat(user, span_notice("You must open the panel first!"))
+ else if(O.is_crowbar())
+ if(open && paicard)
+ to_chat(user, span_notice("You are attempting to remove the pAI.."))
+ if(do_after(user,10 * O.toolspeed))
+ ejectpai(user)
else
..()
@@ -203,6 +231,13 @@
if(LAZYLEN(can_go))
if(step_towards(src, pick(can_go)))
return
+ for(var/mob in loc)
+ if(istype(mob, /mob/living/bot) && mob != src) // Same as above, but we also don't want to have bots ontop of bots. Cleanbots shouldn't stack >:(
+ var/turf/my_turf = get_turf(src)
+ var/list/can_go = my_turf.CardinalTurfsWithAccess(botcard)
+ if(LAZYLEN(can_go))
+ if(step_towards(src, pick(can_go)))
+ return
handleIdle()
/mob/living/bot/proc/handleRegular()
@@ -351,9 +386,14 @@
update_icons()
/mob/living/bot/proc/explode()
+ if(paicard)
+ ejectpai()
+ release_vore_contents()
qdel(src)
/mob/living/bot/is_sentient()
+ if(paicard)
+ return TRUE
return FALSE
/******************************************************************/
@@ -443,3 +483,68 @@
/mob/living/bot/isSynthetic() //Robots are synthetic, no?
return 1
+
+/mob/living/bot/proc/insertpai(mob/user, obj/item/device/paicard/card)
+ //var/obj/item/paicard/card = I
+ var/mob/living/silicon/pai/AI = card.pai
+ if(paicard)
+ to_chat(user, span_notice("This bot is already under PAI Control!"))
+ return
+ if(!istype(card)) // TODO: Add sleevecard support.
+ return
+ if(client)
+ to_chat(user, span_notice("Higher levels of processing are already present!"))
+ return
+ if(!card.pai)
+ to_chat(user, span_notice("This card does not currently have a personality!"))
+ return
+ paicard = card
+ user.unEquip(card)
+ card.forceMove(src)
+ src.ckey = AI.ckey
+ name = AI.name
+ ooc_notes = AI.ooc_notes
+ to_chat(src, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)]."))
+ if(AI.idcard.access)
+ botcard.access |= AI.idcard.access
+
+/mob/living/bot/proc/ejectpai(mob/user)
+ if(paicard)
+ var/mob/living/silicon/pai/AI = paicard.pai
+ AI.ckey = src.ckey
+ AI.ooc_notes = ooc_notes
+ paicard.forceMove(src.loc)
+ paicard = null
+ name = initial(name)
+ botcard.access = botcard_access.Copy()
+ to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)]."))
+
+ if(user)
+ to_chat(user, span_notice("You eject the card from \the [initial(src.name)]."))
+
+/mob/living/bot/verb/bot_nom(var/mob/living/T in oview(1))
+ set name = "Bot Nom"
+ set category = "Bot Commands"
+ set desc = "Allows you to eat someone. Yum."
+
+ if (stat != CONSCIOUS)
+ return
+ return feed_grabbed_to_self(src,T)
+
+/mob/living/bot/verb/ejectself()
+ set name = "Eject pAI"
+ set category = "Bot Commands"
+ set desc = "Eject your card, return to smole."
+
+ return ejectpai()
+
+/mob/living/bot/Login()
+ no_vore = FALSE // ROBOT VORE
+ init_vore() // ROBOT VORE
+ verbs |= /mob/living/proc/insidePanel
+
+/mob/living/bot/Logout()
+ no_vore = TRUE // ROBOT VORE
+ release_vore_contents()
+ init_vore() // ROBOT VORE
+ verbs -= /mob/living/proc/insidePanel
\ No newline at end of file
diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm
index 061574bd645..f60bccbfc32 100644
--- a/code/modules/mob/living/bot/cleanbot.dm
+++ b/code/modules/mob/living/bot/cleanbot.dm
@@ -140,8 +140,8 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
- qdel(src)
- return
+ //qdel(src)
+ return ..()
/mob/living/bot/cleanbot/update_icons()
if(busy)
diff --git a/code/modules/mob/living/bot/ed209bot.dm b/code/modules/mob/living/bot/ed209bot.dm
index 17d2da7878e..8700988e592 100644
--- a/code/modules/mob/living/bot/ed209bot.dm
+++ b/code/modules/mob/living/bot/ed209bot.dm
@@ -49,7 +49,7 @@
s.start()
new /obj/effect/decal/cleanable/blood/oil(Tsec)
- qdel(src)
+ return ..()
/mob/living/bot/secbot/ed209/handleRangedTarget()
RangedAttack(target)
diff --git a/code/modules/mob/living/bot/edCLNbot.dm b/code/modules/mob/living/bot/edCLNbot.dm
index bbb1e9861d8..ce0edabe088 100644
--- a/code/modules/mob/living/bot/edCLNbot.dm
+++ b/code/modules/mob/living/bot/edCLNbot.dm
@@ -68,8 +68,8 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
- qdel(src)
- return
+ //qdel(src)
+ return ..()
/mob/living/bot/cleanbot/edCLN/tgui_data(mob/user)
var/list/data = ..()
diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm
index 083da22d3d1..969bfc1c831 100644
--- a/code/modules/mob/living/bot/farmbot.dm
+++ b/code/modules/mob/living/bot/farmbot.dm
@@ -286,8 +286,8 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
- qdel(src)
- return
+ //qdel(src)
+ return ..()
/mob/living/bot/farmbot/confirmTarget(var/atom/targ)
diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm
index 9e869e0d81a..a7a7def771c 100644
--- a/code/modules/mob/living/bot/floorbot.dm
+++ b/code/modules/mob/living/bot/floorbot.dm
@@ -42,7 +42,7 @@
data["on"] = on
data["open"] = open
data["locked"] = locked
-
+
data["vocal"] = vocal
data["amount"] = amount
@@ -75,7 +75,7 @@
/mob/living/bot/floorbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
-
+
add_fingerprint(src)
switch(action)
@@ -85,7 +85,7 @@
else
turn_on()
. = TRUE
-
+
if(locked && !issilicon(usr))
return
@@ -302,7 +302,8 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
- qdel(src)
+ //qdel(src)
+ return ..()
/mob/living/bot/floorbot/proc/addTiles(var/am)
amount += am
diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm
index 39b0b882bb1..ced48594f1c 100644
--- a/code/modules/mob/living/bot/medbot.dm
+++ b/code/modules/mob/living/bot/medbot.dm
@@ -268,10 +268,10 @@
/mob/living/bot/medbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
-
+
usr.set_machine(src)
add_fingerprint(usr)
-
+
. = TRUE
switch(action)
if("power")
@@ -348,8 +348,8 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
- qdel(src)
- return
+ //qdel(src)
+ return ..()
/mob/living/bot/medbot/handleRegular()
. = ..()
diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm
index 66134335725..f6a868d11aa 100644
--- a/code/modules/mob/living/bot/secbot.dm
+++ b/code/modules/mob/living/bot/secbot.dm
@@ -128,7 +128,7 @@
/mob/living/bot/secbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return
-
+
add_fingerprint(usr)
switch(action)
@@ -379,7 +379,8 @@
s.start()
new /obj/effect/decal/cleanable/blood/oil(Tsec)
- qdel(src)
+ //qdel(src)
+ return ..()
/mob/living/bot/secbot/proc/target_name(mob/living/T)
if(ishuman(T))
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 7df66eaff46..a1764fbcd26 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -127,7 +127,7 @@
pda.ownjob = "Personal Assistant"
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
@@ -247,6 +247,9 @@
last_special = world.time + 100
+ if(istype(card.loc, /obj/machinery)) // VOREStation edit, this statement allows pAIs stuck in a machine to eject themselves.
+ var/obj/machinery/M = card.loc
+ M.ejectpai()
//I'm not sure how much of this is necessary, but I would rather avoid issues.
if(istype(card.loc,/obj/item/rig_module))
to_chat(src, "There is no room to unfold inside this rig module. You're good and stuck.")