diff --git a/_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm b/_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm new file mode 100644 index 00000000000..fbdf10f74a1 --- /dev/null +++ b/_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm @@ -0,0 +1,327 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/shuttle/engine/heater{ + dir = 8 + }, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"c" = ( +/obj/machinery/door/airlock/external{ + id_tag = "s_docking_airlock"; + name = "Shuttle Hatch"; + req_access_txt = "109" + }, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"d" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/mob/living/simple_animal/hostile/retaliate/skeleton/warden{ + dir = 4 + }, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"e" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "burst_r" + }, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"f" = ( +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"g" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/shuttle/engine/heater{ + dir = 8 + }, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"h" = ( +/turf/simulated/wall/mineral/plastitanium, +/area/ruin/space/sec_shuttle) +"j" = ( +/obj/machinery/computer/nonfunctional{ + dir = 1 + }, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"m" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood, +/obj/effect/mob_spawn/human/corpse/skeleton/security_officer, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"n" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"o" = ( +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/shuttle/engine/heater{ + dir = 8 + }, +/turf/space, +/area/ruin/space/sec_shuttle) +"t" = ( +/obj/effect/decal/cleanable/blood, +/obj/effect/decal/cleanable/blood/footprints, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"w" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"y" = ( +/obj/effect/decal/cleanable/blood, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"z" = ( +/turf/space, +/area/template_noop) +"B" = ( +/obj/machinery/recharge_station/upgraded, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"D" = ( +/obj/machinery/computer/nonfunctional, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"E" = ( +/obj/structure/closet/crate/secure/sec_shuttle_ruin{ + name = "emergency supplies crate" + }, +/obj/item/gun/medbeam/damaged, +/obj/item/gun/projectile/automatic/pistol/enforcer, +/obj/item/grenade/flashbang, +/obj/item/storage/firstaid/regular, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"F" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/obj/effect/decal/cleanable/blood/footprints, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"G" = ( +/obj/effect/decal/cleanable/blood/splatter, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"H" = ( +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"J" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/footprints, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"N" = ( +/obj/effect/mob_spawn/human/corpse/skeleton/prisoner, +/turf/space, +/area/space/nearstation) +"Q" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/obj/effect/mob_spawn/human/corpse/skeleton/security_officer, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"R" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"S" = ( +/obj/machinery/computer/security{ + dir = 1; + network = list("SS13") + }, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) +"T" = ( +/obj/machinery/door/airlock/external{ + id_tag = "s_docking_airlock"; + name = "Shuttle Hatch"; + req_access_txt = "109" + }, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"U" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/space, +/area/ruin/space/sec_shuttle) +"V" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8 + }, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"X" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood, +/obj/effect/decal/cleanable/blood/footprints, +/turf/simulated/floor/plating/airless, +/area/ruin/space/sec_shuttle) +"Y" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "burst_l" + }, +/turf/space, +/area/ruin/space/sec_shuttle) +"Z" = ( +/obj/structure/computerframe, +/turf/simulated/floor/plasteel/airless{ + icon_state = "dark" + }, +/area/ruin/space/sec_shuttle) + +(1,1,1) = {" +z +z +z +Y +U +V +V +e +"} +(2,1,1) = {" +z +z +z +h +o +g +a +h +"} +(3,1,1) = {" +z +z +z +h +D +d +j +h +"} +(4,1,1) = {" +z +z +z +h +Z +f +S +h +"} +(5,1,1) = {" +z +z +z +h +B +f +Q +h +"} +(6,1,1) = {" +z +z +z +c +H +H +w +h +"} +(7,1,1) = {" +z +z +z +c +G +J +F +h +"} +(8,1,1) = {" +N +z +z +t +X +J +R +h +"} +(9,1,1) = {" +z +z +z +y +m +n +E +h +"} +(10,1,1) = {" +z +z +z +h +h +H +h +h +"} +(11,1,1) = {" +z +z +z +z +h +T +h +z +"} diff --git a/code/datums/particles.dm b/code/datums/particles.dm index 01206630faa..2b2dca7e396 100644 --- a/code/datums/particles.dm +++ b/code/datums/particles.dm @@ -107,3 +107,21 @@ velocity = generator(GEN_CIRCLE, 30, 30) scale = 0.1 friction = 0.1 + +/particles/fire_particles + icon = 'icons/effects/particles/generic_particles.dmi' + icon_state = "bonfire" + width = 100 + height = 100 + count = 1000 + spawning = 8 + lifespan = 0.7 SECONDS + fade = 1 SECONDS + grow = -0.01 + velocity = list(0, 0) + position = generator("box", list(-16, -16), list(16, 16), NORMAL_RAND) + drift = generator("vector", list(0, -0.2), list(0, 0.2)) + gravity = list(0, 0.95) + scale = generator("vector", list(0.3, 0.3), list(1,1), NORMAL_RAND) + rotation = 30 + spin = generator("num", -20, 20) diff --git a/code/datums/ruins/space_ruins.dm b/code/datums/ruins/space_ruins.dm index 41d93e14769..03e494504d8 100644 --- a/code/datums/ruins/space_ruins.dm +++ b/code/datums/ruins/space_ruins.dm @@ -360,3 +360,10 @@ name = "Dorian Casino" description = "A swanky space casino." allow_duplicates = FALSE + +/datum/map_template/ruin/space/abandoned_security_shuttle + id = "abandoned_sec_shuttle" + suffix = "abandoned_sec_shuttle.dmm" + name = "Abandoned Security Shuttle" + description = "A security shuttle that has been floating in space." + allow_duplicates = FALSE diff --git a/code/game/area/areas/ruins/space_areas.dm b/code/game/area/areas/ruins/space_areas.dm index af8b7c6f9eb..24c22722040 100644 --- a/code/game/area/areas/ruins/space_areas.dm +++ b/code/game/area/areas/ruins/space_areas.dm @@ -244,3 +244,7 @@ /area/ruin/space/deepstorage name = "Derelict Facility" apc_starts_off = TRUE + +/area/ruin/space/sec_shuttle + name = "Abandoned Security Shuttle" + apc_starts_off = TRUE diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 60107130674..4a9e2500c02 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -181,6 +181,7 @@ if(parent) UnregisterSignal(parent, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) QDEL_NULL(particles) + holding_parent = null parent.vis_contents -= src return ..() @@ -206,9 +207,9 @@ // Add new if(isitem(attached_to) && ismob(attached_to.loc)) //special case we want to also be emitting from the mob - var/mob/particle_mob = attached_to.loc + holding_parent = attached_to.loc last_attached_location_type = attached_to.loc - particle_mob.vis_contents += src + holding_parent.vis_contents += src // Readd to ourselves attached_to.vis_contents |= src diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index bf36273ab16..733cb21fbd6 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -678,3 +678,24 @@ log_admin(msg) #undef RECURSION_PANIC_AMOUNT + +/obj/structure/closet/crate/secure/sec_shuttle_ruin + name = "locked crate" + desc = "The side of the crate has a slot for a keycard to be swiped." + can_be_emaged = FALSE + +/obj/structure/closet/crate/secure/sec_shuttle_ruin/allowed(mob/user) + if(!user) + return + + var/obj/item/card/sec_shuttle_ruin/keycard = user.get_active_hand() + if(!istype(keycard)) + return + + to_chat(user, "You swipe [keycard] in [src]'s keycard slot.") + return TRUE + +/obj/item/card/sec_shuttle_ruin + name = "warden's card" + desc = "A card used by the warden to unlock their crate." + icon_state = "data" diff --git a/code/modules/awaymissions/mob_spawn.dm b/code/modules/awaymissions/mob_spawn.dm index ea51fed28d8..1741cdb69f1 100644 --- a/code/modules/awaymissions/mob_spawn.dm +++ b/code/modules/awaymissions/mob_spawn.dm @@ -379,6 +379,20 @@ flavour_text = "By unknown powers, your skeletal remains have been reanimated! Walk this mortal plain and terrorize all living adventurers who dare cross your path." assignedrole = "Skeleton" +/obj/effect/mob_spawn/human/corpse/skeleton/security_officer + outfit = /datum/outfit/job/officer + id_access = "Assistant" //no brig access for explorers + +/obj/effect/mob_spawn/human/corpse/skeleton/prisoner + uniform = /obj/item/clothing/under/color/orange/prison + shoes = /obj/item/clothing/shoes/orange + +/obj/effect/mob_spawn/human/corpse/skeleton/prisoner/equip(mob/living/carbon/human/prisoner) //put cuffs on the corpse + . = ..() + var/obj/item/restraints/handcuffs/cuffs = new(prisoner) + prisoner.handcuffed = cuffs + prisoner.update_handcuffed() + //////////Corpses, they can be used for "decoration" purpose.////////// //Default Abductor corpse. diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm index 063ac6b55ea..2807b0860ee 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm @@ -76,6 +76,43 @@ del_on_death = TRUE footstep_type = FOOTSTEP_MOB_SHOE +/mob/living/simple_animal/hostile/retaliate/skeleton/warden + name = "skeleton warden" + desc = "The remains of a warden." + icon = 'icons/mob/simple_human.dmi' + icon_state = "skeleton_warden" + icon_living = "skeleton_warden" + wander = FALSE + loot = list(/obj/effect/decal/cleanable/shreds, /mob/living/simple_animal/hostile/skeleton/angered_warden) + maxHealth = 300 + health = 300 + melee_damage_lower = 15 + melee_damage_upper = 15 + deathmessage = null + +/mob/living/simple_animal/hostile/retaliate/skeleton/warden/Process_Spacemove(movement_dir) + return TRUE + +/mob/living/simple_animal/hostile/skeleton/angered_warden + name = "angered skeleton warden" //round 2 + desc = "An angry skeleton." + icon = 'icons/mob/simple_human.dmi' + icon_state = "skeleton_warden_alt" + icon_living = "skeleton_warden_alt" + + attacktext = "claws" + attack_sound = 'sound/hallucinations/growl1.ogg' + + maxHealth = 200 + health = 200 + speed = -1 + melee_damage_lower = 30 + melee_damage_upper = 30 + loot = list(/obj/effect/decal/remains/human, /obj/item/clothing/head/warden, /obj/item/card/sec_shuttle_ruin) + +/mob/living/simple_animal/hostile/skeleton/angered_warden/Process_Spacemove(movement_dir) + return TRUE + /mob/living/simple_animal/hostile/retaliate/zombie name = "zombie" icon = 'icons/mob/human.dmi' diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index d8f6535a23b..ba949775de1 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -10,14 +10,23 @@ throw_speed = 2 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - var/charge = 0 // note %age conveted to actual charge in New + ///How much charge the battery currently has + var/charge = 0 + ///How much charge the battery can hold var/maxcharge = 1000 + ///How much charge the battery should start with + var/starting_charge materials = list(MAT_METAL = 700, MAT_GLASS = 50) - var/rigged = FALSE // true if rigged to explode - var/chargerate = 100 //how much power is given every tick in a recharger - var/self_recharge = 0 //does it self recharge, over time, or not? + ///If the battery will explode + var/rigged = FALSE + ///How much charge is given every tick when recharging + var/chargerate = 100 + ///Whether it will recharge automatically + var/self_recharge = TRUE + ///Whether the description will include the maxcharge var/ratingdesc = TRUE - var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it. + ///Additional overlay to signify battery being organic + var/grown_battery = FALSE /obj/item/stock_parts/cell/get_cell() return src @@ -25,7 +34,7 @@ /obj/item/stock_parts/cell/New() ..() START_PROCESSING(SSobj, src) - charge = maxcharge + charge = !isnull(starting_charge) ? starting_charge : maxcharge if(ratingdesc) desc += " This one has a power rating of [DisplayPower(maxcharge)], and you should not swallow it." update_icon(UPDATE_OVERLAYS) @@ -164,9 +173,8 @@ return 0 // Cell variants -/obj/item/stock_parts/cell/empty/New() - ..() - charge = 0 +/obj/item/stock_parts/cell/empty + starting_charge = 0 /obj/item/stock_parts/cell/crap name = "\improper Nanotrasen brand rechargeable AA battery" @@ -175,10 +183,8 @@ materials = list(MAT_GLASS = 40) rating = 2 -/obj/item/stock_parts/cell/crap/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/crap/empty + starting_charge = 0 /obj/item/stock_parts/cell/upgraded name = "upgraded power cell" @@ -200,10 +206,8 @@ materials = list(MAT_GLASS = 40) rating = 2.5 -/obj/item/stock_parts/cell/secborg/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/secborg/empty + starting_charge = 0 /obj/item/stock_parts/cell/hos_gun name = "\improper X-01 multiphase energy gun power cell" @@ -242,10 +246,8 @@ maxcharge = 15000 chargerate = 2250 -/obj/item/stock_parts/cell/high/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/high/empty + starting_charge = 0 /obj/item/stock_parts/cell/super name = "super-capacity power cell" @@ -256,10 +258,8 @@ rating = 4 chargerate = 2000 -/obj/item/stock_parts/cell/super/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/super/empty + starting_charge = 0 /obj/item/stock_parts/cell/hyper name = "hyper-capacity power cell" @@ -270,10 +270,8 @@ rating = 5 chargerate = 3000 -/obj/item/stock_parts/cell/hyper/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/hyper/empty + starting_charge = 0 /obj/item/stock_parts/cell/bluespace name = "bluespace power cell" @@ -285,10 +283,8 @@ rating = 6 chargerate = 4000 -/obj/item/stock_parts/cell/bluespace/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/bluespace/empty + starting_charge = 0 /obj/item/stock_parts/cell/bluespace/charging name = "self-charging bluespace power cell" @@ -352,10 +348,8 @@ maxcharge = 500 rating = 3 -/obj/item/stock_parts/cell/emproof/empty/New() - ..() - charge = 0 - update_icon(UPDATE_OVERLAYS) +/obj/item/stock_parts/cell/emproof/empty + starting_charge = 0 /obj/item/stock_parts/cell/emproof/emp_act(severity) return diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index 945960fbb94..6c5836846ce 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -79,7 +79,7 @@ return if(current_target) - on_beam_tick(current_target) + on_beam_tick(source, current_target) /obj/item/gun/medbeam/proc/los_check(mob/user,mob/target) var/turf/user_turf = user.loc @@ -105,7 +105,7 @@ qdel(dummy) return TRUE -/obj/item/gun/medbeam/proc/on_beam_tick(mob/living/target) +/obj/item/gun/medbeam/proc/on_beam_tick(mob/living/user, mob/living/target) if(ishuman(target)) var/mob/living/carbon/human/H = target H.adjustBruteLoss(-4, robotic = TRUE) @@ -124,3 +124,224 @@ /obj/effect/ebeam/medical name = "medical beam" + +//Damaged beamgun loot, DO NOT let it break +#define SCREWDRIVER_OPEN 8 +#define REMOVE_OLD_PARTS 7 +#define WELD_SHELL 6 +#define INSTALL_LENS 5 +#define INSTALL_ELECTRONICS 4 +#define INSTALL_CELL 3 +#define MULTITOOL_ELECTRONICS 2 +#define SCREWDRIVER_CLOSED 1 + +/obj/item/gun/medbeam/damaged + name = "damaged beamgun" + desc = "Delivers volatile medical nanites in a focused beam. Don't cross the beams! It is damaged and will rapidly overheat." + ///How hot the beamgun is, if it hits max heat it will break + var/current_heat = 0 + ///How much heat the beamgun needs to break + var/max_heat = 50 + ///when current_heat / max_heat > damaging_heat_percent, it will burn the wielders hands + var/damaging_heat_percent = 0.6 + ///If the gun has overheated and broke down + var/broken = FALSE + ///If the gun is still too hot to repair + var/overheated = FALSE + var/obj/effect/abstract/particle_holder/fire_particles + +/obj/item/gun/medbeam/damaged/Destroy() + . = ..() + if(fire_particles) + QDEL_NULL(fire_particles) + +/obj/item/gun/medbeam/damaged/examine(mob/user) //The 8 Trials of Asclepius + . = ..() + if(!broken) + return + + . += "It is broken, and will not function without repairs." + switch(broken) + if(SCREWDRIVER_OPEN) + . += "The panel can be screwed open to access the internals." + if(REMOVE_OLD_PARTS) + . += "The old fried electronics and melted lens have to be pried out." + if(WELD_SHELL) + . += "The distorted shell needs to be welded back to form." + if(INSTALL_LENS) + . += "It needs a new glass lens." + if(INSTALL_ELECTRONICS) + . += "It needs new cabling for the electronics." + if(INSTALL_CELL) + . += "It needs a fully charged specialized battery to function." + if(MULTITOOL_ELECTRONICS) + . += "The electronics need to be tested and reactivated with a multitool." + if(SCREWDRIVER_CLOSED) + . += "The panel needs to be screwed shut before it is usable." + +/obj/item/gun/medbeam/damaged/process() + . = ..() + if(current_target) + return + + current_heat = max(current_heat - 1, 0) + +/obj/item/gun/medbeam/damaged/can_trigger_gun(mob/living/user) + if(broken) + to_chat(user, "[src] fails to start! It's broken!") + return FALSE + return ..() + +/obj/item/gun/medbeam/damaged/on_beam_tick(mob/living/user, mob/living/target) + . = ..() + if(current_heat >= max_heat) + user.visible_message("[src] pops as it shuts off!", "[src] pops and hisses as it shuts off. It is broken.") + broken = SCREWDRIVER_OPEN + user.adjust_fire_stacks(20) + user.IgniteMob() + LoseTarget() + update_fire_overlay(COLOR_ORANGE) + overheated = TRUE + return + + if(current_heat / max_heat > damaging_heat_percent) + to_chat(user, "[src] burns to hold!") + user.adjustFireLoss(0.1 * (current_heat / max_heat)) + + current_heat = min(current_heat + 1, max_heat) + +/obj/item/gun/medbeam/damaged/attackby(obj/item/attacking_item, mob/user, params) + . = ..() + + if(broken == INSTALL_CELL) + if(istype(attacking_item, /obj/item/stock_parts/cell/medbeam)) + var/obj/item/stock_parts/cell/medbeam/battery = attacking_item + if(battery.charge != battery.maxcharge) + to_chat(user, "[src] won't function without a fully charged [battery].") + return + to_chat(user, "You start replacing [src]'s battery.") + attempt_repair(user, attacking_item, MULTITOOL_ELECTRONICS) + return + + if(broken == INSTALL_ELECTRONICS) + if(istype(attacking_item, /obj/item/stack/cable_coil)) + to_chat(user, "You start replacing the fried electronics in [src].") + attempt_repair(user, attacking_item, INSTALL_CELL) + return + + if(broken == INSTALL_LENS) + if(istype(attacking_item, /obj/item/stack/sheet/glass)) + to_chat(user, "You start replacing the broken lens in [src].") + attempt_repair(user, attacking_item, INSTALL_ELECTRONICS) + return + +/obj/item/gun/medbeam/damaged/screwdriver_act(mob/user, obj/item/screwdriver) + if(broken == SCREWDRIVER_OPEN) + if(overheated) + to_chat(user, "[src] is still too hot for the screws to be safely removed from it.") + return + to_chat(user, "You start removing the screws from [src]'s shell.") + attempt_repair(user, screwdriver, REMOVE_OLD_PARTS) + return TRUE + + if(broken == SCREWDRIVER_CLOSED) + to_chat(user, "You start replacing the screws on [src]'s shell.") + attempt_repair(user, screwdriver, FALSE) + return TRUE + +/obj/item/gun/medbeam/damaged/crowbar_act(mob/living/user, obj/item/crowbar) + if(broken == REMOVE_OLD_PARTS) + to_chat(user, "You start prying out the old electronics and lens from [src].") + attempt_repair(user, crowbar, WELD_SHELL) + return TRUE + +/obj/item/gun/medbeam/damaged/welder_act(mob/living/user, obj/item/welder) + . = ..() + if(broken == WELD_SHELL) + if(!welder.tool_start_check(src, user, 1)) + to_chat(user, "[welder] isn't functioning.") + return + to_chat(user, "You start welding [src] back to form.") + attempt_repair(user, welder, INSTALL_LENS) + return TRUE + +/obj/item/gun/medbeam/damaged/multitool_act(mob/living/user, obj/item/multitool) + if(broken == MULTITOOL_ELECTRONICS) + if(user.electrocute_act(rand(1, 10), src)) + do_sparks(6, FALSE, user) + return TRUE + to_chat(user, "You start to activate the electronics in [src].") + attempt_repair(user, multitool, SCREWDRIVER_CLOSED) + return TRUE + +/obj/item/gun/medbeam/damaged/proc/update_fire_overlay(new_color) + if(!fire_particles) + fire_particles = new(src, /particles/fire_particles) + fire_particles.color = COLOR_RED + + animate(fire_particles, 20 SECONDS, color = COLOR_ORANGE) + animate(fire_particles, 10 SECONDS, color = COLOR_GRAY, delay = 20 SECONDS) + addtimer(VARSET_CALLBACK(src, overheated, FALSE), 30 SECONDS) + +/obj/item/gun/medbeam/damaged/proc/attempt_repair(mob/living/user, obj/item/tool_used, next_broken_state) + if(!do_after_once(user, 5 SECONDS, TRUE, src)) + to_chat(user, "You stop repairing [src].") + return + + if(!user.Adjacent(src)) + return + + if(!user.get_active_hand() == tool_used) + return + + switch(broken) + if(REMOVE_OLD_PARTS) + user.put_in_hands(new /obj/item/stock_parts/cell/medbeam) + + if(WELD_SHELL) + if(!tool_used.tool_use_check(user, 1)) + return + + if(INSTALL_LENS) + var/obj/item/stack/sheet/glass/lens = tool_used + if(!istype(lens)) + return + if(!lens.use(5)) + to_chat(user, "You need [5 - lens.get_amount()] more [lens] to repair [src]'s electronics.") + return + + if(INSTALL_ELECTRONICS) + var/obj/item/stack/cable_coil/cable = tool_used + if(!istype(cable)) + return + if(!cable.use(10)) + to_chat(user, "You need [10 - cable.get_amount()] more [cable] to repair [src]'s electronics.") + return + + if(INSTALL_CELL) + var/obj/item/stock_parts/cell/medbeam/battery = tool_used + if(!istype(battery)) + return + if(!user.get_active_hand() == battery) + to_chat(user, "You lost [src]'s battery.") + return + qdel(battery) + + if(SCREWDRIVER_CLOSED) + QDEL_NULL(fire_particles) + + broken = next_broken_state + +#undef SCREWDRIVER_OPEN +#undef REMOVE_OLD_PARTS +#undef WELD_SHELL +#undef INSTALL_LENS +#undef INSTALL_ELECTRONICS +#undef INSTALL_CELL +#undef MULTITOOL_ELECTRONICS +#undef SCREWDRIVER_CLOSED + +/obj/item/stock_parts/cell/medbeam + name = "beamgun cell" + desc = "A cell that fell out of a beamgun. It cannot be reused until fully charged. Only this brand of battery is compatible with medical beamguns." + starting_charge = 0 diff --git a/config/example/config.toml b/config/example/config.toml index 0ed2c1da0de..83d590b8759 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -682,6 +682,7 @@ active_space_ruins = [ "_maps/map_files/RandomRuins/SpaceRuins/telecomns_returns.dmm", "_maps/map_files/RandomRuins/SpaceRuins/casino.dmm", "_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm", ### The following ruins are based from past pre-spawned Zlevel content ### "_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm", diff --git a/icons/effects/particles/generic_particles.dmi b/icons/effects/particles/generic_particles.dmi index e322afcebbe..0eda2ecc2d6 100644 Binary files a/icons/effects/particles/generic_particles.dmi and b/icons/effects/particles/generic_particles.dmi differ diff --git a/icons/mob/simple_human.dmi b/icons/mob/simple_human.dmi index dd33948a4ca..16eb7497229 100644 Binary files a/icons/mob/simple_human.dmi and b/icons/mob/simple_human.dmi differ