Skip to content

[BOUNTY] Implements atom integrity for walls, (which is needed to do) Upgraded Emitters can now tear down walls! Take Two! #5938

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion _maps/map_files/debug/runtimestation.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,6 @@
},
/obj/machinery/camera/autoname/directional/west,
/obj/machinery/light/directional/west,
/obj/structure/test_boulder_spawner,
/turf/open/floor/iron,
/area/station/construction)
"pI" = (
Expand Down Expand Up @@ -2298,6 +2297,8 @@
/obj/item/screwdriver{
pixel_y = 10
},
/obj/item/storage/box/beakers/variety,
/obj/item/storage/box/beakers,
/turf/open/floor/iron,
/area/station/medical/chemistry)
"GS" = (
Expand Down
14 changes: 14 additions & 0 deletions code/game/turfs/closed/_closed.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
rad_insulation = RAD_MEDIUM_INSULATION
pass_flags_self = PASSCLOSEDTURF

//Monkestation edit start
/turf/closed/examine(mob/user)
. = ..()
if(uses_integrity && atom_integrity < max_integrity)
var/healthpercent = (atom_integrity/max_integrity) * 100
switch(healthpercent)
if(50 to 99)
. += "It looks slightly damaged."
if(25 to 50)
. += "It appears heavily damaged."
if(0 to 25)
. += span_warning("It's falling apart!")
//Monkestation edit end

/turf/closed/AfterChange()
. = ..()
SSair.high_pressure_delta -= src
Expand Down
4 changes: 3 additions & 1 deletion code/game/turfs/closed/wall/reinf_walls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
sheet_amount = 1
girder_type = /obj/structure/girder/reinforced
explosive_resistance = 2
max_integrity = 600 //Monkestation edit
damage_deflection = 75 // can't be damaged with most conventional weapons or tools Monkestation edit
rad_insulation = RAD_HEAVY_INSULATION
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall. also indicates the temperature at wich the wall will melt (currently only able to melt with H/E pipes)
///Dismantled state, related to deconstruction.
Expand Down Expand Up @@ -205,7 +207,7 @@
icon_state = "[base_icon_state]-[smoothing_junction]"
return ..()

/turf/closed/wall/r_wall/wall_singularity_pull(current_size)
/turf/closed/wall/r_wall/singularity_pull(current_size) //Monkestation edit
if(current_size >= STAGE_FIVE)
if(prob(30))
dismantle_wall()
Expand Down
134 changes: 96 additions & 38 deletions code/game/turfs/closed/walls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@

var/list/dent_decals

//Monkestation edit start
max_integrity = 300
damage_deflection = 22 // big chunk of solid metal
uses_integrity = TRUE
armor_type = /datum/armor/wall

/datum/armor/wall
melee = 60
bullet = 60
laser = 60
energy = 0
bomb = 0
bio = 0
acid = 50
wound = 0
//Monkestation edit end


/turf/closed/wall/MouseDrop_T(mob/living/carbon/carbon_mob, mob/user)
..()
if(carbon_mob != user)
Expand Down Expand Up @@ -108,10 +126,6 @@
if(SSstation_coloring.wall_trims)
trim_color = SSstation_coloring.get_default_color()

/turf/closed/wall/atom_destruction(damage_flag)
. = ..()
dismantle_wall(TRUE, FALSE)

/turf/closed/wall/Destroy()
if(is_station_level(z))
GLOB.station_turfs -= src
Expand All @@ -122,6 +136,37 @@
. += ..()
. += deconstruction_hints(user)

//monkestation edit start
/turf/closed/wall/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration)
. = ..()
if(.) // add a dent if it took damage
add_dent(WALL_DENT_HIT)

/turf/closed/wall/attacked_by(obj/item/attacking_item, mob/living/user)
if(!uses_integrity)
CRASH("attacked_by() was called on an wall that doesn't use integrity!")

if(!attacking_item.force)
return

var/damage = take_damage(attacking_item.force * attacking_item.demolition_mod, attacking_item.damtype, MELEE, 1)
//only witnesses close by and the victim see a hit message.
user.visible_message(span_danger("[user] hits [src] with [attacking_item][damage ? "." : ", without leaving a mark!"]"), \
span_danger("You hit [src] with [attacking_item][damage ? "." : ", without leaving a mark!"]"), null, COMBAT_MESSAGE_RANGE)
log_combat(user, src, "attacked", attacking_item)

/turf/closed/wall/run_atom_armor(damage_amount, damage_type, damage_flag, attack_dir, armour_penetration)
if(damage_amount < damage_deflection && (damage_type in list(MELEE, BULLET, LASER, ENERGY)))
return 0 // absolutely no bypassing damage deflection by using projectiles
return ..()

/turf/closed/wall/atom_destruction(damage_flag)
. = ..()
if(damage_flag == MELEE)
playsound(src, 'sound/effects/meteorimpact.ogg', 50, TRUE) //Otherwise there's no sound for hitting the wall, since it's just dismantled
dismantle_wall(TRUE, TRUE)
//monkestation edit end

/turf/closed/wall/proc/deconstruction_hints(mob/user)
return span_notice("The outer plating is <b>welded</b> firmly in place.")

Expand Down Expand Up @@ -167,7 +212,7 @@

/turf/closed/wall/ex_act(severity, target)
if(target == src)
dismantle_wall(1,1)
dismantle_wall(TRUE, TRUE) //monkestation edit
return

switch(severity)
Expand All @@ -179,17 +224,16 @@
if(EXPLODE_HEAVY)
dismantle_wall(prob(50), TRUE)
if(EXPLODE_LIGHT)
if (prob(hardness))
dismantle_wall(0,1)
take_damage(150, BRUTE, BOMB) // less kaboom monkestation edit
if(!density)
..()


/turf/closed/wall/blob_act(obj/structure/blob/B)
if(prob(50))
dismantle_wall()
else
add_dent(WALL_DENT_HIT)
//monkestation edit start
take_damage(400, BRUTE, MELEE, FALSE)
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
//monkestation edit end

/turf/closed/wall/attack_paw(mob/living/user, list/modifiers)
user.changeNext_move(CLICK_CD_MELEE)
Expand All @@ -202,19 +246,14 @@
return
if(arm.bodypart_disabled)
return
if(prob(hardness))
playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE)
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
hulk_recoil(arm, user)
dismantle_wall(1)

else
playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
add_dent(WALL_DENT_HIT)
user.visible_message(span_danger("[user] smashes \the [src]!"), \
span_danger("You smash \the [src]!"), \
span_hear("You hear a booming smash!"))
//monkestation edit start
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
take_damage(400, BRUTE, MELEE, FALSE)
playsound(src, 'sound/effects/bang.ogg', 50, 1)
to_chat(user, span_notice("You punch the wall."))
hulk_recoil(arm, user)
return TRUE
//monkestation edit end

/**
*Deals damage back to the hulk's arm.
Expand Down Expand Up @@ -243,7 +282,7 @@
playsound(src, 'sound/weapons/genhit.ogg', 25, TRUE)
add_fingerprint(user)

/turf/closed/wall/attackby(obj/item/W, mob/user, params)
/turf/closed/wall/attackby(obj/item/attacking_item, mob/user, params) //monkestation edit
user.changeNext_move(CLICK_CD_MELEE)
if (!ISADVANCEDTOOLUSER(user))
to_chat(user, span_warning("You don't have the dexterity to do this!"))
Expand All @@ -256,27 +295,34 @@
add_fingerprint(user)

//the istype cascade has been spread among various procs for easy overriding
if(try_clean(W, user) || try_wallmount(W, user) || try_decon(W, user))
if(try_clean(attacking_item, user) || try_wallmount(attacking_item, user) || try_decon(attacking_item, user)) //monkestation edit
return

return ..()
return ..() || (attacking_item.attack_atom(src, user))

/turf/closed/wall/proc/try_clean(obj/item/W, mob/living/user, turf/T)
if(((user.istate & ISTATE_HARM)) || !LAZYLEN(dent_decals))
if(!(user.istate & ISTATE_HARM)) //monkestation edit
return FALSE

//monkestation edit start
if(W.tool_behaviour == TOOL_WELDER)
if(!W.tool_start_check(user, amount=0))
return FALSE
if(atom_integrity >= max_integrity)
to_chat(user, span_warning("[src] is intact!"))
return TRUE

to_chat(user, span_notice("You begin fixing dents on the wall..."))
if(W.use_tool(src, user, 0, volume=100))
if(iswallturf(src) && LAZYLEN(dent_decals))
to_chat(user, span_notice("You fix some dents on the wall."))
cut_overlay(dent_decals)
dent_decals.Cut()
if(!W.tool_start_check(user, amount=0))
to_chat(user, span_warning("You need more fuel to repair [src]!"))
return TRUE

to_chat(user, span_notice("You begin repairing [src]..."))
if(W.use_tool(src, user, 3 SECONDS, volume=100))
update_integrity(max_integrity)
to_chat(user, span_notice("You repair [src]."))
cut_overlay(dent_decals)
dent_decals.Cut()
return TRUE
return TRUE
//monkestation edit end
return FALSE

/turf/closed/wall/proc/try_wallmount(obj/item/W, mob/user)
Expand Down Expand Up @@ -308,9 +354,15 @@
return FALSE

/turf/closed/wall/singularity_pull(S, current_size)
..()
wall_singularity_pull(current_size)
. = ..()
//monkestation edit start
if(current_size >= STAGE_FIVE)
take_damage(300, armour_penetration=100) // LORD SINGULOTH CARES NOT FOR YOUR "ARMOR"
else if(current_size == STAGE_FOUR)
take_damage(150, armour_penetration=100)
//monkestation edit end

/* //MONKESTATION REMOVAL: Deprecated, obselete old code proc
/turf/closed/wall/proc/wall_singularity_pull(current_size)
if(current_size >= STAGE_FIVE)
if(prob(50))
Expand All @@ -319,6 +371,7 @@
if(current_size == STAGE_FOUR)
if(prob(30))
dismantle_wall()
*/

/turf/closed/wall/narsie_act(force, ignore_mobs, probability = 20)
. = ..()
Expand Down Expand Up @@ -358,7 +411,12 @@
return TRUE
return FALSE

/turf/closed/wall/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8))
//monkestation edit start
/turf/proc/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8)) // this only exists because turf code is terrible, monkestation
return

/turf/closed/wall/add_dent(denttype, x=rand(-8, 8), y=rand(-8, 8))
//monkestation edit end
if(LAZYLEN(dent_decals) >= MAX_DENT_DECALS)
return

Expand Down
29 changes: 28 additions & 1 deletion code/modules/power/singularity/emitter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
///stores the direction and orientation of the last projectile
var/last_projectile_params

//monkestation edit start
//Basic Emitters projectile characteristics
///damage modifier on walls
var/wall_dem_mod = 1
///can projectile hit walls
var/is_proj_hit_walls = FALSE
//monkestation edit end

/obj/machinery/power/emitter/Initialize(mapload)
. = ..()
RefreshParts()
Expand Down Expand Up @@ -87,10 +95,19 @@
var/fire_shoot_delay = 12 SECONDS
var/min_fire_delay = 2.4 SECONDS
var/power_usage = 350
//monkestation edit start
var/list/wall_mod_table = list(1, 1.25, 2.5, 5, 8.35) //infinite, 20, 10, 5, 3 hits respectively to destroy a normal wall, last two tiers, 10, 7 shots for r-walls
for(var/datum/stock_part/micro_laser/laser in component_parts)
max_fire_delay -= 2 SECONDS * laser.tier
min_fire_delay -= 0.4 SECONDS * laser.tier
fire_shoot_delay -= 2 SECONDS * laser.tier
var/parts_tier = laser.tier
if(obj_flags & EMAGGED)
parts_tier += 1
if(parts_tier >= 2)
is_proj_hit_walls = TRUE
wall_dem_mod = wall_mod_table[clamp(parts_tier, 0, LAZYLEN(wall_mod_table))]
//monkestation edit end
maximum_fire_delay = max_fire_delay
minimum_fire_delay = min_fire_delay
fire_delay = fire_shoot_delay
Expand Down Expand Up @@ -219,6 +236,15 @@

/obj/machinery/power/emitter/proc/fire_beam(mob/user)
var/obj/projectile/projectile = new projectile_type(get_turf(src))
//monkestation edit start
if(istype(projectile, /obj/projectile/beam/emitter/hitscan)) //TODO: LESS SNOWFLAKE CHECK
projectile.wall_dem_mod = wall_dem_mod
projectile.damage_walls = is_proj_hit_walls
if(obj_flags & EMAGGED)
take_damage((round(max_integrity/100 * 5)))
visible_message(span_warning("The [src] visibly buckles under overloaded pressure!"))

//monkestation edit end
playsound(src, projectile_sound, 50, TRUE)
if(prob(35))
sparks.start()
Expand Down Expand Up @@ -373,7 +399,8 @@
return FALSE
locked = FALSE
obj_flags |= EMAGGED
balloon_alert(user, "id lock shorted out")
balloon_alert(user, "id lock shorted out and lasers overloaded") //monkestation edit
RefreshParts() //monkestation edit
return TRUE


Expand Down
11 changes: 11 additions & 0 deletions code/modules/projectiles/projectile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
/// We are flagged PHASING temporarily to not stop moving when we Bump something but want to keep going anyways.
var/temporary_unstoppable_movement = FALSE

//monkestation edit start
/// Do we damage walls?
var/damage_walls = FALSE
/// demolition mod on walls
var/wall_dem_mod = 1
//monkestation edit end

/** PROJECTILE PIERCING
* WARNING:
* Projectile piercing MUST be done using these variables.
Expand Down Expand Up @@ -297,6 +304,10 @@
if(damage > 0 && (damage_type == BRUTE || damage_type == BURN) && iswallturf(target_turf) && prob(75))
var/turf/closed/wall/target_wall = target_turf
target_wall.add_dent(WALL_DENT_SHOT, hitx, hity)
//monkestation edit start
if(damage_walls)
target_wall.take_damage(damage * wall_dem_mod, damage_type, armor_flag, armour_penetration = 100)
//monkestation edit end

return BULLET_ACT_HIT

Expand Down
1 change: 1 addition & 0 deletions code/modules/projectiles/projectile/beams.dm
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
impact_light_intensity = 7
impact_light_outer_range = 2.5
impact_light_color_override = COLOR_LIME
range = 255 //come on, have some fun now! monkestation edit

/obj/projectile/beam/lasertag
name = "laser tag beam"
Expand Down
Loading