mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-21 20:11:04 +01:00
Removes ERT from standard gameplay. The Horizon now sends distress beacons for other Overmap vessels instead. Barricades and crew armoury buff. (#14371)
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
/obj/structure/barricade
|
||||
icon = 'icons/obj/barricades.dmi'
|
||||
climbable = TRUE
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
throwpass = TRUE //You can throw objects over this, despite its density.
|
||||
layer = BELOW_OBJ_LAYER
|
||||
flags = ON_BORDER
|
||||
|
||||
var/stack_type //The type of stack the barricade dropped when disassembled if any.
|
||||
var/stack_amount = 5 //The amount of stack dropped when disassembled at full health
|
||||
var/destroyed_stack_amount //to specify a non-zero amount of stack to drop when destroyed
|
||||
var/health = 100 //Pretty tough. Changes sprites at 300 and 150
|
||||
var/maxhealth = 100 //Basic code functions
|
||||
/// Used for calculating some stuff related to maxhealth as it constantly changes due to e.g. barbed wire. set to 100 to avoid possible divisions by zero
|
||||
var/starting_maxhealth = 100
|
||||
var/force_level_absorption = 5 //How much force an item needs to even damage it at all.
|
||||
var/barricade_hitsound
|
||||
var/barricade_type = "barricade" //"metal", "plasteel", etc.
|
||||
var/can_change_dmg_state = TRUE
|
||||
var/damage_state = BARRICADE_DMG_NONE
|
||||
var/closed = FALSE
|
||||
var/can_wire = FALSE
|
||||
var/is_wired = FALSE
|
||||
var/metallic = TRUE
|
||||
|
||||
/obj/structure/barricade/Initialize(mapload, mob/user)
|
||||
. = ..()
|
||||
update_icon()
|
||||
starting_maxhealth = maxhealth
|
||||
|
||||
/obj/structure/barricade/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, SPAN_INFO("It is recommended to stand flush to a barricade or one tile away for maximum efficiency."))
|
||||
if(is_wired)
|
||||
to_chat(user, SPAN_INFO("There is a length of wire strewn across the top of this barricade."))
|
||||
switch(damage_state)
|
||||
if(BARRICADE_DMG_NONE)
|
||||
to_chat(user, SPAN_INFO("It appears to be in good shape."))
|
||||
if(BARRICADE_DMG_SLIGHT)
|
||||
to_chat(user, SPAN_WARNING("It's slightly damaged, but still very functional."))
|
||||
if(BARRICADE_DMG_MODERATE)
|
||||
to_chat(user, SPAN_WARNING("It's quite beat up, but it's holding together."))
|
||||
if(BARRICADE_DMG_HEAVY)
|
||||
to_chat(user, SPAN_WARNING("It's crumbling apart, just a few more blows will tear it apart!"))
|
||||
|
||||
/obj/structure/barricade/update_icon()
|
||||
overlays.Cut()
|
||||
if(!closed)
|
||||
if(can_change_dmg_state)
|
||||
icon_state = "[barricade_type]_[damage_state]"
|
||||
else
|
||||
icon_state = "[barricade_type]"
|
||||
switch(dir)
|
||||
if(SOUTH)
|
||||
layer = ABOVE_MOB_LAYER
|
||||
else if(NORTH)
|
||||
layer = initial(layer) - 0.01
|
||||
else
|
||||
layer = initial(layer)
|
||||
if(!anchored)
|
||||
layer = initial(layer)
|
||||
else
|
||||
if(can_change_dmg_state)
|
||||
icon_state = "[barricade_type]_closed_[damage_state]"
|
||||
else
|
||||
icon_state = "[barricade_type]_closed"
|
||||
layer = OBJ_LAYER
|
||||
|
||||
if(is_wired)
|
||||
if(!closed)
|
||||
overlays += image('icons/obj/barricades.dmi', icon_state = "[src.barricade_type]_wire")
|
||||
else
|
||||
overlays += image('icons/obj/barricades.dmi', icon_state = "[src.barricade_type]_closed_wire")
|
||||
|
||||
..()
|
||||
|
||||
/obj/structure/barricade/proc/handle_barrier_chance()
|
||||
if(!anchored)
|
||||
return FALSE
|
||||
return prob(max(30,(100.0*health)/maxhealth))
|
||||
|
||||
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0))
|
||||
return TRUE
|
||||
if(istype(mover, /obj/item/projectile))
|
||||
return (check_cover(mover,target))
|
||||
if (get_dir(loc, target) == dir)
|
||||
return !density
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/structure/barricade/proc/check_cover(obj/item/projectile/P, turf/from)
|
||||
var/turf/cover = get_turf(src)
|
||||
if(!cover)
|
||||
return TRUE
|
||||
if (get_dist(P.starting, loc) <= 1)
|
||||
return TRUE
|
||||
var/chance = handle_barrier_chance()
|
||||
if(chance)
|
||||
bullet_act(P)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/barricade/CheckExit(atom/movable/O as mob|obj, target as turf)
|
||||
if(istype(O) && O.checkpass(PASSTABLE))
|
||||
return TRUE
|
||||
if (get_dir(loc, target) == dir)
|
||||
return !density
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/structure/barricade/attack_robot(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/structure/barricade/attack_hand(var/mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/shredding = H.species.can_shred(H)
|
||||
if(shredding)
|
||||
var/datum/unarmed_attack/UA = H.default_attack
|
||||
if((UA.damage + UA.armor_penetration) > force_level_absorption)
|
||||
var/attack_verb = pick("mangles", "slices", "slashes", "shreds")
|
||||
attack_generic(user, UA.damage, attack_verb)
|
||||
|
||||
/obj/structure/barricade/attack_generic(mob/user, damage, attack_verb, wallbreaker)
|
||||
if(!damage)
|
||||
return FALSE
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
L.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
visible_message(SPAN_DANGER("[L] [attack_verb] the [src]!"))
|
||||
if(barricade_hitsound)
|
||||
playsound(src, barricade_hitsound, 50, 1)
|
||||
if(is_wired)
|
||||
visible_message(SPAN_DANGER("\The [src]'s barbed wire slices into [L]!"))
|
||||
L.apply_damage(rand(5, 10), BRUTE, pick(BP_R_HAND, BP_L_HAND), "barbed wire", DAM_SHARP|DAM_EDGE, 25)
|
||||
L.do_attack_animation(src)
|
||||
take_damage(damage)
|
||||
|
||||
/obj/structure/barricade/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/stack/barbed_wire))
|
||||
var/obj/item/stack/barbed_wire/B = W
|
||||
if(can_wire)
|
||||
user.visible_message(SPAN_NOTICE("[user] starts setting up [W.name] on [src]."),
|
||||
SPAN_NOTICE("You start setting up [W.name] on [src]."))
|
||||
if(do_after(user, 20, act_target = src) && can_wire)
|
||||
// Make sure there's still enough wire in the stack
|
||||
if(!B.use(1))
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/effects/barbed_wire_movement.ogg', 25, 1)
|
||||
user.visible_message(SPAN_NOTICE("[user] sets up [W.name] on [src]."),
|
||||
SPAN_NOTICE("You set up [W.name] on [src]."))
|
||||
|
||||
maxhealth += 50
|
||||
update_health(-50)
|
||||
can_wire = FALSE
|
||||
is_wired = TRUE
|
||||
climbable = FALSE
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(W.iswirecutter())
|
||||
if(is_wired)
|
||||
user.visible_message(SPAN_NOTICE("[user] begin removing the barbed wire on [src]."),
|
||||
SPAN_NOTICE("You begin removing the barbed wire on [src]."))
|
||||
if(do_after(user, 20, act_target = src))
|
||||
if(!is_wired)
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/items/Wirecutter.ogg', 25, 1)
|
||||
user.visible_message(SPAN_NOTICE("[user] removes the barbed wire on [src]."),
|
||||
SPAN_NOTICE("You remove the barbed wire on [src]."))
|
||||
maxhealth -= 50
|
||||
update_health(50)
|
||||
can_wire = TRUE
|
||||
is_wired = FALSE
|
||||
climbable = TRUE
|
||||
update_icon()
|
||||
new /obj/item/stack/barbed_wire(loc)
|
||||
return
|
||||
|
||||
if((W.force + W.armor_penetration) > force_level_absorption)
|
||||
..()
|
||||
if(barricade_hitsound)
|
||||
playsound(src, barricade_hitsound, 25, 1)
|
||||
hit_barricade(W, user)
|
||||
|
||||
/obj/structure/barricade/bullet_act(obj/item/projectile/P)
|
||||
bullet_ping(P)
|
||||
var/damage_to_take = P.damage * P.anti_materiel_potential
|
||||
take_damage(damage_to_take)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/barricade/proc/barricade_deconstruct(deconstruct)
|
||||
if(deconstruct && is_wired)
|
||||
new /obj/item/stack/barbed_wire(loc)
|
||||
if(stack_type)
|
||||
var/stack_amt
|
||||
if(!deconstruct && destroyed_stack_amount)
|
||||
stack_amt = destroyed_stack_amount
|
||||
else
|
||||
stack_amt = round(stack_amount * (health/starting_maxhealth)) //Get an amount of sheets back equivalent to remaining health. Obviously, fully destroyed means 0
|
||||
|
||||
if(stack_amt)
|
||||
new stack_type (loc, stack_amt)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/barricade/ex_act(severity, direction, cause_data)
|
||||
for(var/obj/structure/barricade/B in get_step(src,dir)) //discourage double-stacking barricades by removing health from opposing barricade
|
||||
if(B.dir == reverse_direction(dir))
|
||||
INVOKE_ASYNC(B, /atom/.proc/ex_act, severity, direction)
|
||||
update_health(round(severity))
|
||||
|
||||
// This proc is called whenever the cade is moved, so I thought it was appropriate,
|
||||
// especially since the barricade's direction needs to be handled when moving
|
||||
// diagonally.
|
||||
/obj/structure/barricade/Move()
|
||||
. = ..()
|
||||
if (dir & EAST)
|
||||
set_dir(EAST)
|
||||
else if(dir & WEST)
|
||||
set_dir(WEST)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/barricade/set_dir(ndir)
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/barricade/proc/hit_barricade(var/obj/item/I, var/mob/user)
|
||||
if(!isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
L.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
var/message = pick(I.attack_verb)
|
||||
visible_message(SPAN_DANGER("[L] has [message] the [src]!"))
|
||||
L.do_attack_animation(src)
|
||||
take_damage(I.force)
|
||||
|
||||
/obj/structure/barricade/proc/take_damage(var/damage)
|
||||
for(var/obj/structure/barricade/B in get_step(src,dir)) //discourage double-stacking barricades by removing health from opposing barricade
|
||||
if(B.dir == reverse_direction(dir))
|
||||
B.update_health(damage)
|
||||
update_health(damage)
|
||||
|
||||
/obj/structure/barricade/proc/update_health(damage, nomessage)
|
||||
health -= damage
|
||||
health = Clamp(health, 0, maxhealth)
|
||||
|
||||
if(!health)
|
||||
if(!nomessage)
|
||||
visible_message(SPAN_DANGER("[src] falls apart!"))
|
||||
barricade_deconstruct()
|
||||
return
|
||||
|
||||
update_damage_state()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/barricade/proc/update_damage_state()
|
||||
var/health_percent = round(health/maxhealth * 100)
|
||||
switch(health_percent)
|
||||
if(0 to 25) damage_state = BARRICADE_DMG_HEAVY
|
||||
if(25 to 50) damage_state = BARRICADE_DMG_MODERATE
|
||||
if(50 to 75) damage_state = BARRICADE_DMG_SLIGHT
|
||||
if(75 to INFINITY) damage_state = BARRICADE_DMG_NONE
|
||||
|
||||
/obj/structure/barricade/proc/weld_cade(obj/item/weldingtool/WT, mob/user)
|
||||
if(!metallic)
|
||||
return FALSE
|
||||
|
||||
if(!(WT.use(2, user)))
|
||||
return FALSE
|
||||
|
||||
user.visible_message(SPAN_NOTICE("[user] begins repairing damage to [src]."),
|
||||
SPAN_NOTICE("You begin repairing the damage to [src]."))
|
||||
|
||||
if(WT.use_tool(src, user, 7 SECONDS, volume = 40))
|
||||
user.visible_message(SPAN_NOTICE("[user] repairs some damage on [src]."),
|
||||
SPAN_NOTICE("You repair \the [src]."))
|
||||
update_health(-200)
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/structure/barricade/verb/count_rotate()
|
||||
set name = "Rotate Barricade Counter-Clockwise"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
rotate(usr, 1)
|
||||
|
||||
/obj/structure/barricade/verb/clock_rotate()
|
||||
set name = "Rotate Barricade Clockwise"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
rotate(usr, -1)
|
||||
|
||||
/obj/structure/barricade/rotate(var/mob/user, var/rotation_dir = -1)//-1 for clockwise, 1 for counter clockwise
|
||||
if(world.time <= user.next_move || !ishuman(user) || use_check_and_message(user))
|
||||
return
|
||||
|
||||
if(anchored)
|
||||
to_chat(usr, SPAN_WARNING("\The [src] is fastened to the floor, you can't rotate it!"))
|
||||
return
|
||||
|
||||
user.next_move = world.time + 3 //slight spam prevention? you don't want every metal cade to turn into a doorway
|
||||
set_dir(turn(dir, 90 * rotation_dir))
|
||||
update_icon()
|
||||
|
||||
/obj/structure/barricade/AltClick(mob/user)
|
||||
rotate(user)
|
||||
@@ -0,0 +1,129 @@
|
||||
/obj/structure/barricade/liquid
|
||||
name = "liquid-bag barricade"
|
||||
desc = "An advanced version of sandbags, used in conflict since their inception in the late 2300s. These barricades are made of bags that contain non-newtonian liquid that hardens in response to projectile impacts. Easy to set up as well!"
|
||||
icon_state = "sandbag1"
|
||||
force_level_absorption = 15
|
||||
health = BARRICADE_LIQUIDBAG_TRESHOLD_1
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_1
|
||||
stack_type = /obj/item/stack/liquidbags
|
||||
barricade_hitsound = 'sound/weapons/Genhit.ogg'
|
||||
barricade_type = "sandbag"
|
||||
can_wire = TRUE
|
||||
stack_amount = 1
|
||||
var/build_stage = BARRICADE_LIQUIDBAG_1
|
||||
|
||||
/obj/structure/barricade/liquid/Initialize(mapload, mob/user, var/direction, var/amount)
|
||||
if(direction)
|
||||
set_dir(direction)
|
||||
|
||||
if(dir == SOUTH)
|
||||
pixel_y = -7
|
||||
else if(dir == NORTH)
|
||||
pixel_y = 7
|
||||
|
||||
for(var/i = 1 to amount-1)
|
||||
increment_build_stage()
|
||||
. = ..(loc, user)
|
||||
|
||||
/obj/structure/barricade/liquid/update_icon()
|
||||
..()
|
||||
icon_state = "sandbag[build_stage]"
|
||||
|
||||
/obj/structure/barricade/liquid/update_damage_state()
|
||||
var/changed = FALSE
|
||||
if(health <= BARRICADE_LIQUIDBAG_TRESHOLD_4 && build_stage != BARRICADE_LIQUIDBAG_4)
|
||||
changed = TRUE
|
||||
build_stage = BARRICADE_LIQUIDBAG_4
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_4
|
||||
stack_amount = 4
|
||||
if(health <= BARRICADE_LIQUIDBAG_TRESHOLD_3 && build_stage != BARRICADE_LIQUIDBAG_3)
|
||||
changed = TRUE
|
||||
build_stage = BARRICADE_LIQUIDBAG_3
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_3
|
||||
stack_amount = 3
|
||||
if(health <= BARRICADE_LIQUIDBAG_TRESHOLD_2 && build_stage != BARRICADE_LIQUIDBAG_2)
|
||||
changed = TRUE
|
||||
build_stage = BARRICADE_LIQUIDBAG_2
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_2
|
||||
stack_amount = 2
|
||||
if(health <= BARRICADE_LIQUIDBAG_TRESHOLD_1 && build_stage != BARRICADE_LIQUIDBAG_1)
|
||||
changed = TRUE
|
||||
build_stage = BARRICADE_LIQUIDBAG_1
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_1
|
||||
stack_amount = 1
|
||||
if(changed && is_wired)
|
||||
maxhealth += 50
|
||||
|
||||
/obj/structure/barricade/liquid/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/crowbar) && user.a_intent != I_HURT)
|
||||
var/obj/item/crowbar/ET = W
|
||||
user.visible_message(SPAN_NOTICE("[user] starts disassembling [src]."), \
|
||||
SPAN_NOTICE("You start disassembling [src]."))
|
||||
if(ET.use_tool(src, user, 4 SECONDS))
|
||||
user.visible_message(SPAN_NOTICE("[user] disassembles [src]."),
|
||||
SPAN_NOTICE("You disassemble [src]."))
|
||||
barricade_deconstruct(TRUE)
|
||||
return TRUE
|
||||
|
||||
if(istype(W, stack_type))
|
||||
var/obj/item/stack/liquidbags/SB = W
|
||||
if(build_stage == BARRICADE_LIQUIDBAG_5)
|
||||
to_chat(user, SPAN_WARNING("You can't stack more on [src]."))
|
||||
return
|
||||
|
||||
user.visible_message(SPAN_NOTICE("[user] starts adding more [SB] to [src]."), \
|
||||
SPAN_NOTICE("You start adding liquid bags to [src]."))
|
||||
for(var/i = build_stage to BARRICADE_LIQUIDBAG_5)
|
||||
if(build_stage >= BARRICADE_LIQUIDBAG_5 || !do_after(user, 5, act_target = src) || build_stage >= BARRICADE_LIQUIDBAG_5)
|
||||
break
|
||||
SB.use(1)
|
||||
increment_build_stage()
|
||||
update_icon()
|
||||
user.visible_message(SPAN_NOTICE("[user] finishes stacking [SB] onto [src]."), \
|
||||
SPAN_NOTICE("You stack [SB] onto [src]."))
|
||||
return
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/structure/barricade/liquid/barricade_deconstruct(deconstruct)
|
||||
if(deconstruct && is_wired)
|
||||
new /obj/item/stack/barbed_wire(loc)
|
||||
if(stack_type && health > 0)
|
||||
new stack_type(loc, stack_amount)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/barricade/liquid/proc/increment_build_stage()
|
||||
switch(build_stage)
|
||||
if(BARRICADE_LIQUIDBAG_1)
|
||||
health = BARRICADE_LIQUIDBAG_TRESHOLD_2
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_2
|
||||
stack_amount = 2
|
||||
if(BARRICADE_LIQUIDBAG_2)
|
||||
health = BARRICADE_LIQUIDBAG_TRESHOLD_3
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_3
|
||||
stack_amount = 3
|
||||
if(BARRICADE_LIQUIDBAG_3)
|
||||
health = BARRICADE_LIQUIDBAG_TRESHOLD_4
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_4
|
||||
stack_amount = 4
|
||||
if(BARRICADE_LIQUIDBAG_4)
|
||||
health = BARRICADE_LIQUIDBAG_TRESHOLD_5
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_5
|
||||
stack_amount = 5
|
||||
if(is_wired)
|
||||
maxhealth += 50
|
||||
health += 50
|
||||
build_stage++
|
||||
|
||||
/obj/structure/barricade/liquid/wired/Initialize(mapload, mob/user, var/direction, var/amount)
|
||||
. = ..()
|
||||
health = BARRICADE_LIQUIDBAG_TRESHOLD_5
|
||||
maxhealth = BARRICADE_LIQUIDBAG_TRESHOLD_5
|
||||
maxhealth += 50
|
||||
update_health(-50)
|
||||
stack_amount = 5
|
||||
can_wire = FALSE
|
||||
is_wired = TRUE
|
||||
build_stage = BARRICADE_LIQUIDBAG_5
|
||||
update_icon()
|
||||
climbable = FALSE
|
||||
@@ -0,0 +1,104 @@
|
||||
/obj/structure/barricade/metal
|
||||
name = "metal barricade"
|
||||
desc = "A sturdy and easily assembled barricade made of metal plates, often used for quick fortifications. Use a blowtorch to repair."
|
||||
icon_state = "metal_0"
|
||||
build_amt = 4
|
||||
health = 450
|
||||
maxhealth = 450
|
||||
force_level_absorption = 10
|
||||
stack_type = /obj/item/stack/material/steel
|
||||
stack_amount = 4
|
||||
destroyed_stack_amount = 2
|
||||
barricade_hitsound = 'sound/effects/metalhit.ogg'
|
||||
barricade_type = "metal"
|
||||
can_wire = TRUE
|
||||
var/build_state = BARRICADE_BSTATE_SECURED //Look at __game.dm for barricade defines
|
||||
|
||||
/obj/structure/barricade/metal/examine(mob/user)
|
||||
..()
|
||||
switch(build_state)
|
||||
if(BARRICADE_BSTATE_SECURED)
|
||||
to_chat(user, SPAN_INFO("The protection panel is still tighly screwed in place."))
|
||||
if(BARRICADE_BSTATE_UNSECURED)
|
||||
to_chat(user, SPAN_INFO("The protection panel has been removed, you can see the anchor bolts."))
|
||||
if(BARRICADE_BSTATE_MOVABLE)
|
||||
to_chat(user, SPAN_INFO("The protection panel has been removed and the anchor bolts loosened. It's ready to be taken apart."))
|
||||
|
||||
/obj/structure/barricade/metal/attackby(obj/item/W, mob/user)
|
||||
if(W.iswelder())
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if(damage_state == BARRICADE_DMG_HEAVY)
|
||||
to_chat(user, SPAN_WARNING("[src] has sustained too much structural damage to be repaired."))
|
||||
return
|
||||
|
||||
if(health == maxhealth)
|
||||
to_chat(user, SPAN_WARNING("[src] doesn't need repairs."))
|
||||
return
|
||||
|
||||
weld_cade(WT, user)
|
||||
return
|
||||
|
||||
switch(build_state)
|
||||
if(BARRICADE_BSTATE_SECURED) //Fully constructed step. Use screwdriver to remove the protection panels to reveal the bolts
|
||||
if(W.isscrewdriver())
|
||||
if(!W.use_tool(src, user, 1 SECOND, volume = 40))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] removes [src]'s protection panel."),
|
||||
SPAN_NOTICE("You remove [src]'s protection panels, exposing the anchor bolts."))
|
||||
build_state = BARRICADE_BSTATE_UNSECURED
|
||||
return
|
||||
|
||||
if(BARRICADE_BSTATE_UNSECURED) //Protection panel removed step. Screwdriver to put the panel back, wrench to unsecure the anchor bolts
|
||||
if(W.isscrewdriver())
|
||||
if(!W.use_tool(src, user, 2 SECONDS, volume = 40))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] screws \the [src]'s protection panel back."),
|
||||
SPAN_NOTICE("You screw \the [src]'s protection panel back."))
|
||||
build_state = BARRICADE_BSTATE_SECURED
|
||||
return
|
||||
if(W.iswrench())
|
||||
if(!W.use_tool(src, user, 1 SECOND, volume = 40))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] loosens [src]'s anchor bolts."),
|
||||
SPAN_NOTICE("You loosen [src]'s anchor bolts."))
|
||||
anchored = FALSE
|
||||
build_state = BARRICADE_BSTATE_MOVABLE
|
||||
update_icon() //unanchored changes layer
|
||||
return
|
||||
if(BARRICADE_BSTATE_MOVABLE) //Anchor bolts loosened step. Apply crowbar to unseat the panel and take apart the whole thing. Apply wrench to resecure anchor bolts
|
||||
if(W.iswrench())
|
||||
for(var/obj/structure/barricade/B in loc)
|
||||
if(B != src && B.dir == dir)
|
||||
to_chat(user, SPAN_WARNING("There's already a barricade here."))
|
||||
return
|
||||
var/turf/T = loc
|
||||
if(!(istype(T)) || istype(T, /turf/space))
|
||||
to_chat(user, SPAN_WARNING("[src] must be secured on a proper surface!"))
|
||||
return
|
||||
if(!W.use_tool(src, user, 1 SECOND, volume = 50))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] secures [src]'s anchor bolts."),
|
||||
SPAN_NOTICE("You secure [src]'s anchor bolts."))
|
||||
build_state = BARRICADE_BSTATE_UNSECURED
|
||||
anchored = TRUE
|
||||
update_icon() //unanchored changes layer
|
||||
return
|
||||
if(W.iscrowbar())
|
||||
user.visible_message(SPAN_NOTICE("[user] starts unseating [src]'s panels."),
|
||||
SPAN_NOTICE("You start unseating [src]'s panels."))
|
||||
if(W.use_tool(src, user, 3 SECONDS, volume = 40))
|
||||
user.visible_message(SPAN_NOTICE("[user] takes [src]'s panels apart."),
|
||||
SPAN_NOTICE("You take [src]'s panels apart."))
|
||||
barricade_deconstruct(TRUE) //Note : Handles deconstruction too !
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/structure/barricade/metal/wired/Initialize(mapload, mob/user)
|
||||
. = ..()
|
||||
maxhealth += 50
|
||||
update_health(-50)
|
||||
can_wire = FALSE
|
||||
is_wired = TRUE
|
||||
climbable = FALSE
|
||||
update_icon()
|
||||
@@ -0,0 +1,226 @@
|
||||
/obj/structure/barricade/plasteel
|
||||
name = "plasteel barricade"
|
||||
desc = "A very sturdy barricade made out of plasteel panels, the pinnacle of strongpoints. Use a blowtorch to repair. Can be flipped down to create a path."
|
||||
icon_state = "plasteel_closed_0"
|
||||
health = 800
|
||||
maxhealth = 800
|
||||
force_level_absorption = 20
|
||||
stack_type = /obj/item/stack/material/plasteel
|
||||
build_amt = 8
|
||||
stack_amount = 8
|
||||
destroyed_stack_amount = 4
|
||||
barricade_hitsound = 'sound/effects/metalhit.ogg'
|
||||
barricade_type = "plasteel"
|
||||
density = 0
|
||||
closed = TRUE
|
||||
can_wire = TRUE
|
||||
|
||||
var/build_state = BARRICADE_BSTATE_SECURED //Look at __game.dm for barricade defines
|
||||
var/tool_cooldown = 0 //Delay to apply tools to prevent spamming
|
||||
var/busy = 0 //Standard busy check
|
||||
var/linked = 0
|
||||
var/recentlyflipped = FALSE
|
||||
var/hasconnectionoverlay = TRUE
|
||||
var/linkable = TRUE
|
||||
|
||||
/obj/structure/barricade/plasteel/update_icon()
|
||||
..()
|
||||
if(linked)
|
||||
for(var/direction in cardinal)
|
||||
for(var/obj/structure/barricade/plasteel/cade in get_step(src, direction))
|
||||
if(((dir & (NORTH|SOUTH) && get_dir(src, cade) & (EAST|WEST)) || (dir & (EAST|WEST) && get_dir(src, cade) & (NORTH|SOUTH))) && dir == cade.dir && cade.linked && cade.closed == src.closed && hasconnectionoverlay)
|
||||
if(closed)
|
||||
overlays += image('icons/obj/barricades.dmi', icon_state = "[src.barricade_type]_closed_connection_[get_dir(src, cade)]")
|
||||
else
|
||||
overlays += image('icons/obj/barricades.dmi', icon_state = "[src.barricade_type]_connection_[get_dir(src, cade)]")
|
||||
continue
|
||||
|
||||
|
||||
/obj/structure/barricade/plasteel/handle_barrier_chance(mob/living/M)
|
||||
if(!closed) // Closed = gate down for plasteel for some reason
|
||||
return ..()
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/structure/barricade/plasteel/examine(mob/user)
|
||||
..()
|
||||
|
||||
switch(build_state)
|
||||
if(BARRICADE_BSTATE_SECURED)
|
||||
to_chat(user, SPAN_INFO("The protection panel is still tighly screwed in place."))
|
||||
if(BARRICADE_BSTATE_UNSECURED)
|
||||
to_chat(user, SPAN_INFO("The protection panel has been removed, you can see the anchor bolts."))
|
||||
if(BARRICADE_BSTATE_MOVABLE)
|
||||
to_chat(user, SPAN_INFO("The protection panel has been removed and the anchor bolts loosened. It's ready to be taken apart."))
|
||||
|
||||
/obj/structure/barricade/plasteel/weld_cade(obj/item/W, mob/user)
|
||||
busy = TRUE
|
||||
..()
|
||||
busy = FALSE
|
||||
|
||||
/obj/structure/barricade/plasteel/attackby(obj/item/W, mob/user)
|
||||
if(W.iswelder())
|
||||
if(busy || tool_cooldown > world.time)
|
||||
return
|
||||
tool_cooldown = world.time + 10
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if(damage_state == BARRICADE_DMG_HEAVY)
|
||||
to_chat(user, SPAN_WARNING("[src] has sustained too much structural damage to be repaired."))
|
||||
return
|
||||
|
||||
if(health == maxhealth)
|
||||
to_chat(user, SPAN_WARNING("[src] doesn't need repairs."))
|
||||
return
|
||||
|
||||
weld_cade(WT, user)
|
||||
return
|
||||
|
||||
switch(build_state)
|
||||
if(2) //Fully constructed step. Use screwdriver to remove the protection panels to reveal the bolts
|
||||
if(W.isscrewdriver())
|
||||
if(busy || tool_cooldown > world.time)
|
||||
return
|
||||
tool_cooldown = world.time + 10
|
||||
for(var/obj/structure/barricade/B in loc)
|
||||
if(B != src && B.dir == dir)
|
||||
to_chat(user, SPAN_WARNING("There's already a barricade here."))
|
||||
return
|
||||
if(!W.use_tool(src, user, 10, volume = 50))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] removes [src]'s protection panel."),
|
||||
SPAN_NOTICE("You remove [src]'s protection panels, exposing the anchor bolts."))
|
||||
build_state = BARRICADE_BSTATE_UNSECURED
|
||||
return
|
||||
if(W.iscrowbar())
|
||||
playsound(src.loc, 'sound/items/crowbar_pry.ogg', 25, 1)
|
||||
if(linked)
|
||||
user.visible_message(SPAN_NOTICE("[user] removes the linking on [src]."),
|
||||
SPAN_NOTICE("You remove the linking on [src]."))
|
||||
else if(linkable)
|
||||
user.visible_message(SPAN_NOTICE("[user] sets up [src] for linking."),
|
||||
SPAN_NOTICE("You set up [src] for linking."))
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("The [src] has no linking points."))
|
||||
return
|
||||
linked = !linked
|
||||
for(var/direction in cardinal)
|
||||
for(var/obj/structure/barricade/plasteel/cade in get_step(src, direction))
|
||||
cade.update_icon()
|
||||
update_icon()
|
||||
if(1) //Protection panel removed step. Screwdriver to put the panel back, wrench to unsecure the anchor bolts
|
||||
if(W.isscrewdriver())
|
||||
if(busy || tool_cooldown > world.time)
|
||||
return
|
||||
tool_cooldown = world.time + 10
|
||||
if(!W.use_tool(src, user, 10, volume = 50))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] set [src]'s protection panel back."),
|
||||
SPAN_NOTICE("You set [src]'s protection panel back."))
|
||||
build_state = BARRICADE_BSTATE_SECURED
|
||||
return
|
||||
if(W.iswrench())
|
||||
if(busy || tool_cooldown > world.time)
|
||||
return
|
||||
if(!W.use_tool(src, user, 10, volume = 50))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] loosens [src]'s anchor bolts."),
|
||||
SPAN_NOTICE("You loosen [src]'s anchor bolts."))
|
||||
anchored = FALSE
|
||||
build_state = BARRICADE_BSTATE_MOVABLE
|
||||
update_icon() //unanchored changes layer
|
||||
return
|
||||
|
||||
if(0) //Anchor bolts loosened step. Apply crowbar to unseat the panel and take apart the whole thing. Apply wrench to rescure anchor bolts
|
||||
if(W.iswrench())
|
||||
if(busy || tool_cooldown > world.time)
|
||||
return
|
||||
tool_cooldown = world.time + 10
|
||||
var/turf/T = loc
|
||||
if(!(istype(T)) || istype(T, /turf/space))
|
||||
to_chat(user, SPAN_WARNING("[src] must be secured on a proper surface!"))
|
||||
return
|
||||
if(!W.use_tool(src, user, 10, volume = 50))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] secures [src]'s anchor bolts."),
|
||||
SPAN_NOTICE("You secure [src]'s anchor bolts."))
|
||||
anchored = TRUE
|
||||
build_state = BARRICADE_BSTATE_UNSECURED
|
||||
update_icon() //unanchored changes layer
|
||||
return
|
||||
if(W.iscrowbar())
|
||||
if(busy || tool_cooldown > world.time)
|
||||
return
|
||||
tool_cooldown = world.time + 10
|
||||
user.visible_message(SPAN_NOTICE("[user] starts unseating [src]'s panels."),
|
||||
SPAN_NOTICE("You start unseating [src]'s panels."))
|
||||
playsound(src.loc, 'sound/items/crowbar_pry.ogg', 25, 1)
|
||||
busy = 1
|
||||
if(W.use_tool(src, user, 8 SECONDS, volume = 50))
|
||||
busy = 0
|
||||
user.visible_message(SPAN_NOTICE("[user] takes [src]'s panels apart."),
|
||||
SPAN_NOTICE("You take [src]'s panels apart."))
|
||||
playsound(loc, 'sound/items/Deconstruct.ogg', 25, 1)
|
||||
barricade_deconstruct(TRUE) //Note : Handles deconstruction too !
|
||||
else
|
||||
busy = 0
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/structure/barricade/plasteel/attack_hand(mob/user as mob)
|
||||
if(closed)
|
||||
if(recentlyflipped)
|
||||
to_chat(user, SPAN_NOTICE("\The [src] has been flipped too recently!"))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] flips [src] open."),
|
||||
SPAN_NOTICE("You flip [src] open."))
|
||||
open(src)
|
||||
recentlyflipped = TRUE
|
||||
addtimer(CALLBACK(src, .proc/remove_cooldown), 1 SECOND)
|
||||
|
||||
else
|
||||
if(recentlyflipped)
|
||||
to_chat(user, SPAN_NOTICE("\The [src] has been flipped too recently!"))
|
||||
return
|
||||
user.visible_message(SPAN_NOTICE("[user] flips [src] closed."),
|
||||
SPAN_NOTICE("You flip [src] closed."))
|
||||
close(src)
|
||||
recentlyflipped = TRUE
|
||||
addtimer(CALLBACK(src, .proc/remove_cooldown), 1 SECOND)
|
||||
|
||||
/obj/structure/barricade/plasteel/proc/remove_cooldown()
|
||||
recentlyflipped = !recentlyflipped
|
||||
|
||||
/obj/structure/barricade/plasteel/proc/open(var/obj/structure/barricade/plasteel/origin)
|
||||
if(!closed)
|
||||
return
|
||||
playsound(src.loc, 'sound/items/wrench.ogg', 25, 1)
|
||||
closed = 0
|
||||
density = 1
|
||||
if(linked)
|
||||
for(var/direction in cardinal)
|
||||
for(var/obj/structure/barricade/plasteel/cade in get_step(src, direction))
|
||||
if(((dir & (NORTH|SOUTH) && get_dir(src, cade) & (EAST|WEST)) || (dir & (EAST|WEST) && get_dir(src, cade) & (NORTH|SOUTH))) && dir == cade.dir && cade != origin && cade.linked)
|
||||
cade.open(src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/barricade/plasteel/proc/close(var/obj/structure/barricade/plasteel/origin)
|
||||
if(closed)
|
||||
return
|
||||
playsound(src.loc, 'sound/items/wrench.ogg', 25, 1)
|
||||
closed = 1
|
||||
density = 0
|
||||
if(linked)
|
||||
for(var/direction in cardinal)
|
||||
for(var/obj/structure/barricade/plasteel/cade in get_step(src, direction))
|
||||
if(((dir & (NORTH|SOUTH) && get_dir(src, cade) & (EAST|WEST)) || (dir & (EAST|WEST) && get_dir(src, cade) & (NORTH|SOUTH))) && dir == cade.dir && cade != origin && cade.linked)
|
||||
cade.close(src)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/structure/barricade/plasteel/wired/New()
|
||||
can_wire = FALSE
|
||||
is_wired = TRUE
|
||||
climbable = FALSE
|
||||
update_icon()
|
||||
. = ..()
|
||||
@@ -0,0 +1,33 @@
|
||||
/obj/structure/barricade/wooden
|
||||
name = "wooden barricade"
|
||||
desc = "A wall made out of wooden planks nailed together. Not very sturdy, but can provide some concealment."
|
||||
icon_state = "wooden"
|
||||
health = 100
|
||||
maxhealth = 100
|
||||
layer = OBJ_LAYER
|
||||
stack_type = /obj/item/stack/material/wood
|
||||
stack_amount = 5
|
||||
build_amt = 5
|
||||
destroyed_stack_amount = 3
|
||||
barricade_hitsound = 'sound/effects/woodhit.ogg'
|
||||
can_change_dmg_state = 0
|
||||
barricade_type = "wooden"
|
||||
can_wire = FALSE
|
||||
metallic = FALSE
|
||||
|
||||
/obj/structure/barricade/wooden/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/stack/material/wood))
|
||||
var/obj/item/stack/material/wood/D = W
|
||||
if(health < maxhealth)
|
||||
if(D.get_amount() < 1)
|
||||
to_chat(user, SPAN_WARNING("You need one plank of wood to repair [src]."))
|
||||
return
|
||||
visible_message(SPAN_NOTICE("[user] begins to repair [src]."))
|
||||
if(do_after(user, 2 SECONDS, act_target = src) && (health < maxhealth))
|
||||
if(D.use(1))
|
||||
update_health(-0.5*maxhealth)
|
||||
update_damage_state()
|
||||
visible_message(SPAN_NOTICE("[user] clumsily repairs [src]."))
|
||||
return
|
||||
|
||||
. = ..()
|
||||
@@ -44,7 +44,7 @@
|
||||
var/deflating = FALSE
|
||||
var/undeploy_path = null
|
||||
var/torn_path = null
|
||||
var/health = 50.0
|
||||
var/health = 15
|
||||
|
||||
/obj/structure/inflatable/wall
|
||||
name = "inflatable wall"
|
||||
@@ -60,6 +60,10 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/inflatable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(isprojectile(mover))
|
||||
visible_message(SPAN_DANGER("\The [src] rapidly deflates!"))
|
||||
deflate(TRUE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/inflatable/bullet_act(var/obj/item/projectile/Proj)
|
||||
@@ -67,6 +71,8 @@
|
||||
if(!proj_damage)
|
||||
return
|
||||
|
||||
bullet_ping(Proj)
|
||||
|
||||
health -= proj_damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
@@ -199,6 +205,10 @@
|
||||
return state
|
||||
if(istype(mover, /obj/effect/beam))
|
||||
return !opacity
|
||||
if(isprojectile(mover))
|
||||
visible_message(SPAN_DANGER("\The [src] rapidly deflates!"))
|
||||
deflate(TRUE)
|
||||
return TRUE
|
||||
return !density
|
||||
|
||||
/obj/structure/inflatable/door/proc/TryToSwitchState(mob/user)
|
||||
|
||||
@@ -185,8 +185,8 @@
|
||||
|
||||
/obj/structure/simple_door/bullet_act(var/obj/item/projectile/Proj)
|
||||
health -= Proj.damage
|
||||
bullet_ping(Proj)
|
||||
CheckHealth()
|
||||
return
|
||||
|
||||
/obj/structure/simple_door/proc/CheckHealth()
|
||||
if(health <= 0)
|
||||
|
||||
@@ -128,7 +128,8 @@
|
||||
|
||||
/obj/structure/window/bullet_act(var/obj/item/projectile/Proj)
|
||||
var/proj_damage = Proj.get_structure_damage()
|
||||
if(!proj_damage) return
|
||||
if(!proj_damage)
|
||||
return
|
||||
|
||||
..()
|
||||
take_damage(proj_damage)
|
||||
|
||||
Reference in New Issue
Block a user