mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 18:53:06 +00:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into dice_thing
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = "" )
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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]"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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>"
|
||||
..()
|
||||
@@ -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>"
|
||||
..()
|
||||
@@ -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>"
|
||||
..()
|
||||
33
code/game/gamemodes/technomancer/spells/modifier/corona.dm
Normal file
33
code/game/gamemodes/technomancer/spells/modifier/corona.dm
Normal 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()
|
||||
28
code/game/gamemodes/technomancer/spells/modifier/haste.dm
Normal file
28
code/game/gamemodes/technomancer/spells/modifier/haste.dm
Normal 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
|
||||
31
code/game/gamemodes/technomancer/spells/modifier/modifier.dm
Normal file
31
code/game/gamemodes/technomancer/spells/modifier/modifier.dm
Normal 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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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>",\
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
@@ -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]"))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]°C ([M.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
263
code/game/objects/items/weapons/material/material_armor.dm
Normal file
263
code/game/objects/items/weapons/material/material_armor.dm
Normal 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"
|
||||
@@ -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")
|
||||
|
||||
@@ -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"
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user