mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-03 14:02:49 +00:00
Merge resolution with master.
This commit is contained in:
@@ -108,7 +108,6 @@ var/global/floorIsLava = 0
|
||||
body += "<B>Is an AI</B> "
|
||||
else if(ishuman(M))
|
||||
body += {"<A href='?src=\ref[src];makeai=\ref[M]'>Make AI</A> |
|
||||
<A href='?src=\ref[src];makemask=\ref[M]'>Make Mask</A> |
|
||||
<A href='?src=\ref[src];makerobot=\ref[M]'>Make Robot</A> |
|
||||
<A href='?src=\ref[src];makealien=\ref[M]'>Make Alien</A> |
|
||||
<A href='?src=\ref[src];makeslime=\ref[M]'>Make slime</A>
|
||||
|
||||
@@ -563,8 +563,8 @@ var/list/admin_verbs_mentor = list(
|
||||
|
||||
/client/proc/give_disease(mob/T as mob in mob_list) // -- Giacom
|
||||
set category = "Fun"
|
||||
set name = "Give Disease"
|
||||
set desc = "Gives a Disease to a mob."
|
||||
set name = "Give Disease (old)"
|
||||
set desc = "Gives a (tg-style) Disease to a mob."
|
||||
var/list/disease_names = list()
|
||||
for(var/v in diseases)
|
||||
// "/datum/disease/" 15 symbols ~Intercross
|
||||
@@ -576,6 +576,34 @@ var/list/admin_verbs_mentor = list(
|
||||
feedback_add_details("admin_verb","GD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the disease [D].")
|
||||
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the disease [D].", 1)
|
||||
|
||||
/client/proc/give_disease2(mob/T as mob in mob_list) // -- Giacom
|
||||
set category = "Fun"
|
||||
set name = "Give Disease"
|
||||
set desc = "Gives a Disease to a mob."
|
||||
|
||||
var/datum/disease2/disease/D = new /datum/disease2/disease()
|
||||
|
||||
var/greater = ((input("Is this a lesser or greater disease?", "Give Disease") in list("Lesser", "Greater")) == "Greater")
|
||||
|
||||
D.makerandom(greater)
|
||||
if (!greater)
|
||||
D.infectionchance = 1
|
||||
|
||||
D.infectionchance = input("How virulent is this disease? (1-100)", "Give Disease", D.infectionchance) as num
|
||||
|
||||
if(istype(T,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = T
|
||||
if (H.species)
|
||||
D.affected_species = list(H.species.name)
|
||||
if(istype(T,/mob/living/carbon/monkey))
|
||||
var/mob/living/carbon/monkey/M = T
|
||||
D.affected_species = list(M.greaterform)
|
||||
infect_virus2(T,D,1)
|
||||
|
||||
feedback_add_details("admin_verb","GD2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] a [(greater)? "greater":"lesser"] disease2 with infection chance [D.infectionchance].")
|
||||
message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] a [(greater)? "greater":"lesser"] disease2 with infection chance [D.infectionchance].", 1)
|
||||
|
||||
/client/proc/make_sound(var/obj/O in world) // -- TLE
|
||||
set category = "Special Verbs"
|
||||
|
||||
@@ -265,9 +265,6 @@
|
||||
|
||||
else if(isobserver(M))
|
||||
M_job = "Ghost"
|
||||
|
||||
else if(isSpirit(M))
|
||||
M_job = (ismask(M)) ? "Mask" : "Spirit"
|
||||
|
||||
M_job = replacetext(M_job, "'", "")
|
||||
M_job = replacetext(M_job, "\"", "")
|
||||
@@ -351,10 +348,6 @@
|
||||
dat += "<td>Monkey</td>"
|
||||
else if(isalien(M))
|
||||
dat += "<td>Alien</td>"
|
||||
else if(ismask(M))
|
||||
dat += "<td>Mask</td>"
|
||||
else if(isSpirit(M))
|
||||
dat += "<td>Spirit</td>"
|
||||
else
|
||||
dat += "<td>Unknown</td>"
|
||||
|
||||
|
||||
@@ -1200,15 +1200,6 @@
|
||||
message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!", 1)
|
||||
log_admin("[key_name(usr)] AIized [key_name(H)]")
|
||||
H.AIize()
|
||||
|
||||
|
||||
else if(href_list["makemask"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
var/mob/currentMob = locate(href_list["makemask"])
|
||||
message_admins("\red Admin [key_name_admin(usr)] made [key_name_admin(currentMob)] into a Mask of Nar'Sie!", 1)
|
||||
log_admin("[key_name(usr)] made [key_name(currentMob)] into a Mask of Nar'Sie!")
|
||||
currentMob.make_into_mask(0,0)
|
||||
|
||||
|
||||
else if(href_list["makealien"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
@@ -58,7 +58,7 @@ var/intercom_range_display_status = 0
|
||||
del(C)
|
||||
|
||||
if(camera_range_display_status)
|
||||
for(var/obj/machinery/camera/C in cameranet.viewpoints)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
new/obj/effect/debugging/camera_range(C.loc)
|
||||
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -74,7 +74,7 @@ var/intercom_range_display_status = 0
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
for(var/obj/machinery/camera/C in cameranet.viewpoints)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
CL += C
|
||||
|
||||
var/output = {"<B>CAMERA ANNOMALITIES REPORT</B><HR>
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
//BS12: Species-restricted clothing check.
|
||||
/obj/item/clothing/mob_can_equip(M as mob, slot)
|
||||
|
||||
//if we can equip the item anyway, don't bother with species_restricted (aslo cuts down on spam)
|
||||
if (!..())
|
||||
return 0
|
||||
|
||||
if(species_restricted && istype(M,/mob/living/carbon/human))
|
||||
|
||||
var/wearable = null
|
||||
@@ -26,7 +30,7 @@
|
||||
M << "\red Your species cannot wear [src]."
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
return 1
|
||||
|
||||
//Ears: headsets, earmuffs and tiny objects
|
||||
/obj/item/clothing/ears
|
||||
@@ -220,7 +224,7 @@ BLIND // can't see anything
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen)
|
||||
slowdown = 3
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
|
||||
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
|
||||
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
siemens_coefficient = 0.9
|
||||
@@ -252,7 +256,7 @@ BLIND // can't see anything
|
||||
if(hastie)
|
||||
hastie.attackby(I, user)
|
||||
return
|
||||
|
||||
|
||||
if(!hastie && istype(I, /obj/item/clothing/tie))
|
||||
user.drop_item()
|
||||
hastie = I
|
||||
@@ -265,7 +269,7 @@ BLIND // can't see anything
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/clothing/under/attack_hand(mob/user as mob)
|
||||
//only forward to the attached accessory if the clothing is equipped (not in a storage)
|
||||
if(hastie && src.loc == user)
|
||||
@@ -282,7 +286,7 @@ BLIND // can't see anything
|
||||
//makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
|
||||
if (!(src.loc == usr))
|
||||
return
|
||||
|
||||
|
||||
if (!( usr.restrained() ) && !( usr.stat ))
|
||||
switch(over_object.name)
|
||||
if("r_hand")
|
||||
@@ -310,13 +314,10 @@ BLIND // can't see anything
|
||||
if(hastie)
|
||||
usr << "\A [hastie] is clipped to it."
|
||||
|
||||
/obj/item/clothing/under/verb/toggle()
|
||||
set name = "Toggle Suit Sensors"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
/obj/item/clothing/under/proc/set_sensors(mob/usr as mob)
|
||||
var/mob/M = usr
|
||||
if (istype(M, /mob/dead/)) return
|
||||
if (usr.stat) return
|
||||
if (usr.stat || usr.restrained()) return
|
||||
if(has_sensor >= 2)
|
||||
usr << "The controls are locked."
|
||||
return 0
|
||||
@@ -326,17 +327,41 @@ BLIND // can't see anything
|
||||
|
||||
var/list/modes = list("Off", "Binary sensors", "Vitals tracker", "Tracking beacon")
|
||||
var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes
|
||||
if(get_dist(usr, src) > 1)
|
||||
usr << "You have moved too far away."
|
||||
return
|
||||
sensor_mode = modes.Find(switchMode) - 1
|
||||
|
||||
switch(sensor_mode)
|
||||
if(0)
|
||||
usr << "You disable your suit's remote sensing equipment."
|
||||
if(1)
|
||||
usr << "Your suit will now report whether you are live or dead."
|
||||
if(2)
|
||||
usr << "Your suit will now report your vital lifesigns."
|
||||
if(3)
|
||||
usr << "Your suit will now report your vital lifesigns as well as your coordinate position."
|
||||
if (src.loc == usr)
|
||||
switch(sensor_mode)
|
||||
if(0)
|
||||
usr << "You disable your suit's remote sensing equipment."
|
||||
if(1)
|
||||
usr << "Your suit will now report whether you are live or dead."
|
||||
if(2)
|
||||
usr << "Your suit will now report your vital lifesigns."
|
||||
if(3)
|
||||
usr << "Your suit will now report your vital lifesigns as well as your coordinate position."
|
||||
else if (istype(src.loc, /mob))
|
||||
switch(sensor_mode)
|
||||
if(0)
|
||||
for(var/mob/V in viewers(usr, 1))
|
||||
V.show_message("\red [usr] disables [src.loc]'s remote sensing equipment.", 1)
|
||||
if(1)
|
||||
for(var/mob/V in viewers(usr, 1))
|
||||
V.show_message("[usr] turns [src.loc]'s remote sensors to binary.", 1)
|
||||
if(2)
|
||||
for(var/mob/V in viewers(usr, 1))
|
||||
V.show_message("[usr] sets [src.loc]'s sensors to track vitals.", 1)
|
||||
if(3)
|
||||
for(var/mob/V in viewers(usr, 1))
|
||||
V.show_message("[usr] sets [src.loc]'s sensors to maximum.", 1)
|
||||
|
||||
/obj/item/clothing/under/verb/toggle()
|
||||
set name = "Toggle Suit Sensors"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
set_sensors(usr)
|
||||
..()
|
||||
|
||||
/obj/item/clothing/under/verb/rollsuit()
|
||||
@@ -357,7 +382,7 @@ BLIND // can't see anything
|
||||
/obj/item/clothing/under/proc/remove_accessory(mob/user as mob)
|
||||
if(!hastie)
|
||||
return
|
||||
|
||||
|
||||
hastie.on_removed(user)
|
||||
hastie = null
|
||||
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
else
|
||||
nudge_lib = "lib/nudge.so"
|
||||
|
||||
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
|
||||
spawn(0)
|
||||
call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]")
|
||||
else
|
||||
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
|
||||
spawn(0)
|
||||
ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]")
|
||||
return
|
||||
|
||||
/proc/send2mainirc(var/msg)
|
||||
|
||||
@@ -161,28 +161,8 @@ proc/move_mining_shuttle()
|
||||
src.req_access = list()
|
||||
hacked = 1
|
||||
usr << "You fried the consoles ID checking system. It's now available to everyone!"
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/mining_shuttle/M = new /obj/item/weapon/circuitboard/mining_shuttle( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
|
||||
del(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/******************************Lantern*******************************/
|
||||
|
||||
|
||||
@@ -71,10 +71,9 @@
|
||||
var/datum/organ/external/head = get_organ("head")
|
||||
var/mob/living/simple_animal/borer/B
|
||||
|
||||
if(istype(head))
|
||||
for(var/I in head.implants)
|
||||
if(istype(I,/mob/living/simple_animal/borer))
|
||||
B = I
|
||||
for(var/I in head.implants)
|
||||
if(istype(I,/mob/living/simple_animal/borer))
|
||||
B = I
|
||||
if(B)
|
||||
if(!B.ckey && ckey && B.controlling)
|
||||
B.ckey = ckey
|
||||
|
||||
@@ -106,6 +106,11 @@
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
if(istype(tmob,/mob/living/silicon/robot/drone)) //I have no idea why the hell this isn't already happening. How do mice do it?
|
||||
loc = tmob.loc
|
||||
now_pushing = 0
|
||||
return
|
||||
|
||||
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
|
||||
if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && canmove) // mutual brohugs all around!
|
||||
var/turf/oldloc = loc
|
||||
@@ -398,6 +403,9 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user as mob)
|
||||
var/obj/item/clothing/under/suit = null
|
||||
if (istype(w_uniform, /obj/item/clothing/under))
|
||||
suit = w_uniform
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
@@ -412,21 +420,22 @@
|
||||
<BR><B>Right Ear:</B> <A href='?src=\ref[src];item=r_ear'>[(r_ear ? r_ear : "Nothing")]</A>
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=head'>[(head ? head : "Nothing")]</A>
|
||||
<BR><B>Shoes:</B> <A href='?src=\ref[src];item=shoes'>[(shoes ? shoes : "Nothing")]</A>
|
||||
<BR><B>Belt:</B> <A href='?src=\ref[src];item=belt'>[(belt ? belt : "Nothing")]</A>
|
||||
<BR><B>Uniform:</B> <A href='?src=\ref[src];item=uniform'>[(w_uniform ? w_uniform : "Nothing")]</A>
|
||||
<BR><B>Belt:</B> <A href='?src=\ref[src];item=belt'>[(belt ? belt : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(belt, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
|
||||
<BR><B>Uniform:</B> <A href='?src=\ref[src];item=uniform'>[(w_uniform ? w_uniform : "Nothing")]</A> [(suit) ? ((suit.has_sensor == 1) ? text(" <A href='?src=\ref[];item=sensor'>Sensors</A>", src) : "") :]
|
||||
<BR><B>(Exo)Suit:</B> <A href='?src=\ref[src];item=suit'>[(wear_suit ? wear_suit : "Nothing")]</A>
|
||||
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
|
||||
<BR><B>ID:</B> <A href='?src=\ref[src];item=id'>[(wear_id ? wear_id : "Nothing")]</A>
|
||||
<BR><B>Suit Storage:</B> <A href='?src=\ref[src];item=s_store'>[(s_store ? s_store : "Nothing")]</A>
|
||||
<BR><B>Suit Storage:</B> <A href='?src=\ref[src];item=s_store'>[(s_store ? s_store : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
|
||||
<BR>[(handcuffed ? text("<A href='?src=\ref[src];item=handcuff'>Handcuffed</A>") : text("<A href='?src=\ref[src];item=handcuff'>Not Handcuffed</A>"))]
|
||||
<BR>[(legcuffed ? text("<A href='?src=\ref[src];item=legcuff'>Legcuffed</A>") : text(""))]
|
||||
<BR>[(suit) ? ((suit.hastie) ? text(" <A href='?src=\ref[];item=tie'>Remove Accessory</A>", src) : "") :]
|
||||
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
|
||||
<BR><A href='?src=\ref[src];item=splints'>Remove Splints</A>
|
||||
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
|
||||
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR>"}
|
||||
user << browse(dat, text("window=mob[name];size=340x480"))
|
||||
user << browse(dat, text("window=mob[name];size=340x540"))
|
||||
onclose(user, "mob[name]")
|
||||
return
|
||||
|
||||
|
||||
@@ -388,11 +388,14 @@
|
||||
if(count == 0)
|
||||
del(src)
|
||||
return
|
||||
if("sensor")
|
||||
if (! target.w_uniform )
|
||||
del(src)
|
||||
if("internal")
|
||||
if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal )))
|
||||
del(src)
|
||||
|
||||
var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel")
|
||||
var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel", "sensor", "internal", "tie")
|
||||
if ((item && !( L.Find(place) )))
|
||||
if(isrobot(source) && place != "handcuff")
|
||||
del(src)
|
||||
@@ -508,6 +511,17 @@
|
||||
return
|
||||
else
|
||||
message = "\red <B>[source] is trying to take off \a [target.w_uniform] from [target]'s body!</B>"
|
||||
if("tie")
|
||||
var/obj/item/clothing/under/suit = target.w_uniform
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their accessory ([suit.hastie]) removed by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) accessory ([suit.hastie])</font>")
|
||||
if(istype(suit.hastie, /obj/item/clothing/tie/holobadge) || istype(suit.hastie, /obj/item/clothing/tie/medal))
|
||||
for(var/mob/M in viewers(target, null))
|
||||
M.show_message("\red <B>[source] tears off \the [suit.hastie] from [target]'s suit!</B>" , 1)
|
||||
done()
|
||||
return
|
||||
else
|
||||
message = "\red <B>[source] is trying to take off \a [suit.hastie] from [target]'s suit!</B>"
|
||||
if("s_store")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their suit storage item ([target.s_store]) removed by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) suit storage item ([target.s_store])</font>")
|
||||
@@ -537,6 +551,14 @@
|
||||
message = "\red <B>[source] is trying to set on [target]'s internals.</B>"
|
||||
if("splints")
|
||||
message = text("\red <B>[] is trying to remove []'s splints!</B>", source, target)
|
||||
if("sensor")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their sensors toggled by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to toggle [target.name]'s ([target.ckey]) sensors</font>")
|
||||
var/obj/item/clothing/under/suit = target.w_uniform
|
||||
if (suit.has_sensor >= 2)
|
||||
source << "The controls are locked."
|
||||
return
|
||||
message = "\red <B>[source] is trying to set [target]'s suit sensors!</B>"
|
||||
|
||||
for(var/mob/M in viewers(target, null))
|
||||
M.show_message(message, 1)
|
||||
@@ -624,6 +646,19 @@ It can still be worn/put on as normal.
|
||||
slot_to_process = slot_wear_suit
|
||||
if (target.wear_suit && target.wear_suit.canremove)
|
||||
strip_item = target.wear_suit
|
||||
if("tie")
|
||||
var/obj/item/clothing/under/suit = target.w_uniform
|
||||
//var/obj/item/clothing/tie/tie = suit.hastie
|
||||
/*if(tie)
|
||||
if (istype(tie,/obj/item/clothing/tie/storage))
|
||||
var/obj/item/clothing/tie/storage/W = tie
|
||||
if (W.hold)
|
||||
W.hold.close(usr)
|
||||
usr.put_in_hands(tie)
|
||||
suit.hastie = null*/
|
||||
suit.hastie.on_removed(usr)
|
||||
suit.hastie = null
|
||||
target.update_inv_w_uniform()
|
||||
if("id")
|
||||
slot_to_process = slot_wear_id
|
||||
if (target.wear_id)
|
||||
@@ -675,8 +710,20 @@ It can still be worn/put on as normal.
|
||||
O.show_message("\red [source] injects [target] with the DNA Injector!", 1)
|
||||
S.inuse = 0
|
||||
if("pockets")
|
||||
slot_to_process = slot_l_store
|
||||
strip_item = target.l_store //We'll do both
|
||||
if (!item || (target.l_store && target.r_store)) // Only empty pockets when hand is empty or both pockets are full
|
||||
slot_to_process = slot_l_store
|
||||
strip_item = target.l_store //We'll do both
|
||||
else if (target.l_store)
|
||||
slot_to_process = slot_r_store
|
||||
else
|
||||
slot_to_process = slot_l_store
|
||||
if("sensor")
|
||||
var/obj/item/clothing/under/suit = target.w_uniform
|
||||
if (suit)
|
||||
if(suit.has_sensor >= 2)
|
||||
source << "The controls are locked."
|
||||
else
|
||||
suit.set_sensors(source)
|
||||
if("internal")
|
||||
if (target.internal)
|
||||
target.internal.add_fingerprint(source)
|
||||
|
||||
@@ -321,9 +321,11 @@
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
// HACK NEED CHANGING LATER
|
||||
if(health < config.health_threshold_crit)
|
||||
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
|
||||
losebreath++
|
||||
|
||||
if(losebreath>0) //Suffocating so do not take a breath
|
||||
losebreath--
|
||||
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
|
||||
@@ -431,8 +433,6 @@
|
||||
return
|
||||
|
||||
if(!breath || (breath.total_moles() == 0) || suiciding)
|
||||
if(reagents.has_reagent("inaprovaline"))
|
||||
return
|
||||
if(suiciding)
|
||||
adjustOxyLoss(2)//If you are suiciding, you should die a little bit faster
|
||||
failed_last_breath = 1
|
||||
@@ -508,7 +508,7 @@
|
||||
if(prob(20))
|
||||
spawn(0) emote("gasp")
|
||||
if(inhale_pp > 0)
|
||||
var/ratio = safe_pressure_min/inhale_pp
|
||||
var/ratio = inhale_pp/safe_pressure_min
|
||||
|
||||
// Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS after all!)
|
||||
// The hell? By definition ratio > 1, and HUMAN_MAX_OXYLOSS = 1... why do we even have this?
|
||||
|
||||
@@ -367,7 +367,7 @@ var/list/ai_list = list()
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
if (href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"])) in cameranet.viewpoints
|
||||
switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
|
||||
if (href_list["showalerts"])
|
||||
ai_alerts()
|
||||
//Carn: holopad requests
|
||||
@@ -583,7 +583,7 @@ var/list/ai_list = list()
|
||||
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
for (var/obj/machinery/camera/C in cameranet.viewpoints)
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
|
||||
@@ -601,7 +601,7 @@ var/list/ai_list = list()
|
||||
if(isnull(network))
|
||||
network = old_network // If nothing is selected
|
||||
else
|
||||
for(var/obj/machinery/camera/C in cameranet.viewpoints)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(network in C.network)
|
||||
|
||||
@@ -1,25 +1,148 @@
|
||||
/datum/visibility_network/cameras
|
||||
ChunkType = /datum/visibility_chunk/camera
|
||||
// CAMERA NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
/datum/visibility_network/cameras/getViewpointFromMob(var/mob/currentMob)
|
||||
var/mob/living/silicon/robot/currentRobot=currentMob
|
||||
if(currentRobot)
|
||||
return currentRobot.camera
|
||||
return FALSE
|
||||
|
||||
/datum/visibility_network/cameras/validViewpoint(var/viewpoint)
|
||||
var/obj/machinery/camera/c = viewpoint
|
||||
if (!c)
|
||||
return FALSE
|
||||
return c.can_use()
|
||||
|
||||
|
||||
// adding some indirection so that I don't have to edit a ton of files
|
||||
/datum/visibility_network/cameras/proc/addCamera(var/camera)
|
||||
return addViewpoint(camera)
|
||||
|
||||
/datum/visibility_network/cameras/proc/removeCamera(var/camera)
|
||||
return removeViewpoint(camera)
|
||||
|
||||
/datum/visibility_network/cameras/proc/checkCameraVis(var/atom/target)
|
||||
return checkCanSee(target)
|
||||
var/datum/cameranet/cameranet = new()
|
||||
|
||||
/datum/cameranet
|
||||
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
||||
var/list/cameras = list()
|
||||
// The chunks of the map, mapping the areas that the cameras can see.
|
||||
var/list/chunks = list()
|
||||
var/ready = 0
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
return (chunks[key])
|
||||
|
||||
// Returns the chunk in the x, y, z.
|
||||
// If there is no chunk, it creates a new chunk and returns that.
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
if(!chunks[key])
|
||||
chunks[key] = new /datum/camerachunk(null, x, y, z)
|
||||
|
||||
return chunks[key]
|
||||
|
||||
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
|
||||
|
||||
/datum/cameranet/proc/visibility(mob/aiEye/ai)
|
||||
// 0xf = 15
|
||||
var/x1 = max(0, ai.x - 16) & ~0xf
|
||||
var/y1 = max(0, ai.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
|
||||
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
visibleChunks += getCameraChunk(x, y, ai.z)
|
||||
|
||||
var/list/remove = ai.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - ai.visibleCameraChunks
|
||||
|
||||
for(var/chunk in remove)
|
||||
var/datum/camerachunk/c = chunk
|
||||
c.remove(ai)
|
||||
|
||||
for(var/chunk in add)
|
||||
var/datum/camerachunk/c = chunk
|
||||
c.add(ai)
|
||||
|
||||
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
|
||||
/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
|
||||
if(!ticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
/datum/cameranet/proc/updateChunk(x, y, z)
|
||||
// 0xf = 15
|
||||
if(!chunkGenerated(x, y, z))
|
||||
return
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
|
||||
chunk.hasChanged()
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
|
||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// Add a camera to a chunk.
|
||||
|
||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
|
||||
// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
|
||||
|
||||
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
//else
|
||||
// majorChunkChange(c, 0)
|
||||
|
||||
// Never access this proc directly!!!!
|
||||
// This will update the chunk and all the surrounding chunks.
|
||||
// It will also add the atom to the cameras list if you set the choice to 1.
|
||||
// Setting the choice to 0 will remove the camera from the chunks.
|
||||
// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
|
||||
|
||||
/datum/cameranet/proc/majorChunkChange(atom/c, var/choice)
|
||||
// 0xf = 15
|
||||
if(!c)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(c)
|
||||
if(T)
|
||||
var/x1 = max(0, T.x - 8) & ~0xf
|
||||
var/y1 = max(0, T.y - 8) & ~0xf
|
||||
var/x2 = min(world.maxx, T.x + 8) & ~0xf
|
||||
var/y2 = min(world.maxy, T.y + 8) & ~0xf
|
||||
|
||||
//world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]"
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, T.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
|
||||
if(choice == 0)
|
||||
// Remove the camera.
|
||||
chunk.cameras -= c
|
||||
else if(choice == 1)
|
||||
// You can't have the same camera in the list twice.
|
||||
chunk.cameras |= c
|
||||
chunk.hasChanged()
|
||||
|
||||
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
|
||||
/datum/cameranet/proc/checkCameraVis(mob/living/target as mob)
|
||||
|
||||
// 0xf = 15
|
||||
var/turf/position = get_turf(target)
|
||||
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
|
||||
if(chunk)
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
if(chunk.visibleTurfs[position])
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
// Debug verb for VVing the chunk that the turf is in.
|
||||
/*
|
||||
/turf/verb/view_chunk()
|
||||
set src in world
|
||||
|
||||
if(cameranet.chunkGenerated(x, y, z))
|
||||
var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z)
|
||||
usr.client.debug_variables(chunk)
|
||||
*/
|
||||
@@ -1,23 +1,168 @@
|
||||
/datum/visibility_chunk/camera
|
||||
#define UPDATE_BUFFER 25 // 2.5 seconds
|
||||
|
||||
// CAMERA CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the AI Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/camerachunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/obscured = list()
|
||||
var/list/cameras = list()
|
||||
var/list/turfs = list()
|
||||
var/list/seenby = list()
|
||||
var/visible = 0
|
||||
var/changed = 0
|
||||
var/updating = 0
|
||||
var/x = 0
|
||||
var/y = 0
|
||||
var/z = 0
|
||||
|
||||
// Add an AI eye to the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/ai)
|
||||
if(!ai.ai)
|
||||
return
|
||||
ai.visibleCameraChunks += src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images += obscured
|
||||
visible++
|
||||
seenby += ai
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
// Remove an AI eye from the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/ai)
|
||||
if(!ai.ai)
|
||||
return
|
||||
ai.visibleCameraChunks -= src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images -= obscured
|
||||
seenby -= ai
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!visibleTurfs[loc])
|
||||
return
|
||||
hasChanged()
|
||||
|
||||
// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
|
||||
// instead be flagged to update the next time an AI Eye moves near it.
|
||||
|
||||
/datum/camerachunk/proc/hasChanged(var/update_now = 0)
|
||||
if(visible || update_now)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once
|
||||
update()
|
||||
updating = 0
|
||||
else
|
||||
changed = 1
|
||||
|
||||
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
|
||||
|
||||
/datum/camerachunk/proc/update()
|
||||
|
||||
set background = 1
|
||||
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/camera in cameras)
|
||||
var/obj/machinery/camera/c = camera
|
||||
|
||||
if(!c)
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
continue
|
||||
|
||||
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
|
||||
if(get_dist(point, c) > 24)
|
||||
continue
|
||||
|
||||
for(var/turf/t in c.can_see())
|
||||
newVisibleTurfs[t] = t
|
||||
|
||||
// Removes turf that isn't in turfs.
|
||||
newVisibleTurfs &= turfs
|
||||
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
obscuredTurfs = turfs - newVisibleTurfs
|
||||
|
||||
for(var/turf in visAdded)
|
||||
var/turf/t = turf
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/aiEye/m = eye
|
||||
if(!m || !m.ai)
|
||||
continue
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf in visRemoved)
|
||||
var/turf/t = turf
|
||||
if(obscuredTurfs[t])
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/aiEye/m = eye
|
||||
if(!m || !m.ai)
|
||||
seenby -= m
|
||||
continue
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
|
||||
// 0xf = 15
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
src.x = x
|
||||
src.y = y
|
||||
src.z = z
|
||||
|
||||
/datum/visibility_chunk/camera/validViewpoint(var/viewpoint)
|
||||
var/obj/machinery/camera/c = viewpoint
|
||||
if(!c)
|
||||
return FALSE
|
||||
if(!c.can_use())
|
||||
return FALSE
|
||||
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
|
||||
if(get_dist(point, c) > 24)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/visibility_chunk/camera/getVisibleTurfsForViewpoint(var/viewpoint)
|
||||
var/obj/machinery/camera/c = viewpoint
|
||||
return c.can_see()
|
||||
|
||||
|
||||
/datum/visibility_chunk/camera/findNearbyViewpoints()
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.can_use())
|
||||
viewpoints += c
|
||||
cameras += c
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs[t] = t
|
||||
|
||||
for(var/camera in cameras)
|
||||
var/obj/machinery/camera/c = camera
|
||||
if(!c)
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
continue
|
||||
|
||||
for(var/turf/t in c.can_see())
|
||||
visibleTurfs[t] = t
|
||||
|
||||
// Removes turf that isn't in turfs.
|
||||
visibleTurfs &= turfs
|
||||
|
||||
obscuredTurfs = turfs - visibleTurfs
|
||||
|
||||
for(var/turf in obscuredTurfs)
|
||||
var/turf/t = turf
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
|
||||
obscured += t.obscured
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
@@ -6,16 +6,13 @@
|
||||
/mob/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
density = 0
|
||||
status_flags = GODMODE // You can't damage it.
|
||||
mouse_opacity = 0
|
||||
see_in_dark = 7
|
||||
|
||||
/mob/aiEye/New()
|
||||
..()
|
||||
visibility_interface = new /datum/visibility_interface/ai_eye(src)
|
||||
|
||||
// Movement code. Returns 0 to stop air movement from moving it.
|
||||
/mob/aiEye/Move()
|
||||
return 0
|
||||
@@ -40,6 +37,7 @@
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
|
||||
/mob/aiEye/proc/setLoc(var/T)
|
||||
|
||||
if(ai)
|
||||
if(!isturf(ai.loc))
|
||||
return
|
||||
@@ -138,8 +136,7 @@
|
||||
|
||||
if(client && client.eye)
|
||||
client.eye = src
|
||||
|
||||
for(var/datum/visibility_chunk/camera/c in eyeobj.visibility_interface.visible_chunks)
|
||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
||||
c.remove(eyeobj)
|
||||
|
||||
/mob/living/silicon/ai/verb/toggle_acceleration()
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
WHERE IS EVERYTHING?
|
||||
|
||||
cameraNetwork.dm = Everything about the cameraNetwork datum.
|
||||
cameranet.dm = Everything about the cameranet datum.
|
||||
chunk.dm = Everything about the chunk datum.
|
||||
eye.dm = Everything about the AI and the AIEye.
|
||||
updating.dm = Everything about triggers that will update chunks.
|
||||
|
||||
@@ -1,5 +1,80 @@
|
||||
#define BORG_CAMERA_BUFFER 30
|
||||
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
// TURFS
|
||||
|
||||
/turf
|
||||
var/image/obscured
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/turf/simulated/Del()
|
||||
visibilityChanged()
|
||||
..()
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
visibilityChanged()
|
||||
|
||||
|
||||
|
||||
// STRUCTURES
|
||||
|
||||
/obj/structure/Del()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
// EFFECTS
|
||||
|
||||
/obj/effect/Del()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
|
||||
/obj/effect/New()
|
||||
..()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
|
||||
// DOORS
|
||||
|
||||
// Simply updates the visibility of the area when it opens/closes/destroyed.
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
// Glass door glass = 1
|
||||
// don't check then?
|
||||
if(!glass && cameranet)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
|
||||
// ROBOT MOVEMENT
|
||||
|
||||
// Update the portable camera everytime the Robot moves.
|
||||
// This might be laggy, comment it out if there are problems.
|
||||
/mob/living/silicon/robot/var/updating = 0
|
||||
|
||||
/mob/living/silicon/robot/Move()
|
||||
var/oldLoc = src.loc
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.camera && src.camera.network.len)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
// CAMERA
|
||||
|
||||
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
|
||||
@@ -7,23 +82,23 @@
|
||||
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
||||
..(user, choice)
|
||||
if(src.can_use())
|
||||
cameranet.addViewpoint(src)
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
src.SetLuminosity(0)
|
||||
cameranet.removeViewpoint(src)
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
cameranet.viewpoints += src //Camera must be added to global list of all cameras no matter what...
|
||||
cameranet.cameras += src //Camera must be added to global list of all cameras no matter what...
|
||||
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
|
||||
if(open_networks.len) //If there is at least one open network, chunk is available for AI usage.
|
||||
cameranet.addViewpoint(src)
|
||||
cameranet.addCamera(src)
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
cameranet.viewpoints -= src
|
||||
cameranet.cameras -= src
|
||||
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS)
|
||||
if(open_networks.len)
|
||||
cameranet.removeViewpoint(src)
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
@@ -1,10 +0,0 @@
|
||||
/datum/visibility_interface/ai_eye
|
||||
chunk_type = /datum/visibility_chunk/camera
|
||||
|
||||
/datum/visibility_interface/ai_eye/getClient()
|
||||
var/mob/aiEye/eye = controller
|
||||
if (!eye)
|
||||
return FALSE
|
||||
if (!eye.ai)
|
||||
return FALSE
|
||||
return eye.ai.client
|
||||
@@ -11,11 +11,10 @@
|
||||
pass_flags = PASSTABLE
|
||||
braintype = "Robot"
|
||||
lawupdate = 0
|
||||
density = 0
|
||||
density = 1
|
||||
|
||||
// We need to keep track of a few module items so we don't need to do list operations
|
||||
// every time we need them. These get set in New() after the module is chosen.
|
||||
|
||||
var/obj/item/stack/sheet/metal/cyborg/stack_metal = null
|
||||
var/obj/item/stack/sheet/wood/cyborg/stack_wood = null
|
||||
var/obj/item/stack/sheet/glass/cyborg/stack_glass = null
|
||||
@@ -25,6 +24,8 @@
|
||||
//Used for self-mailing.
|
||||
var/mail_destination = 0
|
||||
|
||||
//Used for pulling.
|
||||
|
||||
/mob/living/silicon/robot/drone/New()
|
||||
|
||||
..()
|
||||
@@ -58,7 +59,6 @@
|
||||
updatename()
|
||||
updateicon()
|
||||
|
||||
|
||||
//Redefining some robot procs...
|
||||
/mob/living/silicon/robot/drone/updatename()
|
||||
real_name = "maintenance drone ([rand(100,999)])"
|
||||
@@ -101,10 +101,27 @@
|
||||
return emote(copytext(message,2))
|
||||
else if(length(message) >= 2)
|
||||
if(copytext(message, 1 ,3) == ":b" || copytext(message, 1 ,3) == ":B")
|
||||
|
||||
if(!is_component_functioning("comms"))
|
||||
src << "\red Your binary communications component isn't functional."
|
||||
return
|
||||
|
||||
robot_talk(trim(copytext(message,3)))
|
||||
|
||||
else if(copytext(message, 1 ,3) == ":d" || copytext(message, 1 ,3) == ":d")
|
||||
|
||||
if(!is_component_functioning("radio"))
|
||||
src << "\red Your radio transmitter isn't functional."
|
||||
return
|
||||
|
||||
for (var/mob/living/S in living_mob_list)
|
||||
if(istype(S, /mob/living/silicon/robot/drone))
|
||||
S << "<i><span class='game say'>Drone Talk, <span class='name'>[name]</span><span class='message'> transmits, \"[message]\"</span></span></i>"
|
||||
|
||||
for (var/mob/M in dead_mob_list)
|
||||
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain))
|
||||
M << "<i><span class='game say'>Drone Talk, <span class='name'>[name]</span><span class='message'> transmits, \"[message]\"</span></span></i>"
|
||||
|
||||
else
|
||||
|
||||
var/list/listeners = hearers(5,src)
|
||||
@@ -298,8 +315,35 @@
|
||||
if(player.mob && player.mob.mind)
|
||||
player.mob.mind.transfer_to(src)
|
||||
|
||||
emagged = 0
|
||||
lawupdate = 0
|
||||
src << "<b>Systems rebooted</b>. Loading base pattern maintenance protocol... <b>loaded</b>."
|
||||
full_law_reset()
|
||||
src << "<br><b>You are a maintenance drone, a tiny-brained robotic repair machine</b>."
|
||||
src << "You have no individual will, no personality, and no drives or urges other than your laws."
|
||||
src << "Use <b>:b</b> to talk to your fellow synthetics, or use <b>say</b> to speak silently to other drones nearby."
|
||||
src << "Remember, you are <b>lawed against interference with the crew</b>."
|
||||
src << "<b>Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets.</b>"
|
||||
src << "<b>If a crewmember has noticed you, <i>you are probably breaking your third law</i></b>."
|
||||
|
||||
/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if (!yes || (!istype(AM,/obj/machinery/door) && !istype(AM,/obj/machinery/recharge_station)) ) return
|
||||
..()
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/Bumped(AM as mob|obj)
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
|
||||
|
||||
if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct))
|
||||
..()
|
||||
else if(istype(AM,/obj/item))
|
||||
var/obj/item/O = AM
|
||||
if(O.w_class > 2)
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
else
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
|
||||
@@ -53,9 +53,12 @@
|
||||
wrapped = null
|
||||
//update_icon()
|
||||
|
||||
/obj/item/weapon/gripper/afterattack(atom/target, mob/user as mob)
|
||||
/obj/item/weapon/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
return
|
||||
|
||||
if(!target) //Target is invalid.
|
||||
/obj/item/weapon/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
|
||||
|
||||
if(!target || !flag) //Target is invalid or we are not adjacent.
|
||||
return
|
||||
|
||||
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
|
||||
@@ -139,7 +142,12 @@
|
||||
"plastic" = 0
|
||||
)
|
||||
|
||||
/obj/item/weapon/matter_decompiler/afterattack(atom/target, mob/user as mob)
|
||||
/obj/item/weapon/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
return
|
||||
|
||||
/obj/item/weapon/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
|
||||
|
||||
if(!flag) return //Not adjacent.
|
||||
|
||||
//We only want to deal with using this on turfs. Specific items aren't important.
|
||||
var/turf/T = get_turf(target)
|
||||
@@ -160,7 +168,7 @@
|
||||
stored_comms["plastic"]++
|
||||
return
|
||||
|
||||
else if(istype(M,/mob/living/silicon/robot/drone) && M.stat == 2 && !M.client)
|
||||
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
|
||||
|
||||
var/mob/living/silicon/robot/drone/D = src.loc
|
||||
|
||||
|
||||
@@ -90,10 +90,7 @@
|
||||
modtype = "Security"
|
||||
else if(istype(src,/mob/living/silicon/robot/drone))
|
||||
laws = new /datum/ai_laws/drone()
|
||||
connected_ai = select_active_ai_with_fewest_borgs()
|
||||
if(connected_ai)
|
||||
connected_ai.connected_robots += src
|
||||
lawsync()
|
||||
connected_ai = null
|
||||
else
|
||||
laws = new /datum/ai_laws/nanotrasen()
|
||||
connected_ai = select_active_ai_with_fewest_borgs()
|
||||
@@ -531,15 +528,15 @@
|
||||
/mob/living/silicon/robot/triggerAlarm(var/class, area/A, list/cameralist, var/source)
|
||||
if (stat == 2)
|
||||
return 1
|
||||
|
||||
|
||||
..()
|
||||
|
||||
|
||||
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
|
||||
|
||||
|
||||
/mob/living/silicon/robot/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
var/has_alarm = ..()
|
||||
|
||||
|
||||
if (!has_alarm)
|
||||
queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0)
|
||||
// if (viewalerts) robot_alerts()
|
||||
|
||||
@@ -305,9 +305,9 @@
|
||||
src.modules += new /obj/item/weapon/wirecutters(src)
|
||||
src.modules += new /obj/item/device/multitool(src)
|
||||
src.modules += new /obj/item/device/lightreplacer(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner(src)
|
||||
src.modules += new /obj/item/weapon/gripper(src)
|
||||
src.modules += new /obj/item/weapon/matter_decompiler(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
|
||||
|
||||
src.emag = new /obj/item/weapon/card/emag(src)
|
||||
src.emag.name = "Cryptographic Sequencer"
|
||||
@@ -324,7 +324,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules
|
||||
C.reagents.add_reagent("cleaner", 10)
|
||||
C.reagents.add_reagent("cleaner", 3)
|
||||
|
||||
for(var/T in stacktypes)
|
||||
var/O = locate(T) in src.modules
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
icon_state = "spiderbot-chassis"
|
||||
icon_living = "spiderbot-chassis"
|
||||
icon_dead = "spiderbot-smashed"
|
||||
universal_speak = 1 //Temp until these are rewritten.
|
||||
|
||||
wander = 0
|
||||
|
||||
health = 10
|
||||
@@ -33,9 +35,8 @@
|
||||
response_disarm = "shoos"
|
||||
response_harm = "stomps on"
|
||||
|
||||
var/emagged = 0
|
||||
var/obj/item/held_item = null //Storage for single item they can hold.
|
||||
var/emagged = 0 //IS WE EXPLODEN?
|
||||
var/syndie = 0 //IS WE SYNDICAT? (currently unused)
|
||||
speed = -1 //Spiderbots gotta go fast.
|
||||
//pass_flags = PASSTABLE //Maybe griefy?
|
||||
small = 1
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
// Copy Mimic
|
||||
//
|
||||
|
||||
var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window)
|
||||
var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/animate)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy
|
||||
|
||||
|
||||
@@ -454,22 +454,22 @@
|
||||
overlays = null
|
||||
if (targeted_by && target_locked)
|
||||
overlays += target_locked
|
||||
|
||||
/mob/living/simple_animal/say(var/message)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
if(copytext(message,1,2) == "*")
|
||||
return emote(copytext(message,2))
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
var/verb = "says"
|
||||
|
||||
if(speak_emote.len)
|
||||
verb = pick(speak_emote)
|
||||
|
||||
message = capitalize(trim_left(message))
|
||||
|
||||
..(message, null, verb)
|
||||
|
||||
/mob/living/simple_animal/say(var/message)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
if(copytext(message,1,2) == "*")
|
||||
return emote(copytext(message,2))
|
||||
|
||||
if(stat)
|
||||
return
|
||||
|
||||
var/verb = "says"
|
||||
|
||||
if(speak_emote.len)
|
||||
verb = pick(speak_emote)
|
||||
|
||||
message = capitalize(trim_left(message))
|
||||
|
||||
..(message, null, verb)
|
||||
|
||||
@@ -333,9 +333,6 @@ var/list/slot_equipment_priority = list( \
|
||||
return
|
||||
*/
|
||||
|
||||
/mob
|
||||
var/newPlayerType = /mob/new_player
|
||||
|
||||
/mob/verb/abandon_mob()
|
||||
set name = "Respawn"
|
||||
set category = "OOC"
|
||||
@@ -385,12 +382,14 @@ var/list/slot_equipment_priority = list( \
|
||||
log_game("[usr.key] AM failed due to disconnect.")
|
||||
return
|
||||
|
||||
var/mob/newPlayer = new newPlayerType()
|
||||
var/mob/new_player/M = new /mob/new_player()
|
||||
if(!client)
|
||||
log_game("[usr.key] AM failed due to disconnect.")
|
||||
del(newPlayer)
|
||||
del(M)
|
||||
return
|
||||
newPlayer.key = key
|
||||
|
||||
M.key = key
|
||||
// M.Login() //wat
|
||||
return
|
||||
|
||||
/client/verb/changes()
|
||||
|
||||
@@ -205,7 +205,6 @@
|
||||
|
||||
|
||||
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
|
||||
var/datum/visibility_interface/visibility_interface = null // used by the visibility system to provide an interface for the visibility networks
|
||||
|
||||
//Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything.
|
||||
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
|
||||
|
||||
@@ -114,17 +114,7 @@ proc/isobserver(A)
|
||||
if(istype(A, /mob/dead/observer))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/isSpirit(A)
|
||||
if(istype(A, /mob/spirit))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/ismask(A)
|
||||
if(istype(A, /mob/spirit/mask))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/isorgan(A)
|
||||
if(istype(A, /datum/organ/external))
|
||||
return 1
|
||||
|
||||
@@ -176,15 +176,8 @@
|
||||
return
|
||||
|
||||
if(mob.stat==2) return
|
||||
|
||||
// handle possible spirit movement
|
||||
if(istype(mob,/mob/spirit))
|
||||
var/mob/spirit/currentSpirit = mob
|
||||
return currentSpirit.Spirit_Move(direct)
|
||||
|
||||
// handle possible AI movement
|
||||
if(isAI(mob))
|
||||
return AIMove(n,direct,mob)
|
||||
|
||||
if(isAI(mob)) return AIMove(n,direct,mob)
|
||||
|
||||
if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var
|
||||
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
if(name != real_name)
|
||||
alt_name = " (died as [real_name])"
|
||||
|
||||
message = src.say_quote(message)
|
||||
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name] <span class='message'>[message]</span></span>"
|
||||
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name] [pick("complains","moans","whines","laments","blubbers")], <span class='message'>\"[message]\"</span></span>"
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(istype(M, /mob/new_player))
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
|
||||
This file contains the code necessary to do the display code for cult spirits.
|
||||
|
||||
It reuses a lot of code from the AIEye cameraNetwork. In order to work properly, some of those files needed to be modified as well.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/proc/isCultRune(var/viewpoint)
|
||||
var/obj/effect/rune/test_rune = viewpoint
|
||||
if (test_rune)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/proc/isCultViewpoint(var/viewpoint)
|
||||
var/obj/cult_viewpoint/vp = viewpoint
|
||||
if (vp)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/visibility_chunk/cult/validViewpoint(var/atom/viewpoint)
|
||||
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
|
||||
if(get_dist(point, viewpoint) > 24)
|
||||
return FALSE
|
||||
|
||||
if (isCultRune(viewpoint) || isCultViewpoint(viewpoint))
|
||||
return viewpoint:can_use()
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/visibility_chunk/cult/getVisibleTurfsForViewpoint(var/viewpoint)
|
||||
var/obj/effect/rune/rune = viewpoint
|
||||
if (rune)
|
||||
return rune.can_see()
|
||||
var/obj/cult_viewpoint/cvp = viewpoint
|
||||
if (cvp)
|
||||
return cvp.can_see()
|
||||
return null
|
||||
|
||||
|
||||
/datum/visibility_chunk/cult/findNearbyViewpoints()
|
||||
for(var/obj/cult_viewpoint/vp in range(16, locate(x + 8, y + 8, z)))
|
||||
if(vp.can_use())
|
||||
viewpoints += vp
|
||||
for(var/obj/effect/rune/rune in range(16, locate(x + 8, y + 8, z)))
|
||||
viewpoints += rune
|
||||
|
||||
|
||||
/datum/visibility_network/cult
|
||||
ChunkType = /datum/visibility_chunk/cult
|
||||
|
||||
|
||||
/datum/visibility_network/cult/validViewpoint(var/viewpoint)
|
||||
if (isCultRune(viewpoint) || isCultViewpoint(viewpoint))
|
||||
return viewpoint:can_use()
|
||||
return FALSE
|
||||
|
||||
/datum/visibility_network/cult/getViewpointFromMob(var/mob/currentMob)
|
||||
for(var/obj/cult_viewpoint/currentView in currentMob)
|
||||
return currentView
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/visibility_interface/cult
|
||||
chunk_type = /datum/visibility_chunk/cult
|
||||
|
||||
|
||||
/*
|
||||
RUNE JUNK
|
||||
*/
|
||||
|
||||
/obj/effect/rune/proc/can_use()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/rune/proc/can_see()
|
||||
return hear(view_range, get_turf(src))
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
/mob/spirit/mask
|
||||
icon = 'icons/mob/spirits/mask.dmi'
|
||||
icon_state = "depressurized"
|
||||
|
||||
/mob/spirit/mask/New()
|
||||
..()
|
||||
spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman(src)
|
||||
spell_list += new /obj/effect/proc_holder/spell/aoe_turf/blood_speech(src)
|
||||
spell_list += new /obj/effect/proc_holder/spell/aoe_turf/shatter_lights(src)
|
||||
|
||||
|
||||
/mob/spirit/mask/verb/go_to_follower()
|
||||
set category = "Mask"
|
||||
set name = "Go to follower"
|
||||
set desc = "Select who you would like to go too."
|
||||
|
||||
var/obj/cult_viewpoint/cultist = pick_cultist()
|
||||
if (cultist)
|
||||
follow_cultist(cultist.owner)
|
||||
cult_log("[key_name_admin(src)] started following [key_name_admin(cultist)].")
|
||||
src << "You start following [cultist.get_display_name()]."
|
||||
|
||||
|
||||
/mob/spirit/mask/verb/urge_cultist()
|
||||
set category = "Mask"
|
||||
set name = "Urge cultist"
|
||||
set desc = "Push your cultists to do something."
|
||||
|
||||
var/obj/cult_viewpoint/cultist = pick_cultist()
|
||||
if (cultist)
|
||||
if (cultist.owner)
|
||||
var/newUrge = stripped_input(usr, "", "Set Urge", "")
|
||||
cultist.set_urge(newUrge)
|
||||
src << "You urge [cultist.owner.name] to [newUrge]."
|
||||
cult_log("controlled by [key_name_admin(src)] has urged [key_name_admin(cultist.owner)] to [newUrge].")
|
||||
|
||||
/mob/spirit/mask/verb/set_cult_name()
|
||||
set category = "Mask"
|
||||
set name = "Set Cult Name"
|
||||
set desc = "Grant a cultist a name."
|
||||
|
||||
var/obj/cult_viewpoint/cultist = pick_cultist()
|
||||
if (cultist)
|
||||
var/newName = stripped_input(usr, "", "Set Cult Name", "")
|
||||
if (!newName)
|
||||
return
|
||||
cultist.set_cult_name(newName)
|
||||
src << "You grant [cultist.owner.name] the secret name of [newName]."
|
||||
if (cultist.owner)
|
||||
cult_log("[key_name_admin(src)] has set [key_name_admin(cultist.owner)] to \'[newName]\'")
|
||||
|
||||
|
||||
/mob/spirit/mask/verb/urge_cult()
|
||||
set category = "Mask"
|
||||
set name = "Urge Cult"
|
||||
set desc = "Set urge on the entire cult."
|
||||
|
||||
var/newUrge = stripped_input(usr, "Please choose an urge.", "Set Urge", "")
|
||||
for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints)
|
||||
viewpoint.set_urge(newUrge)
|
||||
src << "You urge the entire cult to [newUrge]."
|
||||
cult_log("[key_name_admin(src)] has urged the entire cult to [newUrge]")
|
||||
|
||||
|
||||
/mob/spirit/mask/verb/set_favor_for_cultist()
|
||||
set category = "Mask"
|
||||
set name = "Show your favor"
|
||||
set desc = "Set the favor for a cultist"
|
||||
|
||||
var/obj/cult_viewpoint/cultist = pick_cultist()
|
||||
if (cultist)
|
||||
if (cultist.owner)
|
||||
var/list/favor = list("Pleased", "Displeased", "Indifference")
|
||||
var/emotion = input("Pick your emotion", "Mask", null, null) in favor
|
||||
switch(emotion)
|
||||
if("Pleased")
|
||||
cultist.set_favor(1)
|
||||
cult_log("[key_name_admin(src)] is pleased with [key_name_admin(cultist.owner)]")
|
||||
if("Displeased")
|
||||
cultist.set_favor(-1)
|
||||
cult_log("[key_name_admin(src)] is displeased with [key_name_admin(cultist.owner)]")
|
||||
if("Indifference")
|
||||
cultist.set_favor(0)
|
||||
cult_log("[key_name_admin(src)] is indifferent too [key_name_admin(cultist.owner)]")
|
||||
|
||||
|
||||
/mob/spirit/mask/proc/set_name()
|
||||
spawn(0)
|
||||
var/newName = stripped_input(src, "Please pick a name.", "Pick Name for Mask", "")
|
||||
name = newName ? newName : "Mask of Nar'sie"
|
||||
src << "You have set your name to [name]."
|
||||
|
||||
|
||||
/mob/spirit/mask/proc/pick_cultist()
|
||||
var/list/cultists = list()
|
||||
for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints)
|
||||
cultists[viewpoint.get_display_name()]=viewpoint
|
||||
var/input = input("Please, select a cultist!", "Cult", null, null) as null|anything in cultists
|
||||
var/obj/cult_viewpoint/result = cultists[input]
|
||||
return result
|
||||
|
||||
|
||||
// this proc makes the mask visible very briefly
|
||||
/mob/spirit/mask/proc/flicker()
|
||||
spawn(0)
|
||||
alpha = 127
|
||||
invisibility=0
|
||||
sleep(5)
|
||||
invisibility=initial(invisibility)
|
||||
alpha = 255
|
||||
|
||||
/proc/flicker_mask(mob/spirit/mask/target)
|
||||
if(istype(target))
|
||||
target.flicker()
|
||||
|
||||
// SPELLS
|
||||
/obj/effect/proc_holder/spell/aoe_turf/blood_speech
|
||||
name = "Speak to your Acolytes"
|
||||
desc = "This spell allows you to speak to your flock."
|
||||
school = "unknown evil"
|
||||
charge_type = "recharge"
|
||||
charge_max = 2000
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/blood_speech/cast(list/targets)
|
||||
var/input = stripped_input(usr, "Please choose a message to tell your acolytes.", "Voice of Blood", "")
|
||||
if(!input)
|
||||
revert_cast(usr)
|
||||
cult_log("[key_name_admin(usr)]says : [input]")
|
||||
flicker_mask(usr)
|
||||
for(var/datum/mind/H in ticker.mode.cult)
|
||||
if (H.current)
|
||||
H.current << "<span class='cultspeech'><font size=3><span class='name'>[usr.name]: </span><span class='message'>[input]</span></font></span>"
|
||||
for(var/mob/spirit/spirit in spirits)
|
||||
spirit << "<span class='cultspeech'><font size=3><span class='name'>[usr.name]: </span><span class='message'>[input]</span></font></span>"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/shatter_lights
|
||||
name = "Spread Shadows"
|
||||
desc = "This spell breaks lights near the mask."
|
||||
school = "unknown evil"
|
||||
charge_type = "recharge"
|
||||
charge_max = 1000
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/shatter_lights/cast(list/targets)
|
||||
cult_log("[key_name_admin(usr)] used Spread Shadows.")
|
||||
flicker_mask(usr)
|
||||
spawn(0)
|
||||
for(var/area/A in range(3,get_turf(usr)))
|
||||
for(var/obj/machinery/light/L in A)
|
||||
L.on = 1
|
||||
L.broken()
|
||||
sleep(1)
|
||||
for(var/obj/item/device/flashlight/F in A)
|
||||
F.on = 0
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman
|
||||
name = "Create Talisman"
|
||||
desc = "This spell conjures a talisman"
|
||||
|
||||
school = "conjuration"
|
||||
charge_type = "recharge"
|
||||
charge_max = 3000
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
summon_type = list(/obj/item/weapon/paper/talisman)
|
||||
|
||||
var/list/talismans = list( "Armor"="armor",
|
||||
"Blind"="blind",
|
||||
"Conceal"="conceal",
|
||||
"Communicate"="communicate",
|
||||
"Deafen"="deafen",
|
||||
"EMP"="emp",
|
||||
"Teleport"="teleport",
|
||||
"Tome"="newtome",
|
||||
"Reveal Runes",
|
||||
"Stun"="runestun",
|
||||
"Soul Stone"="soulstone",
|
||||
"Construct"="construct")
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/create_talisman/cast(list/targets)
|
||||
|
||||
var/talisman = input("Pick a talisman type", "Talisman", null, null) as null|anything in talismans
|
||||
var/imbue_value = talismans[talisman]
|
||||
if (!talisman)
|
||||
usr << "You choose not to create a talisman."
|
||||
revert_cast(usr)
|
||||
return
|
||||
|
||||
cult_log("[key_name_admin(usr,0)] created a talisman of type [talisman].")
|
||||
flicker_mask(usr)
|
||||
|
||||
switch(talisman)
|
||||
|
||||
if ("Teleport")
|
||||
var/target_rune = input("Pick a teleport target", "Teleport Rune", null, null) as null|anything in engwords
|
||||
if (!target_rune)
|
||||
usr << "You choose not to create a talisman."
|
||||
revert_cast(usr)
|
||||
return
|
||||
summon_type = list(/obj/item/weapon/paper/talisman)
|
||||
newVars = list("imbue" = "[target_rune]", "info" = "[target_rune]")
|
||||
|
||||
if ("Soul Stone")
|
||||
summon_type = list(/obj/item/device/soulstone)
|
||||
newVars = list()
|
||||
|
||||
if ("Construct")
|
||||
summon_type = list(/obj/structure/constructshell)
|
||||
newVars = list()
|
||||
|
||||
else
|
||||
summon_type = list(/obj/item/weapon/paper/talisman)
|
||||
newVars = list("imbue" = "[imbue_value]")
|
||||
|
||||
..()
|
||||
@@ -1,20 +0,0 @@
|
||||
/proc/there_can_be_only_one_mask(var/mob/spirit/mask/target)
|
||||
if(!istype(target))
|
||||
return
|
||||
for(var/mob/spirit/mask/currentSpirit in spirits)
|
||||
if(currentSpirit)
|
||||
if(currentSpirit!=target)
|
||||
// create the ghost
|
||||
var/mob/dead/observer/ghost = currentSpirit.ghostize(TRUE)
|
||||
// let the deposed mask respawn immediately, the poor dear
|
||||
ghost.timeofdeath = world.time - 20000
|
||||
ghost.newPlayerType = /mob/new_player/cultist
|
||||
// remove old mask body
|
||||
del(currentSpirit)
|
||||
|
||||
|
||||
/mob/new_player/cultist/AttemptLateSpawn(rank)
|
||||
var/mob/newCharacter = ..(rank)
|
||||
if(ticker.mode)
|
||||
if(is_convertable_to_cult(newCharacter.mind))
|
||||
ticker.mode.add_cultist(newCharacter.mind)
|
||||
@@ -1,62 +0,0 @@
|
||||
// spirits are not moved by airflow
|
||||
mob/spirit/Move()
|
||||
return 0
|
||||
|
||||
// this is the main move proc for spirits, it uses their 'setLoc' function to handle all the visibility shenanigans
|
||||
// this, like most movement code for these guys, is cribbed from the AIEye movement code
|
||||
mob/spirit/proc/Spirit_Move(direct)
|
||||
|
||||
var/initial = initial(sprint)
|
||||
var/max_sprint = 50
|
||||
|
||||
// if we haven't moved in a while, we stop sprinting
|
||||
if(cooldown && cooldown < world.timeofday) // 3 seconds
|
||||
sprint = initial
|
||||
|
||||
for(var/i = 0; i < max(sprint, initial); i += 20)
|
||||
var/turf/step = get_turf(get_step(src, direct))
|
||||
if(step)
|
||||
setLoc(step)
|
||||
|
||||
dir = direct // update our sprite
|
||||
|
||||
cooldown = world.timeofday + 5
|
||||
if(acceleration)
|
||||
sprint = min(sprint + 0.5, max_sprint)
|
||||
else
|
||||
sprint = initial
|
||||
|
||||
// if we're trying to move, we want to stop following our target
|
||||
follow_target = null
|
||||
|
||||
|
||||
/mob/spirit/proc/follow_cultist(mob/living/target as mob)
|
||||
if(!istype(target)) return
|
||||
var/obj/cult_viewpoint/currentView = getCultViewpoint(target)
|
||||
var/mob/spirit/U = usr
|
||||
|
||||
if (!currentView)
|
||||
U << "As a spirit, you may only track cultists."
|
||||
|
||||
U.follow_target = target
|
||||
U << "Now following [currentView.get_cult_name()]."
|
||||
|
||||
spawn (0)
|
||||
while (U.follow_target == target)
|
||||
if (U.follow_target == null)
|
||||
return
|
||||
U.setLoc(get_turf(target))
|
||||
sleep(10)
|
||||
|
||||
|
||||
mob/spirit/proc/setLoc(var/T)
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
cultNetwork.visibility(src)
|
||||
|
||||
mob/spirit/verb/toggle_acceleration()
|
||||
set category = "Spirit"
|
||||
set name = "Toggle Acceleration"
|
||||
|
||||
acceleration = !acceleration
|
||||
usr << "Acceleration has been toggled [acceleration ? "on" : "off"]."
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
This mob type is used for entities that exist within the Cult's spirit world. They share the same visibility network and are intangible.
|
||||
*/
|
||||
|
||||
mob/spirit
|
||||
name = "spirit"
|
||||
desc = "A spirit"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "ghost"
|
||||
layer = 4
|
||||
stat = CONSCIOUS
|
||||
status_flags = GODMODE // spirits cannot be killed
|
||||
density = 0
|
||||
canmove = 0
|
||||
blinded = 0
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
invisibility = INVISIBILITY_SPIRIT
|
||||
universal_speak = 1
|
||||
|
||||
// pseudo-movement values
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
var/follow_target = null
|
||||
|
||||
|
||||
mob/spirit/is_active()
|
||||
if (client && client.inactivity <= 10 * 60 * 10)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
mob/spirit/New()
|
||||
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
see_invisible = SEE_SPIRITS
|
||||
see_in_dark = 100
|
||||
|
||||
loc = pick(latejoin)
|
||||
|
||||
// hook them to the cult visibility network
|
||||
visibility_interface = new /datum/visibility_interface/cult(src)
|
||||
|
||||
// no nameless spirits
|
||||
if (!name)
|
||||
name = "Boogyman"
|
||||
|
||||
spirits+=src
|
||||
|
||||
..()
|
||||
|
||||
mob/spirit/Del()
|
||||
spirits-=src
|
||||
..()
|
||||
|
||||
|
||||
mob/spirit/Topic(href, href_list)
|
||||
|
||||
if(usr != src)
|
||||
return
|
||||
..()
|
||||
|
||||
usr << "Spirit Href = [href]"
|
||||
for (var/tempref in href_list)
|
||||
usr << "Spirit href list [tempref] = [href_list[tempref]]"
|
||||
|
||||
if (href_list["track"])
|
||||
usr << "Got to tracking."
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
var/mob/spirit/A = locate(href_list["track2"]) in spirits
|
||||
if(A && target)
|
||||
A.follow_cultist(target)
|
||||
return
|
||||
@@ -1,202 +0,0 @@
|
||||
#define FAVOR_PLEASED 1
|
||||
#define FAVOR_INDIFFERENT 0
|
||||
#define FAVOR_DISPLEASED -1
|
||||
|
||||
|
||||
var/obj/cult_viewpoint/list/cult_viewpoints = list()
|
||||
|
||||
|
||||
/obj/cult_viewpoint
|
||||
var/view_range = 7
|
||||
var/updating = 0
|
||||
var/mob/owner = null
|
||||
var/urge = ""
|
||||
var/favor = FAVOR_INDIFFERENT
|
||||
var/cult_name = null
|
||||
|
||||
|
||||
/obj/cult_viewpoint/New(var/mob/target)
|
||||
owner = target
|
||||
//src.loc = owner
|
||||
owner.addToVisibilityNetwork(cultNetwork)
|
||||
cultNetwork.viewpoints+=src
|
||||
cultNetwork.addViewpoint(src)
|
||||
cult_viewpoints+=src
|
||||
//handle_missing_mask()
|
||||
..()
|
||||
|
||||
|
||||
/obj/cult_viewpoint/Del()
|
||||
processing_objects.Remove(src)
|
||||
cultNetwork.viewpoints-=src
|
||||
cultNetwork.removeViewpoint(src)
|
||||
cult_viewpoints-=src
|
||||
owner.removeFromVisibilityNetwork(cultNetwork)
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
// VERBS
|
||||
/obj/cult_viewpoint/verb/check_urge()
|
||||
set category = "Cult"
|
||||
set desc = "Discover what your god commands of you."
|
||||
set name = "Check Urge"
|
||||
set src in usr
|
||||
if (src.urge)
|
||||
owner << "\red \b You feel the urge to [src.urge]"
|
||||
else
|
||||
owner << "\b You feel no supernatural compulsions."
|
||||
|
||||
|
||||
/obj/cult_viewpoint/verb/reach_out()
|
||||
set category = "Cult"
|
||||
set desc = "Reach out for your gods presence."
|
||||
set name = "Reach Out"
|
||||
set src in usr
|
||||
|
||||
for(var/mob/spirit/mask/currentMask in spirits)
|
||||
if (currentMask.is_active())
|
||||
owner << "\red \b You feel the reassuring presence of your god."
|
||||
currentMask << "<span class='cultspeech'><span class='name'><a href='byond://?src=\ref[currentMask];track2=\ref[currentMask];track=\ref[usr]'>[get_display_name()]</a></span><span class='message'> has reached out to you.</span></span>"
|
||||
return
|
||||
owner << "\b You feel a chilling absence."
|
||||
handle_missing_mask()
|
||||
|
||||
|
||||
/obj/cult_viewpoint/verb/check_favor()
|
||||
set category = "Cult"
|
||||
set desc = "Check your favor with your god."
|
||||
set name = "Check Favor"
|
||||
set src in usr
|
||||
switch(favor)
|
||||
if(FAVOR_PLEASED)
|
||||
owner << "\red \b You bask in your gods favor."
|
||||
if(FAVOR_INDIFFERENT)
|
||||
owner << "\red \b You feel nothing."
|
||||
if(FAVOR_DISPLEASED)
|
||||
owner << "\red \b You cringe at your gods displeasure."
|
||||
|
||||
|
||||
/obj/cult_viewpoint/verb/pray_to_mask()
|
||||
set category = "Cult"
|
||||
set desc = "Pray to your god"
|
||||
set name = "Pray to Nar'Sie"
|
||||
set src in usr
|
||||
|
||||
var/input = stripped_input(usr, "Please choose a message to say to your god.", "Pray to Nar'Sie", "")
|
||||
if(!input)
|
||||
return
|
||||
|
||||
cult_log("[key_name(usr,0)](Pray):[input]")
|
||||
owner << "<span class='cultspeech'><b>You pray to Nar'Sie</b>: [input]</span>"
|
||||
|
||||
for(var/mob/spirit/spirit in spirits)
|
||||
spirit << "<span class='cultspeech'><span class='name'><a href='byond://?src=\ref[spirit];track2=\ref[spirit];track=\ref[usr]'>[get_display_name()]</a> prays : </span><span class='message'>[input]</span></span>"
|
||||
|
||||
// PROCS
|
||||
/obj/cult_viewpoint/proc/set_favor(var/newFavor)
|
||||
favor = newFavor
|
||||
check_favor()
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/set_urge(var/newUrge)
|
||||
if (!newUrge)
|
||||
src.urge = null
|
||||
src.urge = copytext(newUrge, 1, MAX_MESSAGE_LEN)
|
||||
check_urge()
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/can_use()
|
||||
if (owner.stat != DEAD)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/can_see()
|
||||
return hear(view_range, get_turf(owner))
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/get_cult_name()
|
||||
if (cult_name)
|
||||
return cult_name
|
||||
return "An Unknown Servent"
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/set_cult_name(var/newName)
|
||||
if (!owner)
|
||||
return FALSE
|
||||
if (newName)
|
||||
cult_name = newName
|
||||
owner << "\red \b You have been blessed with the secret name of '[newName]'."
|
||||
else
|
||||
cult_name = null
|
||||
owner << "\red \b Your god has taken your secret name."
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/get_display_name()
|
||||
if (!owner)
|
||||
return
|
||||
if (cult_name)
|
||||
return cult_name
|
||||
return owner.name
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/become_mask()
|
||||
set category = "Cult"
|
||||
set name = "Become Mask"
|
||||
set desc = "Sacrifice your life and become a Mask of Nar'sie."
|
||||
set src in usr
|
||||
|
||||
cult_log("[key_name(usr,0)] has tried to become a Mask of Nar'sie.")
|
||||
|
||||
if (!active_mask())
|
||||
var/transformation_type = alert(owner.client, "You are about to become a Mask. Do you want it to be subtle or violent?", "Mask", "Subtle", "Violent")
|
||||
if(!active_mask())
|
||||
cult_log("[key_name(usr,0)] has become a Mask of Nar'sie.")
|
||||
if (transformation_type=="Subtle")
|
||||
log_admin("[key_name_admin(owner)] has subtly become a Mask of Nar'sie")
|
||||
owner.make_into_mask(0,0)
|
||||
else
|
||||
log_admin("[key_name_admin(owner)] has violently become a Mask of Nar'sie")
|
||||
owner.make_into_mask(1,1)
|
||||
else
|
||||
owner << "\b You cannot become a mask of Nar'Sie because a Mask already exists."
|
||||
mask_has_been_found()
|
||||
return
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/active_mask()
|
||||
for(var/mob/spirit/mask/currentMask in spirits)
|
||||
if (currentMask.is_active())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/handle_missing_mask()
|
||||
if (active_mask())
|
||||
mask_has_been_found()
|
||||
else
|
||||
mask_is_missing()
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/mask_has_been_found()
|
||||
for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints)
|
||||
if (viewpoint.verbs.Find(/obj/cult_viewpoint/proc/become_mask))
|
||||
viewpoint.verbs-=/obj/cult_viewpoint/proc/become_mask
|
||||
|
||||
|
||||
/obj/cult_viewpoint/proc/mask_is_missing()
|
||||
for(var/obj/cult_viewpoint/viewpoint in cult_viewpoints)
|
||||
if (!viewpoint.verbs.Find(/obj/cult_viewpoint/proc/become_mask))
|
||||
viewpoint.verbs+=/obj/cult_viewpoint/proc/become_mask
|
||||
|
||||
|
||||
/proc/getCultViewpoint(var/mob/currentMob)
|
||||
for(var/obj/cult_viewpoint/currentView in currentMob)
|
||||
return currentView
|
||||
return FALSE
|
||||
|
||||
|
||||
#undef FAVOR_PLEASED
|
||||
#undef FAVOR_INDIFFERENT
|
||||
#undef FAVOR_DISPLEASED
|
||||
@@ -134,59 +134,7 @@
|
||||
. = O
|
||||
del(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/make_into_mask(var/should_gib = 0)
|
||||
for(var/t in organs)
|
||||
del(t)
|
||||
return ..(should_gib)
|
||||
|
||||
|
||||
/mob/proc/make_into_mask(var/should_gib = 0, var/should_remove_items = 0)
|
||||
|
||||
if(!should_gib)
|
||||
icon = null
|
||||
invisibility = 101
|
||||
|
||||
if(!should_remove_items)
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_inventory(W)
|
||||
|
||||
var/mob/spirit/mask/new_spirit = new()
|
||||
|
||||
if(mind)
|
||||
new_spirit.mind = mind
|
||||
new_spirit.mind.assigned_role = "Mask"
|
||||
new_spirit.mind.original = new_spirit
|
||||
|
||||
new_spirit.key = key
|
||||
new_spirit.loc=loc
|
||||
|
||||
if (should_gib)
|
||||
spawn(0)
|
||||
src.gib() // gib the body
|
||||
else
|
||||
spawn(0)//To prevent the proc from returning null.
|
||||
src.visible_message( \
|
||||
"[src] disappears into the shadows, never to be seen again.", \
|
||||
"You disappear into the shadows, never to be seen again.", \
|
||||
"You hear strange noise, you can't quite place it.")
|
||||
del(src)
|
||||
|
||||
new_spirit << "<font color=\"purple\"><b><i>You are a Mask of Nar'sie now. You are a tiny fragment of the unknowable entity that is the god.</b></i></font>"
|
||||
new_spirit << "<font color=\"purple\"><b><i>Your job is to help your acolytes complete their goals. Be spooky. Do evil.</b></i></font>"
|
||||
|
||||
new_spirit.set_name()
|
||||
|
||||
// let spirits identify cultists
|
||||
if(ticker.mode)
|
||||
ticker.mode.reset_cult_icons_for_spirit(new_spirit)
|
||||
|
||||
// highlander test
|
||||
there_can_be_only_one_mask(new_spirit)
|
||||
|
||||
return new_spirit
|
||||
|
||||
|
||||
//human -> robot
|
||||
/mob/living/carbon/human/proc/Robotize()
|
||||
if (monkeyizing)
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
P.info += "[S.fields["com_[counter]"]]<BR>"
|
||||
counter++
|
||||
P.info += "</TT>"
|
||||
P.name = "paper - '[G.fields["name"]]'"
|
||||
P.name = "Security Record ([G.fields["name"]])"
|
||||
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
|
||||
//before the records have been generated, so we do this inside the loop.
|
||||
..()
|
||||
@@ -157,7 +157,7 @@
|
||||
P.info += "[M.fields["com_[counter]"]]<BR>"
|
||||
counter++
|
||||
P.info += "</TT>"
|
||||
P.name = "paper - '[G.fields["name"]]'"
|
||||
P.name = "Medical Record ([G.fields["name"]])"
|
||||
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
|
||||
//before the records have been generated, so we do this inside the loop.
|
||||
..()
|
||||
|
||||
@@ -329,25 +329,45 @@
|
||||
clown = 1
|
||||
|
||||
if(istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/photo))
|
||||
if (istype(P, /obj/item/weapon/paper/carbon))
|
||||
var/obj/item/weapon/paper/carbon/C = P
|
||||
if (!C.iscopy && !C.copied)
|
||||
user << "<span class='notice'>Take off the carbon copy first.</span>"
|
||||
add_fingerprint(user)
|
||||
return
|
||||
var/obj/item/weapon/paper_bundle/B = new(src.loc)
|
||||
if (name != "paper")
|
||||
B.name = name
|
||||
else if (P.name != "paper" && P.name != "photo")
|
||||
B.name = P.name
|
||||
user.drop_from_inventory(P)
|
||||
if (user.r_hand == src)
|
||||
user.drop_from_inventory(src)
|
||||
B.loc = user
|
||||
user.r_hand = B
|
||||
B.layer = 20
|
||||
else if (user.l_hand == src)
|
||||
user.drop_from_inventory(src)
|
||||
B.loc = user
|
||||
user.l_hand = B
|
||||
B.layer = 20
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
user:update_inv_l_hand()
|
||||
user:update_inv_r_hand()
|
||||
if (istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/h_user = user
|
||||
if (h_user.r_hand == src)
|
||||
h_user.drop_from_inventory(src)
|
||||
h_user.put_in_r_hand(B)
|
||||
else if (h_user.l_hand == src)
|
||||
h_user.drop_from_inventory(src)
|
||||
h_user.put_in_l_hand(B)
|
||||
else if (h_user.l_store == src)
|
||||
h_user.drop_from_inventory(src)
|
||||
B.loc = h_user
|
||||
B.layer = 20
|
||||
h_user.l_store = B
|
||||
h_user.update_inv_pockets()
|
||||
else if (h_user.r_store == src)
|
||||
h_user.drop_from_inventory(src)
|
||||
B.loc = h_user
|
||||
B.layer = 20
|
||||
h_user.r_store = B
|
||||
h_user.update_inv_pockets()
|
||||
else if (h_user.head == src)
|
||||
h_user.u_equip(src)
|
||||
h_user.put_in_hands(B)
|
||||
else if (!istype(src.loc, /turf))
|
||||
src.loc = get_turf(h_user)
|
||||
if(h_user.client) h_user.client.screen -= src
|
||||
h_user.put_in_hands(B)
|
||||
user << "<span class='notice'>You clip the [P.name] to [(src.name == "paper") ? "the paper" : src.name].</span>"
|
||||
src.loc = B
|
||||
P.loc = B
|
||||
|
||||
@@ -21,6 +21,13 @@
|
||||
var/obj/item/weapon/paper/P
|
||||
if(istype(W, /obj/item/weapon/paper))
|
||||
P = W
|
||||
if (istype(P, /obj/item/weapon/paper/carbon))
|
||||
var/obj/item/weapon/paper/carbon/C = P
|
||||
if (!C.iscopy && !C.copied)
|
||||
user << "<span class='notice'>Take off the carbon copy first.</span>"
|
||||
add_fingerprint(user)
|
||||
return
|
||||
|
||||
amount++
|
||||
if(screen == 2)
|
||||
screen = 1
|
||||
@@ -37,9 +44,18 @@
|
||||
user << "<span class='notice'>You add [(W.name == "photo") ? "the photo" : W.name] to [(src.name == "paper bundle") ? "the paper bundle" : src.name].</span>"
|
||||
user.drop_from_inventory(W)
|
||||
W.loc = src
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
user:update_inv_l_hand()
|
||||
user:update_inv_r_hand()
|
||||
else if(istype(W, /obj/item/weapon/lighter))
|
||||
burnpaper(W, user)
|
||||
else if(istype(W, /obj/item/weapon/paper_bundle))
|
||||
user.drop_from_inventory(W)
|
||||
for(var/obj/O in W)
|
||||
O.loc = src
|
||||
O.add_fingerprint(usr)
|
||||
src.amount++
|
||||
if(screen == 2)
|
||||
screen = 1
|
||||
user << "<span class='notice'>You add \the [W.name] to [(src.name == "paper bundle") ? "the paper bundle" : src.name].</span>"
|
||||
del(W)
|
||||
else
|
||||
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/toy/crayon))
|
||||
usr << browse("", "window=[name]") //Closes the dialog
|
||||
@@ -50,6 +66,31 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/paper_bundle/proc/burnpaper(obj/item/weapon/lighter/P, mob/user)
|
||||
var/class = "<span class='warning'>"
|
||||
|
||||
if(P.lit && !user.restrained())
|
||||
if(istype(P, /obj/item/weapon/lighter/zippo))
|
||||
class = "<span class='rose'>"
|
||||
|
||||
user.visible_message("[class][user] holds \the [P] up to \the [src], it looks like \he's trying to burn it!", \
|
||||
"[class]You hold \the [P] up to \the [src], burning it slowly.")
|
||||
|
||||
spawn(20)
|
||||
if(get_dist(src, user) < 2 && user.get_active_hand() == P && P.lit)
|
||||
user.visible_message("[class][user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \
|
||||
"[class]You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.")
|
||||
|
||||
if(user.get_inactive_hand() == src)
|
||||
user.drop_from_inventory(src)
|
||||
|
||||
new /obj/effect/decal/cleanable/ash(src.loc)
|
||||
del(src)
|
||||
|
||||
else
|
||||
user << "\red You must hold \the [P] steady to burn \the [src]."
|
||||
|
||||
|
||||
/obj/item/weapon/paper_bundle/examine()
|
||||
set src in oview(1)
|
||||
|
||||
@@ -103,7 +144,7 @@
|
||||
|
||||
/obj/item/weapon/paper_bundle/Topic(href, href_list)
|
||||
..()
|
||||
if((src in usr.contents) || (src.loc in usr.contents))
|
||||
if((src in usr.contents) || (istype(src.loc, /obj/item/weapon/folder) && (src.loc in usr.contents)))
|
||||
usr.set_machine(src)
|
||||
if(href_list["next_page"])
|
||||
if(page == amount)
|
||||
@@ -125,44 +166,18 @@
|
||||
playsound(src.loc, "pageturn", 50, 1)
|
||||
if(href_list["remove"])
|
||||
var/obj/item/weapon/W = src[page]
|
||||
W.loc = usr.loc
|
||||
if(istype(usr,/mob/living/carbon))
|
||||
//Place the item in the user's hand if possible
|
||||
if(!usr.r_hand)
|
||||
W.loc = usr
|
||||
usr.r_hand = W
|
||||
W.layer = 20
|
||||
else if(!usr.l_hand)
|
||||
W.loc = usr
|
||||
usr.l_hand = W
|
||||
W.layer = 20
|
||||
usr.put_in_hands(W)
|
||||
usr << "<span class='notice'>You remove the [W.name] from the bundle.</span>"
|
||||
|
||||
if(amount == 1)
|
||||
var/obj/item/weapon/paper/P = src[1]
|
||||
P.loc = usr.loc
|
||||
if (usr.r_hand == src)
|
||||
usr.drop_from_inventory(src)
|
||||
P.loc = usr
|
||||
usr.r_hand = P
|
||||
P.layer = 20
|
||||
else if (usr.l_hand == src)
|
||||
usr.drop_from_inventory(src)
|
||||
P.loc = usr
|
||||
usr.l_hand = P
|
||||
P.layer = 20
|
||||
if(istype(usr,/mob/living/carbon/human))
|
||||
usr:update_inv_l_hand()
|
||||
usr:update_inv_r_hand()
|
||||
usr.drop_from_inventory(src)
|
||||
usr.put_in_hands(P)
|
||||
del(src)
|
||||
else if(page == amount)
|
||||
screen = 2
|
||||
else if(page == amount+1)
|
||||
page--
|
||||
|
||||
if(istype(usr,/mob/living/carbon/human))
|
||||
usr:update_inv_l_hand()
|
||||
usr:update_inv_r_hand()
|
||||
amount--
|
||||
update_icon()
|
||||
else
|
||||
@@ -193,10 +208,9 @@
|
||||
usr << "<span class='notice'>You loosen the bundle.</span>"
|
||||
for(var/obj/O in src)
|
||||
O.loc = usr.loc
|
||||
O.layer = initial(O.layer)
|
||||
O.add_fingerprint(usr)
|
||||
usr.drop_from_inventory(src)
|
||||
if(istype(usr,/mob/living/carbon/human))
|
||||
usr:update_inv_l_hand()
|
||||
usr:update_inv_r_hand()
|
||||
del(src)
|
||||
return
|
||||
|
||||
@@ -220,7 +234,6 @@
|
||||
i++
|
||||
else if(istype(O, /obj/item/weapon/photo))
|
||||
var/obj/item/weapon/photo/Ph = O
|
||||
// img.icon_state = "photo"
|
||||
img = Ph.tiny
|
||||
photo = 1
|
||||
overlays += img
|
||||
|
||||
@@ -223,14 +223,18 @@
|
||||
var/obj/item/weapon/photo/p = new /obj/item/weapon/photo (src.loc)
|
||||
var/icon/I = icon(photocopy.icon, photocopy.icon_state)
|
||||
var/icon/img = icon(photocopy.img)
|
||||
var/icon/tiny = icon(photocopy.tiny)
|
||||
if(toner > 10) //plenty of toner, go straight greyscale
|
||||
I.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) //I'm not sure how expensive this is, but given the many limitations of photocopying, it shouldn't be an issue.
|
||||
img.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
tiny.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
|
||||
else //not much toner left, lighten the photo
|
||||
I.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(100,100,100))
|
||||
img.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(100,100,100))
|
||||
tiny.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(100,100,100))
|
||||
p.icon = I
|
||||
p.img = img
|
||||
p.tiny = tiny
|
||||
p.name = photocopy.name
|
||||
p.desc = photocopy.desc
|
||||
p.scribble = photocopy.scribble
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_NAME_LEN)
|
||||
//loc.loc check is for making possible renaming photos in clipboards
|
||||
if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0))
|
||||
name = "photo[(n_name ? text("- '[n_name]'") : null)]"
|
||||
name = "[(n_name ? text("[n_name]") : "photo")]"
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
|
||||
|
||||
@@ -640,39 +640,19 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
|
||||
return ..()
|
||||
|
||||
if(S.burn_dam > 0 && use(1))
|
||||
S.heal_damage(0,15,0,1)
|
||||
|
||||
if(user != M)
|
||||
user.visible_message("<span class='notice'>\The [user] repairs some burn damage on [M]'s [S.display_name] with \the [src]</span>",\
|
||||
"<span class='notice'>\The [user] repairs some burn damage on your [S.display_name]</span>",\
|
||||
"You hear wires being cut.")
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] repairs some burn damage on their [S.display_name] with \the [src]</span>",\
|
||||
"<span class='notice'>You repair some burn damage on your [S.display_name]</span>",\
|
||||
"You hear wires being cut.")
|
||||
|
||||
return
|
||||
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(H.species.flags & IS_SYNTHETIC)
|
||||
|
||||
if(H.getFireLoss() > 0)
|
||||
|
||||
if(M == user)
|
||||
user << "\red You can't repair damage to your own body - it's against OH&S."
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>\The [user] repairs some burn damage on [M] with \the [src]</span>",\
|
||||
"<span class='notice'>You repair some of \the [M]'s burn damage.</span>",\
|
||||
"You hear wires being cut.")
|
||||
H.heal_overall_damage(0,5)
|
||||
if(M == user)
|
||||
user << "\red You can't repair damage to your own body - it's against OH&S."
|
||||
return
|
||||
|
||||
user << "Nothing to fix!"
|
||||
if(S.burn_dam > 0 && use(1))
|
||||
S.heal_damage(0,15,0,1)
|
||||
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
|
||||
return
|
||||
else
|
||||
user << "Nothing to fix!"
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
desc = "A computer to remotely control a gas turbine"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "airtunnel0e"
|
||||
circuit = /obj/item/weapon/circuitboard/turbine_control
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/obj/machinery/compressor/compressor
|
||||
@@ -220,6 +221,7 @@
|
||||
if(P.id == id)
|
||||
doors += P
|
||||
|
||||
/*
|
||||
/obj/machinery/computer/turbine_computer/attackby(I as obj, user as mob)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
@@ -252,6 +254,7 @@
|
||||
else
|
||||
src.attack_hand(user)
|
||||
return
|
||||
*/
|
||||
|
||||
/obj/machinery/computer/turbine_computer/attack_hand(var/mob/user as mob)
|
||||
user.machine = src
|
||||
|
||||
@@ -599,8 +599,9 @@
|
||||
anchored = 1
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "mixer0"
|
||||
use_power = 1
|
||||
idle_power_usage = 20
|
||||
circuit = /obj/item/weapon/circuitboard/pandemic
|
||||
//use_power = 1
|
||||
//idle_power_usage = 20 //defaults make more sense.
|
||||
var/temphtml = ""
|
||||
var/wait = null
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
@@ -829,33 +830,7 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/pandemic/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe(src.loc)
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
var/obj/item/weapon/circuitboard/pandemic/M = new /obj/item/weapon/circuitboard/pandemic(A)
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/pandemic/M = new /obj/item/weapon/circuitboard/pandemic(A)
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
if(src.beaker)
|
||||
user << "A beaker is already loaded into the machine."
|
||||
|
||||
@@ -118,11 +118,14 @@
|
||||
name = "space cleaner"
|
||||
desc = "BLAM!-brand non-foaming space cleaner!"
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/cleaner/drone
|
||||
name = "space cleaner"
|
||||
desc = "BLAM!-brand non-foaming space cleaner!"
|
||||
volume = 50
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/cleaner/New()
|
||||
..()
|
||||
reagents.add_reagent("cleaner", 250)
|
||||
|
||||
reagents.add_reagent("cleaner", src.volume)
|
||||
//pepperspray
|
||||
/obj/item/weapon/reagent_containers/spray/pepper
|
||||
name = "pepperspray"
|
||||
|
||||
@@ -34,6 +34,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
/obj/machinery/computer/rdconsole
|
||||
name = "R&D Console"
|
||||
icon_state = "rdcomp"
|
||||
circuit = /obj/item/weapon/circuitboard/rdconsole
|
||||
var/datum/research/files //Stores all the collected research data.
|
||||
var/obj/item/weapon/disk/tech_disk/t_disk = null //Stores the technology disk.
|
||||
var/obj/item/weapon/disk/design_disk/d_disk = null //Stores the design disk.
|
||||
@@ -46,7 +47,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
var/id = 0 //ID of the computer (for server restrictions).
|
||||
var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console
|
||||
|
||||
req_access = list(access_tox) //Data and setting manipulation requires scientist access.
|
||||
req_access = list(access_research) //Data and setting manipulation requires scientist access.
|
||||
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallTechName(var/ID) //A simple helper proc to find the name of a tech with a given ID.
|
||||
@@ -141,35 +142,8 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
*/
|
||||
|
||||
/obj/machinery/computer/rdconsole/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||
//The construction/deconstruction of the console code.
|
||||
if(istype(D, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdconsole/M = new /obj/item/weapon/circuitboard/rdconsole( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdconsole/M = new /obj/item/weapon/circuitboard/rdconsole( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
//Loading a disk into it.
|
||||
else if(istype(D, /obj/item/weapon/disk))
|
||||
if(istype(D, /obj/item/weapon/disk))
|
||||
if(t_disk || d_disk)
|
||||
user << "A disk is already loaded into the machine."
|
||||
return
|
||||
@@ -186,6 +160,10 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
user << "\blue You you disable the security protocols"
|
||||
else
|
||||
//The construction/deconstruction of the console code.
|
||||
..()
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
|
||||
@@ -104,24 +104,5 @@ proc/move_research_shuttle()
|
||||
hacked = 1
|
||||
usr << "You fried the consoles ID checking system. It's now available to everyone!"
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/research_shuttle/M = new /obj/item/weapon/circuitboard/research_shuttle( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
|
||||
del(src)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
/obj/machinery/computer/rdservercontrol
|
||||
name = "R&D Server Controller"
|
||||
icon_state = "rdcomp"
|
||||
circuit = /obj/item/weapon/circuitboard/rdservercontrol
|
||||
var/screen = 0
|
||||
var/obj/machinery/r_n_d/server/temp_server
|
||||
var/list/servers = list()
|
||||
@@ -332,38 +333,12 @@
|
||||
return
|
||||
|
||||
/obj/machinery/computer/rdservercontrol/attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
|
||||
if(istype(D, /obj/item/weapon/screwdriver))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (src.stat & BROKEN)
|
||||
user << "\blue The broken glass falls out."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdservercontrol/M = new /obj/item/weapon/circuitboard/rdservercontrol( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else
|
||||
user << "\blue You disconnect the monitor."
|
||||
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
|
||||
var/obj/item/weapon/circuitboard/rdservercontrol/M = new /obj/item/weapon/circuitboard/rdservercontrol( A )
|
||||
for (var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
A.circuit = M
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
del(src)
|
||||
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
|
||||
if(istype(D, /obj/item/weapon/card/emag) && !emagged)
|
||||
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
user << "\blue You you disable the security protocols"
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/r_n_d/server/robotics
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
name = "Cure Research Machine"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "dna"
|
||||
circuit = /obj/item/weapon/circuitboard/curefab
|
||||
var/curing
|
||||
var/virusing
|
||||
|
||||
var/obj/item/weapon/reagent_containers/container = null
|
||||
|
||||
/obj/machinery/computer/curer/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
return ..(I,user)
|
||||
if(istype(I,/obj/item/weapon/reagent_containers))
|
||||
var/mob/living/carbon/C = user
|
||||
if(!container)
|
||||
container = I
|
||||
C.drop_item()
|
||||
I.loc = src
|
||||
return
|
||||
if(istype(I,/obj/item/weapon/virusdish))
|
||||
if(virusing)
|
||||
user << "<b>The pathogen materializer is still recharging.."
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
state("The [src.name] Buzzes", "blue")
|
||||
return
|
||||
src.attack_hand(user)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/curer/attack_ai(var/mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
Reference in New Issue
Block a user