diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index f67b3b9f7e1..20f82d3a0bc 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -49,7 +49,7 @@ grabber << "You scoop up \the [src]." src << "\The [grabber] scoops you up." grabber.status_flags |= PASSEMOTES - return + return H //Mob specific holders. @@ -65,4 +65,9 @@ name = "maintenance drone" desc = "It's a small maintenance robot." icon_state = "drone" - origin_tech = "magnets=3;engineering=5" \ No newline at end of file + origin_tech = "magnets=3;engineering=5" + +/obj/item/weapon/holder/pai + name = "pAI" + desc = "It's a little robot." + icon_state = "pai" diff --git a/code/modules/mob/living/silicon/pai/emote.dm b/code/modules/mob/living/silicon/pai/emote.dm new file mode 100644 index 00000000000..d66d7f555b6 --- /dev/null +++ b/code/modules/mob/living/silicon/pai/emote.dm @@ -0,0 +1,90 @@ +/mob/living/silicon/pai/emote(var/act,var/m_type=1,var/message = null) + var/param = null + if (findtext(act, "-", 1, null)) + var/t1 = findtext(act, "-", 1, null) + param = copytext(act, t1 + 1, length(act) + 1) + act = copytext(act, 1, t1) + + if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' + act = copytext(act,1,length(act)) + + //Emote Cooldown System (it's so simple!) + // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] + var/on_CD = 0 + switch(act) + //Cooldown-inducing emotes + if("ping","buzz") + on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + //Everything else, including typos of the above emotes + else + on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown + + if(on_CD == 1) // Check if we need to suppress the emote attempt. + return // Suppress emote, you're still cooling off. + //--FalseIncarnate + + switch(act) + if ("me") + if (src.client) + if(client.prefs.muted & MUTE_IC) + src << "You cannot send IC messages (muted)." + return + if (src.client.handle_spam_prevention(message,MUTE_IC)) + return + if (stat) + return + if(!(message)) + return + else + return custom_emote(m_type, message) + + if ("custom") + return custom_emote(m_type, message) + + if("ping") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] pings at [param]." + else + message = "[src] pings." + playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + m_type = 1 + + if("buzz") + var/M = null + if(param) + for (var/mob/A in view(null, null)) + if (param == A.name) + M = A + break + if(!M) + param = null + + if (param) + message = "[src] buzzes at [param]." + else + message = "[src] buzzes." + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + m_type = 1 + + if ("help") + src << "ping, \nbuzz." + else + src << "\blue Unusable emote '[act]'. Say *help for a list." + + if ((message && src.stat == 0)) + if (m_type & 1) + for(var/mob/O in viewers(src, null)) + O.show_message(message, m_type) + else + for(var/mob/O in hearers(src, null)) + O.show_message(message, m_type) + return \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index b8d54dacbff..4dc1758066f 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -8,7 +8,7 @@ small = 1 pass_flags = 1 density = 0 - + holder_type = /obj/item/weapon/holder/pai var/network = "SS13" var/obj/machinery/camera/current = null @@ -25,7 +25,11 @@ "Mouse" = "mouse", "Monkey" = "monkey", "Corgi" = "borgi", - "Fox" = "fox" + "Fox" = "fox", + "Parrot" = "parrot", + "Box Bot" = "boxbot", + "Spider Bot" = "spiderbot", + "Fairy" = "fairy" ) var/global/list/possible_say_verbs = list( @@ -461,6 +465,16 @@ src.client.perspective = EYE_PERSPECTIVE src.client.eye = card +// 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.unEquip(H) + H.loc = get_turf(src) + src.loc = get_turf(H) + + // Move us into the card and move the card to the ground //This seems redundant but not including the forced loc setting messes the behavior up. src.loc = card card.loc = get_turf(card) @@ -520,6 +534,31 @@ // No binary for pAIs. /mob/living/silicon/pai/binarycheck() return 0 + +// Handle being picked up. + + +/mob/living/silicon/pai/get_scooped(var/mob/living/carbon/grabber) + var/obj/item/weapon/holder/H = ..() + if(!istype(H)) + return + H.icon_state = "pai-[icon_state]" + H.item_state = "pai-[icon_state]" + H.icon_override = 'icons/mob/in-hand/paiheld.dmi'//I have these in diffrent DMI so i am overriding + grabber.put_in_active_hand(H)//for some reason unless i call this it dosen't work + grabber.update_inv_l_hand() + grabber.update_inv_r_hand() + + return H + +/mob/living/silicon/pai/MouseDrop(atom/over_object) + var/mob/living/carbon/H = over_object + if(!istype(H) || !Adjacent(H)) return ..() + if(H.a_intent == "help") + get_scooped(H) + //return + else + return ..() /mob/living/silicon/pai/on_forcemove(atom/newloc) if(card) diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index 4e04e619c44..07bde3732c4 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -549,3 +549,42 @@ P.sradio.code = min(100, P.sradio.code) P.sradio.code = max(1, P.sradio.code) return 1 + +/datum/pai_software/host_scan + name = "Host Bioscan" + ram_cost = 5 + id = "bioscan" + toggle = 0 + + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + + var/data[0] + var/mob/living/held = user.loc + var/count = 0 + + // Find the carrier + while(!isliving(held)) + if(!held || !held.loc || count > 6) + //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) + src << "You are not being carried by anyone!" + return 0 + held = held.loc + count++ + if(isliving(held)) + data["holder"] = held + data["health"] = "[held.stat > 1 ? "dead" : "[held.health]% healthy"]" + data["oxy"] = "[held.getOxyLoss() > 50 ? "" : ""][held.getOxyLoss()]" + data["tox"] = "[held.getToxLoss() > 50 ? "" : ""][held.getToxLoss()]" + data["burn"] = "[held.getFireLoss() > 50 ? "" : ""][held.getFireLoss()]" + data["temp"] = "[held.bodytemperature-T0C]°C ([held.bodytemperature*1.8-459.67]°F)" + else + data["holder"] = 0 + + ui = nanomanager.try_update_ui(user, user, id, ui,data , force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_bioscan.tmpl", "Host Bioscan", 400, 350) + ui.set_initial_data(data) + ui.open() + //.set_auto_update(1) diff --git a/icons/mob/in-hand/paiheld.dmi b/icons/mob/in-hand/paiheld.dmi new file mode 100644 index 00000000000..fe50e96da35 Binary files /dev/null and b/icons/mob/in-hand/paiheld.dmi differ diff --git a/icons/mob/pai.dmi b/icons/mob/pai.dmi index 6057915fbbb..0f67135e0fe 100644 Binary files a/icons/mob/pai.dmi and b/icons/mob/pai.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 7393f11d276..b081f62ac65 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/nano/templates/pai_bioscan.tmpl b/nano/templates/pai_bioscan.tmpl new file mode 100644 index 00000000000..fb5d99b2286 --- /dev/null +++ b/nano/templates/pai_bioscan.tmpl @@ -0,0 +1,27 @@ + + +{{if data.holder}} +
+
+ Bioscan Results for {{:data.holder}} : +
+
+ Health Status : {{:data.health}} +
+
+ Oxygen Content : {{:data.oxy}} +
+ Toxin Cotnet : {{:data.tox}} +
+
+ Burn Status : {{:data.burn}} +
+
+ User Temprature : {{:data.temp}} +
+
+{{else}} + Error: No biological host found! +{{/if}} \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 22ee01225f2..b17128a95b3 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1384,6 +1384,7 @@ #include "code\modules\mob\living\silicon\decoy\decoy.dm" #include "code\modules\mob\living\silicon\decoy\life.dm" #include "code\modules\mob\living\silicon\pai\death.dm" +#include "code\modules\mob\living\silicon\pai\emote.dm" #include "code\modules\mob\living\silicon\pai\examine.dm" #include "code\modules\mob\living\silicon\pai\life.dm" #include "code\modules\mob\living\silicon\pai\pai.dm"