Merge pull request #810 from Zuhayr/bayupdate

Bay update.
This commit is contained in:
Neerti
2016-02-05 23:21:07 -05:00
136 changed files with 1163 additions and 1513 deletions
+21 -22
View File
@@ -1315,7 +1315,7 @@ proc/admin_notice(var/message, var/rights)
if (!istype(src,/datum/admins))
src = usr.client.holder
if (!istype(src,/datum/admins))
if (!istype(src,/datum/admins) || !check_rights(R_ADMIN))
usr << "Error: you are not an admin!"
return
@@ -1323,17 +1323,31 @@ proc/admin_notice(var/message, var/rights)
usr << "Mode has not started."
return
message_admins("[key_name(usr)] attempting to force mode latespawn.")
ticker.mode.next_spawn = 0
log_and_message_admins("attempting to force mode autospawn.")
ticker.mode.try_latespawn()
/datum/admins/proc/paralyze_mob(mob/living/H as mob)
set category = "Admin"
set name = "Toggle Paralyze"
set desc = "Paralyzes a player. Or unparalyses them."
var/msg
if(check_rights(R_ADMIN))
if (H.paralysis == 0)
H.paralysis = 8000
msg = "has paralyzed [key_name(H)]."
else
H.paralysis = 0
msg = "has unparalyzed [key_name(H)]."
log_and_message_admins(msg)
/datum/admins/proc/set_tcrystals(mob/living/carbon/human/H as mob)
set category = "Debug"
set name = "Set Telecrystals"
set desc = "Allows admins to change telecrystals of a user."
var/crystals
if(check_rights(R_ADMIN))
crystals = input("Amount of telecrystals for [H.ckey]", crystals) as null|num
if (!isnull(crystals))
@@ -1342,19 +1356,4 @@ proc/admin_notice(var/message, var/rights)
message_admins(msg)
else
usr << "You do not have access to this command."
/datum/admins/proc/paralyze_mob(mob/living/H as mob)
set category = "Admin"
set name = "Toggle Paralyze"
set desc = "Paralyzes a player. Or unparalyses them."
var/msg
if(check_rights(R_ADMIN|R_MOD))
if (H.paralysis == 0)
H.paralysis = 8000
msg = "[key_name(usr)] has paralyzed [key_name(H)]."
else
H.paralysis = 0
msg = "[key_name(usr)] has unparalyzed [key_name(H)]."
message_admins(msg)
-3
View File
@@ -132,9 +132,6 @@ var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_plant,
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
/client/proc/respawn_character,
/client/proc/FireLaser,
/client/proc/FireCannons,
/client/proc/ChangeIcarusPosition,
/client/proc/virus2_editor,
/client/proc/spawn_chemdisp_cartridge
)
+2 -7
View File
@@ -1681,13 +1681,8 @@
else
var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
if(choice=="Confirm")
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = src.admincaster_feed_channel.channel_name
newChannel.author = src.admincaster_signature
newChannel.locked = src.admincaster_feed_channel.locked
newChannel.is_admin_channel = 1
feedback_inc("newscaster_channels",1)
news_network.network_channels += newChannel //Adding channel to the global network
news_network.CreateFeedChannel(admincaster_feed_channel.channel_name, admincaster_signature, admincaster_feed_channel.locked, 1)
feedback_inc("newscaster_channels",1) //Adding channel to the global network
log_admin("[key_name_admin(usr)] created command feed channel: [src.admincaster_feed_channel.channel_name]!")
src.admincaster_screen=5
src.access_news_network()
+1
View File
@@ -296,3 +296,4 @@
if(pa.Find("right"))
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)
log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]")
-129
View File
@@ -1,129 +0,0 @@
/client/proc/FireLaser()
set name = "Fire the Icarus lasers"
set desc = "Fires a laser bolt at your position. You should only do this as a(n) (a)ghost"
set category = "Fun"
var/turf/target = get_turf(src.mob)
log_and_message_admins("has fired the Icarus point defense laser at [target.x]-[target.y]-[target.z]")
if(!src.holder)
src << "Only administrators may use this command."
return
Icarus_FireLaser(target)
/client/proc/FireCannons()
set name = "Fire the Icarus cannons"
set desc = "Fires an explosive missile at your position. You should only do this as a(n) (a)ghost."
set category = "Fun"
var/turf/target = get_turf(src.mob)
log_and_message_admins("has fired the Icarus main gun projectile at [target.x]-[target.y]-[target.z]")
if(!src.holder)
src << "Only administrators may use this command."
return
Icarus_FireCannon(target)
/client/proc/ChangeIcarusPosition()
set name = "Adjust Icarus Position"
set desc = "Lets you chose the position of the Icarus in regards to the map."
set category = "Fun"
log_and_message_admins("is changing the Icarus position.")
if(!src.holder)
src << "Only administrators may use this command."
return
Icarus_SetPosition(src)
var/icarus_position = SOUTH
proc/Icarus_FireLaser(var/turf/target)
// Find the world edge to fire from.
var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x
var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y
var/x_off = x != target.x ? abs(target.x - x) : INFINITY
var/y_off = y != target.y ? abs(target.y - y) : INFINITY
// Get the minimum number of steps using the rise/run shit.
var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing.
// Now we can get the location of the start.
x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0)
y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0)
var/turf/start = locate(x, y, target.z)
// should step down as:
// 1000, 500, 333, 250, 200, 167, 142, 125, 111, 100, 90
var/damage = 1000
for(var/i in 2 to 12)
var/obj/item/projectile/beam/in_chamber = new (start)
in_chamber.original = target
in_chamber.starting = start
in_chamber.silenced = 1
in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0
in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0
in_chamber.damage = damage
in_chamber.kill_count = 500
in_chamber.process()
damage -= damage / i
sleep(-1)
// Let everyone know what hit them.
var/obj/item/projectile/beam/in_chamber = new (start)
in_chamber.original = target
in_chamber.starting = start
in_chamber.silenced = 0
in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0
in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0
in_chamber.kill_count = 500
in_chamber.damage = 0
in_chamber.name = "point defense laser"
in_chamber.firer = "Icarus" // Never displayed, but we want this to display the hit message.
in_chamber.process()
proc/Icarus_FireCannon(var/turf/target)
// Find the world edge to fire from.
var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x
var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y
var/x_off = x != target.x ? abs(target.x - x) : INFINITY
var/y_off = y != target.y ? abs(target.y - y) : INFINITY
// Get the minimum number of steps using the rise/run shit.
var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing.
// Now we can get the location of the start.
x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0)
y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0)
var/turf/start = locate(x, y, target.z)
// Now we find the corresponding turf on the other side of the level.
// Yeah, yeah. Overuse of the terinary operator. So sue me.
x = icarus_position & EAST ? 1 : icarus_position & WEST ? world.maxx : target.x
y = icarus_position & NORTH ? 1 : icarus_position & SOUTH ? world.maxy : target.y
x_off = x != target.x ? abs(target.x - x) : INFINITY
y_off = y != target.y ? abs(target.y - y) : INFINITY
iterations = round(min(x_off, y_off))
x = target.x + (icarus_position & EAST ? -iterations : icarus_position & WEST ? iterations : 0)
y = target.y + (icarus_position & NORTH ? -iterations : icarus_position & SOUTH ? iterations : 0)
target = locate(x, y, target.z)
// Finally fire the fucker.
var/obj/effect/meteor/projectile = new (start)
projectile.dest = target
projectile.name = "main gun projectile" // stealthy
projectile.hits = 6
// Make sure it travels
spawn(0)
walk_towards(projectile, projectile.dest, 1)
proc/Icarus_SetPosition(var/user)
var/global/list/directions = list("North" = 1, "North East" = 5, "East" = 4, "South East" = 6, "South" = 2, "South West" = 10, "West" = 8, "North West" = 9)
var/direction = input(user, "Where should the Icarus fire from?", "Icarus Comms") as null|anything in directions
if(!direction)
return
icarus_position = directions[direction]
+2 -1
View File
@@ -520,7 +520,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'[command_name()] Update.'"
P.info = input
P.info = replacetext(input, "\n", "<br/>")
P.update_space(P.info)
P.update_icon()
C.messagetitle.Add("[command_name()] Update")
C.messagetext.Add(P.info)
+1
View File
@@ -158,6 +158,7 @@
spawn(5) // And wait a half-second, since it sounds like you can do this too fast.
if(src)
winset(src, null, "command=\".configure graphics-hwmode off\"")
sleep(2) // wait a bit more, possibly fixes hardware mode not re-activating right
winset(src, null, "command=\".configure graphics-hwmode on\"")
log_client_to_db()
+1 -1
View File
@@ -368,4 +368,4 @@ datum/preferences
user << browse(dat, "window=saves;size=300x390")
/datum/preferences/proc/close_load_dialog(mob/user)
user << browse(null, "window=saves")
user << browse(null, "window=saves")
+1 -1
View File
@@ -25,7 +25,7 @@ var/global/list/home_system_choices = list(
"Vir",
"Nyx",
"Tau Ceti",
"Epsilon Ursae Majoris",
"Epsilon Ursae Minoris",
"S'randarr"
)
+32 -22
View File
@@ -18,7 +18,17 @@ var/global/list/gear_datums = list()
//create a list of gear datums to sort
for(var/type in typesof(/datum/gear)-/datum/gear)
var/datum/gear/G = new type()
var/datum/gear/G = type
if(!initial(G.display_name))
error("Loadout - Missing display name: [G]")
continue
if(!initial(G.cost))
error("Loadout - Missing cost: [G]")
continue
if(!initial(G.path))
error("Loadout - Missing path definition: [G]")
continue
G = new G()
var/category = (G.sort_category in sort_categories)? G.sort_category : "unknown"
sort_categories[category][G.display_name] = G
@@ -210,7 +220,7 @@ var/global/list/gear_datums = list()
cost = 1
slot = slot_head
/datum/gear/bowler
/datum/gear/bowler
display_name = "hat, bowler"
path = /obj/item/clothing/head/bowler
cost = 1
@@ -566,7 +576,7 @@ var/global/list/gear_datums = list()
cost = 1
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/white
/datum/gear/pants
display_name = "pants, white"
path = /obj/item/clothing/under/pants/white
slot = slot_w_uniform
@@ -616,55 +626,55 @@ var/global/list/gear_datums = list()
display_name = "pants, young folks jeans"
path = /obj/item/clothing/under/pants/youngfolksjeans
/datum/gear/shorts/jeans
/datum/gear/jeans
display_name = "shorts, jeans"
path = /obj/item/clothing/under/shorts/jeans
slot = slot_w_uniform
cost = 1
/datum/gear/shorts/jeans/classic
/datum/gear/jeans/classic
display_name = "shorts, classic jeans"
path = /obj/item/clothing/under/shorts/jeans/classic
/datum/gear/shorts/jeans/mustang
/datum/gear/jeans/mustang
display_name = "shorts, mustang jeans"
path = /obj/item/clothing/under/shorts/jeans/mustang
/datum/gear/shorts/jeans/youngfolks
/datum/gear/jeans/youngfolks
display_name = "shorts, young folks jeans"
path = /obj/item/clothing/under/shorts/jeans/youngfolks
/datum/gear/shorts/jeans/black
/datum/gear/jeans/black
display_name = "shorts, black jeans"
path = /obj/item/clothing/under/shorts/jeans/black
/datum/gear/shorts/jeans/female
/datum/gear/jeans/female
display_name = "shorts, female, jeans"
path = /obj/item/clothing/under/shorts/jeans/female
/datum/gear/shorts/jeans/classic/female
/datum/gear/jeans/classic/female
display_name = "shorts, female, classic jeans"
path = /obj/item/clothing/under/shorts/jeans/classic/female
/datum/gear/shorts/jeans/mustang/female
/datum/gear/jeans/mustang/female
display_name = "shorts, female, mustang jeans"
path = /obj/item/clothing/under/shorts/jeans/mustang/female
/datum/gear/shorts/jeans/youngfolks/female
/datum/gear/jeans/youngfolks/female
display_name = "shorts, female, young folks jeans"
path = /obj/item/clothing/under/shorts/jeans/youngfolks/female
/datum/gear/shorts/jeans/black/female
/datum/gear/jeans/black/female
display_name = "shorts, female, black jeans"
path = /obj/item/clothing/under/shorts/jeans/black/female
/datum/gear/shorts/khaki
/datum/gear/khaki
display_name = "shorts, khaki"
path = /obj/item/clothing/under/shorts/khaki
slot = slot_w_uniform
cost = 1
/datum/gear/shorts/khaki/female
/datum/gear/khaki/female
display_name = "shorts, female, khaki"
path = /obj/item/clothing/under/shorts/khaki/female
@@ -1223,7 +1233,7 @@ var/global/list/gear_datums = list()
slot = slot_wear_suit
whitelisted = "Tajara" // You do have a monopoly on a fur suit tho
/datum/gear/forensics/red
/datum/gear/forensics
display_name = "forensics long, red"
path = /obj/item/clothing/suit/storage/forensics/red/long
cost = 2
@@ -1627,11 +1637,11 @@ var/global/list/gear_datums = list()
display_name = "skrell headtail-wear, male, blue, cloth"
path = /obj/item/clothing/ears/skrell/cloth_male/blue
/datum/gear/skrell_cloth_male/green
/datum/gear/skrell_cloth/male/green
display_name = "skrell headtail-wear, male, green, cloth"
path = /obj/item/clothing/ears/skrell/cloth_male/green
/datum/gear/skrell_cloth_male/pink
/datum/gear/skrell_cloth/male/pink
display_name = "skrell headtail-wear, male, pink, cloth"
path = /obj/item/clothing/ears/skrell/cloth_male/pink
@@ -1639,18 +1649,18 @@ var/global/list/gear_datums = list()
display_name = "skrell headtail-wear, female, red, cloth"
path = /obj/item/clothing/ears/skrell/cloth_female
/datum/gear/skrell_cloth_female/black
/datum/gear/skrell_cloth/female/black
display_name = "skrell headtail-wear, female, black, cloth"
path = /obj/item/clothing/ears/skrell/cloth_female/black
/datum/gear/skrell_cloth_female/blue
/datum/gear/skrell_cloth/female/blue
display_name = "skrell headtail-wear, female, blue, cloth"
path = /obj/item/clothing/ears/skrell/cloth_female/blue
/datum/gear/skrell_cloth_female/green
/datum/gear/skrell_cloth/female/green
display_name = "skrell headtail-wear, female, green, cloth"
path = /obj/item/clothing/ears/skrell/cloth_female/green
/datum/gear/skrell_cloth_female/pink
/datum/gear/skrell_cloth/female/pink
display_name = "skrell headtail-wear, female, pink, cloth"
path = /obj/item/clothing/ears/skrell/cloth_female/pink
+1 -1
View File
@@ -90,4 +90,4 @@
return 1
#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN
#undef SAVEFILE_VERSION_MIN
@@ -38,6 +38,7 @@
interface_desc = "A self-sustaining plasma arc capable of cutting through walls."
suit_overlay_active = "plasmacutter"
suit_overlay_inactive = "plasmacutter"
use_power_cost = 0.5
device_type = /obj/item/weapon/pickaxe/plasmacutter
@@ -58,6 +59,7 @@
interface_desc = "A diamond-tipped industrial drill."
suit_overlay_active = "mounted-drill"
suit_overlay_inactive = "mounted-drill"
use_power_cost = 0.1
device_type = /obj/item/weapon/pickaxe/diamonddrill
@@ -1,6 +1,6 @@
/obj/item/clothing/head/helmet/space/rig/ert
light_overlay = "helmet_light_dual"
camera_networks = list("ERT")
camera_networks = list(NETWORK_ERT)
/obj/item/weapon/rig/ert
name = "ERT-C hardsuit control module"
@@ -40,7 +40,7 @@
airtight = 0
seal_delay = 5 //not being vaccum-proof has an upside I guess
helm_type = /obj/item/clothing/head/lightrig/hacker
chest_type = /obj/item/clothing/suit/lightrig/hacker
glove_type = /obj/item/clothing/gloves/lightrig/hacker
@@ -1,23 +1,23 @@
/obj/item/clothing/head/helmet/space/rig/industrial
camera_networks = list("Mine")
camera_networks = list(NETWORK_MINE)
/obj/item/clothing/head/helmet/space/rig/ce
camera_networks = list("Engineering")
camera_networks = list(NETWORK_ENGINEERING)
/obj/item/clothing/head/helmet/space/rig/eva
light_overlay = "helmet_light_dual"
camera_networks = list("Engineering")
camera_networks = list(NETWORK_ENGINEERING)
/obj/item/clothing/head/helmet/space/rig/hazmat
light_overlay = "hardhat_light"
camera_networks = list("Research")
camera_networks = list(NETWORK_RESEARCH)
/obj/item/clothing/head/helmet/space/rig/medical
camera_networks = list("Medbay")
camera_networks = list(NETWORK_MEDICAL)
/obj/item/clothing/head/helmet/space/rig/hazard
light_overlay = "helmet_light_dual"
camera_networks = list("Security")
camera_networks = list(NETWORK_SECURITY)
/obj/item/weapon/rig/internalaffairs
name = "augmented tie"
+1
View File
@@ -39,6 +39,7 @@
return
name = "[seed.seed_name]"
trash = seed.get_trash_type()
update_icon()
+3
View File
@@ -69,6 +69,9 @@
/datum/seed/proc/get_trait(var/trait)
return traits["[trait]"]
/datum/seed/proc/get_trash_type()
return trash_type
/datum/seed/proc/set_trait(var/trait,var/nval,var/ubound,var/lbound, var/degrade)
if(!isnull(degrade)) nval *= degrade
if(!isnull(ubound)) nval = min(nval,ubound)
+24 -15
View File
@@ -124,7 +124,7 @@
)
/obj/machinery/portable_atmospherics/hydroponics/AltClick()
if(mechanical && !usr.stat && !usr.lying && Adjacent(usr))
if(mechanical && !usr.incapacitated() && Adjacent(usr))
close_lid(usr)
return 1
return ..()
@@ -357,12 +357,15 @@
set category = "Object"
set src in view(1)
if(labelled)
usr << "You remove the label."
labelled = null
update_icon()
else
usr << "There is no label to remove."
if(usr.incapacitated())
return
if(ishuman(usr) || istype(usr, /mob/living/silicon/robot))
if(labelled)
usr << "You remove the label."
labelled = null
update_icon()
else
usr << "There is no label to remove."
return
/obj/machinery/portable_atmospherics/hydroponics/verb/setlight()
@@ -370,10 +373,14 @@
set category = "Object"
set src in view(1)
var/new_light = input("Specify a light level.") as null|anything in list(0,1,2,3,4,5,6,7,8,9,10)
if(new_light)
tray_light = new_light
usr << "You set the tray to a light level of [tray_light] lumens."
if(usr.incapacitated())
return
if(ishuman(usr) || istype(usr, /mob/living/silicon/robot))
var/new_light = input("Specify a light level.") as null|anything in list(0,1,2,3,4,5,6,7,8,9,10)
if(new_light)
tray_light = new_light
usr << "You set the tray to a light level of [tray_light] lumens."
return
/obj/machinery/portable_atmospherics/hydroponics/proc/check_level_sanity()
//Make sure various values are sane.
@@ -614,12 +621,14 @@
set name = "Toggle Tray Lid"
set category = "Object"
set src in view(1)
close_lid(usr)
if(usr.incapacitated())
return
if(ishuman(usr) || istype(usr, /mob/living/silicon/robot))
close_lid(usr)
return
/obj/machinery/portable_atmospherics/hydroponics/proc/close_lid(var/mob/living/user)
if(!user || user.stat || user.restrained())
return
closed_system = !closed_system
user << "You [closed_system ? "close" : "open"] the tray's lid."
update_icon()
+1 -1
View File
@@ -11,7 +11,7 @@
recipes += new/datum/stack_recipe("[display_name] ashtray", /obj/item/weapon/material/ashtray, 2, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]")
if(integrity>=100)
if(integrity>=50)
recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] barricade", /obj/structure/barricade, 5, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] stool", /obj/item/weapon/stool, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
+1 -1
View File
@@ -571,7 +571,7 @@ var/list/name_to_material
name = "wood"
stack_type = /obj/item/stack/material/wood
icon_colour = "#824B28"
integrity = 25
integrity = 50
icon_base = "solid"
explosion_resistance = 2
shard_type = SHARD_SPLINTER
@@ -151,6 +151,8 @@ Works together with spawning an observer, noted above.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
if(ghost.client)
ghost.client.time_died_as_mouse = ghost.timeofdeath
if(ghost.client && !ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
return ghost
+1 -2
View File
@@ -2,9 +2,8 @@
//m_type == 1 --> visual.
//m_type == 2 --> audible
/mob/proc/custom_emote(var/m_type=1,var/message = null)
if(stat || !use_me && usr == src)
usr << "You are unable to emote."
src << "You are unable to emote."
return
var/muzzled = is_muzzled()
+13 -43
View File
@@ -103,64 +103,34 @@ var/list/slot_equipment_priority = list( \
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(!l_hand)
W.forceMove(src) //TODO: move to equipped?
l_hand = W
W.layer = 20 //TODO: move to equipped?
// l_hand.screen_loc = ui_lhand
W.equipped(src,slot_l_hand)
if(client) client.screen |= W
if(pulling == W) stop_pulling()
update_inv_l_hand()
return 1
return 0
if(lying || !istype(W))
return 0
return 1
//Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_r_hand(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(!r_hand)
W.forceMove(src)
r_hand = W
W.layer = 20
// r_hand.screen_loc = ui_rhand
W.equipped(src,slot_r_hand)
if(client) client.screen |= W
if(pulling == W) stop_pulling()
update_inv_r_hand()
return 1
return 0
if(lying || !istype(W))
return 0
return 1
//Puts the item into our active hand if possible. returns 1 on success.
/mob/proc/put_in_active_hand(var/obj/item/W)
if(hand) return put_in_l_hand(W)
else return put_in_r_hand(W)
return 0 // Moved to human procs because only they need to use hands.
//Puts the item into our inactive hand if possible. returns 1 on success.
/mob/proc/put_in_inactive_hand(var/obj/item/W)
if(hand) return put_in_r_hand(W)
else return put_in_l_hand(W)
return 0 // As above.
//Puts the item our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success.
//If both fail it drops it on the floor and returns 0.
//This is probably the main one you need to know :)
/mob/proc/put_in_hands(var/obj/item/W)
if(!W) return 0
if(put_in_active_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else if(put_in_inactive_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else
W.forceMove(get_turf(src))
W.layer = initial(W.layer)
W.dropped()
if(!W)
return 0
W.forceMove(get_turf(src))
W.layer = initial(W.layer)
W.dropped()
return 0
// Removes an item from inventory and places it in the target atom.
// If canremove or other conditions need to be checked then use unEquip instead.
+78 -56
View File
@@ -26,6 +26,8 @@
var/blood = 1
var/list/target_types = list()
var/maximum_search_range = 7
/mob/living/bot/cleanbot/New()
..()
get_targets()
@@ -36,6 +38,25 @@
if(radio_controller)
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
/mob/living/bot/cleanbot/proc/handle_target()
if(loc == target.loc)
if(!cleaning)
UnarmedAttack(target)
return 1
if(!path.len)
// spawn(0)
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
custom_emote(2, "[src] can't reach the target and is giving up.")
target = null
path = list()
return
if(path.len)
step_to(src, path[1])
path -= path[1]
return 1
return
/mob/living/bot/cleanbot/Life()
..()
@@ -46,7 +67,7 @@
return
if(cleaning)
return
if(!screwloose && !oddbutton && prob(5))
custom_emote(2, "makes an excited beeping booping sound!")
@@ -62,65 +83,64 @@
spawn(600)
ignorelist -= gib
if(!target) // Find a target
for(var/obj/effect/decal/cleanable/D in view(7, src))
if(D in ignorelist)
continue
for(var/T in target_types)
if(istype(D, T))
target = D
patrol_path = list()
// Find a target
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
return
if(!target) // No targets in range
if(!should_patrol)
return
var/found_spot
search_loop:
for(var/i=0, i <= maximum_search_range, i++)
for(var/obj/effect/decal/cleanable/D in view(i, src))
if(D in ignorelist)
continue
for(var/T in target_types)
if(istype(D, T))
patrol_path = list()
target = D
found_spot = handle_target()
if (found_spot)
break search_loop
else
target = null
continue // no need to check the other types
if(!patrol_path || !patrol_path.len)
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
if(!frequency)
return
closest_dist = 9999
next_dest = null
next_dest_loc = null
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
signal.data = list("findbeakon" = "patrol")
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
signal_sent = world.time
else
if(next_dest)
next_dest_loc = listener.memorized[next_dest]
if(next_dest_loc)
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
signal_sent = 0
else
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
if(!found_spot && !target) // No targets in range
if(!patrol_path || !patrol_path.len)
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
if(!frequency)
return
if(patrol_path[1] == loc)
patrol_path -= patrol_path[1]
var/moved = step_towards(src, patrol_path[1])
if(moved)
patrol_path -= patrol_path[1]
if(target)
if(loc == target.loc)
if(!cleaning)
UnarmedAttack(target)
closest_dist = 9999
next_dest = null
next_dest_loc = null
var/datum/signal/signal = new()
signal.source = src
signal.transmission_method = 1
signal.data = list("findbeakon" = "patrol")
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
signal_sent = world.time
else
if(next_dest)
next_dest_loc = listener.memorized[next_dest]
if(next_dest_loc)
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
signal_sent = 0
else
if(pulledby) // Don't wiggle if someone pulls you
patrol_path = list()
return
if(!path.len)
spawn(0)
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
path = list()
return
if(path.len)
step_to(src, path[1])
path -= path[1]
return
if(patrol_path[1] == loc)
patrol_path -= patrol_path[1]
var/moved = step_towards(src, patrol_path[1])
if(moved)
patrol_path -= patrol_path[1]
/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity)
if(!..())
@@ -133,7 +153,7 @@
return
cleaning = 1
custom_emote(2, "begins to clean up the [D]")
custom_emote(2, "begins to clean up \the [D]")
update_icons()
var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
if(do_after(src, cleantime))
@@ -143,6 +163,8 @@
if(!D)
return
qdel(D)
if(D == target)
target = null
cleaning = 0
update_icons()
+1 -1
View File
@@ -185,7 +185,7 @@
if(40 to INFINITY)
status += "peeling away"
if(org.status & ORGAN_DESTROYED)
if(org.is_stump())
status += "MISSING"
if(org.status & ORGAN_MUTATED)
status += "weirdly shapen"
+36 -47
View File
@@ -1,53 +1,42 @@
mob/living/carbon/verb/give(var/mob/living/carbon/target in view(1)-usr)
/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr)
set category = "IC"
set name = "Give"
if(!istype(target) || target.stat == 2 || usr.stat == 2|| target.client == null)
// TODO : Change to incapacitated() on merge.
if(usr.stat || usr.lying || usr.resting || usr.buckled)
return
var/obj/item/I
if(!usr.hand && usr.r_hand == null)
usr << "<span class='warning'>You don't have anything in your right hand to give to [target.name]</span>"
if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
return
if(usr.hand && usr.l_hand == null)
usr << "<span class='warning'>You don't have anything in your left hand to give to [target.name]</span>"
return
if(usr.hand)
I = usr.l_hand
else if(!usr.hand)
I = usr.r_hand
var/obj/item/I = usr.get_active_hand()
if(!I)
I = usr.get_inactive_hand()
if(!I)
usr << "<span class='warning'>You don't have anything in your hands to give to \the [target].</span>"
return
if(target.r_hand == null || target.l_hand == null)
switch(alert(target,"[usr] wants to give you \a [I]?",,"Yes","No"))
if("Yes")
if(!I)
return
if(!Adjacent(usr))
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
target << "<span class='warning'>[usr.name] moved too far away.</span>"
return
if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I))
usr << "<span class='warning'>You need to keep the item in your active hand.</span>"
target << "<span class='warning'>[usr.name] seem to have given up on giving \the [I.name] to you.</span>"
return
if(target.r_hand != null && target.l_hand != null)
target << "<span class='warning'>Your hands are full.</span>"
usr << "<span class='warning'>Their hands are full.</span>"
return
else
usr.drop_item()
if(target.r_hand == null)
target.r_hand = I
else
target.l_hand = I
I.loc = target
I.layer = 20
I.add_fingerprint(target)
target.update_inv_l_hand()
target.update_inv_r_hand()
usr.update_inv_l_hand()
usr.update_inv_r_hand()
target.visible_message("<span class='notice'>[usr.name] handed \the [I.name] to [target.name].</span>")
if("No")
target.visible_message("<span class='warning'>[usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.</span>")
else
usr << "<span class='warning'>[target.name]'s hands are full.</span>"
if(alert(target,"[usr] wants to give you \a [I]. Will you accept it?",,"No","Yes") == "No")
target.visible_message("<span class='notice'>\The [usr] tried to hand \the [I] to \the [target], \
but \the [target] didn't want it.</span>")
return
if(!I) return
if(!Adjacent(target))
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
target << "<span class='warning'>\The [usr] moved too far away.</span>"
return
if(I.loc != usr || (usr.l_hand != I && usr.r_hand != I))
usr << "<span class='warning'>You need to keep the item in your hands.</span>"
target << "<span class='warning'>\The [usr] seems to have given up on passing \the [I] to you.</span>"
return
if(target.r_hand != null && target.l_hand != null)
target << "<span class='warning'>Your hands are full.</span>"
usr << "<span class='warning'>Their hands are full.</span>"
return
if(usr.unEquip(I))
target.put_in_hands(I) // If this fails it will just end up on the floor, but that's fitting for things like dionaea.
target.visible_message("<span class='notice'>\The [usr] handed \the [I] to \the [target].</span>")
@@ -251,14 +251,12 @@
msg += "<span class='deadsay'>[T.He] [T.is] [ssd_msg].</span>\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
var/list/is_bleeding = list()
for(var/organ_tag in species.has_limbs)
var/list/organ_data = species.has_limbs[organ_tag]
var/organ_descriptor = organ_data["descriptor"]
is_destroyed["organ_descriptor"] = 1
var/obj/item/organ/external/E = organs_by_name[organ_tag]
if(!E)
@@ -266,13 +264,11 @@
else if(E.is_stump())
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[T.He] [T.has] a stump where [T.his] [organ_descriptor] should be.</b></span>\n"
else
is_destroyed["organ_descriptor"] = 0
continue
for(var/obj/item/organ/external/temp in organs)
if(temp)
if(temp.status & ORGAN_DESTROYED)
is_destroyed["[temp.name]"] = 1
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[T.He] [T.is] missing [T.his] [temp.name].</b></span>\n"
continue
if(!is_synth && temp.status & ORGAN_ROBOT)
+50 -1
View File
@@ -305,7 +305,7 @@
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
/mob/living/carbon/human/proc/get_face_name()
var/obj/item/organ/external/head = get_organ(BP_HEAD)
if(!head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
if(!head || head.disfigured || head.is_stump() || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
return "Unknown"
return real_name
@@ -1357,6 +1357,55 @@
return 1
return 0
/mob/living/carbon/human/MouseDrop(var/atom/over_object)
var/mob/living/carbon/human/H = over_object
if(holder_type && a_intent == I_HELP && istype(H) && H == usr && H.a_intent == I_HELP && !issmall(H) && Adjacent(H))
get_scooped(H)
return
return ..()
//Puts the item into our active hand if possible. returns 1 on success.
/mob/living/carbon/human/put_in_active_hand(var/obj/item/W)
return (hand ? put_in_l_hand(W) : put_in_r_hand(W))
//Puts the item into our inactive hand if possible. returns 1 on success.
/mob/living/carbon/human/put_in_inactive_hand(var/obj/item/W)
return (hand ? put_in_r_hand(W) : put_in_l_hand(W))
/mob/living/carbon/human/put_in_hands(var/obj/item/W)
if(!W)
return 0
if(put_in_active_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else if(put_in_inactive_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else
return ..()
/mob/living/carbon/human/put_in_l_hand(var/obj/item/W)
if(!..() || l_hand)
return 0
W.forceMove(src)
l_hand = W
W.equipped(src,slot_l_hand)
W.add_fingerprint(src)
update_inv_l_hand()
return 1
/mob/living/carbon/human/put_in_r_hand(var/obj/item/W)
if(!..() || r_hand)
return 0
W.forceMove(src)
r_hand = W
W.equipped(src,slot_r_hand)
W.add_fingerprint(src)
update_inv_r_hand()
return 1
/mob/living/carbon/human/can_stand_overridden()
if(wearing_rig && wearing_rig.ai_can_move_suit(check_for_ai = 1))
// Actually missing a leg will screw you up. Everything else can be compensated for.
@@ -138,7 +138,7 @@
var/hit_zone = H.zone_sel.selecting
var/obj/item/organ/external/affecting = get_organ(hit_zone)
if(!affecting || affecting.is_stump() || (affecting.status & ORGAN_DESTROYED))
if(!affecting || affecting.is_stump())
M << "<span class='danger'>They are missing that limb!</span>"
return 1
@@ -143,6 +143,12 @@ emp_act
for(var/obj/O in src)
if(!O) continue
O.emp_act(severity)
for(var/obj/item/organ/external/O in organs)
O.emp_act(severity)
for(var/obj/item/organ/I in O.internal_organs)
if(!(I.status & ORGAN_ROBOT))
continue
I.emp_act(severity)
..()
@@ -160,7 +166,7 @@ emp_act
var/obj/item/organ/external/affecting = get_organ(target_zone)
if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump())
if (!affecting || affecting.is_stump())
user << "<span class='danger'>They are missing that limb!</span>"
return 0
@@ -0,0 +1,37 @@
#define HUMAN_EATING_NO_ISSUE 0
#define HUMAN_EATING_NO_MOUTH 1
#define HUMAN_EATING_BLOCKED_MOUTH 2
/mob/living/carbon/human/can_eat(var/food, var/feedback = 1)
var/list/status = can_eat_status()
if(status[1] == HUMAN_EATING_NO_ISSUE)
return 1
if(feedback)
if(status[1] == HUMAN_EATING_NO_MOUTH)
src << "Where do you intend to put \the [food]? You don't have a mouth!"
else if(status[1] == HUMAN_EATING_BLOCKED_MOUTH)
src << "<span class='warning'>\The [status[2]] is in the way!</span>"
return 0
/mob/living/carbon/human/can_force_feed(var/feeder, var/food, var/feedback = 1)
var/list/status = can_eat_status()
if(status[1] == HUMAN_EATING_NO_ISSUE)
return 1
if(feedback)
if(status[1] == HUMAN_EATING_NO_MOUTH)
feeder << "Where do you intend to put \the [food]? \The [src] doesn't have a mouth!"
else if(status[1] == HUMAN_EATING_BLOCKED_MOUTH)
feeder << "<span class='warning'>\The [status[2]] is in the way!</span>"
return 0
/mob/living/carbon/human/proc/can_eat_status()
if(!check_has_mouth())
return list(HUMAN_EATING_NO_MOUTH)
var/obj/item/blocked = check_mouth_coverage()
if(blocked)
return list(HUMAN_EATING_BLOCKED_MOUTH, blocked)
return list(HUMAN_EATING_NO_ISSUE)
#undef HUMAN_EATING_NO_ISSUE
#undef HUMAN_EATING_NO_MOUTH
#undef HUMAN_EATING_BLOCKED_MOUTH
@@ -28,7 +28,7 @@
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
for(var/organ_name in list(BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM))
var/obj/item/organ/external/E = get_organ(organ_name)
if(!E || (E.status & ORGAN_DESTROYED))
if(!E || E.is_stump())
tally += 4
if(E.status & ORGAN_SPLINTED)
tally += 0.5
@@ -40,7 +40,7 @@
for(var/organ_name in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))
var/obj/item/organ/external/E = get_organ(organ_name)
if(!E || (E.status & ORGAN_DESTROYED))
if(!E || E.is_stump())
tally += 4
else if(E.status & ORGAN_SPLINTED)
tally += 0.5
@@ -71,7 +71,7 @@
var/limb_pain
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
var/obj/item/organ/external/E = organs_by_name[limb_tag]
if(!E || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD)))
if(!E || (E.status & (ORGAN_MUTATED|ORGAN_DEAD)) || E.is_stump()) //should just be !E.is_usable() here but dislocation screws that up.
stance_damage += 2 // let it fail even if just foot&leg
else if (E.is_malfunctioning())
//malfunctioning only happens intermittently so treat it as a missing limb when it procs
@@ -1,15 +1,7 @@
/*
Add fingerprints to items when we put them in our hands.
This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically.
*/
/mob/living/carbon/human/put_in_l_hand(var/obj/item/W)
. = ..()
if(.) W.add_fingerprint(src)
/mob/living/carbon/human/put_in_r_hand(var/obj/item/W)
. = ..()
if(.) W.add_fingerprint(src)
/mob/living/carbon/human/verb/quick_equip()
set name = "quick-equip"
@@ -40,7 +32,7 @@ This saves us from having to call add_fingerprint() any time something is put in
/mob/living/carbon/human/proc/has_organ(name)
var/obj/item/organ/external/O = organs_by_name[name]
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
return (O && !O.is_stump())
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
switch(slot)
+28 -16
View File
@@ -563,7 +563,14 @@
pl_effects()
break
if(!istype(get_turf(src), /turf/space)) //space is not meant to change your body temperature.
if(istype(get_turf(src), /turf/space))
//Don't bother if the temperature drop is less than 0.1 anyways. Hopefully BYOND is smart enough to turn this constant expression into a constant
if(bodytemperature > (0.1 * HUMAN_HEAT_CAPACITY/(HUMAN_EXPOSED_SURFACE_AREA*STEFAN_BOLTZMANN_CONSTANT))**(1/4) + COSMIC_RADIATION_TEMPERATURE)
//Thermal radiation into space
var/heat_loss = HUMAN_EXPOSED_SURFACE_AREA * STEFAN_BOLTZMANN_CONSTANT * ((bodytemperature - COSMIC_RADIATION_TEMPERATURE)**4)
var/temperature_loss = heat_loss/HUMAN_HEAT_CAPACITY
bodytemperature -= temperature_loss
else
var/loc_temp = T0C
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
@@ -577,7 +584,7 @@
pressure_alert = 0
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection (convection)
var/temp_adj = 0
if(loc_temp < bodytemperature) //Place is colder than we are
var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
@@ -671,6 +678,8 @@
// We produce heat naturally.
if (species.passive_temp_gain)
bodytemperature += species.passive_temp_gain
if (species.body_temperature == null)
return //this species doesn't have metabolic thermoregulation
// Robolimbs cause overheating too.
if(robolimb_count)
@@ -682,7 +691,7 @@
return //fuck this precision
if (on_fire)
return //too busy for pesky convection
return //too busy for pesky metabolic regulation
if(bodytemperature < species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
@@ -1237,7 +1246,7 @@
if(healths)
if (analgesic > 100)
healths.icon_state = "health_health_numb"
healths.icon_state = "health_numb"
else
switch(hal_screwyhud)
if(1) healths.icon_state = "health6"
@@ -1253,8 +1262,6 @@
if(0 to 20) healths.icon_state = "health5"
else healths.icon_state = "health6"
if(!seer)
see_invisible = SEE_INVISIBLE_LIVING
if(nutrition_icon)
switch(nutrition)
if(450 to INFINITY) nutrition_icon.icon_state = "nutrition0"
@@ -1292,31 +1299,36 @@
if(260 to 280) bodytemp.icon_state = "temp-3"
else bodytemp.icon_state = "temp-4"
else
//TODO: precalculate all of this stuff when the species datum is created
var/base_temperature = species.body_temperature
if(base_temperature == null) //some species don't have a set metabolic temperature
base_temperature = (species.heat_level_1 + species.cold_level_1)/2
var/temp_step
if (bodytemperature >= species.body_temperature)
temp_step = (species.heat_level_1 - species.body_temperature)/4
if (bodytemperature >= base_temperature)
temp_step = (species.heat_level_1 - base_temperature)/4
if (bodytemperature >= species.heat_level_1)
bodytemp.icon_state = "temp4"
else if (bodytemperature >= species.body_temperature + temp_step*3)
else if (bodytemperature >= base_temperature + temp_step*3)
bodytemp.icon_state = "temp3"
else if (bodytemperature >= species.body_temperature + temp_step*2)
else if (bodytemperature >= base_temperature + temp_step*2)
bodytemp.icon_state = "temp2"
else if (bodytemperature >= species.body_temperature + temp_step*1)
else if (bodytemperature >= base_temperature + temp_step*1)
bodytemp.icon_state = "temp1"
else
bodytemp.icon_state = "temp0"
else if (bodytemperature < species.body_temperature)
temp_step = (species.body_temperature - species.cold_level_1)/4
else if (bodytemperature < base_temperature)
temp_step = (base_temperature - species.cold_level_1)/4
if (bodytemperature <= species.cold_level_1)
bodytemp.icon_state = "temp-4"
else if (bodytemperature <= species.body_temperature - temp_step*3)
else if (bodytemperature <= base_temperature - temp_step*3)
bodytemp.icon_state = "temp-3"
else if (bodytemperature <= species.body_temperature - temp_step*2)
else if (bodytemperature <= base_temperature - temp_step*2)
bodytemp.icon_state = "temp-2"
else if (bodytemperature <= species.body_temperature - temp_step*1)
else if (bodytemperature <= base_temperature - temp_step*1)
bodytemp.icon_state = "temp-1"
else
bodytemp.icon_state = "temp0"
@@ -263,18 +263,14 @@
var/obj/item/organ/O = new limb_path(H)
organ_data["descriptor"] = O.name
for(var/organ in has_organ)
var/organ_type = has_organ[organ]
H.internal_organs_by_name[organ] = new organ_type(H,1)
for(var/organ_tag in has_organ)
var/organ_type = has_organ[organ_tag]
var/obj/item/organ/O = new organ_type(H,1)
if(organ_tag != O.organ_tag)
warning("[O.type] has a default organ tag \"[O.organ_tag]\" that differs from the species' organ tag \"[organ_tag]\". Updating organ_tag to match.")
O.organ_tag = organ_tag
H.internal_organs_by_name[organ_tag] = O
for(var/name in H.organs_by_name)
H.organs |= H.organs_by_name[name]
for(var/name in H.internal_organs_by_name)
H.internal_organs |= H.internal_organs_by_name[name]
for(var/obj/item/organ/O in (H.organs|H.internal_organs))
O.owner = H
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
@@ -271,3 +271,4 @@
qdel(D)
H.visible_message("<span class='danger'>\The [H] splits apart with a wet slithering noise!</span>")
@@ -29,11 +29,11 @@ var/global/list/sparring_attack_cache = list()
// Check if they have a functioning hand.
var/obj/item/organ/external/E = user.organs_by_name["l_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
if(E && !E.is_stump())
return 1
E = user.organs_by_name["r_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
if(E && !E.is_stump())
return 1
return 0
@@ -181,11 +181,11 @@ var/global/list/sparring_attack_cache = list()
return 0
var/obj/item/organ/external/E = user.organs_by_name["l_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
if(E && !E.is_stump())
return 1
E = user.organs_by_name["r_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
if(E && !E.is_stump())
return 1
return 0
@@ -225,11 +225,11 @@ var/global/list/sparring_attack_cache = list()
if(target.grabbed_by == user && target.lying)
return 0
var/obj/item/organ/external/E = user.organs_by_name["l_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
if(E && !E.is_stump())
return 1
E = user.organs_by_name["r_foot"]
if(E && !(E.status & ORGAN_DESTROYED))
if(E && !E.is_stump())
return 1
return 0
@@ -187,9 +187,10 @@ var/global/list/damage_icon_parts = list()
for(var/obj/item/organ/external/O in organs)
if(O.is_stump())
continue
if(O.status & ORGAN_DESTROYED) damage_appearance += "d"
else
damage_appearance += O.damage_state
//if(O.status & ORGAN_DESTROYED) damage_appearance += "d" //what is this?
//else
// damage_appearance += O.damage_state
damage_appearance += O.damage_state
if(damage_appearance == previous_damage_appearance)
// nothing to do here
@@ -205,21 +206,21 @@ var/global/list/damage_icon_parts = list()
for(var/obj/item/organ/external/O in organs)
if(O.is_stump())
continue
if(!(O.status & ORGAN_DESTROYED))
O.update_icon()
if(O.damage_state == "00") continue
var/use_colour = ((O.status & ORGAN_ROBOT) ? SYNTH_BLOOD_COLOUR : O.species.get_blood_colour(src))
var/icon/DI
var/cache_index = "[O.damage_state]/[O.icon_name]/[use_colour]/[species.get_bodytype()]"
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(use_colour, ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
standing_image.overlays += DI
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(species.blood_color, ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
standing_image.overlays += DI
overlays_standing[DAMAGE_LAYER] = standing_image
@@ -261,7 +262,7 @@ var/global/list/damage_icon_parts = list()
for(var/organ_tag in species.has_limbs)
var/obj/item/organ/external/part = organs_by_name[organ_tag]
if(isnull(part) || part.is_stump() || (part.status & ORGAN_DESTROYED))
if(isnull(part) || part.is_stump())
icon_key += "0"
else if(part.status & ORGAN_ROBOT)
icon_key += "2[part.model ? "-[part.model]": ""]"
@@ -353,7 +354,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[HAIR_LAYER] = null
var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD)
if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED) )
if(!head_organ || head_organ.is_stump() )
if(update_icons) update_icons()
return
@@ -11,6 +11,7 @@
origin_tech = list(TECH_BIO = 4)
var/Uses = 1 // uses before it goes inert
var/enhanced = 0 //has it been enhanced before?
flags = OPENCONTAINER
attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/slimesteroid2))
@@ -36,11 +36,13 @@
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc
if(bodytemperature <= (T0C - 50)) // hurt temperature
if(bodytemperature <= 50) // sqrting negative numbers is bad
if(bodytemperature <= hurt_temperature)
if(bodytemperature <= die_temperature)
adjustToxLoss(200)
else
adjustToxLoss(round(sqrt(bodytemperature)) * 2)
// could be more fancy, but doesn't worth the complexity: when the slimes goes into a cold area
// the damage is mostly determined by how fast its body cools
adjustToxLoss(30)
updatehealth()
@@ -529,4 +531,4 @@
return 0
/mob/living/carbon/slime/slip() //Can't slip something without legs.
return 0
return 0
@@ -49,6 +49,9 @@
var/SStun = 0 // NPC stun variable. Used to calm them down when they are attacked while feeding, or they will immediately re-attach
var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while. The part about freeze gun is a lie
var/hurt_temperature = T0C-50 // slime keeps taking damage when its bodytemperature is below this
var/die_temperature = 50 // slime dies instantly when its bodytemperature is below this
///////////TIME FOR SUBSPECIES
var/colour = "grey"
+25 -9
View File
@@ -166,7 +166,6 @@ var/list/ai_verbs_default = list(
spawn(5)
new /obj/machinery/ai_powersupply(src)
hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[LIFE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
@@ -208,8 +207,23 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/Destroy()
ai_list -= src
qdel(eyeobj)
..()
eyeobj = null
qdel(psupply)
psupply = null
qdel(aiMulti)
aiMulti = null
qdel(aiRadio)
aiRadio = null
qdel(aiCamera)
aiCamera = null
return ..()
/mob/living/silicon/ai/proc/setup_icon()
var/file = file2text("config/custom_sprites.txt")
@@ -267,20 +281,22 @@ var/list/ai_verbs_default = list(
/obj/machinery/ai_powersupply/New(var/mob/living/silicon/ai/ai=null)
powered_ai = ai
powered_ai.psupply = src
if(isnull(powered_ai))
qdel(src)
loc = powered_ai.loc
use_power(1) // Just incase we need to wake up the power system.
forceMove(powered_ai.loc)
..()
use_power(1) // Just incase we need to wake up the power system.
/obj/machinery/ai_powersupply/Destroy()
. = ..()
powered_ai = null
/obj/machinery/ai_powersupply/process()
if(!powered_ai || powered_ai.stat & DEAD)
qdel()
if(!powered_ai || powered_ai.stat == DEAD)
qdel(src)
return
if(powered_ai.psupply != src) // For some reason, the AI has different powersupply object. Delete this one, it's no longer needed.
qdel(src)
return
if(powered_ai.APU_power)
use_power = 0
return
@@ -17,7 +17,7 @@
msg += "It looks slightly charred.\n"
else
msg += "<B>Its casing is melted and heat-warped!</B>\n"
if (src.getOxyLoss())
if (src.getOxyLoss() && (aiRestorePowerRoutine != 0 && !APU_power))
if (src.getOxyLoss() > 175)
msg += "<B>It seems to be running on backup power. Its display is blinking a \"BACKUP POWER CRITICAL\" warning.</B>\n"
else if(src.getOxyLoss() > 100)
@@ -146,13 +146,13 @@
/mob/living/silicon/robot/handle_regular_hud_updates()
if (src.stat == 2 || XRAY in mutations || src.sight_mode & BORGXRAY)
if (src.stat == 2 || (XRAY in mutations) || (src.sight_mode & BORGXRAY))
src.sight |= SEE_TURFS
src.sight |= SEE_MOBS
src.sight |= SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
else if ((src.sight_mode & BORGMESON) && (src.sight_mode & BORGTHERM))
src.sight |= SEE_TURFS
src.sight |= SEE_MOBS
src.see_in_dark = 8
@@ -161,6 +161,10 @@
src.sight |= SEE_TURFS
src.see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGMATERIAL)
src.sight |= SEE_OBJS
src.see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else if (src.sight_mode & BORGTHERM)
src.sight |= SEE_MOBS
src.see_in_dark = 8
@@ -314,6 +314,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/device/pipe_painter(src)
src.modules += new /obj/item/device/floor_painter(src)
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel()
@@ -566,7 +567,7 @@ var/global/list/robot_modules = list(
/obj/item/weapon/robot_module/miner/New()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/borg/sight/material(src)
src.modules += new /obj/item/weapon/wrench(src)
src.modules += new /obj/item/weapon/screwdriver(src)
src.modules += new /obj/item/weapon/storage/bag/ore(src)
@@ -677,6 +678,7 @@ var/global/list/robot_modules = list(
src.modules += new /obj/item/device/lightreplacer(src)
src.modules += new /obj/item/weapon/gripper(src)
src.modules += new /obj/item/weapon/soap(src)
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/device/pipe_painter(src)
src.modules += new /obj/item/device/floor_painter(src)
@@ -74,7 +74,7 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/E = H.organs_by_name[BP_HEAD]
if(!E || (E.status & ORGAN_DESTROYED))
if(!E || E.is_stump())
src << "\The [H] does not have a head!"
if(!H.should_have_organ("brain"))
@@ -14,74 +14,68 @@
//////////////////////////////Capturing////////////////////////////////////////////////////////
attack(mob/living/carbon/human/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
return ..()
if(istype(M, /mob/living/carbon/human/dummy))
return..()
/obj/item/device/soulstone/attack(mob/living/carbon/human/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
return ..()
if(istype(M, /mob/living/carbon/human/dummy))
return..()
if(M.has_brain_worms()) //Borer stuff - RR
user << "<span class='warning'>This being is corrupted by an alien intelligence and cannot be soul trapped.</span>"
return..()
if(M.has_brain_worms()) //Borer stuff - RR
user << "<span class='warning'>This being is corrupted by an alien intelligence and cannot be soul trapped.</span>"
return..()
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their soul captured with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their soul captured with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
transfer_soul("VICTIM", M, user)
return
transfer_soul("VICTIM", M, user)
return
/*attack(mob/living/simple_animal/shade/M as mob, mob/user as mob)//APPARENTLY THEY NEED THEIR OWN SPECIAL SNOWFLAKE CODE IN THE LIVING ANIMAL DEFINES
if(!istype(M, /mob/living/simple_animal/shade))//If target is not a shade
return ..()
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
transfer_soul("SHADE", M, user)
return*/
///////////////////Options for using captured souls///////////////////////////////////////
attack_self(mob/user)
if (!in_range(src, user))
return
user.set_machine(src)
var/dat = "<TT><B>Soul Stone</B><BR>"
for(var/mob/living/simple_animal/shade/A in src)
dat += "Captured Soul: [A.name]<br>"
dat += {"<A href='byond://?src=\ref[src];choice=Summon'>Summon Shade</A>"}
dat += "<br>"
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
user << browse(dat, "window=aicard")
onclose(user, "aicard")
/obj/item/device/soulstone/attack_self(mob/user)
if (!in_range(src, user))
return
user.set_machine(src)
var/dat = "<TT><B>Soul Stone</B><BR>"
for(var/mob/living/simple_animal/shade/A in src)
dat += "Captured Soul: [A.name]<br>"
dat += {"<A href='byond://?src=\ref[src];choice=Summon'>Summon Shade</A>"}
dat += "<br>"
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
user << browse(dat, "window=aicard")
onclose(user, "aicard")
return
/obj/item/device/soulstone/Topic(href, href_list)
var/mob/U = usr
if (!in_range(src, U)||U.machine!=src)
U << browse(null, "window=aicard")
U.unset_machine()
return
add_fingerprint(U)
U.set_machine(src)
Topic(href, href_list)
var/mob/U = usr
if (!in_range(src, U)||U.machine!=src)
switch(href_list["choice"])//Now we switch based on choice.
if ("Close")
U << browse(null, "window=aicard")
U.unset_machine()
return
add_fingerprint(U)
U.set_machine(src)
switch(href_list["choice"])//Now we switch based on choice.
if ("Close")
U << browse(null, "window=aicard")
U.unset_machine()
return
if ("Summon")
for(var/mob/living/simple_animal/shade/A in src)
A.status_flags &= ~GODMODE
A.canmove = 1
A << "<b>You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.</b>"
A.loc = U.loc
A.cancel_camera()
src.icon_state = "soulstone"
attack_self(U)
if ("Summon")
for(var/mob/living/simple_animal/shade/A in src)
A.status_flags &= ~GODMODE
A.canmove = 1
A << "<b>You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.</b>"
A.forceMove(U.loc)
A.cancel_camera()
src.icon_state = "soulstone"
attack_self(U)
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
/obj/structure/constructshell
@@ -99,118 +93,127 @@
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/device/soulstone))
O.transfer_soul("CONSTRUCT",src,user)
var/obj/item/device/soulstone/S = O;
S.transfer_soul("CONSTRUCT",src,user)
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
/obj/item/device/soulstone/proc/transfer_human(var/mob/living/carbon/human/T,var/mob/U)
if(!istype(T))
return;
if(src.imprinted != "empty")
U << "<span class='danger'>Capture failed!</span>: The soul stone has already been imprinted with [src.imprinted]'s mind!"
return
if ((T.health + T.halloss) > config.health_threshold_crit && T.stat != DEAD)
U << "<span class='danger'>Capture failed!</span>: Kill or maim the victim first!"
return
if(T.client == null)
U << "<span class='danger'>Capture failed!</span>: The soul has already fled it's mortal frame."
return
if(src.contents.len)
U << "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room."
return
for(var/obj/item/W in T)
T.drop_from_inventory(W)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
T.invisibility = 101
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = T
flick("dust-h", animation)
qdel(animation)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
S.loc = src //put shade in stone
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = 0//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.icon = T.icon
S.icon_state = T.icon_state
S.overlays = T.overlays
S.color = rgb(254,0,0)
S.alpha = 127
if (T.client)
T.client.mob = S
S.cancel_camera()
/obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
src.icon_state = "soulstone2"
src.name = "Soul Stone: [S.real_name]"
S << "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs."
U << "<span class='notice'>Capture successful!</span> : [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls."
src.imprinted = "[S.name]"
qdel(T)
/obj/item/device/soulstone/proc/transfer_shade(var/mob/living/simple_animal/shade/T,var/mob/U)
if(!istype(T))
return;
if (T.stat == DEAD)
U << "<span class='danger'>Capture failed!</span>: The shade has already been banished!"
return
if(src.contents.len)
U << "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room."
return
if(T.name != src.imprinted)
U << "<span class='danger'>Capture failed!</span>: The soul stone has already been imprinted with [src.imprinted]'s mind!"
return
T.loc = src //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
src.icon_state = "soulstone2"
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
U << "<span class='notice'>Capture successful!</span> : [T.name]'s has been recaptured and stored within the soul stone."
/obj/item/device/soulstone/proc/transfer_construct(var/obj/structure/constructshell/T,var/mob/U)
var/mob/living/simple_animal/shade/A = locate() in src
if(!A)
U << "<span class='danger'>Capture failed!</span>: The soul stone is empty! Go kill someone!"
return;
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
switch(construct_class)
if("Juggernaut")
var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
qdel(T)
Z << "<B>You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(src)
if("Wraith")
var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
qdel(T)
Z << "<B>You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(src)
if("Artificer")
var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
qdel(T)
Z << "<B>You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(src)
/obj/item/device/soulstone/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
switch(choice)
if("VICTIM")
var/mob/living/carbon/human/T = target
var/obj/item/device/soulstone/C = src
if(C.imprinted != "empty")
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
else
if ((T.health + T.halloss) > config.health_threshold_crit)
U << "\red <b>Capture failed!</b>: \black Kill or maim the victim first!"
else
if(T.client == null)
U << "\red <b>Capture failed!</b>: \black The soul has already fled it's mortal frame."
else
if(C.contents.len)
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
else
for(var/obj/item/W in T)
T.drop_from_inventory(W)
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
T.invisibility = 101
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = T
flick("dust-h", animation)
qdel(animation)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
S.loc = C //put shade in stone
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = 0//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.icon = T.icon
S.icon_state = T.icon_state
S.overlays = T.overlays
S.color = rgb(254,0,0)
S.alpha = 127
if (T.client)
T.client.mob = S
S.cancel_camera()
C.icon_state = "soulstone2"
C.name = "Soul Stone: [S.real_name]"
S << "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs."
U << "\blue <b>Capture successful!</b>: \black [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls."
C.imprinted = "[S.name]"
qdel(T)
transfer_human(target,U)
if("SHADE")
var/mob/living/simple_animal/shade/T = target
var/obj/item/device/soulstone/C = src
if (T.stat == DEAD)
U << "\red <b>Capture failed!</b>: \black The shade has already been banished!"
else
if(C.contents.len)
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
else
if(T.name != C.imprinted)
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
else
T.loc = C //put shade in stone
T.status_flags |= GODMODE
T.canmove = 0
T.health = T.maxHealth
C.icon_state = "soulstone2"
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
U << "\blue <b>Capture successful!</b>: \black [T.name]'s has been recaptured and stored within the soul stone."
transfer_shade(target,U)
if("CONSTRUCT")
var/obj/structure/constructshell/T = target
var/obj/item/device/soulstone/C = src
var/mob/living/simple_animal/shade/A = locate() in C
if(A)
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
switch(construct_class)
if("Juggernaut")
var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
qdel(T)
Z << "<B>You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(C)
if("Wraith")
var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
qdel(T)
Z << "<B>You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(C)
if("Artificer")
var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
Z.key = A.key
if(iscultist(U))
cult.add_antagonist(Z.mind)
qdel(T)
Z << "<B>You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs</B>"
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(C)
else
U << "\red <b>Creation failed!</b>: \black The soul stone is empty! Go kill someone!"
return
transfer_construct(target,U)
@@ -37,7 +37,8 @@
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/device/soulstone))
O.transfer_soul("SHADE", src, user)
var/obj/item/device/soulstone/S = O;
S.transfer_soul("SHADE", src, user)
return
/mob/living/simple_animal/shade/proc/OnDeathInLife()
+10 -10
View File
@@ -717,17 +717,17 @@
if(!TurfAdjacent(listed_turf))
listed_turf = null
else
statpanel(listed_turf.name, null, listed_turf)
for(var/atom/A in listed_turf)
if(!A.mouse_opacity)
continue
if(A.invisibility > see_invisible)
continue
if(is_type_in_list(A, shouldnt_see))
continue
statpanel(listed_turf.name, null, A)
if(statpanel("Turf"))
stat("\icon[listed_turf]", listed_turf.name)
for(var/atom/A in listed_turf)
if(!A.mouse_opacity)
continue
if(A.invisibility > see_invisible)
continue
if(is_type_in_list(A, shouldnt_see))
continue
stat(A)
sleep(4) //Prevent updating the stat panel for the next .4 seconds, prevents clientside latency from updates
// facing verbs
/mob/proc/canface()
+1 -1
View File
@@ -3,7 +3,7 @@
var/obj/item/organ/external/E = H.get_organ(target_zone)
if(!E || (E.status & ORGAN_DESTROYED))
if(!E || E.is_stump())
user << "<span class='notice'>[H] is missing that bodypart.</span>"
return
+6
View File
@@ -466,6 +466,12 @@ proc/is_blind(A)
/mob/proc/is_client_active(var/active = 1)
return client && client.inactivity < active MINUTES
/mob/proc/can_eat()
return 1
/mob/proc/can_force_feed()
return 1
#define SAFE_PERP -50
/mob/living/proc/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest)
if(stat == DEAD)
+1 -1
View File
@@ -304,7 +304,7 @@
var/mob/living/carbon/human/driver = mob
var/obj/item/organ/external/l_hand = driver.get_organ("l_hand")
var/obj/item/organ/external/r_hand = driver.get_organ("r_hand")
if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED)))
if((!l_hand || l_hand.is_stump()) && (!r_hand || r_hand.is_stump()))
return // No hands to drive your chair? Tough luck!
//drunk wheelchair driving
else if(mob.confused)
@@ -2,7 +2,19 @@ datum/preferences
//The mob should have a gender you want before running this proc. Will run fine without H
proc/randomize_appearance_for(var/mob/living/carbon/human/H)
gender = pick(MALE, FEMALE)
s_tone = random_skin_tone()
var/datum/species/current_species = all_species[species]
if(current_species)
if(current_species.flags & HAS_SKIN_TONE)
s_tone = random_skin_tone()
if(current_species.flags & HAS_EYE_COLOR)
randomize_eyes_color()
if(current_species.flags & HAS_SKIN_COLOR)
randomize_skin_color()
if(current_species.flags & HAS_UNDERWEAR)
underwear = rand(1,underwear_m.len)
undershirt = rand(1,undershirt_t.len)
var/use_head_species
var/obj/item/organ/external/head/temp_head = H.get_organ(BP_HEAD)
@@ -17,10 +29,7 @@ datum/preferences
randomize_hair_color("hair")
randomize_hair_color("facial")
randomize_eyes_color()
randomize_skin_color()
underwear = rand(1,underwear_m.len)
undershirt = rand(1,undershirt_t.len)
socks = rand(1,socks_t.len)
backbag = 2
age = rand(AGE_MIN,AGE_MAX)
+2 -1
View File
@@ -58,7 +58,7 @@ var/list/organ_cache = list()
var/mob/living/carbon/human/H = holder
if(istype(H))
if(internal)
var/obj/item/organ/external/E = H.organs_by_name[src.parent_organ]
var/obj/item/organ/external/E = H.get_organ(parent_organ)
if(E)
if(E.internal_organs == null)
E.internal_organs = list()
@@ -247,6 +247,7 @@ var/list/organ_cache = list()
status |= ORGAN_ASSISTED
status |= ORGAN_ROBOT
/obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc
status = 0
status |= ORGAN_ASSISTED
+34 -41
View File
@@ -100,15 +100,15 @@
if(istype(I,/obj/item/organ))
continue
removable_objects |= I
if(!removable_objects.len)
return ..()
var/obj/item/I = pick(removable_objects)
if(!istype(I))
return ..()
I.loc = get_turf(user)
if(!(user.l_hand && user.r_hand))
user.put_in_hands(I)
user.visible_message("<span class='danger'>\The [user] rips \the [I] out of \the [src]!</span>")
if(removable_objects.len)
var/obj/item/I = pick(removable_objects)
I.loc = get_turf(user) //just in case something was embedded that is not an item
if(istype(I))
if(!(user.l_hand && user.r_hand))
user.put_in_hands(I)
user.visible_message("<span class='danger'>\The [user] rips \the [I] out of \the [src]!</span>")
return //no eating the limb until everything's been removed
return ..()
/obj/item/organ/external/examine()
..()
@@ -181,8 +181,8 @@
return
/obj/item/organ/external/New(var/mob/living/carbon/holder, var/internal)
..()
/obj/item/organ/external/New(var/mob/living/carbon/holder)
..(holder, 0)
if(owner)
replaced(owner)
sync_colour_to_human(owner)
@@ -215,8 +215,6 @@
/obj/item/organ/external/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
if((brute <= 0) && (burn <= 0))
return 0
if(status & ORGAN_DESTROYED)
return 0
brute *= brute_mod
burn *= burn_mod
@@ -460,11 +458,11 @@ This function completely restores a damaged organ to perfect condition.
/obj/item/organ/external/process()
if(owner)
if(parent)
if(parent.status & ORGAN_DESTROYED)
status |= ORGAN_DESTROYED
owner.update_body(1)
return
//Dismemberment
//if(parent && parent.is_stump()) //should never happen
// warning("\The [src] ([src.type]) belonging to [owner] ([owner.type]) was attached to a stump")
// remove()
// return
// Process wounds, doing healing etc. Only do this every few ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
@@ -503,7 +501,7 @@ Note that amputating the affected organ does in fact remove the infection from t
*/
/obj/item/organ/external/proc/update_germs()
if(status & (ORGAN_ROBOT|ORGAN_DESTROYED) || (owner.species && owner.species.flags & IS_PLANT)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
if(status & (ORGAN_ROBOT) || (owner.species && owner.species.flags & IS_PLANT)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
germ_level = 0
return
@@ -680,8 +678,6 @@ Note that amputating the affected organ does in fact remove the infection from t
// new damage icon system
// returns just the brute/burn damage code
/obj/item/organ/external/proc/damage_state_text()
if(status & ORGAN_DESTROYED)
return "--"
var/tburn = 0
var/tbrute = 0
@@ -710,14 +706,11 @@ Note that amputating the affected organ does in fact remove the infection from t
****************************************************/
//Handles dismemberment
/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children, var/silent)
/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate = DROPLIMB_EDGE, var/ignore_children = null)
if(cannot_amputate || !owner)
return
if(!disintegrate)
disintegrate = DROPLIMB_EDGE
switch(disintegrate)
if(DROPLIMB_EDGE)
if(!clean)
@@ -741,16 +734,16 @@ Note that amputating the affected organ does in fact remove the infection from t
"<span class='danger'>You hear the [gore_sound].</span>")
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
var/obj/item/organ/external/parent_organ = parent
removed(null, ignore_children)
victim.traumatic_shock += 60
wounds.Cut()
if(parent)
if(parent_organ)
var/datum/wound/lost_limb/W = new (src, disintegrate, clean)
parent.children -= src
if(clean)
parent.wounds |= W
parent.update_damages()
parent_organ.wounds |= W
parent_organ.update_damages()
else
var/obj/item/organ/external/stump/stump = new (victim, 0, src)
if(status & ORGAN_ROBOT)
@@ -758,7 +751,6 @@ Note that amputating the affected organ does in fact remove the infection from t
stump.wounds |= W
victim.organs |= stump
stump.update_damages()
parent = null
spawn(1)
victim.updatehealth()
@@ -985,9 +977,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return 0
/obj/item/organ/external/proc/is_usable()
if((status & ORGAN_ROBOT) && get_damage() >= max_damage) //robot limbs just become inoperable at max damage
return
return !is_dislocated() && !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
return !is_dislocated() && !(status & (ORGAN_MUTATED|ORGAN_DEAD))
/obj/item/organ/external/proc/is_malfunctioning()
return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))
@@ -1006,7 +996,7 @@ Note that amputating the affected organ does in fact remove the infection from t
H.drop_from_inventory(W)
W.loc = owner
/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children)
/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children = 0)
if(!owner)
return
@@ -1015,14 +1005,13 @@ Note that amputating the affected organ does in fact remove the infection from t
..()
status |= ORGAN_DESTROYED
victim.bad_external_organs -= src
for(var/obj/item/implant in implants)
if(!istype(implant))
return
if(implant.w_class <= 2)
qdel(implant)
for(var/atom/movable/implant in implants)
//large items and non-item objs fall to the floor, everything else stays
var/obj/item/I = implant
if(istype(I) && I.w_class < 3)
implant.loc = get_turf(victim.loc)
else
implant.loc = src
implants.Cut()
@@ -1041,6 +1030,10 @@ Note that amputating the affected organ does in fact remove the infection from t
organ.removed()
organ.loc = src
// Remove parent references
parent.children -= src
parent = null
release_restraints(victim)
victim.organs -= src
victim.organs_by_name[organ_tag] = null // Remove from owner's vars.
@@ -1117,7 +1110,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(wound_descriptors.len)
var/list/flavor_text = list()
var/list/no_exclude = list("gaping wound", "big gaping wound", "massive wound", "large bruise",\
"huge bruise", "massive bruise", "severe burn", "large burn", "deep burn", "carbonised area")
"huge bruise", "massive bruise", "severe burn", "large burn", "deep burn", "carbonised area") //note to self make this more robust
for(var/wound in wound_descriptors)
switch(wound_descriptors[wound])
if(1)
+2 -1
View File
@@ -190,7 +190,8 @@
return ..(user, 1)
/obj/item/organ/internal/diona/node
name = "receptor node"
name = "response node"
parent_organ = "head"
organ_tag = "receptor node"
icon = 'icons/mob/alien.dmi'
icon_state = "claw"
+1
View File
@@ -18,6 +18,7 @@
owner.stat = 0
owner.visible_message("<span class='danger'>\The [owner] twitches visibly!</span>")
// Used for an MMI or posibrain being installed into a human.
/obj/item/organ/internal/mmi_holder
name = "brain interface"
+1
View File
@@ -84,6 +84,7 @@
i.loc = src
user << "<span class='notice'>You put [i] in [src].</span>"
papers.Add(i)
update_icon()
amount++
+4 -5
View File
@@ -493,8 +493,6 @@
user << "<span class='warning'>There is nothing to secure.</span>"
return
update_icon()
else if(emagged)
user << "The interface is broken."
else
wiresexposed = !wiresexposed
user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]"
@@ -623,8 +621,9 @@
qdel(W)
stat &= ~BROKEN
// Malf AI, removes the APC from AI's hacked APCs list.
if(hacker && hacker.hacked_apcs && src in hacker.hacked_apcs)
if(hacker && hacker.hacked_apcs && (src in hacker.hacked_apcs))
hacker.hacked_apcs -= src
hacker = null
if (opened==2)
opened = 1
update_icon()
@@ -735,7 +734,7 @@
return
var/list/data = list(
"locked" = locked,
"locked" = (locked && !emagged) ? 1 : 0,
"isOperating" = operating,
"externalPower" = main_status,
"powerCellStatus" = cell ? cell.percent() : null,
@@ -850,7 +849,7 @@
user << "<span class='danger'>\The [src] have AI control disabled!</span>"
return 0
else
if ((!in_range(src, user) || !istype(src.loc, /turf) || hacker)) // AI-hacked APCs cannot be controlled by other AIs, unlinked cyborgs or humans.
if (!in_range(src, user) || !istype(src.loc, /turf))
return 0
var/mob/living/carbon/human/H = user
if (istype(H) && prob(H.getBrainLoss()))
+1 -1
View File
@@ -883,4 +883,4 @@ obj/structure/cable/proc/cableColor(var/colorC)
/obj/item/stack/cable_coil/random/New()
stacktype = /obj/item/stack/cable_coil
color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
..()
..()
+3 -2
View File
@@ -284,7 +284,7 @@
for(var/obj/item/weapon/grab/G in M.grabbed_by)
grabstate = max(grabstate, G.state)
if(grabstate >= GRAB_NECK)
damage_mult = 3.0
damage_mult = 2.5
else if(grabstate >= GRAB_AGGRESSIVE)
damage_mult = 1.5
P.damage *= damage_mult
@@ -363,7 +363,8 @@
in_chamber.on_hit(M)
if (in_chamber.damage_type != HALLOSS)
user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, BP_HEAD, used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1)
log_and_message_admins("[key_name(user)] commited suicide using \a [src]")
user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1)
user.death()
else
user << "<span class = 'notice'>Ow...</span>"
@@ -156,55 +156,3 @@ obj/item/weapon/gun/energy/staff/focus
user << "<span class='warning'>The [src.name] will now strike only a single person.</span>"
projectile_type = "/obj/item/projectile/forcebolt"
*/
/* Adminbus guns */
// Serves as a target spotter for the Icarus.
/obj/item/weapon/gun/energy/icarus
name = "rubber ducky"
desc = "It's a cute rubber duck. With an evil gleam in it's eye."
projectile_type = /obj/item/projectile/icarus/pointdefense
icon = 'icons/obj/watercloset.dmi'
item_icons = null
icon_state = "rubberducky"
item_state = "rubberducky"
charge_cost = 0
silenced = 1
/obj/item/weapon/gun/energy/icarus/attack_self(mob/living/user as mob)
if(projectile_type == /obj/item/projectile/icarus/pointdefense)
projectile_type = /obj/item/projectile/icarus/guns
user << "You inform the Icarus to switch to the main guns."
else
projectile_type = /obj/item/projectile/icarus/pointdefense
user << "You inform the Icarus to switch to the point-defense lasers."
. = ..()
/obj/item/weapon/gun/energy/icarus/update_icon()
return
/obj/item/weapon/gun/energy/icarus/verb/SetIcarusAngle()
set src in usr
set name = "Set Firing Angle"
set desc = "Sets the angle from which the icarus will fire."
set category = "Object"
Icarus_SetPosition(usr)
/obj/item/weapon/gun/energy/variable
name = "abstract weapon"
desc = "It seems to shift and flow as you watch."
charge_cost = 0
silenced = 1
/obj/item/weapon/gun/energy/variable/update_icon()
return
/obj/item/weapon/gun/energy/variable/attack_self(mob/living/user as mob)
var/type = input(user,"What projectile type?","Projectile", null) as null|anything in typesof(/obj/item/projectile)
if(!type)
return ..()
projectile_type = type
. = ..()
+1 -14
View File
@@ -136,20 +136,6 @@
if(ishuman(target))
var/mob/living/carbon/human/M = target
M.confused += rand(5,8)
/obj/item/projectile/icarus/pointdefense/process()
Icarus_FireLaser(get_turf(original))
spawn
qdel(src)
return
/obj/item/projectile/icarus/guns/process()
Icarus_FireCannon(get_turf(original))
spawn
qdel(src)
return
/obj/item/projectile/chameleon
name = "bullet"
icon_state = "bullet"
@@ -158,3 +144,4 @@
nodamage = 1
damage_type = HALLOSS
muzzle_type = /obj/effect/projectile/bullet/muzzle
+2 -1
View File
@@ -206,5 +206,6 @@ var/global/list/map_count = list()
target_map.map[target_map.get_map_cell(tx+x,ty+y)] = map[current_cell]
handle_post_overlay_on(target_map,tx,ty)
/datum/random_map/proc/handle_post_overlay_on(var/datum/random_map/target_map, var/tx, var/ty)
return
return
+1 -1
View File
@@ -288,7 +288,7 @@
return splash_mob(target, amount, copy)
if(isturf(target))
return trans_to_turf(target, amount, multiplier, copy)
if(isobj(target))
if(isobj(target) && target.is_open_container())
return trans_to_obj(target, amount, multiplier, copy)
return 0
@@ -27,6 +27,7 @@
var/pillsprite = "1"
var/client/has_sprites = list()
var/max_pill_count = 20
flags = OPENCONTAINER
/obj/machinery/chem_master/New()
..()
@@ -1,7 +1,4 @@
///jar
/obj/item/weapon/reagent_containers/food/drinks/jar
name = "empty jar"
desc = "A jar. You're not sure what it's supposed to hold."
@@ -9,23 +6,20 @@
item_state = "beaker"
center_of_mass = list("x"=15, "y"=8)
unacidable = 1
New()
..()
reagents.add_reagent("slime", 50)
on_reagent_change()
if (reagents.reagent_list.len > 0)
switch(reagents.get_master_reagent_id())
if("slime")
icon_state = "jar_slime"
name = "slime jam"
desc = "A jar of slime jam. Delicious!"
else
icon_state ="jar_what"
name = "jar of something"
desc = "You can't really tell what this is."
else
icon_state = "jar"
name = "empty jar"
desc = "A jar. You're not sure what it's supposed to hold."
return
/obj/item/weapon/reagent_containers/food/drinks/jar/on_reagent_change()
if (reagents.reagent_list.len > 0)
switch(reagents.get_master_reagent_id())
if("slime")
icon_state = "jar_slime"
name = "slime jam"
desc = "A jar of slime jam. Delicious!"
else
icon_state ="jar_what"
name = "jar of something"
desc = "You can't really tell what this is."
else
icon_state = "jar"
name = "empty jar"
desc = "A jar. You're not sure what it's supposed to hold."
return
@@ -231,7 +231,7 @@
var/target_zone = ran_zone(check_zone(user.zone_sel.selecting, target))
var/obj/item/organ/external/affecting = H.get_organ(target_zone)
if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump())
if (!affecting || affecting.is_stump())
user << "<span class='danger'>They are missing that limb!</span>"
return
+3 -1
View File
@@ -163,7 +163,9 @@
qdel(src)
/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+500)
if (modded)
explode()
else if (temperature > T0C+500)
explode()
return ..()
+20 -10
View File
@@ -145,9 +145,15 @@
// mouse drop another mob or self
//
/obj/machinery/disposal/MouseDrop_T(mob/target, mob/user)
if (!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai))
if(user.stat || !user.canmove || !istype(target))
return
if(isanimal(user) && target != user) return //animals cannot put mobs other than themselves into disposal
if(target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1)
return
//animals cannot put mobs other than themselves into disposal
if(isanimal(user) && target != user)
return
src.add_fingerprint(user)
var/target_loc = target.loc
var/msg
@@ -737,22 +743,26 @@
// expel the held objects into a turf
// called when there is a break in the pipe
//
proc/expel(var/obj/structure/disposalholder/H, var/turf/T, var/direction)
var/turf/target
if(T.density) // dense ouput turf, so stop holder
H.active = 0
H.loc = src
if(!istype(H))
return
// Empty the holder if it is expelled into a dense turf.
// Leaving it intact and sitting in a wall is stupid.
if(T.density)
for(var/atom/movable/AM in H)
AM.loc = T
AM.pipe_eject(0)
qdel(H)
return
if(!T.is_plating() && istype(T,/turf/simulated/floor)) //intact floor, pop the tile
var/turf/simulated/floor/F = T
F.break_tile()
new /obj/item/stack/tile(H) // add to holder so it will be thrown with other stuff
var/turf/target
if(direction) // direction is specified
if(istype(T, /turf/space)) // if ended in space, then range is unlimited
target = get_edge_target_turf(T, direction)
@@ -257,7 +257,7 @@ var/list/valid_secondary_effect_types = list(\
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_WATER && prob(25))
secondary_effect.ToggleActivate(0)
else if(W.reagents.has_reagent("acid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
else if(W.reagents.has_reagent("sacid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
if(my_effect.trigger == TRIGGER_ACID)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_ACID && prob(25))
@@ -85,6 +85,7 @@
var/obj/machinery/artifact/A = scanned_object
A.anchored = 0
A.being_used = 0
scanned_object = null
/obj/machinery/artifact_analyser/Topic(href, href_list)
if(href_list["begin_scan"])
@@ -97,8 +98,8 @@
continue
if(O.invisibility)
continue
if(istype(scanned_object, /obj/machinery/artifact))
var/obj/machinery/artifact/A = scanned_object
if(istype(O, /obj/machinery/artifact))
var/obj/machinery/artifact/A = O
if(A.being_used)
artifact_in_use = 1
else
+7 -1
View File
@@ -93,4 +93,10 @@
return 1
/obj/machinery/computer/shuttle_control/bullet_act(var/obj/item/projectile/Proj)
visible_message("[Proj] ricochets off [src]!")
visible_message("\The [Proj] ricochets off \the [src]!")
/obj/machinery/computer/shuttle_control/ex_act()
return
/obj/machinery/computer/shuttle_control/emp_act()
return
+11 -9
View File
@@ -48,13 +48,15 @@
victim.verbs -= V
var/mob/dead/observer/ghost = victim.ghostize(0)
ghost.spell_list = victim.spell_list//If they have spells, transfer them. Now we basically have a backup mob.
ghost.spell_list += victim.spell_list//If they have spells, transfer them. Now we basically have a backup mob.
caster.mind.transfer_to(victim)
victim.spell_list = list() //clear those out
for(var/spell/S in caster.spell_list)
victim.add_spell(S) //Now they are inside the victim's body - this also generates the HUD
caster.spell_list = list() //clean that out as well
for(var/spell/S in victim.spell_list) //get rid of spells the new way
victim.remove_spell(S) //This will make it so that players will not get the HUD and all that spell bugginess that caused copies of spells and stuff of that nature.
for(var/spell/S in caster.spell_list)
victim.add_spell(S) //Now they are inside the victim's body - this also generates the HUD
caster.remove_spell(S) //remove the spells from the caster
if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster.
for(var/V in caster.mind.special_verbs)//Not too important but could come into play.
@@ -62,9 +64,9 @@
ghost.mind.transfer_to(caster)
caster.key = ghost.key //have to transfer the key since the mind was not active
for(var/spell/S in ghost.spell_list)
caster.add_spell(S)
ghost.spell_list = list()
for(var/spell/S in ghost.spell_list)
caster.add_spell(S)
ghost.spell_list = list()
if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here.
for(var/V in caster.mind.special_verbs)
@@ -76,4 +78,4 @@
//After a certain amount of time the victim gets a message about being in a different body.
spawn(msg_wait)
caster << "<span class='danger'>You feel woozy and lightheaded. Your body doesn't seem like your own.</span>"
caster << "<span class='danger'>You feel woozy and lightheaded. Your body doesn't seem like your own.</span>"
+1 -3
View File
@@ -15,7 +15,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (affected == null)
return 0
if (affected.status & ORGAN_DESTROYED)
if (affected.is_stump())
return 0
if (affected.status & ORGAN_ROBOT)
return 0
@@ -285,8 +285,6 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (affected == null)
return 0
if (affected.status & ORGAN_DESTROYED)
return 0
return !affected.cannot_amputate
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+5
View File
@@ -278,6 +278,10 @@
user << "<span class='danger'>You cannot install a naked organ into a robotic body.</span>"
return SURGERY_FAILURE
if(!target.species)
user << "<span class='danger'>You have no idea what species this person is. Report this on the bug tracker.</span>"
return SURGERY_FAILURE
var/o_is = (O.gender == PLURAL) ? "are" : "is"
var/o_a = (O.gender == PLURAL) ? "" : "a "
var/o_do = (O.gender == PLURAL) ? "don't" : "doesn't"
@@ -294,6 +298,7 @@
if(O && affected.organ_tag == O.parent_organ)
organ_compatible = 1
else
user << "<span class='warning'>\The [O.organ_tag] [o_do] normally go in \the [affected.name].</span>"
return SURGERY_FAILURE
+1
View File
@@ -393,6 +393,7 @@
return SURGERY_FAILURE
if(!target.should_have_organ("brain"))
user << "<span class='danger'>You're pretty sure [target.species.name_plural] don't normally have a brain.</span>"
return SURGERY_FAILURE
+14 -9
View File
@@ -306,7 +306,7 @@
return 1
/datum/gas_mixture/proc/react(atom/dump_location)
/datum/gas_mixture/proc/react()
zburn(null, force_burn=0, no_check=0) //could probably just call zburn() here with no args but I like being explicit.
@@ -442,20 +442,25 @@
total_gas[g] += gasmix.gas[g]
if(total_volume > 0)
//Average out the gases
for(var/g in total_gas)
total_gas[g] /= total_volume
var/datum/gas_mixture/combined = new(total_volume)
combined.gas = total_gas
//Calculate temperature
var/temperature = 0
if(total_heat_capacity > 0)
temperature = total_thermal_energy / total_heat_capacity
combined.temperature = total_thermal_energy / total_heat_capacity
combined.update_values()
//Allow for reactions
combined.react()
//Average out the gases
for(var/g in combined.gas)
combined.gas[g] /= total_volume
//Update individual gas_mixtures
for(var/datum/gas_mixture/gasmix in gases)
gasmix.gas = total_gas.Copy()
gasmix.temperature = temperature
gasmix.gas = combined.gas.Copy()
gasmix.temperature = combined.temperature
gasmix.multiply(gasmix.volume)
return 1