diff --git a/code/__DEFINES/mecha.dm b/code/__DEFINES/mecha.dm index bf62e6b67ba..f5fad9cdf68 100644 --- a/code/__DEFINES/mecha.dm +++ b/code/__DEFINES/mecha.dm @@ -4,6 +4,14 @@ #define MECHA_INT_TANK_BREACH (1<<3) #define MECHA_INT_CONTROL_LOST (1<<4) +#define ADDING_ACCESS_POSSIBLE (1<<0) +#define ADDING_MAINT_ACCESS_POSSIBLE (1<<1) +#define CANSTRAFE (1<<2) +#define LIGHTS_ON (1<<3) +#define SILICON_PILOT (1<<4) +#define IS_ENCLOSED (1<<5) +#define HAS_LIGHTS (1<<6) + #define MECHA_MELEE (1 << 0) #define MECHA_RANGED (1 << 1) diff --git a/code/__DEFINES/vehicles.dm b/code/__DEFINES/vehicles.dm index 4b59e585aa3..a15c211d877 100644 --- a/code/__DEFINES/vehicles.dm +++ b/code/__DEFINES/vehicles.dm @@ -4,15 +4,5 @@ #define VEHICLE_CONTROL_DRIVE 2 #define VEHICLE_CONTROL_KIDNAPPED 4 //Can't leave vehicle voluntarily, has to resist. -//Mech flags -#define ADDING_ACCESS_POSSIBLE (1<<0) -#define ADDING_MAINT_ACCESS_POSSIBLE (1<<1) -#define CANSTRAFE (1<<2) -#define LIGHTS_ON (1<<3) -#define SILICON_PILOT (1<<4) -#define IS_ENCLOSED (1<<5) -#define HAS_LIGHTS (1<<6) - - //Car trait flags #define CAN_KIDNAP 1 diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 00b1c54bedc..239e4bd14c8 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -166,6 +166,23 @@ DEFINE_BITFIELD(machine_stat, list( "NOPOWER" = NOPOWER, )) +DEFINE_BITFIELD(internal_damage, list( + "MECHA_INT_FIRE" = MECHA_INT_FIRE, + "MECHA_INT_TEMP_CONTROL" = MECHA_INT_TEMP_CONTROL, + "MECHA_INT_TANK_BREACH" = MECHA_INT_TANK_BREACH, + "MECHA_INT_CONTROL_LOST" = MECHA_INT_CONTROL_LOST, +)) + +DEFINE_BITFIELD(mecha_flags, list( + "ADDING_ACCESS_POSSIBLE" = ADDING_ACCESS_POSSIBLE, + "ADDING_MAINT_ACCESS_POSSIBLE" = ADDING_MAINT_ACCESS_POSSIBLE, + "CANSTRAFE" = CANSTRAFE, + "LIGHTS_ON" = LIGHTS_ON, + "SILICON_PILOT" = SILICON_PILOT, + "IS_ENCLOSED" = IS_ENCLOSED, + "HAS_LIGHTS" = HAS_LIGHTS, +)) + DEFINE_BITFIELD(mob_biotypes, list( "MOB_BEAST" = MOB_BEAST, "MOB_BUG" = MOB_BUG, diff --git a/code/modules/cargo/bounties/mech.dm b/code/modules/cargo/bounties/mech.dm index 3651be1af4e..b3dd8d580d1 100644 --- a/code/modules/cargo/bounties/mech.dm +++ b/code/modules/cargo/bounties/mech.dm @@ -13,10 +13,10 @@ /datum/bounty/item/mech/mark_high_priority(scale_reward) return ..(max(scale_reward * 0.7, 1.2)) -/datum/bounty/item/mech/ripleymkii +/datum/bounty/item/mech/ripleymk2 name = "APLU MK-II \"Ripley\"" reward = 13000 - wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/mkii) + wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/mk2) /datum/bounty/item/mech/clarke name = "Clarke" diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 9fe8ceb9bc1..7be1eccf148 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -31,6 +31,7 @@ COOLDOWN_DECLARE(mecha_bump_smash) light_system = MOVABLE_LIGHT light_on = FALSE + light_range = 4 ///What direction will the mech face when entered/powered on? Defaults to South. var/dir_in = SOUTH ///How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. @@ -257,7 +258,7 @@ mob_occupant.update_mouse_pointer() /obj/vehicle/sealed/mecha/CheckParts(list/parts_list) - ..() + . = ..() cell = locate(/obj/item/stock_parts/cell) in contents scanmod = locate(/obj/item/stock_parts/scanning_module) in contents capacitor = locate(/obj/item/stock_parts/capacitor) in contents @@ -650,8 +651,16 @@ if(!allow_diagonal_movement && ISDIAGONALDIR(direction)) return TRUE + var/keyheld = FALSE + if(strafe) + for(var/D in return_drivers()) + var/mob/driver = D + if(driver.client?.keys_held["Alt"]) + keyheld = TRUE + break + //if we're not facing the way we're going rotate us - if(dir != direction && !strafe || forcerotate) + if(dir != direction && !strafe || forcerotate || keyheld) setDir(direction) if(turnsound) playsound(src,turnsound,40,TRUE) @@ -662,10 +671,6 @@ . = step(src,direction, dir) if(strafe) - for(var/D in return_drivers()) - var/mob/driver = D - if(driver.client?.keys_held["Alt"]) - return setDir(olddir) @@ -771,7 +776,8 @@ to_chat(user, "Take control of exosuit?
") /obj/vehicle/sealed/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) + . = ..() + if(!.) return //Transfer from core or card to mech. Proc is called by mech. @@ -796,15 +802,15 @@ AI.remote_control = null to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") + return if(AI_MECH_HACK) //Called by AIs on the mech AI.linked_core = new /obj/structure/ai_core/deactivated(AI.loc) - if(AI.can_dominate_mechs) - if(LAZYLEN(occupants)) //Oh, I am sorry, were you using that? - to_chat(AI, "Occupants detected! Forced ejection initiated!") - to_chat(occupants, "You have been forcibly ejected!") - ejectall() //IT IS MINE, NOW. SUCK IT, RD! - ai_enter_mech(AI, interaction) + if(AI.can_dominate_mechs && LAZYLEN(occupants)) //Oh, I am sorry, were you using that? + to_chat(AI, "Occupants detected! Forced ejection initiated!") + to_chat(occupants, "You have been forcibly ejected!") + ejectall() //IT IS MINE, NOW. SUCK IT, RD! + AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. AI = card.AI @@ -823,10 +829,10 @@ AI.radio_enabled = TRUE to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") card.AI = null - ai_enter_mech(AI, interaction) + ai_enter_mech(AI) //Hack and From Card interactions share some code, so leave that here for both to use. -/obj/vehicle/sealed/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) +/obj/vehicle/sealed/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI) AI.ai_restore_power() mecha_flags |= SILICON_PILOT moved_inside(AI) @@ -834,8 +840,6 @@ AI.controlled_mech = src AI.remote_control = src AI.mobility_flags = ALL //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. - if(interaction == AI_MECH_HACK) - AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" :\ "You have been uploaded to a mech's onboard computer.") to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.") @@ -939,21 +943,20 @@ initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats) initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/strafe) -/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/H) - . = FALSE - if(!(H?.client)) - return - if(ishuman(H) && !Adjacent(H)) - return - add_occupant(H) - H.forceMove(src) - H.update_mouse_pointer() - add_fingerprint(H) - log_message("[H] moved in as pilot.", LOG_MECHA) +/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/newoccupant) + if(!(newoccupant?.client)) + return FALSE + if(ishuman(newoccupant) && !Adjacent(newoccupant)) + return FALSE + add_occupant(newoccupant) + newoccupant.forceMove(src) + newoccupant.update_mouse_pointer() + add_fingerprint(newoccupant) + log_message("[newoccupant] moved in as pilot.", LOG_MECHA) setDir(dir_in) playsound(src, 'sound/machines/windowdoor.ogg', 50, TRUE) if(!internal_damage) - SEND_SOUND(H, sound('sound/mecha/nominal.ogg',volume=50)) + SEND_SOUND(newoccupant, sound('sound/mecha/nominal.ogg',volume=50)) return TRUE /obj/vehicle/sealed/mecha/proc/mmi_move_inside(obj/item/mmi/M, mob/user) @@ -997,7 +1000,6 @@ B.remote_control = src B.update_mobility() B.update_mouse_pointer() - update_icon() setDir(dir_in) log_message("[M] moved in as pilot.", LOG_MECHA) if(!internal_damage) @@ -1067,7 +1069,6 @@ mmi.mecha = null mmi.update_icon() L.mobility_flags = NONE - update_icon() setDir(dir_in) return ..() @@ -1076,21 +1077,21 @@ RegisterSignal(M, COMSIG_MOB_DEATH, .proc/mob_exit) RegisterSignal(M, COMSIG_MOB_CLICKON, .proc/on_mouseclick) RegisterSignal(M, COMSIG_MOB_SAY, .proc/display_speech_bubble) + . = ..() update_icon() - return ..() /obj/vehicle/sealed/mecha/remove_occupant(mob/M) UnregisterSignal(M, COMSIG_MOB_DEATH) UnregisterSignal(M, COMSIG_MOB_CLICKON) UnregisterSignal(M, COMSIG_MOB_SAY) - update_icon() M.clear_alert("charge") M.clear_alert("mech damage") if(M.client) M.update_mouse_pointer() M.client.view_size.resetToDefault() zoom_mode = 0 - return ..() + . = ..() + update_icon() ///////////////////////// ////// Access stuff ///// diff --git a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm index 361106a31a5..ad911ba7dd0 100644 --- a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm @@ -373,7 +373,7 @@ return TRUE /obj/item/mecha_parts/mecha_equipment/ripleyupgrade/attach(obj/vehicle/sealed/mecha/M) - var/obj/vehicle/sealed/mecha/working/ripley/mkii/N = new /obj/vehicle/sealed/mecha/working/ripley/mkii(get_turf(M),1) + var/obj/vehicle/sealed/mecha/working/ripley/mk2/N = new (get_turf(M),1) if(!N) return QDEL_NULL(N.cell) diff --git a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm index f9e2933a75a..846b768b96f 100644 --- a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm @@ -49,7 +49,7 @@ if(kickback) chassis.newtonian_move(newtonian_target) chassis.log_message("Fired from [src.name], targeting [target].", LOG_MECHA) - return ..() + return //Base energy weapon type /obj/item/mecha_parts/mecha_equipment/weapon/energy diff --git a/code/modules/vehicles/mecha/mecha_wreckage.dm b/code/modules/vehicles/mecha/mecha_wreckage.dm index c70d711560f..8fd45616fac 100644 --- a/code/modules/vehicles/mecha/mecha_wreckage.dm +++ b/code/modules/vehicles/mecha/mecha_wreckage.dm @@ -154,7 +154,7 @@ /obj/item/mecha_parts/part/ripley_left_leg, /obj/item/mecha_parts/part/ripley_right_leg) -/obj/structure/mecha_wreckage/ripley/mkii +/obj/structure/mecha_wreckage/ripley/mk2 name = "\improper Ripley MK-II wreckage" icon_state = "ripleymkii-broken" diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 3cc13ab6883..3ef07ff3c71 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -30,13 +30,12 @@ . = ..() update_pressure() -/obj/vehicle/sealed/mecha/working/ripley/mob_exit(mob/M, silent, forced) - ..() - update_icon() - -/obj/vehicle/sealed/mecha/working/ripley/moved_inside(mob/living/carbon/human/H) - ..() - update_icon() +/obj/vehicle/sealed/mecha/working/ripley/generate_actions() //isnt allowed to have internal air + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/strafe) /obj/vehicle/sealed/mecha/working/ripley/check_for_internal_damage(list/possible_int_damage, ignore_threshold = FALSE) if (!enclosed) @@ -55,7 +54,7 @@ cargo.Cut() return ..() -/obj/vehicle/sealed/mecha/working/ripley/mkii +/obj/vehicle/sealed/mecha/working/ripley/mk2 desc = "Autonomous Power Loader Unit MK-II. This prototype Ripley is refitted with a pressurized cabin, trading its prior speed for atmospheric protection and armor." name = "\improper APLU MK-II \"Ripley\"" icon_state = "ripleymkii" @@ -65,11 +64,18 @@ max_temperature = 30000 max_integrity = 250 armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100) - wreckage = /obj/structure/mecha_wreckage/ripley/mkii + wreckage = /obj/structure/mecha_wreckage/ripley/mk2 enclosed = TRUE enter_delay = 40 silicon_icon_state = null +/obj/vehicle/sealed/mecha/working/ripley/mk2/generate_actions() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_eject) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_internals) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/strafe) /obj/vehicle/sealed/mecha/working/ripley/deathripley desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index e3a019427bf..de8be112025 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -91,9 +91,12 @@ user.put_in_hands(inserted_key) inserted_key = null +/obj/vehicle/sealed/obj_destruction(damage_flag) + explosion(loc, 0, 1, 2, 3, 0) + return ..() + /obj/vehicle/sealed/Destroy() DumpMobs() - explosion(loc, 0, 1, 2, 3, 0) return ..() /obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE)