From 6f20e1f4bec7ded96610f85d587083c940e075e0 Mon Sep 17 00:00:00 2001 From: ShiftyRail <31417754+ShiftyRail@users.noreply.github.com> Date: Tue, 15 Mar 2022 22:42:00 +0000 Subject: [PATCH] Revert breakable objects for now. (#32234) * revert * why didn't this get reverted? --- code/_onclick/item_attack.dm | 2 +- code/_onclick/mindUI/blob.dm | 4 +- .../factions/bloodcult/bloodcult_buildings.dm | 4 +- code/game/atoms_movable.dm | 2 +- code/game/gamemodes/blob/blobs/core.dm | 12 +- code/game/gamemodes/blob/blobs/factory.dm | 2 +- code/game/gamemodes/blob/blobs/node.dm | 6 +- code/game/gamemodes/blob/blobs/resource.dm | 2 +- code/game/gamemodes/blob/blobs/shield.dm | 2 +- code/game/gamemodes/blob/theblob.dm | 10 +- code/game/gamemodes/endgame/xmas/snowman.dm | 2 +- code/game/gamemodes/events/biomass.dm | 2 +- code/game/machinery/atmoalter/canister.dm | 2 +- code/game/machinery/bees_apiary.dm | 4 +- code/game/machinery/bots/bots.dm | 12 +- code/game/machinery/bots/buttbot.dm | 2 +- code/game/machinery/bots/cleanbot.dm | 2 +- code/game/machinery/bots/draculabot.dm | 2 +- code/game/machinery/bots/ed209bot.dm | 2 +- code/game/machinery/bots/farmbot.dm | 2 +- code/game/machinery/bots/floorbot.dm | 2 +- code/game/machinery/bots/medbot.dm | 2 +- code/game/machinery/bots/mulebot.dm | 6 +- code/game/machinery/bots/secbot.dm | 4 +- code/game/machinery/camera/camera.dm | 18 +- code/game/machinery/deployable.dm | 19 +- code/game/machinery/doors/mineral.dm | 4 +- code/game/machinery/doors/windowdoor.dm | 8 +- code/game/machinery/shieldgen.dm | 10 +- code/game/machinery/turrets.dm | 21 +- code/game/machinery/vending.dm | 4 +- code/game/mecha/mecha.dm | 27 +- code/game/objects/breakable.dm | 299 ------------------ code/game/objects/effects/aliens.dm | 6 +- code/game/objects/items.dm | 9 +- code/game/objects/items/breakable.dm | 280 ++++++++++++++++ code/game/objects/items/breakable_test.dm | 130 ++++++++ code/game/objects/items/devices/flashlight.dm | 33 +- .../objects/items/weapons/storage/storage.dm | 5 +- code/game/objects/objs.dm | 8 +- .../structures/crates_lockers/closets.dm | 2 +- code/game/objects/structures/displaycase.dm | 2 +- code/game/objects/structures/flora/flora.dm | 4 +- code/game/objects/structures/grille.dm | 2 +- code/game/objects/structures/inflatable.dm | 16 +- code/game/objects/structures/lamarr_cage.dm | 2 +- code/game/objects/structures/mannequin.dm | 4 +- .../stool_bed_chair_nest/alien_nests.dm | 2 +- code/game/objects/structures/support_rail.dm | 2 +- code/game/objects/structures/tables_racks.dm | 4 +- .../objects/structures/vehicles/vehicle.dm | 2 +- code/game/objects/structures/window.dm | 2 +- code/modules/flufftext/Hallucination.dm | 2 +- code/modules/hydroponics/hydro_tray.dm | 14 +- .../modules/hydroponics/hydro_tray_process.dm | 36 +-- .../hydroponics/spreading/spreading.dm | 34 +- .../hydroponics/spreading/spreading_growth.dm | 8 +- code/modules/library/lib_items.dm | 2 +- code/modules/mining/mine_structures.dm | 20 -- .../living/carbon/human/human_attackhand.dm | 2 +- .../hostile/giant_spider/effects.dm | 2 +- code/modules/power/solars/panel.dm | 10 +- code/modules/reagents/Chemistry-Reagents.dm | 4 +- .../reagents/reagent_containers/glass.dm | 24 +- code/modules/reagents/reagent_dispenser.dm | 16 +- code/modules/recycling/disposal.dm | 2 +- code/modules/research/server.dm | 2 +- .../tools/anomaly_container.dm | 2 +- code/modules/spacepods/spacepods.dm | 4 +- maps/RandomZLevels/hive.dm | 2 +- maps/metaclub.dmm | 2 +- maps/randomvaults/objects.dm | 2 +- vgstation13.dme | 3 +- 73 files changed, 628 insertions(+), 582 deletions(-) delete mode 100644 code/game/objects/breakable.dm create mode 100644 code/game/objects/items/breakable.dm create mode 100644 code/game/objects/items/breakable_test.dm diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index d697096e870..33f31e7860f 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -239,7 +239,7 @@ //Break the item if applicable. if(power && (I.breakable_flags & BREAKABLE_AS_MELEE) && (I.breakable_flags & BREAKABLE_MOB)) - take_damage(min(power, BREAKARMOR_MEDIUM), skip_break = TRUE, mute = FALSE) //Cap recoil damage at BREAKARMOR_MEDIUM to avoid a powerful weapon also needing really strong armor to avoid breaking apart when used. Be verbose about the item being damaged if applicable. + take_damage(min(power, BREAKARMOR_MEDIUM), FALSE, skip_break = TRUE) //Cap recoil damage at BREAKARMOR_MEDIUM to avoid a powerful weapon also needing really strong armor to avoid breaking apart when used. Be verbose about the item being damaged if applicable. try_break(hit_atom = M) //Break the item and spill any reagents onto the target. diff --git a/code/_onclick/mindUI/blob.dm b/code/_onclick/mindUI/blob.dm index b76435e5a57..3d86df14592 100644 --- a/code/_onclick/mindUI/blob.dm +++ b/code/_onclick/mindUI/blob.dm @@ -529,11 +529,11 @@ gauge_state = "healthcrit" var/image/gauge = image('icons/ui/blob/18x200.dmi', src, gauge_state) var/matrix/gauge_matrix = matrix() - gauge_matrix.Scale(1,M.blob_core.health/M.blob_core.maxHealth) + gauge_matrix.Scale(1,M.blob_core.health/M.blob_core.maxhealth) gauge.transform = gauge_matrix gauge.layer = MIND_UI_BUTTON gauge.pixel_x = 3 - gauge.pixel_y = round(-79 + 100 * (M.blob_core.health/M.blob_core.maxHealth)) + gauge.pixel_y = round(-79 + 100 * (M.blob_core.health/M.blob_core.maxhealth)) overlays += gauge var/image/cover = image(icon, src, "coverRIGHT") diff --git a/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm b/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm index ed83ce42f1d..303c28d9e0d 100644 --- a/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm +++ b/code/datums/gamemode/factions/bloodcult/bloodcult_buildings.dm @@ -3,8 +3,8 @@ density = 1 anchored = 1 icon = 'icons/obj/cult.dmi' - health = 50 - maxHealth = 50 + var/health = 50 + var/maxHealth = 50 var/sound_damaged = null var/sound_destroyed = null var/conceal_cooldown = 0 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f5381604b16..7ab11319b52 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -567,7 +567,7 @@ throwing = 0 . = 0 -/atom/movable/proc/throw_at(atom/target, range, speed, override = TRUE, var/fly_speed = 0) //fly_speed parameter: if 0, does nothing. Otherwise, changes how fast the object flies WITHOUT affecting damage! +/atom/movable/proc/throw_at(atom/target, range, speed, override = 1, var/fly_speed = 0) //fly_speed parameter: if 0, does nothing. Otherwise, changes how fast the object flies WITHOUT affecting damage! set waitfor = FALSE if(!target || !src) return 0 diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index e5efb77fae3..595235c4876 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -3,7 +3,7 @@ icon_state = "core" desc = "A part of a blob. It is large and pulsating." health = 200 - maxHealth = 200 + maxhealth = 200 fire_resist = 2 custom_process=1 destroy_sound = "sound/effects/blobkill.ogg" @@ -86,8 +86,8 @@ overmind.add_points(points_to_collect) last_resource_collection = world.time - if(health < maxHealth) - health = min(maxHealth, health + 1) + if(health < maxhealth) + health = min(maxhealth, health + 1) update_icon() if(asleep) @@ -228,7 +228,7 @@ if (looks == "AME_new") icon_state = "core" - var/hurt_percentage = round((health * 100) / maxHealth) + var/hurt_percentage = round((health * 100) / maxhealth) if (hurt_percentage < 25) icon_state = "core_fuck" else if (hurt_percentage < 50) @@ -252,8 +252,8 @@ /obj/effect/blob/update_icon(var/spawnend = 0) if(icon_size == 64) - if(health < maxHealth) - var/hurt_percentage = round((health * 100) / maxHealth) + if(health < maxhealth) + var/hurt_percentage = round((health * 100) / maxhealth) var/hurt_icon switch(hurt_percentage) if(0 to 25) diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index b44c965e46e..44001d719b5 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -3,7 +3,7 @@ icon_state = "factory" desc = "A part of a blob. It makes the sound of organic tissue being torn." health = 100 - maxHealth = 100 + maxhealth = 100 fire_resist = 2 var/list/spores = list() var/max_spores = 2 diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index 23138d2bbe7..03734106565 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -3,7 +3,7 @@ icon_state = "node" desc = "A part of a blob." health = 100 - maxHealth = 100 + maxhealth = 100 fire_resist = 2 custom_process=1 layer = BLOB_NODE_LAYER @@ -51,8 +51,8 @@ for(var/i = 1; i < 8; i += i) Pulse(5, i, overmind) - if(health < maxHealth) - health = min(maxHealth, health + 1) + if(health < maxhealth) + health = min(maxhealth, health + 1) update_icon() /obj/effect/blob/node/run_action() diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm index 8c9c20f7e06..d5fbb999b9c 100644 --- a/code/game/gamemodes/blob/blobs/resource.dm +++ b/code/game/gamemodes/blob/blobs/resource.dm @@ -3,7 +3,7 @@ icon_state = "resource" desc = "A part of a blob. It makes a slow, deep breathing sound." health = 30 - maxHealth = 30 + maxhealth = 30 fire_resist = 2 var/resource_delay = 0 spawning = 0 diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index e72f86b517a..0e1fd659fa3 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -3,7 +3,7 @@ icon_state = "strong" desc = "A dense part of a blob." health = 75 - maxHealth = 75 + maxhealth = 75 fire_resist = 2 layer = BLOB_SHIELD_LAYER spawning = 0 diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 8756485ef16..1f09c066db0 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -20,8 +20,8 @@ var/list/blob_overminds = list() penetration_dampening = 17 mouse_opacity = 1 pass_flags_self = PASSBLOB - health = 20 - maxHealth = 20 + var/health = 20 + var/maxhealth = 20 var/health_timestamp = 0 var/brute_resist = 4 var/fire_resist = 1 @@ -207,8 +207,8 @@ var/list/blob_overminds = list() /obj/effect/blob/update_icon(var/spawnend = 0) if(icon_size == 64) - if(health < maxHealth) - var/hurt_percentage = round((health * 100) / maxHealth) + if(health < maxhealth) + var/hurt_percentage = round((health * 100) / maxhealth) var/hurt_icon switch(hurt_percentage) if(0 to 25) @@ -407,7 +407,7 @@ var/list/blob_looks_player = list(//Options available to players qdel(src) /obj/effect/blob/proc/update_health() - if(asleep && (health < maxHealth)) + if(asleep && (health < maxhealth)) for (var/obj/effect/blob/B in range(7,src)) B.asleep = FALSE if(!dying && (health <= 0)) diff --git a/code/game/gamemodes/endgame/xmas/snowman.dm b/code/game/gamemodes/endgame/xmas/snowman.dm index 1dd1b269b82..d89c112c910 100644 --- a/code/game/gamemodes/endgame/xmas/snowman.dm +++ b/code/game/gamemodes/endgame/xmas/snowman.dm @@ -7,7 +7,7 @@ density = TRUE var/obj/item/clothing/head/hat = null var/obj/item/carrot = null - health = 40 + var/health = 40 /obj/structure/snowman/Destroy() qdel(hat) diff --git a/code/game/gamemodes/events/biomass.dm b/code/game/gamemodes/events/biomass.dm index 09d7c2dcb81..0e71aad7232 100644 --- a/code/game/gamemodes/events/biomass.dm +++ b/code/game/gamemodes/events/biomass.dm @@ -13,7 +13,7 @@ mouse_opacity = 1 var/energy = 0 var/obj/effect/biomass_controller/master = null - health = 15 + var/health = 15 /obj/effect/biomass/Destroy() unreferenceMaster() diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 5f32d025ed8..596e7118b29 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -11,7 +11,7 @@ icon = 'icons/obj/atmos.dmi' icon_state = "yellow" density = 1 - health = 100.0 + var/health = 100.0 flags = FPRINT siemens_coefficient = 1 diff --git a/code/game/machinery/bees_apiary.dm b/code/game/machinery/bees_apiary.dm index fd8beb9359a..fabef2333ab 100644 --- a/code/game/machinery/bees_apiary.dm +++ b/code/game/machinery/bees_apiary.dm @@ -518,7 +518,7 @@ var/list/apiaries_list = list() var/base_icon_state = "apiary-wild-inprogress" var/prefix = "" var/remaining_work = 10 - health = 20 + var/health = 20 /obj/structure/wild_apiary/New(turf/loc, var/p = "") prefix = p @@ -581,7 +581,7 @@ var/list/apiaries_list = list() cycledelay = 100 - health = 100 + var/health = 100 //Cannot normally harvest the apiary other than by breaking it wild = APIARY_WILDERNESS_WILD diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index f0ec5bda925..4b0e4234ed2 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -30,8 +30,8 @@ var/obj/item/weapon/card/id/botcard // the ID card that the bot "holds" var/mob/living/simple_animal/hostile/pulse_demon/PD_occupant // for when they take over them var/on = 1 - health = 0 //do not forget to set health for your bot! - maxHealth = 0 + var/health = 0 //do not forget to set health for your bot! + var/maxhealth = 0 var/fire_dam_coeff = 1.0 var/brute_dam_coeff = 1.0 var/open = 0//Maint panel @@ -599,8 +599,8 @@ /obj/machinery/bot/examine(mob/user) ..() - if (src.health < maxHealth) - if (src.health > maxHealth/3) + if (src.health < maxhealth) + if (src.health > maxhealth/3) to_chat(user, "[src]'s parts look loose.") else to_chat(user, "[src]'s parts look very loose!") @@ -660,11 +660,11 @@ to_chat(user, "Maintenance panel is now [open ? "opened" : "closed"].") updateUsrDialog() else if(iswelder(W) && user.a_intent != I_HURT) - if(health < maxHealth) + if(health < maxhealth) if(open) var/obj/item/tool/weldingtool/WT = W if(WT.remove_fuel(0)) - health = min(maxHealth, health+10) + health = min(maxhealth, health+10) user.visible_message("[user] repairs [src]!","You repair [src]!") else to_chat(user, "Unable to repair with the maintenance panel closed.") diff --git a/code/game/machinery/bots/buttbot.dm b/code/game/machinery/bots/buttbot.dm index f19f0508a9a..af23959a227 100644 --- a/code/game/machinery/bots/buttbot.dm +++ b/code/game/machinery/bots/buttbot.dm @@ -17,7 +17,7 @@ Here it is: Buttbot. anchored = 0 //weight = 1.0E7 health = 25 - maxHealth = 25 + maxhealth = 25 var/buttchance = 80 //Like an 80% chance of it working. It's just a butt with an arm in it. var/sincelastfart = 0 var/det_chance diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 10edf8028a9..717b4beea4b 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -25,7 +25,7 @@ anchored = 0 //weight = 1.0E7 health = 25 - maxHealth = 25 + maxhealth = 25 var/cleaning = 0 var/screwloose = 0 var/oddbutton = 0 diff --git a/code/game/machinery/bots/draculabot.dm b/code/game/machinery/bots/draculabot.dm index ff53e20d996..e8fe0eb6f91 100644 --- a/code/game/machinery/bots/draculabot.dm +++ b/code/game/machinery/bots/draculabot.dm @@ -14,7 +14,7 @@ on = 0 anchored = 0 health = 40 - maxHealth = 20 + maxhealth = 20 req_access = list(access_medical) var/currently_drawing_blood = 0 //One patient at a time. var/quiet = 0 diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 2691da07cbe..a5b15bea71c 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -9,7 +9,7 @@ // weight = 1.0E7 req_one_access = list(access_security, access_forensics_lockers) health = 100 - maxHealth = 100 + maxhealth = 100 fire_dam_coeff = 0.7 brute_dam_coeff = 0.5 steps_per = 2 diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm index c787cee31c1..83b0782e11d 100644 --- a/code/game/machinery/bots/farmbot.dm +++ b/code/game/machinery/bots/farmbot.dm @@ -34,7 +34,7 @@ density = 1 anchored = 0 health = 50 - maxHealth = 50 + maxhealth = 50 req_access =list(access_hydroponics) bot_flags = BOT_DENSE|BOT_NOT_CHASING diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index 230ddaa85d7..9caf176e5a4 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -40,7 +40,7 @@ var/global/list/floorbot_targets=list() density = 0 anchored = 0 health = 25 - maxHealth = 25 + maxhealth = 25 auto_patrol = 0 // set to make bot automatically patrol bot_flags = BOT_PATROL|BOT_BEACON|BOT_NOT_CHASING|BOT_SPACEWORTHY|BOT_CONTROL var/amount = 10 diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 1c30a88c88a..8c43b387eb5 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -34,7 +34,7 @@ var/list/firstaid_exceptions = list( density = 0 anchored = 0 health = 20 - maxHealth = 20 + maxhealth = 20 req_access =list(access_medical) bot_flags = BOT_NOT_CHASING|BOT_CONTROL can_take_pai = TRUE diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 621f7d39570..e28a5b1364c 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -26,7 +26,7 @@ var/global/mulebot_count = 0 anchored = 1 animate_movement=1 health = 150 //yeah, it's tougher than ed209 because it is a big metal box with wheels --rastaf0 - maxHealth = 150 + maxhealth = 150 fire_dam_coeff = 0.7 brute_dam_coeff = 0.5 can_take_pai = TRUE @@ -152,8 +152,8 @@ var/global/mulebot_count = 0 updateDialog() else if (I.is_wrench(user) && user.a_intent != I_HURT) - if (src.health < maxHealth) - src.health = min(maxHealth, src.health+25) + if (src.health < maxhealth) + src.health = min(maxhealth, src.health+25) user.visible_message( "[user] repairs [src]!", "You repair [src]!" diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 785d624ab64..602fb033079 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -9,7 +9,7 @@ density = 0 anchored = 0 health = 25 - maxHealth = 25 + maxhealth = 25 fire_dam_coeff = 0.7 brute_dam_coeff = 0.5 // weight = 1.0E7 @@ -572,7 +572,7 @@ Auto Patrol: []"}, icon_state = "cheapsky0" icon_initial = "cheapsky" health = 15 - maxHealth = 15 + maxhealth = 15 //Cheapsky Construction /obj/item/weapon/secbot_assembly/cheapsky diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index cad3da71fd7..57b9d09787f 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -40,7 +40,7 @@ var/list/camera_names=list() var/hear_voice = 0 var/vision_flags = SEE_SELF //Only applies when viewing the camera through a console. - health = CAMERA_MAX_HEALTH + var/health = CAMERA_MAX_HEALTH hack_abilities = list( /datum/malfhack_ability/oneuse/overload_quiet, @@ -48,10 +48,6 @@ var/list/camera_names=list() /datum/malfhack_ability/oneuse/camera_upgrade ) - breakable_flags = BREAKABLE_UNARMED //Custom behavior already exists for armed cases. - damage_armor = CAMERA_MIN_WEAPON_DAMAGE - damage_resist = 0 - /obj/machinery/camera/flawless failure_chance = 0 @@ -322,23 +318,19 @@ var/list/camera_messages = list() to_chat(user, "\The [W] does no damage to [src].") visible_message("[user] hits [src] with [W]. It's not very effective.") return - if(W.hitsound) - playsound(src, W.hitsound, 50, 1) visible_message("[user] hits [src] with [W].") take_damage(W.force) -/obj/machinery/camera/damaged_updates() +/obj/machinery/camera/proc/take_damage(var/amount) + if(amount <= 0) + return triggerCameraAlarm() + health -= amount if(health <= CAMERA_DEACTIVATE_HEALTH && status) deactivate() - -/obj/machinery/camera/try_break() if(health <= 0) spark(src) dismantle() - return TRUE - else - return FALSE /obj/machinery/camera/Topic(href, href_list) if(..()) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 7a24e7d745b..1e9db2c48a4 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -12,8 +12,8 @@ density = TRUE icon_state = "barrier0" pass_flags_self = PASSTABLE - health = 140 - maxHealth = 140 + var/health = 140 + var/maxhealth = 140 machine_flags = EMAGGABLE @@ -61,12 +61,12 @@ visible_message("[src] has been hit by [user] with [W].") user.delayNextAttack(1 SECONDS) user.do_attack_animation(src, user) - take_damage(W.force, damage_type = W.damtype) + take_damage(W.force, W.damtype) /obj/machinery/deployable/barrier/bullet_act(var/obj/item/projectile/Proj) . = ..() if(Proj.damage) - take_damage(Proj.damage, damage_type = Proj.damage_type) + take_damage(Proj.damage, Proj.damage_type) /obj/machinery/deployable/barrier/ex_act(var/severity) switch(severity) @@ -99,13 +99,10 @@ explosion(loc,-1,-1,0) qdel(src) -/obj/machinery/deployable/barrier/take_damage(incoming_damage, damage_type = BRUTE, skip_break, mute) //Custom take_damage() proc because of unimplemented general object damage resistances. +/obj/machinery/deployable/barrier/proc/take_damage(var/amount, var/kind = BRUTE) var/modifier = 1 - if(damage_type == BRUTE) + if(kind == BRUTE) modifier = 0.75 - health -= incoming_damage * modifier - try_break() - -/obj/machinery/deployable/barrier/try_break() + health -= amount * modifier if(health <= 0) - explode() \ No newline at end of file + explode() diff --git a/code/game/machinery/doors/mineral.dm b/code/game/machinery/doors/mineral.dm index 5e7a317091b..37887b3c3f5 100644 --- a/code/game/machinery/doors/mineral.dm +++ b/code/game/machinery/doors/mineral.dm @@ -335,8 +335,8 @@ explosion_block = 1 prefix = "cult" animation_delay = 0 - health = 100 - maxHealth = 100 + var/health = 100 + var/maxHealth = 100 /obj/machinery/door/mineral/cult/New() ..() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 076803933d0..bf2b2fbb021 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/doors/windoor.dmi' icon_state = "left" var/base_state = "left" - health = 60 + var/health = 60 visible = 0.0 use_power = 0 flow_flags = ON_BORDER @@ -181,16 +181,14 @@ operating = 0 return TRUE -/obj/machinery/door/window/try_break() +/obj/machinery/door/window/proc/take_damage(var/damage) + health = max(0, health - damage) if(health <= 0) playsound(src, "shatter", 70, 1) new shard_type(loc) new /obj/item/stack/cable_coil(loc, 2) eject_electronics() qdel(src) - return TRUE - else - return FALSE /obj/machinery/door/window/bullet_act(var/obj/item/projectile/Proj) if(Proj.damage) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index d6b18bdb63f..ab08572a9d5 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -8,8 +8,8 @@ anchored = 1 ghost_read = 0 ghost_write = 0 - maxHealth = 200 - health = 200 //The shield can only take so much beating (prevents perma-prisons) + var/const/max_health = 200 + var/health = max_health //The shield can only take so much beating (prevents perma-prisons) /obj/machinery/shield/acidable() return 0 @@ -134,8 +134,8 @@ anchored = 0 pressure_resistance = 2*ONE_ATMOSPHERE req_access = list(access_engine) - maxHealth = 100 - health = 100 + var/const/max_health = 100 + var/health = max_health var/active = 0 var/malfunction = 0 //Malfunction causes parts of the shield to slowly dissapate var/list/deployed_shields = list() @@ -275,7 +275,7 @@ if(!src || !coil) return coil.use(1) - health = maxHealth + health = max_health malfunction = 0 to_chat(user, "You repair the [src]!") update_icon() diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 50d191c0ac9..68f2cf8b0f4 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -10,7 +10,7 @@ density = 1 var/faction = null //No shooting our buddies! var/shootsilicons = 0 //You can make turrets that shoot those robot pricks (except AIs)! You can't toggle this at the control console - health = 80 // the turret's health + var/health = 80 // the turret's health var/obj/machinery/turretcover/cover = null // the cover that is covering this turret var/raising = 0 // if the turret is currently opening or closing its cover var/wasvalid = 0 @@ -18,7 +18,7 @@ var/reqpower = 350 // Amount of power per shot var/shot_delay = 30 //3 seconds between shots - var/last_shot + var/last_shot var/fire_twice = 0 use_power = 1 // this turret uses and requires power @@ -61,7 +61,7 @@ if(stat & BROKEN) icon_state = "grey_target_prism" else - if( powered() ) + if( powered() ) if (src.enabled && !(stat & FORCEDISABLE)) if(istype(installed,/obj/item/weapon/gun/energy/gun)) var/obj/item/weapon/gun/energy/gun/EG = installed @@ -175,7 +175,7 @@ return if(!check_target(cur_target)) //if current target fails target check - if(fire_twice) + if(fire_twice) shootAt(cur_target) cur_target = get_new_target() else @@ -222,7 +222,7 @@ playsound(src, installed.fire_sound, 75, 1) - last_shot = world.time + last_shot = world.time var/obj/item/projectile/A if(istype(installed, /obj/item/weapon/gun/projectile/roulette_revolver)) var/obj/item/weapon/gun/projectile/roulette_revolver/R = installed @@ -361,7 +361,7 @@ if(!A.eyeobj) A.make_eyeobj() A.eyeobj.forceMove(get_turf(src)) - A.current = src + A.current = src controlling_malf = A if(stat & (NOPOWER|BROKEN|FORCEDISABLE)) return @@ -572,7 +572,7 @@ var/list/exclude = list() var/atom/cur_target var/scan_range = 7 - health = 40 + var/health = 40 var/list/scan_for = list("human"=0,"cyborg"=0,"mecha"=0,"alien"=1) var/on = 0 icon = 'icons/obj/turrets.dmi' @@ -592,6 +592,13 @@ qdel (src) return +/obj/structure/turret/gun_turret/proc/take_damage(damage) + src.health -= damage + if(src.health<=0) + qdel (src) + return + + /obj/structure/turret/gun_turret/bullet_act(var/obj/item/projectile/Proj) src.take_damage(Proj.damage) return ..() diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index ffef910cb26..a074e2d899a 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -21,8 +21,8 @@ var/global/num_vending_terminals = 1 density = 1 layer = OPEN_DOOR_LAYER //This is below BELOW_OBJ_LAYER because vendors can contain crates/closets pass_flags_self = PASSMACHINE - health = 100 - maxHealth = 100 //Kicking feature + var/health = 100 + var/maxhealth = 100 //Kicking feature var/active = 1 //No sales pitches if off! var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index fa120528e80..0c27961ccba 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -28,7 +28,7 @@ var/step_in = 10 //make a step in step_in/10 sec. var/dir_in = SOUTH//What direction will the mech face when entered/powered on? Defaults to South. var/step_energy_drain = 10 //How much energy we consume in a single step - health = 300 //health is health + var/health = 300 //health is health var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. //the values in this list show how much damage will pass through, not how much will be absorbed. var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1) @@ -534,12 +534,12 @@ //////// Health related procs //////// //////////////////////////////////////// -/obj/mecha/take_damage(incoming_damage, damage_type = "brute", skip_break, mute) - if(incoming_damage) - var/damage = absorbDamage(incoming_damage, damage_type) +/obj/mecha/proc/take_damage(amount, type="brute") + if(amount) + var/damage = absorbDamage(amount,type) health -= damage update_health() - log_append_to_last("Took [damage] points of damage. Damage type: \"[damage_type]\".",1) + log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1) return /obj/mecha/proc/absorbDamage(damage,damage_type) @@ -548,6 +548,7 @@ /obj/mecha/proc/dynabsorbdamage(damage,damage_type) return damage*(listgetindex(damage_absorption,damage_type) || 1) + /obj/mecha/proc/update_health() if(src.health > 0) spark(src, 2, FALSE) @@ -662,7 +663,7 @@ return if(istype(Proj, /obj/item/projectile/beam/pulse)) ignore_threshold = 1 - src.take_damage(Proj.damage, damage_type = Proj.flag) + src.take_damage(Proj.damage,Proj.flag) src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) Proj.on_hit(src) return @@ -712,13 +713,13 @@ */ /obj/mecha/blob_act() - take_damage(30, damage_type = "brute") + take_damage(30, "brute") return /obj/mecha/emp_act(severity) if(get_charge()) cell.emp_act(severity*1.25) - take_damage(50 / severity, damage_type = "energy") + take_damage(50 / severity,"energy") src.log_message("EMP detected",1) check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) for(var/obj/item/mecha_parts/mecha_equipment/M in equipment) @@ -728,7 +729,7 @@ /obj/mecha/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature>src.max_temperature) src.log_message("Exposed to dangerous temperature.",1) - src.take_damage(5, damage_type = "fire") + src.take_damage(5,"fire") src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL)) return @@ -747,7 +748,7 @@ else src.occupant_message("[user] hits [src] with [W].") user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") - src.take_damage(W.force, damage_type = W.damtype) + src.take_damage(W.force,W.damtype) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return @@ -918,7 +919,7 @@ else src.occupant_message("[user] hits [src] with [W].") user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") - src.take_damage(W.force, damage_type = W.damtype) + src.take_damage(W.force,W.damtype) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) */ return @@ -2092,7 +2093,7 @@ /obj/mecha/apply_beam_damage(var/obj/effect/beam/B) // Actually apply damage - take_damage(B.get_damage(), damage_type = "emitter laser") + take_damage(B.get_damage(), "emitter laser") /proc/mech_integrity_to_icon_state(var/integrity_ratio) switch(integrity_ratio) @@ -2222,7 +2223,7 @@ if(mecha.cabin_air && mecha.cabin_air.return_volume()>0) mecha.cabin_air.temperature = min(6000+T0C, mecha.cabin_air.return_temperature()+rand(10,15)) if(mecha.cabin_air.return_temperature()>mecha.max_temperature/2) - mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.return_temperature(),0.1), damage_type = "fire") + mecha.take_damage(4/round(mecha.max_temperature/mecha.cabin_air.return_temperature(),0.1),"fire") if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum mecha.pr_int_temp_processor.stop() if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank diff --git a/code/game/objects/breakable.dm b/code/game/objects/breakable.dm deleted file mode 100644 index df9d2ce20fd..00000000000 --- a/code/game/objects/breakable.dm +++ /dev/null @@ -1,299 +0,0 @@ -/////////////////////// -// Breakable Objects // -// by Hinaichigo // -/////////////////////// - -/obj - //Breakability: - var/health //Structural integrity of the object. If breakable_flags are set, at 0, the object breaks. - var/maxHealth //Maximum structural integrity of the object. - var/breakable_flags //Flags for different situations the object can break in. See breakable_defines.dm for the full list and explanations of each. - var/damage_armor //Attacks of this much damage or below will glance off. - var/damage_resist //Attacks stronger than damage_armor will have their damage reduced by this much. - var/list/breakable_exclude //List of objects that won't be used to hit the object even on harm intent, so as to allow for other interactions. - //Fragmentation: - var/list/breakable_fragments //List of objects that will be produced when the object is broken apart. eg. /obj/item/weapon/shard. - var/list/fragment_amounts //List of the numbers of fragments of each object type in breakable_fragments to be dropped. Should be either null (1 each) or the same length as breakable_fragments. - //Text: - var/damaged_examine_text //Addendum to the description when the object is damaged. eg. damaged_examine_text of "It is dented." - var/take_hit_text //String or list of strings when the object is damaged but not fully broken. eg. "chipping" becomes "..., chipping it!" - var/take_hit_text2 //String or list of strings for contexts like "cracks" becomes "the ... cracks!" - var/glances_text //String or list of strings when the object is attacked but the attack glances off. eg. "bounces" becomes "but it bounces off!" - var/breaks_text //Visible message when the object breaks. eg. "breaks apart" - //Sounds: - var/breaks_sound //Audible sound when the object breaks apart. Defaults to damaged_sound if unset. - var/damaged_sound //Audible sound when the object is damaged by an attack, but not fully broken. Defaults to glanced_sound if unset. - var/glanced_sound //Audible sound when the object recives a glancing attack not strong enough to damage it. - -/obj/New() - ..() - if(breakable_flags) //Initialize health and maxHealth to the same value if only one is specified. - if(isnull(health) && maxHealth) - health = maxHealth - else if(isnull(maxHealth) && health) - maxHealth = health - -/obj/proc/on_broken(var/datum/throwparams/propelparams, var/atom/hit_atom) //Called right before an object breaks. - //Drop and and propel any fragments: - drop_fragments(propelparams) - //Drop and propel any contents: - drop_contents(propelparams) - //Spill any reagents: - spill_reagents(hit_atom) - if(breaks_text) - visible_message("\The [src] [breaks_text]!") - if(breaks_sound) - playsound(src, breaks_sound, 50, 1) - else if(damaged_sound) - playsound(src, damaged_sound, 50, 1) - -/obj/proc/drop_fragments(var/datum/throwparams/propelparams) //Drop the object's fragments and propel them if applicable with propelparams. - if(breakable_fragments?.len) - var/oneeach=(isnull(fragment_amounts) || breakable_fragments.len != fragment_amounts.len) //default to 1 of each fragment type if fragment_amounts isn't specified or there's a length mismatch - var/numtodrop - var/thisfragment - for(var/frag_ind in 1 to breakable_fragments.len) - if(oneeach) - numtodrop=1 - else - numtodrop=fragment_amounts[frag_ind] - thisfragment=breakable_fragments[frag_ind] - for(var/n in 1 to numtodrop) - var/obj/O = new thisfragment (get_turf(src)) - //Transfer fingerprints, fibers, and bloodstains to the fragment. - transfer_fingerprints(src,O) - transfer_obj_blood_data(src,O) - if(propelparams)//Propel the fragment if specified. - if(propelparams.throw_target && propelparams.throw_range && propelparams.throw_speed) - O.throw_at(propelparams.throw_target, propelparams.throw_range, propelparams.throw_speed, propelparams.throw_override, propelparams.throw_fly_speed) - -/obj/proc/drop_contents(var/datum/throwparams/propelparams) //Drop the contents of the object and propel them if the object itself received a propulsive blow. - if(contents.len) - for(var/obj/item/thiscontent in contents) - thiscontent.forceMove(src.loc) - if(propelparams) - if(propelparams.throw_target && propelparams.throw_range && propelparams.throw_speed) //Propel the content if specified. - thiscontent.throw_at(propelparams.throw_target, propelparams.throw_range, propelparams.throw_speed, propelparams.throw_override, propelparams.throw_fly_speed) - -/obj/proc/spill_reagents(var/atom/hit_atom) //Spill any reagents contained within the object onto the floor, and the atom it hit when it broke, if applicable. - if(!isnull(reagents)) - if(!isnull(hit_atom) && hit_atom != get_turf(src)) //If it hit something other than the floor, spill it onto that. - reagents.reaction(hit_atom, TOUCH) - reagents.reaction(get_turf(src), TOUCH) //Then spill it onto the floor. - -/obj/proc/take_damage(var/incoming_damage, var/damage_type = BRUTE, var/skip_break = FALSE, var/mute = TRUE) - var/thisdmg = (incoming_damage > max(damage_armor, damage_resist)) * (incoming_damage - damage_resist) //damage is 0 if the incoming damage is less than either damage_armor or damage_resist, to prevent negative damage by weak attacks - health -= thisdmg - play_hit_sounds(thisdmg) - if(thisdmg) - if(health > 0) //Only if the object isn't ready to break. - message_take_hit(mute) - damaged_updates() - if(!skip_break) - try_break() - return thisdmg //return the amount of damage taken - -/obj/proc/play_hit_sounds(var/thisdmg, var/hear_glanced = TRUE, var/hear_damaged = TRUE) //Plays any relevant sounds whenever the object is hit. glanced_sound overrides damaged_sound if the latter is not set or hear_damaged is set to FALSE. - if(health <= 0) //Don't play a sound here if the object is ready to break, because sounds are also played by on_broken(). - return - if(thisdmg && damaged_sound && hear_damaged) - playsound(src, damaged_sound, 50, 1) - else if(glanced_sound && hear_glanced) - playsound(src, glanced_sound, 50, 1) - -/obj/proc/message_take_hit(var/mute = FALSE) //Give a visible message when the object takes damage. - if(!isnull(take_hit_text2) && !mute) - visible_message("\The [src] [pick(take_hit_text2)]!") - -/obj/proc/damaged_updates() //Put any damage-related updates to the object here. - return - -/obj/examine(mob/user, var/size = "", var/show_name = TRUE, var/show_icon = TRUE) - ..() - if(health[damaged_examine_text]",\ - "It seems kinda messed up somehow.") - -/obj/proc/transfer_obj_blood_data(obj/A, obj/B) //Transfers blood data from one object to another. - if(!A || !B) - return - if(A.had_blood) - B.blood_color = A.blood_color - B.blood_DNA = A.blood_DNA - B.had_blood = TRUE - -/obj/item/transfer_obj_blood_data(obj/item/A, obj/item/B) - ..() - if(!blood_overlays[B.type]) //If there isn't a precreated blood overlay make one - B.generate_blood_overlay() - if(B.blood_overlay != null) // Just if(blood_overlay) doesn't work. Have to use isnull here. - B.overlays.Remove(B.blood_overlay) - else - B.blood_overlay = blood_overlays[B.type] - B.blood_overlay.color = B.blood_color - B.overlays += B.blood_overlay - -/obj/proc/generate_break_text(var/glanced = FALSE, var/suppress_glance_text) //Generates text for when an object is hit. - if(glanced) - if(suppress_glance_text) - return "!" - else if(glances_text) - return ", but it [pick(glances_text)] off!" - else - return ", but it glances off!" - else if(health > 0 && !isnull(take_hit_text)) - return ", [pick(take_hit_text)] it!" - else - return "!" //Don't say "cracking it" if it breaks because on_broken() will subsequently say "The object shatters!" - -/obj/proc/try_break(var/datum/throwparams/propelparams, var/hit_atom) //Breaks the object if its health is 0 or below. Passes throw-related parameters to on_broken() to allow for an object's fragments to be propelled upon breaking. - if(health <= 0) - on_broken(propelparams, hit_atom) - qdel(src) - return TRUE //Return TRUE if the object was broken - else - return FALSE //Return FALSE if the object wasn't broken - -/datum/throwparams //throw_at() input parameters as a datum to make function inputs neater - var/throw_target - var/throw_range - var/throw_speed - var/throw_override - var/throw_fly_speed - -/datum/throwparams/New(var/target, var/range, var/speed, var/override, var/fly_speed) - throw_target = target - throw_range = range - throw_speed = speed - throw_override = override - throw_fly_speed = fly_speed - -/obj/throw_at(var/atom/target, var/range, var/speed, var/override, var/fly_speed) //Called when an object is thrown, and checks if it's broken or not. If it is broken the fragments are thrown instead, otherwise the object is thrown normally. - if(breakable_flags) - var/datum/throwparams/propelparams = new /datum/throwparams(target, range, speed, override, fly_speed) - if(try_break(propelparams)) - return - ..() - -/obj/proc/breakable_check_weapon(var/obj/item/this_weapon) //Check if a weapon isn't excluded from being used to attempt to break an object. - if(breakable_exclude) - for(var/obj/item/this_excl in breakable_exclude) - if(istype(this_weapon, this_excl)) - return FALSE - return TRUE - -/obj/proc/valid_item_attack(var/obj/item/this_weapon, var/mob/user) //Check if an object is in valid circumstances to be attacked with a wielded weapon. - if(user.a_intent == I_HURT && breakable_flags & BREAKABLE_WEAPON && breakable_check_weapon(this_weapon) && isturf(loc)) //Smash objects on the ground, but not in your inventory. - return TRUE - else - return FALSE - -///////////////////// - -//Breaking objects: - -//Attacking the object with a wielded weapon or other item - -/obj/proc/handle_item_attack(obj/item/W, mob/user) - if(isobserver(user) || !Adjacent(user) || user.is_in_modules(src)) - return FALSE - if(valid_item_attack(W, user)) - user.do_attack_animation(src, W) - user.delayNextAttack(1 SECONDS) - add_fingerprint(user) - var/glanced=!take_damage(W.force, skip_break = TRUE) - if(W.hitsound) - playsound(src, W.hitsound, 50, 1) - user.visible_message("\The [user] [pick(W.attack_verb)] \the [src] with \the [W][generate_break_text(glanced,TRUE)]","You hit \the [src] with \the [W][generate_break_text(glanced)]") - try_break() - //Break the weapon as well, if applicable, based on its own force. - if(W.breakable_flags & BREAKABLE_AS_MELEE) - W.take_damage(min(W.force, BREAKARMOR_MEDIUM), skip_break = FALSE, mute = FALSE) //Cap it at BREAKARMOR_MEDIUM to avoid a powerful weapon also needing really strong armor to avoid breaking apart when used. - return TRUE - else - return FALSE - -//Simple animals attacking the object - -/obj/attack_animal(mob/living/simple_animal/M) - if(M.melee_damage_upper && M.a_intent == I_HURT && breakable_flags & BREAKABLE_UNARMED) - M.do_attack_animation(src, M) - M.delayNextAttack(1 SECONDS) - var/glanced=!take_damage(rand(M.melee_damage_lower,M.melee_damage_upper), skip_break = TRUE) - if(M.attack_sound) - playsound(src, M.attack_sound, 50, 1) - M.visible_message("\The [M] [M.attacktext] \the [src][generate_break_text(glanced,TRUE)]","You hit \the [src][generate_break_text(glanced)]") - try_break() - else - ..() - -//Object ballistically colliding with something - -/obj/throw_impact(atom/impacted_atom, var/speed, mob/user) - ..() - if(!(breakable_flags & BREAKABLE_AS_THROWN)) - return - if(!(breakable_flags & BREAKABLE_MOB) && istype(impacted_atom, /mob)) //Don't break when it hits a mob if it's not flagged with BREAKABLE_MOB - return - if(isturf(loc)) //Don't take damage if it was caught mid-flight. - //Unless the object falls to the floor unobstructed, impacts happens twice, once when it hits the target, and once when it falls to the floor. - var/thisdmg = 10 * get_total_scaled_w_class(1) / (speed ? speed : 1) //impact damage scales with the weight class and speed of the object. since a smaller speed is faster, it's a divisor. - if(istype(impacted_atom, /turf/simulated/floor)) - take_damage(thisdmg/2, skip_break = TRUE) - else - take_damage(thisdmg, skip_break = TRUE, mute = FALSE) //Be verbose about the object taking damage. - try_break(null, impacted_atom) - -//Object being hit by a projectile - -/obj/bullet_act(var/obj/item/projectile/proj) - ..() - if(breakable_flags & BREAKABLE_WEAPON) - take_damage(proj.damage, skip_break = TRUE) - var/impact_power = max(0,round((proj.damage_type == BRUTE) * (proj.damage / 3 - (get_total_scaled_w_class(3))))) //The range of the impact-throw is increased by the damage of the projectile, and decreased by the total weight class of the object. - if(impact_power) - //Throw the object in the direction the projectile was traveling - var/propel_dir = get_dir(proj.starting, proj.target) - var/turf/T = get_edge_target_turf(loc, propel_dir) - throw_at(T, impact_power, proj.projectile_speed) - else if(breakable_flags & BREAKABLE_WEAPON) - try_break() - -/obj/proc/get_total_scaled_w_class(var/scalepower=3) //Returns a scaled sum of the weight class of the object itself and all of its contents, if any. - //scalepower raises the w_class of each object to that exponent before adding it to the total. This helps avoid things like a container full of tiny objects being heavier than it should. - var/total_w_class = (isnull(w_class) ? W_CLASS_MEDIUM : w_class) ** scalepower - if(!isnull(contents) && contents.len) - for(var/obj/item/thiscontent in contents) - total_w_class += (thiscontent.w_class ** scalepower) - return total_w_class - -//Biting the object - -/obj/bite_act(mob/living/carbon/human/biter) - if(breakable_flags & BREAKABLE_UNARMED && biter.can_bite(src)) - var/thisdmg = BREAKARMOR_FLIMSY - if(biter.organ_has_mutation(LIMB_HEAD, M_BEAK)) //Beaks = stronger bites - thisdmg += 4 - - var/attacktype = "bite" - var/attacktype2 = "bites" - var/datum/butchering_product/teeth/T = locate(/datum/butchering_product/teeth) in biter.butchering_drops - - if(!T?.amount) - attacktype = "gum" - attacktype2 = "gums" - thisdmg = 1 - - biter.do_attack_animation(src, biter) - biter.delayNextAttack(1 SECONDS) - var/glanced=!take_damage(thisdmg, skip_break = TRUE) - biter.visible_message("\The [biter] [loc == biter ? "[attacktype2] down on" : "leans over and [attacktype2]"] \the [src]!", - "You [loc == biter ? "[attacktype] down on" : "lean over and [attacktype]"] \the [src][glanced ? "... ouch!" : "[generate_break_text()]"]") - try_break() - if(glanced) - //Damage the biter's mouth. - biter.apply_damage(BREAKARMOR_FLIMSY, BRUTE, TARGET_MOUTH) - else - ..() - -///////////////////// diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 688db0e5bbe..c72e7cb80de 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -28,7 +28,7 @@ density = 1 opacity = 1 anchored = 1 - health = 200 + var/health = 200 var/turf/linked_turf /obj/effect/alien/resin/wall @@ -183,7 +183,7 @@ density = 0 plane = ABOVE_TURF_PLANE layer = WEED_LAYER - health = 14 + var/health = 14 var/obj/effect/alien/weeds/node/linked_node = null var/obj/machinery/door/jammin = null @@ -455,7 +455,7 @@ density = 0 anchored = 1 - health = 50 + var/health = 50 var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive flags = PROXMOVE diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 31b4ced70d1..b3b56da4c34 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -6,11 +6,13 @@ var/item_state = null var/list/inhand_states = list("left_hand" = 'icons/mob/in-hand/left/items_lefthand.dmi', "right_hand" = 'icons/mob/in-hand/right/items_righthand.dmi') var/r_speed = 1.0 + var/health //Structural integrity of the item. If breakable_flags are set, at 0, the item breaks; defaults to maxHealth. + var/maxHealth //Maximum structural integrity of the item. If breakable_flags are set, defaults to health. var/hitsound = null var/miss_sound = 'sound/weapons/punchmiss.ogg' var/armor_penetration = 0 // Chance from 0 to 100 to reduce absorb by one, and then rolls the same value. Check living_defense.dm - w_class = W_CLASS_MEDIUM + var/w_class = W_CLASS_MEDIUM var/attack_delay = 10 //Delay between attacking with this item, in 1/10s of a second (default = 1 second) flags = FPRINT @@ -86,6 +88,11 @@ ..() for(var/path in actions_types) new path(src) + if(breakable_flags) //Initialize health and maxHealth to the same value if only one is specified. + if(isnull(health) && maxHealth) + health = maxHealth + else if(isnull(maxHealth) && health) + maxHealth = health /obj/item/Destroy() infected_items -= src diff --git a/code/game/objects/items/breakable.dm b/code/game/objects/items/breakable.dm new file mode 100644 index 00000000000..6d4865a1fd2 --- /dev/null +++ b/code/game/objects/items/breakable.dm @@ -0,0 +1,280 @@ +///////////////////// +// Breakable Items // +// by Hinaichigo // +///////////////////// + +/obj/item + //Breakability: + var/breakable_flags //Flags for different situations the item can break in. See breakable_defines.dm for the full list and explanations of each. + var/damage_armor //Attacks of this much damage or below will glance off. + var/damage_resist //Attacks stronger than damage_armor will have their damage reduced by this much. + var/list/breakable_exclude //List of objects that won't be used to hit the item even on harm intent, so as to allow for other interactions. + //Fragmentation: + var/list/breakable_fragments //List of objects that will be produced when the item is broken apart. eg. /obj/weapon/item/shard. + var/list/fragment_amounts //List of the number of fragments of each item type in breakable_fragments to be dropped. Should be either null (1 each) or the same length as breakable_fragments. + //Text: + var/damaged_examine_text //Addendum to the description when it's damaged eg. damaged_examine_text of "It is dented." + var/take_hit_text //String or list of strings when the item is damaged but not fully broken. eg. "chipping" becomes "..., chipping it!" + var/take_hit_text2 //String or list of strings for contexts like "cracks" becomes "the ... cracks!" + var/glances_text //String or list of strings when the item is attacked but the attack glances off. eg. "bounces" becomes "but it bounces off!" + var/breaks_text //Visible message when the items breaks. eg. "breaks apart" + //Sounds: + var/breaks_sound //Path to audible sound when the item breaks apart. + var/damaged_sound //Path to audible sound when the item is damaged but not fully destroyed. + var/glanced_sound //Path to audible sound when the item recives a glancing attack not strong enough to damage it. + +/obj/item/proc/on_broken(var/datum/throwparams/propelparams, var/atom/hit_atom) //Called right before an object breaks. + //Drop and and propel any fragments: + drop_fragments(propelparams) + //Drop and propel any contents: + drop_contents(propelparams) + //Spill any reagents: + spill_reagents(hit_atom) + if(breaks_text) + visible_message("\The [src] [breaks_text]!") + if(breaks_sound) + playsound(src, breaks_sound, 50, 1) + else if(damaged_sound) + playsound(src, damaged_sound, 50, 1) + +/obj/item/proc/drop_fragments(var/datum/throwparams/propelparams) //Seperate proc in case special stuff happens with a given item's fragments. Parameters are for throwing the fragments. + if(breakable_fragments?.len) + var/oneeach=(isnull(fragment_amounts) || breakable_fragments.len != fragment_amounts.len) //default to 1 of each fragment type if fragment_amounts isn't specified or there's a length mismatch + var/numtodrop + var/thisfragment + for(var/frag_ind in 1 to breakable_fragments.len) + if(oneeach) + numtodrop=1 + else + numtodrop=fragment_amounts[frag_ind] + thisfragment=breakable_fragments[frag_ind] + for(var/n in 1 to numtodrop) + var/obj/item/O = new thisfragment (get_turf(src)) + //Transfer fingerprints, fibers, and bloodstains to the fragment. + transfer_fingerprints(src,O) + transfer_item_blood_data(src,O) + if(propelparams.throw_target && propelparams.throw_range && propelparams.throw_speed) //Propel the fragment if specified. + O.throw_at(propelparams.throw_target, propelparams.throw_range, propelparams.throw_speed, propelparams.throw_override, propelparams.throw_fly_speed) + +/obj/item/proc/drop_contents(var/datum/throwparams/propelparams) //Drop the contents of the item and propel them if the item itself received a propulsive blow. + if(contents.len) + for(var/obj/item/thiscontent in contents) + thiscontent.forceMove(src.loc) + if(propelparams.throw_target && propelparams.throw_range && propelparams.throw_speed) //Propel the content if specified. + thiscontent.throw_at(propelparams.throw_target, propelparams.throw_range, propelparams.throw_speed, propelparams.throw_override, propelparams.throw_fly_speed) + +/obj/item/proc/spill_reagents(var/atom/hit_atom) //Spill any reagents contained within the item onto the floor, and the atom it hit when it broke, if applicable. + if(!isnull(reagents)) + if(!isnull(hit_atom) && hit_atom != get_turf(src)) //If it hit something other than the floor, spill it onto that. + reagents.reaction(hit_atom, TOUCH) + reagents.reaction(get_turf(src), TOUCH) //Then spill it onto the floor. + +/obj/item/proc/take_damage(var/incoming_damage, var/mute = TRUE, var/skip_break = FALSE) + var/thisdmg=(incoming_damage>max(damage_armor,damage_resist)) * (incoming_damage-damage_resist) //damage is 0 if the incoming damage is less than either damage_armor or damage_resist, to prevent negative damage by weak attacks + health-=thisdmg + play_hit_sounds(thisdmg) + if(!thisdmg) + return 0 //return 0 if the item took no damage (glancing attack) + else + if(health>0) //Only if the item isn't ready to break. + message_take_hit(mute) + damaged_updates() + if(!skip_break) + try_break() + return 1 //return 1 if the item took damage + +/obj/item/proc/play_hit_sounds(var/thisdmg, var/hear_glanced = TRUE, var/hear_damaged = TRUE) //Plays any relevant sounds whenever the item is hit. glanced_sound overrides damaged_sound if the latter is not set or hear_damaged is set to FALSE. + if(health<=0) //Don't play a sound here if the item is ready to break, because sounds are also played by on_broken(). + return + if(thisdmg && !isnull(damaged_sound) && hear_damaged) + playsound(src, damaged_sound, 50, 1) + else if(!isnull(glanced_sound) && hear_glanced) + playsound(src, glanced_sound, 50, 1) + +/obj/item/proc/message_take_hit(var/mute = FALSE) //Give a visible message when the item takes damage. + if(!isnull(take_hit_text2) && !mute) + visible_message("\The [src] [pick(take_hit_text2)]!") + +/obj/item/proc/damaged_updates() //Put any damage-related changes to name, desc, icon, etc. here. + return + +/obj/item/examine(mob/user, var/size = "", var/show_name = TRUE, var/show_icon = TRUE) + ..() + if(health [damaged_examine_text]",\ + " It seems kinda messed up somehow.") + +/obj/item/proc/transfer_item_blood_data(obj/item/A,obj/item/B) //Transfers blood data from one item to another. + if(!A || !B) + return + if(A.had_blood) + B.blood_color = A.blood_color + B.blood_DNA = A.blood_DNA + B.had_blood = TRUE + + if(!blood_overlays[B.type]) //If there isn't a precreated blood overlay make one + B.generate_blood_overlay() + + if(B.blood_overlay != null) // Just if(blood_overlay) doesn't work. Have to use isnull here. + B.overlays.Remove(B.blood_overlay) + else + B.blood_overlay = blood_overlays[B.type] + + B.blood_overlay.color = B.blood_color + B.overlays += B.blood_overlay + +/obj/item/proc/generate_break_text(var/glanced = FALSE, var/suppress_glance_text) //Generates text for when an item is hit. + if(glanced) + if(suppress_glance_text) + return "!" + else if(glances_text) + return ", but it [pick(glances_text)] off!" + else + return ", but it [pick("bounces","gleams","glances")] off!" + else if(health > 0 && !isnull(take_hit_text)) + return ", [pick(take_hit_text)] it!" + else + return "!" //Don't say "cracking it" if it breaks because on_broken() will subsequently say "The item shatters!" + +/obj/item/proc/try_break(var/datum/throwparams/propelparams, var/hit_atom) //Breaks the item if its health is 0 or below. Passes throw-related parameters to on_broken() to allow for an object's fragments to be thrown upon breaking. + if(breakable_flags && health<=0) + on_broken(propelparams, hit_atom) + qdel(src) + return TRUE //Return TRUE if the item was broken + else + return FALSE //Return FALSE if the item wasn't broken + + +/datum/throwparams //throw_at() input parameters as a datum to make function inputs neater + var/throw_target + var/throw_range + var/throw_speed + var/throw_override + var/throw_fly_speed + +/datum/throwparams/New(var/target, var/range, var/speed, var/override, var/fly_speed) + throw_target = target + throw_range = range + throw_speed = speed + throw_override = override + throw_fly_speed = fly_speed + + +/obj/item/throw_at(var/atom/target, var/range, var/speed, var/override , var/fly_speed) //Called when an item is thrown, and checks if it's broken or not. If it is broken the fragments are thrown instead, otherwise the item is thrown normally. + if(breakable_flags) + var/datum/throwparams/propelparams = new /datum/throwparams(target, range, speed, override, fly_speed) + if(try_break(propelparams)) + return + ..() + +/obj/item/proc/breakable_check_weapon(var/obj/item/this_weapon) //Check if a weapon isn't excluded from being used to attempt to break an item. + if(breakable_exclude) + for(var/obj/item/this_excl in breakable_exclude) + if(istype(this_weapon, this_excl)) + return FALSE + return TRUE + +///////////////////// + +//Breaking items: + +//Attacking the item with a wielded weapon or other item + +/obj/item/attackby(obj/item/W, mob/user) + if(isobserver(user) || !Adjacent(user) || user.is_in_modules(src)) + return + if(user.a_intent == I_HURT && breakable_flags & BREAKABLE_WEAPON && breakable_check_weapon(W) && isturf(loc)) //Smash items on the ground, but not in your inventory. + user.do_attack_animation(src, W) + user.delayNextAttack(1 SECONDS) + add_fingerprint(user) + var/glanced=!take_damage(W.force, skip_break = TRUE) + user.visible_message("\The [user] [pick(W.attack_verb)] \the [src] with \the [W][generate_break_text(glanced,TRUE)]","You hit \the [src] with \the [W][generate_break_text(glanced)]") + try_break() + //Break the weapon as well, if applicable, based on its own force. + if(W.breakable_flags & BREAKABLE_AS_MELEE) + W.take_damage(min(W.force, BREAKARMOR_MEDIUM),FALSE) //Cap it at BREAKARMOR_MEDIUM to avoid a powerful weapon also needing really strong armor to avoid breaking apart when used. + else + ..() + +//Simple animals attacking the item + +/obj/item/attack_animal(mob/living/simple_animal/M) + if(M.melee_damage_upper && M.a_intent == I_HURT && breakable_flags & BREAKABLE_UNARMED) + M.do_attack_animation(src, M) + M.delayNextAttack(1 SECONDS) + var/glanced=!take_damage(rand(M.melee_damage_lower,M.melee_damage_upper), skip_break = TRUE) + M.visible_message("\The [M] [M.attacktext] \the [src][generate_break_text(glanced,TRUE)]","You hit \the [src][generate_break_text(glanced)]") + try_break() + else + ..() + +//Item ballistically colliding with something + +/obj/item/throw_impact(atom/impacted_atom, var/speed, mob/user) + ..() + if(!(breakable_flags & BREAKABLE_AS_THROWN)) + return + if(!(breakable_flags & BREAKABLE_MOB) && istype(impacted_atom, /mob)) //Don't break when it hits a mob if it's not flagged with BREAKABLE_MOB + return + if(isturf(loc)) //Don't take damage if it was caught mid-flight. + //Unless the item falls to the floor unobstructed, impacts happens twice, once when it hits the target, and once when it falls to the floor. + var/thisdmg = 5 * get_total_scaled_w_class(1) / speed //impact damage scales with the weight class and speed of the item. since a smaller speed is faster, it's a divisor. + if(istype(impacted_atom, /turf/simulated/floor)) + take_damage(thisdmg/2, skip_break = TRUE) + else + take_damage(thisdmg, mute = FALSE, skip_break = TRUE) //Be verbose about the item taking damage. + try_break(hit_atom = impacted_atom) + +//Item being hit by a projectile + +/obj/item/bullet_act(var/obj/item/projectile/proj) + ..() + if(breakable_flags & BREAKABLE_WEAPON) + take_damage(proj.damage, skip_break = TRUE) + var/impact_power = max(0,round((proj.damage_type == BRUTE) * (proj.damage / 3 - (get_total_scaled_w_class(3))))) //The range of the impact-throw is increased by the damage of the projectile, and decreased by the total weight class of the item. + if(impact_power) + //Throw the item in the direction the projectile was traveling + var/propel_dir = get_dir(proj.starting, proj.target) + var/turf/T = get_edge_target_turf(loc, propel_dir) + throw_at(T, impact_power, proj.projectile_speed) + else if(breakable_flags & BREAKABLE_WEAPON) + try_break() + +/obj/item/proc/get_total_scaled_w_class(var/scalepower=3) //Returns a scaled sum of the weight class of the item itself and all of its contents, if any. + //scalepower raises the w_class of each item to that exponent before adding it to the total. This helps avoid things like a container full of tiny objects being heavier than it should. + var/total_w_class = (w_class ** scalepower) + if(!isnull(contents) && contents.len) + for(var/obj/item/thiscontent in contents) + total_w_class += (thiscontent.w_class ** scalepower) + return total_w_class + +//Biting the item + +/obj/item/bite_act(mob/living/carbon/human/biter) + if(breakable_flags & BREAKABLE_UNARMED && biter.can_bite(src)) + var/thisdmg = BREAKARMOR_FLIMSY + if(biter.organ_has_mutation(LIMB_HEAD, M_BEAK)) //Beaks = stronger bites + thisdmg += 4 + + var/attacktype = "bite" + var/attacktype2 = "bites" + var/datum/butchering_product/teeth/T = locate(/datum/butchering_product/teeth) in biter.butchering_drops + + if(T.amount == 0) + attacktype = "gum" + attacktype2 = "gums" + thisdmg = 1 + + biter.do_attack_animation(src, biter) + biter.delayNextAttack(1 SECONDS) + var/glanced=!take_damage(thisdmg, skip_break = TRUE) + biter.visible_message("\The [biter] [loc == biter ? "[attacktype2] down on" : "leans over and [attacktype2]"] \the [src]!", + "You [loc == biter ? "[attacktype] down on" : "lean over and [attacktype]"] \the [src][glanced ? "... ouch!" : "[generate_break_text()]"]") + try_break() + if(glanced) + //Damage the biter's mouth. + biter.apply_damage(BREAKARMOR_FLIMSY, BRUTE, TARGET_MOUTH) + else + ..() + +///////////////////// diff --git a/code/game/objects/items/breakable_test.dm b/code/game/objects/items/breakable_test.dm new file mode 100644 index 00000000000..628a62475ad --- /dev/null +++ b/code/game/objects/items/breakable_test.dm @@ -0,0 +1,130 @@ +///////////////////// +//Breakability testing items +/obj/item/device/flashlight/test + name = "breakable flashlight" + desc = "This flashlight looks particularly flimsy." + breakable_flags = BREAKABLE_ALL + health = 30 + maxHealth = 30 + damaged_examine_text = "It has gone bad." + breaks_text = "crumbles apart" + take_hit_text = "cracking" + breaks_sound = 'sound/misc/balloon_pop.ogg' + breakable_fragments = list(/obj/item/weapon/shard, /obj/item/weapon/reagent_containers/food/snacks/hotdog) + fragment_amounts = list(2,1) //Will break into 2 shards, 1 hotdog. + damaged_sound = 'sound/effects/grillehit.ogg' + glanced_sound = 'sound/items/trayhit1.ogg' + +/obj/item/weapon/kitchen/utensil/knife/large/test + name = "breakable knife" + desc = "This knife looks like it could break under pressure." + breakable_flags = BREAKABLE_ALL + health = 30 + maxHealth = 30 + damaged_examine_text = "It's seen better days." + breaks_text = "splinters into little bits" + take_hit_text = list("denting","cracking") + breaks_sound = 'sound/items/trayhit1.ogg' + breakable_fragments = list(/obj/item/weapon/shard, /obj/item/weapon/kitchen/utensil/knife/large/test) + +/obj/item/weapon/kitchen/utensil/knife/large/test/weak + name = "flimsy breakable knife" + desc = "This flimsy knife looks like it could fall apart at any time." + breakable_flags = BREAKABLE_ALL + health = 0.1 + maxHealth = 1 + damaged_examine_text = "It's seen much better days." + damage_armor = BREAKARMOR_NOARMOR + damage_resist = 0 + take_hit_text = "chipping" + take_hit_text2 = "chips" + breaks_text = "falls apart into dust" + breakable_fragments = list(/obj/item/weapon/shard, /obj/item/weapon/kitchen/utensil/knife/large/test/weak) + +/obj/item/weapon/pen/fountain/test + name = "breakable fountain pen" + desc = "This pen looks really weak." + breakable_flags = BREAKABLE_ALL + health = 10 + maxHealth = 10 + damaged_examine_text = "It's seen much better days." + damage_armor = 0 + damage_resist = 0 + breaks_text = "falls apart into dust" + density = 1 + breakable_fragments = list(/obj/item/weapon/pen/fountain/test, /obj/item/weapon/kitchen/utensil/knife/) + fragment_amounts = list(1,3) + +/obj/item/weapon/pen/fountain/test/strong + name = "invincible fountain pen" + desc = "This pen looks really, really tough." + breakable_flags = BREAKABLE_ALL + health = 10 + maxHealth = 10 + damaged_examine_text = "Somehow it has a crack in it..." + damage_armor = BREAKARMOR_INVINCIBLE + damage_resist = 0 + density = 1 + breaks_text = "implodes" + breakable_fragments = list(/obj/item/weapon/reagent_containers/food/snacks/hotdog) + +/obj/item/weapon/reagent_containers/glass/jar/erlenmeyer/test + name = "huge breakable flask" + desc = "A huge flask that could break at any time, under the right conditions." + breakable_flags = BREAKABLE_ALL + health = 1 + maxHealth = 1 + damaged_examine_text = "It has a big crack down the side." + damage_armor = BREAKARMOR_NOARMOR + damage_resist = 0 + density = 1 + breaks_text = "shatters" + +/obj/item/weapon/reagent_containers/glass/jar/erlenmeyer/test/New() + ..() + reagents.add_reagent(PACID, 250) + update_icon() + +/obj/item/weapon/reagent_containers/glass/beaker/test + name = "breakable beaker" + desc = "A breakable beaker. Can hold up to 50 units." + icon = 'icons/obj/chemical.dmi' + icon_state = "beaker" + item_state = "beaker" + breakable_flags = BREAKABLE_ALL + maxHealth = 20 + damaged_examine_text = "It has a big crack down the side." + damage_armor = BREAKARMOR_NOARMOR + damage_resist = 0 + breaks_text = "shatters" + take_hit_text = list("cracking","chipping") + take_hit_text2 = list("cracks","chips") + glances_text = list("glances","bounces") + starting_materials = list(MAT_GLASS = 500) + origin_tech = Tc_MATERIALS + "=1" + layer = ABOVE_OBJ_LAYER //So it always gets layered above pills and bottles + +/obj/item/weapon/reagent_containers/glass/jar/erlenmeyer/test/New() + ..() + reagents.add_reagent(PACID, 50) + update_icon() + +/obj/item/weapon/storage/box/survival/test + name = "breakable survival box" + desc = "A box that holds survival equipment, but is also somewhat fragile." + icon_state = "box_emergency" + item_state = "box_emergency" + breakable_flags = BREAKABLE_ALL + health = 10 + maxHealth = 10 + density = 1 + damaged_examine_text = "It's all banged up." + damage_armor = BREAKARMOR_NOARMOR + damage_resist = 0 + breaks_text = "blows apart" + items_to_spawn = list( + /obj/item/weapon/reagent_containers/food/snacks/hotdog, + /obj/item/weapon/reagent_containers/food/snacks/hotdog, + /obj/item/weapon/reagent_containers/food/snacks/hotdog, + ) +///////////////////// diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 041a3f07c04..845978710bc 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -19,19 +19,6 @@ var/sound_on = 'sound/items/flashlight_on.ogg' var/sound_off = 'sound/items/flashlight_off.ogg' - health = 30 - breakable_flags = BREAKABLE_ALL - breakable_fragments = list(/obj/item/weapon/light/bulb/broken, /obj/item/stack/cable_coil/cut/) - damage_armor = 10 - damage_resist = 10 - damaged_examine_text = "It is dented." - take_hit_text = "denting" - take_hit_text2 = "dents" - breaks_text = "breaks apart" - glanced_sound = 'sound/items/metal_impact.ogg' - breaks_sound = 'sound/effects/Glassbr1.ogg' - - /obj/item/device/flashlight/initialize() ..() if(on) @@ -120,18 +107,12 @@ brightness_on = 2 has_sound = 0 - health = 10 - /obj/item/device/flashlight/tactical name = "tactical light" desc = "A compact, tactical flashlight with automatic self-attaching screws. Fits on armor and headgear." icon_state = "taclight" item_state = "" - - health = 40 - damage_armor = 15 - damage_resist = 15 - + /obj/item/device/flashlight/tactical/preattack(atom/target, mob/user, proximity_flag, click_parameters) if(!proximity_flag) return 0 @@ -150,7 +131,7 @@ return 1 else to_chat(user, "\The [src] cannot be attached to that.") - return ..() + return ..() // the desk lamps are a bit special @@ -207,8 +188,6 @@ light_color = LIGHT_COLOR_FLARE - breakable_flags = 0 //Not breakable for now. - /obj/item/device/flashlight/flare/New() fuel = rand(300, 500) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. ..() @@ -299,14 +278,6 @@ var/brightness_max = 6 var/brightness_min = 2 - breakable_fragments = list(/obj/item/weapon/light/bulb/broken) - damaged_examine_text = "It is cracked." - take_hit_text = list("cracking", "chipping") - take_hit_text2 = list("cracks", "chips") - breaks_text = "shatters" - breaks_sound = 'sound/effects/Glassbr3.ogg' - - /obj/item/device/flashlight/lamp/slime/initialize() ..() if(on) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index d72e715167a..1bde296d12d 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -369,13 +369,10 @@ if(usr) //WHYYYYY - //Allow smashing of storage items on harm intent without also putting the weapon into the container. - if(valid_item_attack(W, usr) || (!isnull(health) && health <= 0)) - return 0 - usr.u_equip(W,0) W.dropped(usr) // we're skipping u_equip's forcemove to turf but we still need the item to unset itself usr.update_icons() + W.forceMove(src) W.on_enter_storage(src) if(usr) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 3bc31244018..186a6bff7f8 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -18,8 +18,6 @@ var/global/list/reagents_to_log = list(FUEL, PLASMA, PACID, SACID, AMUTATIONTOXI var/damtype = "brute" var/force = 0 - var/w_class - //Should we alert about reagents that should be logged? var/log_reagents = 1 @@ -89,10 +87,6 @@ var/global/list/reagents_to_log = list(FUEL, PLASMA, PACID, SACID, AMUTATIONTOXI /obj/attackby(obj/item/weapon/W, mob/user) INVOKE_EVENT(src, /event/attackby, "attacker" = user, "item" = W) - - if(handle_item_attack(W, user)) - return - if(can_take_pai && istype(W, /obj/item/device/paicard)) if(integratedpai) to_chat(user, "There's already a Personal AI inserted.") @@ -659,7 +653,7 @@ a { user.visible_message("[user] puts \his foot to \the [A] and kicks \himself away!", \ "You put your foot to \the [A] and kick as hard as you can! [pick("RAAAAAAAARGH!", "HNNNNNNNNNGGGGGGH!", "GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", "AAAAAAARRRGH!")]") var/turf/T = get_edge_target_turf(src, movementdirection) - src.throw_at(T, 8, 20, TRUE, 2) + src.throw_at(T,8,20,fly_speed = 2) else user.visible_message("[user] kicks \himself away from \the [A].", "You kick yourself away from \the [A]. Wee!") for(var/i in list(2,2,3,3)) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 943b661ebe0..b9faf0a5377 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -15,7 +15,7 @@ var/large = 1 var/pick_up_stuff = 1 // Pick up things that spawn at this location. var/wall_mounted = 0 //never solid (You can always pass over it) - health = 100 + var/health = 100 var/lastbang var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate //then open it in a populated area to crash clients. diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 05f113e7b4f..116956fa8c4 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -7,7 +7,7 @@ desc = "A display case for prized possessions. It tempts you to kick it." density = 1 anchored = 1 - health = 30 + var/health = 30 var/obj/item/occupant = null var/destroyed = 0 var/locked = 0 diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm index c595f243ecb..51adbe18e86 100644 --- a/code/game/objects/structures/flora/flora.dm +++ b/code/game/objects/structures/flora/flora.dm @@ -73,8 +73,8 @@ pixel_x = -WORLD_ICON_SIZE/2 - health = 100 - maxHealth = 100 + var/health = 100 + var/maxHealth = 100 var/height = 6 //How many logs are spawned diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index a08818cbe38..1e4c04090c4 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -11,7 +11,7 @@ layer = BELOW_OBJ_LAYER explosion_resistance = 5 pass_flags_self = PASSGRILLE - health = 20 //Relatively "strong" since it's hard to dismantle via brute force + var/health = 20 //Relatively "strong" since it's hard to dismantle via brute force var/broken = 0 var/grille_material = /obj/item/stack/rods diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 9b7ceb9d3be..98b6891bfb1 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -138,7 +138,7 @@ var/undeploy_path = null var/spawn_undeployed = TRUE var/tmp/deflating = 0 - health = 30 + var/health = 30 var/ctrl_deflate = TRUE /obj/structure/inflatable/wall @@ -168,7 +168,7 @@ if(2) deflate(1) if(3) - take_damage(rand(15,45), sound_effect = 0) + take_damage(rand(15,45), 0) /obj/structure/inflatable/attackby(obj/item/I, mob/user) if(!istype(I) || istype(I, /obj/item/weapon/inflatable_dispenser)) @@ -198,19 +198,15 @@ user.visible_message("[user] rips \the [src] apart!") deflate(1) -/obj/structure/inflatable/take_damage(incoming_damage, damage_type, skip_break, mute, var/sound_effect = 1) //Custom take_damage() proc because of sound_effect behavior. - health = max(0, health - incoming_damage) +/obj/structure/inflatable/proc/take_damage(var/damage, var/sound_effect = 1) + health = max(0, health - damage) if(sound_effect) playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) - return try_break() - -/obj/structure/inflatable/try_break() if(health <= 0) spawn(1) deflate(1) - return TRUE - return FALSE - + return 1 + return 0 /obj/structure/inflatable/CtrlClick() if(ctrl_deflate) diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm index 659c5891994..f234734b9a9 100644 --- a/code/game/objects/structures/lamarr_cage.dm +++ b/code/game/objects/structures/lamarr_cage.dm @@ -5,7 +5,7 @@ desc = "A glass lab container for storing interesting creatures." density = 1 anchored = 1 - health = 30 + var/health = 30 var/occupied = 1 var/destroyed = 0 diff --git a/code/game/objects/structures/mannequin.dm b/code/game/objects/structures/mannequin.dm index c9b5aecfb03..49bc086adec 100644 --- a/code/game/objects/structures/mannequin.dm +++ b/code/game/objects/structures/mannequin.dm @@ -34,8 +34,8 @@ var/hair_color = "#B9C1B8" var/clothing_offset_x = 0 var/clothing_offset_y = 3*PIXEL_MULTIPLIER - health = 90 - maxHealth = 90 + var/health = 90 + var/maxHealth = 90 var/has_pedestal = TRUE var/timer = 80 //in seconds var/mob/living/captured diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 8fae98ba44f..22c91ec8865 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -6,7 +6,7 @@ desc = "It's a gruesome pile of thick, sticky resin shaped like a nest." icon = 'icons/mob/alien.dmi' icon_state = "nest" - health = 100 + var/health = 100 /obj/structure/bed/nest/New() ..() diff --git a/code/game/objects/structures/support_rail.dm b/code/game/objects/structures/support_rail.dm index 1ffbe00749f..36a26739e3c 100644 --- a/code/game/objects/structures/support_rail.dm +++ b/code/game/objects/structures/support_rail.dm @@ -10,7 +10,7 @@ pressure_resistance = 5*ONE_ATMOSPHERE layer = DECAL_LAYER explosion_resistance = 5 - health = 10 + var/health = 10 var/destroyed = 0 var/mob/living/carbon/human/supported_mob diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 5676313d01f..e74a13da8c6 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -23,7 +23,7 @@ pass_flags_self = PASSTABLE var/parts = /obj/item/weapon/table_parts var/flipped = 0 - health = 100 + var/health = 100 /obj/structure/table/proc/update_adjacent() for(var/direction in alldirs) @@ -720,7 +720,7 @@ pass_flags_self = PASSTABLE var/parts = /obj/item/weapon/rack_parts var/offset_step = 0 - health = 20 + var/health = 20 /obj/structure/rack/proc/destroy(var/dropParts = TRUE) if(parts && dropParts) diff --git a/code/game/objects/structures/vehicles/vehicle.dm b/code/game/objects/structures/vehicles/vehicle.dm index ecd8ae9ffc2..c1565e7d385 100644 --- a/code/game/objects/structures/vehicles/vehicle.dm +++ b/code/game/objects/structures/vehicles/vehicle.dm @@ -36,7 +36,7 @@ density = 1 buckle_range = 1 var/empstun = 0 - health = 100 + var/health = 100 var/max_health = 100 plane = ABOVE_HUMAN_PLANE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 33c20a07830..ad4c9195d17 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -18,7 +18,7 @@ var/list/one_way_windows layer = SIDE_WINDOW_LAYER pressure_resistance = 4*ONE_ATMOSPHERE anchored = 1 - health = 10 //This window is so bad blowing on it would break it, sucks for it + var/health = 10 //This window is so bad blowing on it would break it, sucks for it var/d_state = WINDOWLOOSEFRAME //Normal windows have one step (unanchor), reinforced windows have three var/shardtype = /obj/item/weapon/shard var/reinforcetype = /obj/item/stack/rods diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 080875357ad..5ce379fe0b9 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -423,7 +423,7 @@ proc/check_panel(mob/M) var/collapse var/image/down - health = 100 + var/health = 100 /obj/effect/fake_attacker/attackby(var/obj/item/weapon/P as obj, mob/living/user as mob) step_away(src,my_target,2) diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/hydro_tray.dm index 8c1ae7daa50..3971a8c42ca 100644 --- a/code/modules/hydroponics/hydro_tray.dm +++ b/code/modules/hydroponics/hydro_tray.dm @@ -35,7 +35,7 @@ var/is_somatoraying = 0 // Lazy way to make it so that the Floral Somatoray can only cause one mutation at a time. // Mechanical concerns. - var/plant_health = 0 // Plant health. + var/health = 0 // Plant health. var/lastproduce = 0 // Last time tray was harvested. var/lastcycle = 0 // Cycle timing/tracking var. var/cycledelay = 150 // Delay per cycle. @@ -193,7 +193,7 @@ if(!seed) return //Weed does not exist, someone fucked up. - plant_health = seed.endurance + health = seed.endurance lastcycle = world.time weedlevel = 0 update_icon() @@ -239,7 +239,7 @@ nutrilevel = 1 //Snowflakey, maybe move this to the seed datum - plant_health = seed.endurance + health = seed.endurance lastcycle = world.time @@ -254,7 +254,7 @@ else if(O.force && seed && user.a_intent == I_HURT) visible_message("\The [seed.display_name] has been attacked by [user] with \the [O]!") if(!dead) - plant_health -= O.force + health -= O.force check_health() user.delayNextAttack(5) @@ -327,7 +327,7 @@ // Create a sample. seed.spawn_seed_packet(get_turf(user)) to_chat(user, "You take a sample from the [seed.display_name].") - plant_health -= (rand(3,5)*10) + health -= (rand(3,5)*10) if(prob(30)) sampled = 1 @@ -404,7 +404,7 @@ to_chat(user, "You use \the [O] as compost for \the [src].") O.reagents.trans_to(src, O.reagents.total_volume, log_transfer = TRUE, whodunnit = user) qdel(O) - + else return ..() @@ -451,7 +451,7 @@ /obj/machinery/portable_atmospherics/hydroponics/proc/view_contents(mob/user) if(src.seed && !src.dead) to_chat(user, "[src.seed.display_name] is growing here.") - if(src.plant_health <= (src.seed.endurance / 2)) + if(src.health <= (src.seed.endurance / 2)) to_chat(user, "The plant looks [age > seed.lifespan ? "old and wilting" : "unhealthy"].") else if(src.seed && src.dead) to_chat(user, "[src] is full of dead plant matter.") diff --git a/code/modules/hydroponics/hydro_tray_process.dm b/code/modules/hydroponics/hydro_tray_process.dm index 894544e5364..c5e53ef2e52 100644 --- a/code/modules/hydroponics/hydro_tray_process.dm +++ b/code/modules/hydroponics/hydro_tray_process.dm @@ -84,18 +84,18 @@ // cause a plant to become healthier. Lack of sustenance will stunt the plant's growth. if(prob(35)) if(nutrilevel > 2) - plant_health += healthmod + health += healthmod else affect_growth(-1) - plant_health -= healthmod + health -= healthmod if(draw_warnings) update_icon_after_process = 1 if(prob(35)) if(waterlevel > 10) - plant_health += healthmod + health += healthmod else affect_growth(-1) - plant_health -= healthmod + health -= healthmod if(draw_warnings) update_icon_after_process = 1 @@ -131,14 +131,14 @@ environment.update_values() if(missing_gas > 0) - plant_health -= missing_gas * HYDRO_SPEED_MULTIPLIER + health -= missing_gas * HYDRO_SPEED_MULTIPLIER if(draw_warnings) update_icon_after_process = 1 // Process it. var/pressure = environment.return_pressure() if(pressure < seed.lowkpa_tolerance || pressure > seed.highkpa_tolerance) - plant_health -= healthmod + health -= healthmod improper_kpa = 1 if(draw_warnings) update_icon_after_process = 1 @@ -146,7 +146,7 @@ improper_kpa = 0 if(abs(environment.temperature - seed.ideal_heat) > seed.heat_tolerance) - plant_health -= healthmod + health -= healthmod improper_heat = 1 if(draw_warnings) update_icon_after_process = 1 @@ -175,7 +175,7 @@ light_available = T.get_lumcount() * 10 if(!seed.biolum && abs(light_available - seed.ideal_light) > seed.light_tolerance) - plant_health -= healthmod + health -= healthmod if(prob(35)) affect_growth(-1) improper_light = 1 @@ -189,7 +189,7 @@ if(toxins > 0) var/toxin_uptake = max(1,round(toxins/10)) if(toxins > seed.toxins_tolerance) - plant_health -= toxin_uptake + health -= toxin_uptake toxins -= toxin_uptake * (1+bees) if(draw_warnings) update_icon_after_process = 1 @@ -198,27 +198,27 @@ // Some carnivorous plants happily eat pests. if(pestlevel > 0) if(seed.carnivorous) - plant_health += HYDRO_SPEED_MULTIPLIER + health += HYDRO_SPEED_MULTIPLIER pestlevel -= HYDRO_SPEED_MULTIPLIER else if (pestlevel >= seed.pest_tolerance) - plant_health -= HYDRO_SPEED_MULTIPLIER + health -= HYDRO_SPEED_MULTIPLIER if(draw_warnings) update_icon_after_process = 1 // Some plants thrive and live off of weeds. if(weedlevel > 0) if(seed.parasite) - plant_health += HYDRO_SPEED_MULTIPLIER + health += HYDRO_SPEED_MULTIPLIER weedlevel -= HYDRO_SPEED_MULTIPLIER else if (weedlevel >= seed.weed_tolerance) - plant_health -= HYDRO_SPEED_MULTIPLIER + health -= HYDRO_SPEED_MULTIPLIER if(draw_warnings) update_icon_after_process = 1 // Handle life and death. // If the plant is too old, it loses health fast. if(age > seed.lifespan) - plant_health -= (rand(3,5) * HYDRO_SPEED_MULTIPLIER)/(1+bees) + health -= (rand(3,5) * HYDRO_SPEED_MULTIPLIER)/(1+bees) if(draw_warnings) update_icon_after_process = 1 // If the plant's age is negative, let's revert it into a seed packet, for funsies @@ -260,7 +260,7 @@ update_icon() /obj/machinery/portable_atmospherics/hydroponics/proc/check_health() - if(plant_health <= 0) + if(health <= 0) die() //ominous /obj/machinery/portable_atmospherics/hydroponics/proc/affect_growth(var/amount) @@ -296,7 +296,7 @@ // Updates the plant overlay. if(!isnull(seed)) - if(draw_warnings && plant_health <= (seed.endurance / 2)) + if(draw_warnings && health <= (seed.endurance / 2)) overlays += image('icons/obj/hydroponics/hydro_tools.dmi',"over_lowhealth3") if(dead) @@ -343,9 +343,9 @@ /obj/machinery/portable_atmospherics/hydroponics/proc/check_level_sanity() //Make sure various values are sane. if(seed) - plant_health = clamp(plant_health, 0, seed.endurance) + health = clamp(health, 0, seed.endurance) else - plant_health = 0 + health = 0 dead = 0 mutation_level = clamp(mutation_level, 0, 100) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 0eafb689fd2..d4818e3bbfc 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -13,8 +13,8 @@ pass_flags = PASSTABLE | PASSGRILLE | PASSGIRDER | PASSMACHINE mouse_opacity = 1 - health = 10 - maxHealth = 100 + var/health = 10 + var/max_health = 100 var/list/turf/simulated/floor/neighbors = list() var/turf/epicenter var/datum/seed/seed @@ -77,7 +77,7 @@ return name = "[seed.seed_name] vines" - maxHealth = round(seed.endurance/2) + max_health = round(seed.endurance/2) if(seed.spread == 1) limited_growth = 1 layer = CREEPER_LAYER @@ -88,7 +88,7 @@ update_icon() if(start_fully_mature) - health = maxHealth + health = max_health mature_time = 0 register_event(/event/before_move, src, /obj/effect/plantsegment/proc/before_moving) @@ -143,8 +143,8 @@ if(at_fringe >= round(spread_distance_limit*0.7)) arbitrary_measurement_of_how_lush_I_am_right_now-- - if(health < maxHealth) - arbitrary_measurement_of_how_lush_I_am_right_now -= round(-(health - maxHealth)/(maxHealth/3)) + if(health < max_health) + arbitrary_measurement_of_how_lush_I_am_right_now -= round(-(health - max_health)/(max_health/3)) arbitrary_measurement_of_how_lush_I_am_right_now = max(1, arbitrary_measurement_of_how_lush_I_am_right_now) @@ -208,12 +208,19 @@ S.handle_item_insertion(G, 1) else ..() - if(W.is_hot() || (W.is_sharp() && !seed.ligneous)) - take_damage(W.force * 4) - else - take_damage(W.force) + take_damage(W) user.delayNextAttack(10) +/obj/effect/plantsegment/proc/take_damage(var/obj/item/weapon/W) + if(!W.force) + return 0 + var/dmg = W.force + if(W.is_hot() || (W.is_sharp() && !seed.ligneous)) + dmg = dmg*4 + health -= dmg + check_health() + update_icon() + /obj/effect/plantsegment/ex_act(severity) switch(severity) if(1.0) @@ -234,14 +241,11 @@ /obj/effect/plantsegment/fire_act(null, temp, volume) die_off() -/obj/effect/plantsegment/damaged_updates() - update_icon() - -/obj/effect/plantsegment/try_break() +/obj/effect/plantsegment/proc/check_health() if(health <= 0) die_off() /obj/effect/plantsegment/proc/is_mature() - return (health >= (maxHealth/2) && age > mature_time) + return (health >= (max_health/2) && age > mature_time) #undef CREEPER_GROWTH_DISTANCE diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm index 9776462efa6..ec85bbd259a 100644 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -52,8 +52,8 @@ // Kudzu does NOT need light, otherwise, you could just turn off the lights to kill it. - if(health < maxHealth) - health = min(maxHealth, health + rand(3,5)) + if(health < max_health) + health = min(max_health, health + rand(3,5)) if(prob(80)) age++ @@ -116,9 +116,9 @@ child.update_icon() // We shouldn't have spawned if the controller doesn't exist. - try_break() + check_health() // Keep processing us until we've done all there is for us to do in life. - if(!neighbors.len && (health == maxHealth || health <= 0) && harvest && !is_locking(/datum/locking_category)) + if(!neighbors.len && (health == max_health || health <= 0) && harvest && !is_locking(/datum/locking_category)) SSplant.remove_plant(src) /obj/effect/plantsegment/proc/die_off() diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 2fe871e2928..5176dd61b90 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -21,7 +21,7 @@ autoignition_temperature = AUTOIGNITION_WOOD fire_fuel = 10 - health = 50 + var/health = 50 var/tmp/busy = 0 var/list/valid_types = list(/obj/item/weapon/book, \ /obj/item/weapon/tome, \ diff --git a/code/modules/mining/mine_structures.dm b/code/modules/mining/mine_structures.dm index 205079c9e76..3f8b8a137e0 100644 --- a/code/modules/mining/mine_structures.dm +++ b/code/modules/mining/mine_structures.dm @@ -25,23 +25,6 @@ var/start_with_lantern = /obj/item/device/flashlight/lantern/on var/busy = 0 - health = 60 - breakable_flags = BREAKABLE_ALL - damage_armor = BREAKARMOR_MEDIUM - damage_resist = BREAKARMOR_WEAK - damaged_examine_text = "It is dented." - take_hit_text = "denting" - take_hit_text2 = "dents" - breaks_text = "breaks apart" - glanced_sound = 'sound/items/trayhit1.ogg' - -/obj/structure/hanging_lantern/try_break() - if(health <= 0) - qdel(src) - return TRUE - else - return FALSE - /obj/structure/hanging_lantern/New(turf/T, var/build_dir) ..() @@ -105,9 +88,6 @@ update() return 1 - else - ..() - /obj/structure/hanging_lantern/update_icon() if(lantern) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 0663306b361..298c5459667 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -54,7 +54,7 @@ damage = run_armor_absorb(affecting, "melee", damage) - if(!T?.amount) + if(T.amount == 0) attacktype = "gummed" damage = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider/effects.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider/effects.dm index d3c16145799..ca165d6c573 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider/effects.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider/effects.dm @@ -6,7 +6,7 @@ desc = "It's stringy and sticky." anchored = 1 density = 0 - health = 15 + var/health = 15 gender = NEUTER w_type=NOT_RECYCLABLE mouse_opacity = 1 diff --git a/code/modules/power/solars/panel.dm b/code/modules/power/solars/panel.dm index dac50272f7b..476b0ae4007 100644 --- a/code/modules/power/solars/panel.dm +++ b/code/modules/power/solars/panel.dm @@ -2,8 +2,8 @@ icon_state = "sp_base" id_tag = 0 penetration_dampening = 1 // Fragile - health = 15 //Fragile shit, even with state-of-the-art reinforced glass - maxHealth = 15 //If ANYONE ever makes it so that solars can be directly repaired without glass, also used for fancy calculations + var/health = 15 //Fragile shit, even with state-of-the-art reinforced glass + var/maxhealth = 15 //If ANYONE ever makes it so that solars can be directly repaired without glass, also used for fancy calculations var/obscured = 0 var/sunfrac = 0 var/adir = SOUTH @@ -28,7 +28,7 @@ solar_assembly = S var/obj/item/stack/sheet/glass/G = solar_assembly.glass_type //This is how you call up variables from an object without making one src.glass_quality_factor = initial(G.glass_quality) //Don't use istype checks kids - src.maxHealth = initial(G.shealth) + src.maxhealth = initial(G.shealth) src.health = initial(G.shealth) solar_assembly.forceMove(src) update_icon() @@ -70,7 +70,7 @@ /obj/machinery/power/solar/panel/proc/healthcheck() if(health <= 0) - if(!(stat & BROKEN) && health > -maxHealth) + if(!(stat & BROKEN) && health > -maxhealth) broken() else var/obj/item/stack/sheet/glass/G = solar_assembly.glass_type @@ -124,7 +124,7 @@ if(obscured) return - var/sgen = SOLARGENRATE * sunfrac * glass_quality_factor * (health / maxHealth) //Raw generating power * Sun angle effect * Glass quality * Current panel health. Simple but thorough + var/sgen = SOLARGENRATE * sunfrac * glass_quality_factor * (health / maxhealth) //Raw generating power * Sun angle effect * Glass quality * Current panel health. Simple but thorough add_avail(sgen) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 97e20dd6564..65f9a1f8132 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -2586,10 +2586,10 @@ dmg -= K.seed.toxins_tolerance*20 for(var/obj/effect/plantsegment/KV in orange(O,1)) KV.health -= dmg*0.4 - KV.try_break() + KV.check_health() SSplant.add_plant(KV) K.health -= dmg - K.try_break() + K.check_health() SSplant.add_plant(K) else if(istype(O,/obj/machinery/portable_atmospherics/hydroponics)) var/obj/machinery/portable_atmospherics/hydroponics/tray = O diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 3e1caa53e21..458440e5974 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -1,3 +1,4 @@ + //////////////////////////////////////////////////////////////////////////////// /// (Mixing) Glass. //////////////////////////////////////////////////////////////////////////////// @@ -89,8 +90,6 @@ playsound(target, 'sound/effects/slosh.ogg', 25, 1) //or in an hydro tray, then we make some noise. /obj/item/weapon/reagent_containers/glass/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(valid_item_attack(W, user)) - return ..() if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) if(istype(W, /obj/item/weapon/pen/fountain)) var/obj/item/weapon/pen/fountain/P = W @@ -112,20 +111,8 @@ origin_tech = Tc_MATERIALS + "=1" layer = ABOVE_OBJ_LAYER //So it always gets layered above pills and bottles - //Breakability: - health = 3 - breakable_flags = BREAKABLE_ALL - damage_armor = BREAKARMOR_FLIMSY - damage_resist = BREAKARMOR_NOARMOR - breakable_fragments = list(/obj/item/weapon/shard) - damaged_examine_text = "It is cracked." - take_hit_text = list("cracking", "chipping") - take_hit_text2 = list("cracks", "chips") - breaks_text = "shatters" - breaks_sound = 'sound/effects/Glassbr3.ogg' - /obj/item/weapon/reagent_containers/glass/beaker/attackby(obj/item/weapon/W, mob/user) - if(user.a_intent != I_HURT && src.type == /obj/item/weapon/reagent_containers/glass/beaker && istype(W, /obj/item/tool/surgicaldrill)) //regular beakers only + if(src.type == /obj/item/weapon/reagent_containers/glass/beaker && istype(W, /obj/item/tool/surgicaldrill)) //regular beakers only to_chat(user, "You begin drilling holes into the bottom of \the [src].") playsound(user, 'sound/machines/juicer.ogg', 50, 1) if(do_after(user, src, 60)) @@ -487,6 +474,7 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "blender_jug_e" volume = 100 + on_reagent_change() switch(src.reagents.total_volume) if(0) @@ -495,6 +483,7 @@ icon_state = "blender_jug_h" if(76 to 100) icon_state = "blender_jug_f" + /obj/item/weapon/reagent_containers/glass/canister //not used apparantly desc = "It's a canister. Mainly used for transporting fuel." name = "canister" @@ -504,10 +493,12 @@ m_amt = 300 g_amt = 0 w_class = W_CLASS_LARGE + amount_per_transfer_from_this = 20 possible_transfer_amounts = list(10,20,30,60) volume = 120 flags = FPRINT + /obj/item/weapon/reagent_containers/glass/dispenser name = "reagent glass" desc = "A reagent glass." @@ -515,12 +506,15 @@ icon_state = "beaker0" amount_per_transfer_from_this = 10 flags = FPRINT | OPENCONTAINER + /obj/item/weapon/reagent_containers/glass/dispenser/surfactant name = "reagent glass (surfactant)" icon_state = "liquid" + /obj/item/weapon/reagent_containers/glass/dispenser/surfactant/New() ..() reagents.add_reagent(FLUOROSURFACTANT, 20) + */ //No idea if this actually works anymore. Please handle carefully diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 0c8ae553d35..3f38952b4f3 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -505,7 +505,7 @@ layer = TABLE_LAYER flags = FPRINT | TWOHANDABLE | MUSTTWOHAND // If I end up being coherent enough to make it holdable in-hand var/list/exiting = list() // Manages people leaving the barrel - health = 50 + var/health = 50 /obj/structure/reagent_dispensers/cauldron/barrel/wood name = "wooden barrel" @@ -516,19 +516,15 @@ /obj/structure/reagent_dispensers/cauldron/barrel/update_icon() return -/obj/structure/reagent_dispensers/cauldron/barrel/take_damage(incoming_damage, damage_type, skip_break, mute, var/sound_effect = 1) //Custom take_damage() proc because of sound_effect behavior. - health = max(0, health - incoming_damage) +/obj/structure/reagent_dispensers/cauldron/barrel/proc/take_damage(var/damage, var/sound_effect = 1) + health = max(0, health - damage) if(sound_effect) playsound(loc, 'sound/effects/grillehit.ogg', 75, 1) - return try_break() - -/obj/structure/reagent_dispensers/cauldron/barrel/try_break() if(health <= 0) spawn(1) Destroy() - return TRUE - else - return FALSE + return 1 + return 0 /obj/structure/reagent_dispensers/cauldron/barrel/kick_act(mob/living/carbon/human/H) ..() @@ -624,7 +620,7 @@ if(2) Destroy() if(3) - take_damage(rand(15,45), sound_effect = 0) + take_damage(rand(15,45), 0) /obj/structure/reagent_dispensers/cauldron/barrel/attack_animal(var/mob/living/simple_animal/M) if(take_damage(rand(M.melee_damage_lower, M.melee_damage_upper))) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 318cc26b66e..414f0c06a2e 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -737,7 +737,7 @@ level = LEVEL_BELOW_FLOOR // underfloor only var/dpdir = 0 // bitmask of pipe directions dir = 0 // dir will contain dominant direction for junction pipes - health = 10 // health points 0-10 + var/health = 10 // health points 0-10 layer = DISPOSALS_PIPE_LAYER plane = ABOVE_TURF_PLANE //Set above turf for mapping preview only, supposed to be ABOVE_PLATING_PLANE, handled in New() var/base_icon_state // initial icon state on map diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 14456ffe780..356727fffad 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/machines/telecomms.dmi' icon_state = "server" var/datum/research/files - health = 100 + var/health = 100 var/list/id_with_upload = list() //List of R&D consoles with upload to server access. var/list/id_with_download = list() //List of R&D consoles with download from server access. var/id_with_upload_string = "" //String versions for easy editing in map editor. diff --git a/code/modules/research/xenoarchaeology/tools/anomaly_container.dm b/code/modules/research/xenoarchaeology/tools/anomaly_container.dm index 75bafc65b5d..2e0b317bc0f 100644 --- a/code/modules/research/xenoarchaeology/tools/anomaly_container.dm +++ b/code/modules/research/xenoarchaeology/tools/anomaly_container.dm @@ -9,7 +9,7 @@ var/obj/machinery/artifact/contained var/obj/item/weapon/paper/anomaly/report var/broken = FALSE - health = 1000 + var/health = 1000 /obj/structure/anomaly_container/Destroy() if (contained) diff --git a/code/modules/spacepods/spacepods.dm b/code/modules/spacepods/spacepods.dm index aaa24362573..51deedde4a2 100644 --- a/code/modules/spacepods/spacepods.dm +++ b/code/modules/spacepods/spacepods.dm @@ -39,8 +39,8 @@ var/locked = FALSE var/next_firetime = 0 var/list/pod_overlays - health = 400 - maxHealth = 400 + var/health = 400 + var/maxHealth = 400 var/lights_enabled = FALSE light_power = 2 light_range = SPACEPOD_LIGHTS_RANGE_OFF diff --git a/maps/RandomZLevels/hive.dm b/maps/RandomZLevels/hive.dm index a247c3a76ac..06c370bbfb6 100644 --- a/maps/RandomZLevels/hive.dm +++ b/maps/RandomZLevels/hive.dm @@ -501,7 +501,7 @@ anchored = TRUE density = TRUE - health = 10 + var/health = 10 var/gibtype = /obj/effect/gibspawner/robot /obj/structure/hive/proc/healthcheck() diff --git a/maps/metaclub.dmm b/maps/metaclub.dmm index dcb75dd385e..70a3425debb 100644 --- a/maps/metaclub.dmm +++ b/maps/metaclub.dmm @@ -18811,7 +18811,7 @@ /obj/machinery/bot/secbot/beepsky{ desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too. "; health = 45; - maxHealth = 45; + maxhealth = 45; name = "Officer Beepsky" }, /turf/simulated/floor, diff --git a/maps/randomvaults/objects.dm b/maps/randomvaults/objects.dm index a287f75ba91..31e3b0f2655 100644 --- a/maps/randomvaults/objects.dm +++ b/maps/randomvaults/objects.dm @@ -482,7 +482,7 @@ name = "Duey" desc = "Looks like a maintenance droid, repurposed for botany management. Seems the years haven't been too kind." health = 150 - maxHealth = 150 + maxhealth = 150 icon_state = "duey0" icon_initial = "duey" Max_Fertilizers = 50 diff --git a/vgstation13.dme b/vgstation13.dme index 10b5706b9ae..e2258ce3fd6 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -855,7 +855,6 @@ #include "code\game\mecha\working\clarke.dm" #include "code\game\mecha\working\ripley.dm" #include "code\game\mecha\working\working.dm" -#include "code\game\objects\breakable.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\explosion.dm" #include "code\game\objects\explosion_recursive.dm" @@ -907,6 +906,8 @@ #include "code\game\objects\items\beacon.dm" #include "code\game\objects\items\blueprints.dm" #include "code\game\objects\items\bodybag.dm" +#include "code\game\objects\items\breakable.dm" +#include "code\game\objects\items\breakable_test.dm" #include "code\game\objects\items\candle.dm" #include "code\game\objects\items\changeling_vial.dm" #include "code\game\objects\items\contraband.dm"