mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-23 13:57:03 +01:00
1c8c0c2221
Fixes several runtimes from the past few weeks, some additional material repath regressions, and the fact that if I shoot you with a stream of ionized deuterium particles, it doesn't riddle you with cancer. changes: - bugfix: "Fixes emergency shields runtiming when hit by thrown objects." - bugfix: "Fixes several stale global list runtimes." - bugfix: "Fixes several health percentage checks that could use unset initial health values." - bugfix: "Fixes additional materials regressions in INDRA code." - bugfix: "Fixes invalid fuel injector depletion math." - bugfix: "Makes accelerated particles apply radiation damage to living mobs they pass through."
274 lines
7.9 KiB
Plaintext
274 lines
7.9 KiB
Plaintext
/obj/structure
|
|
icon = 'icons/obj/structures.dmi'
|
|
w_class = WEIGHT_CLASS_GIGANTIC
|
|
layer = STRUCTURE_LAYER
|
|
blocks_emissive = EMISSIVE_BLOCK_GENERIC
|
|
pass_flags_self = PASSSTRUCTURE
|
|
should_use_health = TRUE
|
|
|
|
/// Overrides for material shit. Set them manually if you don't want colors etc. See wood chairs/office chairs.
|
|
var/material_alteration = MATERIAL_ALTERATION_ALL
|
|
var/climbable
|
|
var/parts
|
|
var/list/climbers
|
|
/// Footstep sounds when stepped on
|
|
var/list/footstep_sound
|
|
|
|
var/singleton/material/material
|
|
/// Used by some structures to determine into how many pieces they should disassemble into or be made with
|
|
var/build_amt = 2
|
|
/// Amount that pulling mobs have their movement delayed by
|
|
var/slowdown = 0
|
|
|
|
/obj/structure/Initialize(mapload)
|
|
. = ..()
|
|
if(!isnull(material) && !istype(material))
|
|
material = SSmaterials.get_material_by_id(material)
|
|
if (!mapload)
|
|
updateVisibility(src) // No point checking this before visualnet initializes.
|
|
if(climbable)
|
|
verbs += /obj/structure/proc/climb_on
|
|
if (smoothing_flags)
|
|
QUEUE_SMOOTH(src)
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
|
|
/obj/structure/Destroy()
|
|
if(parts)
|
|
new parts(loc)
|
|
if (smoothing_flags)
|
|
SSicon_smooth.remove_from_queues(src)
|
|
QUEUE_SMOOTH_NEIGHBORS(src)
|
|
|
|
climbers = null
|
|
material = null
|
|
return ..()
|
|
|
|
/obj/structure/examine_descriptor(mob/user)
|
|
return "structure"
|
|
|
|
/obj/structure/examine_tags(atom/source, mob/user, list/examine_list)
|
|
. = ..()
|
|
if(climbable)
|
|
.["climbable"] = "It can be climbed on, either by dragging your mob onto it or middle-clicking it."
|
|
|
|
/obj/structure/attackby(obj/item/attacking_item, mob/user, params)
|
|
. = ..()
|
|
if(user?.a_intent == I_HURT && maxhealth)
|
|
user.do_attack_animation(src)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
add_damage(attacking_item.force, attacking_item.damage_flags(), attacking_item.damtype, attacking_item.armor_penetration, attacking_item)
|
|
if(hitsound)
|
|
playsound(user, hitsound, attacking_item.get_clamped_volume())
|
|
|
|
/obj/structure/attack_hand(mob/living/user)
|
|
if((user.mutations & HULK) && !(user.isSynthetic()) && !(isvaurca(user)))
|
|
user.say(pick("RAAAAAAAARGH!!!", "HNNNNNNNNNGGGGGGH!!!", "GWAAAAAAAARRRHHH!!!", "NNNNNNNNGGGGGGGGHH!!!", "AAAAAAARRRGH!!!" ))
|
|
attack_generic(user, 25, "smashes")
|
|
else if(istype(user,/mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = user
|
|
if(H.species.can_shred(user))
|
|
attack_generic(user, 25, "slices")
|
|
|
|
if(LAZYLEN(climbers) && !(user in climbers))
|
|
user.visible_message(SPAN_WARNING("[user] shakes \the [src]."), \
|
|
SPAN_NOTICE("You shake \the [src]."))
|
|
structure_shaken()
|
|
|
|
return ..()
|
|
|
|
/obj/structure/ex_act(severity)
|
|
// If this object doesn't use health for whatever reason, default to ancient ex_act() code.
|
|
if(!should_use_health)
|
|
switch(severity)
|
|
if(1.0)
|
|
qdel(src)
|
|
return
|
|
if(2.0)
|
|
if(prob(50))
|
|
qdel(src)
|
|
return
|
|
if(3.0)
|
|
return
|
|
// If we do use health, normal atom health behavior.
|
|
else
|
|
switch(severity)
|
|
if(1)
|
|
add_damage(maxhealth)
|
|
if(2)
|
|
add_damage(maxhealth * 0.5)
|
|
if(3)
|
|
add_damage(maxhealth * 0.25)
|
|
|
|
/obj/structure/proc/dismantle()
|
|
var/singleton/material/dismantle_material
|
|
if(!get_material())
|
|
dismantle_material = GET_SINGLETON(MATERIAL_STEEL)
|
|
else
|
|
dismantle_material = get_material()
|
|
if(should_use_health && health <= 0)
|
|
build_amt /= rand(2, 4) //if the structure is destroyed by damage, it will yield less materials.
|
|
build_amt = max(1, min(build_amt, 5)) //Bound between 5 and 1, as shards don't stack into sheets.
|
|
for(var/i = 1 to build_amt)
|
|
dismantle_material.place_shard(loc)
|
|
else
|
|
for(var/i = 1 to build_amt)
|
|
dismantle_material.place_sheet(loc)
|
|
qdel(src)
|
|
|
|
/obj/structure/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
|
|
. = ..()
|
|
if(. != BULLET_ACT_HIT)
|
|
return .
|
|
|
|
if(hitting_projectile.get_structure_damage() > 5)
|
|
bullet_ping(hitting_projectile)
|
|
|
|
add_damage(hitting_projectile.damage, hitting_projectile.damage_flags(), hitting_projectile.damage_type, hitting_projectile.armor_penetration, hitting_projectile)
|
|
|
|
/obj/structure/proc/climb_on()
|
|
|
|
set name = "Climb Structure"
|
|
set desc = "Climbs onto a structure. Shortcut middle-mouse click."
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
|
|
if(can_climb(usr))
|
|
do_climb(usr)
|
|
|
|
/obj/structure/handle_middle_mouse_click(mob/user)
|
|
if(can_climb(user))
|
|
do_climb(usr)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/structure/mouse_drop_receive(atom/dropped, mob/user, params)
|
|
var/mob/living/H = user
|
|
if(istype(H) && can_climb(H) && dropped == user)
|
|
do_climb(dropped)
|
|
return ..()
|
|
|
|
/obj/structure/proc/can_climb(var/mob/living/user, post_climb_check=0)
|
|
if (!climbable)
|
|
return FALSE
|
|
|
|
if (!can_touch(user) || (!post_climb_check && (user in climbers)))
|
|
return FALSE
|
|
|
|
if (!user.Adjacent(src))
|
|
return FALSE
|
|
|
|
var/obj/occupied = turf_is_crowded()
|
|
if(occupied)
|
|
to_chat(user, SPAN_WARNING("There's \a [occupied] in the way of climbing this."))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/structure/proc/turf_is_crowded(var/exclude_self = FALSE)
|
|
var/turf/T = get_turf(src)
|
|
if(!T || !istype(T))
|
|
return 0
|
|
for(var/obj/O in T.contents)
|
|
if(istype(O,/obj/structure))
|
|
var/obj/structure/S = O
|
|
if(S.climbable)
|
|
continue
|
|
if(O && O.density && !(O.atom_flags & ATOM_FLAG_CHECKS_BORDER)) //ATOM_FLAG_CHECKS_BORDER structures are handled by the Adjacent() check.
|
|
if(exclude_self && O == src)
|
|
continue
|
|
return O
|
|
return 0
|
|
|
|
/obj/structure/proc/do_climb(var/mob/living/user)
|
|
if (!can_climb(user))
|
|
return FALSE
|
|
|
|
user.visible_message(SPAN_WARNING("[user] starts [atom_flags & ATOM_FLAG_CHECKS_BORDER ? "leaping over" : "climbing onto"] \the [src]!"))
|
|
LAZYADD(climbers, user)
|
|
|
|
if(!do_after(user, 5 SECONDS, src, DO_DEFAULT | DO_USER_UNIQUE_ACT))
|
|
LAZYREMOVE(climbers, user)
|
|
return
|
|
|
|
if (!can_climb(user, post_climb_check=1))
|
|
LAZYREMOVE(climbers, user)
|
|
return
|
|
|
|
var/turf/TT = get_turf(src)
|
|
if(atom_flags & ATOM_FLAG_CHECKS_BORDER)
|
|
TT = get_step(get_turf(src), dir)
|
|
if(user.loc == TT)
|
|
TT = get_turf(src)
|
|
|
|
user.visible_message(SPAN_WARNING("[user] [atom_flags & ATOM_FLAG_CHECKS_BORDER ? "leaps over" : "climbs onto"] \the [src]!"))
|
|
user.forceMove(TT)
|
|
LAZYREMOVE(climbers, user)
|
|
|
|
/obj/structure/proc/structure_shaken()
|
|
for(var/mob/living/M in climbers)
|
|
M.Weaken(1)
|
|
to_chat(M, SPAN_DANGER("You topple as you are shaken off \the [src]!"))
|
|
LAZYREMOVE(climbers, M)
|
|
|
|
for(var/mob/living/M in get_turf(src))
|
|
if(M.lying) return //No spamming this on people.
|
|
|
|
M.Weaken(3)
|
|
to_chat(M, SPAN_DANGER("You topple as \the [src] moves under you!"))
|
|
|
|
if(prob(25))
|
|
|
|
var/damage = rand(15,30)
|
|
var/mob/living/carbon/human/H = M
|
|
if(!istype(H))
|
|
to_chat(H, SPAN_DANGER("You land heavily!"))
|
|
M.adjustBruteLoss(damage)
|
|
return
|
|
|
|
var/obj/item/organ/external/affecting
|
|
|
|
switch(pick(list("ankle","wrist",BP_HEAD,"knee","elbow")))
|
|
if("ankle")
|
|
affecting = H.get_organ(pick(BP_L_FOOT, BP_R_FOOT))
|
|
if("knee")
|
|
affecting = H.get_organ(pick(BP_L_LEG, BP_R_LEG))
|
|
if("wrist")
|
|
affecting = H.get_organ(pick(BP_L_HAND, BP_R_HAND))
|
|
if("elbow")
|
|
affecting = H.get_organ(pick(BP_L_ARM, BP_R_ARM))
|
|
if(BP_HEAD)
|
|
affecting = H.get_organ(BP_HEAD)
|
|
|
|
if(affecting)
|
|
to_chat(M, SPAN_DANGER("You land heavily on your [affecting.name]!"))
|
|
affecting.take_damage(damage, 0)
|
|
if(affecting.parent)
|
|
affecting.parent.add_autopsy_data("Misadventure", damage)
|
|
else
|
|
to_chat(H, SPAN_DANGER("You land heavily!"))
|
|
H.adjustBruteLoss(damage)
|
|
|
|
H.UpdateDamageIcon()
|
|
H.updatehealth()
|
|
return
|
|
|
|
/obj/structure/proc/can_touch(var/mob/user)
|
|
if (!user)
|
|
return 0
|
|
if(!Adjacent(user))
|
|
return 0
|
|
if (user.restrained() || user.buckled_to)
|
|
to_chat(user, SPAN_NOTICE("You need your hands and legs free for this."))
|
|
return 0
|
|
if (user.stat || user.paralysis || user.sleeping || user.lying || user.weakened)
|
|
return 0
|
|
if (issilicon(user))
|
|
to_chat(user, SPAN_NOTICE("You need hands for this."))
|
|
return 0
|
|
return 1
|
|
|
|
/obj/structure/on_death(damage, damage_flags, damage_type, armor_penetration, obj/weapon)
|
|
dismantle()
|
|
|
|
/obj/structure/get_material()
|
|
return material
|