Skip to content

Commit

Permalink
Breacher Shuttle addition
Browse files Browse the repository at this point in the history
  • Loading branch information
SpypigDev committed Sep 10, 2024
1 parent dffcf65 commit a2529ab
Show file tree
Hide file tree
Showing 8 changed files with 2,104 additions and 70,041 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,13 @@
#define ESCAPE_SHUTTLE_WEST "escape_shuttle_w"
#define ESCAPE_SHUTTLE_NORTH "escape_shuttle_n"
#define ESCAPE_SHUTTLE_SOUTH "escape_shuttle_s"
#define ESCAPE_SHUTTLE_BREACH "breacher_shuttle"

#define ESCAPE_SHUTTLE_WEST_PREFIX "escape_shuttle_w"
#define ESCAPE_SHUTTLE_EAST_PREFIX "escape_shuttle_e"
#define ESCAPE_SHUTTLE_NORTH_PREFIX "escape_shuttle_n"
#define ESCAPE_SHUTTLE_SOUTH_PREFIX "escape_shuttle_s"
#define ESCAPE_SHUTTLE_BREACH_PREFIX "breacher_shuttle"

#define ESCAPE_SHUTTLE_DOCK_PREFIX "almayer-hangar-escape-shuttle-"

Expand Down
4 changes: 4 additions & 0 deletions code/game/area/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@
icon = 'icons/turf/area_almayer.dmi'
icon_state = "lifeboat"

/area/shuttle/breach
icon = 'icons/turf/area_almayer.dmi'
icon_state = "lifeboat"

/area/shuttle/escape_pod/afterShuttleMove(new_parallax_dir)
. = ..()
playsound_area(src, 'sound/effects/escape_pod_launch.ogg', 50, 1)
Expand Down
233 changes: 233 additions & 0 deletions code/modules/shuttle/computers/breacher_computer.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
#define STATE_IDLE 4 //Pod is idle, not ready to launch.
#define STATE_BROKEN 5 //Pod failed to launch, is now broken.
#define STATE_READY 6 //Pod is armed and ready to go.
#define STATE_DELAYED 7 //Pod is being delayed from launching automatically.
#define STATE_LAUNCHING 8 //Pod is about to launch.
#define STATE_LAUNCHED 9 //Pod has successfully launched.

/obj/structure/machinery/computer/shuttle/breacher_pod_panel
name = "breacher shuttle controller"
icon = 'icons/obj/structures/machinery/airlock_machines.dmi'
icon_state = "airlock_control_standby"
unslashable = TRUE
unacidable = TRUE
var/pod_state = STATE_IDLE
var/launch_without_evac = FALSE

/obj/structure/machinery/computer/shuttle/breacher_pod_panel/ex_act(severity)
return FALSE

// TGUI stufferinos \\
/obj/structure/machinery/computer/shuttle/breacher_pod_panel/attack_hand(mob/user)
if(..())
return
tgui_interact(user)

/obj/structure/machinery/computer/shuttle/breacher_pod_panel/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "EscapePodConsole", "[src.name]")
ui.open()

/obj/structure/machinery/computer/shuttle/breacher_pod_panel/ui_state(mob/user)
return GLOB.not_incapacitated_and_adjacent_state

/obj/structure/machinery/computer/shuttle/breacher_pod_panel/ui_status(mob/user, datum/ui_state/state)
. = ..()
if(inoperable())
return UI_CLOSE

/obj/structure/machinery/computer/shuttle/breacher_pod_panel/ui_data(mob/user)
. = list()
var/obj/docking_port/mobile/crashable/breacher/shuttle = SSshuttle.getShuttle(shuttleId)

if(pod_state == STATE_IDLE && shuttle.evac_set)
pod_state = STATE_READY

.["docking_status"] = pod_state
switch(shuttle.mode)
if(SHUTTLE_CRASHED)
.["docking_status"] = STATE_BROKEN
if(SHUTTLE_IGNITING)
.["docking_status"] = STATE_LAUNCHING
if(SHUTTLE_CALL)
.["docking_status"] = STATE_LAUNCHED
var/obj/structure/machinery/door/door = shuttle.door_handler.doors[1]
.["door_state"] = door.density
.["door_lock"] = shuttle.door_handler.status == SHUTTLE_DOOR_LOCKED
.["can_delay"] = TRUE//launch_status[2]
.["launch_without_evac"] = launch_without_evac


/obj/structure/machinery/computer/shuttle/breacher_pod_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return

var/obj/docking_port/mobile/crashable/breacher/shuttle = SSshuttle.getShuttle(shuttleId)
switch(action)
if("force_launch")
if(!launch_without_evac && pod_state != STATE_READY && pod_state != STATE_DELAYED)
return

shuttle.evac_launch()
pod_state = STATE_LAUNCHING
. = TRUE
if("delay_launch")
pod_state = pod_state == STATE_DELAYED ? STATE_READY : STATE_DELAYED
. = TRUE
if("lock_door")
var/obj/structure/machinery/door/target_door = shuttle.door_handler.doors[1]
if(target_door.density) //Closed
shuttle.door_handler.control_doors("force-unlock")
else //Open
shuttle.door_handler.control_doors("force-lock-launch")
. = TRUE

/obj/structure/machinery/computer/shuttle/breacher_pod_panel/liaison
launch_without_evac = TRUE

//=========================================================================================
//================================Evacuation Sleeper=======================================
//=========================================================================================

/obj/structure/machinery/cryopod/evacuation/ex_act(severity)
return FALSE

/obj/structure/machinery/cryopod/evacuation/attackby(obj/item/grab/G, mob/user)
if(istype(G))
if(being_forced)
to_chat(user, SPAN_WARNING("There's something forcing it open!"))
return FALSE

if(occupant)
to_chat(user, SPAN_WARNING("There is someone in there already!"))
return FALSE

if(dock_state < STATE_READY)
to_chat(user, SPAN_WARNING("The cryo pod is not responding to commands!"))
return FALSE

var/mob/living/carbon/human/M = G.grabbed_thing
if(!istype(M))
return FALSE

visible_message(SPAN_WARNING("[user] starts putting [M.name] into the cryo pod."), null, null, 3)

if(do_after(user, 20, INTERRUPT_ALL, BUSY_ICON_GENERIC))
if(!M || !G || !G.grabbed_thing || !G.grabbed_thing.loc || G.grabbed_thing != M)
return FALSE
move_mob_inside(M)

/obj/structure/machinery/cryopod/evacuation/eject()
set name = "Eject Pod"
set category = "Object"
set src in oview(1)

if(!occupant || !usr.stat || usr.is_mob_restrained())
return FALSE

if(occupant) //Once you're in, you cannot exit, and outside forces cannot eject you.
//The occupant is actually automatically ejected once the evac is canceled.
if(occupant != usr) to_chat(usr, SPAN_WARNING("You are unable to eject the occupant unless the evacuation is canceled."))

add_fingerprint(usr)

/obj/structure/machinery/cryopod/evacuation/go_out() //When the system ejects the occupant.
if(occupant)
occupant.forceMove(get_turf(src))
occupant.in_stasis = FALSE
occupant = null
icon_state = orient_right ? "body_scanner_open-r" : "body_scanner_open"

/obj/structure/machinery/cryopod/evacuation/move_inside()
set name = "Enter Pod"
set category = "Object"
set src in oview(1)

var/mob/living/carbon/human/user = usr

if(!istype(user) || user.stat || user.is_mob_restrained())
return FALSE

if(being_forced)
to_chat(user, SPAN_WARNING("You can't enter when it's being forced open!"))
return FALSE

if(occupant)
to_chat(user, SPAN_WARNING("The cryogenic pod is already in use! You will need to find another."))
return FALSE

if(dock_state < STATE_READY)
to_chat(user, SPAN_WARNING("The cryo pod is not responding to commands!"))
return FALSE

visible_message(SPAN_WARNING("[user] starts climbing into the cryo pod."), null, null, 3)

if(do_after(user, 20, INTERRUPT_NO_NEEDHAND, BUSY_ICON_GENERIC))
user.stop_pulling()
move_mob_inside(user)

/obj/structure/machinery/cryopod/evacuation/attack_alien(mob/living/carbon/xenomorph/user)
if(being_forced)
to_chat(user, SPAN_XENOWARNING("It's being forced open already!"))
return XENO_NO_DELAY_ACTION

if(!occupant)
to_chat(user, SPAN_XENOWARNING("There is nothing of interest in there."))
return XENO_NO_DELAY_ACTION

being_forced = !being_forced
xeno_attack_delay(user)
visible_message(SPAN_WARNING("[user] begins to pry \the [src]'s cover!"), null, null, 3)
playsound(src,'sound/effects/metal_creaking.ogg', 25, 1)
if(do_after(user, 20, INTERRUPT_ALL, BUSY_ICON_HOSTILE)) go_out() //Force the occupant out.
being_forced = !being_forced
return XENO_NO_DELAY_ACTION

/obj/structure/machinery/door/airlock/evacuation/Initialize()
. = ..()
if(start_locked)
INVOKE_ASYNC(src, PROC_REF(lock))

/obj/structure/machinery/door/airlock/evacuation/Destroy()
if(linked_shuttle)
linked_shuttle.mode = SHUTTLE_CRASHED
linked_shuttle.door_handler.doors -= list(src)
. = ..()

//Can't interact with them, mostly to prevent grief and meta.
/obj/structure/machinery/door/airlock/evacuation/Collided()
return FALSE

/obj/structure/machinery/door/airlock/evacuation/attackby()
return FALSE

/obj/structure/machinery/door/airlock/evacuation/attack_hand()
return FALSE

/obj/structure/machinery/door/airlock/evacuation/attack_alien(mob/living/carbon/xenomorph/xeno)
if(!density || unslashable) //doors become slashable after evac is called
return FALSE

if(xeno.claw_type < CLAW_TYPE_SHARP)
to_chat(xeno, SPAN_WARNING("[src] is bolted down tight."))
return XENO_NO_DELAY_ACTION

xeno.animation_attack_on(src)
playsound(src, 'sound/effects/metalhit.ogg', 25, 1)
take_damage(HEALTH_DOOR / XENO_HITS_TO_DESTROY_BOLTED_DOOR)
return XENO_ATTACK_ACTION


/obj/structure/machinery/door/airlock/evacuation/attack_remote()
return FALSE

/obj/structure/machinery/door/airlock/evacuation/get_applying_acid_time() //you can melt evacuation doors only when they are manually locked
if(!density)
return -1
return ..()

/obj/structure/machinery/door/airlock/evacuation/liaison
start_locked = FALSE
134 changes: 134 additions & 0 deletions code/modules/shuttle/shuttles/crashable/breacher.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/obj/docking_port/mobile/crashable/breacher
name = "Breacher Shuttle"
id = ESCAPE_SHUTTLE
area_type = /area/shuttle/breach
width = 5
height = 13
preferred_direction = SOUTH
rechargeTime = SHUTTLE_RECHARGE
ignitionTime = 8 SECONDS
ignition_sound = 'sound/effects/escape_pod_warmup.ogg'
/// The % chance of the escape pod crashing into the groundmap before lifeboats leaving
var/early_crash_land_chance = 75
/// The % chance of the escape pod crashing into the groundmap
var/crash_land_chance = 0
/// How many people can be in the escape pod before it crashes
var/max_capacity = 3

var/datum/door_controller/single/door_handler = new()
var/launched = FALSE
var/evac_set = FALSE

/obj/docking_port/mobile/crashable/breacher/Initialize(mapload)
. = ..(mapload)
for(var/place in shuttle_areas)
for(var/obj/structure/machinery/door/airlock/evacuation/air in place)
door_handler.doors += list(air)
air.breakable = FALSE
air.indestructible = TRUE
air.unacidable = TRUE
air.linked_shuttle = src

/obj/docking_port/mobile/crashable/breacher/proc/cancel_evac()
door_handler.control_doors("force-unlock")
evac_set = FALSE

var/obj/structure/machinery/computer/shuttle/escape_pod_panel/panel = getControlConsole()
if(panel.pod_state != STATE_READY && panel.pod_state != STATE_DELAYED)
return
panel.pod_state = STATE_IDLE
for(var/area/interior_area in shuttle_areas)
for(var/obj/structure/machinery/cryopod/evacuation/cryotube in interior_area)
cryotube.dock_state = STATE_IDLE

/obj/docking_port/mobile/crashable/breacher/proc/prepare_evac()
door_handler.control_doors("force-unlock")
evac_set = TRUE
for(var/area/interior_area in shuttle_areas)
for(var/obj/structure/machinery/cryopod/evacuation/cryotube in interior_area)
cryotube.dock_state = STATE_READY
for(var/obj/structure/machinery/door/air in door_handler.doors)
air.breakable = TRUE
air.indestructible = FALSE
air.unslashable = FALSE
air.unacidable = FALSE

/obj/docking_port/mobile/crashable/breacher/evac_launch()
. = ..()

if(mode == SHUTTLE_CRASHED)
return

if(launched)
return

var/obj/structure/machinery/computer/shuttle/escape_pod_panel/panel = getControlConsole()
if(panel.pod_state == STATE_DELAYED)
return

door_handler.control_doors("force-lock-launch")
var/occupant_count = 0
var/list/cryos = list()
for(var/area/interior_area in shuttle_areas)
for(var/mob/living/occupant in interior_area)
occupant_count++
for(var/obj/structure/machinery/cryopod/evacuation/cryotube in interior_area)
cryos += list(cryotube)
if (occupant_count > max_capacity)
playsound(src,'sound/effects/escape_pod_warmup.ogg', 50, 1)
sleep(31)
var/turf/sploded = return_center_turf()
cell_explosion(sploded, 100, 20, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, create_cause_data("escape pod malfunction")) //Clears out walls
sleep(25)
mode = SHUTTLE_CRASHED
for(var/obj/structure/machinery/cryopod/evacuation/cryotube in cryos)
cryotube.go_out()
door_handler.control_doors("force-unlock")
return

set_mode(SHUTTLE_IGNITING)
on_ignition()
setTimer(ignitionTime)
launched = TRUE

if(!crash_land) // so doors won't break in space
for(var/obj/structure/machinery/door/air in door_handler.doors)
for(var/obj/effect/xenomorph/acid/acid in air.loc)
if(acid.acid_t == air)
qdel(acid)
air.breakable = FALSE
air.indestructible = TRUE
air.unacidable = TRUE

/obj/docking_port/mobile/crashable/breacher/crash_check()
. = ..()

if(prob((SShijack.hijack_status >= HIJACK_OBJECTIVES_COMPLETE ? crash_land_chance : early_crash_land_chance)))
return TRUE

/obj/docking_port/mobile/crashable/breacher/open_doors()
. = ..()

door_handler.control_doors("force-unlock")

/obj/docking_port/mobile/crashable/breacher/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
playsound(src,'sound/effects/escape_pod_launch.ogg', 50, 1)

/obj/docking_port/mobile/crashable/breacher/b
id = ESCAPE_SHUTTLE_BREACH
width = 5
height = 13

/obj/docking_port/stationary/breacher
name = "Breacher Dock"

/obj/docking_port/stationary/breacher/b
id = ESCAPE_SHUTTLE_BREACH_PREFIX
roundstart_template = /datum/map_template/shuttle/breacher_shuttle
width = 5
height = 13

/datum/map_template/shuttle/breacher_shuttle
name = "Breacher Shuttle"
shuttle_id = ESCAPE_SHUTTLE_BREACH
Loading

0 comments on commit a2529ab

Please sign in to comment.