diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index d8c4c69e0a..aa334224ad 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -288,4 +288,18 @@ var/global/list/##LIST_NAME = list();\ #define IS_SCREWDRIVER "screwdriver" #define IS_CROWBAR "crowbar" #define IS_WIRECUTTER "wirecutter" -#define IS_WRENCH "wrench" \ No newline at end of file +#define IS_WRENCH "wrench" + +// RCD modes. Used on the RCD, and gets passed to an object's rcd_act() when an RCD is used on it, to determine what happens. +#define RCD_FLOORWALL "Floor / Wall" // Builds plating on space/ground/open tiles. Builds a wall when on floors. Finishes walls when used on girders. +#define RCD_AIRLOCK "Airlock" // Builds an airlock on the tile if one isn't already there. +#define RCD_WINDOWGRILLE "Window / Grille" // Builds a full tile window and grille pair on floors. +#define RCD_DECONSTRUCT "Deconstruction" // Removes various things. Still consumes compressed matter. + +#define RCD_VALUE_MODE "mode" +#define RCD_VALUE_DELAY "delay" +#define RCD_VALUE_COST "cost" + + +#define RCD_SHEETS_PER_MATTER_UNIT 4 // Each physical material sheet is worth four matter units. +#define RCD_MAX_CAPACITY 30 * RCD_SHEETS_PER_MATTER_UNIT \ No newline at end of file diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index 8d2edbeeb9..bf38ab7a1c 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -15,6 +15,7 @@ bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0") bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA bar.pixel_y = 32 + bar.plane = PLANE_PLAYER_HUD src.user = user if(user) client = user.client diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 983c92cdf5..d1289a23de 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -209,6 +209,16 @@ /atom/proc/fire_act() return + +// Returns an assoc list of RCD information. +// Example would be: list(RCD_VALUE_MODE = RCD_DECONSTRUCT, RCD_VALUE_DELAY = 50, RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 4) +// This occurs before rcd_act() is called, and it won't be called if it returns FALSE. +/atom/proc/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + return FALSE + +/atom/proc/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + return + /atom/proc/melt() return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 327b1e11cd..541e461f27 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1260,3 +1260,24 @@ About the new airlock wires panel: src.open() src.lock() return + + +/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + // Old RCD code made it cost 10 units to decon an airlock. + // Now the new one costs ten "sheets". + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 5 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 10 + ) + return FALSE + +/obj/machinery/door/airlock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + qdel(src) + return TRUE + return FALSE diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index dd4472282c..73bddbb433 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -244,100 +244,43 @@ equip_cooldown = 10 energy_drain = 250 range = MELEE|RANGED - var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. - var/disabled = 0 //malf - equip_type = EQUIP_SPECIAL + var/obj/item/weapon/rcd/electric/mounted/mecha/my_rcd = null + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/initialize() + my_rcd = new(src) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/Destroy() + QDEL_NULL(my_rcd) + return ..() /obj/item/mecha_parts/mecha_equipment/tool/rcd/action(atom/target) - if(istype(target,/area/shuttle)||istype(target, /turf/space/transit))//>implying these are ever made -Sieve - disabled = 1 - else - disabled = 0 - if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock)) - target = get_turf(target) - if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return - playsound(chassis, 'sound/machines/click.ogg', 50, 1) - //meh - switch(mode) - if(0) - if (istype(target, /turf/simulated/wall)) - occupant_message("Deconstructing [target]...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - target:ChangeTurf(/turf/simulated/floor/plating) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.use_power(energy_drain) - else if (istype(target, /turf/simulated/floor)) - occupant_message("Deconstructing [target]...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - target:ChangeTurf(get_base_turf_by_area(target)) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.use_power(energy_drain) - else if (istype(target, /obj/machinery/door/airlock)) - occupant_message("Deconstructing [target]...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - qdel(target) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.use_power(energy_drain) - if(1) - if(istype(target, /turf/space) || istype(target,get_base_turf_by_area(target))) - occupant_message("Building Floor...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - target:ChangeTurf(/turf/simulated/floor/plating) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.spark_system.start() - chassis.use_power(energy_drain*2) - else if(istype(target, /turf/simulated/floor)) - occupant_message("Building Wall...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - target:ChangeTurf(/turf/simulated/wall) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.spark_system.start() - chassis.use_power(energy_drain*2) - if(2) - if(istype(target, /turf/simulated/floor)) - occupant_message("Building Airlock...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) - T.autoclose = 1 - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - playsound(target, 'sound/effects/sparks2.ogg', 50, 1) - chassis.use_power(energy_drain*2) - return + if(!action_checks(target) || get_dist(chassis, target) > 3) + return FALSE + + my_rcd.use_rcd(target, chassis.occupant) /obj/item/mecha_parts/mecha_equipment/tool/rcd/Topic(href,href_list) ..() if(href_list["mode"]) - mode = text2num(href_list["mode"]) - switch(mode) - if(0) - occupant_message("Switched RCD to Deconstruct.") - if(1) - occupant_message("Switched RCD to Construct.") - if(2) - occupant_message("Switched RCD to Construct Airlock.") - return - + my_rcd.mode_index = text2num(href_list["mode"]) + occupant_message("RCD reconfigured to '[my_rcd.modes[my_rcd.mode_index]]'.") +/* /obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() return "[..()] \[D|C|A\]" +*/ +/obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() + var/list/content = list(..()) // This is all for one line, in the interest of string tree conservation. + var/i = 1 + content += "
" + for(var/mode in my_rcd.modes) + content += " [mode]" + if(i < my_rcd.modes.len) + content += "
" + i++ - + return content.Join() /obj/item/mecha_parts/mecha_equipment/teleporter diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index d9543fed20..a0587d5dbb 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -1,167 +1,291 @@ -//Contains the rapid construction device. +// Contains the rapid construction device. /obj/item/weapon/rcd name = "rapid construction device" - desc = "A device used to rapidly build walls and floors." - icon = 'icons/obj/items.dmi' + desc = "A device used to rapidly build and deconstruct. Reload with compressed matter cartridges." + icon = 'icons/obj/tools.dmi' icon_state = "rcd" - opacity = 0 - density = 0 - anchored = 0.0 - flags = CONDUCT - force = 10.0 - throwforce = 10.0 + item_state = "rcd" + flags = CONDUCT | NOBLUDGEON + force = 10 + throwforce = 10 throw_speed = 1 throw_range = 5 w_class = ITEMSIZE_NORMAL origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2) matter = list(DEFAULT_WALL_MATERIAL = 50000) - preserve_item = 1 + preserve_item = TRUE // RCDs are pretty important. var/datum/effect/effect/system/spark_spread/spark_system var/stored_matter = 0 - var/max_stored_matter = 30 - var/working = 0 - var/mode = 1 - var/list/modes = list("Floor & Walls","Airlock","Deconstruct") - var/canRwall = 0 - var/disabled = 0 + var/max_stored_matter = RCD_MAX_CAPACITY + var/ranged = FALSE + var/busy = FALSE + var/allow_concurrent_building = FALSE // If true, allows for multiple RCD builds at the same time. + var/mode_index = 1 + var/list/modes = list(RCD_FLOORWALL, RCD_AIRLOCK, RCD_WINDOWGRILLE, RCD_DECONSTRUCT) + var/can_remove_rwalls = FALSE + var/airlock_type = /obj/machinery/door/airlock + var/window_type = /obj/structure/window/reinforced/full + var/material_to_use = DEFAULT_WALL_MATERIAL // So badmins can make RCDs that print diamond walls. + var/make_rwalls = FALSE // If true, when building walls, they will be reinforced. -/obj/item/weapon/rcd/attack() - return 0 - -/obj/item/weapon/rcd/proc/can_use(var/mob/user,var/turf/T) - var/usable = 0 - if(user.Adjacent(T) && user.get_active_hand() == src && !user.stat && !user.restrained()) - usable = 1 - if(!user.IsAdvancedToolUser() && istype(user, /mob/living/simple_animal)) - var/mob/living/simple_animal/S = user - if(!S.IsHumanoidToolUser(src)) - usable = 0 - return usable - -/obj/item/weapon/rcd/examine() - ..() - if(src.type == /obj/item/weapon/rcd && loc == usr) - usr << "It currently holds [stored_matter]/[max_stored_matter] matter-units." - -/obj/item/weapon/rcd/New() - ..() +/obj/item/weapon/rcd/initialize() src.spark_system = new /datum/effect/effect/system/spark_spread spark_system.set_up(5, 0, src) spark_system.attach(src) + return ..() /obj/item/weapon/rcd/Destroy() - qdel(spark_system) + QDEL_NULL(spark_system) spark_system = null return ..() -/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user) +/obj/item/weapon/rcd/examine(mob/user) + ..() + to_chat(user, display_resources()) +// Used to show how much stuff (matter units, cell charge, etc) is left inside. +/obj/item/weapon/rcd/proc/display_resources() + return "It currently holds [stored_matter]/[max_stored_matter] matter-units." + +// Used to add new cartridges. +/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user) if(istype(W, /obj/item/weapon/rcd_ammo)) var/obj/item/weapon/rcd_ammo/cartridge = W if((stored_matter + cartridge.remaining) > max_stored_matter) - to_chat(user, "The RCD can't hold that many additional matter-units.") - return + to_chat(user, span("warning", "The RCD can't hold that many additional matter-units.")) + return FALSE stored_matter += cartridge.remaining user.drop_from_inventory(W) qdel(W) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - to_chat(user, "The RCD now holds [stored_matter]/[max_stored_matter] matter-units.") - return - ..() + to_chat(user, span("notice", "The RCD now holds [stored_matter]/[max_stored_matter] matter-units.")) + return TRUE + return ..() -/obj/item/weapon/rcd/attack_self(mob/user) - //Change the mode - if(++mode > 3) mode = 1 - user << "Changed mode to '[modes[mode]]'" - playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - if(prob(20)) src.spark_system.start() - -/obj/item/weapon/rcd/afterattack(atom/A, mob/user, proximity) - if(!proximity) return - if(disabled && !isrobot(user)) - return 0 - if(istype(get_area(A),/area/shuttle)||istype(get_area(A),/turf/space/transit)) - return 0 - return alter_turf(A,user,(mode == 3)) - -/obj/item/weapon/rcd/proc/useResource(var/amount, var/mob/user) - if(stored_matter < amount) - return 0 - stored_matter -= amount - return 1 - -/obj/item/weapon/rcd/proc/alter_turf(var/turf/T,var/mob/user,var/deconstruct) - - var/build_cost = 0 - var/build_type - var/build_turf - var/build_delay - var/build_other - - if(working == 1) - return 0 - - if(mode == 3 && istype(T,/obj/machinery/door/airlock)) - build_cost = 10 - build_delay = 50 - build_type = "airlock" - else if(mode == 2 && !deconstruct && istype(T,/turf/simulated/floor)) - build_cost = 10 - build_delay = 50 - build_type = "airlock" - build_other = /obj/machinery/door/airlock - else if(!deconstruct && isturf(T) && (istype(T,/turf/space) || istype(T,get_base_turf_by_area(T)))) - build_cost = 1 - build_type = "floor" - build_turf = /turf/simulated/floor/airless - else if(!deconstruct && istype(T,/turf/simulated/mineral/floor)) - build_cost = 1 - build_type = "floor" - build_turf = /turf/simulated/floor/plating - else if(deconstruct && istype(T,/turf/simulated/wall)) - var/turf/simulated/wall/W = T - build_delay = deconstruct ? 50 : 40 - build_cost = 5 - build_type = (!canRwall && W.reinf_material) ? null : "wall" - build_turf = /turf/simulated/floor - else if(istype(T,/turf/simulated/floor) || (istype(T,/turf/simulated/mineral) && !T.density)) - var/turf/simulated/F = T - build_delay = deconstruct ? 50 : 20 - build_cost = deconstruct ? 10 : 3 - build_type = deconstruct ? "floor" : "wall" - build_turf = deconstruct ? get_base_turf_by_area(F) : /turf/simulated/wall - - if(!build_type) - working = 0 - return 0 - - if(!useResource(build_cost, user)) - user << "Insufficient resources." - return 0 - - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - - working = 1 - user << "[(deconstruct ? "Deconstructing" : "Building")] [build_type]..." - - if(build_delay && !do_after(user, build_delay)) - working = 0 - return 0 - - working = 0 - if(build_delay && !can_use(user,T)) - return 0 - - if(build_turf) - T.ChangeTurf(build_turf, preserve_outdoors = TRUE) - else if(build_other) - new build_other(T) +// Changes which mode it is on. +/obj/item/weapon/rcd/attack_self(mob/living/user) + if(mode_index >= modes.len) // Shouldn't overflow unless someone messes with it in VV poorly but better safe than sorry. + mode_index = 1 else - qdel(T) + mode_index++ - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - return 1 + to_chat(user, span("notice", "Changed mode to '[modes[mode_index]]'.")) + playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) + if(prob(20)) + src.spark_system.start() + +// Removes resources if the RCD can afford it. +/obj/item/weapon/rcd/proc/consume_resources(amount) + if(!can_afford(amount)) + return FALSE + stored_matter -= amount + return TRUE + +// Useful for testing before actually paying (e.g. before a do_after() ). +/obj/item/weapon/rcd/proc/can_afford(amount) + return stored_matter >= amount + +/obj/item/weapon/rcd/afterattack(atom/A, mob/living/user, proximity) + if(!ranged && !proximity) + return FALSE + use_rcd(A, user) + +// Used to call rcd_act() on the atom hit. +/obj/item/weapon/rcd/proc/use_rcd(atom/A, mob/living/user) + if(busy && !allow_concurrent_building) + to_chat(user, span("warning", "\The [src] is busy finishing its current operation, be patient.")) + return FALSE + + var/list/rcd_results = A.rcd_values(user, src, modes[mode_index]) + if(!rcd_results) + to_chat(user, span("warning", "\The [src] blinks a red light as you point it towards \the [A], indicating \ + that it won't work. Try changing the mode, or use it on something else.")) + return FALSE + if(!can_afford(rcd_results[RCD_VALUE_COST])) + to_chat(user, span("warning", "\The [src] lacks the required material to start.")) + return FALSE + + playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + + var/true_delay = rcd_results[RCD_VALUE_DELAY] * toolspeed + + var/datum/beam/rcd_beam = null + if(ranged) + var/atom/movable/beam_origin = user // This is needed because mecha pilots are inside an object and the beam won't be made if it tries to attach to them.. + if(!isturf(beam_origin.loc)) + beam_origin = user.loc + rcd_beam = beam_origin.Beam(A, icon_state = "rped_upgrade", time = max(true_delay, 5)) + busy = TRUE + + if(do_after(user, true_delay, target = A)) + busy = FALSE + // Doing another check in case we lost matter during the delay for whatever reason. + if(!can_afford(rcd_results[RCD_VALUE_COST])) + to_chat(user, span("warning", "\The [src] lacks the required material to finish the operation.")) + return FALSE + if(A.rcd_act(user, src, rcd_results[RCD_VALUE_MODE])) + consume_resources(rcd_results[RCD_VALUE_COST]) + playsound(get_turf(A), 'sound/items/deconstruct.ogg', 50, 1) + return TRUE + + // If they moved, kill the beam immediately. + qdel(rcd_beam) + busy = FALSE + return FALSE + +// RCD variants. + +// This one starts full. +/obj/item/weapon/rcd/loaded/initialize() + stored_matter = max_stored_matter + return ..() + +// This one makes cooler walls by using an alternative material. +/obj/item/weapon/rcd/shipwright + name = "shipwright's rapid construction device" + desc = "A device used to rapidly build and deconstruct. This version creates a stronger variant of wall, often \ + used in the construction of hulls for starships. Reload with compressed matter cartridges." + material_to_use = MAT_STEELHULL + +/obj/item/weapon/rcd/shipwright/loaded/initialize() + stored_matter = max_stored_matter + return ..() + + +/obj/item/weapon/rcd/advanced + name = "advanced rapid construction device" + desc = "A device used to rapidly build and deconstruct. This version works at a range, builds faster, and has a much larger capacity. \ + Reload with compressed matter cartridges." + icon_state = "adv_rcd" + ranged = TRUE + toolspeed = 0.5 // Twice as fast. + max_stored_matter = RCD_MAX_CAPACITY * 3 // Three times capacity. + +/obj/item/weapon/rcd/advanced/loaded/initialize() + stored_matter = max_stored_matter + return ..() + + +// Electric RCDs. +// Currently just a base for the mounted RCDs. +// Currently there isn't a way to swap out the cells. +// One could be added if there is demand to do so. +/obj/item/weapon/rcd/electric + name = "electric rapid construction device" + desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity, no matter cartridges needed." + icon_state = "electric_rcd" + var/obj/item/weapon/cell/cell = null + var/make_cell = TRUE // If false, initialize() won't spawn a cell for this. + var/electric_cost_coefficent = 83.33 // Higher numbers make it less efficent. 86.3... means it should matche the standard RCD capacity on a 10k cell. + +/obj/item/weapon/rcd/electric/initialize() + if(make_cell) + cell = new /obj/item/weapon/cell/high(src) + return ..() + +/obj/item/weapon/rcd/electric/Destroy() + if(cell) + QDEL_NULL(cell) + return ..() + +/obj/item/weapon/rcd/electric/get_cell() + return cell + +/obj/item/weapon/rcd/electric/can_afford(amount) // This makes it so borgs won't drain their last sliver of charge by mistake, as a bonus. + var/obj/item/weapon/cell/cell = get_cell() + if(cell) + return cell.check_charge(amount * electric_cost_coefficent) + return FALSE + +/obj/item/weapon/rcd/electric/consume_resources(amount) + if(!can_afford(amount)) + return FALSE + var/obj/item/weapon/cell/cell = get_cell() + return cell.checked_use(amount * electric_cost_coefficent) + +/obj/item/weapon/rcd/electric/display_resources() + var/obj/item/weapon/cell/cell = get_cell() + if(cell) + return "The power source connected to \the [src] has a charge of [cell.percent()]%." + return "It lacks a source of power, and cannot function." + + + +// 'Mounted' RCDs, used for borgs/RIGs/Mechas, all of which use their cells to drive the RCD. +/obj/item/weapon/rcd/electric/mounted + name = "mounted electric rapid construction device" + desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity from an external power source." + make_cell = FALSE + +/obj/item/weapon/rcd/electric/mounted/get_cell() + return get_external_power_supply() + +/obj/item/weapon/rcd/electric/mounted/proc/get_external_power_supply() + if(isrobot(loc)) // In a borg. + var/mob/living/silicon/robot/R = loc + return R.cell + if(istype(loc, /obj/item/rig_module)) // In a RIG. + var/obj/item/rig_module/module = loc + if(module.holder) // Is it attached to a RIG? + return module.holder.cell + if(istype(loc, /obj/item/mecha_parts/mecha_equipment)) // In a mech. + var/obj/item/mecha_parts/mecha_equipment/ME = loc + if(ME.chassis) // Is the part attached to a mech? + return ME.chassis.cell + return null + + +// RCDs for borgs. +/obj/item/weapon/rcd/electric/mounted/borg + can_remove_rwalls = TRUE + desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity, drawing directly from your cell." + electric_cost_coefficent = 41.66 // Twice as efficent, out of pity. + toolspeed = 0.5 // Twice as fast, since borg versions typically have this. + +/obj/item/weapon/rcd/electric/mounted/borg/lesser + can_remove_rwalls = FALSE + + +// RCDs for RIGs. +/obj/item/weapon/rcd/electric/mounted/rig + + +// RCDs for Mechs. +/obj/item/weapon/rcd/electric/mounted/mecha + ranged = TRUE + toolspeed = 0.5 + + +// Infinite use RCD for debugging/adminbuse. +/obj/item/weapon/rcd/debug + name = "self-repleshing rapid construction device" + desc = "An RCD that appears to be plated with gold. For some reason it also seems to just \ + be vastly superior to all other RCDs ever created, possibly due to it being colored gold." + icon_state = "debug_rcd" + ranged = TRUE + can_remove_rwalls = TRUE + allow_concurrent_building = TRUE + toolspeed = 0.25 // Four times as fast. + +/obj/item/weapon/rcd/debug/can_afford(amount) + return TRUE + +/obj/item/weapon/rcd/debug/consume_resources(amount) + return TRUE + +/obj/item/weapon/rcd/debug/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/weapon/rcd_ammo)) + to_chat(user, span("notice", "\The [src] makes its own material, no need to add more.")) + return FALSE + return ..() + +/obj/item/weapon/rcd/debug/display_resources() + return "It has UNLIMITED POWER!" + + + +// Ammo for the (non-electric) RCDs. /obj/item/weapon/rcd_ammo name = "compressed matter cartridge" desc = "Highly compressed matter for the RCD." @@ -171,50 +295,11 @@ w_class = ITEMSIZE_SMALL origin_tech = list(TECH_MATERIAL = 2) matter = list(DEFAULT_WALL_MATERIAL = 30000,"glass" = 15000) - var/remaining = 10 + var/remaining = RCD_MAX_CAPACITY / 3 /obj/item/weapon/rcd_ammo/large name = "high-capacity matter cartridge" desc = "Do not ingest." matter = list(DEFAULT_WALL_MATERIAL = 45000,"glass" = 22500) - remaining = 30 origin_tech = list(TECH_MATERIAL = 4) - -/obj/item/weapon/rcd/borg - canRwall = 1 - -/obj/item/weapon/rcd/borg/lesser - canRwall = FALSE - -/obj/item/weapon/rcd/borg/useResource(var/amount, var/mob/user) - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.cell) - var/cost = amount*30 - if(R.cell.charge >= cost) - R.cell.use(cost) - return 1 - return 0 - -/obj/item/weapon/rcd/borg/attackby() - return - -/obj/item/weapon/rcd/borg/can_use(var/mob/user,var/turf/T) - return (user.Adjacent(T) && !user.stat) - - -/obj/item/weapon/rcd/mounted/useResource(var/amount, var/mob/user) - var/cost = amount*130 //so that a rig with default powercell can build ~2.5x the stuff a fully-loaded RCD can. - if(istype(loc,/obj/item/rig_module)) - var/obj/item/rig_module/module = loc - if(module.holder && module.holder.cell) - if(module.holder.cell.charge >= cost) - module.holder.cell.use(cost) - return 1 - return 0 - -/obj/item/weapon/rcd/mounted/attackby() - return - -/obj/item/weapon/rcd/mounted/can_use(var/mob/user,var/turf/T) - return (user.Adjacent(T) && !user.stat && !user.restrained()) + remaining = RCD_MAX_CAPACITY diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index b61d01d2a4..058398d850 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -353,3 +353,54 @@ to_chat(user, "You drill through the girder!") new /obj/effect/decal/remains/human(get_turf(src)) dismantle() + + +/obj/structure/girder/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + var/turf/simulated/T = get_turf(src) + if(!istype(T) || T.density) + return FALSE + + switch(passed_mode) + if(RCD_FLOORWALL) + // Finishing a wall costs two sheets. + var/cost = RCD_SHEETS_PER_MATTER_UNIT * 2 + // Rwalls cost three to finish. + if(the_rcd.make_rwalls) + cost += RCD_SHEETS_PER_MATTER_UNIT * 1 + return list( + RCD_VALUE_MODE = RCD_FLOORWALL, + RCD_VALUE_DELAY = 2 SECONDS, + RCD_VALUE_COST = cost + ) + if(RCD_DECONSTRUCT) + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 2 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5 + ) + return FALSE + +/obj/structure/girder/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + var/turf/simulated/T = get_turf(src) + if(!istype(T) || T.density) // Should stop future bugs of people bringing girders to centcom and RCDing them, or somehow putting a girder on a durasteel wall and deconning it. + return FALSE + + switch(passed_mode) + if(RCD_FLOORWALL) + to_chat(user, span("notice", "You finish a wall.")) + // This is mostly the same as using on a floor. The girder's material is preserved, however. + T.ChangeTurf(/turf/simulated/wall) + var/turf/simulated/wall/new_T = get_turf(src) // Ref to the wall we just built. + // Apparently set_material(...) for walls requires refs to the material singletons and not strings. + // This is different from how other material objects with their own set_material(...) do it, but whatever. + var/material/M = name_to_material[the_rcd.material_to_use] + new_T.set_material(M, the_rcd.make_rwalls ? M : null, girder_material) + new_T.add_hiddenprint(user) + qdel(src) + return TRUE + + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + qdel(src) + return TRUE + diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index f8d532688c..50fa3e8c6e 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -96,7 +96,9 @@ /obj/structure/grille/attackby(obj/item/W as obj, mob/user as mob) if(!istype(W)) return - if(W.is_wirecutter()) + if(istype(W, /obj/item/weapon/rcd)) // To stop us from hitting the grille when building windows, because grilles don't let parent handle it properly. + return FALSE + else if(W.is_wirecutter()) if(!shock(user, 100)) playsound(src, W.usesound, 100, 1) new /obj/item/stack/rods(get_turf(src), destroyed ? 1 : 2) @@ -252,3 +254,38 @@ /obj/structure/grille/broken/rustic icon_state = "grillerustic-b" + + +/obj/structure/grille/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_WINDOWGRILLE) + // A full tile window costs 4 glass sheets. + return list( + RCD_VALUE_MODE = RCD_WINDOWGRILLE, + RCD_VALUE_DELAY = 2 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 4 + ) + + if(RCD_DECONSTRUCT) + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 2 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 2 + ) + return FALSE + +/obj/structure/grille/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + qdel(src) + return TRUE + if(RCD_WINDOWGRILLE) + if(locate(/obj/structure/window) in loc) + return FALSE + to_chat(user, span("notice", "You construct a window.")) + var/obj/structure/window/WD = new the_rcd.window_type(loc) + WD.anchored = TRUE + return TRUE + return FALSE + diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 5ada656156..5c7adf8f0e 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -647,3 +647,20 @@ MT.update_icon() return TRUE . = ..() + +/obj/structure/window/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 5 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5 + ) + +/obj/structure/window/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + qdel(src) + return TRUE + return FALSE diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index d80e5f249e..e3e955ff17 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -298,7 +298,7 @@ initial_flooring = /decl/flooring/tiling/asteroidfloor /turf/simulated/floor/tiled/asteroid_steel/airless - name = "airless plating" + name = "plating" oxygen = 0 nitrogen = 0 @@ -332,25 +332,25 @@ temperature = TCMB /turf/simulated/floor/airless - name = "airless plating" + name = "plating" oxygen = 0 nitrogen = 0 temperature = TCMB /turf/simulated/floor/tiled/airless - name = "airless floor" + name = "floor" oxygen = 0 nitrogen = 0 temperature = TCMB /turf/simulated/floor/bluegrid/airless - name = "airless floor" + name = "floor" oxygen = 0 nitrogen = 0 temperature = TCMB /turf/simulated/floor/greengrid/airless - name = "airless floor" + name = "floor" oxygen = 0 nitrogen = 0 temperature = TCMB @@ -359,7 +359,7 @@ oxygen = 0 /turf/simulated/floor/tiled/white/airless - name = "airless floor" + name = "floor" oxygen = 0 nitrogen = 0 temperature = TCMB diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 9f3a8e67b0..b615c0cc42 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -91,3 +91,71 @@ /turf/simulated/floor/levelupdate() for(var/obj/O in src) O.hide(O.hides_under_flooring() && src.flooring) + +/turf/simulated/floor/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_FLOORWALL) + // A wall costs four sheets to build (two for the grider and two for finishing it). + var/cost = RCD_SHEETS_PER_MATTER_UNIT * 4 + // R-walls cost five sheets, however. + if(the_rcd.make_rwalls) + cost += RCD_SHEETS_PER_MATTER_UNIT * 1 + return list( + RCD_VALUE_MODE = RCD_FLOORWALL, + RCD_VALUE_DELAY = 2 SECONDS, + RCD_VALUE_COST = cost + ) + if(RCD_AIRLOCK) + // Airlock assemblies cost four sheets. Let's just add another for the electronics/wires/etc. + return list( + RCD_VALUE_MODE = RCD_AIRLOCK, + RCD_VALUE_DELAY = 5 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5 + ) + if(RCD_WINDOWGRILLE) + // One steel sheet for the girder (two rods, which is one sheet). + return list( + RCD_VALUE_MODE = RCD_WINDOWGRILLE, + RCD_VALUE_DELAY = 1 SECOND, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1 + ) + if(RCD_DECONSTRUCT) + // Old RCDs made deconning the floor cost 10 units (IE, three times on full RCD). + // Now it's ten sheets worth of units (which is the same capacity-wise, three times on full RCD). + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = 5 SECONDS, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 10 + ) + return FALSE + + +/turf/simulated/floor/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_FLOORWALL) + to_chat(user, span("notice", "You build a wall.")) + ChangeTurf(/turf/simulated/wall) + var/turf/simulated/wall/T = get_turf(src) // Ref to the wall we just built. + // Apparently set_material(...) for walls requires refs to the material singletons and not strings. + // This is different from how other material objects with their own set_material(...) do it, but whatever. + var/material/M = name_to_material[the_rcd.material_to_use] + T.set_material(M, the_rcd.make_rwalls ? M : null, M) + T.add_hiddenprint(user) + return TRUE + if(RCD_AIRLOCK) + if(locate(/obj/machinery/door/airlock) in src) + return FALSE // No more airlock stacking. + to_chat(user, span("notice", "You build an airlock.")) + new the_rcd.airlock_type(src) + return TRUE + if(RCD_WINDOWGRILLE) + if(locate(/obj/structure/grille) in src) + return FALSE + to_chat(user, span("notice", "You construct the grille.")) + var/obj/structure/grille/G = new(src) + G.anchored = TRUE + return TRUE + if(RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + ChangeTurf(get_base_turf_by_area(src), preserve_outdoors = TRUE) + return TRUE diff --git a/code/game/turfs/simulated/outdoors/outdoors.dm b/code/game/turfs/simulated/outdoors/outdoors.dm index fc373c0577..968816dc6a 100644 --- a/code/game/turfs/simulated/outdoors/outdoors.dm +++ b/code/game/turfs/simulated/outdoors/outdoors.dm @@ -15,6 +15,7 @@ var/list/turf_edge_cache = list() edge_blending_priority = 1 outdoors = TRUE // This variable is used for weather effects. can_dirty = FALSE // Looks hideous with dirt on it. + can_build_into_floor = TRUE // When a turf gets demoted or promoted, this list gets adjusted. The top-most layer is the layer on the bottom of the list, due to how pop() works. var/list/turf_layers = list(/turf/simulated/floor/outdoors/rocks) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index b64ba73ee3..136b8eeba6 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -287,3 +287,27 @@ W.burn((temperature/4)) for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) D.ignite(temperature/4) + +/turf/simulated/wall/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + if(material.integrity > 1000) // Don't decon things like elevatorium. + return FALSE + if(reinf_material && !the_rcd.can_remove_rwalls) // Gotta do it the old fashioned way if your RCD can't. + return FALSE + + if(passed_mode == RCD_DECONSTRUCT) + var/delay_to_use = material.integrity / 3 // Steel has 150 integrity, so it'll take five seconds to down a regular wall. + if(reinf_material) + delay_to_use += reinf_material.integrity / 3 + return list( + RCD_VALUE_MODE = RCD_DECONSTRUCT, + RCD_VALUE_DELAY = delay_to_use, + RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5 + ) + return FALSE + +/turf/simulated/wall/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + if(passed_mode == RCD_DECONSTRUCT) + to_chat(user, span("notice", "You deconstruct \the [src].")) + ChangeTurf(/turf/simulated/floor/airless, preserve_outdoors = TRUE) + return TRUE + return FALSE diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index ed48013050..d9a41718a8 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -6,6 +6,7 @@ temperature = T20C thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT + can_build_into_floor = TRUE var/keep_sprite = FALSE // heat_capacity = 700000 No. diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 79550c3f30..0bfcb4e0f6 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -1,5 +1,6 @@ /turf/space/transit keep_sprite = TRUE + can_build_into_floor = FALSE var/pushdirection // push things that get caught in the transit tile this direction //Overwrite because we dont want people building rods in space. diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 8d26d11543..0c18524346 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -31,6 +31,7 @@ var/list/footstep_sounds = null var/block_tele = FALSE // If true, most forms of teleporting to or from this turf tile will fail. + var/can_build_into_floor = FALSE // Used for things like RCDs (and maybe lattices/floor tiles in the future), to see if a floor should replace it. /turf/New() ..() @@ -321,3 +322,28 @@ var/const/enterloopsanity = 100 /turf/AllowDrop() return TRUE + +// This is all the way up here since its the common ancestor for things that need to get replaced with a floor when an RCD is used on them. +// More specialized turfs like walls should instead override this. +// The code for applying lattices/floor tiles onto lattices could also utilize something similar in the future. +/turf/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + if(density || !can_build_into_floor) + return FALSE + if(passed_mode == RCD_FLOORWALL) + var/obj/structure/lattice/L = locate() in src + // A lattice costs one rod to make. A sheet can make two rods, meaning a lattice costs half of a sheet. + // A sheet also makes four floor tiles, meaning it costs 1/4th of a sheet to place a floor tile on a lattice. + // Therefore it should cost 3/4ths of a sheet if a lattice is not present, or 1/4th of a sheet if it does. + return list( + RCD_VALUE_MODE = RCD_FLOORWALL, + RCD_VALUE_DELAY = 0, + RCD_VALUE_COST = L ? RCD_SHEETS_PER_MATTER_UNIT * 0.25 : RCD_SHEETS_PER_MATTER_UNIT * 0.75 + ) + return FALSE + +/turf/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + if(passed_mode == RCD_FLOORWALL) + to_chat(user, span("notice", "You build a floor.")) + ChangeTurf(/turf/simulated/floor/airless, preserve_outdoors = TRUE) + return TRUE + return FALSE diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm index b4c1999b48..fe6a77cb08 100644 --- a/code/game/turfs/unsimulated.dm +++ b/code/game/turfs/unsimulated.dm @@ -4,6 +4,7 @@ nitrogen = MOLES_N2STANDARD initialized = TRUE // Don't call init on unsimulated turfs (at least not yet) +<<<<<<< HEAD //VOREStation Add /turf/unsimulated/fake_space name = "\proper space" @@ -14,4 +15,12 @@ /turf/unsimulated/fake_space/New() ..() icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" -//VOREStation Add End \ No newline at end of file +//VOREStation Add End +======= +// Better nip this just in case. +/turf/unsimulated/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + return FALSE + +/turf/unsimulated/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode) + return FALSE +>>>>>>> 3b72438... Makes RCDs Clean Again (#5679) diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 583f491d5e..058c1118ca 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -94,7 +94,7 @@ usable = 1 engage_string = "Configure RCD" - device_type = /obj/item/weapon/rcd/mounted + device_type = /obj/item/weapon/rcd/electric/mounted/rig /obj/item/rig_module/device/New() ..() diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 11ac4dcae9..4ff5fd7e17 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -62,6 +62,7 @@ var/list/mining_overlay_cache = list() density = 0 opacity = 0 blocks_air = 0 + can_build_into_floor = TRUE /turf/simulated/mineral/floor/ignore_mapgen ignore_mapgen = 1 @@ -72,6 +73,7 @@ var/list/mining_overlay_cache = list() density = 0 opacity = 0 blocks_air = 0 + can_build_into_floor = TRUE update_general() /turf/simulated/mineral/proc/make_wall() @@ -80,6 +82,7 @@ var/list/mining_overlay_cache = list() density = 1 opacity = 1 blocks_air = 1 + can_build_into_floor = FALSE update_general() /turf/simulated/mineral/proc/update_general() diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm index 90b51ac415..2416b339ff 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm @@ -423,7 +423,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/inflatable_dispenser/robot(src) src.emag = new /obj/item/weapon/melee/baton/robot/arm(src) src.modules += new /obj/item/device/geiger(src) - src.modules += new /obj/item/weapon/rcd/borg(src) + src.modules += new /obj/item/weapon/rcd/electric/mounted/borg(src) src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) src.modules += new /obj/item/weapon/gripper/no_use/loader(src) @@ -890,7 +890,7 @@ var/global/list/robot_modules = list( /obj/item/weapon/robot_module/drone/construction/New() ..() - src.modules += new /obj/item/weapon/rcd/borg(src) + src.modules += new /obj/item/weapon/rcd/electric/mounted/borg/lesser(src) /obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/device/lightreplacer/LR = locate() in src.modules diff --git a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm index 3c8e981c3b..72caaa2d73 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm @@ -83,7 +83,7 @@ src.modules += new /obj/item/weapon/tool/wirecutters/cyborg(src) src.modules += new /obj/item/device/multitool/ai_detector(src) src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) - src.modules += new /obj/item/weapon/rcd/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese. + src.modules += new /obj/item/weapon/rcd/electric/mounted/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese. src.modules += new /obj/item/weapon/melee/energy/sword/ionic_rapier(src) // FBP repair. diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index ae44c58412..cbf7623267 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -26,6 +26,7 @@ plane = OPENSPACE_PLANE_START pathweight = 100000 //Seriously, don't try and path over this one numbnuts dynamic_lighting = 0 // Someday lets do proper lighting z-transfer. Until then we are leaving this off so it looks nicer. + can_build_into_floor = TRUE var/turf/below diff --git a/html/changelogs/Neerti-RCDs.yml b/html/changelogs/Neerti-RCDs.yml new file mode 100644 index 0000000000..04c5778974 --- /dev/null +++ b/html/changelogs/Neerti-RCDs.yml @@ -0,0 +1,37 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Neerti + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "RCDs can now build grilles and windows, with a new mode. They can also finish walls when used on girders on floor/wall mode." + - rscadd: "Adds various new RCDs that are not obtainable at the moment." diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index a8e41841c3..d33437164e 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index 9cbb46748a..b25a6cbc56 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ