Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Nebbaymechs as Exosuits, Legally Distinct from Mechas, obviously. #8956

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
7 changes: 7 additions & 0 deletions code/__defines/_planes+layers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ What is the naming convention for planes or layers?
// Mob planes
#define MOB_PLANE -25
#define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps
#define MECH_BASE_LAYER 4.01
#define MECH_INTERMEDIATE_LAYER 4.02
#define MECH_PILOT_LAYER 4.03
#define MECH_LEG_LAYER 4.04
#define MECH_COCKPIT_LAYER 4.05
#define MECH_ARM_LAYER 4.06
#define MECH_GEAR_LAYER 4.07
#define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps

#define ABOVE_MOB_PLANE -24
Expand Down
15 changes: 15 additions & 0 deletions code/_onclick/MouseDrag.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//If we intercept it return true else return false
/atom/proc/RelayMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params, var/mob/user)
return FALSE

/mob/proc/OnMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params)
if(istype(loc, /atom))
var/atom/A = loc
if(A.RelayMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params, src))
return

if(over_object && !incapacitated())
var/obj/item/gun/gun = get_active_hand()
if(istype(gun) && gun.can_autofire())
set_dir(get_dir(src, over_object))
gun.Fire(get_turf(over_object), src, params, (get_dist(over_object, src) <= 1), FALSE)
11 changes: 11 additions & 0 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
var/obj/mecha/M = loc
return M.click_action(A, src, params)

else if(!isturf(loc) && !isnull(loc)) // If you are in Nullspace you should be adminhelping not clicking.
var/atom/movable/AM = loc
if(AM.allow_click_through(A, src))
return AM.click_through(A, src, params)

if(restrained())
setClickCooldown(10)
RestrainedClickOn(A)
Expand Down Expand Up @@ -141,6 +146,12 @@
trigger_aiming(TARGET_CAN_CLICK)
return 1

/atom/movable/proc/click_through(var/atom/target, var/atom/movable/source, var/params)
return FALSE

/atom/movable/proc/allow_click_through(var/atom/target, var/atom/movable/source)
return FALSE

/mob/proc/setClickCooldown(var/timeout)
next_click = max(world.time + timeout, next_click)

Expand Down
3 changes: 2 additions & 1 deletion code/game/mecha/mech_bay.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
var/repair = 0
var/list/chargable_types = list(
/obj/mecha,
/mob/living/exosuit,
/mob/living/silicon/robot/platform
)

Expand Down Expand Up @@ -58,7 +59,7 @@
var/done = FALSE
var/obj/mecha/mech = charging
var/obj/item/cell/cell = charging.get_cell()
if(cell)
if(cell)
var/t = min(charge, cell.maxcharge - cell.charge)
if(t > 0)
if(istype(mech))
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/weapons/id cards/station_ids.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
SPECIES_TESHARI = 'icons/mob/species/teshari/id.dmi'
)

var/access = list()
var/list/access = list()
var/registered_name = "Unknown" // The name registered_name on the card
var/registered_id_string = "ID Card"
slot_flags = SLOT_ID | SLOT_EARS
Expand Down
6 changes: 6 additions & 0 deletions code/modules/client/client procs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,12 @@
else
. = ..()

/client/MouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params)
. = ..()
var/mob/living/M = mob
if(istype(M))
M.OnMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params)

/client/proc/last_activity_seconds()
return inactivity / 10

Expand Down
44 changes: 44 additions & 0 deletions code/modules/exosuits/_exosuit_setup.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
GLOBAL_DATUM_INIT(default_hardpoint_background, /image, null)
GLOBAL_DATUM_INIT(hardpoint_error_icon, /image, null)
GLOBAL_DATUM_INIT(hardpoint_bar_empty, /image, null)

GLOBAL_LIST_INIT(hardpoint_bar_cache, new)
GLOBAL_LIST_INIT(mech_damage_overlay_cache, new)
GLOBAL_LIST_INIT(mech_image_cache, new)
GLOBAL_LIST_INIT(mech_icon_cache, new)
GLOBAL_LIST_INIT(mech_weapon_overlays, icon_states('icons/mob/mecha/mech_weapon_overlays.dmi'))

#define HARDPOINT_BACK "back"
#define HARDPOINT_LEFT_HAND "left hand"
#define HARDPOINT_RIGHT_HAND "right hand"
#define HARDPOINT_LEFT_SHOULDER "left shoulder"
#define HARDPOINT_RIGHT_SHOULDER "right shoulder"
#define HARDPOINT_HEAD "head"

// No software required: taser. light, radio.
#define MECH_SOFTWARE_UTILITY "utility equipment" // Plasma torch, clamp, drill.
#define MECH_SOFTWARE_MEDICAL "medical support systems" // Sleeper.
#define MECH_SOFTWARE_WEAPONS "standard weapon systems" // Ballistics and energy weapons.
#define MECH_SOFTWARE_ADVWEAPONS "advanced weapon systems" // Railguns, missile launcher.
#define MECH_SOFTWARE_ENGINEERING "advanced engineering systems" // RCD.

// EMP damage points before various effects occur.
#define EMP_GUI_DISRUPT 5 // 1 ion rifle shot == 8.
#define EMP_MOVE_DISRUPT 10 // 2 shots.
#define EMP_ATTACK_DISRUPT 20 // 3 shots.

//About components
#define MECH_COMPONENT_DAMAGE_UNDAMAGED 1
#define MECH_COMPONENT_DAMAGE_DAMAGED 2
#define MECH_COMPONENT_DAMAGE_DAMAGED_BAD 3
#define MECH_COMPONENT_DAMAGE_DAMAGED_TOTAL 4

//Construction
#define EXOFRAME_REINFORCED 1
#define EXOFRAME_REINFORCED_SECURE 2
#define EXOFRAME_REINFORCED_WELDED 3

#define EXOFRAME_WIRED 1
#define EXOFRAME_WIRED_ADJUSTED 2

#define BAR_CAP 12
160 changes: 160 additions & 0 deletions code/modules/exosuits/component/_components.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/obj/item/mech_component
icon = 'icons/mob/mecha/mech_parts_held.dmi'
w_class = ITEMSIZE_HUGE
gender = PLURAL
color = COLOR_GUNMETAL

var/on_mech_icon = 'icons/mob/mecha/mech_parts.dmi'
var/exosuit_desc_string
var/total_damage = 0
var/brute_damage = 0
var/burn_damage = 0
var/max_damage = 60
var/damage_state = MECH_COMPONENT_DAMAGE_UNDAMAGED
var/list/has_hardpoints = list()
var/decal
var/power_use = 0
matter = list(MATERIAL_STEEL = 15000, MATERIAL_PLASTIC = 1000, MATERIAL_OSMIUM = 500)
dir = SOUTH

/obj/item/mech_component/proc/query_color(var/mob/living/user)
if(istype(user))
var/input = input("Modify part color:", "Color", color) as color|null
if(input)
return set_colour(input)

/obj/item/mech_component/proc/set_colour(new_colour)
var/last_colour = color
color = new_colour
return color != last_colour

/obj/item/mech_component/emp_act(var/severity)
take_burn_damage(rand((10 - (severity*3)),15-(severity*4)))
for(var/obj/item/thing in contents)
thing.emp_act(severity)

/obj/item/mech_component/examine(mob/user)
. = ..()
if(ready_to_install())
. += SPAN_NOTICE("It is ready for installation.")
else
. += show_missing_parts(user)

//These icons have multiple directions but before they're attached we only want south.
/obj/item/mech_component/set_dir()
..(SOUTH)

/obj/item/mech_component/proc/show_missing_parts(var/mob/user)
return

/obj/item/mech_component/proc/prebuild()
return

/obj/item/mech_component/proc/install_component(var/obj/item/thing, var/mob/user)
if(!user.unEquip(thing, src))
return FALSE
user.visible_message(SPAN_NOTICE("\The [user] installs \the [thing] in \the [src]."))
thing.forceMove(src)
update_components()
return TRUE

/obj/item/mech_component/proc/update_health()
total_damage = min(max_damage, brute_damage + burn_damage)
damage_state = between(MECH_COMPONENT_DAMAGE_UNDAMAGED, round((total_damage/max_damage) * 4), MECH_COMPONENT_DAMAGE_DAMAGED_TOTAL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What actually uses damage_state? Can we just compute this on the fly? (It smells like an icon state index)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used in the health doll for the exosuit UI, looking at the refs


/obj/item/mech_component/proc/ready_to_install()
return TRUE

/obj/item/mech_component/proc/repair_brute_damage(var/amt)
take_brute_damage(-amt)

/obj/item/mech_component/proc/repair_burn_damage(var/amt)
take_burn_damage(-amt)

/obj/item/mech_component/proc/take_brute_damage(var/amt)
brute_damage = max(0, brute_damage + amt)
update_health()
if(total_damage == max_damage)
take_component_damage(amt,0)

/obj/item/mech_component/proc/take_burn_damage(var/amt)
burn_damage = max(0, burn_damage + amt)
update_health()
if(total_damage == max_damage)
take_component_damage(0,amt)

/obj/item/mech_component/proc/take_component_damage(var/brute, var/burn)
var/list/damageable_components = list()
for(var/obj/item/robot_parts/robot_component/RC in contents)
damageable_components += RC
if(!damageable_components.len) return
var/obj/item/robot_parts/robot_component/RC = pick(damageable_components)
if(RC.take_damage(brute, burn))
qdel(RC)
update_components()

/obj/item/mech_component/attackby(var/obj/item/thing, var/mob/user)
if(thing.has_tool_quality(TOOL_SCREWDRIVER))
if(contents.len)
var/obj/item/removed = input("Which component would you like to remove") as null|anything in contents
if(!removed)
return
user.visible_message(SPAN_NOTICE("\The [user] removes \the [removed] from \the [src]."))
removed.forceMove(user.loc)
playsound(user.loc, 'sound/effects/pop.ogg', 50, 0)
update_components()
else
to_chat(user, SPAN_WARNING("There is nothing to remove."))
return
if(istype(thing, /obj/item/weldingtool))
repair_brute_generic(thing, user)
return
if(istype(thing, /obj/item/stack/cable_coil))
repair_burn_generic(thing, user)
return

if(thing.has_tool_quality(TOOL_MULTITOOL))
query_color(user)
return

return ..()

/obj/item/mech_component/proc/update_components()
return

/obj/item/mech_component/proc/repair_brute_generic(var/obj/item/weldingtool/WT, var/mob/user)
if(!istype(WT))
return
if(!brute_damage)
to_chat(user, SPAN_NOTICE("You inspect \the [src] but find nothing to repair."))
return
if(!WT.welding)
to_chat(user, SPAN_WARNING("Turn \the [WT] on, first."))
return
if(WT.remove_fuel(1, user))
if(do_after(user, 10, src) && brute_damage)
repair_brute_damage(10)
to_chat(user, SPAN_NOTICE("You mend the damage to \the [src]."))
playsound(user.loc, 'sound/items/Welder.ogg', 25, 1)

/obj/item/mech_component/proc/repair_burn_generic(var/obj/item/stack/cable_coil/CC, var/mob/user)
if(!istype(CC))
return
if(!burn_damage)
to_chat(user, SPAN_NOTICE("\The [src]'s wiring doesn't need replacing."))
return

if(CC.get_amount() < 6)
to_chat(user, SPAN_WARNING("You need at least 6 units of cable to repair this section."))
return

user.visible_message("\The [user] begins replacing the wiring of \the [src]...")

if(do_after(user, 10, src) && burn_damage)
if(QDELETED(CC) || QDELETED(src) || !CC.use(6))
return

repair_burn_damage(25)
to_chat(user, SPAN_NOTICE("You mend the damage to \the [src]'s wiring."))
playsound(user.loc, 'sound/items/Deconstruct.ogg', 25, 1)
return
54 changes: 54 additions & 0 deletions code/modules/exosuits/component/armour.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/obj/item/robot_parts/robot_component/armour/exosuit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File organization: Can we split the folders for robot_components and mech_components?

name = "exosuit armour plating"
armor = list(
melee = 70,
bullet = 30,
laser = 40,
energy = 10,
bomb = 30,
bio = 100,
rad = 20
)
origin_tech = list(TECH_MATERIAL = 1)

/obj/item/robot_parts/robot_component/armour/exosuit/radproof
name = "radiation-proof armour plating"
desc = "A fully enclosed radiation hardened shell designed to protect the pilot from radiation"
armor = list(
melee = 70,
bullet = 30,
laser = 40,
energy = 10,
bomb = 30,
bio = 100,
rad = 100
)
origin_tech = list(TECH_MATERIAL = 3)

/obj/item/robot_parts/robot_component/armour/exosuit/em
name = "EM-shielded armour plating"
desc = "A shielded plating that surrounds the eletronics and protects them from electromagnetic radiation"
armor = list(
melee =70,
bullet = 25,
laser = 25,
energy = 100,
bomb = 10,
bio = 100,
rad = 20
)
origin_tech = list(TECH_MATERIAL = 3)

/obj/item/robot_parts/robot_component/armour/exosuit/combat
name = "heavy combat plating"
desc = "Plating designed to deflect incoming attacks and explosions"
armor = list(
melee = 70,
bullet = 60,
laser = 70,
energy = 10,
bomb = 60,
bio = 100,
rad = 20
)
origin_tech = list(TECH_MATERIAL = 5)
Loading
Loading