mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-26 13:37:58 +01:00
Job Perks - True Professionals (#29478)
* ddsadsa ddsadsa * moderate again * revert * medical first steps * more work * lots more work done * more progress * finished up * attack chain linter * attack chain update * attack chain work * fixes + chemist update * gives comments
This commit is contained in:
@@ -166,7 +166,9 @@
|
||||
return ", missing tool."
|
||||
if(!check_pathtools(user, recipe, contents))
|
||||
return ", missing tool."
|
||||
|
||||
var/craft_time = recipe.time
|
||||
if(HAS_TRAIT(user.mind, TRAIT_CRAFTY))
|
||||
craft_time /= 3
|
||||
if(!do_after(user, recipe.time, target = user))
|
||||
return "."
|
||||
contents = get_surroundings(user)
|
||||
|
||||
@@ -936,6 +936,10 @@
|
||||
update_state()
|
||||
plant_hud_set_status()
|
||||
plant_hud_set_health()
|
||||
else if(user.mind && HAS_TRAIT(user.mind, TRAIT_GREEN_THUMB) && weedlevel > 0)
|
||||
user.visible_message("[user] uproots the weeds.", "<span class='notice'>You pluck the weeds from [src] with your hands.</span>")
|
||||
adjustWeeds(-10)
|
||||
update_state()
|
||||
else
|
||||
examine(user)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
drop_sound = 'sound/items/handling/book_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/book_pickup.ogg'
|
||||
new_attack_chain = TRUE
|
||||
|
||||
///Title & Real name of the book
|
||||
var/title
|
||||
@@ -40,6 +41,8 @@
|
||||
var/pages = list()
|
||||
///What page is the book currently opened to? Page 0 - Intro Page | Page 1-5 - Content Pages
|
||||
var/current_page = 0
|
||||
///Is this item imaginary and not able to interact with anything else?
|
||||
var/imaginary = FALSE
|
||||
|
||||
///Book UI Popup Height
|
||||
var/book_height = 400
|
||||
@@ -74,37 +77,48 @@
|
||||
icon_state = "book[rand(1,8)]"
|
||||
|
||||
|
||||
/obj/item/book/attack__legacy__attackchain(mob/M, mob/living/user)
|
||||
/obj/item/book/attack(mob/M, mob/living/user)
|
||||
if(imaginary)
|
||||
return FINISH_ATTACK
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
force = 0
|
||||
attack_verb = list("educated")
|
||||
else
|
||||
force = initial(force)
|
||||
attack_verb = list("bashed", "whacked")
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/book/attack_self__legacy__attackchain(mob/user)
|
||||
/obj/item/book/activate_self(mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(imaginary)
|
||||
read_book(user)
|
||||
return FINISH_ATTACK
|
||||
if(carved)
|
||||
//Attempt to remove inserted object, if none found, remind user that someone vandalized their book (Bastards)!
|
||||
if(!remove_stored_item(user, TRUE))
|
||||
to_chat(user, "<span class='notice'>The pages of [title] have been cut out!</span>")
|
||||
return
|
||||
return FINISH_ATTACK
|
||||
user.visible_message("<span class='notice'>[user] opens a book titled \"[title]\" and begins reading intently.</span>")
|
||||
read_book(user)
|
||||
return ..()
|
||||
|
||||
/obj/item/book/attackby__legacy__attackchain(obj/item/I, mob/user, params)
|
||||
if(is_pen(I))
|
||||
/obj/item/book/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(imaginary)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(is_pen(used))
|
||||
edit_book(user)
|
||||
else if(istype(I, /obj/item/barcodescanner))
|
||||
var/obj/item/barcodescanner/scanner = I
|
||||
else if(istype(used, /obj/item/barcodescanner))
|
||||
var/obj/item/barcodescanner/scanner = used
|
||||
scanner.scanBook(src, user) //abstraction and proper scoping ftw | did you know barcode scanner code used to be here?
|
||||
return
|
||||
else if(I.sharp && !carved) //don't use sharp objects on your books if you don't want to carve out all of its pages kids!
|
||||
carve_book(user, I)
|
||||
else if(store_item(I, user))
|
||||
return
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else if(used.sharp && !carved) //don't use sharp objects on your books if you don't want to carve out all of its pages kids!
|
||||
carve_book(user, used)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else if(store_item(used, user))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/book/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
@@ -109,20 +109,22 @@
|
||||
for(var/mutation_type in active_mutations)
|
||||
var/datum/mutation/mutation = GLOB.dna_mutations[mutation_type]
|
||||
mutation.on_life(src)
|
||||
|
||||
if(!ignore_gene_stability && gene_stability < GENETIC_DAMAGE_STAGE_1)
|
||||
var/gene_bonus
|
||||
if(mind && HAS_TRAIT(mind, TRAIT_GENETIC_BUDGET))
|
||||
gene_bonus = 5
|
||||
if(!ignore_gene_stability && gene_stability < GENETIC_DAMAGE_STAGE_1 - gene_bonus)
|
||||
var/instability = DEFAULT_GENE_STABILITY - gene_stability
|
||||
if(prob(instability * 0.1))
|
||||
adjustFireLoss(min(10, instability * 0.67))
|
||||
to_chat(src, "<span class='danger'>You feel like your skin is burning and bubbling off!</span>")
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_2)
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_2 - gene_bonus)
|
||||
if(prob(instability * 0.83))
|
||||
adjustCloneLoss(min(8, instability * 0.05))
|
||||
to_chat(src, "<span class='danger'>You feel as if your body is warping.</span>")
|
||||
if(prob(instability * 0.1))
|
||||
adjustToxLoss(min(10, instability * 0.67))
|
||||
to_chat(src, "<span class='danger'>You feel weak and nauseous.</span>")
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_3 && prob(1))
|
||||
if(gene_stability < (GENETIC_DAMAGE_STAGE_3 - gene_bonus) && prob(1))
|
||||
to_chat(src, "<span class='biggerdanger'>You feel incredibly sick... Something isn't right!</span>")
|
||||
spawn(300)
|
||||
if(gene_stability < GENETIC_DAMAGE_STAGE_3)
|
||||
@@ -895,8 +897,9 @@
|
||||
if(HAS_TRAIT(H, TRAIT_NOBREATH))
|
||||
continue //no puking if you can't smell!
|
||||
// Humans can lack a mind datum, y'know
|
||||
if(H.mind && (H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Coroner"))
|
||||
continue //too cool for puke
|
||||
if(H.mind && HAS_TRAIT(H.mind, TRAIT_CORPSE_RESIST))
|
||||
to_chat(H, "<span class='warning'>You smell something rotting nearby.</span>")
|
||||
continue
|
||||
to_chat(H, "<span class='warning'>You smell something foul...</span>")
|
||||
H.fakevomit()
|
||||
|
||||
|
||||
@@ -2174,3 +2174,45 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/AltClick(mob/user, modifiers)
|
||||
. = ..()
|
||||
if(user.stat || user.restrained() || (!in_range(src, user)))
|
||||
return
|
||||
|
||||
if(user.mind && !HAS_TRAIT(user.mind, TRAIT_MED_EXAMINE))
|
||||
return
|
||||
|
||||
user.visible_message("[user] begins to thoroughly examine [src].")
|
||||
if(do_after_once(user, 12 SECONDS, target = src, allow_moving = FALSE, attempt_cancel_message = "You couldn't get a good look at [src]!"))
|
||||
var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")
|
||||
var/list/analysis = list()
|
||||
for(var/obj/item/organ/external/E in src.bodyparts)
|
||||
missing -= E.limb_name
|
||||
if(E.status & ORGAN_DEAD)
|
||||
analysis += "<span class='info'>You conclude [src]'s [E.name] is dead.</span>"
|
||||
if(E.status & ORGAN_INT_BLEEDING)
|
||||
analysis += "<span class='info'>You conclude [src]'s [E.name] has internal bleeding.</span>"
|
||||
if(E.status & ORGAN_BURNT)
|
||||
analysis += "<span class='info'>You conclude [src]'s [E.name] has been critically burned.</span>"
|
||||
if(E.status & ORGAN_BROKEN)
|
||||
if(!E.broken_description)
|
||||
analysis += "<span class='info'>You conclude [src]'s [E.name] is broken.</span>"
|
||||
else
|
||||
analysis += "<span class='info'>You conclude [src]'s [E.name] has a [E.broken_description].</span>"
|
||||
to_chat(user, chat_box_healthscan(analysis.Join("<br>")))
|
||||
|
||||
/mob/living/carbon/human/pointed(atom/A as mob|obj|turf in view())
|
||||
set name = "Point To"
|
||||
set category = null
|
||||
if(next_move >= world.time)
|
||||
return
|
||||
|
||||
if(istype(A, /obj/effect/temp_visual/point) || istype(A, /atom/movable/emissive_blocker))
|
||||
return FALSE
|
||||
if(mind && HAS_TRAIT(mind, TRAIT_COFFEE_SNOB) && reagents.has_reagent("coffee"))
|
||||
changeNext_move(CLICK_CD_POINT / 3)
|
||||
else
|
||||
changeNext_move(CLICK_CD_POINT)
|
||||
|
||||
DEFAULT_QUEUE_OR_CALL_VERB(VERB_CALLBACK(src, PROC_REF(run_pointed), A))
|
||||
|
||||
@@ -941,8 +941,12 @@
|
||||
if(user.a_intent == INTENT_HARM && stat == DEAD && butcher_results && I.sharp) //can we butcher it?
|
||||
to_chat(user, "<span class='notice'>You begin to butcher [src]...</span>")
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 50, TRUE, -1)
|
||||
if(do_mob(user, src, 8 SECONDS) && Adjacent(I))
|
||||
harvest(user)
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_BUTCHER))
|
||||
if(do_mob(user, src, 3 SECONDS) && Adjacent(I))
|
||||
harvest(user)
|
||||
else
|
||||
if(do_mob(user, src, 8 SECONDS) && Adjacent(I))
|
||||
harvest(user)
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/harvest(mob/living/user)
|
||||
|
||||
@@ -104,6 +104,9 @@
|
||||
/// Famous last words -- if succumbing, what the user's last words were
|
||||
var/last_words
|
||||
|
||||
/// Does this mob talk with a BIG VOICE. 0 off, 1 single use, 2 multi-use
|
||||
var/big_voice = 0
|
||||
|
||||
///This variable is the chance for a mob to automatically dodge a bullet. Useful for admins, and applied to some mobs by default, such as the malfunctioning drone mobs.
|
||||
var/advanced_bullet_dodge_chance = 0
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
return returns
|
||||
|
||||
|
||||
/mob/living/say(message, verb = null, sanitize = TRUE, ignore_speech_problems = FALSE, ignore_atmospherics = FALSE, ignore_languages = FALSE, automatic = FALSE)
|
||||
/mob/living/say(message, verb = null, sanitize = TRUE, ignore_speech_problems = FALSE, ignore_atmospherics = FALSE, ignore_languages = FALSE, automatic = FALSE, bigvoice = FALSE)
|
||||
if(client)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
@@ -139,6 +139,9 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
|
||||
message = trim_left(message)
|
||||
|
||||
if(big_voice)
|
||||
message = "<span class='reallybig'>[message]</span>"
|
||||
|
||||
//parse the language code and consume it
|
||||
var/list/message_pieces = list()
|
||||
if(ignore_languages)
|
||||
|
||||
@@ -130,6 +130,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
var/base_icon = ""
|
||||
/// If set to TRUE, the robot's 3 module slots will progressively become unusable as they take damage.
|
||||
var/modules_break = TRUE
|
||||
/// Is the robot already being charged by a roboticist?
|
||||
var/being_charged
|
||||
|
||||
/// Maximum brightness of a robot's headlamp. Set as a var for easy adjusting.
|
||||
var/lamp_max = 10
|
||||
@@ -923,6 +925,33 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
|
||||
/mob/living/silicon/robot/item_interaction(mob/living/user, obj/item/W, list/modifiers)
|
||||
// Check if the user is trying to insert another component like a radio, actuator, armor etc.
|
||||
if(istype(W, /obj/item/stock_parts/cell) && user.mind && HAS_TRAIT(user.mind, TRAIT_CYBORG_SPECIALIST) && !opened && user.a_intent != INTENT_HARM)
|
||||
var/obj/item/stock_parts/cell/donor = W
|
||||
if(being_charged)
|
||||
to_chat(user, "<span class='warning'>You are already charging [src]!")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(donor.charge == 0)
|
||||
to_chat(user, "<span class='warning'>[donor] has no charge to donate!")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
being_charged = TRUE
|
||||
while(do_after(user, 0.5 SECONDS, target = src))
|
||||
var/cell_difference = cell.maxcharge - cell.charge
|
||||
if(donor.charge >= 500 && cell_difference >= 500)
|
||||
cell.charge += 500
|
||||
donor.charge -= 500
|
||||
else if(donor.charge <= cell_difference)
|
||||
cell.charge += donor.charge
|
||||
donor.charge = 0
|
||||
else if(donor.charge > cell_difference)
|
||||
cell.charge = cell.maxcharge
|
||||
donor.charge -= cell_difference
|
||||
if(donor.charge == 0 || cell.charge >= cell.maxcharge)
|
||||
donor.update_icon(UPDATE_OVERLAYS)
|
||||
break
|
||||
cell.update_icon(UPDATE_OVERLAYS)
|
||||
being_charged = FALSE
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(istype(W, /obj/item/robot_parts/robot_component) && opened)
|
||||
for(var/V in components)
|
||||
var/datum/robot_component/C = components[V]
|
||||
@@ -1129,10 +1158,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
C.uninstall()
|
||||
thing.forceMove(loc)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/silicon/robot/attacked_by(obj/item/I, mob/living/user, def_zone)
|
||||
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
|
||||
spark_system.start()
|
||||
|
||||
@@ -331,8 +331,33 @@
|
||||
// Adding APC electronics.
|
||||
if(istype(used, /obj/item/apc_electronics) && opened)
|
||||
if(has_electronics())
|
||||
to_chat(user, "<span class='warning'>[src] already contains APC electronics!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_ELECTRICAL_SPECIALIST))
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, "<span class='warning'>[src] is damaged! You must repair the frame before you can install [used]!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(malfhack)
|
||||
malfai = null
|
||||
malfhack = FALSE
|
||||
user.visible_message(\
|
||||
"<span class='notice'>[name] has discarded the strangely programmed APC electronics from [src]!</span>",
|
||||
"<span class='notice'>You discarded the strangely programmed board.</span>",
|
||||
"<span class='warning'>You hear metallic levering.</span>"
|
||||
)
|
||||
else
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] exchanges out broken the APC electronics inside [src]!</span>",
|
||||
"<span class='notice'>You carefully remove the charred electronics, replacing it with a functional board.</span>",
|
||||
"<span class='warning'>You hear metallic levering and a crack, followed by a gentle click.</span>")
|
||||
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
qdel(used)
|
||||
electronics_state = APC_ELECTRONICS_INSTALLED
|
||||
locked = FALSE
|
||||
stat &= ~MAINT
|
||||
update_icon()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] already contains APC electronics!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, "<span class='warning'>[src] is damaged! You must repair the frame before you can install [used]!</span>")
|
||||
@@ -368,7 +393,7 @@
|
||||
update_icon()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(has_electronics())
|
||||
if(has_electronics() && user.mind && !HAS_TRAIT(user.mind, TRAIT_ELECTRICAL_SPECIALIST))
|
||||
to_chat(user, "<span class='warning'>You cannot repair [src] until you remove the electronics!</span>")
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
|
||||
@@ -231,8 +231,13 @@
|
||||
if(amount < 3)
|
||||
to_chat(user, "<span class='warning'>You need more paper.</span>")
|
||||
return
|
||||
if(!do_after_once(user, 1.5 SECONDS, target = C) || C.opened || !use(3)) // Checking these again since it's after a delay
|
||||
return
|
||||
// Checking these again since it's after a delay
|
||||
if(user.mind && HAS_TRAIT(user.mind, TRAIT_PACK_RAT))
|
||||
if(!do_after_once(user, 0.75 SECONDS, target = C) || C.opened || !use(3))
|
||||
return
|
||||
else
|
||||
if(!do_after_once(user, 2 SECONDS, target = C) || C.opened || !use(3))
|
||||
return
|
||||
var/obj/structure/big_delivery/P = new(get_turf(C))
|
||||
P.wrapped = C
|
||||
C.loc = P
|
||||
|
||||
@@ -41,3 +41,8 @@
|
||||
name = "[quality.name] " + name
|
||||
return
|
||||
name = "[quality.name] [material.name] [initial(name)]"
|
||||
|
||||
/obj/item/smithed_item/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user.mind, TRAIT_SMITH))
|
||||
. += "<span class='notice'>You can use <b>ALT + Click</b> while in-hand to determine specific statistics of this item.</span>"
|
||||
|
||||
@@ -168,3 +168,20 @@
|
||||
siemens_coeff = 1
|
||||
quality = /datum/smith_quality/masterwork
|
||||
material = /datum/smith_material/platinum
|
||||
|
||||
/obj/item/smithed_item/insert/AltClick(mob/user, modifiers)
|
||||
if(!HAS_TRAIT(user.mind, TRAIT_SMITH))
|
||||
return
|
||||
if(do_after_once(user, 3 SECONDS, target = src, allow_moving = TRUE, must_be_held = TRUE))
|
||||
var/compiled_message = "<span class='notice'>\
|
||||
You determine the following properties on [src]: <br>\
|
||||
Brute Armor mod: [brute_armor] <br>\
|
||||
Burn Armor mod: [burn_armor] <br>\
|
||||
Laser Armor mod: [laser_armor] <br>\
|
||||
Explosive Resistance mod: [explosive_armor] <br>\
|
||||
Movement Speed mod: [movement_speed_mod] <br>\
|
||||
Heat Insulation mod: [heat_insulation] <br>\
|
||||
Siemens Coefficient mod: [siemens_coeff] <br>\
|
||||
Radiation Resistance mod: [radiation_armor] <br>\
|
||||
</span>"
|
||||
to_chat(user, compiled_message)
|
||||
|
||||
@@ -148,3 +148,21 @@
|
||||
durability = 3000
|
||||
quality = /datum/smith_quality/masterwork
|
||||
material = /datum/smith_material/platinum
|
||||
|
||||
/obj/item/smithed_item/lens/AltClick(mob/user, modifiers)
|
||||
if(!HAS_TRAIT(user.mind, TRAIT_SMITH))
|
||||
return
|
||||
if(do_after_once(user, 3 SECONDS, target = src, allow_moving = TRUE, must_be_held = TRUE))
|
||||
var/compiled_message = "<span class='notice'>\
|
||||
You determine the following properties on [src]: <br>\
|
||||
Base Laser Speed mod: [base_laser_speed_mult] <br>\
|
||||
Base Power Draw mod: [base_power_mult] <br>\
|
||||
Base Damage mod: [base_damage_mult] <br>\
|
||||
Base Fire Rate mod: [base_fire_rate_mult] <br>\
|
||||
Laser Speed Multiplier: [laser_speed_mult] <br>\
|
||||
Power Draw Multiplier: [power_mult] <br>\
|
||||
Damage multiplier: [damage_mult] <br>\
|
||||
Fire Rate Multiplier: [fire_rate_mult] <br>\
|
||||
Durability: [durability] <br>\
|
||||
</span>"
|
||||
to_chat(user, compiled_message)
|
||||
|
||||
@@ -150,3 +150,21 @@
|
||||
durability = 300
|
||||
quality = /datum/smith_quality/masterwork
|
||||
material = /datum/smith_material/platinum
|
||||
|
||||
/obj/item/smithed_item/tool_bit/AltClick(mob/user, modifiers)
|
||||
if(!HAS_TRAIT(user.mind, TRAIT_SMITH))
|
||||
return
|
||||
if(do_after_once(user, 3 SECONDS, target = src, allow_moving = TRUE, must_be_held = TRUE))
|
||||
var/compiled_message = "<span class='notice'>\
|
||||
You determine the following properties on [src]: <br>\
|
||||
Base Speed mod: [base_speed_mod] <br>\
|
||||
Base Efficiency mod: [base_efficiency_mod] <br>\
|
||||
Base Productivity mod: [base_productivity_mod] <br>\
|
||||
Speed Multiplier: [speed_mod] <br>\
|
||||
Efficiency Multiplier: [efficiency_mod] <br>\
|
||||
Productivity Multiplier: [productivity_mod] <br>\
|
||||
Failure Rate: [failure_rate] <br>\
|
||||
Size Mod: [size_mod] <br>\
|
||||
Durability: [durability] <br>\
|
||||
</span>"
|
||||
to_chat(user, compiled_message)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "This is what the paramedic uses to run over people they need to take to medbay."
|
||||
icon_state = "docwagon2"
|
||||
key_type = /obj/item/key/ambulance
|
||||
var/siren_on = FALSE
|
||||
var/obj/structure/bed/amb_trolley/bed = null
|
||||
var/datum/action/ambulance_alarm/AA
|
||||
var/datum/looping_sound/ambulance_alarm/soundloop
|
||||
@@ -41,9 +42,11 @@
|
||||
cooldown = world.time
|
||||
|
||||
if(A.soundloop.muted)
|
||||
A.siren_on = TRUE
|
||||
A.soundloop.start()
|
||||
A.set_light(4,3,"#F70027")
|
||||
else
|
||||
A.siren_on = FALSE
|
||||
A.soundloop.stop()
|
||||
A.set_light(0)
|
||||
|
||||
@@ -104,6 +107,51 @@
|
||||
var/mob/living/buckled_mob = m
|
||||
buckled_mob.setDir(Dir)
|
||||
|
||||
/obj/vehicle/ambulance/Bump(atom/movable/M)
|
||||
if(has_buckled_mobs())
|
||||
for(var/mob/living/L in buckled_mobs)
|
||||
if(L.mind && HAS_TRAIT(L.mind, TRAIT_SPEED_DEMON))
|
||||
if(isobj(M))
|
||||
var/obj/O = M
|
||||
if(!O.anchored)
|
||||
step(M, dir)
|
||||
else if(ismob(M) && siren_on)
|
||||
run_over(M)
|
||||
break
|
||||
|
||||
/obj/vehicle/ambulance/proc/run_over(mob/living/M)
|
||||
var/directional_blocked = FALSE
|
||||
var/turf/T = get_step(M.loc, turn(dir, 90))
|
||||
if(check_density(T))
|
||||
T = get_step(M.loc, turn(dir, -90))
|
||||
if(check_density(T))
|
||||
directional_blocked = TRUE
|
||||
else
|
||||
step(M, turn(dir, -90))
|
||||
else
|
||||
step(M, turn(dir, 90))
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE)
|
||||
if(directional_blocked || (emagged == TRUE && installed_vtec == TRUE)) // GET OUT OF THE WAY, ASSHOLE!
|
||||
M.KnockDown(2 SECONDS)
|
||||
|
||||
/obj/vehicle/ambulance/proc/check_density(turf/T)
|
||||
if(T.density)
|
||||
return TRUE
|
||||
for(var/atom/movable/thing in T.contents)
|
||||
if(thing.density)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/vehicle/ambulance/emag_act(mob/user)
|
||||
emagged = TRUE
|
||||
visible_message("[src] sputters and fizzles as the safeties are shorted out!")
|
||||
do_sparks(3, 0, src)
|
||||
|
||||
/obj/vehicle/ambulance/examine(mob/user)
|
||||
. = ..()
|
||||
if(emagged && in_range(src, user))
|
||||
. += "<span class='danger'>The safeties seem to have been shorted out!</span>"
|
||||
|
||||
/obj/structure/bed/amb_trolley
|
||||
name = "ambulance train trolley"
|
||||
icon = 'icons/vehicles/CargoTrain.dmi'
|
||||
|
||||
Reference in New Issue
Block a user