Merge branch 'master' into upstream-merge-33590

This commit is contained in:
LetterJay
2017-12-25 21:29:18 -06:00
committed by GitHub
373 changed files with 2567 additions and 2775 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define ON_BORDER_1 512 // item has priority to check when entering or leaving
#define NOSLIP_1 1024 //prevents from slipping on wet floors, in space etc
#define CLEAN_ON_MOVE_1 2048
#define _UNUSED_1 2048
// BLOCK_GAS_SMOKE_EFFECT_1 only used in masks at the moment.
#define BLOCK_GAS_SMOKE_EFFECT_1 4096 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
+23 -11
View File
@@ -10,17 +10,29 @@
//mob disabilities stat
#define BLIND 1
#define MUTE 2
#define DEAF 4
#define NEARSIGHT 8
#define FAT 32
#define HUSK 64
#define NOCLONE 128
#define CLUMSY 256
#define DUMB 512
#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE
#define PACIFISM 2048
#define BLIND "blind"
#define MUTE "mute"
#define DEAF "deaf"
#define NEARSIGHT "nearsighted"
#define FAT "fat"
#define HUSK "husk"
#define NOCLONE "noclone"
#define CLUMSY "clumsy"
#define DUMB "dumb"
#define MONKEYLIKE "monkeylike" //sets IsAdvancedToolUser to FALSE
#define PACIFISM "pacifism"
// common disability sources
#define EYE_DAMAGE "eye_damage"
#define GENETIC_MUTATION "genetic"
#define STATUE_MUTE "statue"
#define CHANGELING_DRAIN "drain"
#define OBESITY "obesity"
#define MAGIC_DISABILITY "magic"
#define STASIS_MUTE "stasis"
#define GENETICS_SPELL "genetics_spell"
#define TRAUMA_DISABILITY "trauma"
// bitflags for machine stat variable
#define BROKEN 1
+12
View File
@@ -0,0 +1,12 @@
/datum/action/item_action/zoom_speed_action
name = "Toggle Zooming Speed"
icon_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "projectile"
background_icon_state = "bg_tech"
/datum/action/item_action/zoom_lock_action
name = "Switch Zoom Mode"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "zoom_mode"
background_icon_state = "bg_tech"
-2
View File
@@ -1,5 +1,3 @@
/datum/action/item_action/flightsuit
icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
+1 -1
View File
@@ -223,7 +223,7 @@
if(verbose)
to_chat(user, "<span class='warning'>[target] is not compatible with our biology.</span>")
return
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
if((target.has_disability(NOCLONE)) || (target.has_disability(NOCLONE)))
if(verbose)
to_chat(user, "<span class='warning'>DNA of [target] is ruined beyond usability!</span>")
return
+2 -2
View File
@@ -42,7 +42,7 @@
lose_text = "<span class='notice'>You feel smart again.</span>"
/datum/brain_trauma/mild/dumbness/on_gain()
owner.disabilities |= DUMB
owner.add_disability(DUMB, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/mild/dumbness/on_life()
@@ -54,7 +54,7 @@
..()
/datum/brain_trauma/mild/dumbness/on_lose()
owner.disabilities &= ~DUMB
owner.remove_disability(DUMB, TRAUMA_DISABILITY)
owner.derpspeech = 0
..()
+22 -19
View File
@@ -12,17 +12,11 @@
lose_text = "<span class='notice'>You suddenly remember how to speak.</span>"
/datum/brain_trauma/severe/mute/on_gain()
owner.disabilities |= MUTE
..()
//no fiddling with genetics to get out of this one
/datum/brain_trauma/severe/mute/on_life()
if(!(owner.disabilities & MUTE))
on_gain()
owner.add_disability(MUTE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/mute/on_lose()
owner.disabilities &= ~MUTE
owner.remove_disability(MUTE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/aphasia
@@ -56,17 +50,11 @@
lose_text = "<span class='notice'>Your vision returns.</span>"
/datum/brain_trauma/severe/blindness/on_gain()
owner.become_blind()
..()
//no fiddling with genetics to get out of this one
/datum/brain_trauma/severe/blindness/on_life()
if(!(owner.disabilities & BLIND))
on_gain()
owner.become_blind(TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/blindness/on_lose()
owner.cure_blind()
owner.cure_blind(TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/paralysis
@@ -132,7 +120,7 @@
stress -= 4
/datum/brain_trauma/severe/monophobia/proc/check_alone()
if(owner.disabilities & BLIND)
if(owner.has_disability(BLIND))
return TRUE
for(var/mob/M in oview(owner, 7))
if(!isliving(M)) //ghosts ain't people
@@ -194,11 +182,26 @@
lose_text = "<span class='notice'>You feel in control of your hands again.</span>"
/datum/brain_trauma/severe/discoordination/on_gain()
owner.disabilities |= MONKEYLIKE
owner.add_disability(MONKEYLIKE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/discoordination/on_lose()
owner.disabilities &= ~MONKEYLIKE
owner.remove_disability(MONKEYLIKE, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism
name = "Traumatic Non-Violence"
desc = "Patient is extremely unwilling to harm others in violent ways."
scan_desc = "pacific syndrome"
gain_text = "<span class='notice'>You feel oddly peaceful.</span>"
lose_text = "<span class='notice'>You no longer feel compelled to not harm.</span>"
/datum/brain_trauma/severe/pacifism/on_gain()
owner.add_disability(PACIFISM, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism/on_lose()
owner.remove_disability(PACIFISM, TRAUMA_DISABILITY)
..()
/datum/brain_trauma/severe/pacifism
+40
View File
@@ -0,0 +1,40 @@
/datum/component/cleaning
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
/datum/component/cleaning/Initialize()
if(!ismovableatom(parent))
. = COMPONENT_INCOMPATIBLE
CRASH("[type] added to a [parent.type]")
RegisterSignal(list(COMSIG_MOVABLE_MOVED), .proc/Clean)
/datum/component/cleaning/proc/Clean()
var/atom/movable/AM = parent
var/turf/tile = AM.loc
if(!isturf(tile))
return
tile.clean_blood()
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
cleaned_item.clean_blood()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
cleaned_human.wear_suit.clean_blood()
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.clean_blood()
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes()
cleaned_human.clean_blood()
cleaned_human.wash_cream()
to_chat(cleaned_human, "<span class='danger'>[AM] cleans your face!</span>")
@@ -58,11 +58,12 @@ Bonus
M.blur_eyes(20)
M.adjust_eye_damage(5)
if(eyes.eye_damage >= 10)
M.become_nearsighted()
M.become_nearsighted(EYE_DAMAGE)
if(prob(eyes.eye_damage - 10 + 1))
if(!remove_eyes)
if(M.become_blind())
if(!M.has_disability(BLIND))
to_chat(M, "<span class='userdanger'>You go blind!</span>")
M.become_blind(EYE_DAMAGE)
else
M.visible_message("<span class='warning'>[M]'s eyes fall off their sockets!</span>", "<span class='userdanger'>Your eyes fall off their sockets!</span>")
eyes.Remove(M)
@@ -111,16 +112,16 @@ Bonus
return
switch(A.stage)
if(4, 5) //basically oculine
if(M.disabilities & BLIND)
if(M.has_disability(BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, "<span class='warning'>Your vision slowly returns...</span>")
M.cure_blind()
M.cure_nearsighted()
M.cure_blind(EYE_DAMAGE)
M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(35)
else if(M.disabilities & NEARSIGHT)
else if(M.has_disability(NEARSIGHT, EYE_DAMAGE))
to_chat(M, "<span class='warning'>The blackness in your peripheral vision fades.</span>")
M.cure_nearsighted()
M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(10)
else if(M.eye_blind || M.eye_blurry)
+5 -15
View File
@@ -1,6 +1,6 @@
/datum/disease/gbs
name = "GBS"
max_stages = 5
max_stages = 4
spread_text = "On contact"
spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS
cure_text = "Synaptizine & Sulfur"
@@ -16,25 +16,15 @@
..()
switch(stage)
if(2)
if(prob(45))
affected_mob.adjustToxLoss(5)
affected_mob.updatehealth()
if(prob(1))
affected_mob.emote("sneeze")
if(3)
if(prob(5))
affected_mob.emote("cough")
else if(prob(5))
if(3)
if(prob(5))
affected_mob.emote("gasp")
if(prob(10))
to_chat(affected_mob, "<span class='danger'>You're starting to feel very weak...</span>")
to_chat(affected_mob, "<span class='danger'>Your body hurts all over!</span>")
if(4)
if(prob(10))
affected_mob.emote("cough")
affected_mob.adjustToxLoss(5)
affected_mob.updatehealth()
if(5)
to_chat(affected_mob, "<span class='danger'>Your body feels as if it's trying to rip itself open...</span>")
to_chat(affected_mob, "<span class='userdanger'>Your body feels as if it's trying to rip itself apart!</span>")
if(prob(50))
affected_mob.gib()
else
+2
View File
@@ -45,6 +45,8 @@
set name = "Show Server Revision"
set desc = "Check the current server code revision"
if(GLOB.round_id)
to_chat(src, "<b>Round ID:</b> [GLOB.round_id]")
if(GLOB.revdata.originmastercommit)
to_chat(src, "<b>Server revision compiled on:</b> [GLOB.revdata.date]")
var/prefix = ""
+1 -1
View File
@@ -197,7 +197,7 @@
/obj/item/twohanded/bostaff/attack(mob/target, mob/living/user)
add_fingerprint(user)
if((CLUMSY in user.disabilities) && prob(50))
if((user.has_disability(CLUMSY)) && prob(50))
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
user.Knockdown(60)
if(ishuman(user))
-1
View File
@@ -8,7 +8,6 @@ GLOBAL_LIST_EMPTY(mutations_list)
GLOB.mutations_list[name] = src
/datum/mutation/human
var/dna_block
var/quality
var/get_chance = 100
+4 -4
View File
@@ -85,12 +85,12 @@
/datum/mutation/human/clumsy/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.disabilities |= CLUMSY
owner.add_disability(CLUMSY, GENETIC_MUTATION)
/datum/mutation/human/clumsy/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.disabilities &= ~CLUMSY
owner.remove_disability(CLUMSY, GENETIC_MUTATION)
//Tourettes causes you to randomly stand in place and shout.
@@ -124,12 +124,12 @@
/datum/mutation/human/deaf/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.disabilities |= DEAF
owner.add_disability(DEAF, GENETIC_MUTATION)
/datum/mutation/human/deaf/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.disabilities &= ~DEAF
owner.remove_disability(DEAF, GENETIC_MUTATION)
//Monified turns you into a monkey.
+4 -4
View File
@@ -7,12 +7,12 @@
/datum/mutation/human/nearsight/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.become_nearsighted()
owner.become_nearsighted(GENETIC_MUTATION)
/datum/mutation/human/nearsight/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.cure_nearsighted()
owner.cure_nearsighted(GENETIC_MUTATION)
//Blind makes you blind. Who knew?
@@ -24,12 +24,12 @@
/datum/mutation/human/blind/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.become_blind()
owner.become_blind(GENETIC_MUTATION)
/datum/mutation/human/blind/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.cure_blind()
owner.cure_blind(GENETIC_MUTATION)
//X-Ray Vision lets you see through walls.
+2 -2
View File
@@ -30,12 +30,12 @@
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.disabilities |= MUTE
owner.add_disability(MUTE, GENETIC_MUTATION)
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.disabilities &= ~MUTE
owner.remove_disability(MUTE, GENETIC_MUTATION)
/datum/mutation/human/smile
+239
View File
@@ -0,0 +1,239 @@
//Designed for things that need precision trajectories like projectiles.
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
#define RETURN_PRECISE_POINT(A) new /datum/point(A)
/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
var/x = 0
var/y = 0
var/z = 0
var/pixel_x = 0
var/pixel_y = 0
/datum/position/proc/valid()
return x && y && z && !isnull(pixel_x) && !isnull(pixel_y)
/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point.
if(istype(_x, /datum/point))
var/datum/point/P = _x
var/turf/T = P.return_turf()
_x = T.x
_y = T.y
_z = T.z
_pixel_x = P.return_px()
_pixel_y = P.return_py()
else if(isatom(_x))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
x = _x
y = _y
z = _z
pixel_x = _pixel_x
pixel_y = _pixel_y
/datum/position/proc/return_turf()
return locate(x, y, z)
/datum/position/proc/return_px()
return pixel_x
/datum/position/proc/return_py()
return pixel_y
/datum/position/proc/return_point()
return new /datum/point(src)
/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
var/datum/point/P = new
P.x = round(a.x + (b.x - a.x) / 2, 1)
P.y = round(a.y + (b.y - a.y) / 2, 1)
P.z = a.z
return P
/proc/pixel_length_between_points(datum/point/a, datum/point/b)
return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2))
/proc/angle_between_points(datum/point/a, datum/point/b)
return ATAN2((b.y - a.y), (b.x - a.x))
/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
var/x = 0
var/y = 0
var/z = 0
/datum/point/proc/valid()
return x && y && z
/datum/point/proc/copy_to(datum/point/p = new)
p.x = x
p.y = y
p.z = z
return p
/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom.
if(istype(_x, /datum/position))
var/datum/position/P = _x
_x = P.x
_y = P.y
_z = P.z
_pixel_x = P.pixel_x
_pixel_y = P.pixel_y
else if(istype(_x, /atom))
var/atom/A = _x
_x = A.x
_y = A.y
_z = A.z
_pixel_x = A.pixel_x
_pixel_y = A.pixel_y
initialize_location(_x, _y, _z, _pixel_x, _pixel_y)
/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
if(!isnull(tile_x))
x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x
if(!isnull(tile_y))
y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2+ p_y
if(!isnull(tile_z))
z = tile_z
/datum/point/proc/return_turf()
return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_coordinates() //[turf_x, turf_y, z]
return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
/datum/point/proc/return_position()
return new /datum/position(src)
/datum/point/proc/return_px()
return MODULUS(x, world.icon_size) - 16
/datum/point/proc/return_py()
return MODULUS(y, world.icon_size) - 16
/datum/point/proc/mapcheck()
. = FALSE
var/maxx = world.icon_size * world.maxx
var/maxy = world.icon_size * world.maxy
var/move_zx = 0
var/move_zy = 0
if(x < 0)
x += maxx
move_zx -= 1
if(y < 0)
y += maxy
move_zy -= 1
if(x > maxx)
x -= maxx
move_zx += 1
if(y > maxy)
y -= maxy
move_zy += 1
var/datum/space_level/S = GLOB.z_levels_list["[z]"]
if(move_zx != 0)
var/datum/space_level/L = S.neigbours["[move_zx < 0? WEST : EAST]"]
z = L.z_value
. = TRUE
if(move_zy != 0)
var/datum/space_level/L = S.neigbours["[move_zy < 0? SOUTH : NORTH]"]
z = L.z_value
. = TRUE
/datum/point/vector
var/speed = 32 //pixels per iteration
var/iteration = 0
var/angle = 0
var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step.
var/mpy = 0
var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
var/starting_y = 0
var/starting_z = 0
/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed)
..()
initialize_trajectory(_speed, _angle)
/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
. = ..()
starting_x = x
starting_y = y
starting_z = z
/datum/point/vector/copy_to(datum/point/vector/v = new)
..(v)
v.speed = speed
v.iteration = iteration
v.angle = angle
v.mpx = mpx
v.mpy = mpy
v.starting_x = starting_x
v.starting_y = starting_y
v.starting_z = starting_z
return v
/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle)
if(!isnull(pixel_speed))
speed = pixel_speed
set_angle(new_angle)
/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270.
if(isnull(angle))
return
angle = new_angle
update_offsets()
/datum/point/vector/proc/update_offsets()
mpx = sin(angle) * speed
mpy = cos(angle) * speed
/datum/point/vector/proc/set_speed(new_speed)
if(isnull(new_speed) || speed == new_speed)
return
speed = new_speed
update_offsets()
/datum/point/vector/proc/increment(multiplier = 1)
iteration++
x += mpx * 1
y += mpy * 1
if(mapcheck())
on_z_change()
/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
var/datum/point/vector/v = copy_to()
if(force_simulate)
for(var/i in 1 to amount)
v.increment(multiplier)
else
v.increment(multiplier * amount)
return v
/datum/point/vector/proc/on_z_change()
return
/datum/point/vector/processed //pixel_speed is per decisecond.
var/last_process = 0
var/last_move = 0
var/paused = FALSE
/datum/point/vector/processed/Destroy()
STOP_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/proc/start()
last_process = world.time
last_move = world.time
START_PROCESSING(SSprojectiles, src)
/datum/point/vector/processed/process()
if(paused)
last_move += world.time - last_process
last_process = world.time
return
var/needed_time = world.time - last_move
last_process = world.time
last_move = world.time
increment(needed_time)
+1
View File
@@ -78,6 +78,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
QDEL_NULL(ghost_appearance)
/datum/atom_hud/alternate_appearance/basic/add_to_hud(atom/A)
LAZYINITLIST(A.hud_list)
A.hud_list[appearance_key] = theImage
. = ..()
-32
View File
@@ -132,44 +132,12 @@
if (orbiting)
orbiting.Check()
if(flags_1 & CLEAN_ON_MOVE_1)
clean_on_move()
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
if(proximity_monitor)
proximity_monitor.HandleMove()
return 1
/atom/movable/proc/clean_on_move()
var/turf/tile = loc
if(isturf(tile))
tile.clean_blood()
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
cleaned_item.clean_blood()
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
cleaned_human.wear_suit.clean_blood()
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.clean_blood()
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes()
cleaned_human.clean_blood()
cleaned_human.wash_cream()
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
/atom/movable/Destroy(force)
var/inform_admins = (flags_2 & INFORM_ADMINS_ON_RELOCATE_2)
var/stationloving = (flags_2 & STATIONLOVING_2)
@@ -55,12 +55,14 @@
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_handcuffs(mob/living/carbon/human/user, obj/O)
if(O && user.handcuffed == O)
user.visible_message("<span class='warning'>[O] dissolve[O.gender==PLURAL?"":"s"] into a puddle of sizzling goop.</span>")
user.uncuff()
new /obj/effect/decal/cleanable/greenglow(O.drop_location())
qdel(O)
/obj/effect/proc_holder/changeling/biodegrade/proc/dissolve_straightjacket(mob/living/carbon/human/user, obj/S)
if(S && user.wear_suit == S)
user.visible_message("<span class='warning'>[S] dissolves into a puddle of sizzling goop.</span>")
user.uncuff()
new /obj/effect/decal/cleanable/greenglow(S.drop_location())
qdel(S)
@@ -20,7 +20,7 @@
to_chat(user, "<span class='notice'>We prepare our sting, use alt+click or middle mouse button on target to sting them.</span>")
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.chosen_sting = src
user.hud_used.lingstingdisplay.icon_state = sting_icon
user.hud_used.lingstingdisplay.invisibility = 0
@@ -28,7 +28,7 @@
to_chat(user, "<span class='warning'>We retract our sting, we can't sting anyone for now.</span>")
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
changeling.chosen_sting = null
user.hud_used.lingstingdisplay.icon_state = null
user.hud_used.lingstingdisplay.invisibility = INVISIBILITY_ABSTRACT
@@ -90,7 +90,7 @@
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target)
if(!..())
return
if((target.disabilities & HUSK) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
if((target.has_disability(HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits))
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
@@ -129,9 +129,11 @@
/obj/effect/proc_holder/changeling/sting/false_armblade/can_sting(mob/user, mob/target)
if(!..())
return
if((target.disabilities & HUSK) || !target.has_dna())
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
if(isliving(target))
var/mob/living/L = target
if((L.has_disability(HUSK)) || !L.has_dna())
to_chat(user, "<span class='warning'>Our sting appears ineffective against its DNA.</span>")
return 0
return 1
/obj/effect/proc_holder/changeling/sting/false_armblade/sting_action(mob/user, mob/target)
@@ -207,7 +209,7 @@
/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
add_logs(user, target, "stung", "blind sting")
to_chat(target, "<span class='danger'>Your eyes burn horrifically!</span>")
target.become_nearsighted()
target.become_nearsighted(EYE_DAMAGE)
target.blind_eyes(20)
target.blur_eyes(40)
return TRUE
@@ -32,7 +32,7 @@
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
if(src == H.glasses && !up)
if(H.disabilities & BLIND)
if(H.has_disability(BLIND))
to_chat(H, "<span class='heavy_brass'>\"You're blind, idiot. Stop embarrassing yourself.\"</span>")
return
if(blind_cultist(H))
@@ -51,7 +51,7 @@
to_chat(victim, "<span class='heavy_brass'>\"It looks like Nar-Sie's dogs really don't value their eyes.\"</span>")
to_chat(victim, "<span class='userdanger'>Your eyes explode with horrific pain!</span>")
victim.emote("scream")
victim.become_blind()
victim.become_blind(EYE_DAMAGE)
victim.adjust_blurriness(30)
victim.adjust_blindness(30)
return TRUE
@@ -76,7 +76,7 @@
..()
if(slot != slot_glasses || up)
return
if(user.disabilities & BLIND)
if(user.has_disability(BLIND))
to_chat(user, "<span class='heavy_brass'>\"You're blind, idiot. Stop embarrassing yourself.\"</span>" )
return
if(blind_cultist(user)) //Cultists instantly go blind
@@ -115,11 +115,11 @@
var/obj/item/clothing/glasses/wraith_spectacles/WS = L.glasses
desc = "[glasses_right && !WS.up ? "<font color=#DAAA18><b>":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right && !WS.up ? "!</b></font>":"."]<br>\
You have taken <font color=#DAAA18><b>[W.eye_damage_done]</b></font> eye damage from them.<br>"
if(L.disabilities & NEARSIGHT)
if(L.has_disability(NEARSIGHT))
desc += "<font color=#DAAA18><b>You are nearsighted!</b></font><br>"
else if(glasses_right && !WS.up)
desc += "You will become nearsighted at <font color=#DAAA18><b>[W.nearsight_breakpoint]</b></font> eye damage.<br>"
if(L.disabilities & BLIND)
if(L.has_disability(BLIND))
desc += "<font color=#DAAA18><b>You are blind!</b></font>"
else if(glasses_right && !WS.up)
desc += "You will become blind at <font color=#DAAA18><b>[W.blind_breakpoint]</b></font> eye damage."
@@ -142,8 +142,8 @@
apply_eye_damage(H)
else
if(GLOB.ratvar_awakens)
H.cure_nearsighted()
H.cure_blind()
H.cure_nearsighted(list(EYE_DAMAGE))
H.cure_blind(list(EYE_DAMAGE))
H.adjust_eye_damage(-eye_damage_done)
eye_damage_done = 0
else if(prob(50) && eye_damage_done)
@@ -153,17 +153,20 @@
qdel(src)
/datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H)
if(H.disabilities & BLIND)
if(H.has_disability(BLIND))
return
H.adjust_eye_damage(0.5)
eye_damage_done += 0.5
if(eye_damage_done >= 20)
H.adjust_blurriness(2)
if(eye_damage_done >= nearsight_breakpoint)
if(H.become_nearsighted())
to_chat(H, "<span class='nzcrentr'>Your vision doubles, then trebles. Darkness begins to close in. You can't keep this up!</span>")
if(!H.has_disability(NEARSIGHT))
to_chat(H, "<span class='nzcrentr'>Your vision doubles, then trembles. Darkness begins to close in. You can't keep this up!</span>")
H.become_nearsighted(EYE_DAMAGE)
if(eye_damage_done >= blind_breakpoint)
if(H.become_blind())
if(!H.has_disability(BLIND))
to_chat(H, "<span class='nzcrentr_large'>A piercing white light floods your vision. Suddenly, all goes dark!</span>")
H.become_blind(EYE_DAMAGE)
if(prob(min(20, 5 + eye_damage_done)))
to_chat(H, "<span class='nzcrentr_small'><i>Your eyes continue to burn.</i></span>")
@@ -12,6 +12,7 @@
layer = FLY_LAYER
faction = list("ratvar")
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
var/turf/last_failed_turf
var/static/superheated_walls = 0
/mob/camera/eminence/CanPass(atom/movable/mover, turf/target)
@@ -20,7 +21,18 @@
/mob/camera/eminence/Move(NewLoc, direct)
var/OldLoc = loc
if(NewLoc && !istype(NewLoc, /turf/open/indestructible/reebe_void))
forceMove(get_turf(NewLoc))
var/turf/T = get_turf(NewLoc)
if(T.flags_1 & NOJAUNT_1)
if(last_failed_turf != T)
T.visible_message("<span class='warning'>[T] suddenly emits a ringing sound!</span>", ignore_mob = src)
playsound(T, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE)
last_failed_turf = T
to_chat(src, "<span class='warning'>This turf is consecrated and can't be crossed!</span>")
return
if(istype(get_area(T), /area/chapel))
to_chat(src, "<span class='warning'>The Chapel is hallowed ground under a heretical deity, and can't be accessed!</span>")
return
forceMove(T)
Moved(OldLoc, direct)
if(GLOB.ratvar_awakens)
for(var/turf/T in range(5, src))
@@ -110,7 +110,7 @@
if(!(BI.resistance_flags & ON_FIRE))
BI.fire_act()
continue
if(is_servant_of_ratvar(L) || (L.disabilities & BLIND) || L.null_rod_check())
if(is_servant_of_ratvar(L) || (L.has_disability(BLIND)) || L.null_rod_check())
continue
if(L.stat || L.restrained() || L.buckled || L.lying)
continue
+1 -1
View File
@@ -115,7 +115,7 @@ structure_check() searches for nearby cultist structures required for the invoca
continue
if(ishuman(L))
var/mob/living/carbon/human/H = L
if((H.disabilities & MUTE) || H.silent)
if((H.has_disability(MUTE)) || H.silent)
continue
if(L.stat)
continue
@@ -304,7 +304,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
sleep(30)
if(!owner || QDELETED(owner))
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE
+1 -1
View File
@@ -524,7 +524,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/list/otherwise = M.GetAllContents()
for(var/obj/item/disk/tech_disk/TD in otherwise)
TD.stored_research.copy_research_to(checking)
return checking.researched_nodes.len >= target
return checking.researched_nodes.len >= target_amount
/datum/objective/capture
@@ -300,6 +300,9 @@
else if(isspaceturf(T))
to_chat(user, "<span class='sevtug_small'>[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]</span>")
return
else if(T.flags_1 & NOJAUNT_1)
to_chat(user, "<span class='sevtug_small'>This tile is blessed by holy water and deflects the warp.</span>")
return
var/area/AR = get_area(T)
if(!AR.clockwork_warp_allowed)
to_chat(user, "<span class='sevtug_small'>[AR.clockwork_warp_fail]</span>")
+1 -1
View File
@@ -449,7 +449,7 @@
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2))
if((mob_occupant.has_disability(NOCLONE)) && (src.scanner.scan_level < 2))
scantemp = "<font class='bad'>Subject no longer contains the fundamental materials required to create a living clone.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
return
+2 -2
View File
@@ -81,7 +81,7 @@
if(connected && connected.is_operational())
if(connected.occupant) //set occupant_status message
viable_occupant = connected.occupant
if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupant is viable for dna modification
if(viable_occupant.has_dna() && (!(RADIMMUNE in viable_occupant.dna.species.species_traits)) && (!(viable_occupant.has_disability(NOCLONE)) || (connected.scan_level == 3))) //occupant is viable for dna modification
occupant_status += "[viable_occupant.name] => "
switch(viable_occupant.stat)
if(CONSCIOUS)
@@ -528,7 +528,7 @@
var/mob/living/carbon/viable_occupant = null
if(connected)
viable_occupant = connected.occupant
if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.disabilities & NOCLONE))
if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.has_disability(NOCLONE)))
viable_occupant = null
return viable_occupant
+1 -1
View File
@@ -100,7 +100,7 @@
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
if(istype(mob_occupant))
if(locate_computer(/obj/machinery/computer/cloning))
if(!mob_occupant.suiciding && !(mob_occupant.disabilities & NOCLONE) && !mob_occupant.hellbound)
if(!mob_occupant.suiciding && !(mob_occupant.has_disability(NOCLONE)) && !mob_occupant.hellbound)
mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)
// DNA manipulators cannot operate on severed heads or brains
+1 -4
View File
@@ -251,16 +251,13 @@
note = null
update_icon()
/obj/machinery/door/airlock/proc/unzap() //for addtimer
justzap = FALSE
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
if(!issilicon(usr))
if(isElectrified())
if(!justzap)
if(shock(user, 100))
justzap = TRUE
addtimer(CALLBACK(src, .proc/unzap), 10)
addtimer(VARSET_CALLBACK(src, justzap, FALSE) , 10)
return
else
return
+1 -1
View File
@@ -195,7 +195,7 @@
/obj/machinery/door/emp_act(severity)
if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, .proc/open)
if(prob(40/severity))
if(prob(severity*10 - 20))
if(secondsElectrified == 0)
secondsElectrified = -1
shockedby += "\[[time_stamp()]\]EM Pulse"
+97 -181
View File
@@ -25,8 +25,8 @@
integrity_failure = 100
armor = list(melee = 20, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70)
circuit = /obj/item/circuitboard/machine/vendor
var/active = 1 //No sales pitches if off!
var/vend_ready = 1 //Are we ready to vend?? Is it time??
var/active = TRUE //No sales pitches if off!
var/vend_ready = TRUE //Are we ready to vend?? Is it time??
// To be filled out at compile time
var/list/products = list() //For each, use the following pattern:
@@ -227,15 +227,15 @@
if(!allowed(user) && !emagged && scan_id)
to_chat(user, "<span class='warning'>[src]'s chef compartment blinks red: Access denied.</span>")
req_access_txt = "0"
return 0
return FALSE
req_access_txt = "0"
return 1
return TRUE
/obj/machinery/vending/snack/proc/iscompartmentfull(mob/user)
if(contents.len >= 30) // no more than 30 dishes can fit inside
to_chat(user, "<span class='warning'>[src]'s chef compartment is full.</span>")
return 1
return 0
return TRUE
return FALSE
/obj/machinery/vending/snack/proc/food_load(obj/item/reagent_containers/food/snacks/S)
if(dish_quants[S.name])
@@ -350,180 +350,6 @@
/obj/machinery/vending/attack_ai(mob/user)
return attack_hand(user)
/obj/machinery/vending/attack_hand(mob/user)
var/dat = ""
if(panel_open && !isAI(user))
return wires.interact(user)
else
if(stat & (BROKEN|NOPOWER))
return
dat += "<h3>Select an item</h3>"
dat += "<div class='statusDisplay'>"
if(product_records.len == 0)
dat += "<font color = 'red'>No product loaded!</font>"
else
var/list/display_records = product_records
if(extended_inventory)
display_records = product_records + hidden_records
if(coin || bill)
display_records = product_records + coin_records
if((coin || bill) && extended_inventory)
display_records = product_records + hidden_records + coin_records
dat += "<ul>"
for (var/datum/data/vending_product/R in display_records)
dat += "<li>"
if(R.amount > 0)
dat += "<a href='byond://?src=[REF(src)];vend=[REF(R)]'>Vend</a> "
else
dat += "<span class='linkOff'>Sold out</span> "
dat += "<font color = '[R.display_color]'><b>[sanitize(R.product_name)]</b>:</font>"
dat += " <b>[R.amount]</b>"
dat += "</li>"
dat += "</ul>"
dat += "</div>"
if(premium.len > 0)
dat += "<b>Change Return:</b> "
if (coin || bill)
dat += "[(coin ? coin : "")][(bill ? bill : "")]&nbsp;&nbsp;<a href='byond://?src=[REF(src)];remove_coin=1'>Remove</a>"
else
dat += "<i>No money</i>&nbsp;&nbsp;<span class='linkOff'>Remove</span>"
if(istype(src, /obj/machinery/vending/snack))
dat += "<h3>Chef's Food Selection</h3>"
dat += "<div class='statusDisplay'>"
for (var/O in dish_quants)
if(dish_quants[O] > 0)
var/N = dish_quants[O]
dat += "<a href='byond://?src=[REF(src)];dispense=[sanitize(O)]'>Dispense</A> "
dat += "<B>[capitalize(O)]: [N]</B><br>"
dat += "</div>"
user.set_machine(src)
if(seconds_electrified && !(stat & NOPOWER))
if(shock(user, 100))
return
var/datum/browser/popup = new(user, "vending", (name))
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/vending/Topic(href, href_list)
if(..())
return
if(href_list["remove_coin"])
if(!(coin || bill))
to_chat(usr, "<span class='notice'>There is no money in this machine.</span>")
return
if(coin)
if(!usr.get_active_held_item())
usr.put_in_hands(coin)
else
coin.forceMove(get_turf(src))
to_chat(usr, "<span class='notice'>You remove [coin] from [src].</span>")
coin = null
if(bill)
if(!usr.get_active_held_item())
usr.put_in_hands(bill)
else
bill.forceMove(get_turf(src))
to_chat(usr, "<span class='notice'>You remove [bill] from [src].</span>")
bill = null
usr.set_machine(src)
if((href_list["dispense"]) && (vend_ready))
var/N = href_list["dispense"]
if(dish_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
return
vend_ready = 0
use_power(5)
dish_quants[N] = max(dish_quants[N] - 1, 0)
for(var/obj/O in contents)
if(O.name == N)
O.forceMove(drop_location())
break
vend_ready = 1
updateUsrDialog()
return
if((href_list["vend"]) && (vend_ready))
if(panel_open)
to_chat(usr, "<span class='notice'>The vending machine cannot dispense products while its service panel is open!</span>")
return
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
to_chat(usr, "<span class='warning'>Access denied.</span>" )
flick(icon_deny,src)
return
vend_ready = 0 //One thing at a time!!
var/datum/data/vending_product/R = locate(href_list["vend"])
if(!R || !istype(R) || !R.product_path)
vend_ready = 1
return
if(R in hidden_records)
if(!extended_inventory)
vend_ready = 1
return
else if(R in coin_records)
if(!(coin || bill))
to_chat(usr, "<span class='warning'>You need to insert money to get this item!</span>")
vend_ready = 1
return
if(coin && coin.string_attached)
if(prob(50))
if(usr.put_in_hands(coin))
to_chat(usr, "<span class='notice'>You successfully pull [coin] out before [src] could swallow it.</span>")
coin = null
else
to_chat(usr, "<span class='warning'>You couldn't pull [coin] out because your hands are full!</span>")
QDEL_NULL(coin)
else
to_chat(usr, "<span class='warning'>You weren't able to pull [coin] out fast enough, the machine ate it, string and all!</span>")
QDEL_NULL(coin)
else
QDEL_NULL(coin)
QDEL_NULL(bill)
else if (!(R in product_records))
vend_ready = 1
message_admins("Vending machine exploit attempted by [key_name(usr, usr.client)]!")
return
if (R.amount <= 0)
to_chat(usr, "<span class='warning'>Sold out.</span>")
vend_ready = 1
return
else
R.amount--
if(((last_reply + 200) <= world.time) && vend_reply)
speak(vend_reply)
last_reply = world.time
use_power(5)
if(icon_vend) //Show the vending animation if needed
flick(icon_vend,src)
new R.product_path(get_turf(src))
SSblackbox.record_feedback("nested tally", "vending_machine_usage", 1, list("[type]", "[R.product_path]"))
vend_ready = 1
return
updateUsrDialog()
return
else if(href_list["togglevoice"] && panel_open)
shut_up = !shut_up
updateUsrDialog()
/obj/machinery/vending/process()
if(stat & (BROKEN|NOPOWER))
return
@@ -605,6 +431,96 @@
else
return FALSE
/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "vending", name, 350, 475, master_ui, state)
ui.open()
/obj/machinery/vending/ui_data()
var/list/data = list()
var/list/listed_products = list()
var/list/display_records = product_records
if(extended_inventory)
display_records += hidden_records
if(coin)
display_records += coin_records
for(var/key = 1 to display_records.len)
var/datum/data/vending_product/I = display_records[key]
listed_products.Add(list(list(
"key" = key,
"name" = I.product_name,
"color" = I.display_color,
"amount" = I.amount)))
data["products"] = listed_products
if(!isnull(coin))
data["coin"] = coin.name
data["coinslot"] = premium.len
data["canvend"] = vend_ready
return data
/obj/machinery/vending/ui_act(action, params)
if(..())
return
if(!vend_ready)
return
switch(action)
if("vend")
if(!allowed(usr) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
to_chat(usr, "<span class='warning'>Access denied.</span>")
flick(icon_deny,src)
return
vend_ready = FALSE
addtimer(VARSET_CALLBACK(src, vend_ready, TRUE), 10)
var/key = text2num(params["key"])
var/datum/data/vending_product/R = product_records[key]
if(R in hidden_records)
if(!extended_inventory)
return
else if(R in coin_records)
if(!coin)
to_chat(usr, "<span class='warning'>You need to insert a coin to get this item!</span>")
return
if(coin.string_attached)
if(prob(50))
if(usr.put_in_hands(coin))
to_chat(usr, "<span class='notice'>You successfully pull [coin] out before [src] could swallow it.</span>")
coin = null
else
to_chat(usr, "<span class='warning'>You couldn't pull [coin] out because your hands are full!</span>")
QDEL_NULL(coin)
else
to_chat(usr, "<span class='warning'>You weren't able to pull [coin] out fast enough, the machine ate it, string and all!</span>")
QDEL_NULL(coin)
else
QDEL_NULL(coin)
else if (!(R in product_records))
return
if (R.amount <= 0)
to_chat(usr, "<span class='warning'>Sold out.</span>")
return
R.amount--
if(((last_reply + 200) <= world.time) && vend_reply)
speak(vend_reply)
last_reply = world.time
use_power(5)
if(icon_vend) //Show the vending animation if needed
flick(icon_vend,src)
new R.product_path(drop_location())
return TRUE
if("eject")
if(!coin)
to_chat(usr, "<span class='notice'>There is no coin in this machine.</span>")
return
usr.put_in_hands(coin)
to_chat(usr, "<span class='notice'>You remove [coin] from [src].</span>")
coin = null
/*
* Vending machine types
*/
@@ -1195,4 +1111,4 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
#undef STANDARD_CHARGE
#undef CONTRABAND_CHARGE
#undef COIN_CHARGE
#undef COIN_CHARGE
+42 -9
View File
@@ -16,7 +16,7 @@
/obj/effect/landmark/start
name = "start"
icon = 'icons/mob/screen_gen.dmi'
icon = 'icons/mob/landmarks.dmi'
icon_state = "x"
anchored = TRUE
var/jobspawn_override = FALSE
@@ -40,9 +40,9 @@
// START LANDMARKS FOLLOW. Don't change the names unless
// you are refactoring shitty landmark code.
/obj/effect/landmark/start/assistant
name = "Assistant"
icon_state = "Assistant"
/obj/effect/landmark/start/assistant/override
jobspawn_override = TRUE
@@ -50,102 +50,135 @@
/obj/effect/landmark/start/janitor
name = "Janitor"
icon_state = "Janitor"
/obj/effect/landmark/start/cargo_technician
name = "Cargo Technician"
icon_state = "Cargo Technician"
/obj/effect/landmark/start/bartender
name = "Bartender"
icon_state = "Bartender"
/obj/effect/landmark/start/clown
name = "Clown"
icon_state = "Clown"
/obj/effect/landmark/start/mime
name = "Mime"
icon_state = "Mime"
/obj/effect/landmark/start/quartermaster
name = "Quartermaster"
icon_state = "Quartermaster"
/obj/effect/landmark/start/atmospheric_technician
name = "Atmospheric Technician"
icon_state = "Atmospheric Technician"
/obj/effect/landmark/start/cook
name = "Cook"
icon_state = "Cook"
/obj/effect/landmark/start/shaft_miner
name = "Shaft Miner"
icon_state = "Shaft Miner"
/obj/effect/landmark/start/security_officer
name = "Security Officer"
icon_state = "Security Officer"
/obj/effect/landmark/start/botanist
name = "Botanist"
icon_state = "Botanist"
/obj/effect/landmark/start/head_of_security
name = "Head of Security"
/obj/effect/landmark/start/ai
name = "AI"
delete_after_roundstart = FALSE
icon_state = "Head of Security"
/obj/effect/landmark/start/captain
name = "Captain"
icon_state = "Captain"
/obj/effect/landmark/start/detective
name = "Detective"
icon_state = "Detective"
/obj/effect/landmark/start/warden
name = "Warden"
icon_state = "Warden"
/obj/effect/landmark/start/chief_engineer
name = "Chief Engineer"
/obj/effect/landmark/start/cyborg
name = "Cyborg"
icon_state = "Chief Engineer"
/obj/effect/landmark/start/head_of_personnel
name = "Head of Personnel"
icon_state = "Head of Personnel"
/obj/effect/landmark/start/librarian
name = "Curator"
icon_state = "Curator"
/obj/effect/landmark/start/lawyer
name = "Lawyer"
icon_state = "Lawyer"
/obj/effect/landmark/start/station_engineer
name = "Station Engineer"
icon_state = "Station Engineer"
/obj/effect/landmark/start/medical_doctor
name = "Medical Doctor"
icon_state = "Medical Doctor"
/obj/effect/landmark/start/scientist
name = "Scientist"
icon_state = "Scientist"
/obj/effect/landmark/start/chemist
name = "Chemist"
icon_state = "Chemist"
/obj/effect/landmark/start/roboticist
name = "Roboticist"
icon_state = "Roboticist"
/obj/effect/landmark/start/research_director
name = "Research Director"
icon_state = "Research Director"
/obj/effect/landmark/start/geneticist
name = "Geneticist"
icon_state = "Geneticist"
/obj/effect/landmark/start/chief_medical_officer
name = "Chief Medical Officer"
icon_state = "Chief Medical Officer"
/obj/effect/landmark/start/virologist
name = "Virologist"
icon_state = "Virologist"
/obj/effect/landmark/start/chaplain
name = "Chaplain"
icon_state = "Chaplain"
/obj/effect/landmark/start/cyborg
name = "Cyborg"
icon_state = "Cyborg"
/obj/effect/landmark/start/ai
name = "AI"
icon_state = "AI"
delete_after_roundstart = FALSE
//Department Security spawns
/obj/effect/landmark/start/depsec
name = "department_sec"
icon_state = "Security Officer"
/obj/effect/landmark/start/depsec/New()
..()
@@ -0,0 +1,70 @@
/proc/generate_projectile_beam_between_points(datum/point/starting, datum/point/ending, beam_type, color, qdel_in = 5) //Do not pass z-crossing points as that will not be properly (and likely will never be properly until it's absolutely needed) supported!
if(!istype(starting) || !istype(ending) || !ispath(beam_type))
return
var/datum/point/midpoint = point_midpoint_points(starting, ending)
var/obj/effect/projectile_beam/PB = new beam_type
PB.apply_vars(angle_between_points(starting, ending), midpoint.return_px(), midpoint.return_py(), color, pixel_length_between_points(starting, ending) / world.icon_size, midpoint.return_turf(), 0)
. = PB
if(qdel_in)
QDEL_IN(PB, qdel_in)
/obj/effect/projectile_beam
icon = 'icons/obj/projectiles.dmi'
layer = ABOVE_MOB_LAYER
anchored = TRUE
light_power = 1
light_range = 2
light_color = "#00ffff"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
flags_1 = ABSTRACT_1
appearance_flags = 0
/obj/effect/projectile_beam/singularity_pull()
return
/obj/effect/projectile_beam/singularity_act()
return
/obj/effect/projectile_beam/proc/scale_to(nx,ny,override=TRUE)
var/matrix/M
if(!override)
M = transform
else
M = new
M.Scale(nx,ny)
transform = M
/obj/effect/projectile_beam/proc/turn_to(angle,override=TRUE)
var/matrix/M
if(!override)
M = transform
else
M = new
M.Turn(angle)
transform = M
/obj/effect/projectile_beam/New(angle_override, p_x, p_y, color_override, scaling = 1)
if(angle_override && p_x && p_y && color_override && scaling)
apply_vars(angle_override, p_x, p_y, color_override, scaling)
return ..()
/obj/effect/projectile_beam/proc/apply_vars(angle_override, p_x = 0, p_y = 0, color_override, scaling = 1, new_loc, increment = 0)
var/mutable_appearance/look = new(src)
look.pixel_x = p_x
look.pixel_y = p_y
if(color_override)
look.color = color_override
appearance = look
scale_to(1,scaling, FALSE)
turn_to(angle_override, FALSE)
if(!isnull(new_loc)) //If you want to null it just delete it...
forceMove(new_loc)
for(var/i in 1 to increment)
pixel_x += round((sin(angle_override)+16*sin(angle_override)*2), 1)
pixel_y += round((cos(angle_override)+16*cos(angle_override)*2), 1)
/obj/effect/projectile_beam/tracer
icon_state = "tracer_beam"
/obj/effect/projectile_beam/tracer/aiming
icon_state = "gbeam"
+5 -5
View File
@@ -539,9 +539,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.adjust_blurriness(15)
if(M.stat != DEAD)
to_chat(M, "<span class='danger'>Your eyes start to bleed profusely!</span>")
if(!(M.disabilities & (NEARSIGHT | BLIND)))
if(M.become_nearsighted())
to_chat(M, "<span class='danger'>You become nearsighted!</span>")
if(!(M.has_disability(BLIND) || M.has_disability(NEARSIGHT)))
to_chat(M, "<span class='danger'>You become nearsighted!</span>")
M.become_nearsighted(EYE_DAMAGE)
if(prob(50))
if(M.stat != DEAD)
if(M.drop_all_held_items())
@@ -550,8 +550,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.Unconscious(20)
M.Knockdown(40)
if (prob(eyes.eye_damage - 10 + 1))
if(M.become_blind())
to_chat(M, "<span class='danger'>You go blind!</span>")
M.become_blind(EYE_DAMAGE)
to_chat(M, "<span class='danger'>You go blind!</span>")
/obj/item/clean_blood()
. = ..()
+2 -2
View File
@@ -393,7 +393,7 @@
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/human/H)
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
return (!H.suiciding && !(H.disabilities & NOCLONE) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
return (!H.suiciding && !(H.has_disability(NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(isliving(H.pulledby)) //CLEAR!
@@ -514,7 +514,7 @@
shock_touching(30, H)
var/failed
if (H.suiciding || (H.disabilities & NOCLONE))
if (H.suiciding || (H.has_disability(NOCLONE)))
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.</span>"
else if (H.hellbound)
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile.</span>"
@@ -48,7 +48,7 @@
add_fingerprint(user)
if(istype(M) && on && user.zone_selected in list("eyes", "mouth"))
if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) //too dumb to use flashlight properly
if((user.has_disability(CLUMSY) || user.has_disability(DUMB)) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
if(!user.IsAdvancedToolUser())
@@ -82,7 +82,7 @@
else
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
if(M.stat == DEAD || (M.disabilities & BLIND) || !M.flash_act(visual = 1)) //mob is dead or fully blind
if(M.stat == DEAD || (M.has_disability(BLIND)) || !M.flash_act(visual = 1)) //mob is dead or fully blind
to_chat(user, "<span class='warning'>[M]'s pupils don't react to the light!</span>")
else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-RAY vision
to_chat(user, "<span class='danger'>[M]'s pupils give an eerie glow!</span>")
+7 -4
View File
@@ -85,7 +85,7 @@ GAS ANALYZER
/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/carbon/human/user)
// Clumsiness/brain damage check
if ((user.disabilities & (CLUMSY | DUMB)) && prob(50))
if ((user.has_disability(CLUMSY) || user.has_disability(DUMB)) && prob(50))
to_chat(user, "<span class='notice'>You stupidly try to analyze the floor's vitals!</span>")
user.visible_message("<span class='warning'>[user] has analyzed the floor's vitals!</span>")
to_chat(user, "<span class='info'>Analyzing results for The floor:\n\tOverall status: <b>Healthy</b>")
@@ -181,9 +181,12 @@ GAS ANALYZER
to_chat(user, "\t<span class='info'><b>==EAR STATUS==</b></span>")
if(istype(ears))
var/healthy = TRUE
if(C.disabilities & DEAF)
if(C.has_disability(DEAF, GENETIC_MUTATION))
healthy = FALSE
to_chat(user, "\t<span class='alert'>Subject is genetically deaf.</span>")
else if(C.has_disability(DEAF))
healthy = FALSE
to_chat(user, "\t<span class='alert'>Subject is deaf.</span>")
else
if(ears.ear_damage)
to_chat(user, "\t<span class='alert'>Subject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.</span>")
@@ -199,10 +202,10 @@ GAS ANALYZER
to_chat(user, "\t<span class='info'><b>==EYE STATUS==</b></span>")
if(istype(eyes))
var/healthy = TRUE
if(C.disabilities & BLIND)
if(C.has_disability(BLIND))
to_chat(user, "\t<span class='alert'>Subject is blind.</span>")
healthy = FALSE
if(C.disabilities & NEARSIGHT)
if(C.has_disability(NEARSIGHT))
to_chat(user, "\t<span class='alert'>Subject is nearsighted.</span>")
healthy = FALSE
if(eyes.eye_damage > 30)
+2 -2
View File
@@ -31,7 +31,7 @@
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.disabilities & NOCLONE))
if(M.has_dna() && !(RADIMMUNE in M.dna.species.species_traits) && !(M.has_disability(NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
@@ -313,7 +313,7 @@
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
return FALSE
if(M.has_dna() && !(M.disabilities & NOCLONE))
if(M.has_dna() && !(M.has_disability(NOCLONE)))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
+28 -6
View File
@@ -7,6 +7,9 @@
/*
* Gifts
*/
GLOBAL_LIST_EMPTY(possible_gifts)
/obj/item/a_gift
name = "gift"
desc = "PRESENTS!!!! eek!"
@@ -30,6 +33,14 @@
to_chat(M, "<span class='warning'>You're supposed to be spreading gifts, not opening them yourself!</span>")
return
var/gift_type = get_gift_type()
qdel(src)
var/obj/item/I = new gift_type(M)
M.put_in_hands(I)
I.add_fingerprint(M)
/obj/item/a_gift/proc/get_gift_type()
var/gift_type_list = list(/obj/item/sord,
/obj/item/storage/wallet,
/obj/item/storage/photo_album,
@@ -72,10 +83,21 @@
var/gift_type = pick(gift_type_list)
if(!ispath(gift_type, /obj/item))
return
return gift_type
qdel(src)
var/obj/item/I = new gift_type(M)
M.put_in_hands(I)
I.add_fingerprint(M)
/obj/item/a_gift/anything
name = "christmas gift"
desc = "It could be anything!"
/obj/item/a_gift/anything/get_gift_type()
if(!GLOB.possible_gifts.len)
var/list/gift_types_list = subtypesof(/obj/item)
for(var/V in gift_types_list)
var/obj/item/I = V
if((!initial(I.icon_state)) || (!initial(I.item_state)) || (initial(I.flags_1) & ABSTRACT_1))
gift_types_list -= V
GLOB.possible_gifts = gift_types_list
var/gift_type = pick(GLOB.possible_gifts)
return gift_type
+1 -1
View File
@@ -24,7 +24,7 @@
qdel(src)
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
+1 -1
View File
@@ -26,7 +26,7 @@
/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/carbon/human/user)
if(!istype(C))
return
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user,user)
return
+2 -2
View File
@@ -44,7 +44,7 @@
forkload = null
else if(user.zone_selected == "eyes")
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
M = user
return eyestab(M,user)
else
@@ -70,7 +70,7 @@
/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user)
if(user.zone_selected == "eyes")
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
M = user
return eyestab(M,user)
else
+1 -1
View File
@@ -99,7 +99,7 @@
return ..()
add_fingerprint(user)
if((CLUMSY in user.disabilities) && prob(50))
if((user.has_disability(CLUMSY)) && prob(50))
to_chat(user, "<span class ='danger'>You club yourself over the head.</span>")
user.Knockdown(60 * force)
if(ishuman(user))
@@ -72,6 +72,6 @@
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
/obj/item/melee/transforming/proc/clumsy_transform_effect(mob/living/user)
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
user.take_bodypart_damage(5,5)
+142 -142
View File
@@ -1,142 +1,142 @@
/obj/item/shield
name = "shield"
block_chance = 50
armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "riot"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = SLOT_BACK
force = 10
throwforce = 5
throw_speed = 2
throw_range = 3
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
if(cooldown < world.time - 25)
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else
return ..()
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
final_block_chance = 100
return ..()
/obj/item/shield/riot/roman
name = "roman shield"
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
icon_state = "roman_shield"
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
/obj/item/shield/riot/buckler
name = "wooden buckler"
desc = "A medieval wooden buckler."
icon_state = "buckler"
item_state = "buckler"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
materials = list()
resistance_flags = FLAMMABLE
block_chance = 30
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "eshield0" // eshield1 for expanded
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
force = 3
throwforce = 3
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
var/active = 0
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/shield/energy/IsReflect()
return (active)
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(user.disabilities & CLUMSY && prob(50))
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "eshield[active]"
if(active)
force = 10
throwforce = 8
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "teleriot0"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = null
force = 3
throwforce = 3
throw_speed = 3
throw_range = 4
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
icon_state = "teleriot[active]"
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
if(active)
force = 8
throwforce = 5
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
to_chat(user, "<span class='notice'>You extend \the [src].</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_NORMAL
slot_flags = null
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield
name = "shield"
block_chance = 50
armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70)
/obj/item/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "riot"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = SLOT_BACK
force = 10
throwforce = 5
throw_speed = 2
throw_range = 3
w_class = WEIGHT_CLASS_BULKY
materials = list(MAT_GLASS=7500, MAT_METAL=1000)
attack_verb = list("shoved", "bashed")
var/cooldown = 0 //shield bash cooldown. based on world.time
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/melee/baton))
if(cooldown < world.time - 25)
user.visible_message("<span class='warning'>[user] bashes [src] with [W]!</span>")
playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1)
cooldown = world.time
else
return ..()
/obj/item/shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == THROWN_PROJECTILE_ATTACK)
final_block_chance += 30
if(attack_type == LEAP_ATTACK)
final_block_chance = 100
return ..()
/obj/item/shield/riot/roman
name = "roman shield"
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>."
icon_state = "roman_shield"
item_state = "roman_shield"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
/obj/item/shield/riot/buckler
name = "wooden buckler"
desc = "A medieval wooden buckler."
icon_state = "buckler"
item_state = "buckler"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
materials = list()
resistance_flags = FLAMMABLE
block_chance = 30
/obj/item/shield/energy
name = "energy combat shield"
desc = "A shield capable of stopping most melee attacks. Protects user from almost all energy projectiles. It can be retracted, expanded, and stored anywhere."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "eshield0" // eshield1 for expanded
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
force = 3
throwforce = 3
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_TINY
attack_verb = list("shoved", "bashed")
var/active = 0
/obj/item/shield/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
/obj/item/shield/energy/IsReflect()
return (active)
/obj/item/shield/energy/attack_self(mob/living/carbon/human/user)
if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You beat yourself in the head with [src].</span>")
user.take_bodypart_damage(5)
active = !active
icon_state = "eshield[active]"
if(active)
force = 10
throwforce = 8
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
playsound(user, 'sound/weapons/saberon.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] is now active.</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_TINY
playsound(user, 'sound/weapons/saberoff.ogg', 35, 1)
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
/obj/item/shield/riot/tele
name = "telescopic shield"
desc = "An advanced riot shield made of lightweight materials that collapses for easy storage."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "teleriot0"
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
slot_flags = null
force = 3
throwforce = 3
throw_speed = 3
throw_range = 4
w_class = WEIGHT_CLASS_NORMAL
var/active = 0
/obj/item/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(active)
return ..()
return 0
/obj/item/shield/riot/tele/attack_self(mob/living/user)
active = !active
icon_state = "teleriot[active]"
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
if(active)
force = 8
throwforce = 5
throw_speed = 2
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
to_chat(user, "<span class='notice'>You extend \the [src].</span>")
else
force = 3
throwforce = 3
throw_speed = 3
w_class = WEIGHT_CLASS_NORMAL
slot_flags = null
to_chat(user, "<span class='notice'>[src] can now be concealed.</span>")
add_fingerprint(user)
+3 -3
View File
@@ -109,7 +109,7 @@
if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list))
var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist]
recipe_list = srl.recipes
var/t1 = "Amount Left: [amount]<br>"
var/t1 = "Amount Left: [get_amount()]<br>"
for(var/i in 1 to length(recipe_list))
var/E = recipe_list[i]
if (isnull(E))
@@ -161,8 +161,8 @@
if (href_list["sublist"] && !href_list["make"])
interact(usr, text2num(href_list["sublist"]))
if (href_list["make"])
if (get_amount() < 1)
qdel(src) //Never should happen
if (get_amount() < 1 && !is_cyborg)
qdel(src)
var/list/recipes_list = recipes
if (href_list["sublist"])
+1 -1
View File
@@ -94,7 +94,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
if (user.disabilities & CLUMSY && prob(50))
if (user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='danger'>[src] slips out of your hand and hits your head.</span>")
user.take_bodypart_damage(10)
user.Unconscious(400)
+1 -1
View File
@@ -108,7 +108,7 @@
add_fingerprint(user)
/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user)
if(status && user.disabilities & CLUMSY && prob(50))
if(status && user.has_disability(CLUMSY) && prob(50))
user.visible_message("<span class='danger'>[user] accidentally hits themself with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
user.Knockdown(stunforce*3)
+1 -1
View File
@@ -8,7 +8,7 @@
/obj/item/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
..()
if(status && user.disabilities & CLUMSY && prob(50))
if(status && user.has_disability(CLUMSY) && prob(50))
user.visible_message("<span class='danger'>[user] accidentally hits themself with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
if(do_teleport(user, get_turf(user), 50))//honk honk
+2 -2
View File
@@ -75,7 +75,7 @@
return ..()
if(user.zone_selected != "eyes" && user.zone_selected != "head")
return ..()
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
M = user
return eyestab(M,user)
@@ -105,7 +105,7 @@
item_state = "drill"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
w_class = WEIGHT_CLASS_SMALL
throwforce = 8
+1 -1
View File
@@ -302,7 +302,7 @@
unwield()
return
..()
if(user.disabilities & CLUMSY && (wielded) && prob(40))
if(user.has_disability(CLUMSY) && (wielded) && prob(40))
impale(user)
return
if((wielded) && prob(50))
+15 -3
View File
@@ -36,9 +36,6 @@
else
return ..()
/obj/structure/flora/tree/pine
name = "pine tree"
desc = "A coniferous pine tree."
@@ -53,6 +50,21 @@
name = "xmas tree"
desc = "A wondrous decorated Christmas tree."
icon_state = "pine_c"
var/gifts_under_tree = FALSE
var/list/ckeys_that_took = list()
/obj/structure/flora/tree/pine/xmas/attack_hand(mob/living/user)
if(!gifts_under_tree)
return
if(!user.ckey)
return
if(ckeys_that_took[user.ckey])
to_chat(user, "<span class='warning'>You already took your gift.</span>")
return
to_chat(user, "<span class='warning'>After a bit of rummaging, you locate a gift with your name on it!</span>")
ckeys_that_took[user.ckey] = TRUE
var/obj/item/a_gift/anything/A = new
user.put_in_hands(A)
/obj/structure/flora/tree/pine/xmas/Initialize()
. = ..()
@@ -17,7 +17,7 @@
L.buckled.unbuckle_mob(L,force=1)
L.visible_message("<span class='warning'>[L]'s skin rapidly turns to marble!</span>", "<span class='userdanger'>Your body freezes up! Can't... move... can't... think...</span>")
L.forceMove(src)
L.disabilities |= MUTE
L.add_disability(MUTE, STATUE_MUTE)
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
L.status_flags |= GODMODE
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
@@ -59,7 +59,7 @@
if(petrified_mob)
petrified_mob.status_flags &= ~GODMODE
petrified_mob.forceMove(loc)
petrified_mob.disabilities &= ~MUTE
petrified_mob.remove_disability(MUTE, STATUE_MUTE)
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
petrified_mob.faction -= "mimic"
petrified_mob = null
+3 -3
View File
@@ -202,7 +202,7 @@
var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180)
if(ISINRANGE_EX(norm_inc, -90, 90))
return FALSE
P.Angle = new_angle
P.setAngle(new_angle)
return ..()
//DOUBLE
@@ -229,7 +229,7 @@
var/new_angle = WRAP(rotation_angle + norm_inc, 180, -180)
if(ISINRANGE_EX(norm_inc, -90, 90))
new_angle += 180
P.Angle = new_angle
P.setAngle(new_angle)
return ..()
//BOX
@@ -251,7 +251,7 @@
anchored = TRUE
/obj/structure/reflector/box/auto_reflect(obj/item/projectile/P)
P.Angle = rotation_angle
P.setAngle(rotation_angle)
return ..()
/obj/structure/reflector/ex_act()
@@ -146,6 +146,9 @@
var/uses_overlay = TRUE
var/obj/effect/clockwork/overlay/floor/realappearence
/turf/open/floor/clockwork/Bless() //Who needs holy blessings when you have DADDY RATVAR?
return
/turf/open/floor/clockwork/Initialize()
. = ..()
if(uses_overlay)
+1 -1
View File
@@ -61,7 +61,7 @@
new_angle_s -= 360
while(new_angle_s < -180)
new_angle_s += 360
P.Angle = new_angle_s
P.setAngle(new_angle_s)
return TRUE
/turf/closed/wall/proc/dismantle_wall(devastated=0, explode=0)
+1
View File
@@ -251,3 +251,4 @@ GLOBAL_PROTECT(security_mode)
hub_password = "kMZy3U5jJHSiBQjr"
else
hub_password = "SORRYNOPASSWORD"
+10 -3
View File
@@ -107,6 +107,8 @@ GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(target, procname, list/arguments)
var/current_caller = GLOB.AdminProcCaller
@@ -114,9 +116,14 @@ GLOBAL_PROTECT(LastAdminCalledProc)
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
UNTIL(!GLOB.AdminProcCaller)
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
if(!GLOB.AdminProcCallSpamPrevention[ckey])
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
UNTIL(!GLOB.AdminProcCaller)
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
GLOB.AdminProcCallSpamPrevention -= ckey
else
UNTIL(!GLOB.AdminProcCaller)
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "[REF(target)]"
+30 -1
View File
@@ -45,7 +45,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/manipulate_organs,
/client/proc/start_line_profiling,
/client/proc/stop_line_profiling,
/client/proc/show_line_profiling
/client/proc/show_line_profiling,
/client/proc/create_mapping_job_icons
))
/obj/effect/debugging/mapfix_marker
@@ -265,3 +266,31 @@ GLOBAL_VAR_INIT(say_disabled, FALSE)
message_admins("[src.ckey] used 'Disable all communication verbs', killing all communication methods.")
else
message_admins("[src.ckey] used 'Disable all communication verbs', restoring all communication methods.")
//This generates the icon states for job starting location landmarks.
/client/proc/create_mapping_job_icons()
set name = "Generate job landmarks icons"
set category = "Mapping"
var/icon/final = icon()
var/mob/living/carbon/human/dummy/D = new(locate(1,1,1)) //spawn on 1,1,1 so we don't have runtimes when items are deleted
D.setDir(SOUTH)
for(var/job in subtypesof(/datum/job))
var/datum/job/JB = new job
switch(JB.title)
if("AI")
final.Insert(icon('icons/mob/ai.dmi', "ai", SOUTH, 1), "AI")
if("Cyborg")
final.Insert(icon('icons/mob/robots.dmi', "robot", SOUTH, 1), "Cyborg")
else
for(var/obj/item/I in D)
qdel(I)
randomize_human(D)
JB.equip(D, TRUE, FALSE)
COMPILE_OVERLAYS(D)
var/icon/I = icon(getFlatIcon(D), frame = 1)
final.Insert(I, JB.title)
qdel(D)
//Also add the x
for(var/x_number in 1 to 4)
final.Insert(icon('icons/mob/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]")
fcopy(final, "icons/mob/landmarks.dmi")
+1 -1
View File
@@ -30,7 +30,7 @@
holder.update_icon()
/obj/item/device/assembly/flash/proc/clown_check(mob/living/carbon/human/user)
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
flash_carbon(user, user, 15, 0)
return 0
return 1
+142 -142
View File
@@ -1,142 +1,142 @@
/obj/item/device/assembly/mousetrap
name = "mousetrap"
desc = "A handy little spring-loaded trap for catching pesty rodents."
icon_state = "mousetrap"
materials = list(MAT_METAL=100)
attachable = 1
var/armed = 0
/obj/item/device/assembly/mousetrap/examine(mob/user)
..()
if(armed)
to_chat(user, "The mousetrap is armed!")
else
to_chat(user, "The mousetrap is not armed.")
/obj/item/device/assembly/mousetrap/activate()
if(..())
armed = !armed
if(!armed)
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY && prob(50))
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
pulse(0)
update_icon()
if(usr)
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/device/assembly/mousetrap/describe()
return "The pressure switch is [armed?"primed":"safe"]."
/obj/item/device/assembly/mousetrap/update_icon()
if(armed)
icon_state = "mousetraparmed"
else
icon_state = "mousetrap"
if(holder)
holder.update_icon()
/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
if(!armed)
return
var/obj/item/bodypart/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(PIERCEIMMUNE in H.dna.species.species_traits)
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
armed = 0
update_icon()
pulse(0)
return 0
switch(type)
if("feet")
if(!H.shoes)
affecting = H.get_bodypart(pick("l_leg", "r_leg"))
H.Knockdown(60)
if("l_hand", "r_hand")
if(!H.gloves)
affecting = H.get_bodypart(type)
H.Stun(60)
if(affecting)
if(affecting.receive_damage(1, 0))
H.update_damage_overlays()
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='boldannounce'>SPLAT!</span>")
M.splat()
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
armed = 0
update_icon()
pulse(0)
/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
if(!armed)
to_chat(user, "<span class='notice'>You arm [src].</span>")
else
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
to_chat(user, "<span class='notice'>You disarm [src].</span>")
armed = !armed
update_icon()
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
if(armed)
if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
..()
/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
if(armed)
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
if(ishuman(AM))
var/mob/living/carbon/H = AM
if(H.m_intent == MOVE_INTENT_RUN)
triggered(H)
H.visible_message("<span class='warning'>[H] accidentally steps on [src].</span>", \
"<span class='warning'>You accidentally step on [src]</span>")
else if(ismouse(MM))
triggered(MM)
else if(AM.density) // For mousetrap grenades, set off by anything heavy
triggered(AM)
..()
/obj/item/device/assembly/mousetrap/on_found(mob/finder)
if(armed)
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
return 1 //end the search!
return 0
/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
if(!armed)
return ..()
visible_message("<span class='warning'>[src] is triggered by [A].</span>")
triggered(null)
/obj/item/device/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = TRUE
/obj/item/device/assembly/mousetrap
name = "mousetrap"
desc = "A handy little spring-loaded trap for catching pesty rodents."
icon_state = "mousetrap"
materials = list(MAT_METAL=100)
attachable = 1
var/armed = 0
/obj/item/device/assembly/mousetrap/examine(mob/user)
..()
if(armed)
to_chat(user, "The mousetrap is armed!")
else
to_chat(user, "The mousetrap is not armed.")
/obj/item/device/assembly/mousetrap/activate()
if(..())
armed = !armed
if(!armed)
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
pulse(0)
update_icon()
if(usr)
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/device/assembly/mousetrap/describe()
return "The pressure switch is [armed?"primed":"safe"]."
/obj/item/device/assembly/mousetrap/update_icon()
if(armed)
icon_state = "mousetraparmed"
else
icon_state = "mousetrap"
if(holder)
holder.update_icon()
/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet")
if(!armed)
return
var/obj/item/bodypart/affecting = null
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(PIERCEIMMUNE in H.dna.species.species_traits)
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
armed = 0
update_icon()
pulse(0)
return 0
switch(type)
if("feet")
if(!H.shoes)
affecting = H.get_bodypart(pick("l_leg", "r_leg"))
H.Knockdown(60)
if("l_hand", "r_hand")
if(!H.gloves)
affecting = H.get_bodypart(type)
H.Stun(60)
if(affecting)
if(affecting.receive_damage(1, 0))
H.update_damage_overlays()
else if(ismouse(target))
var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='boldannounce'>SPLAT!</span>")
M.splat()
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
armed = 0
update_icon()
pulse(0)
/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
if(!armed)
to_chat(user, "<span class='notice'>You arm [src].</span>")
else
if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
to_chat(user, "<span class='notice'>You disarm [src].</span>")
armed = !armed
update_icon()
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
if(armed)
if((user.has_disability(DUMB) || user.has_disability(CLUMSY)) && prob(50))
var/which_hand = "l_hand"
if(!(user.active_hand_index % 2))
which_hand = "r_hand"
triggered(user, which_hand)
user.visible_message("<span class='warning'>[user] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
return
..()
/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj)
if(armed)
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
if(ishuman(AM))
var/mob/living/carbon/H = AM
if(H.m_intent == MOVE_INTENT_RUN)
triggered(H)
H.visible_message("<span class='warning'>[H] accidentally steps on [src].</span>", \
"<span class='warning'>You accidentally step on [src]</span>")
else if(ismouse(MM))
triggered(MM)
else if(AM.density) // For mousetrap grenades, set off by anything heavy
triggered(AM)
..()
/obj/item/device/assembly/mousetrap/on_found(mob/finder)
if(armed)
finder.visible_message("<span class='warning'>[finder] accidentally sets off [src], breaking their fingers.</span>", \
"<span class='warning'>You accidentally trigger [src]!</span>")
triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand")
return 1 //end the search!
return 0
/obj/item/device/assembly/mousetrap/hitby(A as mob|obj)
if(!armed)
return ..()
visible_message("<span class='warning'>[src] is triggered by [A].</span>")
triggered(null)
/obj/item/device/assembly/mousetrap/armed
icon_state = "mousetraparmed"
armed = 1
+1 -1
View File
@@ -41,7 +41,7 @@
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(!(H.disabilities & BLIND))
if(!(H.has_disability(BLIND)))
if(H.glasses == src)
to_chat(H, "<span class='danger'>[src] overloads and blinds you!</span>")
H.flash_act(visual = 1)
+3 -3
View File
@@ -13,7 +13,7 @@
var/max_severity = 3
/datum/round_event/disease_outbreak/announce()
/datum/round_event/disease_outbreak/announce(fake)
priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
/datum/round_event/disease_outbreak/setup()
@@ -33,7 +33,7 @@
var/turf/T = get_turf(H)
if(!T)
continue
if(T.z != ZLEVEL_STATION_PRIMARY)
if(!(T.z in GLOB.station_z_levels))
continue
if(!H.client)
continue
@@ -51,7 +51,7 @@
var/datum/disease/D
if(!advanced_virus)
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst.
if(!H.dna || (H.has_disability(BLIND))) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D
+4 -21
View File
@@ -1,19 +1,3 @@
/datum/round_event_control/treevenge
name = "Treevenge (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/treevenge
max_occurrences = 1
weight = 20
/datum/round_event/treevenge/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
evil_tree.icon_state = xmas.icon_state
evil_tree.icon_living = evil_tree.icon_state
evil_tree.icon_dead = evil_tree.icon_state
evil_tree.icon_gib = evil_tree.icon_state
qdel(xmas) //b-but I don't want to delete xmas...
//this is an example of a possible round-start event
/datum/round_event_control/presents
name = "Presents under Trees (Christmas)"
@@ -24,12 +8,11 @@
earliest_start = 0
/datum/round_event/presents/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
for(var/obj/structure/flora/tree/pine/xmas/xmas in world)
if(!(xmas.z in GLOB.station_z_levels))
continue
for(var/turf/open/floor/T in orange(1,xmas))
for(var/i=1,i<=rand(1,5),i++)
new /obj/item/a_gift(T)
xmas.icon_state = "pinepresents"
xmas.gifts_under_tree = TRUE
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
@@ -98,7 +81,7 @@
name = "Santa is coming to town! (Christmas)"
holidayID = CHRISTMAS
typepath = /datum/round_event/santa
weight = 150
weight = 20
max_occurrences = 1
earliest_start = 20000
@@ -1,4 +1,3 @@
/obj/machinery/gibber
name = "gibber"
desc = "The name isn't descriptive enough?"
@@ -12,10 +11,10 @@
circuit = /obj/item/circuitboard/machine/gibber
var/operating = FALSE //Is it on?
var/dirty = 0 // Does it need cleaning?
var/dirty = FALSE // Does it need cleaning?
var/gibtime = 40 // Time from starting until meat appears
var/meat_produced = 0
var/ignore_clothing = 0
var/ignore_clothing = FALSE
/obj/machinery/gibber/Initialize()
@@ -30,7 +29,7 @@
gib_time -= 5 * M.rating
gibtime = gib_time
if(M.rating >= 2)
ignore_clothing = 1
ignore_clothing = TRUE
/obj/machinery/gibber/update_icon()
cut_overlays()
@@ -61,6 +60,10 @@
to_chat(user, "<span class='danger'>It's locked and running.</span>")
return
if(!anchored)
to_chat(user, "<span class='notice'>[src] cannot be used unless bolted to the ground.</span>")
return
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
var/mob/living/L = user.pulling
if(!iscarbon(L))
@@ -70,12 +73,17 @@
if(C.buckled ||C.has_buckled_mobs())
to_chat(user, "<span class='warning'>[C] is attached to something!</span>")
return
if(C.abiotic(1) && !ignore_clothing)
to_chat(user, "<span class='danger'>Subject may not have abiotic items on.</span>")
return
if(!ignore_clothing)
for(var/obj/item/I in C.held_items + C.get_equipped_items())
if(!(I.flags_1 & NODROP_1))
to_chat(user, "<span class='danger'>Subject may not have abiotic items on.</span>")
return
user.visible_message("<span class='danger'>[user] starts to put [C] into the gibber!</span>")
src.add_fingerprint(user)
add_fingerprint(user)
if(do_after(user, gibtime, target = src))
if(C && user.pulling == C && !C.buckled && !C.has_buckled_mobs() && !occupant)
user.visible_message("<span class='danger'>[user] stuffs [C] into the gibber!</span>")
+2 -2
View File
@@ -387,9 +387,9 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
/datum/holiday/xmas
name = CHRISTMAS
begin_day = 23
begin_day = 22
begin_month = DECEMBER
end_day = 25
end_day = 27
/datum/holiday/xmas/greet()
return "Have a merry Christmas!"
+2 -2
View File
@@ -146,7 +146,7 @@
/obj/item/reagent_containers/food/snacks/grown/on_grind()
var/nutriment = reagents.get_reagent_amount("nutriment")
if(grind_results.len)
if(grind_results&&grind_results.len)
for(var/i in 1 to grind_results.len)
grind_results[grind_results[i]] = nutriment
reagents.del_reagent("nutriment")
@@ -154,7 +154,7 @@
/obj/item/reagent_containers/food/snacks/grown/on_juice()
var/nutriment = reagents.get_reagent_amount("nutriment")
if(juice_results.len)
if(juice_results&&juice_results.len)
for(var/i in 1 to juice_results.len)
juice_results[juice_results[i]] = nutriment
reagents.del_reagent("nutriment")
@@ -20,6 +20,8 @@
var/charge_tick = FALSE
var/charge_delay = 4
var/use_cyborg_cell = TRUE
max_integrity = 50
armor = list(melee = 50, bullet = 70, laser = 70, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 0, acid = 0)
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
return user.canUseTopic(src,be_close = TRUE)
@@ -30,8 +32,6 @@
START_PROCESSING(SScircuit, src)
materials[MAT_METAL] = round((max_complexity + max_components) / 4) * SScircuit.cost_multiplier
/obj/item/device/electronic_assembly/Destroy()
STOP_PROCESSING(SScircuit, src)
return ..()
@@ -273,22 +273,9 @@
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
for(var/obj/item/integrated_circuit/input/sensor/S in assembly_components)
if(!proximity)
if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user))
if(user.client)
if(!(target in view(user.client)))
continue
else
if(!(target in view(user)))
continue
else
continue
S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
S.check_then_do_work()
S.scan(target)
visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
for(var/obj/item/integrated_circuit/input/S in assembly_components)
if(S.sense(target,user,proximity))
visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
/obj/item/device/electronic_assembly/screwdriver_act(mob/living/user, obj/item/S)
@@ -326,8 +313,11 @@
interact(user)
return TRUE
else
for(var/obj/item/integrated_circuit/input/S in assembly_components)
S.attackby_react(I,user,user.a_intent)
return ..()
/obj/item/device/electronic_assembly/attack_self(mob/user)
if(!check_interactivity(user))
return
@@ -391,7 +381,6 @@
/obj/item/device/electronic_assembly/proc/get_object()
return src
// Returns the location to be used for dropping items.
// Same as the regular drop_location(), but with checks being run on acting_object if necessary.
/obj/item/integrated_circuit/drop_location()
@@ -406,6 +395,7 @@
/obj/item/device/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves.
name = "type-a electronic assembly"
/obj/item/device/electronic_assembly/calc
name = "type-b electronic assembly"
icon_state = "setup_small_calc"
@@ -507,4 +497,4 @@
/obj/item/device/electronic_assembly/drone/arms
name = "type-b electronic drone"
icon_state = "setup_drone_arms"
desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
@@ -56,7 +56,7 @@
data_to_show = A.name
to_chat(user, "<span class='notice'>You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].</span>")
else if(io.io_type == PULSE_CHANNEL)
io.holder.check_then_do_work(ignore_power = TRUE)
io.holder.check_then_do_work(io.ord,ignore_power = TRUE)
to_chat(user, "<span class='notice'>You pulse \the [io.holder]'s [io].</span>")
io.holder.interact(user) // This is to update the UI.
@@ -15,9 +15,9 @@
io_type_override = io_list_copy[io_entry]
if(io_type_override)
io_list.Add(new io_type_override(src, io_entry, default_data, pin_type))
io_list.Add(new io_type_override(src, io_entry, default_data, pin_type,i))
else
io_list.Add(new io_type(src, io_entry, default_data, pin_type))
io_list.Add(new io_type(src, io_entry, default_data, pin_type,i))
/obj/item/integrated_circuit/proc/set_pin_data(pin_type, pin_number, datum/new_data)
@@ -58,6 +58,12 @@ a creative player the means to solve many problems. Circuits are held inside an
/obj/item/integrated_circuit/proc/any_examine(mob/user)
return
/obj/item/integrated_circuit/proc/attackby_react(var/atom/movable/A,mob/user)
return
/obj/item/integrated_circuit/proc/sense(var/atom/movable/A,mob/user,prox)
return
/obj/item/integrated_circuit/proc/check_interactivity(mob/user)
if(assembly)
return assembly.check_interactivity(user)
@@ -291,17 +297,18 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE // Battery has enough.
return FALSE // Not enough power.
/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
/obj/item/integrated_circuit/proc/check_then_do_work(ord,var/ignore_power = FALSE)
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
return
return FALSE
if(power_draw_per_use && !ignore_power)
if(!check_power())
power_fail()
return
return FALSE
next_use = world.time + cooldown_per_use
do_work()
do_work(ord)
return TRUE
/obj/item/integrated_circuit/proc/do_work()
/obj/item/integrated_circuit/proc/do_work(ord)
return
/obj/item/integrated_circuit/proc/disconnect_all()
@@ -369,4 +376,3 @@ a creative player the means to solve many problems. Circuits are held inside an
return TRUE
return FALSE
@@ -25,14 +25,16 @@ D [1]/ ||
var/list/linked = list()
var/io_type = DATA_CHANNEL
var/pin_type // IC_INPUT, IC_OUTPUT, IC_ACTIVATOR - used in saving assembly wiring
var/ord
/datum/integrated_io/New(loc, _name, _data, _pin_type)
/datum/integrated_io/New(loc, _name, _data, _pin_type,_ord)
name = _name
if(_data)
data = _data
if(_pin_type)
pin_type = _pin_type
if(_ord)
ord = _ord
holder = loc
@@ -148,7 +150,7 @@ D [1]/ ||
/datum/integrated_io/activate/push_data()
for(var/k in 1 to linked.len)
var/datum/integrated_io/io = linked[k]
io.holder.check_then_do_work()
io.holder.check_then_do_work(io.ord)
/datum/integrated_io/proc/pull_data()
for(var/k in 1 to linked.len)
@@ -207,7 +209,7 @@ D [1]/ ||
write_data_to_pin(new_data)
/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin.
holder.check_then_do_work(ignore_power = TRUE)
holder.check_then_do_work(ord,ignore_power = TRUE)
to_chat(user, "<span class='notice'>You pulse \the [holder]'s [src] pin.</span>")
/datum/integrated_io/activate
@@ -1,4 +1,4 @@
// These pins can only contain integer numbers between 1 and IC_MAX_LIST_LENGTH. Null is not allowed.
// These pins can only contain integer numbers between 0 and IC_MAX_LIST_LENGTH. Null is allowed.
/datum/integrated_io/index
name = "index pin"
data = 1
@@ -11,10 +11,10 @@
/datum/integrated_io/index/write_data_to_pin(new_data)
if(isnull(new_data))
new_data = 1
new_data = 0
if(isnum(new_data))
data = CLAMP(round(new_data), 1, IC_MAX_LIST_LENGTH)
data = CLAMP(round(new_data), 0, IC_MAX_LIST_LENGTH)
holder.on_data_written()
/datum/integrated_io/index/display_pin_type()
@@ -30,10 +30,9 @@
/obj/item/integrated_circuit/arithmetic/addition/do_work()
var/result = 0
for(var/k in 1 to inputs.len)
var/datum/integrated_io/I = inputs[k]
I.pull_data()
if(isnum(I.data))
result = result + I.data
var/I = get_pin_data(IC_INPUT, k)
if(isnum(I))
result += I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -56,13 +55,10 @@
return
var/result = A.data
for(var/k in 1 to inputs.len)
var/datum/integrated_io/I = inputs[k]
if(I == A)
continue
I.pull_data()
if(isnum(I.data))
result = result - I.data
for(var/k in 2 to inputs.len)
var/I = get_pin_data(IC_INPUT, k)
if(isnum(I))
result -= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -85,13 +81,10 @@
if(!isnum(A.data))
return
var/result = A.data
for(var/k in 1 to inputs.len)
var/datum/integrated_io/I = inputs[k]
if(I == A)
continue
I.pull_data()
if(isnum(I.data))
result = result * I.data
for(var/k in 2 to inputs.len)
var/I = get_pin_data(IC_INPUT, k)
if(isnum(I))
result *= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -114,13 +107,12 @@
return
var/result = A.data
for(var/k in 1 to inputs.len)
var/datum/integrated_io/I = inputs[k]
if(I == A)
continue
I.pull_data()
if(isnum(I.data) && I.data != 0) //No runtimes here.
result = result / I.data
for(var/k in 2 to inputs.len)
var/I = get_pin_data(IC_INPUT, k)
if(isnum(I) && (I != 0))
result /= I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -228,12 +220,11 @@
/obj/item/integrated_circuit/arithmetic/average/do_work()
var/result = 0
var/inputs_used = 0
for(var/k in 1 to inputs.len)
var/datum/integrated_io/I = inputs[k]
I.pull_data()
if(isnum(I.data))
for(var/k in 2 to inputs.len)
var/I = get_pin_data(IC_INPUT, k)
if(isnum(I))
inputs_used++
result = result + I.data
result += I
if(inputs_used)
result = result / inputs_used
@@ -288,11 +279,10 @@
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
var/result = 0
for(var/k in 1 to inputs.len)
var/datum/integrated_io/I = inputs[k]
I.pull_data()
if(isnum(I.data))
result = sqrt(I.data)
for(var/k in 2 to inputs.len)
var/I = get_pin_data(IC_INPUT, k)
if(isnum(I))
result += sqrt(I)
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -160,10 +160,10 @@
/obj/item/integrated_circuit/converter/concatenator/do_work()
var/result = null
for(var/datum/integrated_io/I in inputs)
I.pull_data()
if(!isnull(I.data))
result = result + I.data
for(var/k in 1 to inputs.len)
var/I = get_pin_data(IC_INPUT, k)
if(!isnull(I))
result = result + I
set_pin_data(IC_OUTPUT, 1, result)
push_data()
@@ -128,7 +128,7 @@
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
if(!istype(H)) //Invalid input
return
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
var/missing_health = H.getMaxHealth() - H.health
@@ -143,6 +143,49 @@
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/slime_scanner
name = "slime_scanner"
desc = "A very small version of the xenobio analyser. This allows the machine to know every needed properties of slime."
icon_state = "medscan_adv"
complexity = 12
inputs = list("\<REF\> target")
outputs = list(
"colour" = IC_PINTYPE_STRING,
"adult" = IC_PINTYPE_BOOLEAN,
"nutrition" = IC_PINTYPE_NUMBER,
"charge" = IC_PINTYPE_NUMBER,
"health" = IC_PINTYPE_NUMBER,
"possible mutation" = IC_PINTYPE_LIST,
"genetic destability"= IC_PINTYPE_NUMBER,
"slime core amount" = IC_PINTYPE_NUMBER,
"Growth progress" = IC_PINTYPE_NUMBER,
)
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 80
/obj/item/integrated_circuit/input/slime_scanner/do_work()
var/mob/living/simple_animal/slime/T = get_pin_data_as_type(IC_INPUT, 1, /mob/living/simple_animal/slime)
if(!isslime(T)) //Invalid input
return
if(T in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
set_pin_data(IC_OUTPUT, 1, T.colour)
set_pin_data(IC_OUTPUT, 2, T.is_adult)
set_pin_data(IC_OUTPUT, 3, T.nutrition/T.get_max_nutrition())
set_pin_data(IC_OUTPUT, 4, T.powerlevel)
set_pin_data(IC_OUTPUT, 5, round(T.health/T.maxHealth,0.01)*100)
set_pin_data(IC_OUTPUT, 6, uniqueList(T.slime_mutation))
set_pin_data(IC_OUTPUT, 7, T.mutation_chance)
set_pin_data(IC_OUTPUT, 8, T.cores)
set_pin_data(IC_OUTPUT, 9, T.amount_grown/SLIME_EVOLUTION_THRESHOLD)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/plant_scanner
name = "integrated plant analyzer"
desc = "A very small version of the plant analyser. This allows the machine to know all valuable params of plants in trays. \
@@ -180,7 +223,7 @@
return
for(var/i=1, i<=outputs.len, i++)
set_pin_data(IC_OUTPUT, i, null)
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
if(H.myseed)
set_pin_data(IC_OUTPUT, 1, H.myseed.plantname)
set_pin_data(IC_OUTPUT, 2, H.age)
@@ -228,7 +271,7 @@
return
for(var/i=1, i<=outputs.len, i++)
set_pin_data(IC_OUTPUT, i, null)
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
if(H in view(get_turf(src))) // Like medbot's analyzer it can be used in range..
if(H.myseed)
for(var/datum/plant_gene/reagent/G in H.myseed.genes)
greagents.Add(G.get_name())
@@ -671,12 +714,15 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
/obj/item/integrated_circuit/input/sensor/sense(var/atom/A,mob/user,prox)
if(!prox)
return FALSE
if(!check_then_do_work())
return FALSE
var/ignore_bags = get_pin_data(IC_INPUT, 1)
if(ignore_bags)
if(istype(A, /obj/item/storage))
return FALSE
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
push_data()
activate_pin(1)
@@ -694,6 +740,52 @@
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 120
/obj/item/integrated_circuit/input/sensor/ranged/sense(var/atom/A,mob/user)
if(!user)
return FALSE
if(user.client)
if(!(A in view(user.client)))
return FALSE
else
if(!(A in view(user)))
return FALSE
if(!check_then_do_work())
return FALSE
var/ignore_bags = get_pin_data(IC_INPUT, 1)
if(ignore_bags)
if(istype(A, /obj/item/storage))
return FALSE
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
push_data()
activate_pin(1)
return TRUE
/obj/item/integrated_circuit/input/objscaner
name = "scaner"
desc = "Scans and obtains a reference for any objects you use on assembly."
extended_desc = "If 'put down' pin is set to true, assembly will take scanned object from your hands to it's location.\
useful for interaction with grabber. Scaner works only with help intent."
icon_state = "recorder"
complexity = 4
inputs = list("put down" = IC_PINTYPE_BOOLEAN)
outputs = list("scanned" = IC_PINTYPE_REF)
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 20
/obj/item/integrated_circuit/input/objscaner/attackby_react(var/atom/A,var/mob/user,intent)
if(intent!=INTENT_HELP)
return FALSE
if(!check_then_do_work())
return FALSE
var/pu = get_pin_data(IC_INPUT, 1)
if(pu)
user.transferItemToLoc(A,drop_location())
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
push_data()
activate_pin(1)
return TRUE
/obj/item/integrated_circuit/input/internalbm
name = "internal battery monitor"
desc = "This monitors the charge level of an internal battery."
@@ -760,3 +852,38 @@
activate_pin(2)
push_data()
return
/obj/item/integrated_circuit/input/ntnetsc
name = "NTnet scaner"
desc = "This can return NTnet id of component insi given object, if there is any."
icon_state = "signalsc"
w_class = WEIGHT_CLASS_TINY
complexity = 2
inputs = list("target" = IC_PINTYPE_REF)
outputs = list(
"id" = IC_PINTYPE_STRING
)
activators = list("read" = IC_PINTYPE_PULSE_IN, "found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 1
/obj/item/integrated_circuit/input/ntnetsc/do_work()
var/atom/AM = get_pin_data_as_type(IC_INPUT, 1, /atom)
var/list/processing_list = list(AM)
var/datum/component/ntnet_interface/net = null
set_pin_data(IC_OUTPUT, 1, null)
while(processing_list.len && !net)
var/atom/A = processing_list[1]
processing_list.Cut(1, 2)
//Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
//This is also why we don't need to check against assembled as we go along
processing_list += A.contents
net = A.GetComponent(/datum/component/ntnet_interface)
if(net)
set_pin_data(IC_OUTPUT, 1, net.hardware_id)
activate_pin(2)
else
activate_pin(3)
push_data()
return
@@ -2,7 +2,7 @@
name = "logic gate"
desc = "This tiny chip will decide for you!"
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
complexity = 3
complexity = 1
outputs = list("result")
activators = list("compare" = IC_PINTYPE_PULSE_IN)
category_text = "Logic"
@@ -155,9 +155,11 @@
if(isnum(wanted_dir.data))
if(step(assembly, wanted_dir.data))
activate_pin(2)
return
else
activate_pin(3)
return FALSE
return FALSE
/obj/item/integrated_circuit/manipulation/grenade
name = "grenade primer"
@@ -247,9 +249,14 @@
/obj/item/integrated_circuit/manipulation/plant_module/do_work()
..()
var/turf/T = get_turf(src)
var/obj/machinery/hydroponics/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
if(!istype(AM)) //Invalid input
var/obj/OM = get_pin_data_as_type(IC_INPUT, 1, /obj)
if(istype(OM,/obj/structure/spacevine) && get_pin_data(IC_INPUT, 2) == 2)
qdel(OM)
activate_pin(2)
return
var/obj/machinery/hydroponics/AM = OM
if(!istype(AM)) //Invalid input
return FALSE
var/mob/living/M = get_turf(AM)
if(!M.Adjacent(T))
return //Can't reach
@@ -276,6 +283,7 @@
qdel(AM.myseed)
AM.myseed = null
AM.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds
AM.dead = 0
AM.update_icon()
else
activate_pin(2)
@@ -284,7 +292,7 @@
/obj/item/integrated_circuit/manipulation/grabber
name = "grabber"
desc = "A circuit with it's own inventory for small/medium items, used to grab and store things."
desc = "A circuit with it's own inventory for tiny/small items, used to grab and store things."
icon_state = "grabber"
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
w_class = WEIGHT_CLASS_SMALL
@@ -307,7 +315,7 @@
var/mode = get_pin_data(IC_INPUT, 2)
if(mode == 1)
if(check_target(AM, exclude_contents = TRUE))
if(check_target(AM))
if((contents.len < max_items) && (!max_w_class || AM.w_class <= max_w_class))
AM.forceMove(src)
if(mode == 0)
@@ -9,6 +9,11 @@
. = ..()
if(volume)
create_reagents(volume)
push_vol()
/obj/item/integrated_circuit/reagent/proc/push_vol()
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
push_data()
/obj/item/integrated_circuit/reagent/smoke
name = "smoke generator"
@@ -29,7 +34,8 @@
)
activators = list(
"create smoke" = IC_PINTYPE_PULSE_IN,
"on smoked" = IC_PINTYPE_PULSE_OUT
"on smoked" = IC_PINTYPE_PULSE_OUT,
"push ref" = IC_PINTYPE_PULSE_IN
)
spawn_flags = IC_SPAWN_RESEARCH
power_draw_per_use = 20
@@ -40,24 +46,27 @@
//reset warning only if we have reagents now
if(changetype == ADD_REAGENT)
notified = FALSE
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
push_data()
push_vol()
/obj/item/integrated_circuit/reagent/smoke/do_work()
if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS))
return
var/location = get_turf(src)
var/datum/effect_system/smoke_spread/chem/S = new
S.attach(location)
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
if(S)
S.set_up(reagents, smoke_radius, location, notified)
if(!notified)
notified = TRUE
S.start()
reagents.clear_reagents()
activate_pin(2)
/obj/item/integrated_circuit/reagent/smoke/do_work(ord)
switch(ord)
if(1)
if(!reagents || (reagents.total_volume < IC_SMOKE_REAGENTS_MINIMUM_UNITS))
return
var/location = get_turf(src)
var/datum/effect_system/smoke_spread/chem/S = new
S.attach(location)
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
if(S)
S.set_up(reagents, smoke_radius, location, notified)
if(!notified)
notified = TRUE
S.start()
reagents.clear_reagents()
activate_pin(2)
if(3)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/injector
name = "integrated hypo-injector"
@@ -85,7 +94,9 @@
activators = list(
"inject" = IC_PINTYPE_PULSE_IN,
"on injected" = IC_PINTYPE_PULSE_OUT,
"on fail" = IC_PINTYPE_PULSE_OUT
"on fail" = IC_PINTYPE_PULSE_OUT,
"push ref" = IC_PINTYPE_PULSE_IN
)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
power_draw_per_use = 15
@@ -93,15 +104,8 @@
var/transfer_amount = 10
var/busy = FALSE
/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
..()
/obj/item/integrated_circuit/reagent/injector/on_reagent_change(changetype)
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
push_data()
push_vol()
/obj/item/integrated_circuit/reagent/injector/on_data_written()
var/new_amount = get_pin_data(IC_INPUT, 2)
@@ -127,7 +131,15 @@
temp_reagents.clear_reagents()
qdel(temp_reagents)
/obj/item/integrated_circuit/reagent/injector/do_work()
/obj/item/integrated_circuit/reagent/injector/do_work(ord)
switch(ord)
if(1)
inject()
if(4)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/injector/proc/inject()
set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
var/atom/movable/acting_object = get_object()
@@ -281,17 +293,15 @@
"volume used" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF
)
activators = list()
activators = list("push ref" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
/obj/item/integrated_circuit/reagent/storage/do_work()
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
..()
/obj/item/integrated_circuit/reagent/storage/on_reagent_change(changetype)
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
push_data()
push_vol()
/obj/item/integrated_circuit/reagent/storage/cryo
name = "cryo reagent storage"
@@ -306,6 +316,7 @@
. = ..()
reagents.set_reacting(FALSE)
/obj/item/integrated_circuit/reagent/storage/big
name = "big reagent storage"
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
@@ -317,6 +328,99 @@
complexity = 16
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/reagent/storage/grinder
name = "reagent grinder"
desc = "This is reagent grinder.It accepts ref to something and refines it into reagents. Can store up to 100u."
icon_state = "blender"
extended_desc = ""
inputs = list(
"target" = IC_PINTYPE_REF,
)
outputs = list(
"volume used" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF
)
activators = list(
"grind" = IC_PINTYPE_PULSE_IN,
"on grind" = IC_PINTYPE_PULSE_OUT,
"on fail" = IC_PINTYPE_PULSE_OUT,
"push ref" = IC_PINTYPE_PULSE_IN
)
volume = 100
power_draw_per_use = 150
complexity = 16
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/reagent/storage/grinder/do_work(ord)
switch(ord)
if(1)
grind()
if(4)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/storage/grinder/proc/grind()
if(reagents.total_volume >= reagents.maximum_volume)
activate_pin(3)
return FALSE
var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
if(istype(I)&&(I.grind_results)&&check_target(I)&&(I.on_grind(src) != -1))
reagents.add_reagent_list(I.grind_results)
if(I.reagents)
I.reagents.trans_to(src, I.reagents.total_volume)
qdel(I)
activate_pin(2)
return TRUE
activate_pin(3)
return FALSE
obj/item/integrated_circuit/reagent/storage/juicer
name = "reagent juicer"
desc = "This is reagent juicer.It accepts ref to something and refines it into reagents. Can store up to 100u."
icon_state = "blender"
extended_desc = ""
inputs = list(
"target" = IC_PINTYPE_REF,
)
outputs = list(
"volume used" = IC_PINTYPE_NUMBER,
"self reference" = IC_PINTYPE_REF
)
activators = list(
"juice" = IC_PINTYPE_PULSE_IN,
"on juice" = IC_PINTYPE_PULSE_OUT,
"on fail" = IC_PINTYPE_PULSE_OUT,
"push ref" = IC_PINTYPE_PULSE_IN
)
volume = 100
power_draw_per_use = 150
complexity = 16
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/reagent/storage/juicer/do_work(ord)
switch(ord)
if(1)
juice()
if(4)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/storage/juicer/proc/juice()
if(reagents.total_volume >= reagents.maximum_volume)
activate_pin(3)
return FALSE
var/obj/item/I = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
if(istype(I)&&check_target(I)&&(I.juice_results)&&(I.on_juice() != -1))
reagents.add_reagent_list(I.juice_results)
qdel(I)
activate_pin(2)
return TRUE
activate_pin(3)
return FALSE
/obj/item/integrated_circuit/reagent/storage/scan
name = "reagent scanner"
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents."
@@ -330,17 +434,22 @@
"list of reagents" = IC_PINTYPE_LIST
)
activators = list(
"scan" = IC_PINTYPE_PULSE_IN
"scan" = IC_PINTYPE_PULSE_IN,
"push ref" = IC_PINTYPE_PULSE_IN
)
spawn_flags = IC_SPAWN_RESEARCH
/obj/item/integrated_circuit/reagent/storage/scan/do_work()
var/cont[0]
for(var/datum/reagent/RE in reagents.reagent_list)
cont += RE.id
set_pin_data(IC_OUTPUT, 3, cont)
push_data()
/obj/item/integrated_circuit/reagent/storage/scan/do_work(ord)
switch(ord)
if(1)
var/cont[0]
for(var/datum/reagent/RE in reagents.reagent_list)
cont += RE.id
set_pin_data(IC_OUTPUT, 3, cont)
push_data()
if(2)
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
push_data()
/obj/item/integrated_circuit/reagent/filter
name = "reagent filter"
@@ -394,7 +503,8 @@
if(!source.reagents || !target.reagents)
return
if(!source.is_drainable() || !target.is_refillable())
// FALSE in those procs makes mobs invalid targets.
if(!source.is_drawable(FALSE) || !target.is_injectable(FALSE))
return
if(target.reagents.maximum_volume - target.reagents.total_volume <= 0)
@@ -410,3 +520,45 @@
activate_pin(2)
push_data()
/obj/item/integrated_circuit/reagent/storage/heater
name = "chemical heater"
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. Will heat or freeze reagents \
to target temperature, when turned on."
icon_state = "heater"
container_type = OPENCONTAINER
complexity = 8
inputs = list(
"target temperature" = IC_PINTYPE_NUMBER,
"on" = IC_PINTYPE_BOOLEAN
)
inputs_default = list("1" = 300)
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"temperature" = IC_PINTYPE_NUMBER)
spawn_flags = IC_SPAWN_RESEARCH
var/heater_coefficient = 0.1
/obj/item/integrated_circuit/reagent/storage/heater/on_data_written()
if(get_pin_data(IC_INPUT, 2))
power_draw_idle = 30
else
power_draw_idle = 0
/obj/item/integrated_circuit/reagent/storage/heater/Initialize()
.=..()
START_PROCESSING(SScircuit, src)
/obj/item/integrated_circuit/reagent/storage/heater/Destroy()
STOP_PROCESSING(SScircuit, src)
return ..()
/obj/item/integrated_circuit/reagent/storage/heater/process()
if(power_draw_idle)
var/target_temperature = get_pin_data(IC_INPUT, 1)
if(reagents.chem_temp > target_temperature)
reagents.chem_temp += min(-1, (target_temperature - reagents.chem_temp) * heater_coefficient)
if(reagents.chem_temp < target_temperature)
reagents.chem_temp += max(1, (target_temperature - reagents.chem_temp) * heater_coefficient)
reagents.chem_temp = round(reagents.chem_temp)
reagents.handle_reactions()
set_pin_data(IC_OUTPUT, 3, reagents.chem_temp)
push_data()
@@ -27,6 +27,6 @@
push_data()
return // Can't see the target.
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A)))
push_data()
activate_pin(2)
+18
View File
@@ -0,0 +1,18 @@
// You might be wondering why this isn't client level. If focus is null, we don't want you to move.
// Only way to do that is to tie the behavior into the focus's keyLoop().
/atom/movable/keyLoop(client/user)
if(!user.keys_held["Ctrl"])
var/movement_dir = NONE
for(var/_key in user.keys_held)
movement_dir = movement_dir | GLOB.movement_keys[_key]
if(user.next_move_dir_add)
movement_dir |= user.next_move_dir_add
if(user.next_move_dir_sub)
movement_dir &= ~user.next_move_dir_sub
// Sanity checks in case you hold left and right and up to make sure you only go up
if((movement_dir & NORTH) && (movement_dir & SOUTH))
movement_dir &= ~(NORTH|SOUTH)
if((movement_dir & EAST) && (movement_dir & WEST))
movement_dir &= ~(EAST|WEST)
user.Move(get_step(src, movement_dir), movement_dir)
+1 -1
View File
@@ -142,7 +142,7 @@
hidden_message = newmessage
creator_name = user.real_name
creator_key = user.ckey
realdate = world.timeofday
realdate = world.realtime
map = SSmapping.config.map_name
update_icon()
@@ -656,7 +656,7 @@
playsound(user, 'sound/magic/clockwork/fellowship_armory.ogg', 35, TRUE, frequency = 90000 - (active * 30000))
/obj/item/melee/transforming/cleaving_saw/clumsy_transform_effect(mob/living/user)
if(user.disabilities & CLUMSY && prob(50))
if(user.has_disability(CLUMSY) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
user.take_bodypart_damage(10)
+4 -4
View File
@@ -16,7 +16,7 @@
/mob/living/carbon/monkey/handle_blood()
if(bodytemperature >= 225 && !(disabilities & NOCLONE)) //cryosleep or husked people do not pump the blood.
if(bodytemperature >= 225 && !(has_disability(NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL)
blood_volume += 0.1 // regenerate blood VERY slowly
@@ -28,7 +28,7 @@
bleed_rate = 0
return
if(bodytemperature >= 225 && !(disabilities & NOCLONE)) //cryosleep or husked people do not pump the blood.
if(bodytemperature >= 225 && !(has_disability(NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL && !(NOHUNGER in dna.species.species_traits))
@@ -201,13 +201,13 @@
return "blood"
/mob/living/carbon/monkey/get_blood_id()
if(!(disabilities & NOCLONE))
if(!(has_disability(NOCLONE)))
return "blood"
/mob/living/carbon/human/get_blood_id()
if(dna.species.exotic_blood)
return dna.species.exotic_blood
else if((NOBLOOD in dna.species.species_traits) || (disabilities & NOCLONE))
else if((NOBLOOD in dna.species.species_traits) || (has_disability(NOCLONE)))
return
return "blood"
+2 -2
View File
@@ -79,8 +79,8 @@
if(!brainmob.stored_dna)
brainmob.stored_dna = new /datum/dna/stored(brainmob)
C.dna.copy_dna(brainmob.stored_dna)
if(L.disabilities & NOCLONE)
brainmob.disabilities |= NOCLONE //This is so you can't just decapitate a husked guy and clone them without needing to get a new body
if(L.has_disability(NOCLONE))
brainmob.disabilities[NOCLONE] = L.disabilities[NOCLONE]
var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
if(ZI)
brainmob.set_species(ZI.old_species) //For if the brain is cloned
+4 -4
View File
@@ -157,7 +157,7 @@
if(!throwable_mob.buckled)
thrown_thing = throwable_mob
stop_pulling()
if(disabilities & PACIFISM)
if(has_disability(PACIFISM))
to_chat(src, "<span class='notice'>You gently let go of [throwable_mob].</span>")
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
@@ -170,7 +170,7 @@
thrown_thing = I
dropItemToGround(I)
if(disabilities & PACIFISM && I.throwforce)
if(has_disability(PACIFISM) && I.throwforce)
to_chat(src, "<span class='notice'>You set [I] down gently on the ground.</span>")
return
@@ -409,7 +409,7 @@
dropItemToGround(I)
var/modifier = 0
if(disabilities & CLUMSY)
if(has_disability(CLUMSY))
modifier -= 40 //Clumsy people are more likely to hit themselves -Honk!
switch(rand(1,100)+modifier) //91-100=Nothing special happens
@@ -518,7 +518,7 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
update_stat()
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
become_husk()
become_husk("burn")
med_hud_set_health()
/mob/living/carbon/update_sight()
@@ -306,11 +306,15 @@
if(eyes.eye_damage > 20)
if(prob(eyes.eye_damage - 20))
if(become_nearsighted())
if(!has_disability(NEARSIGHT))
to_chat(src, "<span class='warning'>Your eyes start to burn badly!</span>")
become_nearsighted(EYE_DAMAGE)
else if(prob(eyes.eye_damage - 25))
if(become_blind())
if(!has_disability(BLIND))
to_chat(src, "<span class='warning'>You can't see anything!</span>")
become_blind(EYE_DAMAGE)
else
to_chat(src, "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>")
if(has_bane(BANE_LIGHT))
@@ -48,7 +48,7 @@
/mob/living/carbon/proc/Drain()
become_husk()
disabilities |= NOCLONE
become_husk(CHANGELING_DRAIN)
add_disability(NOCLONE, CHANGELING_DRAIN)
blood_volume = 0
return 1
@@ -44,7 +44,10 @@
if(mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(mind.martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
if(mind.martial_art.deflection_chance >= 100) //if they can NEVER be hit, lets clue sec in ;)
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
else
visible_message("<span class='danger'>[src] deflects the projectile!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
@@ -140,8 +143,8 @@
return ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
vore_attack(user, pulling)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (has_disability(FAT)) && ismonkey(pulling))
devour_mob(pulling)
else
..()
@@ -91,19 +91,8 @@
return wear_id.GetID()
/mob/living/carbon/human/abiotic(full_body = 0)
var/abiotic_hands = FALSE
for(var/obj/item/I in held_items)
if(!(I.flags_1 & NODROP_1))
abiotic_hands = TRUE
break
if(full_body && abiotic_hands && ((back && !(back.flags_1&NODROP_1)) || (wear_mask && !(wear_mask.flags_1&NODROP_1)) || (head && !(head.flags_1&NODROP_1)) || (shoes && !(shoes.flags_1&NODROP_1)) || (w_uniform && !(w_uniform.flags_1&NODROP_1)) || (wear_suit && !(wear_suit.flags_1&NODROP_1)) || (glasses && !(glasses.flags_1&NODROP_1)) || (ears && !(ears.flags_1&NODROP_1)) || (gloves && !(gloves.flags_1&NODROP_1)) ) )
return TRUE
return abiotic_hands
/mob/living/carbon/human/IsAdvancedToolUser()
if(disabilities & MONKEYLIKE)
if(has_disability(MONKEYLIKE))
return FALSE
return TRUE//Humans can use guns and such
@@ -339,7 +339,7 @@
if(TRAITS & TRAIT_SMART)
smartness = 75
else if(TRAITS & TRAIT_DUMB)
disabilities |= CLUMSY
add_disability(CLUMSY, GENETIC_MUTATION)
smartness = 25
if(TRAITS & TRAIT_MEAN)
@@ -187,7 +187,7 @@
if(G.tint)
update_tint()
if(G.vision_correction)
if(disabilities & NEARSIGHT)
if(has_disability(NEARSIGHT))
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
adjust_eye_damage(0)
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
@@ -312,7 +312,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(!HD) //Decapitated
return
if(H.disabilities & HUSK)
if(H.has_disability(HUSK))
return
var/datum/sprite_accessory/S
var/list/standing = list()
@@ -453,7 +453,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/obj/item/bodypart/head/HD = H.get_bodypart("head")
if(HD && !(H.disabilities & HUSK))
if(HD && !(H.has_disability(HUSK)))
// lipstick
if(H.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
@@ -724,7 +724,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(S.center)
accessory_overlay = center_image(accessory_overlay, S.dimension_x, S.dimension_y)
if(!(H.disabilities & HUSK))
if(!(H.has_disability(HUSK)))
if(!forced_colour)
switch(S.color_src)
if(MUTCOLORS)
@@ -1103,16 +1103,16 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
//The fucking FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
if(H.disabilities & FAT)//I share your pain, past coder.
if(H.has_disability(FAT))//I share your pain, past coder.
if(H.overeatduration < 100)
to_chat(H, "<span class='notice'>You feel fit again!</span>")
H.disabilities &= ~FAT
H.remove_disability(FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
else
if(H.overeatduration > 500)
to_chat(H, "<span class='danger'>You suddenly feel blubbery!</span>")
H.disabilities |= FAT
H.add_disability(FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
@@ -1269,7 +1269,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
. += (health_deficiency / 25)
if((hungry >= 70) && !flight) //Being hungry won't stop you from using flightpack controls/flapping your wings although it probably will in the wing case but who cares.
. += hungry / 50
if(H.disabilities & FAT)
if(H.has_disability(FAT))
. += (1.5 - flight)
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
@@ -1315,7 +1315,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(user.disabilities & PACIFISM)
if(user.has_disability(PACIFISM))
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")
return FALSE
if(target.check_block())
@@ -725,7 +725,7 @@
/obj/structure/cloth_pile/proc/revive()
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
return
if(cloth_golem.suiciding || cloth_golem.disabilities & NOCLONE)
if(cloth_golem.suiciding || cloth_golem.has_disability(NOCLONE))
QDEL_NULL(cloth_golem)
return
@@ -11,12 +11,12 @@
amount = dna.species.spec_stun(src,amount)
return ..()
/mob/living/carbon/human/cure_husk()
/mob/living/carbon/human/cure_husk(list/sources)
. = ..()
if(.)
update_hair()
/mob/living/carbon/human/become_husk()
/mob/living/carbon/human/become_husk(source)
if(istype(dna.species, /datum/species/skeleton)) //skeletons shouldn't be husks.
cure_husk()
return
@@ -609,7 +609,7 @@ generate/load female uniform sprites matching all previously decided variables
if(BP.dmg_overlay_type)
. += "-[BP.dmg_overlay_type]"
if(disabilities & HUSK)
if(has_disability(HUSK))
. += "-husk"
/mob/living/carbon/human/load_limb_from_cache()
@@ -121,10 +121,8 @@
if(L == src)
return FALSE
if(disabilities & PACIFISM)
if(has_disability(PACIFISM))
return FALSE
if(enemies[L])
return TRUE

Some files were not shown because too many files have changed in this diff Show More