Merge branch 'master' of https://github.com/PolarisSS13/Polaris into dice_thing

This commit is contained in:
Anewbe
2017-05-02 11:13:53 -05:00
310 changed files with 3332 additions and 1457 deletions

View File

@@ -115,12 +115,7 @@
else if(isturf(hit_atom))
src.throwing = 0
var/turf/T = hit_atom
if(T.density)
spawn(2)
step(src, turn(src.last_move, 180))
if(istype(src,/mob/living))
var/mob/living/M = src
M.turf_collision(T, speed)
T.hitby(src,speed)
//decided whether a movable atom being thrown can pass through the turf it is in.
/atom/movable/proc/hit_check(var/speed)

View File

@@ -210,7 +210,6 @@
/obj/machinery/computer/scan_consolenew
name = "DNA Modifier Access Console"
desc = "Scan DNA."
icon = 'icons/obj/computer.dmi'
icon_keyboard = "med_key"
icon_screen = "dna"
density = 1

View File

@@ -13,12 +13,15 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
var/isabsorbing = 0
var/geneticpoints = 5
var/max_geneticpoints = 5
var/readapts = 1
var/max_readapts = 2
var/list/purchased_powers = list()
var/mimicing = ""
var/cloaked = 0
var/armor_deployed = 0 //This is only used for changeling_generic_equip_all_slots() at the moment.
var/recursive_enhancement = 0 //Used to power up other abilities from the ling power with the same name.
var/list/purchased_powers_history = list() //Used for round-end report, includes respec uses too.
var/last_shriek = null // world.time when the ling last used a shriek.
/datum/changeling/New(var/gender=FEMALE)
..()
@@ -60,6 +63,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
if(!mind.changeling) mind.changeling = new /datum/changeling(gender)
verbs += /datum/changeling/proc/EvolutionMenu
verbs += /mob/proc/changeling_respec
add_language("Changeling")
var/lesser_form = !ishuman(src)
@@ -153,6 +157,46 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
//STINGS// //They get a pretty header because there's just so fucking many of them ;_;
//////////
turf/proc/AdjacentTurfsRangedSting()
//Yes this is snowflakey, but I couldn't get it to work any other way.. -Luke
var/list/allowed = list(
/obj/structure/table,
/obj/structure/closet,
/obj/structure/frame,
/obj/structure/target_stake,
/obj/structure/cable,
/obj/structure/disposalpipe,
/obj/machinery/
)
var/L[] = new()
for(var/turf/simulated/t in oview(src,1))
var/add = 1
if(t.density)
add = 0
if(add && LinkBlocked(src,t))
add = 0
if(add && TurfBlockedNonWindow(t))
add = 0
for(var/obj/O in t)
if(!O.density)
add = 1
break
if(istype(O, /obj/machinery/door))
//not sure why this doesn't fire on LinkBlocked()
add = 0
break
for(var/type in allowed)
if (istype(O, type))
add = 1
break
if(!add)
break
if(add)
L.Add(t)
return L
/mob/proc/sting_can_reach(mob/M as mob, sting_range = 1)
if(M.loc == src.loc)
return 1 //target and source are in the same thing
@@ -160,7 +204,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
src << "<span class='warning'>We cannot reach \the [M] with a sting!</span>"
return 0 //One is inside, the other is outside something.
// Maximum queued turfs set to 25; I don't *think* anything raises sting_range above 2, but if it does the 25 may need raising
if(!AStar(src.loc, M.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, max_nodes=25, max_node_depth=sting_range)) //If we can't find a path, fail
if(!AStar(src.loc, M.loc, /turf/proc/AdjacentTurfsRangedSting, /turf/proc/Distance, max_nodes=25, max_node_depth=sting_range)) //If we can't find a path, fail
src << "<span class='warning'>We cannot find a path to sting \the [M] by!</span>"
return 0
return 1

View File

@@ -32,7 +32,7 @@
return 1
if(M.head || M.wear_suit) //Make sure our slots aren't full
src << "<span class='warning'>We require nothing to be on our head, and we cannot wear any external suits.</span>"
src << "<span class='warning'>We require nothing to be on our head, and we cannot wear any external suits, or shoes.</span>"
return 0
var/obj/item/clothing/suit/A = new armor_type(src)
@@ -140,7 +140,7 @@
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["w_uniform"]
if(!M.w_uniform && t)
@@ -150,7 +150,7 @@
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["gloves"]
if(!M.gloves && t)
@@ -160,7 +160,7 @@
playsound(src, 'sound/effects/splat.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["shoes"]
if(!M.shoes && t)
@@ -170,7 +170,7 @@
playsound(src, 'sound/effects/splat.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["belt"]
if(!M.belt && t)
@@ -180,7 +180,7 @@
playsound(src, 'sound/effects/splat.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["glasses"]
if(!M.glasses && t)
@@ -190,7 +190,7 @@
playsound(src, 'sound/effects/splat.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["wear_mask"]
if(!M.wear_mask && t)
@@ -200,7 +200,7 @@
playsound(src, 'sound/effects/splat.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["back"]
if(!M.back && t)
@@ -210,7 +210,7 @@
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["wear_suit"]
if(!M.wear_suit && t)
@@ -220,7 +220,7 @@
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
t = stuff_to_equip["wear_id"]
if(!M.wear_id && t)
@@ -230,7 +230,7 @@
playsound(src, 'sound/effects/splat.ogg', 30, 1)
M.update_icons()
success = 1
sleep(20)
sleep(1 SECOND)
var/feedback = english_list(grown_items_list, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )

View File

@@ -72,7 +72,12 @@
if(src.nutrition < 400)
src.nutrition = min((src.nutrition + T.nutrition), 400)
changeling.chem_charges += 10
src.verbs += /mob/proc/changeling_respec
if(changeling.readapts <= 0)
changeling.readapts = 0 //SANITYYYYYY
changeling.readapts++
if(changeling.readapts > changeling.max_readapts)
changeling.readapts = changeling.max_readapts
src << "<span class='notice'>We can now re-adapt, reverting our evolution so that we may start anew, if needed.</span>"
var/datum/absorbed_dna/newDNA = new(T.real_name, T.dna, T.species.name, T.languages, T.identifying_gender, T.flavor_texts)

View File

@@ -24,7 +24,7 @@
if(held_item == null)
if(src.mind.changeling.recursive_enhancement)
if(changeling_generic_weapon(/obj/item/weapon/electric_hand/efficent))
if(changeling_generic_weapon(/obj/item/weapon/electric_hand/efficent,0))
src << "<span class='notice'>We will shock others more efficently.</span>"
return 1
else

View File

@@ -26,7 +26,7 @@
src << "<span class='notice'>They will be deprived of sight for longer.</span>"
spawn(duration)
T.disabilities &= ~NEARSIGHTED
T.eye_blind = 10
T.Blind(10)
T.eye_blurry = 20
feedback_add_details("changeling_powers","BS")
return 1

View File

@@ -18,11 +18,11 @@
if(!changeling)
return 0
changeling.chem_charges -= 10
src << "<span class='notice'>Your throat adjusts to launch the sting.</span>"
to_chat(src, "<span class='notice'>Your throat adjusts to launch the sting.</span>")
var/range = 2
if(src.mind.changeling.recursive_enhancement)
range = range + 3
src << "<span class='notice'>We can fire our next sting from five squares away.</span>"
to_chat(src, "<span class='notice'>We can fire our next sting from five squares away.</span>")
changeling.sting_range = range
src.verbs -= /mob/proc/changeling_boost_range
spawn(5)

View File

@@ -2,12 +2,24 @@
name = "Delayed Toxic Sting"
desc = "We silently sting a biological, causing a significant amount of toxins after a few minutes, allowing us to not \
implicate ourselves."
helptext = "The toxin takes effect in about two minutes. The sting has a three minute cooldown between uses."
helptext = "The toxin takes effect in about two minutes. Multiple applications within the two minutes will not cause increased toxicity."
enhancedtext = "The toxic damage is doubled."
ability_icon_state = "ling_sting_del_toxin"
genomecost = 1
verbpath = /mob/proc/changeling_delayed_toxic_sting
/datum/modifier/delayed_toxin_sting
name = "delayed toxin injection"
hidden = TRUE
stacks = MODIFIER_STACK_FORBID
on_expired_text = "<span class='danger'>You feel a burning sensation flowing through your veins!</span>"
/datum/modifier/delayed_toxin_sting/on_expire()
holder.adjustToxLoss(rand(20, 30))
/datum/modifier/delayed_toxin_sting/strong/on_expire()
holder.adjustToxLoss(rand(40, 60))
/mob/proc/changeling_delayed_toxic_sting()
set category = "Changeling"
set name = "Delayed Toxic Sting (20)"
@@ -19,21 +31,13 @@
T.attack_log += text("\[[time_stamp()]\] <font color='red'>Was delayed toxic stung by [key_name(src)]</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'> Used delayed toxic sting on [key_name(T)]</font>")
msg_admin_attack("[key_name(T)] was delayed toxic stung by [key_name(src)]")
var/i = rand(20,30)
var/type_to_give = /datum/modifier/delayed_toxin_sting
if(src.mind.changeling.recursive_enhancement)
i = i * 2
type_to_give = /datum/modifier/delayed_toxin_sting/strong
src << "<span class='notice'>Our toxin will be extra potent, when it strikes.</span>"
spawn(2 MINUTES)
if(T) //We might not exist in two minutes, for whatever reason.
T << "<span class='danger'>You feel a burning sensation flowing through your veins!</span>"
while(i)
T.adjustToxLoss(1)
i--
sleep(2 SECONDS)
src.verbs -= /mob/proc/changeling_delayed_toxic_sting
spawn(3 MINUTES)
src << "<span class='notice'>We are ready to use our delayed toxic string once more.</span>"
src.verbs |= /mob/proc/changeling_delayed_toxic_sting
T.add_modifier(type_to_give, 2 MINUTES)
feedback_add_details("changeling_powers","DTS")

View File

@@ -6,9 +6,18 @@
isVerb = 0
verbpath = /mob/proc/changeling_endoarmor
/datum/modifier/endoarmor
name = "endoarmor"
desc = "We have hard plating underneath our skin, making us more durable."
on_created_text = "<span class='notice'>We feel protective plating form underneath our skin.</span>"
on_expired_text = "<span class='notice'>Our protective armor underneath our skin fades as we absorb it.</span>"
max_health_flat = 50
//Increases macimum chemical storage
/mob/proc/changeling_endoarmor()
if(ishuman(src))
var/mob/living/carbon/human/H = src
H.maxHealth += 50
H.add_modifier(/datum/modifier/endoarmor)
// H.maxHealth += 50
return 1

View File

@@ -1,13 +1,29 @@
/datum/power/changeling/enfeebling_string
name = "Enfeebling String"
desc = "We sting a biological with a potent toxin that will greatly weaken them for a short period of time."
helptext = "Lowers the maximum health of the victim for a few minutes. This sting will also warn them of this. Has a \
five minute coodown between uses."
enhancedtext = "Maximum health is lowered further."
helptext = "Lowers the maximum health of the victim for a few minutes, as well as making them more frail and weak. This sting will also warn them of this."
enhancedtext = "Maximum health and outgoing melee damage is lowered further. Incoming damage is increased."
ability_icon_state = "ling_sting_enfeeble"
genomecost = 1
verbpath = /mob/proc/changeling_enfeebling_string
/datum/modifier/enfeeble
name = "enfeebled"
desc = "You feel really weak and frail for some reason."
stacks = MODIFIER_STACK_EXTEND
max_health_percent = 0.7
outgoing_melee_damage_percent = 0.75
incoming_damage_percent = 1.1
on_created_text = "<span class='danger'>You feel a small prick and you feel extremly weak!</span>"
on_expired_text = "<span class='notice'>You no longer feel extremly weak.</span>"
// Now YOU'RE the Teshari!
/datum/modifier/enfeeble/strong
max_health_percent = 0.5
outgoing_melee_damage_percent = 0.5
incoming_damage_percent = 1.35
/mob/proc/changeling_enfeebling_string()
set category = "Changeling"
set name = "Enfeebling Sting (30)"
@@ -23,22 +39,10 @@
src.attack_log += text("\[[time_stamp()]\] <font color='orange'> Used enfeebling sting on [key_name(T)]</font>")
msg_admin_attack("[key_name(T)] was enfeebling stung by [key_name(src)]")
var/effect = 30 //percent
var/type_to_give = /datum/modifier/enfeeble
if(src.mind.changeling.recursive_enhancement)
effect = effect + 20
type_to_give = /datum/modifier/enfeeble/strong
src << "<span class='notice'>We make them extremely weak.</span>"
var/health_to_take_away = H.maxHealth * (effect / 100)
H.maxHealth -= health_to_take_away
H << "<span class='danger'>You feel a small prick and you feel extremly weak!</span>"
src.verbs -= /mob/proc/changeling_enfeebling_string
spawn(5 MINUTES)
src.verbs |= /mob/proc/changeling_enfeebling_string
src << "<span class='notice'>Our enfeebling string is ready to be used once more.</span>"
if(H) //Just incase we stop existing in five minutes for whatever reason.
H.maxHealth += health_to_take_away
if(!H.stat) //It'd be weird to no longer feel weak when you're dead.
H << "<span class='notice'>You no longer feel extremly weak.</span>"
H.add_modifier(type_to_give, 2 MINUTES)
feedback_add_details("changeling_powers","ES")
return 1

View File

@@ -2,11 +2,20 @@
name = "Epinephrine Overdose"
desc = "We evolve additional sacs of adrenaline throughout our body."
helptext = "We can instantly recover from stuns and reduce the effect of future stuns, but we will suffer toxicity in the long term. Can be used while unconscious."
enhancedtext = "Constant recovery from stuns for thirty seconds."
enhancedtext = "Immunity from most disabling effects for 30 seconds."
ability_icon_state = "ling_epinepherine_overdose"
genomecost = 2
verbpath = /mob/proc/changeling_epinephrine_overdose
/datum/modifier/unstoppable
name = "unstoppable"
desc = "We feel limitless amounts of energy surge in our veins. Nothing can stop us!"
stacks = MODIFIER_STACK_EXTEND
on_created_text = "<span class='notice'>We feel unstoppable!</span>"
on_expired_text = "<span class='warning'>We feel our newfound energy fade...</span>"
disable_duration_percent = 0
//Recover from stuns.
/mob/proc/changeling_epinephrine_overdose()
set category = "Changeling"
@@ -30,18 +39,7 @@
C.reagents.add_reagent("epinephrine", 20)
if(src.mind.changeling.recursive_enhancement)
src << "<span class='notice'>We feel unstoppable.</span>"
spawn(1)
var/i = 30
while(i)
C.SetParalysis(0)
C.SetStunned(0)
C.SetWeakened(0)
C.lying = 0
C.update_canmove()
i--
sleep(10)
src << "<span class='notice'>We feel our newfound energy fade.</span>"
C.add_modifier(/datum/modifier/unstoppable, 30 SECONDS)
feedback_add_details("changeling_powers","UNS")
return 1

View File

@@ -18,7 +18,7 @@ var/global/list/changeling_fabricated_clothing = list(
helptext = "The disguise we create offers no defensive ability. Each equipment slot that is empty will be filled with fabricated equipment. \
To remove our new fabricated clothing, use this ability again."
ability_icon_state = "ling_fabricate_clothing"
genomecost = 2
genomecost = 1
verbpath = /mob/proc/changeling_fabricate_clothing
//Grows biological versions of chameleon clothes.

View File

@@ -12,7 +12,7 @@
set category = "Changeling"
set name = "Regenerative Stasis (20)"
var/datum/changeling/changeling = changeling_power(20,1,100,DEAD)
var/datum/changeling/changeling = changeling_power(CHANGELING_STASIS_COST,1,100,DEAD)
if(!changeling)
return
@@ -28,6 +28,7 @@
C.update_canmove()
C.remove_changeling_powers()
changeling.chem_charges -= CHANGELING_STASIS_COST
if(C.suiciding)
C.suiciding = 0
@@ -35,7 +36,9 @@
if(C.stat != DEAD)
C.adjustOxyLoss(C.maxHealth * 2)
spawn(rand(800,2000))
C.forbid_seeing_deadchat = TRUE
spawn(rand(2 MINUTES, 4 MINUTES))
//The ling will now be able to choose when to revive
src.verbs += /mob/proc/changeling_revive
src << "<span class='notice'><font size='5'>We are ready to rise. Use the <b>Revive</b> verb when you are ready.</font></span>"

View File

@@ -35,7 +35,7 @@
C.species.create_organs(C)
C.restore_all_organs()
C.blinded = 0
C.eye_blind = 0
C.SetBlinded(0)
C.eye_blurry = 0
C.ear_deaf = 0
C.ear_damage = 0

View File

@@ -6,9 +6,14 @@
var/datum/changeling/changeling = changeling_power(0,0,100)
if(!changeling)
return
if(src.mind.changeling.readapts <= 0)
to_chat(src, "<span class='warning'>We must first absorb another compatable creature!</span>")
src.mind.changeling.readapts = 0
return
src.remove_changeling_powers() //First, remove the verbs.
var/datum/changeling/ling_datum = src.mind.changeling
ling_datum.readapts--
ling_datum.purchased_powers = list() //Then wipe all the powers we bought.
ling_datum.geneticpoints = ling_datum.max_geneticpoints //Now refund our points to the maximum.
ling_datum.chem_recharge_rate = 0.5 //If glands were bought, revert that upgrade.
@@ -17,13 +22,10 @@
ling_datum.chem_storage = 50
if(ishuman(src))
var/mob/living/carbon/human/H = src
H.does_not_breathe = 0 //If self respiration was bought, revert that too.
H.maxHealth = initial(H.maxHealth) //Revert endoarmor too.
// H.does_not_breathe = 0 //If self respiration was bought, revert that too.
H.remove_modifiers_of_type(/datum/modifier/endoarmor) //Revert endoarmor too.
src.make_changeling() //And give back our freebies.
src << "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>"
ling_datum.purchased_powers_history.Add("Re-adapt (Reset to [ling_datum.max_geneticpoints])")
//Now to lose the verb, so no unlimited resets.
src.verbs -= /mob/proc/changeling_respec

View File

@@ -41,6 +41,10 @@
current_limb.undislocate()
current_limb.open = 0
BITSET(H.hud_updateflag, HEALTH_HUD)
BITSET(H.hud_updateflag, STATUS_HUD)
BITSET(H.hud_updateflag, LIFE_HUD)
C.halloss = 0
C.shock_stage = 0 //Pain
C << "<span class='notice'>We have regenerated.</span>"
@@ -48,8 +52,12 @@
C.mind.changeling.purchased_powers -= C
feedback_add_details("changeling_powers","CR")
C.stat = CONSCIOUS
C.forbid_seeing_deadchat = FALSE
C.timeofdeath = null
src.verbs -= /mob/proc/changeling_revive
// re-add our changeling powers
C.make_changeling()
return 1

View File

@@ -35,6 +35,14 @@
src << "<span class='danger'>You can't speak!</span>"
return 0
if(world.time < (changeling.last_shriek + 10 SECONDS) )
to_chat(src, "<span class='warning'>We are still recovering from our last shriek...</span>")
return 0
if(!isturf(loc))
to_chat(src, "<span class='warning'>Shrieking here would be a bad idea.</span>")
return 0
src.break_cloak() //No more invisible shrieking
changeling.chem_charges -= 20
@@ -47,6 +55,8 @@
message_admins("[key_name(src)] used Resonant Shriek ([src.x],[src.y],[src.z]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>).")
log_game("[key_name(src)] used Resonant Shriek.")
visible_message("<span class='notice'>[src] appears to shout.</span>")
for(var/mob/living/M in range(range, src))
if(iscarbon(M))
if(!M.mind || !M.mind.changeling)
@@ -55,7 +65,7 @@
M << "<span class='danger'>You hear an extremely loud screeching sound! It \
[pick("confuses","confounds","perturbs","befuddles","dazes","unsettles","disorients")] you.</span>"
M.adjustEarDamage(0,30)
M.confused += 20
M.Confuse(20)
M << sound('sound/effects/screech.ogg')
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Was affected by [key_name(src)]'s Resonant Shriek.</font>")
else
@@ -73,11 +83,7 @@
L.on = 1
L.broken()
/* src.verbs -= /mob/proc/changeling_resonant_shriek
spawn(30 SECONDS)
src << "<span class='notice'>We are ready to use our resonant shriek once more.</span>"
src.verbs |= /mob/proc/changeling_resonant_shriek
Ability Cooldowns don't work properly right now, need to redo this when they are */
changeling.last_shriek = world.time
feedback_add_details("changeling_powers","RS")
return 1
@@ -101,6 +107,14 @@ Ability Cooldowns don't work properly right now, need to redo this when they are
src << "<span class='danger'>You can't speak!</span>"
return 0
if(world.time < (changeling.last_shriek + 10 SECONDS) )
to_chat(src, "<span class='warning'>We are still recovering from our last shriek...</span>")
return 0
if(!isturf(loc))
to_chat(src, "<span class='warning'>Shrieking here would be a bad idea.</span>")
return 0
src.break_cloak() //No more invisible shrieking
changeling.chem_charges -= 20
@@ -117,6 +131,8 @@ Ability Cooldowns don't work properly right now, need to redo this when they are
src << "<span class='notice'>We are extra loud.</span>"
src.mind.changeling.recursive_enhancement = 0
visible_message("<span class='notice'>[src] appears to shout.</span>")
src.attack_log += text("\[[time_stamp()]\] <font color='red'>Used Dissonant Shriek.</font>")
message_admins("[key_name(src)] used Dissonant Shriek ([src.x],[src.y],[src.z]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>).")
log_game("[key_name(src)] used Dissonant Shriek.")
@@ -126,9 +142,6 @@ Ability Cooldowns don't work properly right now, need to redo this when they are
L.broken()
empulse(get_turf(src), range_heavy, range_light, 1)
/* src.verbs -= /mob/proc/changeling_dissonant_shriek
spawn(30 SECONDS)
src << "<span class='notice'>We are ready to use our dissonant shriek once more.</span>"
src.verbs |= /mob/proc/changeling_dissonant_shriek
Ability Cooldowns don't work properly right now, need to redo this when they are */
changeling.last_shriek = world.time
return 1

View File

@@ -13,6 +13,10 @@
var/datum/changeling/changeling = changeling_power(5,1,0)
if(!changeling) return
if(!isturf(loc))
to_chat(src, "<span class='warning'>Transforming here would be a bad idea.</span>")
return 0
var/list/names = list()
for(var/datum/absorbed_dna/DNA in changeling.absorbed_dna)
names += "[DNA.name]"

View File

@@ -3,7 +3,7 @@
desc = "We rapidly shape the color of our skin and secrete easily reversible dye on our clothes, to blend in with our surroundings. \
We are undetectable, so long as we move slowly.(Toggle)"
helptext = "Running, and performing most acts will reveal us. Our chemical regeneration is halted while we are hidden."
enhancedtext = "True invisiblity while cloaked."
enhancedtext = "Can run while hidden."
ability_icon_state = "ling_camoflage"
genomecost = 3
verbpath = /mob/proc/changeling_visible_camouflage
@@ -31,20 +31,35 @@
var/old_regen_rate = H.mind.changeling.chem_recharge_rate
H << "<span class='notice'>We vanish from sight, and will remain hidden, so long as we move carefully.</span>"
H.set_m_intent("walk")
H.mind.changeling.cloaked = 1
H.mind.changeling.chem_recharge_rate = 0
animate(src,alpha = 255, alpha = 10, time = 10)
var/must_walk = TRUE
if(src.mind.changeling.recursive_enhancement)
H.invisibility = INVISIBILITY_OBSERVER
src << "<span class='notice'>We are now truly invisible.</span>"
must_walk = FALSE
to_chat(src, "<span class='notice'>We may move at our normal speed while hidden.</span>")
if(must_walk)
H.set_m_intent("walk")
var/remain_cloaked = TRUE
while(remain_cloaked) //This loop will keep going until the player uncloaks.
sleep(1 SECOND) // Sleep at the start so that if something invalidates a cloak, it will drop immediately after the check and not in one second.
if(H.m_intent != "walk" && must_walk) // Moving too fast uncloaks you.
remain_cloaked = 0
if(!H.mind.changeling.cloaked)
remain_cloaked = 0
if(H.stat) // Dead or unconscious lings can't stay cloaked.
remain_cloaked = 0
if(H.incapacitated(INCAPACITATION_DISABLED)) // Stunned lings also can't stay cloaked.
remain_cloaked = 0
while(H.m_intent == "walk" && H.mind.changeling.cloaked && !H.stat) //This loop will keep going until the player uncloaks.
if(mind.changeling.chem_recharge_rate != 0) //Without this, there is an exploit that can be done, if one buys engorged chem sacks while cloaked.
old_regen_rate += mind.changeling.chem_recharge_rate //Unfortunately, it has to occupy this part of the proc. This fixes it while at the same time
mind.changeling.chem_recharge_rate = 0 //making sure nobody loses out on their bonus regeneration after they're done hiding.
sleep(10)
H.invisibility = initial(invisibility)

View File

@@ -49,7 +49,7 @@
desc = "A hood worn by the followers of Nar-Sie."
flags_inv = HIDEFACE
body_parts_covered = HEAD
armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0)
armor = list(melee = 50, bullet = 30, laser = 50, energy = 80, bomb = 25, bio = 10, rad = 0)
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0
@@ -73,7 +73,7 @@
icon_state = "cultrobes"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade)
armor = list(melee = 50, bullet = 30, laser = 50, energy = 20, bomb = 25, bio = 10, rad = 0)
armor = list(melee = 50, bullet = 30, laser = 50, energy = 80, bomb = 25, bio = 10, rad = 0)
flags_inv = HIDEJUMPSUIT
siemens_coefficient = 0
@@ -95,7 +95,7 @@
name = "cult helmet"
desc = "A space worthy helmet used by the followers of Nar-Sie."
icon_state = "cult_helmet"
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
armor = list(melee = 60, bullet = 50, laser = 30, energy = 80, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0
/obj/item/clothing/head/helmet/space/cult/cultify()
@@ -108,7 +108,7 @@
w_class = ITEMSIZE_NORMAL
allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency/oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 1
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30)
armor = list(melee = 60, bullet = 50, laser = 30, energy = 80, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS

View File

@@ -958,7 +958,7 @@ var/list/sacrificed = list()
if(N)
continue
C.eye_blurry += 50
C.eye_blind += 20
C.Blind(20)
if(prob(5))
C.disabilities |= NEARSIGHTED
if(prob(10))
@@ -981,7 +981,7 @@ var/list/sacrificed = list()
if(N)
continue
C.eye_blurry += 30
C.eye_blind += 10
C.Blind(10)
//talismans is weaker.
affected += C
C.show_message("<span class='warning'>You feel a sharp pain in your eyes, and the world disappears into darkness..</span>", 3)

View File

@@ -7,20 +7,13 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
/datum/game_mode/heist
name = "Heist"
config_tag = "heist"
required_players = 8
required_players_secret = 8
required_enemies = 3
required_players = 15
required_players_secret = 15
required_enemies = 4
round_description = "An unidentified bluespace signature is approaching the station!"
extended_round_description = "The Company's majority control of phoron in the system has marked the \
station to be a highly valuable target for many competing organizations and individuals. Being a \
colony of sizable population and considerable wealth causes it to often be the target of various \
attempts of robbery, fraud and other malicious actions."
end_on_antag_death = 0
antag_tags = list(MODE_RAIDER)
/datum/game_mode/heist/check_finished()
if(!..())
var/datum/shuttle/multi_shuttle/skipjack = shuttle_controller.shuttles["Skipjack"]
if (skipjack && skipjack.returned_home)
return 1
return 0
antag_tags = list(MODE_RAIDER)

View File

@@ -12,9 +12,9 @@ var/list/nuke_disks = list()
colony of sizable population and considerable wealth causes it to often be the target of various \
attempts of robbery, fraud and other malicious actions."
config_tag = "mercenary"
required_players = 8
required_players_secret = 8
required_enemies = 3
required_players = 15
required_players_secret = 15
required_enemies = 4
end_on_antag_death = 0
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level

View File

@@ -191,6 +191,7 @@
icon_state = "scepter"
force = 15
slot_flags = SLOT_BELT
attack_verb = list("beaten", "smashed", "struck", "whacked")
/obj/item/weapon/scepter/attack_self(mob/living/carbon/human/user)
var/obj/item/item_to_test = user.get_other_hand(src)

View File

@@ -285,4 +285,4 @@
to_chat(H, "<span class='warning'>The purple glow makes you feel strange...</span>")
H.adjust_instability(outgoing_instability)
set_light(distance, distance * 2, l_color = "#C26DDE")
set_light(distance, distance * 4, l_color = "#C26DDE")

View File

@@ -25,7 +25,7 @@
if(is_ally(L))
continue
var/damage_to_inflict = max(L.health / L.maxHealth, 0) // Otherwise, those in crit would actually be healed.
var/damage_to_inflict = max(L.health / L.getMaxHealth(), 0) // Otherwise, those in crit would actually be healed.
var/armor_factor = abs(L.getarmor(null, "energy") - 100)
armor_factor = armor_factor / 100

View File

@@ -21,5 +21,6 @@
for(var/obj/item/weapon/inserted_spell/I in target)
I.on_expire(dispelled = 1)
log_and_message_admins("dispelled [I] on [target].")
target.remove_modifiers_of_type(/datum/modifier/technomancer)
user.adjust_instability(10)
qdel(src)

View File

@@ -93,6 +93,9 @@
var/walking = 0
var/step_delay = 10
/mob/living/simple_animal/illusion/update_icon() // We don't want the appearance changing AT ALL unless by copy_appearance().
return
/mob/living/simple_animal/illusion/proc/copy_appearance(var/atom/movable/thing_to_copy)
if(!thing_to_copy)
return 0

View File

@@ -32,7 +32,7 @@
warned_victim = predict_crit(pulses, H, 0)
sleep(4 SECONDS)
H.adjustOxyLoss(5)
var/health_lost = H.maxHealth - H.getOxyLoss() + H.getToxLoss() + H.getFireLoss() + H.getBruteLoss() + H.getCloneLoss()
var/health_lost = H.getMaxHealth() - H.getOxyLoss() + H.getToxLoss() + H.getFireLoss() + H.getBruteLoss() + H.getCloneLoss()
H.adjustOxyLoss(round(abs(health_lost * 0.25)))
//world << "Inflicted [round(abs(health_lost * 0.25))] damage!"
pulses--
@@ -62,7 +62,7 @@
pulses_remaining--
return .(pulses_remaining, victim, previous_damage)
// Now check if our damage predictions are going to cause the victim to go into crit if no healing occurs.
if(previous_damage + health_lost >= victim.maxHealth) // We're probably going to hardcrit
if(previous_damage + health_lost >= victim.getMaxHealth()) // We're probably going to hardcrit
victim << "<span class='danger'><font size='3'>A feeling of immense dread starts to overcome you as everything starts \
to fade to black...</font></span>"
//world << "Predicted hardcrit."

View File

@@ -1,42 +0,0 @@
/datum/technomancer/spell/corona
name = "Corona"
desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \
bright glow also makes it very difficult to be stealthy. The effect lasts for one minute."
spell_power_desc = "Enemies become even easier to hit."
cost = 50
obj_path = /obj/item/weapon/spell/insert/corona
ability_icon_state = "tech_corona"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/corona
name = "corona"
desc = "How brillient!"
icon_state = "radiance"
cast_methods = CAST_RANGED
aspect = ASPECT_LIGHT
light_color = "#D9D900"
spell_light_intensity = 5
spell_light_range = 3
inserting = /obj/item/weapon/inserted_spell/corona
/obj/item/weapon/inserted_spell/corona
var/evasion_reduction = 2 // We store this here because spell power may change when the spell expires.
/obj/item/weapon/inserted_spell/corona/on_insert()
spawn(1)
if(isliving(host))
var/mob/living/L = host
evasion_reduction = round(2 * spell_power_at_creation, 1)
L.evasion -= evasion_reduction
L.visible_message("<span class='warning'>You start to glow very brightly!</span>")
spawn(1 MINUTE)
if(src)
on_expire()
/obj/item/weapon/inserted_spell/corona/on_expire()
if(isliving(host))
var/mob/living/L = host
L.evasion += evasion_reduction
L << "<span class='notice'>Your glow has ended.</span>"
..()

View File

@@ -1,36 +0,0 @@
/datum/technomancer/spell/haste
name = "Haste"
desc = "Allows the target to run at speeds that should not be possible for an ordinary being. For five seconds, the target \
runs extremly fast, and cannot be slowed by any means."
spell_power_desc = "Duration is scaled up."
cost = 100
obj_path = /obj/item/weapon/spell/insert/haste
ability_icon_state = "tech_haste"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/haste
name = "haste"
desc = "Now you can outrun a Teshari!"
icon_state = "haste"
cast_methods = CAST_RANGED
aspect = ASPECT_FORCE
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/haste
/obj/item/weapon/inserted_spell/haste/on_insert()
spawn(1)
if(isliving(host))
var/mob/living/L = host
L.force_max_speed = 1
L << "<span class='notice'>You suddenly find it much easier to move.</span>"
L.adjust_instability(10)
spawn(round(5 SECONDS * spell_power_at_creation, 1))
if(src)
on_expire()
/obj/item/weapon/inserted_spell/haste/on_expire()
if(isliving(host))
var/mob/living/L = host
L.force_max_speed = 0
L << "<span class='warning'>You feel slow again.</span>"
..()

View File

@@ -1,39 +0,0 @@
/datum/technomancer/spell/repel_missiles
name = "Repel Missiles"
desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \
to hit you. The field lasts for five minutes and can be granted to yourself or an ally."
spell_power_desc = "Projectiles will be more likely to be deflected."
cost = 25
obj_path = /obj/item/weapon/spell/insert/repel_missiles
ability_icon_state = "tech_repelmissiles"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/insert/repel_missiles
name = "repel missiles"
desc = "Use it before they start shooting at you!"
icon_state = "generic"
cast_methods = CAST_RANGED
aspect = ASPECT_FORCE
light_color = "#FF5C5C"
inserting = /obj/item/weapon/inserted_spell/repel_missiles
/obj/item/weapon/inserted_spell/repel_missiles
var/evasion_increased = 2 // We store this here because spell power may change when the spell expires.
/obj/item/weapon/inserted_spell/repel_missiles/on_insert()
spawn(1)
if(isliving(host))
var/mob/living/L = host
evasion_increased = round(2 * spell_power_at_creation, 1)
L.evasion += evasion_increased
L << "<span class='notice'>You have a repulsion field around you, which will attempt to deflect projectiles.</span>"
spawn(5 MINUTES)
if(src)
on_expire()
/obj/item/weapon/inserted_spell/repel_missiles/on_expire()
if(isliving(host))
var/mob/living/L = host
L.evasion -= evasion_increased
L << "<span class='warning'>Your repulsion field has expired.</span>"
..()

View File

@@ -0,0 +1,33 @@
/datum/technomancer/spell/corona
name = "Corona"
desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \
bright glow also makes it very difficult to be stealthy. The effect lasts for one minute."
cost = 50
obj_path = /obj/item/weapon/spell/modifier/corona
ability_icon_state = "tech_corona"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/modifier/corona
name = "corona"
desc = "How brillient!"
icon_state = "radiance"
cast_methods = CAST_RANGED
aspect = ASPECT_LIGHT
light_color = "#D9D900"
spell_light_intensity = 5
spell_light_range = 3
modifier_type = /datum/modifier/technomancer/corona
modifier_duration = 1 MINUTE
/datum/modifier/technomancer/corona
name = "corona"
desc = "You appear to be glowing really bright. It doesn't seem to hurt, however hiding will be impossible."
mob_overlay_state = "corona"
on_created_text = "<span class='warning'>You start to glow very brightly!</span>"
on_expired_text = "<span class='notice'>Your glow has ended.</span>"
evasion = -2
stacks = MODIFIER_STACK_EXTEND
/datum/modifier/technomancer/corona/tick()
holder.break_cloak()

View File

@@ -0,0 +1,28 @@
/datum/technomancer/spell/haste
name = "Haste"
desc = "Allows the target to run at speeds that should not be possible for an ordinary being. For five seconds, the target \
runs extremly fast, and cannot be slowed by any means."
cost = 100
obj_path = /obj/item/weapon/spell/modifier/haste
ability_icon_state = "tech_haste"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/modifier/haste
name = "haste"
desc = "Now you can outrun a Teshari!"
icon_state = "haste"
cast_methods = CAST_RANGED
aspect = ASPECT_FORCE
light_color = "#FF5C5C"
modifier_type = /datum/modifier/technomancer/haste
modifier_duration = 5 SECONDS
/datum/modifier/technomancer/haste
name = "haste"
desc = "Moving is almost effortless!"
mob_overlay_state = "haste"
on_created_text = "<span class='notice'>You suddenly find it much easier to move.</span>"
on_expired_text = "<span class='warning'>You feel slow again.</span>"
haste = TRUE
stacks = MODIFIER_STACK_EXTEND

View File

@@ -0,0 +1,31 @@
/obj/item/weapon/spell/modifier
name = "modifier template"
desc = "Tell a coder if you can read this in-game."
icon_state = "purify"
cast_methods = CAST_MELEE
var/modifier_type = null
var/modifier_duration = null // Will last forever by default. Final duration may differ due to 'spell power'
// var/spell_color = "#03A728"
var/spell_light_intensity = 2
var/spell_light_range = 3
/obj/item/weapon/spell/modifier/New()
..()
set_light(spell_light_range, spell_light_intensity, l_color = light_color)
/obj/item/weapon/spell/modifier/on_melee_cast(atom/hit_atom, mob/user)
if(istype(hit_atom, /mob/living))
on_add_modifier(hit_atom)
/obj/item/weapon/spell/modifier/on_ranged_cast(atom/hit_atom, mob/user)
if(istype(hit_atom, /mob/living))
on_add_modifier(hit_atom)
/obj/item/weapon/spell/modifier/proc/on_add_modifier(var/mob/living/L)
var/duration = modifier_duration
if(duration)
duration = round(duration * calculate_spell_power(1.0), 1)
L.add_modifier(modifier_type, duration)
log_and_message_admins("has casted [src] on [L].")
qdel(src)

View File

@@ -0,0 +1,28 @@
/datum/technomancer/spell/repel_missiles
name = "Repel Missiles"
desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \
to hit you. The field lasts for 10 minutes and can be granted to yourself or an ally."
cost = 25
obj_path = /obj/item/weapon/spell/modifier/repel_missiles
ability_icon_state = "tech_repelmissiles"
category = SUPPORT_SPELLS
/obj/item/weapon/spell/modifier/repel_missiles
name = "repel missiles"
desc = "Use it before they start shooting at you!"
icon_state = "generic"
cast_methods = CAST_RANGED
aspect = ASPECT_FORCE
light_color = "#FF5C5C"
modifier_type = /datum/modifier/technomancer/repel_missiles
modifier_duration = 10 MINUTES
/datum/modifier/technomancer/repel_missiles
name = "repel_missiles"
desc = "A repulsion field can always be useful to have."
mob_overlay_state = "repel_missiles"
on_created_text = "<span class='notice'>You have a repulsion field around you, which will attempt to deflect projectiles.</span>"
on_expired_text = "<span class='warning'>Your repulsion field has expired.</span>"
evasion = 3
stacks = MODIFIER_STACK_EXTEND

View File

@@ -32,7 +32,7 @@
user << "<span class='notice'>You stab \the [L] with a hidden integrated hypo, attempting to bring them back...</span>"
if(istype(L, /mob/living/simple_animal))
var/mob/living/simple_animal/SM = L
SM.health = SM.maxHealth / 3
SM.health = SM.getMaxHealth() / 3
SM.stat = CONSCIOUS
dead_mob_list -= SM
living_mob_list += SM

View File

@@ -20,10 +20,10 @@
/obj/item/weapon/spell/spawner/darkness/New()
..()
set_light(6, -5, l_color = "#FFFFFF")
set_light(6, -20, l_color = "#FFFFFF")
/obj/effect/temporary_effect/darkness
name = "darkness"
time_to_die = 2 MINUTES
new_light_range = 6
new_light_power = -5
new_light_power = -20

View File

@@ -62,4 +62,4 @@
// Now we hurt their new pal, because being forcefully abducted by teleportation can't be healthy.
summoned.health = round(summoned.maxHealth * 0.7)
summoned.health = round(summoned.getMaxHealth() * 0.7)

View File

@@ -27,11 +27,13 @@
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/bar(H), slot_belt)
if(has_alt_title(H, alt_title,"Bartender"))
var/obj/item/weapon/permit/gun/bar/permit = new(H)
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/permit/gun/bar(H), slot_l_hand)
H.equip_to_slot_or_del(permit, slot_l_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/permit/gun/bar(H.back), slot_in_backpack)
return 1
H.equip_to_slot_or_del(permit, slot_in_backpack)
permit.set_name(H.real_name)
return 1

View File

@@ -375,6 +375,7 @@ var/global/datum/controller/occupations/job_master
job.equip_backpack(H)
job.equip_survival(H)
job.apply_fingerprints(H)
H.equip_post_job()
//If some custom items could not be equipped before, try again now.
for(var/thing in custom_equip_leftovers)

View File

@@ -68,10 +68,12 @@
anchored = 1
circuit = /obj/item/weapon/circuitboard/sleeper
var/mob/living/carbon/human/occupant = null
var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin")
var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin")
var/obj/item/weapon/reagent_containers/glass/beaker = null
var/filtering = 0
var/obj/machinery/sleep_console/console
var/stasis_level = 0 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1)
var/stasis_choices = list("Complete (1%)" = 100, "Deep (10%)" = 10, "Moderate (20%)" = 5, "Light (50%)" = 2, "None (100%)" = 0)
use_power = 1
idle_power_usage = 15
@@ -98,18 +100,23 @@
/obj/machinery/sleeper/process()
if(stat & (NOPOWER|BROKEN))
return
if(occupant)
occupant.Stasis(stasis_level)
if(stasis_level >= 100 && occupant.timeofdeath)
occupant.timeofdeath += 1 SECOND
if(filtering > 0)
if(beaker)
if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
var/pumped = 0
for(var/datum/reagent/x in occupant.reagents.reagent_list)
occupant.reagents.trans_to_obj(beaker, 3)
pumped++
if(ishuman(occupant))
occupant.vessel.trans_to_obj(beaker, pumped + 1)
else
toggle_filter()
if(filtering > 0)
if(beaker)
if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
var/pumped = 0
for(var/datum/reagent/x in occupant.reagents.reagent_list)
occupant.reagents.trans_to_obj(beaker, 3)
pumped++
if(ishuman(occupant))
occupant.vessel.trans_to_obj(beaker, pumped + 1)
else
toggle_filter()
/obj/machinery/sleeper/update_icon()
icon_state = "sleeper_[occupant ? "1" : "0"]"
@@ -154,6 +161,13 @@
data["beaker"] = -1
data["filtering"] = filtering
var/stasis_level_name = "Error!"
for(var/N in stasis_choices)
if(stasis_choices[N] == stasis_level)
stasis_level_name = N
break
data["stasis"] = stasis_level_name
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "sleeper.tmpl", "Sleeper UI", 600, 600, state = state)
@@ -182,12 +196,20 @@
if(occupant && occupant.stat != DEAD)
if(href_list["chemical"] in available_chemicals) // Your hacks are bad and you should feel bad
inject_chemical(usr, href_list["chemical"], text2num(href_list["amount"]))
if(href_list["change_stasis"])
var/new_stasis = input("Levels deeper than 50% stasis level will render the patient unconscious.","Stasis Level") as null|anything in stasis_choices
if(new_stasis && CanUseTopic(usr, default_state) == STATUS_INTERACTIVE)
stasis_level = stasis_choices[new_stasis]
return 1
/obj/machinery/sleeper/attackby(var/obj/item/I, var/mob/user)
add_fingerprint(user)
if(default_deconstruction_screwdriver(user, I))
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
if(G.affecting)
go_in(G.affecting, user)
else if(default_deconstruction_screwdriver(user, I))
return
else if(default_deconstruction_crowbar(user, I))
return
@@ -201,6 +223,28 @@
user << "<span class='warning'>\The [src] has a beaker already.</span>"
return
/obj/machinery/sleeper/verb/move_eject()
set name = "Eject occupant"
set category = "Object"
set src in oview(1)
if(usr == occupant)
switch(usr.stat)
if(DEAD)
return
if(UNCONSCIOUS)
usr << "<span class='notice'>You struggle through the haze to hit the eject button. This will take a couple of minutes...</span>"
sleep(2 MINUTES)
if(!src || !usr || !occupant || (occupant != usr)) //Check if someone's released/replaced/bombed him already
return
go_out()
if(CONSCIOUS)
go_out()
else
if(usr.stat != 0)
return
go_out()
add_fingerprint(usr)
/obj/machinery/sleeper/MouseDrop_T(var/mob/target, var/mob/user)
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !ishuman(target))
return
@@ -261,6 +305,7 @@
if(occupant.client)
occupant.client.eye = occupant.client.mob
occupant.client.perspective = MOB_PERSPECTIVE
occupant.Stasis(0)
occupant.loc = src.loc
occupant = null
for(var/atom/movable/A in src) // In case an object was dropped inside or something

View File

@@ -301,6 +301,15 @@
occupantData["reagents"] = reagentData
var/ingestedData[0]
if(H.ingested.reagent_list.len >= 1)
for(var/datum/reagent/R in H.ingested.reagent_list)
ingestedData[++ingestedData.len] = list("name" = R.name, "amount" = R.volume)
else
ingestedData = null
occupantData["ingested"] = ingestedData
var/extOrganData[0]
for(var/obj/item/organ/external/E in H.organs)
var/organData[0]
@@ -394,7 +403,7 @@
P.info += "<b>Time of scan:</b> [worldtime2stationtime(world.time)]<br><br>"
P.info += "[printing_text]"
P.info += "<br><br><b>Notes:</b><br>"
P.name = "Body Scan - [href_list["name"]]"
P.name = "Body Scan - [href_list["name"]] ([worldtime2stationtime(world.time)])"
printing = null
printing_text = null
@@ -457,9 +466,13 @@
dat += "[extra_font]\tBlood Level %: [blood_percent] ([blood_volume] units)</font><br>"
if(occupant.reagents)
for(var/datum/reagent/R in occupant.reagents)
for(var/datum/reagent/R in occupant.reagents.reagent_list)
dat += "Reagent: [R.name], Amount: [R.volume]<br>"
if(occupant.ingested)
for(var/datum/reagent/R in occupant.ingested.reagent_list)
dat += "Stomach: [R.name], Amount: [R.volume]<br>"
dat += "<hr><table border='1'>"
dat += "<tr>"
dat += "<th>Organ</th>"

View File

@@ -72,7 +72,6 @@ obj/machinery/air_sensor/Destroy()
..()
/obj/machinery/computer/general_air_control
icon = 'icons/obj/computer.dmi'
icon_keyboard = "atmos_key"
icon_screen = "tank"
name = "Computer"

View File

@@ -232,6 +232,8 @@ mob/living/proc/near_camera()
return TRACKING_TERMINATE
if(digitalcamo)
return TRACKING_TERMINATE
if(alpha < 127) // For lings and possible future alpha-based cloaks.
return TRACKING_TERMINATE
if(istype(loc,/obj/effect/dummy))
return TRACKING_TERMINATE

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/aifixer
name = "\improper AI system integrity restorer"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "rd_key"
icon_screen = "ai-fixer"
light_color = "#a97faa"
@@ -102,7 +101,7 @@
return 1
if (href_list["fix"])
src.active = 1
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-on")
src.overlays += image(icon, "ai-fixer-on")
while (src.occupant.health < 100)
src.occupant.adjustOxyLoss(-1)
src.occupant.adjustFireLoss(-1)
@@ -114,13 +113,13 @@
src.occupant.lying = 0
dead_mob_list -= src.occupant
living_mob_list += src.occupant
src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
src.overlays -= image(icon, "ai-fixer-404")
src.overlays += image(icon, "ai-fixer-full")
src.occupant.add_ai_verbs()
src.updateUsrDialog()
sleep(10)
src.active = 0
src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-on")
src.overlays -= image(icon, "ai-fixer-on")
src.add_fingerprint(usr)
@@ -135,8 +134,8 @@
if(occupant)
if(occupant.stat)
overlays += image('icons/obj/computer.dmi', "ai-fixer-404", overlay_layer)
overlays += image(icon, "ai-fixer-404", overlay_layer)
else
overlays += image('icons/obj/computer.dmi', "ai-fixer-full", overlay_layer)
overlays += image(icon, "ai-fixer-full", overlay_layer)
else
overlays += image('icons/obj/computer.dmi', "ai-fixer-empty", overlay_layer)
overlays += image(icon, "ai-fixer-empty", overlay_layer)

View File

@@ -4,7 +4,6 @@
/obj/machinery/computer/atmoscontrol
name = "\improper Central Atmospherics Computer"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "generic_key"
icon_screen = "comm_logs"
light_color = "#00b000"

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/cloning
name = "cloning control console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "med_key"
icon_screen = "dna"
light_color = "#315ab4"

View File

@@ -85,6 +85,7 @@
if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
dat += "<table><tr><td>Name: [active1.fields["name"]] \
ID: [active1.fields["id"]]<BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];field=sex'>[active1.fields["sex"]]</A><BR>\n"
if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
dat += "Gender identity: <A href='?src=\ref[src];field=id_gender'>[active2.fields["id_gender"]]</A><BR>"

View File

@@ -2,7 +2,6 @@
/obj/machinery/computer/prisoner
name = "prisoner management console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "security_key"
icon_screen = "explosive"
light_color = "#a91515"

View File

@@ -12,7 +12,6 @@ var/prison_shuttle_timeleft = 0
/obj/machinery/computer/prison_shuttle
name = "prison shuttle control console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "security_key"
icon_screen = "syndishuttle"
light_color = "#00ffff"

View File

@@ -1,7 +1,6 @@
/obj/machinery/computer/robotics
name = "robotics control console"
desc = "Used to remotely lockdown or detonate linked cyborgs."
icon = 'icons/obj/computer.dmi'
icon_keyboard = "tech_key"
icon_screen = "robot"
light_color = "#a97faa"

View File

@@ -127,6 +127,7 @@
dat += text("<table><tr><td> \
Name: <A href='?src=\ref[src];choice=Edit Field;field=name'>[active1.fields["name"]]</A><BR> \
ID: <A href='?src=\ref[src];choice=Edit Field;field=id'>[active1.fields["id"]]</A><BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];choice=Edit Field;field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];choice=Edit Field;field=age'>[active1.fields["age"]]</A><BR>\n \
Rank: <A href='?src=\ref[src];choice=Edit Field;field=rank'>[active1.fields["rank"]]</A><BR>\n \
@@ -612,5 +613,4 @@ What a mess.*/
..(severity)
/obj/machinery/computer/secure_data/detective_computer
icon = 'icons/obj/computer.dmi'
icon_state = "messyfiles"

View File

@@ -93,6 +93,7 @@
dat += text("<table><tr><td> \
Name: <A href='?src=\ref[src];choice=Edit Field;field=name'>[active1.fields["name"]]</A><BR> \
ID: <A href='?src=\ref[src];choice=Edit Field;field=id'>[active1.fields["id"]]</A><BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];choice=Edit Field;field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];choice=Edit Field;field=age'>[active1.fields["age"]]</A><BR>\n \
Rank: <A href='?src=\ref[src];choice=Edit Field;field=rank'>[active1.fields["rank"]]</A><BR>\n \

View File

@@ -13,7 +13,6 @@ var/specops_shuttle_timeleft = 0
/obj/machinery/computer/specops_shuttle
name = "special operations shuttle control console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "security_key"
icon_screen = "syndishuttle"
light_color = "#00ffff"

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/supplycomp
name = "supply control console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "tech_key"
icon_screen = "supply"
light_color = "#b88b2e"
@@ -13,7 +12,6 @@
/obj/machinery/computer/ordercomp
name = "supply ordering console"
icon = 'icons/obj/computer.dmi'
icon_screen = "request"
circuit = /obj/item/weapon/circuitboard/ordercomp
var/temp = null

View File

@@ -12,7 +12,6 @@ var/syndicate_elite_shuttle_timeleft = 0
/obj/machinery/computer/syndicate_elite_shuttle
name = "elite syndicate squad shuttle control console"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "syndie_key"
icon_screen = "syndishuttle"
light_color = "#00ffff"

View File

@@ -95,6 +95,7 @@
dat += "<table><tr><td>Name: [active1.fields["name"]] \
ID: [active1.fields["id"]]<BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];field=age'>[active1.fields["age"]]</A><BR>\n \
Fingerprint: <A href='?src=\ref[src];field=fingerprint'>[active1.fields["fingerprint"]]</A><BR>\n \

View File

@@ -134,6 +134,7 @@
dat += text("<table><tr><td> \
Name: <A href='?src=\ref[src];choice=Edit Field;field=name'>[active1.fields["name"]]</A><BR> \
ID: <A href='?src=\ref[src];choice=Edit Field;field=id'>[active1.fields["id"]]</A><BR>\n \
Entity Classification: <A href='?src=\ref[src];field=brain_type'>[active1.fields["brain_type"]]</A><BR>\n \
Sex: <A href='?src=\ref[src];choice=Edit Field;field=sex'>[active1.fields["sex"]]</A><BR>\n \
Age: <A href='?src=\ref[src];choice=Edit Field;field=age'>[active1.fields["age"]]</A><BR>\n \
Rank: <A href='?src=\ref[src];choice=Edit Field;field=rank'>[active1.fields["rank"]]</A><BR>\n \

View File

@@ -96,7 +96,7 @@
occupantData["name"] = occupant.name
occupantData["stat"] = occupant.stat
occupantData["health"] = occupant.health
occupantData["maxHealth"] = occupant.maxHealth
occupantData["maxHealth"] = occupant.getMaxHealth()
occupantData["minHealth"] = config.health_threshold_dead
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()

View File

@@ -534,7 +534,7 @@
time_entered = world.time
if(ishuman(M) && applies_stasis)
var/mob/living/carbon/human/H = M
H.in_stasis = 1
H.Stasis(1000)
// Book keeping!
var/turf/location = get_turf(src)
@@ -602,7 +602,7 @@
set_occupant(usr)
if(ishuman(usr) && applies_stasis)
var/mob/living/carbon/human/H = occupant
H.in_stasis = 1
H.Stasis(1000)
icon_state = occupied_icon_state
@@ -638,7 +638,7 @@
occupant.forceMove(get_turf(src))
if(ishuman(occupant) && applies_stasis)
var/mob/living/carbon/human/H = occupant
H.in_stasis = 0
H.Stasis(0)
set_occupant(null)
icon_state = base_icon_state

View File

@@ -777,7 +777,7 @@ About the new airlock wires panel:
src.welded = 1
else
src.welded = null
playsound(src, 'sound/items/Welder.ogg', 100, 1)
playsound(src, 'sound/items/Welder.ogg', 75, 1)
src.update_icon()
return
else
@@ -802,7 +802,7 @@ About the new airlock wires panel:
cable.plugin(src, user)
else if(!repairing && istype(C, /obj/item/weapon/crowbar))
if(src.p_open && (operating < 0 || (!operating && welded && !src.arePowerSystemsOn() && density && (!src.locked || (stat & BROKEN)))) )
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
playsound(src.loc, 'sound/items/Crowbar.ogg', 75, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.")
if(do_after(user,40))
to_chat(user,"<span class='notice'>You removed the airlock electronics!</span>")
@@ -895,9 +895,9 @@ About the new airlock wires panel:
//if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator
if(arePowerSystemsOn())
playsound(src.loc, open_sound_powered, 100, 1)
playsound(src.loc, open_sound_powered, 75, 1)
else
playsound(src.loc, open_sound_unpowered, 100, 1)
playsound(src.loc, open_sound_unpowered, 75, 1)
if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density)
src.closeOther.close()
@@ -992,9 +992,9 @@ About the new airlock wires panel:
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
has_beeped = 0
if(arePowerSystemsOn())
playsound(src.loc, open_sound_powered, 100, 1)
playsound(src.loc, open_sound_powered, 75, 1)
else
playsound(src.loc, open_sound_unpowered, 100, 1)
playsound(src.loc, open_sound_unpowered, 75, 1)
for(var/turf/turf in locs)
var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf)
if(killthis)

View File

@@ -12,6 +12,7 @@
desc = "That looks like it doesn't open easily."
icon = 'icons/obj/doors/rapid_pdoor.dmi'
icon_state = null
min_force = 20 //minimum amount of force needed to damage the door with a melee weapon
// Icon states for different shutter types. Simply change this instead of rewriting the update_icon proc.
var/icon_state_open = null
@@ -78,7 +79,10 @@
// Proc: force_toggle()
// Parameters: None
// Description: Opens or closes the door, depending on current state. No checks are done inside this proc.
/obj/machinery/door/blast/proc/force_toggle()
/obj/machinery/door/blast/proc/force_toggle(var/forced = 0, mob/user as mob)
if (forced)
playsound(src.loc, 'sound/machines/airlock_creaking.ogg', 100, 1)
if(src.density)
src.force_open()
else
@@ -91,7 +95,7 @@
/obj/machinery/door/blast/attackby(obj/item/weapon/C as obj, mob/user as mob)
src.add_fingerprint(user)
if(istype(C, /obj/item/weapon)) // For reasons unknown, sometimes C is actually not what it is advertised as, like a mob.
if(C.pry == 1) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
if(C.pry == 1 && (user.a_intent != I_HURT || (stat & BROKEN))) // Can we pry it open with something, like a crowbar/fireaxe/lingblade?
if(istype(C,/obj/item/weapon/material/twohanded/fireaxe)) // Fireaxes need to be in both hands to pry.
var/obj/item/weapon/material/twohanded/fireaxe/F = C
if(!F.wielded)
@@ -100,7 +104,8 @@
// If we're at this point, it's a fireaxe in both hands or something else that doesn't care for twohanding.
if(((stat & NOPOWER) || (stat & BROKEN)) && !( src.operating ))
force_toggle()
force_toggle(1, user)
else
usr << "<span class='notice'>[src]'s motors resist your effort.</span>"
return
@@ -123,15 +128,33 @@
usr << "<span class='warning'>You don't have enough sheets to repair this! You need at least [amt] sheets.</span>"
else if(src.density)
var/obj/item/weapon/W = C
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(W.damtype == BRUTE || W.damtype == BURN)
user.do_attack_animation(src)
if(W.force < min_force)
user.visible_message("<span class='danger'>\The [user] hits \the [src] with \the [W] with no visible effect.</span>")
else
user.visible_message("<span class='danger'>\The [user] forcefully strikes \the [src] with \the [W]!</span>")
playsound(src.loc, hitsound, 100, 1)
take_damage(W.force*0.35) //it's a blast door, it should take a while. -Luke
return
// Proc: open()
// Parameters: None
// Description: Opens the door. Does necessary checks. Automatically closes if autoclose is true
/obj/machinery/door/blast/open()
if (src.operating || (stat & BROKEN || stat & NOPOWER))
return
force_open()
if(autoclose)
/obj/machinery/door/blast/open(var/forced = 0)
if(forced)
force_open()
return 1
else
if (src.operating || (stat & BROKEN || stat & NOPOWER))
return 1
force_open()
if(autoclose && src.operating && !(stat & BROKEN || stat & NOPOWER))
spawn(150)
close()
return 1

View File

@@ -312,6 +312,8 @@
/obj/machinery/door/examine(mob/user)
. = ..()
if(src.health <= 0)
user << "\The [src] is broken!"
if(src.health < src.maxhealth / 4)
user << "\The [src] looks like it's about to break!"
else if(src.health < src.maxhealth / 2)

View File

@@ -78,7 +78,7 @@
C.traits = new()
C.nameVar = "grey"
I.add_product(C)
/obj/machinery/smartfridge/secure/medbay
name = "\improper Refrigerated Medicine Storage"
@@ -139,6 +139,7 @@
icon_state = "drying_rack"
icon_on = "drying_rack_on"
icon_off = "drying_rack"
icon_panel = "drying_rack-panel"
/obj/machinery/smartfridge/drying_rack/accept_check(var/obj/item/O as obj)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/))
@@ -260,7 +261,7 @@
locked = -1
user << "You short out the product lock on [src]."
return 1
/obj/machinery/smartfridge/proc/stock(obj/item/O)
var/hasRecord = FALSE //Check to see if this passes or not.
for(var/datum/stored_item/I in item_records)
@@ -273,7 +274,7 @@
item.add_product(O)
item_records.Add(item)
nanomanager.update_uis(src)
/obj/machinery/smartfridge/proc/vend(datum/stored_item/I)
I.get_product(get_turf(src))
nanomanager.update_uis(src)
@@ -357,7 +358,7 @@
if (!throw_item)
continue
break
if(!throw_item)
return 0
spawn(0)

View File

@@ -7,7 +7,7 @@
energy_drain = 20
range = MELEE
equip_cooldown = 50
var/mob/living/carbon/occupant = null
var/mob/living/carbon/human/occupant = null
var/datum/global_iterator/pr_mech_sleeper
var/inject_amount = 10
required_type = /obj/mecha/medical
@@ -28,7 +28,7 @@
Exit(atom/movable/O)
return 0
action(var/mob/living/carbon/target)
action(var/mob/living/carbon/human/target)
if(!action_checks(target))
return
if(!istype(target))
@@ -56,6 +56,7 @@
target.forceMove(src)
occupant = target
target.reset_view(src)
occupant.Stasis(3)
/*
if(target.client)
target.client.perspective = EYE_PERSPECTIVE
@@ -80,6 +81,7 @@
occupant.client.eye = occupant.client.mob
occupant.client.perspective = MOB_PERSPECTIVE
*/
occupant.Stasis(0)
occupant = null
pr_mech_sleeper.stop()
set_ready_state(1)

View File

@@ -1,6 +1,5 @@
/obj/machinery/computer/mecha
name = "Exosuit Control"
icon = 'icons/obj/computer.dmi'
icon_keyboard = "rd_key"
icon_screen = "mecha"
light_color = "#a97faa"

View File

@@ -95,7 +95,7 @@
holder.icon_state = "hudhealth-100"
C.images += holder
else
holder.icon_state = RoundHealth((patient.health-config.health_threshold_crit)/(patient.maxHealth-config.health_threshold_crit)*100)
holder.icon_state = RoundHealth((patient.health-config.health_threshold_crit)/(patient.getMaxHealth()-config.health_threshold_crit)*100)
C.images += holder
holder = patient.hud_list[STATUS_HUD]

View File

@@ -74,7 +74,12 @@
add_fingerprint(user)
unbuckle_mob()
if(buckle_mob(M))
//can't buckle unless you share locs so try to move M to the obj.
if(M.loc != src.loc)
step_towards(M, src)
. = buckle_mob(M)
if(.)
if(M == user)
M.visible_message(\
"<span class='notice'>[M.name] buckles themselves to [src].</span>",\

View File

@@ -77,14 +77,20 @@
/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location)
..()
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
if(!ishuman(usr)) return
if(!ishuman(usr)) return 0
if(opened) return 0
if(contents.len) return 0
visible_message("[usr] folds up the [src.name]")
new item_path(get_turf(src))
var/folded = new item_path(get_turf(src))
spawn(0)
qdel(src)
return
return folded
/obj/structure/closet/body_bag/relaymove(mob/user,direction)
if(src.loc != get_turf(src))
src.loc.relaymove(user,direction)
else
..()
/obj/structure/closet/body_bag/proc/get_occupants()
var/list/occupants = list()
@@ -109,34 +115,43 @@
/obj/item/bodybag/cryobag
name = "stasis bag"
desc = "A folded, non-reusable bag designed to prevent additional damage to an occupant, especially useful if short on time or in \
a hostile enviroment."
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
icon = 'icons/obj/cryobag.dmi'
icon_state = "bodybag_folded"
item_state = "bodybag_cryo_folded"
origin_tech = list(TECH_BIO = 4)
var/obj/item/weapon/reagent_containers/syringe/syringe
/obj/item/bodybag/cryobag/attack_self(mob/user)
var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc)
R.add_fingerprint(user)
if(syringe)
R.syringe = syringe
syringe = null
qdel(src)
/obj/structure/closet/body_bag/cryobag
name = "stasis bag"
desc = "A non-reusable plastic bag designed to prevent additional damage to an occupant, especially useful if short on time or in \
a hostile enviroment."
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
icon = 'icons/obj/cryobag.dmi'
item_path = /obj/item/bodybag/cryobag
store_misc = 0
store_items = 0
var/used = 0
var/obj/item/weapon/tank/tank = null
var/stasis_level = 3 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1)
var/obj/item/weapon/reagent_containers/syringe/syringe
/obj/structure/closet/body_bag/cryobag/New()
tank = new /obj/item/weapon/tank/emergency/oxygen(null) //It's in nullspace to prevent ejection when the bag is opened.
..()
/obj/structure/closet/body_bag/cryobag/Destroy()
if(syringe)
qdel(syringe)
syringe = null
qdel(tank)
tank = null
..()
@@ -151,11 +166,19 @@
O.desc = "Pretty useless now.."
qdel(src)
/obj/structure/closet/body_bag/cryobag/MouseDrop(over_object, src_location, over_location)
. = ..()
if(. && syringe)
var/obj/item/bodybag/cryobag/folded = .
folded.syringe = syringe
syringe = null
/obj/structure/closet/body_bag/cryobag/Entered(atom/movable/AM)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
H.in_stasis = 1
H.Stasis(stasis_level)
src.used = 1
inject_occupant(H)
if(istype(AM, /obj/item/organ))
var/obj/item/organ/O = AM
@@ -167,7 +190,7 @@
/obj/structure/closet/body_bag/cryobag/Exited(atom/movable/AM)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
H.in_stasis = 0
H.Stasis(0)
if(istype(AM, /obj/item/organ))
var/obj/item/organ/O = AM
@@ -181,10 +204,19 @@
return tank.air_contents
..()
/obj/structure/closet/body_bag/cryobag/proc/inject_occupant(var/mob/living/carbon/human/H)
if(!syringe)
return
if(H.reagents)
syringe.reagents.trans_to_mob(H, 30, CHEM_BLOOD)
/obj/structure/closet/body_bag/cryobag/examine(mob/user)
..()
if(Adjacent(user)) //The bag's rather thick and opaque from a distance.
user << "<span class='info'>You peer into \the [src].</span>"
if(syringe)
user << "<span class='info'>It has a syringe added to it.</span>"
for(var/mob/living/L in contents)
L.examine(user)
@@ -196,5 +228,28 @@
var/obj/item/device/healthanalyzer/analyzer = W
for(var/mob/living/L in contents)
analyzer.attack(L,user)
else if(istype(W,/obj/item/weapon/reagent_containers/syringe))
if(syringe)
to_chat(user,"<span class='warning'>\The [src] already has an injector! Remove it first.</span>")
else
var/obj/item/weapon/reagent_containers/syringe/syringe = W
to_chat(user,"<span class='info'>You insert \the [syringe] into \the [src], and it locks into place.</span>")
user.unEquip(syringe)
src.syringe = syringe
syringe.loc = null
for(var/mob/living/carbon/human/H in contents)
inject_occupant(H)
break
else if(istype(W,/obj/item/weapon/screwdriver))
if(syringe)
if(used)
to_chat(user,"<span class='warning'>The injector cannot be removed now that the stasis bag has been used!</span>")
else
syringe.forceMove(src.loc)
to_chat(user,"<span class='info'>You pry \the [syringe] out of \the [src].</span>")
syringe = null
else
..()

View File

@@ -1105,6 +1105,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(M.stat == DEAD && M.client && (M.is_preference_enabled(/datum/client_preference/ghost_ears))) // src.client is so that ghosts don't have to listen to mice
if(istype(M, /mob/new_player))
continue
if(M.forbid_seeing_deadchat)
continue
M.show_message("<span class='game say'>PDA Message - <span class='name'>[owner]</span> -> <span class='name'>[P.owner]</span>: <span class='message'>[t]</span></span>")
if(!conversations.Find("\ref[P]"))

View File

@@ -212,6 +212,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
alert_called = 0
update_icon()
ui_interact(user)
if(video_source)
watch_video(user)
// Proc: MouseDrop()
//Same thing PDAs do
@@ -1032,7 +1034,8 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
if(!Adjacent(user) || !video_source) return
user.set_machine(video_source)
user.reset_view(video_source)
user << "<span class='notice'>Now viewing video session. To leave camera view: OOC -> Cancel Camera View</span>"
to_chat(user,"<span class='notice'>Now viewing video session. To leave camera view, close the communicator window OR: OOC -> Cancel Camera View</span>")
to_chat(user,"<span class='notice'>To return to an active video session, use the communicator in your hand.</span>")
spawn(0)
while(user.machine == video_source && Adjacent(user))
var/turf/T = get_turf(video_source)

View File

@@ -92,8 +92,8 @@
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
H.confused = max(H.confused, flash_strength + 5)
H.eye_blind = max(H.eye_blind, flash_strength)
H.Confuse(flash_strength + 5)
H.Blind(flash_strength)
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
H.flash_eyes()
H.adjustHalLoss(halloss_per_flash * (flash_strength / 5)) // Should take four flashes to stun.

View File

@@ -65,10 +65,12 @@ var/global/list/default_medbay_channels = list(
..()
wires = new(src)
internal_channels = default_internal_channels.Copy()
listening_objects += src
/obj/item/device/radio/Destroy()
qdel(wires)
wires = null
listening_objects -= src
if(radio_controller)
radio_controller.remove_object(src, frequency)
for (var/ch_name in channels)
@@ -474,7 +476,6 @@ var/global/list/default_medbay_channels = list(
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
if (broadcasting)
if(get_dist(src, M) <= canhear_range)
talk_into(M, msg,null,verb,speaking)

View File

@@ -69,7 +69,7 @@ REAGENT SCANNER
user.show_message("<span class='notice'>Analyzing Results for [M]:</span>")
user.show_message("<span class='notice'>Overall Status: dead</span>")
else
user.show_message("<span class='notice'>Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.maxHealth)*100) ]% healthy"]</span>")
user.show_message("<span class='notice'>Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[round((M.health/M.getMaxHealth())*100) ]% healthy"]</span>")
user.show_message("<span class='notice'> Key: <font color='cyan'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font></span>", 1)
user.show_message("<span class='notice'> Damage Specifics: <font color='cyan'>[OX]</font> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font></span>")
user.show_message("<span class='notice'>Body Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)</span>", 1)

View File

@@ -47,6 +47,9 @@
var/mob/living/L = loc
if(!language)
return //Borgs were causing runtimes when passing language=null
if (language && (language.flags & NONVERBAL))
return //Not gonna translate sign language

View File

@@ -155,7 +155,7 @@
singular_name = "advanced trauma kit"
desc = "An advanced trauma kit for severe injuries."
icon_state = "traumakit"
heal_brute = 0
heal_brute = 5
origin_tech = list(TECH_BIO = 1)
/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
@@ -213,7 +213,7 @@
singular_name = "advanced burn kit"
desc = "An advanced treatment kit for severe burns."
icon_state = "burnkit"
heal_burn = 0
heal_burn = 5
origin_tech = list(TECH_BIO = 1)

View File

@@ -39,7 +39,7 @@ RSF
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
if (mode == 1)
mode = 2
user << "Changed dispensing mode to 'Drinking Glass'"
user << "Changed dispensing mode to 'Drinking Glass:Pint'"
return
if (mode == 2)
mode = 3
@@ -82,7 +82,7 @@ RSF
product = new /obj/item/clothing/mask/smokable/cigarette()
used_energy = 10
if(2)
product = new /obj/item/weapon/reagent_containers/food/drinks/glass2()
product = new /obj/item/weapon/reagent_containers/food/drinks/glass2/pint()
used_energy = 50
if(3)
product = new /obj/item/weapon/paper()

View File

@@ -399,21 +399,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM
..()
name = "empty [initial(name)]"
/obj/item/clothing/mask/smokable/pipe/light(var/flavor_text = "[usr] lights the [name].")
if(!src.lit && src.smoketime)
src.lit = 1
damtype = "fire"
icon_state = icon_on
item_state = icon_on
var/turf/T = get_turf(src)
T.visible_message(flavor_text)
processing_objects.Add(src)
if(ismob(loc))
var/mob/living/M = loc
M.update_inv_wear_mask(0)
M.update_inv_l_hand(0)
M.update_inv_r_hand(1)
/obj/item/clothing/mask/smokable/pipe/attack_self(mob/user as mob)
if(lit == 1)
if(user.a_intent == I_HURT)

View File

@@ -41,6 +41,8 @@
user << "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>"
/obj/item/weapon/handcuffs/proc/can_place(var/mob/target, var/mob/user)
if(user == target)
return 1
if(istype(user, /mob/living/silicon/robot))
if(user.Adjacent(target))
return 1

View File

@@ -38,7 +38,10 @@
IC.examine(user)
/obj/item/weapon/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user)
if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) )
if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) || istype(O, /obj/item/weapon/cell/device) )
IC.attackby(O, user)
else
..()
..()
/obj/item/weapon/implant/integrated_circuit/attack_self(mob/user)
IC.attack_self(user)

View File

@@ -7,7 +7,7 @@
/obj/item/weapon/material/kitchen/utensil
w_class = ITEMSIZE_TINY
thrown_force_divisor = 1
origin_tech = "materials=1"
origin_tech = list(TECH_MATERIAL = 1)
attack_verb = list("attacked", "stabbed", "poked")
sharp = 1
edge = 1

View File

@@ -64,7 +64,7 @@
edge = 1
force_divisor = 0.15 // 9 when wielded with hardness 60 (steel)
matter = list(DEFAULT_WALL_MATERIAL = 12000)
origin_tech = "materials=1"
origin_tech = list(TECH_MATERIAL = 1)
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/weapon/material/knife/suicide_act(mob/user)

View File

@@ -0,0 +1,263 @@
#define MATERIAL_ARMOR_COEFFICENT 0.05
/*
SEE code/modules/materials/materials.dm FOR DETAILS ON INHERITED DATUM.
This class of armor takes armor and appearance data from a material "datum".
They are also fragile based on material data and many can break/smash apart when hit.
Materials has a var called protectiveness which plays a major factor in how good it is for armor.
With the coefficent being 0.05, this is how strong different levels of protectiveness are (for melee)
For bullets and lasers, material hardness and reflectivity also play a major role, respectively.
Protectiveness | Armor %
0 = 0%
5 = 20%
10 = 33%
15 = 42%
20 = 50%
25 = 55%
30 = 60%
40 = 66%
50 = 71%
60 = 75%
70 = 77%
80 = 80%
*/
// Putting these at /clothing/ level saves a lot of code duplication in armor/helmets/gauntlets/etc
/obj/item/clothing
var/material/material = null // Why isn't this a datum?
var/applies_material_color = TRUE
var/unbreakable = FALSE
var/default_material = null // Set this to something else if you want material attributes on init.
var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
/obj/item/clothing/New(var/newloc, var/material_key)
..(newloc)
if(!material_key)
material_key = default_material
if(material_key) // May still be null if a material was not specified as a default.
set_material(material_key)
/obj/item/clothing/Destroy()
processing_objects -= src
..()
/obj/item/clothing/get_material()
return material
// Debating if this should be made an /obj/item/ proc.
/obj/item/clothing/proc/set_material(var/new_material)
material = get_material_by_name(new_material)
if(!material)
qdel(src)
else
name = "[material.display_name] [initial(name)]"
health = round(material.integrity/10)
if(applies_material_color)
color = material.icon_colour
if(material.products_need_process())
processing_objects |= src
update_armor()
// This is called when someone wearing the object gets hit in some form (melee, bullet_act(), etc).
// Note that this cannot change if someone gets hurt, as it merely reacts to being hit.
/obj/item/clothing/proc/clothing_impact(var/obj/source, var/damage)
if(material && damage)
material_impact(source, damage)
/obj/item/clothing/proc/material_impact(var/obj/source, var/damage)
if(!material || unbreakable)
return
if(istype(source, /obj/item/projectile))
var/obj/item/projectile/P = source
if(P.pass_flags & PASSGLASS)
if(material.opacity - 0.3 <= 0)
return // Lasers ignore 'fully' transparent material.
if(material.is_brittle())
health = 0
else if(!prob(material.hardness))
health--
if(health <= 0)
shatter()
/obj/item/clothing/proc/shatter()
if(!material)
return
var/turf/T = get_turf(src)
T.visible_message("<span class='danger'>\The [src] [material.destruction_desc]!</span>")
if(istype(loc, /mob/living))
var/mob/living/M = loc
M.drop_from_inventory(src)
if(material.shard_type == SHARD_SHARD) // Wearing glass armor is a bad idea.
var/obj/item/weapon/material/shard/S = material.place_shard(T)
M.embed(S)
playsound(src, "shatter", 70, 1)
qdel(src)
// Might be best to make ablative vests a material armor using a new material to cut down on this copypaste.
/obj/item/clothing/suit/armor/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
if(!material) // No point checking for reflection.
return ..()
if(material.reflectivity)
if(istype(damage_source, /obj/item/projectile/energy) || istype(damage_source, /obj/item/projectile/beam))
var/obj/item/projectile/P = damage_source
if(P.reflected) // Can't reflect twice
return ..()
var/reflectchance = (40 * material.reflectivity) - round(damage/3)
reflectchance *= material_armor_modifer
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
reflectchance /= 2
if(P.starting && prob(reflectchance))
visible_message("<span class='danger'>\The [user]'s [src.name] reflects [attack_text]!</span>")
// Find a turf near or on the original location to bounce to
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(user)
// redirect the projectile
P.redirect(new_x, new_y, curloc, user)
P.reflected = 1
return PROJECTILE_CONTINUE // complete projectile permutation
/proc/calculate_material_armor(amount)
var/result = 1 - MATERIAL_ARMOR_COEFFICENT * amount / (1 + MATERIAL_ARMOR_COEFFICENT * abs(amount))
result = result * 100
result = abs(result - 100)
return round(result)
/obj/item/clothing/proc/update_armor()
if(material)
var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0
melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer)
bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7)
laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7)
if(material.opacity != 1)
laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely.
energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4)
bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5)
// Makes sure the numbers stay capped.
for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor))
number = between(0, number, 100)
armor["melee"] = melee_armor
armor["bullet"] = bullet_armor
armor["laser"] = laser_armor
armor["energy"] = energy_armor
armor["bomb"] = bomb_armor
if(!isnull(material.conductivity))
siemens_coefficient = between(0, material.conductivity / 10, 10)
slowdown = between(0, round(material.weight / 10, 0.1), 6)
/obj/item/clothing/suit/armor/material
name = "armor"
default_material = DEFAULT_WALL_MATERIAL
/obj/item/clothing/suit/armor/material/makeshift
name = "sheet armor"
desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective."
icon_state = "material_armor_makeshift"
/obj/item/clothing/suit/armor/material/makeshift/durasteel
default_material = "durasteel"
/obj/item/clothing/suit/armor/material/makeshift/glass
default_material = "glass"
// Used to craft sheet armor, and possibly other things in the Future(tm).
/obj/item/weapon/material/armor_plating
name = "armor plating"
desc = "A sheet designed to protect something."
icon = 'icons/obj/items.dmi'
icon_state = "armor_plate"
unbreakable = TRUE
force_divisor = 0.05 // Really bad as a weapon.
thrown_force_divisor = 0.2
var/wired = FALSE
/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/S = O
if(wired)
to_chat(user, "<span class='warning'>This already has enough wires on it.</span>")
return
if(S.use(20))
to_chat(user, "<span class='notice'>You attach several wires to \the [src]. Now it needs another plate.</span>")
wired = TRUE
icon_state = "[initial(icon_state)]_wired"
return
else
to_chat(user, "<span class='notice'>You need more wire for that.</span>")
return
if(istype(O, /obj/item/weapon/material/armor_plating))
var/obj/item/weapon/material/armor_plating/second_plate = O
if(!wired && !second_plate.wired)
to_chat(user, "<span class='warning'>You need something to hold the two pieces of plating together.</span>")
return
if(second_plate.material != src.material)
to_chat(user, "<span class='warning'>Both plates need to be the same type of material.</span>")
return
user.drop_from_inventory(src)
user.drop_from_inventory(second_plate)
var/obj/item/clothing/suit/armor/material/makeshift/new_armor = new(null, src.material.name)
user.put_in_hands(new_armor)
qdel(second_plate)
qdel(src)
else
..()
// Used to craft the makeshift helmet
/obj/item/clothing/head/helmet/bucket
name = "bucket"
desc = "It's a bucket with a large hole cut into it. You could wear it on your head and look really stupid."
flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
icon_state = "bucket"
armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/head/helmet/bucket/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/material))
var/obj/item/stack/material/S = O
if(S.use(2))
to_chat(user, "<span class='notice'>You apply some [S.material.use_name] to \the [src]. Hopefully it'll make the makeshift helmet stronger.</span>")
var/obj/item/clothing/head/helmet/material/makeshift/helmet = new(null, S.material.name)
user.put_in_hands(helmet)
user.drop_from_inventory(src)
qdel(src)
return
else
to_chat(user, "<span class='warning'>You don't have enough material to build a helmet!</span>")
else
..()
/obj/item/clothing/head/helmet/material
name = "helmet"
flags_inv = HIDEEARS|HIDEEYES|BLOCKHAIR
default_material = DEFAULT_WALL_MATERIAL
/obj/item/clothing/head/helmet/material/makeshift
name = "bucket"
desc = "A bucket with plating applied to the outside. Very crude, but could potentially be rather protective, if \
it was plated with something strong."
icon_state = "material_armor_makeshift"
/obj/item/clothing/head/helmet/material/makeshift/durasteel
default_material = "durasteel"

View File

@@ -29,7 +29,7 @@
w_class = ITEMSIZE_SMALL
sharp = 1
edge = 1
origin_tech = "materials=2;combat=1"
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1)
attack_verb = list("chopped", "torn", "cut")
applies_material_colour = 0
@@ -99,5 +99,5 @@
throw_range = 3
w_class = ITEMSIZE_LARGE
slot_flags = SLOT_BACK
origin_tech = "materials=2;combat=2"
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 2)
attack_verb = list("chopped", "sliced", "cut", "reaped")

View File

@@ -32,4 +32,9 @@
/obj/item/weapon/permit/gun/bar
name = "bar shotgun permit"
desc = "A card indicating that the owner is allowed to carry a shotgun in the bar."
desc = "A card indicating that the owner is allowed to carry a shotgun in the bar."
/obj/item/weapon/permit/drone
name = "drone identification card"
desc = "A card issued by the EIO, indicating that the owner is a Drone Intelligence. Drones are mandated to carry this card within SolGov space, by law."
icon_state = "drone"

View File

@@ -2,12 +2,12 @@
/obj/item/taperoll
name = "tape roll"
icon = 'icons/policetape.dmi'
icon_state = "rollstart"
icon_state = "tape"
w_class = ITEMSIZE_SMALL
var/turf/start
var/turf/end
var/tape_type = /obj/item/tape
var/icon_base
var/icon_base = "tape"
var/apply_tape = FALSE
@@ -33,7 +33,7 @@ var/list/tape_roll_applications = list()
var/lifted = 0
var/crumpled = 0
var/tape_dir = 0
var/icon_base
var/icon_base = "tape"
/obj/item/tape/update_icon()
//Possible directional bitflags: 0 (AIRLOCK), 1 (NORTH), 2 (SOUTH), 4 (EAST), 8 (WEST), 3 (VERTICAL), 12 (HORIZONTAL)
@@ -60,22 +60,20 @@ var/list/tape_roll_applications = list()
/obj/item/taperoll/police
name = "police tape"
desc = "A roll of police tape used to block off crime scenes from the public."
icon_state = "police"
tape_type = /obj/item/tape/police
icon_base = "police"
color = COLOR_RED_LIGHT
/obj/item/tape/police
name = "police tape"
desc = "A length of police tape. Do not cross."
req_access = list(access_security)
icon_base = "police"
color = COLOR_RED_LIGHT
/obj/item/taperoll/engineering
name = "engineering tape"
desc = "A roll of engineering tape used to block off working areas from the public."
icon_state = "engineering"
tape_type = /obj/item/tape/engineering
icon_base = "engineering"
color = COLOR_YELLOW
/obj/item/taperoll/engineering/applied
apply_tape = TRUE
@@ -84,28 +82,31 @@ var/list/tape_roll_applications = list()
name = "engineering tape"
desc = "A length of engineering tape. Better not cross it."
req_one_access = list(access_engine,access_atmospherics)
icon_base = "engineering"
color = COLOR_YELLOW
/obj/item/taperoll/atmos
name = "atmospherics tape"
desc = "A roll of atmospherics tape used to block off working areas from the public."
icon_state = "atmos"
tape_type = /obj/item/tape/atmos
icon_base = "atmos"
color = COLOR_DEEP_SKY_BLUE
/obj/item/tape/atmos
name = "atmospherics tape"
desc = "A length of atmospherics tape. Better not cross it."
req_one_access = list(access_engine,access_atmospherics)
icon_base = "atmos"
color = COLOR_DEEP_SKY_BLUE
/obj/item/taperoll/update_icon()
overlays.Cut()
var/image/overlay = image(icon = src.icon)
overlay.appearance_flags = RESET_COLOR
if(ismob(loc))
if(!start)
overlays += "start"
overlay.icon_state = "start"
else
overlays += "stop"
overlay.icon_state = "stop"
overlays += overlay
/obj/item/taperoll/dropped(mob/user)
update_icon()

View File

@@ -163,6 +163,15 @@
overlays = null
qdel(src)
/obj/item/weapon/ducttape/attackby(var/obj/item/I, var/mob/user)
if(!(istype(src, /obj/item/weapon/handcuffs/cable/tape) || istype(src, /obj/item/clothing/mask/muzzle/tape)))
return ..()
else
user.drop_from_inventory(I)
I.loc = src
qdel(I)
to_chat(user, "<span-class='notice'>You place \the [I] back into \the [src].</span>")
/obj/item/weapon/ducttape/afterattack(var/A, mob/user, flag, params)
if(!in_range(user, A) || istype(A, /obj/machinery/door) || !stuck)

View File

@@ -401,7 +401,7 @@
user.sdisabilities |= BLIND
else if (E.damage >= E.min_bruised_damage)
user << "<span class='danger'>You go blind!</span>"
user.eye_blind = 5
user.Blind(5)
user.eye_blurry = 5
user.disabilities |= NEARSIGHTED
spawn(100)

View File

@@ -8,7 +8,7 @@
desc = "A mechanically activated leg trap. Low-tech, but reliable. Looks like it could really hurt if you set it off."
throwforce = 0
w_class = ITEMSIZE_NORMAL
origin_tech = "materials=1"
origin_tech = list(TECH_MATERIAL = 1)
matter = list(DEFAULT_WALL_MATERIAL = 18750)
var/deployed = 0

View File

@@ -77,34 +77,44 @@
return
return
/obj/structure/morgue/attack_hand(mob/user as mob)
if (src.connected)
for(var/atom/movable/A as mob|obj in src.connected.loc)
if (!( A.anchored ))
A.forceMove(src)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
qdel(src.connected)
src.connected = null
close()
else
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
src.connected = new /obj/structure/m_tray( src.loc )
step(src.connected, src.dir)
src.connected.layer = OBJ_LAYER
var/turf/T = get_step(src, src.dir)
if (T.contents.Find(src.connected))
src.connected.connected = src
src.icon_state = "morgue0"
for(var/atom/movable/A as mob|obj in src)
A.forceMove(src.connected.loc)
src.connected.icon_state = "morguet"
src.connected.set_dir(src.dir)
else
qdel(src.connected)
src.connected = null
open()
src.add_fingerprint(user)
update()
return
/obj/structure/morgue/proc/close()
for(var/atom/movable/A as mob|obj in src.connected.loc)
if (!( A.anchored ))
A.forceMove(src)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
qdel(src.connected)
src.connected = null
/obj/structure/morgue/proc/open()
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
src.connected = new /obj/structure/m_tray( src.loc )
step(src.connected, src.dir)
src.connected.layer = OBJ_LAYER
var/turf/T = get_step(src, src.dir)
if (T.contents.Find(src.connected))
src.connected.connected = src
src.icon_state = "morgue0"
for(var/atom/movable/A as mob|obj in src)
A.forceMove(src.connected.loc)
src.connected.icon_state = "morguet"
src.connected.set_dir(src.dir)
else
qdel(src.connected)
src.connected = null
/obj/structure/morgue/attackby(P as obj, mob/user as mob)
if (istype(P, /obj/item/weapon/pen))
var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
@@ -123,21 +133,8 @@
/obj/structure/morgue/relaymove(mob/user as mob)
if (user.stat)
return
src.connected = new /obj/structure/m_tray( src.loc )
step(src.connected, EAST)
src.connected.layer = OBJ_LAYER
var/turf/T = get_step(src, EAST)
if (T.contents.Find(src.connected))
src.connected.connected = src
src.icon_state = "morgue0"
for(var/atom/movable/A as mob|obj in src)
A.forceMove(src.connected.loc)
src.connected.icon_state = "morguet"
else
qdel(src.connected)
src.connected = null
return
if (user in src.occupants)
open()
/*
* Morgue tray

View File

@@ -37,6 +37,7 @@ var/list/flooring_types
var/descriptor = "tiles"
var/flags
var/can_paint
var/list/footstep_sounds = list() // key=species name, value = list of soundss
/decl/flooring/grass
name = "grass"
@@ -90,6 +91,12 @@ var/list/flooring_types
build_type = /obj/item/stack/tile/carpet
damage_temperature = T0C+200
flags = TURF_HAS_EDGES | TURF_HAS_CORNERS | TURF_REMOVE_CROWBAR | TURF_CAN_BURN
footstep_sounds = list("human" = list(
'sound/effects/footstep/carpet1.ogg',
'sound/effects/footstep/carpet2.ogg',
'sound/effects/footstep/carpet3.ogg',
'sound/effects/footstep/carpet4.ogg',
'sound/effects/footstep/carpet5.ogg'))
/decl/flooring/carpet/blue
name = "carpet"
@@ -107,6 +114,12 @@ var/list/flooring_types
flags = TURF_REMOVE_CROWBAR | TURF_CAN_BREAK | TURF_CAN_BURN
build_type = /obj/item/stack/tile/floor
can_paint = 1
footstep_sounds = list("human" = list(
'sound/effects/footstep/floor1.ogg',
'sound/effects/footstep/floor2.ogg',
'sound/effects/footstep/floor3.ogg',
'sound/effects/footstep/floor4.ogg',
'sound/effects/footstep/floor5.ogg'))
/decl/flooring/linoleum
name = "linoleum"
@@ -193,6 +206,12 @@ var/list/flooring_types
descriptor = "planks"
build_type = /obj/item/stack/tile/wood
flags = TURF_CAN_BREAK | TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER
footstep_sounds = list("human" = list(
'sound/effects/footstep/wood1.ogg',
'sound/effects/footstep/wood2.ogg',
'sound/effects/footstep/wood3.ogg',
'sound/effects/footstep/wood4.ogg',
'sound/effects/footstep/wood5.ogg'))
/decl/flooring/reinforced
name = "reinforced floor"

View File

@@ -13,6 +13,12 @@
var/base_desc = "The naked hull."
var/base_icon = 'icons/turf/flooring/plating.dmi'
var/base_icon_state = "plating"
var/static/list/base_footstep_sounds = list("human" = list(
'sound/effects/footstep/plating1.ogg',
'sound/effects/footstep/plating2.ogg',
'sound/effects/footstep/plating3.ogg',
'sound/effects/footstep/plating4.ogg',
'sound/effects/footstep/plating5.ogg'))
// Flooring data.
var/flooring_override
@@ -33,10 +39,13 @@
floortype = initial_flooring
if(floortype)
set_flooring(get_flooring_data(floortype))
else
footstep_sounds = base_footstep_sounds
/turf/simulated/floor/proc/set_flooring(var/decl/flooring/newflooring)
make_plating(defer_icon_update = 1)
flooring = newflooring
footstep_sounds = newflooring.footstep_sounds
update_icon(1)
levelupdate()
@@ -53,6 +62,7 @@
desc = base_desc
icon = base_icon
icon_state = base_icon_state
footstep_sounds = base_footstep_sounds
if(flooring)
if(flooring.build_type && place_product)

View File

@@ -31,17 +31,19 @@ var/list/outdoor_turfs = list()
/turf/simulated/floor/Destroy()
if(outdoors)
outdoor_turfs.Remove(src)
planet_controller.unallocateTurf(src)
..()
/turf/simulated/floor/proc/update_icon_edge()
/turf/simulated/proc/update_icon_edge()
if(edge_blending_priority)
for(var/checkdir in cardinal)
var/turf/simulated/T = get_step(src, checkdir)
if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state)
var/cache_key = "[T.get_edge_icon_state()]-[checkdir]"
if(!turf_edge_cache[cache_key])
turf_edge_cache[cache_key] = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
I.plane = 0
turf_edge_cache[cache_key] = I
overlays += turf_edge_cache[cache_key]
/turf/simulated/proc/get_edge_icon_state()

View File

@@ -35,7 +35,16 @@
water_breath.temperature = above_air.temperature
return water_breath
else
return null // Lying down means they're submerged, which means no air.
var/gasid = "carbon_dioxide"
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.species && H.species.exhale_type)
gasid = H.species.exhale_type
var/datum/gas_mixture/water_breath = new()
var/datum/gas_mixture/above_air = return_air()
water_breath.adjust_gas(gasid, BREATH_MOLES) // They have no oxygen, but non-zero moles and temp
water_breath.temperature = above_air.temperature
return water_breath
return return_air() // Otherwise their head is above the water, so get the air from the atmosphere instead.
/turf/simulated/floor/water/Entered(atom/movable/AM, atom/oldloc)
@@ -94,7 +103,7 @@
return
/mob/living/water_act(amount)
adjust_fire_stacks(amount * 5)
adjust_fire_stacks(-amount * 5)
for(var/atom/movable/AM in contents)
AM.water_act(amount)

View File

@@ -26,6 +26,8 @@
var/movement_cost = 0 // How much the turf slows down movement, if any.
var/list/footstep_sounds = null
/turf/New()
..()
for(var/atom/movable/AM as mob|obj in src)
@@ -145,6 +147,9 @@ var/const/enterloopsanity = 100
else if(!is_space())
M.inertia_dir = 0
M.make_floating(0)
if(isliving(M))
var/mob/living/L = M
L.handle_footstep(src)
..()
var/objects = 0
if(A && (A.flags & PROXMOVE))
@@ -243,3 +248,11 @@ var/const/enterloopsanity = 100
/turf/proc/update_blood_overlays()
return
// Called when turf is hit by a thrown object
/turf/hitby(atom/movable/AM as mob|obj, var/speed)
if(src.density)
spawn(2)
step(AM, turn(AM.last_move, 180))
if(isliving(AM))
var/mob/living/M = AM
M.turf_collision(src, speed)

View File

@@ -27,6 +27,15 @@ var/list/planetary_walls = list()
planetary_walls.Remove(src)
..()
/turf/unsimulated/wall/planetary/proc/set_temperature(var/new_temperature)
if(new_temperature == temperature)
return
temperature = new_temperature
// Force ZAS to reconsider our connections because our temperature has changed
if(connections)
connections.erase_all()
air_master.mark_for_update(src)
// Normal station/earth air.
/turf/unsimulated/wall/planetary/normal
oxygen = MOLES_O2STANDARD
@@ -55,3 +64,4 @@ var/list/planetary_walls = list()
oxygen = MOLES_O2STANDARD
nitrogen = MOLES_N2STANDARD
temperature = 310.92 // About 37.7C / 100F

View File

@@ -127,7 +127,7 @@
suiciding = 1
viewers(src) << "<span class='danger'>[src] is powering down. It looks like \he's trying to commit suicide.</span>"
//put em at -175
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
updatehealth()
/mob/living/silicon/robot/verb/suicide()
@@ -147,7 +147,7 @@
suiciding = 1
viewers(src) << "<span class='danger'>[src] is powering down. It looks like \he's trying to commit suicide.</span>"
//put em at -175
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
adjustOxyLoss(max(getMaxHealth() * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
updatehealth()
/mob/living/silicon/pai/verb/suicide()