Skip to content

Commit

Permalink
[MIRROR] Exosuit-mounted RCD now works like the handheld version (#1792)
Browse files Browse the repository at this point in the history
* Exosuit-mounted RCD now works like the handheld version (#81162)

---------

Co-authored-by: NovaBot <[email protected]>
Co-authored-by: SapphicOverload <[email protected]>
  • Loading branch information
3 people authored Feb 6, 2024
1 parent d4c1803 commit 7a30d5f
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 97 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/construction/rcd.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/// Time taken for an rcd hologram to disappear
#define RCD_HOLOGRAM_FADE_TIME (15 SECONDS)

/// Delay before another rcd scan can be performed in the UI
#define RCD_DESTRUCTIVE_SCAN_COOLDOWN (RCD_HOLOGRAM_FADE_TIME + 1 SECONDS)

//All available upgrades
/// Upgrade for building machines
#define RCD_UPGRADE_FRAMES (1 << 0)
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/mecha.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define MECHA_SNOWFLAKE_ID_GENERATOR "generator_snowflake"
#define MECHA_SNOWFLAKE_ID_ORE_SCANNER "orescanner_snowflake"
#define MECHA_SNOWFLAKE_ID_CLAW "lawclaw_snowflake"
#define MECHA_SNOWFLAKE_ID_RCD "rcd_snowflake"

#define MECHA_AMMO_INCENDIARY "Incendiary bullet"
#define MECHA_AMMO_BUCKSHOT "Buckshot shell"
Expand Down
61 changes: 53 additions & 8 deletions code/game/objects/items/rcd/RCD.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/// Multiplier applied on construction & deconstruction time when building multiple structures
#define FREQUENT_USE_DEBUFF_MULTIPLIER 3

/// Delay before another rcd scan can be performed in the UI
#define RCD_DESTRUCTIVE_SCAN_COOLDOWN (RCD_HOLOGRAM_FADE_TIME + 1 SECONDS)

//RAPID CONSTRUCTION DEVICE

/obj/item/construction/rcd
Expand Down Expand Up @@ -33,8 +30,8 @@
/// The path of the structure the rcd is currently creating
var/atom/movable/rcd_design_path

/// owner of this rcd. It can either be an construction console or an player
var/owner
/// Owner of this rcd. It can either be a construction console, player, or mech.
var/atom/owner
/// used by arcd, can this rcd work from a range
var/ranged = FALSE
/// delay multiplier for all construction types
Expand Down Expand Up @@ -243,8 +240,9 @@
return FALSE
var/beam
if(ranged)
beam = user.Beam(target, icon_state = "rped_upgrade", time = delay)
if(!do_after(user, delay, target = target))
var/atom/beam_source = owner ? owner : user
beam = beam_source.Beam(target, icon_state = "rped_upgrade", time = delay)
if(delay && !do_after(user, delay, target = target)) // no need for do_after with no delay
qdel(rcd_effect)
if(!isnull(beam))
qdel(beam)
Expand Down Expand Up @@ -510,8 +508,55 @@
has_ammobar = FALSE
upgrade = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK

/obj/item/construction/rcd/exosuit
name = "mounted RCD"
desc = "An exosuit-mounted Rapid Construction Device."
max_matter = INFINITY // mass-energy equivalence go brrrrrr
canRturf = TRUE
ranged = TRUE
has_ammobar = FALSE
resistance_flags = FIRE_PROOF | INDESTRUCTIBLE // should NOT be destroyed unless the equipment is destroyed
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON | DROPDEL // already qdeleted in the equipment's Destroy() but you can never be too sure
delay_mod = 0.5
///How much charge is used up for each matter unit.
var/mass_to_energy = 16

/obj/item/construction/rcd/exosuit/ui_status(mob/user)
if(ismecha(owner))
return owner.ui_status(user)
return UI_CLOSE

/obj/item/construction/rcd/exosuit/get_matter(mob/user)
if(silo_link)
return ..()
if(!ismecha(owner))
return 0
var/obj/vehicle/sealed/mecha/gundam = owner
return round(gundam.get_charge() / mass_to_energy)

/obj/item/construction/rcd/exosuit/useResource(amount, mob/user)
if(silo_link)
return ..()
if(!ismecha(owner))
return 0
var/obj/vehicle/sealed/mecha/gundam = owner
if(!gundam.use_power(amount * mass_to_energy))
gundam.balloon_alert(user, "insufficient charge!")
return FALSE
return TRUE

/obj/item/construction/rcd/exosuit/checkResource(amount, mob/user)
if(silo_link)
return ..()
if(!ismecha(owner))
return 0
var/obj/vehicle/sealed/mecha/gundam = owner
if(!gundam.has_charge(amount * mass_to_energy))
gundam.balloon_alert(user, "insufficient charge!")
return FALSE
return TRUE

#undef FREQUENT_USE_DEBUFF_MULTIPLIER
#undef RCD_DESTRUCTIVE_SCAN_COOLDOWN

/obj/item/rcd_ammo
name = "RCD matter cartridge"
Expand Down
5 changes: 3 additions & 2 deletions code/game/objects/items/rcd/RHD.dm
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,17 @@
/obj/item/construction/proc/install_upgrade(obj/item/rcd_upgrade/design_disk, mob/user)
if(design_disk.upgrade & upgrade)
balloon_alert(user, "already installed!")
return
return FALSE
if(design_disk.upgrade & banned_upgrades)
balloon_alert(user, "cannot install upgrade!")
return
return FALSE
upgrade |= design_disk.upgrade
if((design_disk.upgrade & RCD_UPGRADE_SILO_LINK) && !silo_mats)
silo_mats = AddComponent(/datum/component/remote_materials, FALSE, FALSE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
qdel(design_disk)
update_static_data_for_all_viewers()
return TRUE

/// Inserts matter into the RCD allowing it to build
/obj/item/construction/proc/insert_matter(obj/item, mob/user)
Expand Down
1 change: 0 additions & 1 deletion code/game/turfs/open/floor/plating.dm
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,6 @@
icon = 'icons/hud/radial.dmi'
icon_state = "wallfloor"


#undef PLATE_INTACT
#undef PLATE_BOLTS_LOOSENED
#undef PLATE_CUT
143 changes: 57 additions & 86 deletions code/modules/vehicles/mecha/equipment/tools/work_tools.dm
Original file line number Diff line number Diff line change
Expand Up @@ -217,117 +217,88 @@
attempt_refill(usr)
return TRUE

#define MODE_DECONSTRUCT 0
#define MODE_WALL 1
#define MODE_AIRLOCK 2

/obj/item/mecha_parts/mecha_equipment/rcd
name = "mounted RCD"
desc = "An exosuit-mounted Rapid Construction Device."
icon_state = "mecha_rcd"
equip_cooldown = 10
energy_drain = 250
equip_cooldown = 0 // internal RCD already handles it
energy_drain = 0 // internal RCD handles power consumption based on matter use
range = MECHA_MELEE|MECHA_RANGED
item_flags = NO_MAT_REDEMPTION
///determines what we'll so when clicking on a turf
var/mode = MODE_DECONSTRUCT
///Maximum range the RCD can construct at.
var/rcd_range = 3
///Whether or not to deconstruct instead.
var/deconstruct_active = FALSE
///The type of internal RCD this equipment uses.
var/rcd_type = /obj/item/construction/rcd/exosuit
///The internal RCD item used by this equipment.
var/obj/item/construction/rcd/internal_rcd

/obj/item/mecha_parts/mecha_equipment/rcd/Initialize(mapload)
. = ..()
internal_rcd = new rcd_type(src)
GLOB.rcd_list += src

/obj/item/mecha_parts/mecha_equipment/rcd/Destroy()
GLOB.rcd_list -= src
qdel(internal_rcd)
return ..()

/obj/item/mecha_parts/mecha_equipment/rcd/get_snowflake_data()
return list(
"snowflake_id" = MECHA_SNOWFLAKE_ID_MODE,
"mode" = get_mode_name(),
"mode_label" = "RCD control",
"snowflake_id" = MECHA_SNOWFLAKE_ID_RCD,
"scan_ready" = COOLDOWN_FINISHED(internal_rcd, destructive_scan_cooldown),
"deconstructing" = deconstruct_active,
"mode" = internal_rcd.design_title,
)

/// fetches the mode name to display in the UI
/obj/item/mecha_parts/mecha_equipment/rcd/proc/get_mode_name()
switch(mode)
if(MODE_DECONSTRUCT)
return "Deconstruct"
if(MODE_WALL)
return "Build wall"
if(MODE_AIRLOCK)
return "Build Airlock"
else
return "Someone didnt set this"
/// Set the RCD's owner when attaching and detaching it
/obj/item/mecha_parts/mecha_equipment/rcd/attach(obj/vehicle/sealed/mecha/new_mecha, attach_right)
internal_rcd.owner = new_mecha
return ..()

/obj/item/mecha_parts/mecha_equipment/rcd/detach(atom/moveto)
internal_rcd.owner = null
return ..()

/obj/item/mecha_parts/mecha_equipment/rcd/handle_ui_act(action, list/params)
if(action == "change_mode")
mode++
if(mode > MODE_AIRLOCK)
mode = MODE_DECONSTRUCT
switch(mode)
if(MODE_DECONSTRUCT)
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][span_notice("Switched RCD to Deconstruct.")]")
energy_drain = initial(energy_drain)
if(MODE_WALL)
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][span_notice("Switched RCD to Construct Walls and Flooring.")]")
energy_drain = 2*initial(energy_drain)
if(MODE_AIRLOCK)
to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][span_notice("Switched RCD to Construct Airlock.")]")
energy_drain = 2*initial(energy_drain)
return TRUE
switch(action)
if("rcd_scan")
if(!COOLDOWN_FINISHED(internal_rcd, destructive_scan_cooldown))
return FALSE
rcd_scan(internal_rcd)
COOLDOWN_START(internal_rcd, destructive_scan_cooldown, RCD_DESTRUCTIVE_SCAN_COOLDOWN)
return TRUE
if("toggle_deconstruct")
deconstruct_active = !deconstruct_active
return TRUE
if("change_mode")
for(var/mob/driver as anything in chassis.return_drivers())
internal_rcd.ui_interact(driver)
return TRUE

/obj/item/mecha_parts/mecha_equipment/rcd/action(mob/source, atom/target, list/modifiers)
if(!isturf(target) && !istype(target, /obj/machinery/door/airlock))
target = get_turf(target)
if(!action_checks(target) || !(target in view(3, chassis)) || istype(target, /turf/open/space/transit))
if(!action_checks(target))
return
playsound(chassis, 'sound/machines/click.ogg', 50, TRUE)

switch(mode)
if(MODE_DECONSTRUCT)
to_chat(source, "[icon2html(src, source)][span_notice("Deconstructing [target]...")]")
if(iswallturf(target))
var/turf/closed/wall/wall_turf = target
if(!do_after_cooldown(wall_turf, source))
return
wall_turf.ScrapeAway()
else if(isfloorturf(target))
var/turf/open/floor/floor_turf = target
if(!do_after_cooldown(floor_turf, source))
return
floor_turf.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
else if (istype(target, /obj/machinery/door/airlock))
if(!do_after_cooldown(target, source))
return
qdel(target)
if(MODE_WALL)
if(isfloorturf(target))
var/turf/open/floor/floor_turf = target
to_chat(source, "[icon2html(src, source)][span_notice("Building Wall...")]")
if(!do_after_cooldown(floor_turf, source))
return
floor_turf.place_on_top(/turf/closed/wall)
else if(isopenturf(target))
var/turf/open/open_turf = target
to_chat(source, "[icon2html(src, source)][span_notice("Building Floor...")]")
if(!do_after_cooldown(open_turf, source))
return
open_turf.place_on_top(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
if(MODE_AIRLOCK)
if(isfloorturf(target))
to_chat(source, "[icon2html(src, source)][span_notice("Building Airlock...")]")
if(!do_after_cooldown(target, source))
return
var/obj/machinery/door/airlock/airlock_door = new /obj/machinery/door/airlock(target)
airlock_door.autoclose = TRUE
playsound(target, 'sound/effects/sparks2.ogg', 50, TRUE)
chassis.spark_system.start()
playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE)
return ..()
if(get_dist(chassis, target) > rcd_range)
balloon_alert(source, "out of range!")
return
if(!internal_rcd) // if it somehow went missing
internal_rcd = new rcd_type(src)
stack_trace("Exosuit-mounted RCD had no internal RCD!")
..() // do this now because the do_after can take a while
var/construction_mode = internal_rcd.mode
if(deconstruct_active) // deconstruct isn't in the RCD menu so switch it to deconstruct mode and set it back when it's done
internal_rcd.mode = RCD_DECONSTRUCT
internal_rcd.rcd_create(target, source)
internal_rcd.mode = construction_mode
return TRUE

#undef MODE_DECONSTRUCT
#undef MODE_WALL
#undef MODE_AIRLOCK
/obj/item/mecha_parts/mecha_equipment/rcd/attackby(obj/item/attacking_item, mob/user, params)
if(istype(attacking_item, /obj/item/rcd_upgrade))
internal_rcd.install_upgrade(attacking_item, user)
return
return ..()

//Dunno where else to put this so shrug
/obj/item/mecha_parts/mecha_equipment/ripleyupgrade
Expand Down
10 changes: 10 additions & 0 deletions code/modules/vehicles/mecha/mecha_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@
ammo_resupply(weapon, user)
return

if(istype(weapon, /obj/item/rcd_upgrade))
upgrade_rcd(weapon, user)
return

if(weapon.GetID())
if(!allowed(user))
if(mecha_flags & ID_LOCK_ON)
Expand Down Expand Up @@ -510,3 +514,9 @@
else
balloon_alert(user, "can't use this ammo!")
return FALSE

///Upgrades any attached RCD equipment.
/obj/vehicle/sealed/mecha/proc/upgrade_rcd(obj/item/rcd_upgrade/rcd_upgrade, mob/user)
for(var/obj/item/mecha_parts/mecha_equipment/rcd/rcd_equip in flat_equipment)
if(rcd_equip.internal_rcd.install_upgrade(rcd_upgrade, user))
return
49 changes: 49 additions & 0 deletions tgui/packages/tgui/interfaces/Mecha/ModulesPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ const MECHA_SNOWFLAKE_ID_WEAPON_BALLISTIC = 'ballistic_weapon_snowflake';
const MECHA_SNOWFLAKE_ID_GENERATOR = 'generator_snowflake';
const MECHA_SNOWFLAKE_ID_ORE_SCANNER = 'orescanner_snowflake';
const MECHA_SNOWFLAKE_ID_CLAW = 'lawclaw_snowflake';
const MECHA_SNOWFLAKE_ID_RCD = 'rcd_snowflake';

export const ModuleDetailsExtra = (props: { module: MechModule }) => {
const module = props.module;
Expand All @@ -332,6 +333,8 @@ export const ModuleDetailsExtra = (props: { module: MechModule }) => {
return <SnowflakeOreScanner module={module} />;
case MECHA_SNOWFLAKE_ID_CLAW:
return <SnowflakeLawClaw module={module} />;
case MECHA_SNOWFLAKE_ID_RCD:
return <SnowflakeRCD module={module} />;
default:
return null;
}
Expand Down Expand Up @@ -978,3 +981,49 @@ const SnowflakeLawClaw = (props) => {
/>
);
};

const SnowflakeRCD = (props) => {
const { act, data } = useBackend<MainData>();
const { ref } = props.module;
const { scan_ready, deconstructing, mode } = props.module.snowflake;
return (
<>
<LabeledList.Item label="Destruction Scan">
<Button
icon="satellite-dish"
color={scan_ready ? 'green' : 'transparent'}
onClick={() =>
act('equip_act', {
ref: ref,
gear_action: 'rcd_scan',
})
}
/>
</LabeledList.Item>
<LabeledList.Item label="Deconstructing">
<Button
icon="power-off"
content={deconstructing ? 'On' : 'Off'}
color={deconstructing ? 'green' : 'blue'}
onClick={() =>
act('equip_act', {
ref: ref,
gear_action: 'toggle_deconstruct',
})
}
/>
</LabeledList.Item>
<LabeledList.Item label="Construction Mode">
<Button
content={mode}
onClick={() =>
act('equip_act', {
ref: ref,
gear_action: 'change_mode',
})
}
/>
</LabeledList.Item>
</>
);
};

0 comments on commit 7a30d5f

Please sign in to comment.