diff --git a/aurorastation.dme b/aurorastation.dme index 1df19864941..4abd60fd068 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -864,6 +864,7 @@ #include "code\game\objects\effects\spawners\gibspawner.dm" #include "code\game\objects\effects\temporary_visuals\blaster_effect.dm" #include "code\game\objects\effects\temporary_visuals\blood_splatter.dm" +#include "code\game\objects\effects\temporary_visuals\incorporeal_mech.dm" #include "code\game\objects\effects\temporary_visuals\nuke.dm" #include "code\game\objects\effects\temporary_visuals\teleport_visuals.dm" #include "code\game\objects\effects\temporary_visuals\temporary_visual.dm" diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 182de847687..d77e62978c4 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -23,6 +23,7 @@ #define INCORPOREAL_NINJA 2 // Pass through matter with a cool effect #define INCORPOREAL_BSTECH 3 // Like ninja, but also go across Z-levels and move in space freely #define INCORPOREAL_SHADE 4 // Shady +#define INCORPOREAL_MECH 5 // stripped down bstech // Grab levels. #define GRAB_PASSIVE 1 diff --git a/code/game/objects/effects/temporary_visuals/incorporeal_mech.dm b/code/game/objects/effects/temporary_visuals/incorporeal_mech.dm new file mode 100644 index 00000000000..e0718d4dde1 --- /dev/null +++ b/code/game/objects/effects/temporary_visuals/incorporeal_mech.dm @@ -0,0 +1,10 @@ +/obj/effect/temp_visual/incorporeal_mech + layer = BELOW_MOB_LAYER + randomdir = FALSE + +/obj/effect/temp_visual/incorporeal_mech/Initialize(mapload, new_dir, var/mob/living/heavy_vehicle/HV) + . = ..() + appearance = HV.appearance + mouse_opacity = 0 + opacity = FALSE + animate(src, time = duration, alpha = 0) \ No newline at end of file diff --git a/code/modules/heavy_vehicle/equipment/combat.dm b/code/modules/heavy_vehicle/equipment/combat.dm index 78b30d161ce..be450a971fb 100644 --- a/code/modules/heavy_vehicle/equipment/combat.dm +++ b/code/modules/heavy_vehicle/equipment/combat.dm @@ -318,11 +318,9 @@ return if((world.time - last_recharge) < cooldown) return - var/obj/item/cell/cell = owner.get_cell() var/actual_required_power = Clamp(max_charge - charge, 0, charging_rate) - if(cell) - charge += cell.use(actual_required_power) + owner.use_cell_power(actual_required_power) /obj/item/mecha_equipment/shield/get_hardpoint_status_value() return charge / max_charge diff --git a/code/modules/heavy_vehicle/equipment/utility.dm b/code/modules/heavy_vehicle/equipment/utility.dm index 163f4d2c6f5..c3aae9f5a1f 100644 --- a/code/modules/heavy_vehicle/equipment/utility.dm +++ b/code/modules/heavy_vehicle/equipment/utility.dm @@ -272,9 +272,7 @@ log_and_message_admins("used [src] to throw [locked] at [target].", user, owner.loc) locked = null - var/obj/item/cell/C = owner.get_cell() - if(istype(C)) - C.use(active_power_use * CELLRATE) + owner.use_cell_power(active_power_use * CELLRATE) else locked = null @@ -293,9 +291,8 @@ log_and_message_admins("used [src]'s area throw on [target].", user, owner.loc) - var/obj/item/cell/C = owner.get_cell() - if(istype(C)) - C.use(active_power_use * CELLRATE * 2) //bit more expensive to throw all + + owner.use_cell_power(active_power_use * CELLRATE * 2) //bit more expensive to throw all /obj/item/material/drill_head var/durability = 0 @@ -374,9 +371,7 @@ to_chat(user, "Your drill doesn't have a head!") return - var/obj/item/cell/C = owner.get_cell() - if(istype(C)) - C.use(active_power_use * CELLRATE) + owner.use_cell_power(active_power_use * CELLRATE) owner.visible_message("\The [owner] starts to drill \the [target]", "You hear a large drill.") var/T = target.loc @@ -657,6 +652,70 @@ /obj/item/mecha_equipment/quick_enter/attack_self() return +/obj/item/mecha_equipment/phazon + name = "phazon bluespace transmission system" + desc = "A large back-mounted device that grants the exosuit it's mounted to the ability to semi-shift into bluespace, allowing it to pass through dense objects." + desc_info = "It needs an anomaly core to function. You can install some simply by using a core on it." + icon_state = "mecha_phazon" + restricted_hardpoints = list(HARDPOINT_BACK) + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 6, TECH_BLUESPACE = 6) + active_power_use = 88 KILOWATTS + + var/obj/item/anomaly_core/AC + var/image/anomaly_overlay + +/obj/item/mecha_equipment/phazon/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/anomaly_core)) + if(AC) + to_chat(user, SPAN_WARNING("\The [src] already has an anomaly core installed!")) + return + user.drop_from_inventory(I, src) + AC = I + to_chat(user, SPAN_NOTICE("You insert \the [AC] into \the [src].")) + desc_info = "\The [src] has an anomaly core installed! You can use a wrench to remove it." + anomaly_overlay = image(AC.icon, null, AC.icon_state) + anomaly_overlay.pixel_y = 3 + add_overlay(anomaly_overlay) + return + if(I.iswrench()) + if(!AC) + to_chat(user, SPAN_WARNING("\The [src] doesn't have an anomaly core installed!")) + return + to_chat(user, SPAN_NOTICE("You remove \the [AC] from \the [src].")) + playsound(loc, I.usesound, 50, TRUE) + user.put_in_hands(AC) + cut_overlay(anomaly_overlay) + qdel(anomaly_overlay) + AC = null + if(owner) + deactivate() + return + return ..() + +/obj/item/mecha_equipment/phazon/attack_self(mob/user) + . = ..() + if(!.) + return + + if(!AC) + to_chat(user, SPAN_WARNING("\The [src] needs an anomaly core to function!")) + return + + if(!owner.incorporeal_move) + to_chat(user, SPAN_NOTICE("You fire up \the [src], semi-shifting into another plane of existence!")) + owner.set_mech_incorporeal(INCORPOREAL_MECH) + else + to_chat(user, SPAN_NOTICE("You disable \the [src], shifting back into your normal reality.")) + owner.set_mech_incorporeal(INCORPOREAL_DISABLE) + +/obj/item/mecha_equipment/phazon/deactivate() + owner.set_mech_incorporeal(INCORPOREAL_DISABLE) + ..() + +/obj/item/mecha_equipment/phazon/uninstalled() + owner.set_mech_incorporeal(INCORPOREAL_DISABLE) + ..() /obj/item/mecha_equipment/mounted_system/grenadecleaner name = "cleaner grenade launcher" diff --git a/code/modules/heavy_vehicle/mech_helpers.dm b/code/modules/heavy_vehicle/mech_helpers.dm index 02956750f46..49fa2a9d6a3 100644 --- a/code/modules/heavy_vehicle/mech_helpers.dm +++ b/code/modules/heavy_vehicle/mech_helpers.dm @@ -18,7 +18,7 @@ next_mecha_move = world.time + 15 return - next_mecha_move = world.time + legs.move_delay + next_mecha_move = world.time + (incorporeal_move ? legs.move_delay / 2 : legs.move_delay) if(maintenance_protocols) if(user) @@ -74,4 +74,44 @@ text = replacemany(text, list("\"" = "", "." = "", "," = "")) text = trim_left(text) text = trim_right(text) - return text \ No newline at end of file + return text + +/mob/living/heavy_vehicle/proc/use_cell_power(var/power_to_use) + var/power_used = get_cell()?.use(power_to_use) + if(power_used <= 0) + for(var/hardpoint in hardpoints) + var/obj/item/mecha_equipment/ME = hardpoints[hardpoint] + if(ME) + ME.deactivate() + return power_used + +/mob/living/heavy_vehicle/proc/drain_cell_power(var/power_to_drain) + var/power_used = get_cell()?.drain_power(0, 0, power_to_drain) + if(power_used <= 0) + for(var/hardpoint in hardpoints) + var/obj/item/mecha_equipment/ME = hardpoints[hardpoint] + if(ME) + ME.deactivate() + return power_used + +/mob/living/heavy_vehicle/proc/checked_use_cell(var/power_to_drain) + var/can_use = get_cell()?.checked_use(0, 0, power_to_drain) + if(!get_cell()?.charge) + for(var/hardpoint in hardpoints) + var/obj/item/mecha_equipment/ME = hardpoints[hardpoint] + if(ME) + ME.deactivate() + return can_use + +/mob/living/heavy_vehicle/proc/set_mech_incorporeal(var/incorporeal_state) + var/old_corporeal_state = incorporeal_move + incorporeal_move = incorporeal_state + if(old_corporeal_state != incorporeal_move) + if(incorporeal_move) + add_filter("INCORPBLUR", 1, list("type" = "blur")) + animate(src, time = 1 SECOND, alpha = 150, flags = ANIMATION_PARALLEL) + animate(get_filter("INCORPBLUR"), time = 1 SECOND, size = 1.5, flags = ANIMATION_PARALLEL) + else + animate(get_filter("INCORPBLUR"), time = 1 SECOND, size = 1, flags = ANIMATION_PARALLEL) + animate(src, time = 1 SECOND, alpha = initial(alpha), flags = ANIMATION_PARALLEL) + remove_filter("INCORPBLUR") \ No newline at end of file diff --git a/code/modules/heavy_vehicle/mech_interaction.dm b/code/modules/heavy_vehicle/mech_interaction.dm index a79151b8e87..a98875765e7 100644 --- a/code/modules/heavy_vehicle/mech_interaction.dm +++ b/code/modules/heavy_vehicle/mech_interaction.dm @@ -75,7 +75,7 @@ setClickCooldown(15) return - if(!(get_cell()?.checked_use(arms.power_use * CELLRATE))) + if(!checked_use_cell(arms.power_use * CELLRATE)) to_chat(user, power == MECH_POWER_ON ? SPAN_WARNING("Error: Power levels insufficient.") : SPAN_WARNING("\The [src] is powered off.")) return @@ -286,9 +286,15 @@ var/turf/target_loc = get_step(src, direction) if(!legs.can_move_on(loc, target_loc)) return - Move(target_loc, direction) + if(incorporeal_move) + if(legs && legs.mech_step_sound) + playsound(src.loc,legs.mech_step_sound,40,1) + use_cell_power(legs.power_use * CELLRATE) + user.client.Process_Incorpmove(direction, src) + else + Move(target_loc, direction) else - get_cell()?.use(legs.power_use * CELLRATE) + use_cell_power(legs.power_use * CELLRATE) if(legs && legs.mech_turn_sound) playsound(src.loc,legs.mech_turn_sound,40,1) next_mecha_move = world.time + legs.turn_delay @@ -307,9 +313,15 @@ if(..() && !istype(loc, /turf/space)) if(legs && legs.mech_step_sound) playsound(src.loc,legs.mech_step_sound,40,1) - get_cell()?.use(legs.power_use * CELLRATE) + use_cell_power(legs.power_use * CELLRATE) update_icon() +/mob/living/heavy_vehicle/Post_Incorpmove() + if(istype(hardpoints[HARDPOINT_BACK], /obj/item/mecha_equipment/phazon)) + var/obj/item/mecha_equipment/phazon/PZ = hardpoints[HARDPOINT_BACK] + use_cell_power(PZ.active_power_use * CELLRATE) + return ..() + /mob/living/heavy_vehicle/attackby(var/obj/item/thing, var/mob/user) if(user.a_intent != I_HURT && istype(thing, /obj/item/mecha_equipment)) if(hardpoints_locked) diff --git a/code/modules/heavy_vehicle/mech_life.dm b/code/modules/heavy_vehicle/mech_life.dm index cfd6e07b10d..3a4ee7a07e4 100644 --- a/code/modules/heavy_vehicle/mech_life.dm +++ b/code/modules/heavy_vehicle/mech_life.dm @@ -30,7 +30,7 @@ var/powered = FALSE if(get_cell()) - powered = get_cell().drain_power(0, 0, calc_power_draw()) > 0 + powered = drain_cell_power(calc_power_draw()) > 0 if(!powered) //Shut down all systems diff --git a/code/modules/heavy_vehicle/mecha.dm b/code/modules/heavy_vehicle/mecha.dm index 6b357750585..eaba2b963e8 100644 --- a/code/modules/heavy_vehicle/mecha.dm +++ b/code/modules/heavy_vehicle/mecha.dm @@ -10,6 +10,7 @@ mob_push_flags = ALLMOBS can_be_buckled = FALSE accent = ACCENT_TTS + appearance_flags = KEEP_TOGETHER var/decal var/emp_damage = 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index a59609b994c..fa9966809f8 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -191,7 +191,7 @@ Move_object(direct) if(mob.incorporeal_move && isobserver(mob)) - Process_Incorpmove(direct) + Process_Incorpmove(direct, mob) return if(moving || world.time < move_delay) @@ -219,8 +219,8 @@ if(isliving(mob)) var/mob/living/L = mob - if(L.incorporeal_move)//Move though walls - Process_Incorpmove(direct) + if(L.incorporeal_move && isturf(mob.loc))//Move though walls + Process_Incorpmove(direct, mob) return if(mob.client && ((mob.client.view != world.view) || (mob.client.pixel_x != 0) || (mob.client.pixel_y != 0))) // If mob moves while zoomed in with device, unzoom them. for(var/obj/item/item in mob) @@ -395,44 +395,49 @@ ///Process_Incorpmove ///Called by client/Move() ///Allows mobs to run though walls -/client/proc/Process_Incorpmove(direct) - var/turf/mobloc = get_turf(mob) - switch(mob.incorporeal_move) +/client/proc/Process_Incorpmove(direct, var/mob/use_mob) + if(!use_mob) + use_mob = mob + var/turf/mobloc = get_turf(use_mob) + switch(use_mob.incorporeal_move) if(INCORPOREAL_GHOST) - var/turf/T = get_step(mob, direct) - if(mob.check_holy(T)) - to_chat(mob, SPAN_WARNING("You cannot get past holy grounds while you are in this plane of existence!")) + var/turf/T = get_step(use_mob, direct) + if(use_mob.check_holy(T)) + to_chat(src, SPAN_WARNING("You cannot get past holy grounds while you are in this plane of existence!")) return else - mob.forceMove(get_step(mob, direct)) - mob.dir = direct + use_mob.forceMove(get_step(use_mob, direct)) + use_mob.dir = direct if(INCORPOREAL_NINJA, INCORPOREAL_BSTECH) - anim(mobloc, mob, 'icons/mob/mob.dmi', null, "shadow", null, mob.dir) - mob.forceMove(get_step(mob, direct)) - mob.dir = direct + anim(mobloc, use_mob, 'icons/mob/mob.dmi', null, "shadow", null, use_mob.dir) + use_mob.forceMove(get_step(use_mob, direct)) + use_mob.dir = direct + if(INCORPOREAL_MECH) + new /obj/effect/temp_visual/incorporeal_mech(mobloc, use_mob.dir, use_mob) + use_mob.forceMove(get_step(use_mob, direct)) if(INCORPOREAL_SHADE) - if(!mob.canmove || mob.anchored) + if(!use_mob.canmove || use_mob.anchored) return move_delay = 1 + world.time - var/turf/T = get_step(mob, direct) + var/turf/T = get_step(use_mob, direct) for(var/obj/structure/window/W in T) if(istype(W, /obj/structure/window/phoronbasic) || istype(W, /obj/structure/window/phoronreinforced)) if(W.is_full_window()) - to_chat(mob, SPAN_WARNING("\The [W] obstructs your movement!")) + to_chat(src, SPAN_WARNING("\The [W] obstructs your movement!")) return if((direct & W.dir) && W.density) - to_chat(mob, SPAN_WARNING("\The [W] obstructs your movement!")) + to_chat(src, SPAN_WARNING("\The [W] obstructs your movement!")) return if(istype(T, /turf/simulated/wall/phoron) || istype(T, /turf/simulated/wall/ironphoron)) - to_chat(mob, SPAN_WARNING("\The [T] obstructs your movement!")) + to_chat(src, SPAN_WARNING("\The [T] obstructs your movement!")) return for(var/mob/living/L in T) if(L.is_diona() == DIONA_WORKER) - to_chat(mob, SPAN_DANGER("You struggle briefly as you are photovored into \the [L], trapped within a nymphomatic husk!")) + to_chat(src, SPAN_DANGER("You struggle briefly as you are photovored into \the [L], trapped within a nymphomatic husk!")) var/mob/living/carbon/alien/diona/D = new /mob/living/carbon/alien/diona(L) - var/mob/living/simple_animal/shade/bluespace/BS = mob + var/mob/living/simple_animal/shade/bluespace/BS = use_mob if (!(/mob/living/carbon/proc/echo_eject in L.verbs)) L.verbs.Add(/mob/living/carbon/proc/echo_eject) BS.mind.transfer_to(D) @@ -445,21 +450,21 @@ qdel(BS) return - mob.forceMove(get_step(mob, direct)) - mob.dir = direct + use_mob.forceMove(get_step(use_mob, direct)) + use_mob.dir = direct // Crossed is always a bit iffy - for(var/obj/S in mob.loc) + for(var/obj/S in use_mob.loc) if(istype(S,/obj/effect/step_trigger) || istype(S,/obj/effect/beam)) - S.Crossed(mob) + S.Crossed(use_mob) - var/area/A = get_area_master(mob) + var/area/A = get_area_master(use_mob) if(A) - A.Entered(mob) - if(isturf(mob.loc)) - var/turf/T = mob.loc - T.Entered(mob) - mob.Post_Incorpmove() + A.Entered(use_mob) + if(isturf(use_mob.loc)) + var/turf/T = use_mob.loc + T.Entered(use_mob) + use_mob.Post_Incorpmove() return 1 /mob/proc/Post_Incorpmove() diff --git a/code/modules/research/designs/mechfab/mechs/designs_exosuit_equipment.dm b/code/modules/research/designs/mechfab/mechs/designs_exosuit_equipment.dm index e37be761086..7b279a9fc56 100644 --- a/code/modules/research/designs/mechfab/mechs/designs_exosuit_equipment.dm +++ b/code/modules/research/designs/mechfab/mechs/designs_exosuit_equipment.dm @@ -131,4 +131,14 @@ /datum/design/item/mechfab/exosuit_equipment/drill_mover name = "Mounted Drill Loader System" materials = list(DEFAULT_WALL_MATERIAL = 15000) - build_path = /obj/item/mecha_equipment/drill_mover \ No newline at end of file + build_path = /obj/item/mecha_equipment/drill_mover + +/datum/design/item/mechfab/exosuit_equipment/phazon + name = "Phazon Bluespace Transmission System" + materials = list(MATERIAL_STEEL = 25000, MATERIAL_PHORON = 10000) + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_BLUESPACE = 5) + build_path = /obj/item/mecha_equipment/phazon + +/datum/design/item/mechfab/exosuit_equipment/phazon/AssembleDesignDesc() + . = ..() + desc += " It needs an anomaly core to function, however." \ No newline at end of file diff --git a/html/changelogs/geeves-phazon_module.yml b/html/changelogs/geeves-phazon_module.yml new file mode 100644 index 00000000000..c14a9065fa7 --- /dev/null +++ b/html/changelogs/geeves-phazon_module.yml @@ -0,0 +1,6 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Added the phazon bluespace transmission system to the mechfab. When built and supplied with an anomaly core, it'll allow exosuit to pass through solid objects, at a massive energy cost." \ No newline at end of file diff --git a/icons/mecha/mech_equipment.dmi b/icons/mecha/mech_equipment.dmi index c9602e9cc91..90c3520826b 100644 Binary files a/icons/mecha/mech_equipment.dmi and b/icons/mecha/mech_equipment.dmi differ