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:
Tastyfish
2016-03-31 13:33:46 -04:00
245 changed files with 6723 additions and 4456 deletions
+1 -1
View File
@@ -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
View File
@@ -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
+4 -3
View File
@@ -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 = ""
-2
View File
@@ -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
-3
View File
@@ -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
+4 -17
View File
@@ -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"
+1 -1
View File
@@ -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
+6
View File
@@ -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)
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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))
+14 -12
View File
@@ -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)
+3
View File
@@ -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)
+33 -16
View File
@@ -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"
+21 -19
View File
@@ -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
+10 -9
View File
@@ -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
+7 -1
View File
@@ -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."
+101 -90
View File
@@ -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
+1 -1
View File
@@ -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)
+3 -9
View File
@@ -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), \
)
+1 -1
View File
@@ -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
+115 -36
View File
@@ -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)
+1 -1
View File
@@ -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
+7 -10
View File
@@ -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 ))
+1 -1
View File
@@ -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",
+55 -3
View File
@@ -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