mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-29 07:59:01 +01:00
pAI Bot Piloting (#8840)
pAI can now pilot farmbots, cleanbots, floorbots and medbots.
Floating messages now appear even if you're inside an object or another mob.
This commit is contained in:
@@ -43,8 +43,8 @@ var/list/floating_chat_colors = list()
|
||||
else
|
||||
C.images += gibberish
|
||||
|
||||
/proc/generate_floating_text(atom/movable/holder, message, style, size, duration, show_to)
|
||||
var/image/I = image(null, holder)
|
||||
/proc/generate_floating_text(atom/movable/holder, message, style, size, duration, show_to)
|
||||
var/image/I = image(null, recursive_loc_turf_check(holder))
|
||||
I.layer = FLY_LAYER
|
||||
I.alpha = 0
|
||||
I.maptext_width = 80
|
||||
@@ -68,4 +68,4 @@ var/list/floating_chat_colors = list()
|
||||
|
||||
/proc/remove_floating_text(atom/movable/holder, image/I)
|
||||
animate(I, 2, pixel_y = I.pixel_y + 10, alpha = 0)
|
||||
LAZYREMOVE(holder.stored_chat_text, I)
|
||||
LAZYREMOVE(holder.stored_chat_text, I)
|
||||
@@ -4,21 +4,27 @@
|
||||
maxHealth = 20
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
layer = MOB_LAYER
|
||||
universal_speak = 1
|
||||
density = 0
|
||||
var/obj/item/card/id/botcard = null
|
||||
universal_speak = TRUE
|
||||
density = FALSE
|
||||
var/obj/item/card/id/botcard
|
||||
var/list/botcard_access = list()
|
||||
var/on = 1
|
||||
var/open = 0
|
||||
var/locked = 1
|
||||
var/emagged = 0
|
||||
var/on = TRUE
|
||||
var/open = FALSE
|
||||
var/locked = TRUE
|
||||
var/emagged = FALSE
|
||||
var/light_strength = 3
|
||||
|
||||
var/obj/access_scanner = null
|
||||
var/obj/access_scanner
|
||||
var/list/req_access = list()
|
||||
var/list/req_one_access = list()
|
||||
var/master_access = access_robotics
|
||||
|
||||
var/last_emote = 0 // timer for emotes
|
||||
|
||||
var/can_take_pai = TRUE
|
||||
var/obj/item/device/paicard/pAI
|
||||
var/old_name
|
||||
|
||||
/mob/living/bot/Initialize()
|
||||
. = ..()
|
||||
update_icons()
|
||||
@@ -31,10 +37,22 @@
|
||||
access_scanner.req_one_access = req_one_access.Copy()
|
||||
|
||||
/mob/living/bot/Destroy()
|
||||
if(pAI)
|
||||
if(isturf(loc))
|
||||
drop_from_inventory(pAI, get_turf(src))
|
||||
pAI.throw_at_random(FALSE, 3, 1)
|
||||
else
|
||||
drop_from_inventory(pAI, loc)
|
||||
pAI = null
|
||||
QDEL_NULL(botcard)
|
||||
QDEL_NULL(access_scanner)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/examine(mob/user, distance, infix, suffix)
|
||||
. = ..()
|
||||
if(pAI)
|
||||
to_chat(user, FONT_SMALL(SPAN_NOTICE("It has a pAI piloting it.")))
|
||||
|
||||
/mob/living/bot/Life()
|
||||
..()
|
||||
if(health <= 0)
|
||||
@@ -44,6 +62,9 @@
|
||||
stunned = 0
|
||||
paralysis = 0
|
||||
|
||||
/mob/living/bot/movement_delay()
|
||||
return 3
|
||||
|
||||
/mob/living/bot/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
health = maxHealth
|
||||
@@ -56,54 +77,82 @@
|
||||
|
||||
/mob/living/bot/proc/has_master_access(var/obj/item/I)
|
||||
var/list/L = I.GetAccess()
|
||||
if (master_access in L)
|
||||
return 1
|
||||
if(master_access in L)
|
||||
return TRUE
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/mob/living/bot/proc/has_ui_access(mob/user)
|
||||
if (access_scanner.allowed(user))
|
||||
return 1
|
||||
if (!locked)
|
||||
return 1
|
||||
if (isAI(user))
|
||||
return 1
|
||||
return 0
|
||||
if(access_scanner.allowed(user))
|
||||
return TRUE
|
||||
if(!locked)
|
||||
return TRUE
|
||||
if(isAI(user))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/bot/attackby(var/obj/item/O, var/mob/user)
|
||||
if(O.GetID())
|
||||
if((has_master_access(O) || access_scanner.allowed(user)) && !open && !emagged)
|
||||
locked = !locked
|
||||
to_chat(user, "<span class='notice'>Controls are now [locked ? "locked." : "unlocked."]</span>")
|
||||
to_chat(user, SPAN_NOTICE("You [locked ? "lock" : "unlock"] the controls."))
|
||||
else
|
||||
if(emagged)
|
||||
to_chat(user, "<span class='warning'>ERROR</span>")
|
||||
to_chat(user, SPAN_WARNING("As you swipe your ID, it reads: \"Interface error!\""))
|
||||
if(open)
|
||||
to_chat(user, "<span class='warning'>Please close the access panel before locking it.</span>")
|
||||
to_chat(user, SPAN_WARNING("You have to close the access panel before locking it."))
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
to_chat(user, SPAN_WARNING("As you swipe your ID, it reads: \"Access denied.\""))
|
||||
return
|
||||
else if(O.isscrewdriver())
|
||||
if(!locked)
|
||||
open = !open
|
||||
to_chat(user, "<span class='notice'>Maintenance panel is now [open ? "opened" : "closed"].</span>")
|
||||
to_chat(user, SPAN_NOTICE("You [open ? "open" : "close"] the maintenance panel."))
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You need to unlock the controls first.</span>")
|
||||
to_chat(user, SPAN_WARNING("You need to unlock the controls first."))
|
||||
return
|
||||
else if(O.iswelder())
|
||||
if(health < maxHealth)
|
||||
if(open)
|
||||
health = min(maxHealth, health + 10)
|
||||
user.visible_message("<span class='notice'>[user] repairs [src].</span>","<span class='notice'>You repair [src].</span>")
|
||||
user.visible_message(SPAN_NOTICE("\The [user] repairs [src]."), SPAN_NOTICE("You repair [src]."))
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Unable to repair with the maintenance panel closed.</span>")
|
||||
to_chat(user, SPAN_WARNING("You are unable to repair [src] with the maintenance panel closed."))
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[src] does not need a repair.</span>")
|
||||
to_chat(user, SPAN_WARNING("[src] does not need a repair."))
|
||||
return
|
||||
else if(O.iscrowbar())
|
||||
if(!pAI)
|
||||
to_chat(user, SPAN_WARNING("\The [src] does not have a pAI installed!"))
|
||||
return
|
||||
if(!old_name)
|
||||
old_name = initial(name)
|
||||
name = old_name
|
||||
user.put_in_hands(pAI)
|
||||
user.visible_message(SPAN_NOTICE("\The [user] pries \the [pAI.pai] out of \the [src]."), SPAN_NOTICE("You pry \the [pAI.pai] out of \the [src]."))
|
||||
pAI = null
|
||||
else if(istype(O, /obj/item/device/paicard))
|
||||
if(!can_take_pai)
|
||||
to_chat(user, SPAN_WARNING("\The [src] cannot take a pAI!"))
|
||||
return
|
||||
if(pAI)
|
||||
to_chat(user, SPAN_WARNING("\The [src] already has a pAI installed!"))
|
||||
return
|
||||
var/obj/item/device/paicard/P = O
|
||||
P.pai.open_up(FALSE)
|
||||
P.pai.close_up()
|
||||
user.drop_from_inventory(P, src)
|
||||
pAI = P
|
||||
user.visible_message(SPAN_NOTICE("\The [user] places \the [pAI.pai] into \the [src]."), SPAN_NOTICE("You place \the [O] into \the [src]."))
|
||||
old_name = src.name
|
||||
name = pAI.pai.name
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/bot/attack_ai(var/mob/user)
|
||||
/mob/living/bot/attack_ai(mob/user)
|
||||
if(pAI)
|
||||
to_chat(user, SPAN_WARNING("\The [src] contains a pAI and cannot be remotely controlled."))
|
||||
return
|
||||
return attack_hand(user)
|
||||
|
||||
/mob/living/bot/say(var/message)
|
||||
@@ -121,8 +170,13 @@
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/mob/living/bot/emag_act(var/remaining_charges, var/mob/user)
|
||||
return 0
|
||||
/mob/living/bot/cleanbot/think()
|
||||
if(pAI) // no AI if we have a pAI installed
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/bot/emag_act()
|
||||
return FALSE
|
||||
|
||||
/mob/living/bot/emp_act(severity)
|
||||
switch(severity)
|
||||
@@ -134,14 +188,14 @@
|
||||
|
||||
/mob/living/bot/proc/turn_on()
|
||||
if(stat)
|
||||
return 0
|
||||
on = 1
|
||||
return FALSE
|
||||
on = TRUE
|
||||
set_light(light_strength)
|
||||
update_icons()
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/bot/proc/turn_off()
|
||||
on = 0
|
||||
on = FALSE
|
||||
set_light(0)
|
||||
update_icons()
|
||||
|
||||
|
||||
@@ -12,37 +12,38 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
|
||||
/mob/living/bot/cleanbot
|
||||
name = "Cleanbot"
|
||||
desc = "A little cleaning robot, he looks so excited!"
|
||||
desc = "A little cleaning robot, consisting of a bucket, a proximity sensor, and a prosthetic arm. It looks excited to clean!"
|
||||
icon_state = "cleanbot0"
|
||||
req_one_access = list(access_janitor, access_robotics)
|
||||
botcard_access = list(access_janitor, access_maint_tunnels)
|
||||
|
||||
locked = 0 // Start unlocked so roboticist can set them to patrol.
|
||||
locked = FALSE // Start unlocked so roboticist can set them to patrol.
|
||||
|
||||
var/obj/effect/decal/cleanable/target
|
||||
var/list/path = list()
|
||||
var/list/patrol_path = list()
|
||||
var/list/ignorelist = list()
|
||||
|
||||
var/obj/cleanbot_listener/listener = null
|
||||
var/obj/cleanbot_listener/listener
|
||||
var/beacon_freq = 1445 // navigation beacon frequency
|
||||
var/signal_sent = 0
|
||||
var/closest_dist
|
||||
var/next_dest
|
||||
var/next_dest_loc
|
||||
|
||||
var/cleaning = 0
|
||||
var/screwloose = 0
|
||||
var/oddbutton = 0
|
||||
var/should_patrol = 0
|
||||
var/blood = 1
|
||||
var/cleaning = FALSE
|
||||
var/screw_loose = FALSE
|
||||
var/odd_button = FALSE
|
||||
var/should_patrol = FALSE
|
||||
var/cleans_blood = TRUE
|
||||
var/list/target_types = list()
|
||||
|
||||
var/maximum_search_range = 7
|
||||
|
||||
/mob/living/bot/cleanbot/Cross(atom/movable/crossed)
|
||||
if(crossed)
|
||||
if(istype(crossed,/mob/living/bot/cleanbot)) return 0
|
||||
if(istype(crossed, /mob/living/bot/cleanbot))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/cleanbot/Initialize()
|
||||
@@ -57,13 +58,13 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
SSradio.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
|
||||
/mob/living/bot/cleanbot/Destroy()
|
||||
. = ..()
|
||||
path = null
|
||||
patrol_path = null
|
||||
target = null
|
||||
ignorelist = null
|
||||
QDEL_NULL(listener)
|
||||
global.janitorial_supplies -= src
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/cleanbot/proc/handle_target()
|
||||
if(target.clean_marked && target.clean_marked != src)
|
||||
@@ -71,24 +72,22 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
path = list()
|
||||
ignorelist |= target
|
||||
return
|
||||
if(loc == target.loc)
|
||||
if(get_turf(src) == get_turf(target))
|
||||
if(!cleaning)
|
||||
UnarmedAttack(target)
|
||||
return 1
|
||||
return TRUE
|
||||
if(!path.len)
|
||||
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
|
||||
path = AStar(get_turf(src), get_turf(target), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
|
||||
if(!path)
|
||||
//log_debug("[src] can't reach [target.name] ([target.x], [target.y])")
|
||||
ignorelist |= target
|
||||
target.clean_marked = null
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
if(path.len)
|
||||
else
|
||||
step_to(src, path[1])
|
||||
path -= path[1]
|
||||
return 1
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/mob/living/bot/cleanbot/proc/remove_from_ignore(path)
|
||||
ignorelist -= path
|
||||
@@ -107,23 +106,24 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
if(cleaning)
|
||||
return
|
||||
|
||||
if(!screwloose && !oddbutton && prob(2))
|
||||
if(!screw_loose && !odd_button && prob(2) && world.time > last_emote + 2 MINUTES)
|
||||
custom_emote(2, "makes an excited beeping booping sound!")
|
||||
last_emote = world.time
|
||||
|
||||
if(screwloose && prob(5)) // Make a mess
|
||||
if(screw_loose && prob(5)) // Make a mess
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
T.wet_floor()
|
||||
|
||||
if(oddbutton && prob(5)) // Make a big mess
|
||||
visible_message("Something flies out of [src]. He seems to be acting oddly.")
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(loc)
|
||||
if(odd_button && prob(5)) // Make a big mess
|
||||
visible_message(SPAN_WARNING("Some bloody gibs fall out of [src]..."))
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gib = new /obj/effect/decal/cleanable/blood/gibs(get_turf(src))
|
||||
ignorelist += gib
|
||||
addtimer(CALLBACK(src, .proc/remove_from_ignore, gib), 600)
|
||||
|
||||
/mob/living/bot/cleanbot/think()
|
||||
..()
|
||||
if (!on)
|
||||
if(!on)
|
||||
return
|
||||
|
||||
if(pulledby) // Don't wiggle if someone pulls you
|
||||
@@ -137,11 +137,12 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
// This loop will progressively search outwards for /cleanables in view(), gradually to prevent excessively large view() calls when none are needed.
|
||||
search_for: // We use the label so we can break out of this loop from within the next loop.
|
||||
// Not breaking out of these loops properly is where the infinite loop was coming from before.
|
||||
for(var/i=0, i <= maximum_search_range, i++)
|
||||
for(var/i = 0, i <= maximum_search_range, i++)
|
||||
clean_for: // This one isn't really needed in this context, but it's good to have in case we expand later.
|
||||
for(var/obj/effect/decal/cleanable/D in view(i, src))
|
||||
if(D.clean_marked && D.clean_marked != src) continue clean_for
|
||||
var/mob/living/bot/cleanbot/other_bot = locate() in D.loc
|
||||
if(D.clean_marked && D.clean_marked != src)
|
||||
continue clean_for
|
||||
var/mob/living/bot/cleanbot/other_bot = locate() in get_turf(D)
|
||||
if(other_bot && other_bot.cleaning && other_bot != src)
|
||||
continue clean_for
|
||||
if((D in ignorelist))
|
||||
@@ -153,9 +154,8 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
target = D
|
||||
D.clean_marked = src
|
||||
found_spot = handle_target()
|
||||
if (found_spot)
|
||||
if(found_spot)
|
||||
break search_for // If the target location is found and pathed properly, break the search loop.
|
||||
|
||||
else
|
||||
target = null // Otherwise we want to try the next cleanable in view, if any.
|
||||
D.clean_marked = null
|
||||
@@ -197,44 +197,47 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
patrol_path -= patrol_path[1]
|
||||
|
||||
/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity)
|
||||
if(!..())
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(isturf(D))
|
||||
D = locate(/obj/effect/decal/cleanable) in D
|
||||
if(!istype(D))
|
||||
return
|
||||
|
||||
if(D.loc != loc)
|
||||
if(!src.Adjacent(D))
|
||||
return
|
||||
|
||||
cleaning = 1
|
||||
target.being_cleaned = 1
|
||||
cleaning = TRUE
|
||||
D.being_cleaned = TRUE
|
||||
update_icons()
|
||||
var/clean_time = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
|
||||
INVOKE_ASYNC(src, .proc/do_clean, D, clean_time)
|
||||
|
||||
/mob/living/bot/cleanbot/proc/do_clean(var/obj/effect/decal/cleanable/D, var/clean_time)
|
||||
if(D && do_after(src, clean_time))
|
||||
if(istype(D.loc, /turf/simulated))
|
||||
var/turf/simulated/f = loc
|
||||
f.dirt = 0
|
||||
if(!D)
|
||||
return
|
||||
D.clean_marked = null
|
||||
if(D == target)
|
||||
target.being_cleaned = FALSE
|
||||
target = null
|
||||
qdel(D)
|
||||
cleaning = FALSE
|
||||
update_icons()
|
||||
var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
|
||||
spawn(1)
|
||||
if(do_after(src, cleantime))
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/f = loc
|
||||
f.dirt = 0
|
||||
if(!D)
|
||||
return
|
||||
D.clean_marked = null
|
||||
if(D == target)
|
||||
target.being_cleaned = 0
|
||||
target = null
|
||||
qdel(D)
|
||||
cleaning = 0
|
||||
update_icons()
|
||||
|
||||
/mob/living/bot/cleanbot/explode()
|
||||
on = 0
|
||||
visible_message("<span class='danger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/reagent_containers/glass/bucket(Tsec)
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
on = FALSE // the first thing i do when i explode is turn off, tbh - geeves
|
||||
visible_message(SPAN_WARNING("[src] blows apart!"))
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/item/reagent_containers/glass/bucket(T)
|
||||
new /obj/item/device/assembly/prox_sensor(T)
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
|
||||
new /obj/item/robot_parts/l_arm(T)
|
||||
spark(src, 3, alldirs)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -252,8 +255,8 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
patrol_path = list()
|
||||
|
||||
/mob/living/bot/cleanbot/attack_hand(var/mob/user)
|
||||
if (!has_ui_access(user) && !emagged)
|
||||
to_chat(user, "<span class='warning'>The unit's interface refuses to unlock!</span>")
|
||||
if(!has_ui_access(user) && !emagged)
|
||||
to_chat(user, SPAN_WARNING("The unit's interface refuses to unlock!"))
|
||||
return
|
||||
|
||||
var/dat
|
||||
@@ -262,11 +265,11 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
dat += "Maintenance panel is [open ? "opened" : "closed"]"
|
||||
if(!locked || issilicon(user))
|
||||
dat += "<BR>Cleans Blood: <A href='?src=\ref[src];operation=blood'>[blood ? "Yes" : "No"]</A><BR>"
|
||||
dat += "<BR>Cleans Blood: <A href='?src=\ref[src];operation=blood'>[cleans_blood ? "Yes" : "No"]</A><BR>"
|
||||
dat += "<BR>Patrol station: <A href='?src=\ref[src];operation=patrol'>[should_patrol ? "Yes" : "No"]</A><BR>"
|
||||
if(open && !locked)
|
||||
dat += "Odd looking screw twiddled: <A href='?src=\ref[src];operation=screw'>[screwloose ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Weird button pressed: <A href='?src=\ref[src];operation=oddbutton'>[oddbutton ? "Yes" : "No"]</A>"
|
||||
dat += "Odd looking screw twiddled: <A href='?src=\ref[src];operation=screw'>[screw_loose ? "Yes" : "No"]</A><BR>"
|
||||
dat += "Weird button pressed: <A href='?src=\ref[src];operation=odd_button'>[odd_button ? "Yes" : "No"]</A>"
|
||||
|
||||
user << browse("<HEAD><TITLE>Cleaner v1.1 controls</TITLE></HEAD>[dat]", "window=autocleaner")
|
||||
onclose(user, "autocleaner")
|
||||
@@ -278,8 +281,8 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
|
||||
if (!has_ui_access(usr) && !emagged)
|
||||
to_chat(usr, "<span class='warning'>Insufficient permissions.</span>")
|
||||
if(!has_ui_access(usr) && !emagged)
|
||||
to_chat(usr, SPAN_WARNING("Insufficient permissions."))
|
||||
return
|
||||
|
||||
switch(href_list["operation"])
|
||||
@@ -289,31 +292,31 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
else
|
||||
turn_on()
|
||||
if("blood")
|
||||
blood = !blood
|
||||
cleans_blood = !cleans_blood
|
||||
get_targets()
|
||||
if("patrol")
|
||||
should_patrol = !should_patrol
|
||||
patrol_path = list()
|
||||
if("freq")
|
||||
var/freq = text2num(input("Select frequency for navigation beacons", "Frequnecy", num2text(beacon_freq / 10))) * 10
|
||||
if (freq > 0)
|
||||
var/freq = text2num(input("Select frequency for navigation beacons", "Frequnecy", num2text(beacon_freq / 10))) * 10
|
||||
if(freq > 0)
|
||||
beacon_freq = freq
|
||||
if("screw")
|
||||
screwloose = !screwloose
|
||||
to_chat(usr, "<span class='notice'>You twiddle the screw.</span>")
|
||||
if("oddbutton")
|
||||
oddbutton = !oddbutton
|
||||
to_chat(usr, "<span class='notice'>You press the weird button.</span>")
|
||||
screw_loose = !screw_loose
|
||||
to_chat(usr, SPAN_NOTICE("You twiddle the screw."))
|
||||
if("odd_button")
|
||||
odd_button = !odd_button
|
||||
to_chat(usr, SPAN_NOTICE("You press the weird button."))
|
||||
attack_hand(usr)
|
||||
|
||||
/mob/living/bot/cleanbot/emag_act(var/remaining_uses, var/mob/user)
|
||||
. = ..()
|
||||
if(!screwloose || !oddbutton)
|
||||
if(!screw_loose || !odd_button)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>The [src] buzzes and beeps.</span>")
|
||||
oddbutton = 1
|
||||
screwloose = 1
|
||||
return 1
|
||||
to_chat(user, SPAN_NOTICE("The [src] buzzes and beeps."))
|
||||
odd_button = TRUE
|
||||
screw_loose = TRUE
|
||||
return TRUE
|
||||
|
||||
/mob/living/bot/cleanbot/proc/get_targets()
|
||||
// To avoid excessive loops, instead of storing a list of top-level types, we're going to store a list of all cleanables.
|
||||
@@ -327,19 +330,8 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
/obj/effect/decal/cleanable/crayon,/obj/effect/decal/cleanable/liquid_fuel,/obj/effect/decal/cleanable/mucus,/obj/effect/decal/cleanable/dirt)
|
||||
// I honestly forgot you could pass multiple types to typesof() until I accidentally did it here.
|
||||
target_types = cleanbot_types.Copy()
|
||||
if(!blood)
|
||||
if(!cleans_blood)
|
||||
target_types -= typesof(/obj/effect/decal/cleanable/blood)-typesof(/obj/effect/decal/cleanable/blood/oil)
|
||||
/* target_types = list()
|
||||
|
||||
target_types += /obj/effect/decal/cleanable/blood/oil
|
||||
target_types += /obj/effect/decal/cleanable/vomit
|
||||
target_types += /obj/effect/decal/cleanable/crayon
|
||||
target_types += /obj/effect/decal/cleanable/liquid_fuel
|
||||
target_types += /obj/effect/decal/cleanable/mucus
|
||||
target_types += /obj/effect/decal/cleanable/dirt
|
||||
|
||||
if(blood)
|
||||
target_types += /obj/effect/decal/cleanable/blood*/
|
||||
|
||||
/* Radio object that listens to signals */
|
||||
|
||||
@@ -367,28 +359,26 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
/* Assembly */
|
||||
|
||||
/obj/item/bucket_sensor
|
||||
desc = "It's a bucket. With a sensor attached."
|
||||
name = "proxy bucket"
|
||||
desc = "It's a bucket. With a sensor attached."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "bucket_proxy"
|
||||
force = 3.0
|
||||
throwforce = 10.0
|
||||
force = 3
|
||||
throwforce = 10
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = 3.0
|
||||
var/created_name = "Cleanbot"
|
||||
|
||||
/obj/item/bucket_sensor/attackby(var/obj/item/O, var/mob/user)
|
||||
..()
|
||||
if(istype(O, /obj/item/robot_parts/l_arm) || istype(O, /obj/item/robot_parts/r_arm))
|
||||
user.drop_from_inventory(O,get_turf(src))
|
||||
user.drop_from_inventory(O, get_turf(src))
|
||||
qdel(O)
|
||||
var/turf/T = get_turf(loc)
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/bot/cleanbot/A = new /mob/living/bot/cleanbot(T)
|
||||
A.name = created_name
|
||||
to_chat(user, "<span class='notice'>You add the robot arm to the bucket and sensor assembly. Beep boop!</span>")
|
||||
to_chat(user, SPAN_NOTICE("You add the robot arm to the bucket and sensor assembly. Beep boop!"))
|
||||
qdel(src)
|
||||
|
||||
else if(O.ispen())
|
||||
var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN)
|
||||
if(!t)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
/mob/living/bot/farmbot
|
||||
name = "Farmbot"
|
||||
desc = "The botanist's best friend."
|
||||
desc = "The botanist's best friend. Various farming equipment seems haphazardly attached to it."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "farmbot0"
|
||||
health = 50
|
||||
@@ -14,17 +14,17 @@
|
||||
req_one_access = list(access_hydroponics, access_robotics)
|
||||
|
||||
var/action = "" // Used to update icon
|
||||
var/waters_trays = 1
|
||||
var/refills_water = 1
|
||||
var/uproots_weeds = 1
|
||||
var/replaces_nutriment = 0
|
||||
var/collects_produce = 0
|
||||
var/removes_dead = 0
|
||||
var/eliminates_pests = 0
|
||||
var/waters_trays = TRUE
|
||||
var/refills_water = TRUE
|
||||
var/uproots_weeds = TRUE
|
||||
var/replaces_nutriment = FALSE
|
||||
var/collects_produce = FALSE
|
||||
var/removes_dead = FALSE
|
||||
var/eliminates_pests = FALSE
|
||||
|
||||
var/obj/structure/reagent_dispensers/watertank/tank
|
||||
|
||||
var/attacking = 0
|
||||
var/attacking = FALSE
|
||||
var/list/path = list()
|
||||
var/atom/target
|
||||
var/frustration = 0
|
||||
@@ -45,7 +45,7 @@
|
||||
return
|
||||
|
||||
if (!has_ui_access(user))
|
||||
to_chat(user, "<span class='warning'>The unit's interface refuses to unlock!</span>")
|
||||
to_chat(user, SPAN_WARNING("The unit's interface refuses to unlock!"))
|
||||
return
|
||||
|
||||
var/dat = ""
|
||||
@@ -79,11 +79,11 @@
|
||||
. = ..()
|
||||
if(!emagged)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>You short out [src]'s plant identifier circuits.</span>")
|
||||
to_chat(user, SPAN_NOTICE("You short out [src]'s plant identifier circuits."))
|
||||
spawn(rand(30, 50))
|
||||
visible_message("<span class='warning'>[src] buzzes oddly.</span>")
|
||||
emagged = 1
|
||||
return 1
|
||||
visible_message(SPAN_WARNING("[src] buzzes oddly."))
|
||||
emagged = TRUE
|
||||
return TRUE
|
||||
|
||||
/mob/living/bot/farmbot/Topic(href, href_list)
|
||||
if(..())
|
||||
@@ -91,8 +91,8 @@
|
||||
usr.machine = src
|
||||
add_fingerprint(usr)
|
||||
|
||||
if (!has_ui_access(usr))
|
||||
to_chat(usr, "<span class='warning'>Insufficient permissions.</span>")
|
||||
if(!has_ui_access(usr))
|
||||
to_chat(usr, SPAN_WARNING("Insufficient permissions."))
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
@@ -180,7 +180,8 @@
|
||||
path = list()
|
||||
|
||||
/mob/living/bot/farmbot/UnarmedAttack(var/atom/A, var/proximity)
|
||||
if(!..())
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(attacking)
|
||||
return
|
||||
@@ -194,48 +195,48 @@
|
||||
if(FARMBOT_COLLECT)
|
||||
action = "collect"
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] starts [T.dead? "removing the plant from" : "harvesting"] \the [A].</span>")
|
||||
attacking = 1
|
||||
visible_message(SPAN_NOTICE("[src] starts [T.dead? "removing the plant from" : "harvesting"] \the [A]."))
|
||||
attacking = TRUE
|
||||
if(do_after(src, 30))
|
||||
visible_message("<span class='notice'>[src] [T.dead? "removes the plant from" : "harvests"] \the [A].</span>")
|
||||
visible_message(SPAN_NOTICE("[src] [T.dead? "removes the plant from" : "harvests"] \the [A]."))
|
||||
T.attack_hand(src)
|
||||
if(FARMBOT_WATER)
|
||||
action = "water"
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] starts watering \the [A].</span>")
|
||||
attacking = 1
|
||||
visible_message(SPAN_NOTICE("[src] starts watering \the [A]."))
|
||||
attacking = TRUE
|
||||
if(do_after(src, 30))
|
||||
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
||||
visible_message("<span class='notice'>[src] waters \the [A].</span>")
|
||||
playsound(get_turf(src), 'sound/effects/slosh.ogg', 25, TRUE)
|
||||
visible_message(SPAN_NOTICE("[src] waters \the [A]."))
|
||||
tank.reagents.trans_to(T, 100 - T.waterlevel)
|
||||
if(FARMBOT_UPROOT)
|
||||
action = "hoe"
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] starts uprooting the weeds in \the [A].</span>")
|
||||
attacking = 1
|
||||
visible_message(SPAN_NOTICE("[src] starts uprooting the weeds in \the [A]."))
|
||||
attacking = TRUE
|
||||
if(do_after(src, 30))
|
||||
visible_message("<span class='notice'>[src] uproots the weeds in \the [A].</span>")
|
||||
visible_message(SPAN_NOTICE("[src] uproots the weeds in \the [A]."))
|
||||
T.weedlevel = 0
|
||||
T.update_icon()
|
||||
if(FARMBOT_PESTKILL)
|
||||
action = "hoe"
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] starts eliminating the pests in \the [A].</span>")
|
||||
attacking = 1
|
||||
visible_message(SPAN_NOTICE("[src] starts eliminating the pests in \the [A]."))
|
||||
attacking = TRUE
|
||||
if(do_after(src, 30))
|
||||
visible_message("<span class='notice'>[src] decimates the pests in \the [A].</span>")
|
||||
visible_message(SPAN_NOTICE("[src] eliminates the pests in \the [A]."))
|
||||
T.pestlevel = 0
|
||||
T.reagents.add_reagent("nutriment", 0.5)
|
||||
T.update_icon()
|
||||
if(FARMBOT_NUTRIMENT)
|
||||
action = "fertile"
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] starts fertilizing \the [A].</span>")
|
||||
attacking = 1
|
||||
visible_message(SPAN_NOTICE("[src] starts fertilizing \the [A]."))
|
||||
attacking = TRUE
|
||||
if(do_after(src, 30))
|
||||
visible_message("<span class='notice'>[src] waters \the [A].</span>")
|
||||
visible_message(SPAN_NOTICE("[src] waters \the [A]."))
|
||||
T.reagents.add_reagent("ammonia", 10)
|
||||
attacking = 0
|
||||
attacking = FALSE
|
||||
action = ""
|
||||
update_icons()
|
||||
T.update_icon()
|
||||
@@ -244,48 +245,46 @@
|
||||
return
|
||||
action = "water"
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] starts refilling its tank from \the [A].</span>")
|
||||
attacking = 1
|
||||
visible_message(SPAN_NOTICE("[src] starts refilling its tank from \the [A]."))
|
||||
attacking = TRUE
|
||||
while(do_after(src, 10) && tank.reagents.total_volume < tank.reagents.maximum_volume)
|
||||
tank.reagents.add_reagent("water", 10)
|
||||
if(prob(5))
|
||||
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
|
||||
attacking = 0
|
||||
playsound(get_turf(src), 'sound/effects/slosh.ogg', 25, TRUE)
|
||||
attacking = FALSE
|
||||
action = ""
|
||||
update_icons()
|
||||
visible_message("<span class='notice'>[src] finishes refilling its tank.</span>")
|
||||
visible_message(SPAN_NOTICE("[src] finishes refilling its tank."))
|
||||
else if(emagged && ishuman(A))
|
||||
var/action = pick("weed", "water")
|
||||
attacking = 1
|
||||
attacking = TRUE
|
||||
spawn(50) // Some delay
|
||||
attacking = 0
|
||||
attacking = FALSE
|
||||
switch(action)
|
||||
if("weed")
|
||||
flick("farmbot_hoe", src)
|
||||
do_attack_animation(A)
|
||||
if(prob(50))
|
||||
visible_message("<span class='danger'>[src] swings wildly at [A] with a minihoe, missing completely!</span>")
|
||||
visible_message(SPAN_DANGER("[src] swings wildly at [A] with a minihoe, missing completely!"))
|
||||
return
|
||||
var/t = pick("slashed", "sliced", "cut", "clawed")
|
||||
A.attack_generic(src, 5, t)
|
||||
if("water")
|
||||
flick("farmbot_water", src)
|
||||
visible_message("<span class='danger'>[src] splashes [A] with water!</span>") // That's it. RP effect.
|
||||
visible_message(SPAN_DANGER("[src] splashes [A] with water!")) // That's it. RP effect.
|
||||
|
||||
/mob/living/bot/farmbot/explode()
|
||||
visible_message("<span class='danger'>[src] blows apart!</span>")
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
new /obj/item/material/minihoe(Tsec)
|
||||
new /obj/item/reagent_containers/glass/bucket(Tsec)
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/device/analyzer/plant_analyzer(Tsec)
|
||||
visible_message(SPAN_DANGER("[src] blows apart!"))
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
new /obj/item/material/minihoe(T)
|
||||
new /obj/item/reagent_containers/glass/bucket(T)
|
||||
new /obj/item/device/assembly/prox_sensor(T)
|
||||
new /obj/item/device/analyzer/plant_analyzer(T)
|
||||
if(tank)
|
||||
tank.forceMove(Tsec)
|
||||
|
||||
tank.forceMove(T)
|
||||
if(prob(50))
|
||||
new /obj/item/robot_parts/l_arm(Tsec)
|
||||
new /obj/item/robot_parts/l_arm(T)
|
||||
|
||||
spark(src, 3, alldirs)
|
||||
qdel(src)
|
||||
@@ -293,34 +292,27 @@
|
||||
|
||||
/mob/living/bot/farmbot/proc/process_tray(var/obj/machinery/portable_atmospherics/hydroponics/tray)
|
||||
if(!tray || !istype(tray))
|
||||
return 0
|
||||
|
||||
return FALSE
|
||||
if(tray.closed_system || !tray.seed)
|
||||
return 0
|
||||
|
||||
return FALSE
|
||||
if(tray.dead && removes_dead || tray.harvest && collects_produce)
|
||||
return FARMBOT_COLLECT
|
||||
|
||||
else if(waters_trays && tray.waterlevel < 10 && !tray.reagents.has_reagent("water"))
|
||||
return FARMBOT_WATER
|
||||
|
||||
else if(uproots_weeds && tray.weedlevel >= 5)
|
||||
return FARMBOT_UPROOT
|
||||
|
||||
else if(eliminates_pests && tray.pestlevel >= 3)
|
||||
return FARMBOT_PESTKILL
|
||||
|
||||
else if(replaces_nutriment && tray.nutrilevel < 2 && tray.reagents.total_volume < 1)
|
||||
return FARMBOT_NUTRIMENT
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
// Assembly
|
||||
|
||||
/mob/living/bot/farmbot/proc/check_tank()
|
||||
if(!tank)
|
||||
return FALSE
|
||||
return ((!target && refills_water && tank.reagents.total_volume < tank.reagents.maximum_volume) || ((tank.reagents.total_volume ) / tank.reagents.maximum_volume) <= 0.3)
|
||||
if(!tank)
|
||||
return FALSE
|
||||
return ((!target && refills_water && tank.reagents.total_volume < tank.reagents.maximum_volume) || ((tank.reagents.total_volume ) / tank.reagents.maximum_volume) <= 0.3)
|
||||
|
||||
/obj/item/farmbot_arm_assembly
|
||||
name = "water tank/robot arm assembly"
|
||||
@@ -329,46 +321,42 @@
|
||||
icon_state = "water_arm"
|
||||
var/build_step = 0
|
||||
var/created_name = "Farmbot"
|
||||
w_class = 3.0
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/robot_parts/S, mob/user as mob)
|
||||
/obj/structure/reagent_dispensers/watertank/attackby(obj/item/robot_parts/S, mob/user)
|
||||
if ((!istype(S, /obj/item/robot_parts/l_arm)) && (!istype(S, /obj/item/robot_parts/r_arm)))
|
||||
..()
|
||||
return
|
||||
|
||||
var/obj/item/farmbot_arm_assembly/A = new /obj/item/farmbot_arm_assembly(loc)
|
||||
|
||||
to_chat(user, "You add the robot arm to [src].")
|
||||
to_chat(user, SPAN_NOTICE("You add \the [S] to \the [src]."))
|
||||
loc = A //Place the water tank into the assembly, it will be needed for the finished bot
|
||||
qdel(S)
|
||||
|
||||
/obj/item/farmbot_arm_assembly/attackby(obj/item/W as obj, mob/user as mob)
|
||||
/obj/item/farmbot_arm_assembly/attackby(obj/item/W, mob/user)
|
||||
..()
|
||||
if((istype(W, /obj/item/device/analyzer/plant_analyzer)) && (build_step == 0))
|
||||
if(istype(W, /obj/item/device/analyzer/plant_analyzer) && build_step == 0)
|
||||
build_step++
|
||||
to_chat(user, "You add the plant analyzer to [src].")
|
||||
to_chat(user, SPAN_NOTICE("You add the plant analyzer to [src]."))
|
||||
name = "farmbot assembly"
|
||||
qdel(W)
|
||||
return 1
|
||||
|
||||
else if((istype(W, /obj/item/reagent_containers/glass/bucket)) && (build_step == 1))
|
||||
return TRUE
|
||||
else if(istype(W, /obj/item/reagent_containers/glass/bucket) && build_step == 1)
|
||||
build_step++
|
||||
to_chat(user, "You add a bucket to [src].")
|
||||
to_chat(user, SPAN_NOTICE("You add a bucket to [src]."))
|
||||
name = "farmbot assembly with bucket"
|
||||
qdel(W)
|
||||
return 1//Prevents the object's afterattack from executing and causing runtime errors
|
||||
|
||||
else if((istype(W, /obj/item/material/minihoe)) && (build_step == 2))
|
||||
return TRUE //Prevents the object's afterattack from executing and causing runtime errors
|
||||
else if(istype(W, /obj/item/material/minihoe) && build_step == 2)
|
||||
build_step++
|
||||
to_chat(user, "You add a minihoe to [src].")
|
||||
to_chat(user, SPAN_NOTICE("You add a minihoe to [src]."))
|
||||
name = "farmbot assembly with bucket and minihoe"
|
||||
user.remove_from_mob(W)
|
||||
qdel(W)
|
||||
return 1
|
||||
|
||||
else if((isprox(W)) && (build_step == 3))
|
||||
return TRUE
|
||||
else if(isprox(W) && build_step == 3)
|
||||
build_step++
|
||||
to_chat(user, "You complete the Farmbot! Beep boop.")
|
||||
to_chat(user, SPAN_NOTICE("You complete the Farmbot! Beep boop."))
|
||||
var/mob/living/bot/farmbot/S = new /mob/living/bot/farmbot(get_turf(src))
|
||||
for(var/obj/structure/reagent_dispensers/watertank/wTank in contents)
|
||||
qdel(S.tank)
|
||||
@@ -378,8 +366,7 @@
|
||||
user.remove_from_mob(W)
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
return TRUE
|
||||
else if(W.ispen())
|
||||
var/t = input(user, "Enter new robot name", name, created_name) as text
|
||||
t = sanitize(t, MAX_NAME_LEN)
|
||||
@@ -387,8 +374,7 @@
|
||||
return
|
||||
if(!in_range(src, usr) && loc != usr)
|
||||
return
|
||||
|
||||
created_name = t
|
||||
|
||||
/obj/item/farmbot_arm_assembly/attack_hand(mob/user as mob)
|
||||
return //it's a converted watertank, no you cannot pick it up and put it in your backpack
|
||||
/obj/item/farmbot_arm_assembly/attack_hand(mob/user)
|
||||
return //it's a converted watertank, no you cannot pick it up and put it in your backpack
|
||||
@@ -194,13 +194,14 @@
|
||||
target = null
|
||||
|
||||
/mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity)
|
||||
if(!..())
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(repairing)
|
||||
return
|
||||
|
||||
if(get_turf(A) != loc)
|
||||
if(!src.Adjacent(A))
|
||||
return
|
||||
|
||||
if(emagged && istype(A, /turf/simulated/floor))
|
||||
|
||||
@@ -74,7 +74,8 @@
|
||||
break
|
||||
|
||||
/mob/living/bot/medbot/UnarmedAttack(var/mob/living/carbon/human/H, var/proximity)
|
||||
if(!..())
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(!on)
|
||||
@@ -84,6 +85,9 @@
|
||||
return
|
||||
|
||||
if(H.stat == DEAD)
|
||||
if(pAI)
|
||||
to_chat(pAI.pai, SPAN_WARNING("\The [H] is dead, you cannot help them now."))
|
||||
return
|
||||
var/death_message = pick("No! NO!", "Live, damnit! LIVE!", "I... I've never lost a patient before. Not today, I mean.")
|
||||
say(death_message)
|
||||
patient = null
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
var/datum/callback/patrol_callback // this is here so we don't constantly recreate this datum, it being identical each time.
|
||||
var/move_to_delay = 4 //delay for the automated movement.
|
||||
can_take_pai = FALSE
|
||||
|
||||
/mob/living/bot/secbot/beepsky
|
||||
name = "Officer Beepsky"
|
||||
|
||||
@@ -35,3 +35,18 @@
|
||||
stat = CONSCIOUS
|
||||
else
|
||||
health = 100 - getBruteLoss() - getFireLoss()
|
||||
|
||||
/mob/living/silicon/pai/Stat()
|
||||
..()
|
||||
|
||||
if(istype(card.loc, /mob/living/bot))
|
||||
var/mob/living/bot/B = card.loc
|
||||
stat(null, "Piloting: [B.name]")
|
||||
stat(null, "Bot Status: [B.on ? "Active" : "Inactive"]")
|
||||
stat(null, "Maintenance Hatch: [B.open ? "Open" : "Closed"]")
|
||||
stat(null, "Maintenance Lock: [B.locked ? "Locked" : "Unlocked"]")
|
||||
if(B.emagged)
|
||||
stat(null, "Bot M#$FUN90: MALFUNC--")
|
||||
if(istype(card.loc, /mob/living/bot/floorbot))
|
||||
var/mob/living/bot/floorbot/F = card.loc
|
||||
stat(null, "Metal Count: [F.amount]/[F.maxAmount]")
|
||||
@@ -209,7 +209,6 @@
|
||||
greet()
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/silicon/pai/proc/greet()
|
||||
|
||||
if (!greeted)
|
||||
@@ -346,12 +345,18 @@
|
||||
return
|
||||
|
||||
last_special = world.time + 20
|
||||
open_up()
|
||||
|
||||
/mob/living/silicon/pai/proc/open_up(var/loud = TRUE)
|
||||
if(istype(card.loc, /mob/living/bot))
|
||||
to_chat(src, SPAN_WARNING("You cannot unfold while inside the bot!"))
|
||||
return FALSE
|
||||
|
||||
//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.")
|
||||
return 0
|
||||
else if(istype(card.loc,/mob))
|
||||
to_chat(src, SPAN_WARNING("There is no room to unfold inside this rig module. You're good and stuck."))
|
||||
return FALSE
|
||||
else if(istype(card.loc, /mob))
|
||||
var/mob/holder = card.loc
|
||||
if(ishuman(holder))
|
||||
var/mob/living/carbon/human/H = holder
|
||||
@@ -359,7 +364,8 @@
|
||||
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>")
|
||||
if(loud)
|
||||
H.visible_message(SPAN_DANGER("\The [src] explodes out of \the [H]'s [affecting.name] in shower of gore!"))
|
||||
break
|
||||
holder.drop_from_inventory(card)
|
||||
else if(istype(card.loc,/obj/item/device/pda))
|
||||
@@ -374,9 +380,11 @@
|
||||
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.")
|
||||
canmove = 1
|
||||
resting = 0
|
||||
if(loud && istype(T))
|
||||
T.visible_message(SPAN_NOTICE("<b>[src]</b> folds outwards, expanding into a mobile form."))
|
||||
canmove = TRUE
|
||||
resting = FALSE
|
||||
|
||||
|
||||
/mob/living/silicon/pai/verb/fold_up()
|
||||
set category = "pAI Commands"
|
||||
@@ -417,8 +425,8 @@
|
||||
set name = "Check location"
|
||||
set desc = "Find out where on their person, someone is holding you."
|
||||
|
||||
if (!get_holding_mob())
|
||||
to_chat(src, "Nobody is holding you!")
|
||||
if(!get_holding_mob())
|
||||
to_chat(src, SPAN_WARNING("Nobody is holding you!"))
|
||||
return
|
||||
|
||||
card.report_onmob_location(0, card.get_equip_slot(), src)
|
||||
|
||||
@@ -766,6 +766,9 @@ proc/is_blind(A)
|
||||
*/
|
||||
|
||||
/obj/proc/report_onmob_location(var/justmoved, var/slot = null, var/mob/reportto)
|
||||
if(istype(reportto.loc, /mob/living/bot))
|
||||
to_chat(reportto, SPAN_NOTICE("You are currently housed within \the [reportto.loc]."))
|
||||
return
|
||||
var/mob/living/carbon/human/H//The person who the item is on
|
||||
var/newlocation
|
||||
var/preposition= ""
|
||||
|
||||
Reference in New Issue
Block a user