mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 13:07:46 +01:00
Merge branch 'master' into buttbots2
Conflicts: code/defines/procs/AStar.dm code/modules/mob/living/simple_animal/bot/cleanbot.dm code/modules/mob/living/simple_animal/bot/medbot.dm paradise.dme
This commit is contained in:
@@ -1789,7 +1789,7 @@ area/security/podbay
|
||||
|
||||
/area/toxins/xenobiology
|
||||
name = "\improper Xenobiology Lab"
|
||||
icon_state = "toxlab"
|
||||
icon_state = "toxmix"
|
||||
|
||||
/area/toxins/xenobiology/xenoflora_storage
|
||||
name = "\improper Xenoflora Storage"
|
||||
|
||||
+17
-4
@@ -362,6 +362,23 @@
|
||||
. = 1
|
||||
return 1
|
||||
|
||||
/atom/proc/add_blood_list(mob/living/carbon/M)
|
||||
// Returns 0 if we have that blood already
|
||||
if(!istype(blood_DNA, /list)) //if our list of DNA doesn't exist yet (or isn't a list) initialise it.
|
||||
blood_DNA = list()
|
||||
//if this blood isn't already in the list, add it
|
||||
if(blood_DNA[M.dna.unique_enzymes])
|
||||
return 0 //already bloodied with this blood. Cannot add more.
|
||||
var/blood_type = "X*"
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
blood_type = H.b_type
|
||||
blood_DNA[M.dna.unique_enzymes] = blood_type
|
||||
return 1
|
||||
|
||||
// Only adds blood on the floor -- Skie
|
||||
/atom/proc/add_blood_floor(mob/living/carbon/M)
|
||||
return //why the fuck this is at an atom level but only works on simulated turfs I don't know
|
||||
|
||||
/atom/proc/clean_blood()
|
||||
src.germ_level = 0
|
||||
@@ -377,10 +394,6 @@
|
||||
if(toxvomit)
|
||||
this.icon_state = "vomittox_[pick(1,4)]"
|
||||
|
||||
/atom/proc/add_poop_floor(mob/living/carbon/M as mob)
|
||||
if( istype(src, /turf/simulated) )
|
||||
new /obj/effect/decal/cleanable/poop(src)
|
||||
|
||||
|
||||
/atom/proc/get_global_map_pos()
|
||||
if(!islist(global_map) || isemptylist(global_map)) return
|
||||
|
||||
@@ -60,10 +60,11 @@
|
||||
|
||||
//called when a carbon changes virus
|
||||
/mob/living/carbon/proc/check_virus()
|
||||
for (var/ID in virus2)
|
||||
if (ID in virusDB)
|
||||
for(var/datum/disease/D in viruses)
|
||||
if((!(D.visibility_flags & HIDDEN_SCANNER)) && (D.severity != NONTHREAT))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//helper for getting the appropriate health status
|
||||
/proc/RoundHealth(health)
|
||||
switch(health)
|
||||
@@ -292,4 +293,4 @@
|
||||
if(BOT_MOVING, BOT_DELIVER, BOT_GO_HOME, BOT_NAV, BOT_WAIT_FOR_NAV) //Moving to target for normal bots, moving to deliver or go home for MULES.
|
||||
holder.icon_state = "hudmove"
|
||||
else
|
||||
holder.icon_state = ""
|
||||
holder.icon_state = ""
|
||||
|
||||
@@ -668,8 +668,6 @@
|
||||
shake_camera(M, 10, 5)
|
||||
if (M == usr)
|
||||
continue
|
||||
if(!airborne_can_reach(UT, T))
|
||||
continue
|
||||
M << "<span class='warning'>You are sent flying!</span>"
|
||||
M.Weaken(5)
|
||||
step_away(M, UT, 15)
|
||||
|
||||
@@ -23,12 +23,8 @@
|
||||
user.reagents.add_reagent("potass_iodide", 10)
|
||||
user.reagents.add_reagent("charcoal", 20)
|
||||
|
||||
if(istype(user, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.virus2.len)
|
||||
for (var/ID in C.virus2)
|
||||
var/datum/disease2/disease/V = C.virus2[ID]
|
||||
C.antibodies |= V.antigen
|
||||
for(var/datum/disease/D in user.viruses)
|
||||
D.cure()
|
||||
|
||||
feedback_add_details("changeling_powers","AP")
|
||||
return 1
|
||||
@@ -25,6 +25,7 @@
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
AIStatus = AI_OFF
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/ectoplasm = 1)
|
||||
var/summoned = FALSE
|
||||
var/cooldown = 0
|
||||
var/damage_transfer = 1 //how much damage from each attack we transfer to the owner
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
wander = 0
|
||||
attacktext = "glomps"
|
||||
attack_sound = 'sound/effects/blobattack.ogg'
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/slab
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2)
|
||||
|
||||
var/morphed = 0
|
||||
var/atom/movable/form = null
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
health = INFINITY //Revenants don't use health, they use essence instead
|
||||
maxHealth = INFINITY
|
||||
see_invisible = INVISIBILITY_REVENANT
|
||||
see_in_dark = 8
|
||||
universal_understand = 1
|
||||
response_help = "passes through"
|
||||
response_disarm = "swings at"
|
||||
@@ -33,6 +34,7 @@
|
||||
density = 0
|
||||
flying = 1
|
||||
anchored = 1
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
|
||||
var/essence = 75 //The resource of revenants. Max health is equal to three times this amount
|
||||
var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
|
||||
@@ -86,112 +88,19 @@
|
||||
if(essence == 0)
|
||||
src << "<span class='revendanger'>You feel your essence fraying!</span>"
|
||||
|
||||
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
|
||||
|
||||
if(client.click_intercept)
|
||||
client.click_intercept.InterceptClickOn(src, params, A)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["middle"])
|
||||
MiddleClickOn(A)
|
||||
return
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["alt"])
|
||||
AltClickOn(A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(world.time <= next_move)
|
||||
return
|
||||
A.attack_ghost(src)
|
||||
if(ishuman(A) && in_range(src, A))
|
||||
Harvest(A)
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target)
|
||||
if(!castcheck(0))
|
||||
return
|
||||
if(draining)
|
||||
src << "<span class='revenwarning'>You are already siphoning the essence of a soul!</span>"
|
||||
return
|
||||
if(target in drained_mobs)
|
||||
src << "<span class='revenwarning'>[target]'s soul is dead and empty.</span>"
|
||||
return
|
||||
if(!target.stat)
|
||||
src << "<span class='revennotice'>This being's soul is too strong to harvest.</span>"
|
||||
if(prob(10))
|
||||
target << "You feel as if you are being watched."
|
||||
return
|
||||
draining = 1
|
||||
essence_drained = rand(15, 20)
|
||||
src << "<span class='revennotice'>You search for the soul of [target].</span>"
|
||||
if(do_after(src, 10, 3, 0, target = target)) //did they get deleted in that second?
|
||||
if(target.ckey)
|
||||
src << "<span class='revennotice'>Their soul burns with intelligence.</span>"
|
||||
essence_drained += rand(20, 30)
|
||||
if(target.stat != DEAD)
|
||||
src << "<span class='revennotice'>Their soul blazes with life!</span>"
|
||||
essence_drained += rand(40, 50)
|
||||
else
|
||||
src << "<span class='revennotice'>Their soul is weak and faltering.</span>"
|
||||
if(do_after(src, 20, 6, 0, target = target)) //did they get deleted NOW?
|
||||
switch(essence_drained)
|
||||
if(1 to 30)
|
||||
src << "<span class='revennotice'>[target] will not yield much essence. Still, every bit counts.</span>"
|
||||
if(30 to 70)
|
||||
src << "<span class='revennotice'>[target] will yield an average amount of essence.</span>"
|
||||
if(70 to 90)
|
||||
src << "<span class='revenboldnotice'>Such a feast! [target] will yield much essence to you.</span>"
|
||||
if(90 to INFINITY)
|
||||
src << "<span class='revenbignotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
|
||||
if(do_after(src, 20, 6, 0, target = target)) //how about now
|
||||
if(!target.stat)
|
||||
src << "<span class='revenwarning'>They are now powerful enough to fight off your draining.</span>"
|
||||
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
|
||||
draining = 0
|
||||
return //hey, wait a minute...
|
||||
src << "<span class='revenminor'>You begin siphoning essence from [target]'s soul.</span>"
|
||||
if(target.stat != DEAD)
|
||||
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
|
||||
icon_state = "revenant_draining"
|
||||
reveal(27)
|
||||
stun(27)
|
||||
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
|
||||
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26)
|
||||
if(do_after(src, 30, 9, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
|
||||
change_essence_amount(essence_drained, 0, target)
|
||||
if(essence_drained > 90)
|
||||
essence_regen_cap += 25
|
||||
perfectsouls += 1
|
||||
src << "<span class='revenboldnotice'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
|
||||
src << "<span class='revennotice'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
|
||||
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
|
||||
"<span class='revenwarning'>Violets lights, dancing in your vision, getting clo--</span>")
|
||||
drained_mobs.Add(target)
|
||||
target.death(0)
|
||||
else
|
||||
src << "<span class='revenwarning'>[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken.</span>"
|
||||
draining = 0
|
||||
essence_drained = 0
|
||||
if(target) //Wait, target is WHERE NOW?
|
||||
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
|
||||
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
|
||||
return
|
||||
else
|
||||
src << "<span class='revenwarning'>You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken.</span>"
|
||||
draining = 0
|
||||
essence_drained = 0
|
||||
return
|
||||
draining = 0
|
||||
essence_drained = 0
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/revenant/say(message)
|
||||
return 0 //Revenants cannot speak out loud.
|
||||
if(!message)
|
||||
return
|
||||
log_say("[key_name(src)] : [message]")
|
||||
var/rendered = "<span class='revennotice'><b>[src]</b> says, \"[message]\"</span>"
|
||||
for(var/mob/M in mob_list)
|
||||
if(istype(M, /mob/living/simple_animal/revenant))
|
||||
M << rendered
|
||||
if(isobserver(M))
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a> [rendered]"
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/revenant/Stat()
|
||||
..()
|
||||
@@ -237,6 +146,7 @@
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/giveSpells()
|
||||
if(src.mind)
|
||||
src.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null))
|
||||
src.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
|
||||
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
|
||||
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
|
||||
@@ -244,9 +154,16 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/revenant/dust()
|
||||
death()
|
||||
|
||||
/mob/living/simple_animal/revenant/gib()
|
||||
death()
|
||||
|
||||
/mob/living/simple_animal/revenant/death()
|
||||
..()
|
||||
if(!revealed) //Revenants cannot die if they aren't revealed
|
||||
if(!revealed || stat == DEAD) //Revenants cannot die if they aren't revealed //or are already dead
|
||||
return
|
||||
ghost_darkness_images -= ghostimage
|
||||
updateallghostimages()
|
||||
@@ -263,6 +180,8 @@
|
||||
alpha = i
|
||||
visible_message("<span class='danger'>[src]'s body breaks apart into a fine pile of blue dust.</span>")
|
||||
var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src))
|
||||
var/reforming_essence = essence_regen_cap //retain the gained essence capacity
|
||||
R.essence = max(reforming_essence - 15 * perfectsouls, 75) //minus any perfect souls
|
||||
R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
|
||||
ghostize()
|
||||
qdel(src)
|
||||
@@ -356,7 +275,7 @@
|
||||
var/targetAmount = 100
|
||||
|
||||
/datum/objective/revenant/New()
|
||||
targetAmount = rand(200,500)
|
||||
targetAmount = rand(350,600)
|
||||
explanation_text = "Absorb [targetAmount] points of essence from humans."
|
||||
..()
|
||||
|
||||
@@ -374,12 +293,17 @@
|
||||
/datum/objective/revenantFluff
|
||||
|
||||
/datum/objective/revenantFluff/New()
|
||||
var/list/explanationTexts = list("Attempt to make your presence unknown to the crew.", \
|
||||
"Collaborate with existing antagonists aboard the station to gain essence.", \
|
||||
"Remain nonlethal and only absorb bodies that have already died.", \
|
||||
"Use your environments to eliminate isolated people.", \
|
||||
"If there is a chaplain aboard the station, ensure they are killed.", \
|
||||
"Hinder the crew without killing them.")
|
||||
var/list/explanationTexts = list("Assist and exacerbate existing threats at critical moments.", \
|
||||
"Avoid killing in plain sight.", \
|
||||
"Cause as much chaos and anger as you can without being killed.", \
|
||||
"Damage and render as much of the station rusted and unusable as possible.", \
|
||||
"Disable and cause malfunctions in as many machines as possible.", \
|
||||
"Ensure that any holy weapons are rendered unusable.", \
|
||||
"Hinder the crew while attempting to avoid being noticed.", \
|
||||
"Make the crew as miserable as possible.", \
|
||||
"Make the clown as miserable as possible.", \
|
||||
"Make the captain as miserable as possible.", \
|
||||
"Prevent the use of energy weapons where possible.")
|
||||
explanation_text = pick(explanationTexts)
|
||||
..()
|
||||
|
||||
@@ -394,6 +318,7 @@
|
||||
icon_state = "revenantEctoplasm"
|
||||
w_class = 2
|
||||
var/reforming = 1
|
||||
var/essence = 75 //the maximum essence of the reforming revenant
|
||||
var/inert = 0
|
||||
var/client/client_to_revive
|
||||
|
||||
|
||||
@@ -1,3 +1,117 @@
|
||||
///Harvest
|
||||
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
|
||||
|
||||
if(client.click_intercept)
|
||||
client.click_intercept.InterceptClickOn(src, params, A)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["middle"])
|
||||
MiddleClickOn(A)
|
||||
return
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["alt"])
|
||||
AltClickOn(A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(world.time <= next_move)
|
||||
return
|
||||
A.attack_ghost(src)
|
||||
if(ishuman(A) && in_range(src, A))
|
||||
Harvest(A)
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target)
|
||||
if(!castcheck(0))
|
||||
return
|
||||
if(draining)
|
||||
src << "<span class='revenwarning'>You are already siphoning the essence of a soul!</span>"
|
||||
return
|
||||
if(target in drained_mobs)
|
||||
src << "<span class='revenwarning'>[target]'s soul is dead and empty.</span>"
|
||||
return
|
||||
if(!target.stat)
|
||||
src << "<span class='revennotice'>This being's soul is too strong to harvest.</span>"
|
||||
if(prob(10))
|
||||
target << "You feel as if you are being watched."
|
||||
return
|
||||
draining = 1
|
||||
essence_drained = rand(15, 20)
|
||||
src << "<span class='revennotice'>You search for the soul of [target].</span>"
|
||||
if(do_after(src, 10, 0, target = target)) //did they get deleted in that second?
|
||||
if(target.ckey)
|
||||
src << "<span class='revennotice'>Their soul burns with intelligence.</span>"
|
||||
essence_drained += rand(20, 30)
|
||||
if(target.stat != DEAD)
|
||||
src << "<span class='revennotice'>Their soul blazes with life!</span>"
|
||||
essence_drained += rand(40, 50)
|
||||
else
|
||||
src << "<span class='revennotice'>Their soul is weak and faltering.</span>"
|
||||
if(do_after(src, 20, 0, target = target)) //did they get deleted NOW?
|
||||
switch(essence_drained)
|
||||
if(1 to 30)
|
||||
src << "<span class='revennotice'>[target] will not yield much essence. Still, every bit counts.</span>"
|
||||
if(30 to 70)
|
||||
src << "<span class='revennotice'>[target] will yield an average amount of essence.</span>"
|
||||
if(70 to 90)
|
||||
src << "<span class='revenboldnotice'>Such a feast! [target] will yield much essence to you.</span>"
|
||||
if(90 to INFINITY)
|
||||
src << "<span class='revenbignotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
|
||||
if(do_after(src, 20, 0, target = target)) //how about now
|
||||
if(!target.stat)
|
||||
src << "<span class='revenwarning'>They are now powerful enough to fight off your draining.</span>"
|
||||
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
|
||||
draining = 0
|
||||
return //hey, wait a minute...
|
||||
src << "<span class='revenminor'>You begin siphoning essence from [target]'s soul.</span>"
|
||||
if(target.stat != DEAD)
|
||||
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
|
||||
icon_state = "revenant_draining"
|
||||
reveal(27)
|
||||
stun(27)
|
||||
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
|
||||
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26)
|
||||
if(do_after(src, 30, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
|
||||
change_essence_amount(essence_drained, 0, target)
|
||||
if(essence_drained > 90)
|
||||
essence_regen_cap += 25
|
||||
perfectsouls += 1
|
||||
src << "<span class='revenboldnotice'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
|
||||
src << "<span class='revennotice'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
|
||||
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
|
||||
"<span class='revenwarning'>Violets lights, dancing in your vision, getting clo--</span>")
|
||||
drained_mobs.Add(target)
|
||||
target.death(0)
|
||||
else
|
||||
src << "<span class='revenwarning'>[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken.</span>"
|
||||
draining = 0
|
||||
essence_drained = 0
|
||||
if(target) //Wait, target is WHERE NOW?
|
||||
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
|
||||
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
|
||||
return
|
||||
else
|
||||
src << "<span class='revenwarning'>You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken.</span>"
|
||||
draining = 0
|
||||
essence_drained = 0
|
||||
return
|
||||
draining = 0
|
||||
essence_drained = 0
|
||||
return
|
||||
|
||||
//Toggle night vision: lets the revenant toggle its night vision
|
||||
/obj/effect/proc_holder/spell/targeted/night_vision/revenant
|
||||
charge_max = 0
|
||||
panel = "Revenant Abilities"
|
||||
message = "<span class='revennotice'>You toggle your night vision.</span>"
|
||||
action_icon_state = "r_nightvision"
|
||||
action_background_icon_state = "bg_revenant"
|
||||
|
||||
|
||||
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
|
||||
/obj/effect/proc_holder/spell/targeted/revenant_transmit
|
||||
name = "Transmit"
|
||||
@@ -81,7 +195,7 @@
|
||||
stun = 30
|
||||
cast_amount = 45
|
||||
var/shock_range = 2
|
||||
var/shock_damage = 18
|
||||
var/shock_damage = 20
|
||||
action_icon_state = "overload_lights"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
|
||||
@@ -116,9 +230,11 @@
|
||||
name = "Defile"
|
||||
desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors."
|
||||
charge_max = 150
|
||||
range = 3
|
||||
range = 4
|
||||
stun = 10
|
||||
reveal = 40
|
||||
unlock_amount = 75
|
||||
cast_amount = 40
|
||||
cast_amount = 30
|
||||
action_icon_state = "defile"
|
||||
var/stamdamage= 25
|
||||
var/toxdamage = 5
|
||||
@@ -144,9 +260,19 @@
|
||||
new/obj/effect/overlay/temp/revenant(T)
|
||||
T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
|
||||
for(var/obj/structure/window/window in T.contents)
|
||||
window.hit(rand(50,90))
|
||||
window.hit(rand(30,80))
|
||||
if(window && window.is_fulltile())
|
||||
new/obj/effect/overlay/temp/revenant/cracks(window.loc)
|
||||
for(var/obj/structure/closet/closet in T.contents)
|
||||
closet.open()
|
||||
|
||||
if(!istype(T, /turf/simulated/floor/plating) && !istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(15))
|
||||
var/turf/simulated/floor/floor = T
|
||||
if(floor.intact)
|
||||
floor.builtin_tile.loc = floor
|
||||
floor.broken = 0
|
||||
floor.burnt = 0
|
||||
floor.make_plating(1)
|
||||
for(var/obj/machinery/light/light in T.contents)
|
||||
light.flicker(30) //spooky
|
||||
|
||||
@@ -156,6 +282,7 @@
|
||||
desc = "Corrupts and damages nearby machines and mechanical objects."
|
||||
charge_max = 200
|
||||
range = 4
|
||||
cast_amount = 45
|
||||
unlock_amount = 150
|
||||
action_icon_state = "malfunction"
|
||||
|
||||
|
||||
@@ -42,11 +42,13 @@
|
||||
var/mob/living/victim = pulling
|
||||
if(victim.stat == CONSCIOUS)
|
||||
visible_message("<span class='warning'>[victim] kicks free of [B] just before entering it!</span>")
|
||||
stop_pulling()
|
||||
else
|
||||
victim.forceMove(holder)//holder
|
||||
victim.emote("scream")
|
||||
visible_message("<span class='warning'><b>[src] drags [victim] into [B]!</b></span>")
|
||||
kidnapped = victim
|
||||
stop_pulling()
|
||||
flick("jaunt",animation)
|
||||
loc = holder
|
||||
holder = holder
|
||||
@@ -94,48 +96,53 @@
|
||||
flags = NODROP|ABSTRACT
|
||||
|
||||
/mob/living/proc/phasein(var/obj/effect/decal/cleanable/B)
|
||||
|
||||
if(notransform)
|
||||
src << "<span class='warning'>Finish eating first!</span>"
|
||||
return 0
|
||||
else
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( B.loc )
|
||||
animation.name = "odd blood"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.icon_state = "jauntup" //Paradise Port:I reversed the jaunt animation so it looks like its rising up
|
||||
animation.layer = 5
|
||||
animation.master = B.loc
|
||||
animation.dir = dir
|
||||
B.visible_message("<span class='warning'>[B] starts to bubble...</span>")
|
||||
if(!do_after(src, 20, target = B))
|
||||
return
|
||||
if(!B)
|
||||
return
|
||||
forceMove(B.loc)
|
||||
client.eye = src
|
||||
if (prob(25) && istype(src, /mob/living/simple_animal/slaughter))
|
||||
var/list/voice = list('sound/hallucinations/behind_you1.ogg','sound/hallucinations/im_here1.ogg','sound/hallucinations/turn_around1.ogg','sound/hallucinations/i_see_you1.ogg')
|
||||
playsound(get_turf(src), pick(voice),50, 1, -1)
|
||||
visible_message("<span class='warning'><B>\The [src] rises out of \the [B]!</B>")
|
||||
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
|
||||
flick("jauntup",animation)
|
||||
qdel(holder)
|
||||
holder = null
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
for(var/obj/item/weapon/bloodcrawl/BC in C)
|
||||
C.flags = null
|
||||
C.unEquip(BC)
|
||||
qdel(BC)
|
||||
var/oldcolor = color
|
||||
color = B.color
|
||||
sleep(6)//wait for animation to finish
|
||||
if(animation)
|
||||
qdel(animation)
|
||||
spawn(30)
|
||||
color = oldcolor
|
||||
return 1
|
||||
B.visible_message("<span class='warning'>[B] starts to bubble...</span>")
|
||||
if(!do_after(src, 20, target = B))
|
||||
return
|
||||
if(!B)
|
||||
return
|
||||
forceMove(B.loc)
|
||||
client.eye = src
|
||||
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( B.loc )
|
||||
animation.name = "odd blood"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.icon_state = "jauntup" //Paradise Port:I reversed the jaunt animation so it looks like its rising up
|
||||
animation.layer = 5
|
||||
animation.master = B.loc
|
||||
animation.dir = dir
|
||||
|
||||
if(prob(25) && istype(src, /mob/living/simple_animal/slaughter))
|
||||
var/list/voice = list('sound/hallucinations/behind_you1.ogg','sound/hallucinations/im_here1.ogg','sound/hallucinations/turn_around1.ogg','sound/hallucinations/i_see_you1.ogg')
|
||||
playsound(get_turf(src), pick(voice),50, 1, -1)
|
||||
visible_message("<span class='warning'><B>\The [src] rises out of \the [B]!</B>")
|
||||
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
|
||||
|
||||
flick("jauntup",animation)
|
||||
qdel(holder)
|
||||
holder = null
|
||||
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
for(var/obj/item/weapon/bloodcrawl/BC in C)
|
||||
C.flags = null
|
||||
C.unEquip(BC)
|
||||
qdel(BC)
|
||||
|
||||
var/oldcolor = color
|
||||
color = B.color
|
||||
sleep(6)//wait for animation to finish
|
||||
if(animation)
|
||||
qdel(animation)
|
||||
spawn(30)
|
||||
color = oldcolor
|
||||
return 1
|
||||
|
||||
/obj/effect/dummy/slaughter //Can't use the wizard one, blocked by jaunt/slow
|
||||
name = "odd blood"
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/phasein()
|
||||
..()
|
||||
. = ..()
|
||||
speed = 0
|
||||
boost = world.time + 60
|
||||
|
||||
|
||||
@@ -95,9 +95,6 @@
|
||||
if(istype(M, /obj/effect/decal/cleanable/blood))
|
||||
score_mess += 1
|
||||
|
||||
if(istype(M, /obj/effect/decal/cleanable/poop))
|
||||
score_mess += 1
|
||||
|
||||
if(istype(M, /obj/effect/decal/cleanable/vomit))
|
||||
score_mess += 1
|
||||
|
||||
|
||||
@@ -192,8 +192,8 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/targetted/disease
|
||||
name = "Diseased Touch (100)"
|
||||
desc = "Touches your victim with infected blood giving them the Shutdown Syndrome which quickly shutsdown their major organs resulting in a quick painful death."
|
||||
gain_desc = "You have gained the Diseased Touch ability which causes those you touch to die shortly after unless treated medically."
|
||||
desc = "Touches your victim with infected blood giving them appendicitis, which will, left untreated, cause a slow death by poison."
|
||||
gain_desc = "You have gained the Diseased Touch ability which causes those you touch to die unless treated medically."
|
||||
action_icon_state = "vampire_disease"
|
||||
required_blood = 100
|
||||
|
||||
@@ -204,21 +204,8 @@
|
||||
if(!affects(target))
|
||||
usr << "<span class='warning'>They seem to be unaffected.</span>"
|
||||
continue
|
||||
var/datum/disease2/disease/shutdown = new /datum/disease2/disease
|
||||
var/datum/disease2/effectholder/holder = new /datum/disease2/effectholder
|
||||
var/datum/disease2/effect/organs/vampire/O = new /datum/disease2/effect/organs/vampire
|
||||
holder.effect += O
|
||||
holder.chance = 10
|
||||
shutdown.infectionchance = 100
|
||||
shutdown.antigen |= text2num(pick(ANTIGENS))
|
||||
shutdown.antigen |= text2num(pick(ANTIGENS))
|
||||
shutdown.spreadtype = "None"
|
||||
shutdown.uniqueID = rand(0,10000)
|
||||
shutdown.effects += holder
|
||||
shutdown.speed = 1
|
||||
shutdown.stage = 2
|
||||
shutdown.clicks = 185
|
||||
infect_virus2(target, shutdown, 0)
|
||||
var/datum/disease/D = new /datum/disease/appendicitis //someone should probably make a better virus for this
|
||||
target.ForceContractDisease(D)
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/mob_aoe/glare
|
||||
name = "Glare"
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
selection_color = "#ffeef0"
|
||||
idtype = /obj/item/weapon/card/id/medical
|
||||
access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics)
|
||||
minimal_access = list(access_medical, access_virology, access_maint_tunnels)
|
||||
minimal_access = list(access_medical, access_virology, access_maint_tunnels, access_mineral_storeroom)
|
||||
alt_titles = list("Pathologist","Microbiologist")
|
||||
minimal_player_age = 7
|
||||
|
||||
|
||||
@@ -126,6 +126,12 @@
|
||||
take_victim(W:affecting,usr)
|
||||
qdel(W)
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 20, target = src))
|
||||
user << "<span class='notice'>You deconstruct the table.</span>"
|
||||
new /obj/item/stack/sheet/plasteel(loc, 5)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/optable/proc/check_table(mob/living/carbon/patient as mob)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
/obj/machinery/pdapainter/New()
|
||||
..()
|
||||
var/blocked = list(/obj/item/device/pda/ai/pai, /obj/item/device/pda/ai, /obj/item/device/pda/heads,
|
||||
var/blocked = list(/obj/item/device/pda/pai, /obj/item/device/pda/ai, /obj/item/device/pda/heads,
|
||||
/obj/item/device/pda/clear, /obj/item/device/pda/syndicate)
|
||||
|
||||
for(var/P in typesof(/obj/item/device/pda)-blocked)
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
occupantData["health"] = H.health
|
||||
occupantData["maxHealth"] = H.maxHealth
|
||||
|
||||
occupantData["hasVirus"] = H.virus2.len
|
||||
occupantData["hasVirus"] = H.viruses.len
|
||||
|
||||
occupantData["bruteLoss"] = H.getBruteLoss()
|
||||
occupantData["oxyLoss"] = H.getOxyLoss()
|
||||
@@ -476,7 +476,7 @@
|
||||
t1 = "*dead*"
|
||||
dat += "[occupant.health > 50 ? "<font color='blue'>" : "<font color='red'>"]\tHealth %: [occupant.health], ([t1])</font><br>"
|
||||
|
||||
if(occupant.virus2.len)
|
||||
if(occupant.viruses.len)
|
||||
dat += "<font color='red'>Viral pathogen detected in blood stream.</font><BR>"
|
||||
|
||||
var/extra_font = null
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
if(do_after(user, 20, target = src))
|
||||
if(!src || !WT.remove_fuel(0, user)) return
|
||||
user << "\blue You deconstruct the frame."
|
||||
new /obj/item/stack/sheet/plasteel( loc, 4)
|
||||
new /obj/item/stack/sheet/plasteel(loc, 4)
|
||||
qdel(src)
|
||||
if(1)
|
||||
if(istype(P, /obj/item/weapon/wrench))
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
/obj/item/weapon/circuitboard/med_data
|
||||
name = "Circuit board (Medical Records)"
|
||||
build_path = /obj/machinery/computer/med_data
|
||||
/obj/item/weapon/circuitboard/pandemic
|
||||
name = "circuit board (PanD.E.M.I.C. 2200)"
|
||||
build_path = /obj/machinery/computer/pandemic
|
||||
origin_tech = "programming=2;biotech=2"
|
||||
/obj/item/weapon/circuitboard/scan_consolenew
|
||||
name = "Circuit board (DNA Machine)"
|
||||
build_path = /obj/machinery/computer/scan_consolenew
|
||||
@@ -243,12 +247,6 @@
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/curefab
|
||||
name = "Circuit board (Cure Fabricator)"
|
||||
build_path = /obj/machinery/computer/curer
|
||||
/obj/item/weapon/circuitboard/splicer
|
||||
name = "Circuit board (Disease Splicer)"
|
||||
build_path = /obj/machinery/computer/diseasesplicer
|
||||
/obj/item/weapon/circuitboard/HolodeckControl
|
||||
name = "Circuit board (Holodeck Control)"
|
||||
build_path = /obj/machinery/computer/HolodeckControl
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/obj/machinery/computer/camera_advanced
|
||||
name = "advanced camera console"
|
||||
desc = "Used to access the various cameras on the station."
|
||||
icon_screen = "cameras"
|
||||
icon_keyboard = "security_key"
|
||||
var/mob/camera/aiEye/remote/eyeobj
|
||||
var/mob/living/carbon/human/current_user = null
|
||||
var/list/networks = list("SS13")
|
||||
var/datum/action/camera_off/off_action = new
|
||||
var/datum/action/camera_jump/jump_action = new
|
||||
|
||||
/obj/machinery/computer/camera_advanced/proc/CreateEye()
|
||||
eyeobj = new()
|
||||
eyeobj.origin = src
|
||||
|
||||
/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/carbon/user)
|
||||
off_action.target = user
|
||||
off_action.Grant(user)
|
||||
jump_action.target = user
|
||||
jump_action.Grant(user)
|
||||
|
||||
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
|
||||
if (get_dist(user, src) > 1 || user.eye_blind)
|
||||
if(user == current_user)
|
||||
off_action.Activate()
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
var/mob/living/carbon/L = user
|
||||
|
||||
if(!current_user)
|
||||
if(!eyeobj)
|
||||
CreateEye()
|
||||
GrantActions(user)
|
||||
current_user = user
|
||||
eyeobj.user = user
|
||||
eyeobj.name = "Camera Eye ([user.name])"
|
||||
L.remote_view = 1
|
||||
L.remote_control = eyeobj
|
||||
L.client.perspective = EYE_PERSPECTIVE
|
||||
if(!eyeobj.initialized)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network&networks)
|
||||
eyeobj.setLoc(get_turf(C))
|
||||
break
|
||||
eyeobj.initialized = 1
|
||||
else
|
||||
eyeobj.setLoc(eyeobj.loc)
|
||||
else
|
||||
user << "The console is already in use!"
|
||||
|
||||
/mob/camera/aiEye/remote
|
||||
name = "Inactive Camera Eye"
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
var/mob/living/carbon/human/user = null
|
||||
var/obj/machinery/computer/camera_advanced/origin
|
||||
var/initialized = 0
|
||||
var/visible_icon = 0
|
||||
var/image/user_image = null
|
||||
|
||||
/mob/camera/aiEye/remote/GetViewerClient()
|
||||
if(user)
|
||||
return user.client
|
||||
return null
|
||||
|
||||
/mob/camera/aiEye/remote/setLoc(T)
|
||||
if(user)
|
||||
if(!isturf(user.loc))
|
||||
return
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
cameranet.visibility(src)
|
||||
if(user.client)
|
||||
if(visible_icon)
|
||||
user.client.images -= user_image
|
||||
user_image = image(icon,loc,icon_state,FLY_LAYER)
|
||||
user.client.images += user_image
|
||||
user.client.eye = src
|
||||
|
||||
/mob/camera/aiEye/remote/relaymove(mob/user,direct)
|
||||
var/initial = initial(sprint)
|
||||
var/max_sprint = 50
|
||||
|
||||
if(cooldown && cooldown < world.timeofday) // 3 seconds
|
||||
sprint = initial
|
||||
|
||||
for(var/i = 0; i < max(sprint, initial); i += 20)
|
||||
var/turf/step = get_turf(get_step(src, direct))
|
||||
if(step)
|
||||
src.setLoc(step)
|
||||
|
||||
cooldown = world.timeofday + 5
|
||||
if(acceleration)
|
||||
sprint = min(sprint + 0.5, max_sprint)
|
||||
else
|
||||
sprint = initial
|
||||
|
||||
/datum/action/camera_off
|
||||
name = "End Camera View"
|
||||
action_type = AB_INNATE
|
||||
button_icon_state = "camera_off"
|
||||
|
||||
/datum/action/camera_off/Activate()
|
||||
if(!target || !iscarbon(target))
|
||||
return
|
||||
var/mob/living/carbon/C = target
|
||||
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
|
||||
C.remote_view = 0
|
||||
remote_eye.origin.current_user = null
|
||||
remote_eye.origin.jump_action.Remove(C)
|
||||
remote_eye.user = null
|
||||
if(C.client)
|
||||
C.client.perspective = MOB_PERSPECTIVE
|
||||
C.client.eye = src
|
||||
C.client.images -= remote_eye.user_image
|
||||
for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
|
||||
C.client.images -= chunk.obscured
|
||||
C.remote_control = null
|
||||
C.unset_machine()
|
||||
src.Remove(C)
|
||||
|
||||
/datum/action/camera_jump
|
||||
name = "Jump To Camera"
|
||||
action_type = AB_INNATE
|
||||
button_icon_state = "camera_jump"
|
||||
|
||||
/datum/action/camera_jump/Activate()
|
||||
if(!target || !iscarbon(target))
|
||||
return
|
||||
var/mob/living/carbon/C = target
|
||||
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
|
||||
var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin
|
||||
|
||||
var/list/L = list()
|
||||
|
||||
for (var/obj/machinery/camera/cam in cameranet.cameras)
|
||||
L.Add(cam)
|
||||
|
||||
camera_sort(L)
|
||||
|
||||
var/list/T = list()
|
||||
|
||||
for (var/obj/machinery/camera/netcam in L)
|
||||
var/list/tempnetwork = netcam.network&origin.networks
|
||||
if (tempnetwork.len)
|
||||
T[text("[][]", netcam.c_tag, (netcam.can_use() ? null : " (Deactivated)"))] = netcam
|
||||
|
||||
|
||||
var/camera = input("Choose which camera you want to view", "Cameras") as null|anything in T
|
||||
var/obj/machinery/camera/final = T[camera]
|
||||
if(final)
|
||||
remote_eye.setLoc(get_turf(final))
|
||||
@@ -84,7 +84,6 @@
|
||||
dat += text("\n<A href='?src=\ref[];print_p=1'>Print Record</A><BR>\n<A href='?src=\ref[];screen=2'>Back</A><BR>", src, src)
|
||||
if(5.0)
|
||||
dat += "<CENTER><B>Virus Database</B></CENTER>"
|
||||
/* Advanced diseases is weak! Feeble! Glory to virus2!
|
||||
for(var/Dt in typesof(/datum/disease/))
|
||||
var/datum/disease/Dis = new Dt(0)
|
||||
if(istype(Dis, /datum/disease/advance))
|
||||
@@ -92,11 +91,6 @@
|
||||
if(!Dis.desc)
|
||||
continue
|
||||
dat += "<br><a href='?src=\ref[src];vir=[Dt]'>[Dis.name]</a>"
|
||||
*/
|
||||
for (var/ID in virusDB)
|
||||
var/datum/data/record/v = virusDB[ID]
|
||||
dat += "<br><a href='?src=\ref[src];vir=\ref[v]'>[v.fields["name"]]</a>"
|
||||
|
||||
dat += "<br><a href='?src=\ref[src];screen=1'>Back</a>"
|
||||
if(6.0)
|
||||
dat += "<center><b>Medical Robot Monitor</b></center>"
|
||||
@@ -206,12 +200,20 @@
|
||||
src.active2 = null
|
||||
|
||||
if(href_list["vir"])
|
||||
var/datum/data/record/v = locate(href_list["vir"])
|
||||
src.temp = "<center>GNAv2 based virus lifeform V-[v.fields["id"]]</center>"
|
||||
src.temp += "<br><b>Name:</b> <A href='?src=\ref[src];field=vir_name;edit_vir=\ref[v]'>[v.fields["name"]]</A>"
|
||||
src.temp += "<br><b>Antigen:</b> [v.fields["antigen"]]"
|
||||
src.temp += "<br><b>Spread:</b> [v.fields["spread type"]] "
|
||||
src.temp += "<br><b>Details:</b><br> <A href='?src=\ref[src];field=vir_desc;edit_vir=\ref[v]'>[v.fields["description"]]</A>"
|
||||
var/type = href_list["vir"]
|
||||
var/datum/disease/Dis = new type(0)
|
||||
var/AfS = ""
|
||||
for(var/mob/M in Dis.viable_mobtypes)
|
||||
AfS += " [initial(M.name)];"
|
||||
src.temp = {"<b>Name:</b> [Dis.name]
|
||||
<BR><b>Number of stages:</b> [Dis.max_stages]
|
||||
<BR><b>Spread:</b> [Dis.spread_text] Transmission
|
||||
<BR><b>Possible Cure:</b> [(Dis.cure_text||"none")]
|
||||
<BR><b>Affected Lifeforms:</b>[AfS]
|
||||
<BR>
|
||||
<BR><b>Notes:</b> [Dis.desc]
|
||||
<BR>
|
||||
<BR><b>Severity:</b> [Dis.severity]"}
|
||||
|
||||
if (href_list["del_all"])
|
||||
src.temp = text("Are you sure you wish to delete all records?<br>\n\t<A href='?src=\ref[];temp=1;del_all2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
|
||||
|
||||
@@ -245,9 +245,12 @@
|
||||
new_meat.name = "[slab_name] [new_meat.name]"
|
||||
new_meat.reagents.add_reagent("nutriment",slab_nutrition)
|
||||
|
||||
|
||||
if(occupant.reagents)
|
||||
occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1))
|
||||
|
||||
if(occupant.get_species() == "Human")
|
||||
new /obj/item/stack/sheet/animalhide/human(src)
|
||||
new /obj/effect/decal/cleanable/blood/gibs(src)
|
||||
|
||||
if(!UserOverride)
|
||||
|
||||
@@ -108,37 +108,54 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/smartfridge/secure/virology
|
||||
name = "\improper Refrigerated Virus Storage"
|
||||
desc = "A refrigerated storage unit for storing viral material."
|
||||
req_access_txt = "39"
|
||||
icon_state = "smartfridge_virology"
|
||||
icon_on = "smartfridge_virology"
|
||||
icon_off = "smartfridge_virology-off"
|
||||
|
||||
/obj/machinery/smartfridge/secure/virology/accept_check(var/obj/item/O as obj)
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/glass/beaker/vial/))
|
||||
return 1
|
||||
if(istype(O,/obj/item/weapon/virusdish/))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/smartfridge/secure/chemistry
|
||||
name = "\improper Smart Chemical Storage"
|
||||
desc = "A refrigerated storage unit for medicine and chemical storage."
|
||||
icon_state = "smartfridge" //To fix the icon in the map editor.
|
||||
icon_on = "smartfridge_chem"
|
||||
req_access_txt = "33"
|
||||
var/list/spawn_meds = list()
|
||||
|
||||
/obj/machinery/smartfridge/secure/chemistry/New()
|
||||
..()
|
||||
for(var/typekey in spawn_meds)
|
||||
var/amount = spawn_meds[typekey]
|
||||
if(isnull(amount)) amount = 1
|
||||
while(amount)
|
||||
var/obj/item/I = new typekey(src)
|
||||
if(item_quants[I.name])
|
||||
item_quants[I.name]++
|
||||
else
|
||||
item_quants[I.name] = 1
|
||||
nanomanager.update_uis(src)
|
||||
amount--
|
||||
|
||||
/obj/machinery/smartfridge/chemistry/accept_check(var/obj/item/O as obj)
|
||||
if(istype(O,/obj/item/weapon/storage/pill_bottle) || istype(O,/obj/item/weapon/reagent_containers))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
// ----------------------------
|
||||
// Virology Medical Smartfridge
|
||||
// ----------------------------
|
||||
/obj/machinery/smartfridge/secure/chemistry/virology
|
||||
name = "\improper Smart Virus Storage"
|
||||
name = "smart virus storage"
|
||||
desc = "A refrigerated storage unit for volatile sample storage."
|
||||
req_access_txt = "39"
|
||||
spawn_meds = list(/obj/item/weapon/reagent_containers/syringe/antiviral = 4,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/cold = 1,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/flu_virion = 1,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/mutagen = 1,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/plasma = 1,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/diphenhydramine = 1)
|
||||
|
||||
/obj/machinery/smartfridge/secure/chemistry/virology/accept_check(obj/item/O)
|
||||
if(..(O))
|
||||
return 1
|
||||
if(istype(O, /obj/item/weapon/reagent_containers/syringe))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/smartfridge/drinks
|
||||
name = "\improper Drink Showcase"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define FONT_SIZE "5pt"
|
||||
#define FONT_COLOR "#09f"
|
||||
#define WARNING_FONT_COLOR "#f90"
|
||||
#define FONT_STYLE "Arial Black"
|
||||
#define SCROLL_SPEED 2
|
||||
|
||||
@@ -21,7 +22,7 @@
|
||||
// 1 = Shuttle timer
|
||||
// 2 = Arbitrary message(s)
|
||||
// 3 = alert picture
|
||||
// 4 = Supply shuttle timer
|
||||
// 4 = Station time
|
||||
|
||||
var/picture_state // icon_state of alert picture
|
||||
var/message1 = "" // message line 1
|
||||
@@ -88,25 +89,25 @@
|
||||
return 1
|
||||
if(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) //emergency shuttle timer
|
||||
if(shuttle_master.emergency.timer)
|
||||
var/line1
|
||||
var/line2 = get_shuttle_timer()
|
||||
message2 = get_shuttle_timer()
|
||||
switch(shuttle_master.emergency.mode)
|
||||
if(SHUTTLE_RECALL)
|
||||
line1 = "-RCL-"
|
||||
if(SHUTTLE_RECALL, SHUTTLE_ESCAPE)
|
||||
message1 = "-ETR-"
|
||||
if(SHUTTLE_CALL)
|
||||
line1 = "-ETA-"
|
||||
message1 = "-ETA-"
|
||||
if(SHUTTLE_DOCKED)
|
||||
line1 = "-ETD-"
|
||||
if(SHUTTLE_ESCAPE)
|
||||
line1 = "-ESC-"
|
||||
if(SHUTTLE_STRANDED)
|
||||
line1 = "-ERR-"
|
||||
line2 = "??:??"
|
||||
if(length(line2) > CHARS_PER_LINE)
|
||||
line2 = "Error!"
|
||||
update_display(line1, line2)
|
||||
message1 = "-ETD-"
|
||||
else
|
||||
message1 = "-ERR-"
|
||||
message2 = "??:??"
|
||||
if(length(message2) > CHARS_PER_LINE)
|
||||
message2 = "Error!"
|
||||
update_display(message1, message2, 1)
|
||||
else
|
||||
remove_display()
|
||||
message1 = "TIME"
|
||||
message2 = worldtime2text()
|
||||
update_display(message1, message2)
|
||||
return 1
|
||||
if(STATUS_DISPLAY_MESSAGE) //custom messages
|
||||
var/line1
|
||||
var/line2
|
||||
@@ -162,8 +163,8 @@
|
||||
remove_display()
|
||||
overlays += image('icons/obj/status_display.dmi', icon_state=picture_state)
|
||||
|
||||
/obj/machinery/status_display/proc/update_display(line1, line2)
|
||||
var/new_text = {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]';text-align:center;" valign="top">[line1]<br>[line2]</div>"}
|
||||
/obj/machinery/status_display/proc/update_display(line1, line2, warning = 0)
|
||||
var/new_text = {"<div style="font-size:[FONT_SIZE];color:[warning ? WARNING_FONT_COLOR : FONT_COLOR];font:'[FONT_STYLE]';text-align:center;" valign="top">[line1]<br>[line2]</div>"}
|
||||
if(maptext != new_text)
|
||||
maptext = new_text
|
||||
|
||||
@@ -291,7 +292,8 @@
|
||||
overlays += image('icons/obj/status_display.dmi', icon_state=picture_state)
|
||||
|
||||
#undef CHARS_PER_LINE
|
||||
#undef FOND_SIZE
|
||||
#undef FONT_SIZE
|
||||
#undef FONT_COLOR
|
||||
#undef WARNING_FONT_COLOR
|
||||
#undef FONT_STYLE
|
||||
#undef SCROLL_SPEED
|
||||
@@ -4,19 +4,20 @@
|
||||
|
||||
/obj/machinery/status_display/supply_display/update()
|
||||
if(!..() && mode == STATUS_DISPLAY_CUSTOM)
|
||||
var/line1
|
||||
var/line2
|
||||
if(shuttle_master.supply.mode == SHUTTLE_IDLE)
|
||||
if(shuttle_master.supply.z == ZLEVEL_STATION)
|
||||
line1 = "CARGO"
|
||||
line2 = "Docked"
|
||||
message1 = "CARGO"
|
||||
message2 = "Docked"
|
||||
else
|
||||
message1 = "TIME"
|
||||
message2 = worldtime2text()
|
||||
else
|
||||
line1 = "CARGO"
|
||||
line2 = get_supply_shuttle_timer()
|
||||
if(lentext(line2) > CHARS_PER_LINE)
|
||||
line2 = "Error"
|
||||
message1 = "CARGO"
|
||||
message2 = get_supply_shuttle_timer()
|
||||
if(lentext(message2) > CHARS_PER_LINE)
|
||||
message2 = "Error"
|
||||
|
||||
update_display(line1, line2)
|
||||
update_display(message1, message2)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -1008,7 +1008,13 @@
|
||||
vend_delay = 15
|
||||
vend_reply = "Have an enchanted evening!"
|
||||
product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!"
|
||||
products = list(/obj/item/clothing/head/wizard = 1,/obj/item/clothing/suit/wizrobe = 1,/obj/item/clothing/head/wizard/red = 1,/obj/item/clothing/suit/wizrobe/red = 1,/obj/item/clothing/shoes/sandal = 1,/obj/item/weapon/twohanded/staff = 2)
|
||||
products = list(/obj/item/clothing/head/wizard = 1,
|
||||
/obj/item/clothing/suit/wizrobe = 1,
|
||||
/obj/item/clothing/head/wizard/red = 1,
|
||||
/obj/item/clothing/suit/wizrobe/red = 1,
|
||||
/obj/item/clothing/shoes/sandal = 1,
|
||||
/obj/item/weapon/twohanded/staff = 2)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/wizarditis = 1)
|
||||
|
||||
/obj/machinery/vending/autodrobe
|
||||
name = "\improper AutoDrobe"
|
||||
|
||||
@@ -18,7 +18,6 @@ var/global/list/image/splatter_cache=list()
|
||||
var/list/viruses = list()
|
||||
blood_DNA = list()
|
||||
var/basecolor="#A10808" // Color when wet.
|
||||
var/list/datum/disease2/disease/virus2 = list()
|
||||
var/amount = 5
|
||||
appearance_flags = NO_CLIENT_COLOR
|
||||
|
||||
@@ -198,20 +197,20 @@ var/global/list/image/splatter_cache=list()
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions)
|
||||
spawn (0)
|
||||
var/direction = pick(directions)
|
||||
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
|
||||
sleep(3)
|
||||
if (i > 0)
|
||||
var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc)
|
||||
b.basecolor = src.basecolor
|
||||
b.update_icon()
|
||||
for(var/datum/disease2/disease/D in src.viruses)
|
||||
var/datum/disease2/disease/ND = D.getcopy()
|
||||
b.viruses += ND
|
||||
|
||||
if (step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
set waitfor = 0
|
||||
var/direction = pick(directions)
|
||||
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
|
||||
sleep(3)
|
||||
if (i > 0)
|
||||
var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc)
|
||||
b.basecolor = src.basecolor
|
||||
b.update_icon()
|
||||
for(var/datum/disease/D in src.viruses)
|
||||
var/datum/disease/ND = D.Copy(1)
|
||||
b.viruses += ND
|
||||
ND.holder = b
|
||||
if (step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/blood/old/New()
|
||||
@@ -221,29 +220,3 @@ var/global/list/image/splatter_cache=list()
|
||||
/obj/effect/decal/cleanable/blood/gibs/old/New()
|
||||
..()
|
||||
dry()
|
||||
|
||||
/obj/effect/decal/cleanable/mucus
|
||||
name = "mucus"
|
||||
desc = "Disgusting mucus."
|
||||
gender = PLURAL
|
||||
density = 0
|
||||
anchored = 1
|
||||
layer = 2
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "mucus"
|
||||
random_icon_states = list("mucus")
|
||||
|
||||
var/list/datum/disease2/disease/virus2 = list()
|
||||
var/dry=0 // Keeps the lag down
|
||||
|
||||
/obj/effect/decal/cleanable/mucus/New()
|
||||
spawn(DRYING_TIME * 2)
|
||||
dry=1
|
||||
|
||||
/obj/effect/decal/cleanable/blood/viralsputum
|
||||
name = "viral sputum"
|
||||
desc = "It's black and nasty."
|
||||
// basecolor="#030303"
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "floor1"
|
||||
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
|
||||
@@ -114,7 +114,6 @@
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "vomit_1"
|
||||
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
|
||||
var/list/datum/disease2/disease/virus2 = list()
|
||||
noclear = 1
|
||||
|
||||
/obj/effect/decal/cleanable/vomit/New()
|
||||
@@ -133,17 +132,6 @@
|
||||
reagents.remove_reagent("vomit", 5)
|
||||
reagents.add_reagent("green_vomit", 5)
|
||||
|
||||
/obj/effect/decal/cleanable/poop
|
||||
name = "poop"
|
||||
desc = "Gosh, how unpleasant."
|
||||
gender = PLURAL
|
||||
density = 0
|
||||
anchored = 1
|
||||
layer = 2
|
||||
icon = 'icons/effects/poop.dmi'
|
||||
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
|
||||
var/list/datum/disease2/disease/virus2 = list()
|
||||
|
||||
/obj/effect/decal/cleanable/tomato_smudge
|
||||
name = "tomato smudge"
|
||||
desc = "It's red."
|
||||
|
||||
@@ -925,6 +925,13 @@ steam.start() -- spawns the effect
|
||||
sleep(30)
|
||||
|
||||
if(metal)
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T, /turf/space))
|
||||
T.ChangeTurf(/turf/simulated/floor/plating/metalfoam)
|
||||
var/turf/simulated/floor/plating/metalfoam/MF = get_turf(src)
|
||||
MF.metal = metal
|
||||
MF.update_icon()
|
||||
|
||||
var/obj/structure/foamedmetal/M = new(src.loc)
|
||||
M.metal = metal
|
||||
M.updateicon()
|
||||
@@ -994,51 +1001,49 @@ steam.start() -- spawns the effect
|
||||
var/list/carried_reagents // the IDs of reagents present when the foam was mixed
|
||||
var/metal = 0 // 0=foam, 1=metalfoam, 2=ironfoam
|
||||
|
||||
/datum/effect/system/foam_spread/set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0)
|
||||
amount = round(sqrt(amt / 3), 1)
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
carried_reagents = list()
|
||||
metal = metalfoam
|
||||
|
||||
|
||||
|
||||
set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0)
|
||||
amount = round(sqrt(amt / 3), 1)
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
carried_reagents = list()
|
||||
metal = metalfoam
|
||||
// bit of a hack here. Foam carries along any reagent also present in the glass it is mixed
|
||||
// with (defaults to water if none is present). Rather than actually transfer the reagents,
|
||||
// this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves.
|
||||
|
||||
|
||||
// bit of a hack here. Foam carries along any reagent also present in the glass it is mixed
|
||||
// with (defaults to water if none is present). Rather than actually transfer the reagents,
|
||||
// this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves.
|
||||
if(carry && !metal)
|
||||
for(var/datum/reagent/R in carry.reagent_list)
|
||||
carried_reagents += R.id
|
||||
|
||||
/datum/effect/system/foam_spread/start()
|
||||
spawn(0)
|
||||
var/obj/effect/effect/foam/F = locate() in location
|
||||
if(F)
|
||||
F.amount += amount
|
||||
return
|
||||
|
||||
if(carry && !metal)
|
||||
for(var/datum/reagent/R in carry.reagent_list)
|
||||
carried_reagents += R.id
|
||||
F = new(src.location, metal)
|
||||
F.amount = amount
|
||||
|
||||
start()
|
||||
spawn(0)
|
||||
var/obj/effect/effect/foam/F = locate() in location
|
||||
if(F)
|
||||
F.amount += amount
|
||||
return
|
||||
if(!metal) // don't carry other chemicals if a metal foam
|
||||
F.create_reagents(10)
|
||||
|
||||
F = new(src.location, metal)
|
||||
F.amount = amount
|
||||
|
||||
if(!metal) // don't carry other chemicals if a metal foam
|
||||
F.create_reagents(10)
|
||||
|
||||
if(carried_reagents)
|
||||
for(var/id in carried_reagents)
|
||||
F.reagents.add_reagent(id,1)
|
||||
else
|
||||
F.reagents.add_reagent("water", 1)
|
||||
if(carried_reagents)
|
||||
for(var/id in carried_reagents)
|
||||
F.reagents.add_reagent(id,1)
|
||||
else
|
||||
F.reagents.add_reagent("water", 1)
|
||||
|
||||
// wall formed by metal foams
|
||||
// dense and opaque, but easy to break
|
||||
|
||||
|
||||
/obj/structure/foamedmetal
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "metalfoam"
|
||||
@@ -1047,79 +1052,85 @@ steam.start() -- spawns the effect
|
||||
anchored = 1
|
||||
name = "foamed metal"
|
||||
desc = "A lightweight foamed metal wall."
|
||||
var/metal = 1 // 1=aluminum, 2=iron
|
||||
var/metal = MFOAM_ALUMINUM
|
||||
|
||||
New()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
/obj/structure/foamedmetal/New()
|
||||
..()
|
||||
air_update_turf(1)
|
||||
|
||||
Destroy()
|
||||
density = 0
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
/obj/structure/foamedmetal/Destroy()
|
||||
density = 0
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
|
||||
Move()
|
||||
var/turf/T = loc
|
||||
..()
|
||||
move_update_air(T)
|
||||
/obj/structure/foamedmetal/Move()
|
||||
var/turf/T = loc
|
||||
..()
|
||||
move_update_air(T)
|
||||
|
||||
proc/updateicon()
|
||||
if(metal == 1)
|
||||
icon_state = "metalfoam"
|
||||
else
|
||||
icon_state = "ironfoam"
|
||||
/obj/structure/foamedmetal/proc/updateicon()
|
||||
if(metal == MFOAM_ALUMINUM)
|
||||
icon_state = "metalfoam"
|
||||
else
|
||||
icon_state = "ironfoam"
|
||||
|
||||
|
||||
ex_act(severity)
|
||||
/obj/structure/foamedmetal/ex_act(severity)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/foamedmetal/blob_act()
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/foamedmetal/bullet_act()
|
||||
if(metal==MFOAM_ALUMINUM || prob(50))
|
||||
qdel(src)
|
||||
|
||||
blob_act()
|
||||
/obj/structure/foamedmetal/attack_hand(var/mob/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
if ((HULK in user.mutations) || (prob(75 - metal*25)))
|
||||
user.visible_message("<span class='warning'>[user] smashes through \the [src].</span>", "<span class='notice'>You smash through \the [src].</span>")
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='notice'>You hit the metal foam but bounce off it.</span>"
|
||||
|
||||
bullet_act()
|
||||
if(metal==1 || prob(50))
|
||||
qdel(src)
|
||||
|
||||
attack_hand(var/mob/user)
|
||||
if ((HULK in user.mutations) || (prob(75 - metal*25)))
|
||||
user << "\blue You smash through the metal foam wall."
|
||||
for(var/mob/O in oviewers(user))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O << "\red [user] smashes through the foamed metal."
|
||||
|
||||
qdel(src)
|
||||
else
|
||||
user << "\blue You hit the metal foam but bounce off it."
|
||||
/obj/structure/foamedmetal/attackby(var/obj/item/I, var/mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
if (istype(I, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = I
|
||||
G.affecting.loc = src.loc
|
||||
user.visible_message("<span class='warning'>[G.assailant] smashes [G.affecting] through the foamed metal wall.</span>")
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(prob(I.force*20 - metal*25))
|
||||
user.visible_message("<span class='warning'>[user] smashes through the foamed metal with \the [I].</span>", "<span class='notice'>You smash through the foamed metal with \the [I].</span>")
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You hit the metal foam to no effect.</span>"
|
||||
|
||||
attackby(var/obj/item/I, var/mob/user, params)
|
||||
/obj/structure/foamedmetal/attack_animal(mob/living/simple_animal/M)
|
||||
M.do_attack_animation(src)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.visible_message("<span class='notice'>[M] nudges \the [src].</span>")
|
||||
else
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
M.visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>")
|
||||
qdel(src)
|
||||
|
||||
if (istype(I, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = I
|
||||
G.affecting.loc = src.loc
|
||||
for(var/mob/O in viewers(src))
|
||||
if (O.client)
|
||||
O << "\red [G.assailant] smashes [G.affecting] through the foamed metal wall."
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
return
|
||||
/obj/structure/foamedmetal/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
M.visible_message("<span class='danger'>[M] tears apart \the [src]!</span>");
|
||||
qdel(src)
|
||||
|
||||
if(prob(I.force*20 - metal*25))
|
||||
user << "\blue You smash through the foamed metal with \the [I]."
|
||||
for(var/mob/O in oviewers(user))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O << "\red [user] smashes through the foamed metal."
|
||||
qdel(src)
|
||||
else
|
||||
user << "\blue You hit the metal foam to no effect."
|
||||
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
if(air_group) return 0
|
||||
return !density
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
if(air_group) return 0
|
||||
return !density
|
||||
|
||||
CanAtmosPass()
|
||||
return !density
|
||||
/obj/structure/foamedmetal/CanAtmosPass()
|
||||
return !density
|
||||
|
||||
/datum/effect/system/reagents_explosion
|
||||
var/amount // TNT equivalent
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
A.name = str
|
||||
usr << "<span class='notice'>You rename the '[prevname]' to '[str]'.</span>"
|
||||
interact()
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/areaeditor/proc/set_area_machinery_title(var/area/A,var/title,var/oldtitle)
|
||||
|
||||
@@ -187,19 +187,13 @@ REAGENT SCANNER
|
||||
if (istype(M, /mob/living/carbon))
|
||||
if(upgraded)
|
||||
chemscan(user, M)
|
||||
if(M:virus2.len) // WHAT IS TYPECASTING
|
||||
var/mob/living/carbon/C = M
|
||||
for (var/ID in C.virus2)
|
||||
if (ID in virusDB)
|
||||
var/datum/data/record/V = virusDB[ID]
|
||||
user.show_message(text("\red Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]"))
|
||||
// user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood."))
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if(!(D.visibility_flags & HIDDEN_SCANNER))
|
||||
user << "<span class='alert'><b>Warning: [D.form] detected</b>\nName: [D.name].\nType: [D.spread_text].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure_text]</span>"
|
||||
if(M.getStaminaLoss())
|
||||
user.show_message("<span class='info'>Subject appears to be suffering from fatigue.</span>")
|
||||
if (M.getCloneLoss())
|
||||
user.show_message("<span class='warning'>Subject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.</span>")
|
||||
// if (M.reagents && M.reagents.get_reagent_amount("epinephrine"))
|
||||
// user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("epinephrine")] units of rejuvenation chemicals.")
|
||||
if (M.has_brain_worms())
|
||||
user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.")
|
||||
else if (M.getBrainLoss() >= 100 || istype(M, /mob/living/carbon/human) && !M.get_int_organ(/obj/item/organ/internal/brain))
|
||||
|
||||
@@ -5,6 +5,22 @@
|
||||
icon_state = "sheet-hide"
|
||||
origin_tech = ""
|
||||
|
||||
var/global/list/datum/stack_recipe/human_recipes = list( \
|
||||
new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/bloated_human, 5, on_floor = 1), \
|
||||
new/datum/stack_recipe("bloated human costume head", /obj/item/clothing/head/human_head, 5, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/animalhide/human/New(var/loc, var/amount=null)
|
||||
recipes = human_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/animalhide/generic
|
||||
name = "generic skin"
|
||||
desc = "A piece of generic skin."
|
||||
singular_name = "generic skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/stack/sheet/animalhide/corgi
|
||||
name = "corgi hide"
|
||||
desc = "The by-product of corgi farming."
|
||||
|
||||
@@ -5,6 +5,7 @@ Mineral Sheets
|
||||
- Diamond
|
||||
- Uranium
|
||||
- Plasma
|
||||
- Plastic
|
||||
- Gold
|
||||
- Silver
|
||||
- Bananium
|
||||
@@ -191,4 +192,4 @@ var/global/list/datum/stack_recipe/mime_recipes = list ( \
|
||||
name = "enriched uranium"
|
||||
icon_state = "sheet-enruranium"
|
||||
origin_tech = "materials=6"
|
||||
materials = list(MAT_URANIUM=3000)
|
||||
materials = list(MAT_URANIUM=3000)
|
||||
|
||||
@@ -51,6 +51,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
|
||||
new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("machine frame", /obj/machinery/constructable_frame/machine_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe_list("airlock assemblies", list( \
|
||||
new/datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
@@ -86,7 +87,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
|
||||
|
||||
/obj/item/stack/sheet/metal
|
||||
name = "metal"
|
||||
desc = "Sheets made out off metal. It has been dubbed Metal Sheets."
|
||||
desc = "Sheets made out of metal."
|
||||
singular_name = "metal sheet"
|
||||
icon_state = "sheet-metal"
|
||||
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT)
|
||||
@@ -96,7 +97,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
|
||||
|
||||
/obj/item/stack/sheet/metal/cyborg
|
||||
name = "metal"
|
||||
desc = "Sheets made out off metal. It has been dubbed Metal Sheets."
|
||||
desc = "Sheets made out of metal."
|
||||
singular_name = "metal sheet"
|
||||
icon_state = "sheet-metal"
|
||||
materials = list()
|
||||
@@ -107,7 +108,6 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
|
||||
recipes = metal_recipes
|
||||
return ..()
|
||||
|
||||
|
||||
/*
|
||||
* Plasteel
|
||||
*/
|
||||
@@ -116,8 +116,6 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \
|
||||
new/datum/stack_recipe("Surgery Table", /obj/machinery/optable, 5, time = 50, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Metal crate", /obj/structure/closet/crate, 10, time = 50, one_per_turf = 1), \
|
||||
new/datum/stack_recipe("Mass Driver frame", /obj/machinery/mass_driver_frame, 3, time = 50, one_per_turf = 1), \
|
||||
// new/datum/stack_recipe("RUST fuel assembly port frame", /obj/item/rust_fuel_assembly_port_frame, 12, time = 50, one_per_turf = 1), \
|
||||
// new/datum/stack_recipe("RUST fuel compressor frame", /obj/item/rust_fuel_compressor_frame, 12, time = 50, one_per_turf = 1), \
|
||||
|
||||
)
|
||||
|
||||
|
||||
@@ -272,4 +272,4 @@
|
||||
New(title, recipes, req_amount = 1)
|
||||
src.title = title
|
||||
src.recipes = recipes
|
||||
src.req_amount = req_amount
|
||||
src.req_amount = req_amount
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
|
||||
//////Kitchen Spike
|
||||
|
||||
/obj/structure/kitchenspike_frame
|
||||
name = "meatspike frame"
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "spikeframe"
|
||||
desc = "The frame of a meat spike."
|
||||
density = 1
|
||||
anchored = 0
|
||||
|
||||
/obj/structure/kitchenspike_frame/attackby(obj/item/I, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(I, /obj/item/weapon/wrench))
|
||||
if(anchored)
|
||||
user << "<span class='notice'>You unwrench [src] from the floor.</span>"
|
||||
anchored = 0
|
||||
else
|
||||
user << "<span class='notice'>You wrench [src] into place.</span>"
|
||||
anchored = 1
|
||||
else if(istype(I, /obj/item/stack/rods))
|
||||
var/obj/item/stack/rods/R = I
|
||||
if(R.get_amount() >= 4)
|
||||
R.use(4)
|
||||
user << "<span class='notice'>You add spikes to the frame.</span>"
|
||||
new /obj/structure/kitchenspike(loc)
|
||||
add_fingerprint(user)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/kitchenspike
|
||||
name = "a meat spike"
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
@@ -7,54 +35,105 @@
|
||||
desc = "A spike for collecting meat from animals."
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/meat = 0
|
||||
var/occupied
|
||||
var/meat_type
|
||||
var/victim_name = "corpse"
|
||||
buckle_lying = 0
|
||||
can_buckle = 1
|
||||
|
||||
|
||||
|
||||
/obj/structure/kitchenspike/attackby(obj/item/weapon/grab/G as obj, mob/user as mob)
|
||||
if(istype(G, /obj/item/weapon/crowbar))
|
||||
if(!buckled_mob)
|
||||
playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
|
||||
if(do_after(user, 20, target = src))
|
||||
user << "<span class='notice'>You pry the spikes out of the frame.</span>"
|
||||
new /obj/item/stack/rods(loc, 4)
|
||||
new /obj/structure/kitchenspike_frame(loc)
|
||||
add_fingerprint(user)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='notice'>You can't do that while something's on the spike!</span>"
|
||||
return
|
||||
if(!istype(G, /obj/item/weapon/grab) || !G.affecting)
|
||||
return
|
||||
if(occupied)
|
||||
if(buckled_mob)
|
||||
user << "<span class = 'danger'>The spike already has something on it, finish collecting its meat first!</span>"
|
||||
else
|
||||
if(spike(G.affecting))
|
||||
visible_message("<span class = 'danger'>[user] has forced [G.affecting] onto the spike, killing them instantly!</span>")
|
||||
qdel(G.affecting)
|
||||
qdel(G)
|
||||
else
|
||||
user << "<span class='danger'>They are too big for the spike, try something smaller!</span>"
|
||||
if(isliving(G.affecting))
|
||||
if(!buckled_mob)
|
||||
if(do_mob(user, src, 120))
|
||||
if(spike(G.affecting))
|
||||
G.affecting.visible_message("<span class='danger'>[user] slams [G.affecting] onto the meat spike!</span>", "<span class='userdanger'>[user] slams you onto the meat spike!</span>", "<span class='italics'>You hear a squishy wet noise.</span>")
|
||||
qdel(G)
|
||||
return
|
||||
user << "<span class='danger'>You can't use that on the spike!</span>"
|
||||
return
|
||||
|
||||
/obj/structure/kitchenspike/proc/spike(var/mob/living/victim)
|
||||
|
||||
if(!istype(victim))
|
||||
return
|
||||
|
||||
if(istype(victim, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = victim
|
||||
if(!H.species.is_small)
|
||||
return 0
|
||||
meat_type = H.species.meat_type
|
||||
icon_state = "spikebloody"
|
||||
else if(istype(victim, /mob/living/carbon/alien))
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
|
||||
icon_state = "spikebloodygreen"
|
||||
else
|
||||
return 0
|
||||
|
||||
victim_name = victim.name
|
||||
occupied = 1
|
||||
meat = 5
|
||||
if(buckled_mob) //to prevent spam/queing up attacks
|
||||
return 0
|
||||
if(victim.buckled)
|
||||
return 0
|
||||
var/mob/living/H = victim
|
||||
playsound(loc, "sound/effects/splat.ogg", 25, 1)
|
||||
H.forceMove(loc)
|
||||
H.emote("scream")
|
||||
if(istype(H, /mob/living/carbon/human)) //So you don't get human blood when you spike a giant spidere
|
||||
var/turf/simulated/pos = get_turf(H)
|
||||
pos.add_blood_floor(H)
|
||||
H.adjustBruteLoss(30)
|
||||
H.buckled = src
|
||||
H.dir = 2
|
||||
buckled_mob = H
|
||||
var/matrix/m180 = matrix()
|
||||
m180.Turn(180)
|
||||
animate(H, transform = m180, time = 3)
|
||||
H.pixel_y = H.get_standard_pixel_y_offset(180)
|
||||
return 1
|
||||
|
||||
/obj/structure/kitchenspike/attack_hand(mob/user as mob)
|
||||
if(..() || !occupied)
|
||||
return
|
||||
meat--
|
||||
new meat_type(get_turf(src))
|
||||
if(src.meat > 1)
|
||||
user << "You remove some meat from \the [victim_name]."
|
||||
else if(src.meat == 1)
|
||||
user << "You remove the last piece of meat from \the [victim_name]!"
|
||||
icon_state = "spike"
|
||||
occupied = 0
|
||||
|
||||
|
||||
/obj/structure/kitchenspike/user_buckle_mob(mob/living/M, mob/living/user) //Don't want them getting put on the rack other than by spiking
|
||||
return
|
||||
|
||||
/obj/structure/kitchenspike/user_unbuckle_mob(mob/living/carbon/human/user)
|
||||
if(buckled_mob && buckled_mob.buckled == src)
|
||||
var/mob/living/M = buckled_mob
|
||||
if(M != user)
|
||||
M.visible_message(\
|
||||
"[user.name] tries to pull [M.name] free of the [src]!",\
|
||||
"<span class='notice'>[user.name] is trying to pull you off of [src], opening up fresh wounds!</span>",\
|
||||
"<span class='italics'>You hear a squishy wet noise.</span>")
|
||||
if(!do_after(user, 300, target = src))
|
||||
if(M && M.buckled)
|
||||
M.visible_message(\
|
||||
"[user.name] fails to free [M.name]!",\
|
||||
"<span class='notice'>[user.name] fails to pull you off of [src].</span>")
|
||||
return
|
||||
|
||||
else
|
||||
M.visible_message(\
|
||||
"<span class='warning'>[M.name] struggles to break free from the [src]!</span>",\
|
||||
"<span class='notice'>You struggle to break free from the [src], exacerbating your wounds! (Stay still for two minutes.)</span>",\
|
||||
"<span class='italics'>You hear a wet squishing noise..</span>")
|
||||
M.adjustBruteLoss(30)
|
||||
if(!do_after(M, 1200, target = src))
|
||||
if(M && M.buckled)
|
||||
M << "<span class='warning'>You fail to free yourself!</span>"
|
||||
return
|
||||
if(!M.buckled)
|
||||
return
|
||||
var/matrix/m180 = matrix(M.transform)
|
||||
m180.Turn(180)
|
||||
animate(M, transform = m180, time = 3)
|
||||
M.pixel_y = M.get_standard_pixel_y_offset(180)
|
||||
M.adjustBruteLoss(30)
|
||||
visible_message("<span class='danger'>[M] falls free of the [src]!</span>")
|
||||
unbuckle_mob()
|
||||
M.emote("scream")
|
||||
M.AdjustWeakened(10)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
if(open)
|
||||
GM.visible_message("<span class='danger'>[user] starts to give [GM] a swirlie!</span>", "<span class='userdanger'>[user] starts to give [GM] a swirlie...</span>")
|
||||
swirlie = GM
|
||||
if(do_after(user, 30, 5, 0, target = src))
|
||||
if(do_after(user, 30, 0, target = src))
|
||||
GM.visible_message("<span class='danger'>[user] gives [GM] a swirlie!</span>", "<span class='userdanger'>[user] gives [GM] a swirlie!</span>", "<span class='italics'>You hear a toilet flushing.</span>")
|
||||
if(iscarbon(GM))
|
||||
var/mob/living/carbon/C = GM
|
||||
|
||||
@@ -113,22 +113,19 @@
|
||||
|
||||
|
||||
//returns 1 if made bloody, returns 0 otherwise
|
||||
/turf/simulated/add_blood(mob/living/carbon/human/M as mob)
|
||||
/turf/simulated/add_blood(mob/living/carbon/human/M)
|
||||
if (!..())
|
||||
return 0
|
||||
|
||||
if(istype(M))
|
||||
for(var/obj/effect/decal/cleanable/blood/B in contents)
|
||||
if(!B.blood_DNA[M.dna.unique_enzymes])
|
||||
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
|
||||
B.virus2 = virus_copylist(M.virus2)
|
||||
return 1 //we bloodied the floor
|
||||
var/obj/effect/decal/cleanable/blood/B = locate() in contents //check for existing blood splatter
|
||||
if(!B)
|
||||
blood_splatter(src,M.get_blood(M.vessel),1)
|
||||
return 1 //we bloodied the floor
|
||||
return 0
|
||||
B = locate(/obj/effect/decal/cleanable/blood) in contents
|
||||
B.add_blood_list(M)
|
||||
return 1 //we bloodied the floor
|
||||
|
||||
// Only adds blood on the floor -- Skie
|
||||
/turf/simulated/proc/add_blood_floor(mob/living/carbon/M as mob)
|
||||
/turf/simulated/add_blood_floor(mob/living/carbon/M as mob)
|
||||
if(ishuman(M))
|
||||
blood_splatter(src,M,1)
|
||||
if( istype(M, /mob/living/carbon/alien ))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","damaged4",
|
||||
"damaged5","panelscorched","floorscorched1","floorscorched2","platingdmg1","platingdmg2",
|
||||
"platingdmg3","plating","light_on","light_on_flicker1","light_on_flicker2",
|
||||
"warnplate", "warnplatecorner",
|
||||
"warnplate", "warnplatecorner","metalfoam", "ironfoam",
|
||||
"light_on_clicker3","light_on_clicker4","light_on_clicker5","light_broken",
|
||||
"light_on_broken","light_off","wall_thermite","grass1","grass2","grass3","grass4",
|
||||
"asteroid","asteroid_dug",
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
if(istype(C, /obj/item/stack/rods))
|
||||
if(broken || burnt)
|
||||
user << "<span class='warning'>Repair the plating first!</span>"
|
||||
return
|
||||
return 1
|
||||
var/obj/item/stack/rods/R = C
|
||||
if (R.get_amount() < 2)
|
||||
user << "<span class='warning'>You need two rods to make a reinforced floor!</span>"
|
||||
return
|
||||
return 1
|
||||
else
|
||||
user << "<span class='notice'>You begin reinforcing the floor...</span>"
|
||||
if(do_after(user, 30, target = src))
|
||||
@@ -41,7 +41,7 @@
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
|
||||
R.use(2)
|
||||
user << "<span class='notice'>You reinforce the floor.</span>"
|
||||
return
|
||||
return 1
|
||||
|
||||
else if(istype(C, /obj/item/stack/tile))
|
||||
if(!broken && !burnt)
|
||||
@@ -52,6 +52,7 @@
|
||||
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
|
||||
else
|
||||
user << "<span class='warning'>This section is too damaged to support a tile! Use a welder to fix the damage.</span>"
|
||||
return 1
|
||||
|
||||
else if(istype(C, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/welder = C
|
||||
@@ -62,6 +63,7 @@
|
||||
icon_state = icon_plating
|
||||
burnt = 0
|
||||
broken = 0
|
||||
return 1
|
||||
|
||||
/turf/simulated/floor/plating/airless
|
||||
icon_state = "plating"
|
||||
@@ -232,6 +234,56 @@
|
||||
CW.update_icon(0)
|
||||
playsound(src, 'sound/items/Screwdriver.ogg', 80, 1)
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam
|
||||
name = "foamed metal plating"
|
||||
icon_state = "metalfoam"
|
||||
var/metal = MFOAM_ALUMINUM
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/iron
|
||||
icon_state = "ironfoam"
|
||||
metal = MFOAM_IRON
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/update_icon()
|
||||
switch(metal)
|
||||
if(MFOAM_ALUMINUM)
|
||||
icon_state = "metalfoam"
|
||||
if(MFOAM_IRON)
|
||||
icon_state = "ironfoam"
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/attackby(var/obj/item/C, mob/user, params)
|
||||
if(..())
|
||||
return 1
|
||||
if(istype(C) && C.force)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
var/smash_prob = max(0, C.force*17 - metal*25) // A crowbar will have a 60% chance of a breakthrough on alum, 35% on iron
|
||||
if(prob(smash_prob))
|
||||
// YAR BE CAUSIN A HULL BREACH
|
||||
visible_message("<span class='danger'>[user] smashes through \the [src] with \the [C]!</span>")
|
||||
smash()
|
||||
else
|
||||
visible_message("<span class='warning'>[user]'s [C.name] bounces against \the [src]!</span>")
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/attack_animal(mob/living/simple_animal/M)
|
||||
M.do_attack_animation(src)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.visible_message("<span class='notice'>[M] nudges \the [src].</span>")
|
||||
else
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
M.visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>")
|
||||
smash(src)
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
M.visible_message("<span class='danger'>[M] tears apart \the [src]!</span>")
|
||||
smash(src)
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/burn_tile()
|
||||
smash()
|
||||
|
||||
/turf/simulated/floor/plating/metalfoam/proc/smash()
|
||||
ChangeTurf(/turf/space)
|
||||
|
||||
/turf/simulated/floor/plasteel/airless
|
||||
name = "airless floor"
|
||||
oxygen = 0.01
|
||||
|
||||
Reference in New Issue
Block a user