Merge remote-tracking branch 'citadel/master' into vampire_haste

This commit is contained in:
kevinz000
2020-02-19 19:16:58 -07:00
110 changed files with 564 additions and 201 deletions
+1 -1
View File
@@ -714,7 +714,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
AI_Interact = !AI_Interact
if(mob && IsAdminGhost(mob))
mob.has_unlimited_silicon_privilege = AI_Interact
mob.silicon_privileges = AI_Interact ? ALL : NONE
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
@@ -170,7 +170,7 @@
// Warn Feeder about Witnesses...
var/was_unnoticed = TRUE
for(var/mob/living/M in viewers(notice_range, owner))
if(M != owner && M != target && iscarbon(M) && M.mind && !M.has_unlimited_silicon_privilege && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
if(M != owner && M != target && iscarbon(M) && M.mind && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
was_unnoticed = FALSE
break
if(was_unnoticed)
@@ -65,7 +65,7 @@
if(T && T.lighting_object && T.get_lumcount()>= 0.1)
// B) Check for Viewers
for(var/mob/living/M in viewers(get_turf(owner)))
if(M != owner && isliving(M) && M.mind && !M.has_unlimited_silicon_privilege && !M.eye_blind) // M.client <--- add this in after testing!
if(M != owner && isliving(M) && M.mind && !M.silicon_privileges && !M.eye_blind) // M.client <--- add this in after testing!
am_seen = TRUE
if (!M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
drop_item = TRUE
@@ -120,7 +120,7 @@
hierophant_network.Grant(current)
current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
if(G.active && ishuman(current))
if(G && G.active && ishuman(current))
current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER))
/datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override)
@@ -174,9 +174,12 @@
log_admin("[key_name(admin)] has made [new_owner.current] into a servant of Ratvar.")
/datum/antagonist/clockcult/admin_remove(mob/user)
remove_servant_of_ratvar(owner.current, TRUE)
message_admins("[key_name_admin(user)] has removed clockwork servant status from [owner.current].")
log_admin("[key_name(user)] has removed clockwork servant status from [owner.current].")
var/mob/target = owner.current
if(!target)
return
remove_servant_of_ratvar(target, TRUE)
message_admins("[key_name_admin(user)] has removed clockwork servant status from [target].")
log_admin("[key_name(user)] has removed clockwork servant status from [target].")
/datum/antagonist/clockcult/get_admin_commands()
. = ..()
@@ -229,7 +229,7 @@
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] the interface.</span>"
/obj/machinery/airalarm/ui_status(mob/user)
if(user.has_unlimited_silicon_privilege && aidisabled)
if(hasSiliconAccessInArea(user) && aidisabled)
to_chat(user, "AI control has been disabled.")
else if(!shorted)
return ..()
@@ -245,7 +245,7 @@
/obj/machinery/airalarm/ui_data(mob/user)
var/data = list(
"locked" = locked,
"siliconUser" = user.has_unlimited_silicon_privilege || hasSiliconAccessInArea(user),
"siliconUser" = hasSiliconAccessInArea(user),
"emagged" = (obj_flags & EMAGGED ? 1 : 0),
"danger_level" = danger_level,
)
@@ -288,7 +288,7 @@
"danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure)
))
if(!locked || user.has_unlimited_silicon_privilege || hasSiliconAccessInArea(user))
if(!locked || hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE))
data["vents"] = list()
for(var/id_tag in A.air_vent_names)
var/long_name = A.air_vent_names[id_tag]
@@ -368,12 +368,14 @@
/obj/machinery/airalarm/ui_act(action, params)
if(..() || buildstage != 2)
return
if((locked && !usr.has_unlimited_silicon_privilege && !hasSiliconAccessInArea(usr)) || (usr.has_unlimited_silicon_privilege && aidisabled))
var/silicon_access = hasSiliconAccessInArea(usr)
var/bot_priviledges = silicon_access || (usr.silicon_privileges & PRIVILEDGES_DRONE)
if((locked && !bot_priviledges) || (silicon_access && aidisabled))
return
var/device_id = params["id_tag"]
switch(action)
if("lock")
if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN))
if(bot_priviledges && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
. = TRUE
if("power", "toggle_filter", "widenet", "scrubbing")
+3 -12
View File
@@ -24,13 +24,13 @@
export_types = list(/obj/structure/ore_box)
/datum/export/large/crate/wood
cost = 140 //
cost = 140
unit_name = "wooden crate"
export_types = list(/obj/structure/closet/crate/wooden)
exclude_types = list()
/datum/export/large/barrel
cost = 500 //150 to make meaning proffit of 350
cost = 300 //double the wooden cost of a coffin.
unit_name = "wooden barrel"
export_types = list(/obj/structure/fermenting_barrel)
@@ -40,19 +40,11 @@
export_types = list(/obj/structure/closet/crate/coffin)
/datum/export/large/reagent_dispenser
cost = 100 // +0-400 depending on amount of reagents left
var/contents_cost = 400
/datum/export/large/reagent_dispenser/get_cost(obj/O)
var/obj/structure/reagent_dispensers/D = O
var/ratio = D.reagents.total_volume / D.reagents.maximum_volume
return ..() + round(contents_cost * ratio)
cost = 100
/datum/export/large/reagent_dispenser/water
unit_name = "watertank"
export_types = list(/obj/structure/reagent_dispensers/watertank)
contents_cost = 200
/datum/export/large/reagent_dispenser/fuel
unit_name = "fueltank"
@@ -60,7 +52,6 @@
/datum/export/large/reagent_dispenser/beer
unit_name = "beer keg"
contents_cost = 700
export_types = list(/obj/structure/reagent_dispensers/beerkeg)
/datum/export/large/pipedispenser
-5
View File
@@ -65,11 +65,6 @@
material_id = MAT_TITANIUM
message = "cm3 of titanium"
/datum/export/material/plastitanium
cost = 165 // plasma + titanium costs
material_id = MAT_TITANIUM // code can only check for one material_id; plastitanium is half plasma, half titanium
message = "cm3 of plastitanium"
/datum/export/material/plastic
cost = 5
material_id = MAT_PLASTIC
+10
View File
@@ -67,6 +67,16 @@
message = "of plasteel"
export_types = list(/obj/item/stack/sheet/plasteel)
/datum/export/material/plastitanium
cost = 165 // plasma + titanium costs
export_types = list(/obj/item/stack/sheet/mineral/plastitanium)
message = "of plastitanium"
/datum/export/material/plastitanium_glass
cost = 168 // plasma + titanium + glass costs
export_types = list(/obj/item/stack/sheet/plastitaniumglass)
message = "of plastitanium glass"
// 1 glass + 0.5 metal, cost is rounded up.
/datum/export/stack/rglass
cost = 6
+25
View File
@@ -199,6 +199,31 @@
unit_name = "advanced shotgun shell"
export_types = list(/obj/item/ammo_casing/shotgun/dragonsbreath, /obj/item/ammo_casing/shotgun/meteorslug, /obj/item/ammo_casing/shotgun/pulseslug, /obj/item/ammo_casing/shotgun/frag12, /obj/item/ammo_casing/shotgun/ion, /obj/item/ammo_casing/shotgun/laserslug)
/////////////////////////
//Bow and Arrows/////////
/////////////////////////
/datum/export/weapon/bows
cost = 450
unit_name = "bow"
export_types = list(/obj/item/gun/ballistic/bow)
/datum/export/weapon/arrows
cost = 150
unit_name = "arrow"
export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ashen)
/datum/export/weapon/bow_teaching
cost = 500
unit_name = "stone tablets"
export_types = list(/obj/item/book/granter/crafting_recipe/bone_bow)
/datum/export/weapon/quiver
cost = 100
unit_name = "quiver"
export_types = list(/obj/item/storage/belt/quiver)
/////////////////////////
//The Traitor Sell Outs//
/////////////////////////
+1 -1
View File
@@ -97,7 +97,7 @@
var/canBeacon = beacon && (isturf(beacon.loc) || ismob(beacon.loc))//is the beacon in a valid location?
var/list/data = list()
data["locked"] = locked//swipe an ID to unlock
data["siliconUser"] = user.has_unlimited_silicon_privilege
data["siliconUser"] = hasSiliconAccessInArea(user)
data["beaconzone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui
data["usingBeacon"] = usingBeacon //is the mode set to deliver to the beacon or the cargobay?
data["canBeacon"] = !usingBeacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location?
+1 -1
View File
@@ -2,7 +2,7 @@
var/name = "Crate"
var/group = ""
var/hidden = FALSE //Aka emag only
var/contraband = FALSE //Hacking the console with a multitool
var/contraband = FALSE //Requires a hacked console UNLESS DropPodOnly = TRUE, in which case it requires an emag
var/cost = 700 // Minimum cost, or infinite points are possible.
var/access = FALSE //What access does the Crate itself need?
var/access_any = FALSE //Do we care about access?
+3 -4
View File
@@ -178,7 +178,7 @@
/datum/supply_pack/security/armory/russian
name = "Russian Surplus Crate"
desc = "Hello Comrade, we have the most modern russian military equipment the black market can offer, for the right price of course. Sadly we couldnt remove the lock so it requires Armory access to open."
cost = 5000
cost = 7500
contraband = TRUE
contains = list(/obj/item/reagent_containers/food/snacks/rationpack,
/obj/item/ammo_box/a762,
@@ -192,12 +192,11 @@
/obj/item/clothing/mask/russian_balaclava,
/obj/item/clothing/head/helmet/rus_ushanka,
/obj/item/clothing/suit/armor/vest/russian_coat,
/obj/item/gun/ballistic/shotgun/boltaction,
/obj/item/gun/ballistic/shotgun/boltaction)
crate_name = "surplus military crate"
/datum/supply_pack/security/armory/russian/fill(obj/structure/closet/crate/C)
for(var/i in 1 to 10)
for(var/i in 1 to 5)
var/item = pick(contains)
new item(C)
@@ -218,7 +217,7 @@
crate_name = "swat crate"
/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
name = "SWAT tatical tasers Crate"
name = "SWAT tactical tasers Crate"
desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
cost = 7000
contains = list(/obj/item/gun/energy/e_gun/stun,
@@ -63,6 +63,7 @@
/obj/item/toy/cards/deck/syndicate,
/obj/item/reagent_containers/food/drinks/bottle/absinthe,
/obj/item/clothing/under/syndicate/tacticool,
/obj/item/clothing/under/syndicate/skirt,
/obj/item/clothing/under/syndicate,
/obj/item/suppressor,
/obj/item/storage/fancy/cigarettes/cigpack_syndicate,
+1 -1
View File
@@ -130,7 +130,7 @@
/datum/supply_pack/emergency/bomb
name = "Explosive Emergency Crate"
desc = "Science gone bonkers? Beeping behind the airlock? Buy now and be the hero the station des... I mean needs! (Time not included.)"
desc = "Science gone bonkers? Beeping behind the airlock? Buy now and become the hero the station des... I mean needs! Time not included, but a full bomb suit and hood, as well as a mask and defusal kit are! Non-Nuclear ordnances only."
cost = 1500
contains = list(/obj/item/clothing/head/bomb_hood,
/obj/item/clothing/suit/bomb_suit,
+2 -1
View File
@@ -88,6 +88,7 @@
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/space/hardsuit/medical)
crate_name = "medical hardsuit"
crate_type = /obj/structure/closet/crate/secure/medical
/datum/supply_pack/medical/supplies
name = "Medical Supplies Crate"
@@ -125,7 +126,7 @@
/obj/item/reagent_containers/medspray/synthflesh,
/obj/item/reagent_containers/medspray/sterilizine)
crate_name = "medco surgery tools"
crate_type = /obj/structure/closet/crate/medical
crate_type = /obj/structure/closet/crate/secure/medical
/datum/supply_pack/medical/surgery
name = "Surgical Supplies Crate"
+2 -1
View File
@@ -193,6 +193,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/bear,
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
/obj/item/reagent_containers/food/snacks/meat/slab/spider,
/obj/item/reagent_containers/food/snacks/meat/rawcrab,
/obj/item/reagent_containers/food/snacks/meat/rawbacon,
/obj/item/reagent_containers/food/snacks/spiderleg,
/obj/item/reagent_containers/food/snacks/carpmeat,
@@ -327,7 +328,7 @@
/datum/supply_pack/organic/seeds
name = "Seeds Crate"
desc = "Big things have small beginnings. Contains thirteen different seeds."
desc = "Big things have small beginnings. Contains fourteen different seeds."
cost = 1250
contains = list(/obj/item/seeds/chili,
/obj/item/seeds/berry,
+4 -4
View File
@@ -84,7 +84,7 @@
/datum/supply_pack/science/glasswork
name = "Glass Blower Kit Crate"
desc = "Learn and make glassworks of usefull things for a profit! Contains glassworking tools and blowing rods. Glass not included."
desc = "Learn and make glassworks of useful things for a profit! Contains glassworking tools and blowing rods. Glass not included."
cost = 1000
contains = list(/obj/item/glasswork/glasskit,
/obj/item/glasswork/glasskit,
@@ -111,9 +111,9 @@
/datum/supply_pack/science/nuke_b_gone
name = "Nuke Defusal Kit"
desc = "Contains set of tools to defuse a nuke."
cost = 7500 //Usefull for traitors/nukies that fucked up
cost = 7500 //Useful for traitors/nukies that fucked up
dangerous = TRUE
DropPodOnly = TRUE
hidden = TRUE
contains = list(/obj/item/nuke_core_container/nt,
/obj/item/screwdriver/nuke/nt,
/obj/item/paper/guides/nt/nuke_instructions)
@@ -194,7 +194,7 @@
/datum/supply_pack/science/supermater
name = "Supermatter Extraction Tools Crate"
desc = "Contains a set of tools to extract a sliver of supermatter. Consult your CE today!"
cost = 7500 //Usefull for traitors that fucked up
cost = 7500 //Useful for traitors that fucked up
hidden = TRUE
contains = list(/obj/item/nuke_core_container/supermatter,
/obj/item/scalpel/supermatter,
+1 -1
View File
@@ -103,7 +103,7 @@
desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip."
contraband = TRUE
access = FALSE
cost = 5500 //
cost = 6500 //
contains = list(/obj/item/clothing/suit/armor/navyblue/russian,
/obj/item/clothing/shoes/combat,
/obj/item/clothing/head/ushanka,
+3 -3
View File
@@ -737,13 +737,13 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
message_admins("<span class='adminnotice'>Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.</span>")
ip_intel = res.intel
/client/Click(atom/object, atom/location, control, params)
/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE)
var/ab = FALSE
var/list/L = params2list(params)
if (object && object == middragatom && L["left"])
ab = max(0, 5 SECONDS-(world.time-middragtime)*0.1)
var/mcl = CONFIG_GET(number/minute_click_limit)
if (!holder && mcl)
if (!holder && !ignore_spam && mcl)
var/minute = round(world.time, 600)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
@@ -768,7 +768,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
return
var/scl = CONFIG_GET(number/second_click_limit)
if (!holder && scl)
if (!holder && !ignore_spam && scl)
var/second = round(world.time, 10)
if (!clicklimiter)
clicklimiter = new(LIMITER_SIZE)
@@ -319,7 +319,7 @@
/obj/machinery/icecream_vat/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
+1 -1
View File
@@ -6,7 +6,7 @@
var/preferred_form = null
if(IsAdminGhost(src))
has_unlimited_silicon_privilege = 1
silicon_privileges = ALL
if(client.prefs.unlock_content)
preferred_form = client.prefs.ghost_form
+3
View File
@@ -987,3 +987,6 @@
return TRUE
if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS))
return TRUE
/mob/living/carbon/can_hold_items()
return TRUE
@@ -823,9 +823,6 @@
. += dna.species.check_weakness(weapon, attacker)
/mob/living/carbon/human/is_literate()
return 1
/mob/living/carbon/human/can_hold_items()
return TRUE
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
@@ -834,7 +831,7 @@
..()
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
if(blood && (NOBLOOD in dna.species.species_traits))
if(blood && dna?.species && (NOBLOOD in dna.species.species_traits))
if(message)
visible_message("<span class='warning'>[src] dry heaves!</span>", \
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
@@ -20,7 +20,7 @@
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type)
if(!d_type)
if(!d_type || !def_zone)
return 0
var/protection = 0
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
@@ -71,14 +71,42 @@
if(/obj/item/projectile/energy/florayield)
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
/datum/species/pod/pseudo_weak
name = "Anthromorphic Plant"
id = "podweak"
limbs_id = "pod"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "legs")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
limbs_id = "pod"
light_nutrition_gain_factor = 7.5
light_bruteheal = 0.2
light_burnheal = 0.2
light_toxheal = 0.7
/datum/species/pod/pseudo_weak/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
stop_wagging_tail(H)
/datum/species/pod/pseudo_weak/spec_stun(mob/living/carbon/human/H,amount)
if(H)
stop_wagging_tail(H)
. = ..()
/datum/species/pod/pseudo_weak/can_wag_tail(mob/living/carbon/human/H)
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
/datum/species/pod/pseudo_weak/is_wagging_tail(mob/living/carbon/human/H)
return ("mam_waggingtail" in mutant_bodyparts)
/datum/species/pod/pseudo_weak/start_wagging_tail(mob/living/carbon/human/H)
if("mam_tail" in mutant_bodyparts)
mutant_bodyparts -= "mam_tail"
mutant_bodyparts |= "mam_waggingtail"
H.update_body()
/datum/species/pod/pseudo_weak/stop_wagging_tail(mob/living/carbon/human/H)
if("mam_waggingtail" in mutant_bodyparts)
mutant_bodyparts -= "mam_waggingtail"
mutant_bodyparts |= "mam_tail"
H.update_body()
+1 -1
View File
@@ -72,7 +72,7 @@
put_in_hands(I)
update_inv_hands()
if(SLOT_IN_BACKPACK)
if(!SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
if(!back || !SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE))
not_handled = TRUE
else
not_handled = TRUE
+3 -3
View File
@@ -357,8 +357,8 @@
if(istype(loc, /obj/structure/closet/crate/coffin)|| istype(loc, /obj/structure/closet/body_bag) || istype(loc, /obj/structure/bodycontainer))
return
// No decay if formaldehyde in corpse or when the corpse is charred
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK))
// No decay if formaldehyde/preservahyde in corpse or when the corpse is charred
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || HAS_TRAIT(src, TRAIT_HUSK) || reagents.has_reagent(/datum/reagent/preservahyde, 1))
return
// Also no decay if corpse chilled or not organic/undead
@@ -397,7 +397,7 @@
if(O)
O.on_life()
else
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1)) // No organ decay if the body contains formaldehyde.
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/preservahyde, 1)) // No organ decay if the body contains formaldehyde. Or preservahyde.
return
for(var/V in internal_organs)
var/obj/item/organ/O = V
@@ -11,6 +11,7 @@
health = 500
maxHealth = 500
layer = BELOW_MOB_LAYER
silicon_privileges = PRIVILEDGES_PAI
var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held.
var/network = "ss13"
+1 -1
View File
@@ -1,6 +1,6 @@
/mob/living/silicon
gender = NEUTER
has_unlimited_silicon_privilege = 1
silicon_privileges = PRIVILEDGES_SILICON
verb_say = "states"
verb_ask = "queries"
verb_exclaim = "declares"
@@ -15,7 +15,7 @@
maxbodytemp = INFINITY
minbodytemp = 0
blood_volume = 0
has_unlimited_silicon_privilege = 1
silicon_privileges = PRIVILEDGES_BOT
sentience_type = SENTIENCE_ARTIFICIAL
status_flags = NONE //no default canpush
verb_say = "states"
@@ -194,10 +194,12 @@
if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again.
locked = FALSE
emagged = 1
to_chat(user, "<span class='notice'>You bypass [src]'s controls.</span>")
if(user)
to_chat(user, "<span class='notice'>You bypass [src]'s controls.</span>")
return TRUE
if(!open)
to_chat(user, "<span class='warning'>You need to open maintenance panel first!</span>")
if(user)
to_chat(user, "<span class='warning'>You need to open maintenance panel first!</span>")
return
emagged = 2
remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel.
@@ -205,7 +207,8 @@
bot_reset()
turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP.
to_chat(src, "<span class='userdanger'>(#$*#$^^( OVERRIDE DETECTED</span>")
log_combat(user, src, "emagged")
if(user)
log_combat(user, src, "emagged")
return TRUE
/mob/living/simple_animal/bot/examine(mob/user)
@@ -123,7 +123,8 @@
emagged = TRUE
if(!open)
locked = !locked
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src]'s controls!</span>")
if(user)
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src]'s controls!</span>")
flick("mulebot-emagged", src)
playsound(src, "sparks", 100, FALSE)
@@ -180,7 +181,7 @@
var/list/data = list()
data["on"] = on
data["locked"] = locked
data["siliconUser"] = user.has_unlimited_silicon_privilege
data["siliconUser"] = hasSiliconAccessInArea(usr)
data["mode"] = mode ? mode_name[mode] : "Ready"
data["modeStatus"] = ""
switch(mode)
@@ -205,11 +206,12 @@
return data
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
if(..() || (locked && !usr.has_unlimited_silicon_privilege))
var/silicon_access = hasSiliconAccessInArea(usr)
if(..() || (locked && silicon_access))
return
switch(action)
if("lock")
if(usr.has_unlimited_silicon_privilege)
if(silicon_access)
locked = !locked
. = TRUE
if("power")
@@ -766,4 +768,3 @@
/obj/machinery/bot_core/mulebot
req_access = list(ACCESS_CARGO)
@@ -41,7 +41,7 @@
bubble_icon = "machine"
initial_language_holder = /datum/language_holder/drone
mob_size = MOB_SIZE_SMALL
has_unlimited_silicon_privilege = 1
silicon_privileges = PRIVILEDGES_DRONE
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
unique_name = TRUE
@@ -126,7 +126,7 @@
// This loop will, at most, loop twice.
for(var/atom/check in check_list)
for(var/mob/living/M in viewers(world.view + 1, check) - src)
if(M.client && CanAttack(M) && !M.has_unlimited_silicon_privilege)
if(M.client && CanAttack(M) && !M.silicon_privileges)
if(!M.eye_blind)
return M
for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you
+1 -1
View File
@@ -95,7 +95,7 @@
var/digitalinvis = 0 //Are they ivisible to the AI?
var/image/digitaldisguise = null //what does the AI see instead of them?
var/has_unlimited_silicon_privilege = 0 // Can they interact with station electronics
var/silicon_privileges = NONE // Can they interact with station electronics
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
var/atom/movable/remote_control //Calls relaymove() to whatever it is
+3 -3
View File
@@ -406,8 +406,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
return
return TRUE
/atom/proc/hasSiliconAccessInArea(mob/user)
return user && (issilicon(user) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas)))
/atom/proc/hasSiliconAccessInArea(mob/user, flags = PRIVILEDGES_SILICON)
return user.silicon_privileges & (flags) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas))
/mob/proc/toggleSiliconAccessArea(area/area)
if (area in siliconaccessareas)
@@ -555,4 +555,4 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
//Can the mob see reagents inside of containers?
/mob/proc/can_see_reagents()
return stat == DEAD || has_unlimited_silicon_privilege //Dead guys and silicons can always see reagents
return stat == DEAD || silicon_privileges //Dead guys and silicons can always see reagents
+2 -2
View File
@@ -5,7 +5,7 @@
return "Default Implementation"
/datum/proc/oui_canuse(mob/user)
if(isobserver(user) && !user.has_unlimited_silicon_privilege)
if(isobserver(user) && !user.silicon_privileges)
return FALSE
return oui_canview(user)
@@ -35,7 +35,7 @@
return ..()
/obj/machinery/oui_canview(mob/user)
if(user.has_unlimited_silicon_privilege || hasSiliconAccessInArea(user))
if(hasSiliconAccessInArea(user, ALL))
return TRUE
if(!can_interact(user))
return FALSE
+7 -7
View File
@@ -846,7 +846,7 @@
return
/obj/machinery/power/apc/oui_canview(mob/user)
if(user.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(user))
if(area.hasSiliconAccessInArea(user)) //some APCs are mapped outside their assigned area, so this is required.
return TRUE
return ..()
@@ -864,7 +864,7 @@
if (H && !H.stealthmode && H.toggled)
abilitiesavail = TRUE
var/list/data = list(
"locked" = locked && !(integration_cog && is_servant_of_ratvar(user)) && !area.hasSiliconAccessInArea(user),
"locked" = locked && !(integration_cog && is_servant_of_ratvar(user)) && !area.hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE),
"lock_nightshift" = nightshift_requires_auth,
"failTime" = failure_timer,
"isOperating" = operating,
@@ -874,7 +874,7 @@
"chargingStatus" = charging,
"totalLoad" = DisplayPower(lastused_total),
"coverLocked" = coverlocked,
"siliconUser" = user.has_unlimited_silicon_privilege || user.using_power_flow_console() || area.hasSiliconAccessInArea(user),
"siliconUser" = user.using_power_flow_console() || area.hasSiliconAccessInArea(user),
"malfStatus" = get_malf_status(user),
"emergencyLights" = !emergency_lights,
"nightshiftLights" = nightshift_lights,
@@ -951,7 +951,7 @@
return TRUE
if (user == hijacker || (area.hasSiliconAccessInArea(user) && !aidisabled))
return TRUE
if(user.has_unlimited_silicon_privilege)
if(user.silicon_privileges & PRIVILEDGES_SILICON)
var/mob/living/silicon/ai/AI = user
var/mob/living/silicon/robot/robot = user
if (src.aidisabled || malfhack && istype(malfai) && ((istype(AI) && (malfai!=AI && malfai != AI.parent)) || (istype(robot) && (robot in malfai.connected_robots))))
@@ -985,7 +985,7 @@
if (action == "hijack" && can_use(usr, 1)) //don't need auth for hijack button
hijack(usr)
return
var/authorized = (!locked || usr.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(usr) || (integration_cog && (is_servant_of_ratvar(usr))))
var/authorized = (!locked || area.hasSiliconAccessInArea(usr, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE) || (integration_cog && (is_servant_of_ratvar(usr))))
if((action == "toggle_nightshift") && (!nightshift_requires_auth || authorized))
toggle_nightshift_lights()
return TRUE
@@ -993,7 +993,7 @@
return
switch(action)
if("lock")
if(usr.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(usr))
if(area.hasSiliconAccessInArea(usr))
if((obj_flags & EMAGGED) || (stat & (BROKEN|MAINT)))
to_chat(usr, "The APC does not respond to the command.")
else
@@ -1027,7 +1027,7 @@
update()
return TRUE
if("overload")
if(usr.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(usr))
if(area.hasSiliconAccessInArea(usr))
overload_lighting()
return TRUE
if("hack")
+13 -14
View File
@@ -24,7 +24,16 @@
/obj/machinery/power/solar/Initialize(mapload, obj/item/solar_assembly/S)
. = ..()
Make(S)
if(!S)
assembly = new /obj/item/solar_assembly
assembly.glass_type = new /obj/item/stack/sheet/glass(null, 2)
assembly.anchored = TRUE
else
S.moveToNullspace()
assembly = S
assembly.glass_type.on_solar_construction(src)
obj_integrity = max_integrity
update_icon()
connect_to_network()
/obj/machinery/power/solar/Destroy()
@@ -45,17 +54,6 @@
control.connected_panels.Remove(src)
control = null
/obj/machinery/power/solar/proc/Make(obj/item/solar_assembly/S)
if(!S)
S = new /obj/item/solar_assembly
S.glass_type = new /obj/item/stack/sheet/glass(null, 2)
S.anchored = TRUE
else
S.moveToNullspace()
S.glass_type.on_solar_construction(src)
obj_integrity = max_integrity
update_icon()
/obj/machinery/power/solar/crowbar_act(mob/user, obj/item/I)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("[user] begins to take the glass off [src].", "<span class='notice'>You begin to take the glass off [src]...</span>")
@@ -201,7 +199,7 @@
new shard(Tsec)
new shard(Tsec)
else if(glass_type)
forceMove(glass_type, Tsec)
glass_type.forceMove(Tsec)
glass_type = null
/obj/item/solar_assembly/attackby(obj/item/W, mob/user, params)
@@ -226,7 +224,8 @@
var/obj/item/stack/sheet/G = S.change_stack(null, 2)
if(G)
glass_type = G
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
G.moveToNullspace()
playsound(loc, 'sound/machines/click.ogg', 50, 1)
user.visible_message("[user] places the glass on the solar assembly.", "<span class='notice'>You place the glass on the solar assembly.</span>")
if(tracker)
new /obj/machinery/power/tracker(get_turf(src), src)
+9 -11
View File
@@ -20,7 +20,15 @@
/obj/machinery/power/tracker/Initialize(mapload, obj/item/solar_assembly/S)
. = ..()
Make(S)
if(!S)
assembly = new /obj/item/solar_assembly
assembly.glass_type = new /obj/item/stack/sheet/glass(null, 2)
assembly.tracker = TRUE
assembly.anchored = TRUE
else
S.moveToNullspace()
assembly = S
update_icon()
connect_to_network()
/obj/machinery/power/tracker/Destroy()
@@ -41,16 +49,6 @@
control.connected_tracker = null
control = null
/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
if(!S)
S = new /obj/item/solar_assembly
S.glass_type = new /obj/item/stack/sheet/glass(null, 2)
S.tracker = TRUE
S.anchored = TRUE
else
S.moveToNullspace()
update_icon()
//updates the tracker icon and the facing angle for the control computer
/obj/machinery/power/tracker/proc/set_angle(angle)
sun_angle = angle
@@ -5,4 +5,22 @@
caliber = "arrow"
icon_state = "arrow"
throwforce = 3 //good luck hitting someone with the pointy end of the arrow
throw_speed = 3
throw_speed = 3
/obj/item/ammo_casing/caseless/arrow/ashen
name = "ashen arrow"
desc = "Fire harderned wooden arrow."
icon_state = "asharrow"
projectile_type = /obj/item/projectile/bullet/reusable/arrow/ashen
/obj/item/ammo_casing/caseless/arrow/bone
name = "bone arrow"
desc = "Arrow made of bone and sinew. The tip is sharp enough to pierce into a goliath plate."
icon_state = "bonearrow"
projectile_type = /obj/item/projectile/bullet/reusable/arrow/bone
/obj/item/ammo_casing/caseless/arrow/bronze
name = "bronze arrow"
desc = "Bronze tipped arrow."
icon_state = "bronzearrow"
projectile_type = /obj/item/projectile/bullet/reusable/arrow/bronze
+16 -1
View File
@@ -50,4 +50,19 @@
icon_state = "bow_[get_ammo() ? (chambered ? "firing" : "loaded") : "unloaded"]"
/obj/item/gun/ballistic/bow/can_shoot()
return chambered
return chambered
/obj/item/gun/ballistic/bow/ashen
name = "bone bow"
desc = "Some sort of primitive projectile weapon made of bone and sinew. Used to fire arrows."
icon_state = "ashenbow"
item_state = "ashenbow"
force = 8
/obj/item/gun/ballistic/bow/pipe
name = "pipe bow"
desc = "Some sort of pipe made projectile weapon made of a silk string and lots of bending. Used to fire arrows."
icon_state = "pipebow"
item_state = "pipebow"
inaccuracy_modifier = 1.1 //Made of pipe and in a rush
force = 0
+2 -1
View File
@@ -67,7 +67,8 @@
/obj/item/gun/energy/Destroy()
if(flags_1 & INITIALIZED_1)
QDEL_NULL(cell)
QDEL_LIST(ammo_type)
if(!(flags_1 & HOLOGRAM_1)) //holodeck stuff.
QDEL_LIST(ammo_type)
STOP_PROCESSING(SSobj, src)
return ..()
+5 -6
View File
@@ -52,7 +52,6 @@
var/hitscan = FALSE //Whether this is hitscan. If it is, speed is basically ignored.
var/list/beam_segments //assoc list of datum/point or datum/point/vector, start = end. Used for hitscan effect generation.
var/datum/point/beam_index
var/turf/hitscan_last //last turf touched during hitscanning.
var/tracer_type
var/muzzle_type
var/impact_type
@@ -492,8 +491,6 @@
process_homing()
var/forcemoved = FALSE
for(var/i in 1 to SSprojectiles.global_iterations_per_move)
if(QDELETED(src))
return
trajectory.increment(trajectory_multiplier)
var/turf/T = trajectory.return_turf()
if(!istype(T))
@@ -506,14 +503,16 @@
forceMove(T)
trajectory_ignore_forcemove = FALSE
after_z_change(old, loc)
forcemoved = TRUE
if(QDELETED(src))
return
if(!hitscanning)
pixel_x = trajectory.return_px()
pixel_y = trajectory.return_py()
forcemoved = TRUE
hitscan_last = loc
else if(T != loc)
step_towards(src, T)
hitscan_last = loc
if(QDELETED(src))
return
if(!hitscanning && !forcemoved)
pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move
pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move
@@ -7,10 +7,11 @@
var/zap_range = 3
var/power = 10000
/obj/item/projectile/energy/tesla/fire(setAngle)
if(firer)
chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
..()
/obj/item/projectile/energy/tesla/fire(setAngle, atom/direct_target)
var/atom/source = fired_from || firer
if(source)
chain = source.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
return ..()
/obj/item/projectile/energy/tesla/on_hit(atom/target)
. = ..()
@@ -3,4 +3,23 @@
desc = "Woosh!"
damage = 15
icon_state = "arrow"
ammo_type = /obj/item/ammo_casing/caseless/arrow
ammo_type = /obj/item/ammo_casing/caseless/arrow
/obj/item/projectile/bullet/reusable/arrow/ashen
name = "ashen arrow"
desc = "Fire harderned arrow."
damage = 25
ammo_type = /obj/item/ammo_casing/caseless/arrow/ashen
/obj/item/projectile/bullet/reusable/arrow/bone //AP for ashwalkers
name = "bone arrow"
desc = "Arrow made of bone and sinew."
damage = 35
armour_penetration = 40
ammo_type = /obj/item/ammo_casing/caseless/arrow/bone
/obj/item/projectile/bullet/reusable/arrow/bronze //Just some AP shots
name = "bronze arrow"
desc = "Bronze tipped arrow."
armour_penetration = 10
ammo_type = /obj/item/ammo_casing/caseless/arrow/bronze
@@ -408,7 +408,7 @@
if(beaker)
var/obj/item/reagent_containers/B = beaker
B.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(B)
if(new_beaker)
beaker = new_beaker
@@ -38,7 +38,7 @@
/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
@@ -129,7 +129,7 @@
if(beaker)
var/obj/item/reagent_containers/B = beaker
B.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(B)
if(new_beaker)
beaker = new_beaker
@@ -139,7 +139,7 @@
if(bottle)
var/obj/item/storage/pill_bottle/B = bottle
B.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(B)
else
adjust_item_drop_location(B)
@@ -192,7 +192,7 @@
update_icon()
var/turf/source_turf = get_turf(src)
log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]")
. = TRUE
if("create_vaccine_bottle")
wait = TRUE
@@ -202,9 +202,9 @@
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[D.name] vaccine bottle"
B.reagents.add_reagent(/datum/reagent/vaccine, 15, list(id))
update_icon()
. = TRUE
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
@@ -229,7 +229,7 @@
/obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
if(!user.put_in_hands(beaker))
beaker.forceMove(drop_location())
if(new_beaker)
@@ -75,7 +75,7 @@
/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
@@ -1482,14 +1482,14 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
/datum/reagent/medicine/polypyr //This is intended to be an ingredient in advanced chems.
name = "Polypyrylium Oligomers"
description = "Apurple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals."
description = "A purple mixture of short polyelectrolyte chains not easily synthesized in the laboratory. It is valued as an intermediate in the synthesis of the cutting edge pharmaceuticals."
reagent_state = SOLID
color = "#9423FF"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 50
taste_description = "numbing bitterness"
/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wnted a collection of small positive effects, this is as hard to obtain as coniine after all.
/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all.
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25)
M.adjustBruteLoss(-0.35, 0)
if(prob(50))
@@ -1511,4 +1511,3 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5)
..()
. = 1
@@ -2108,3 +2108,10 @@
to_chat(M, "<span class='userlove'>You feel like playing with your [G.name]!</span>")
..()
/datum/reagent/preservahyde
name = "Preservahyde"
description = "A powerful preservation agent, utilizing the preservative effects of formaldehyde with significantly less of the histamine."
reagent_state = LIQUID
color = "#f7685e"
metabolization_rate = REAGENTS_METABOLISM * 0.25
@@ -504,7 +504,7 @@
toxpwr = 0
/datum/reagent/toxin/itching_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
if((method == TOUCH || method == VAPOR) && M.reagents)
M.reagents.add_reagent(/datum/reagent/toxin/itching_powder, reac_volume)
/datum/reagent/toxin/itching_powder/on_mob_life(mob/living/carbon/M)
@@ -47,6 +47,12 @@
results = list(/datum/reagent/consumable/sodiumchloride = 3)
required_reagents = list(/datum/reagent/water = 1, /datum/reagent/sodium = 1, /datum/reagent/chlorine = 1)
/datum/chemical_reaction/preservahyde
name = "Preservahyde"
id = "preservahyde"
results = list(/datum/reagent/preservahyde = 3)
required_reagents = list(/datum/reagent/water = 1, /datum/reagent/toxin/formaldehyde = 1, /datum/reagent/bromine = 1)
/datum/chemical_reaction/plasmasolidification
name = "Solid Plasma"
id = "solidplasma"
@@ -431,4 +431,4 @@
/obj/item/reagent_containers/glass/bottle/hexacamphor
name = "Hexacamphor bottle"
desc = "A bottle of strong anaphrodisiac. Reduces libido."
list_reagents = list(/datum/reagent/drug/anaphrodisiacplus = 30)
list_reagents = list(/datum/reagent/drug/anaphrodisiacplus = 30)
@@ -95,7 +95,7 @@
ignore_flags = 1 //so you can medipen through hardsuits
reagent_flags = DRAWABLE
flags_1 = null
list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/toxin/formaldehyde = 3)
list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3)
/obj/item/reagent_containers/hypospray/medipen/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins to choke on \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -3,7 +3,7 @@
///////////////////////////////////
/datum/design/milk
name = "10 Milk"
name = "10u Milk"
id = "milk"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 20)
@@ -11,7 +11,7 @@
category = list("initial","Food")
/datum/design/cream
name = "10 Cream"
name = "10u Cream"
id = "cream"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 30)
@@ -123,6 +123,22 @@
build_path = /obj/item/reagent_containers/glass/bottle/killer/pestkiller
category = list("initial","Botany Chemicals")
/datum/design/ammonia
name = "10u Ammonia"
id = "ammonia_biogen"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 25)
make_reagents = list(/datum/reagent/ammonia = 10)
category = list("initial","Botany Chemicals")
/datum/design/saltpetre
name = "10u Saltpetre"
id = "saltpetre_biogen"
build_type = BIOGENERATOR
materials = list(MAT_BIOMASS = 75)
make_reagents = list(/datum/reagent/saltpetre = 10)
category = list("initial","Botany Chemicals")
/datum/design/botany_bottle
name = "Empty Bottle"
id = "botany_bottle"
@@ -890,8 +890,8 @@ datum/status_effect/stabilized/blue/on_remove()
healing_types += TOX
if(owner.getCloneLoss() > 0)
healing_types += CLONE
owner.apply_damage_type(-heal_amount, damagetype=pick(healing_types))
if(length(healing_types))
owner.apply_damage_type(-heal_amount, damagetype=pick(healing_types))
owner.nutrition += 3
M.adjustCloneLoss(heal_amount * 1.2) //This way, two people can't just convert each other's damage away.
else
@@ -13,6 +13,7 @@
action_icon_state = "bloodcrawl"
action_background_icon_state = "bg_demon"
var/phased = 0
charge_max = 6
/obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr)
for(var/obj/effect/decal/cleanable/target in range(range, get_turf(user)))
+1 -1
View File
@@ -56,7 +56,7 @@
var/mob/living/carbon/human/H = C
H.eye_color = old_eye_color
if(!special)
H.dna.species.handle_body()
H.dna.species.handle_body(H)
if(!special)
C.update_tint()
C.update_sight()