diff --git a/code/__DEFINES/mode.dm b/code/__DEFINES/mode.dm index c396beba64ac..28471f3a5ea1 100644 --- a/code/__DEFINES/mode.dm +++ b/code/__DEFINES/mode.dm @@ -2,7 +2,7 @@ //Self-destruct, nuke, and evacuation. #define EVACUATION_TIME_LOCK 1 HOURS #define DISTRESS_TIME_LOCK 6 MINUTES -#define SHUTTLE_TIME_LOCK 0 MINUTES +#define SHUTTLE_TIME_LOCK 15 MINUTES #define SHUTTLE_LOCK_COOLDOWN 10 MINUTES #define MONORAIL_LOCK_COOLDOWN 3 MINUTES #define SHUTTLE_LOCK_TIME_LOCK 1 MINUTES diff --git a/code/game/machinery/computer/dropship_weapons.dm b/code/game/machinery/computer/dropship_weapons.dm index 2b137c3ef742..c49ba4b31ee0 100644 --- a/code/game/machinery/computer/dropship_weapons.dm +++ b/code/game/machinery/computer/dropship_weapons.dm @@ -454,44 +454,47 @@ initiate_firemission(user, fm_tag, direction, text2num(offset_x_value), text2num(offset_y_value)) return TRUE if("paradrop-lock") - to_chat(world, "test12314124") var/obj/docking_port/mobile/marine_dropship/linked_shuttle = SSshuttle.getShuttle(shuttle_tag) if(!linked_shuttle) return FALSE - to_chat(world, "1") if(linked_shuttle.mode != SHUTTLE_CALL) return FALSE - to_chat(world, "2") if(linked_shuttle.paradrop_signal) clear_locked_turf_and_lock_aft() return TRUE - to_chat(world, "3 [camera_target_id]") var/datum/cas_signal/sig = get_cas_signal(camera_target_id) if(!sig) return FALSE - to_chat(world, "4 [camera_target_id]") var/turf/location = get_turf(sig.signal_loc) var/area/location_area = get_area(location) if(CEILING_IS_PROTECTED(location_area.ceiling, CEILING_PROTECTION_TIER_1)) return FALSE - to_chat(world, "5 [camera_target_id]") linked_shuttle.paradrop_signal = sig linked_shuttle.door_control.control_doors("force-unlock", "aft", TRUE) RegisterSignal(linked_shuttle.paradrop_signal, COMSIG_PARENT_QDELETING, PROC_REF(clear_locked_turf_and_lock_aft)) RegisterSignal(linked_shuttle, COMSIG_SHUTTLE_SETMODE, PROC_REF(clear_locked_turf_and_lock_aft)) - to_chat(world, "test123141245555555555") + var/equipment_tag = params["equipment_id"] + for(var/obj/structure/dropship_equipment/equipment as anything in shuttle.equipments) + var/mount_point = equipment.ship_base.attach_id + if(mount_point != equipment_tag) + continue + if(istype(equipment, /obj/structure/dropship_equipment/paradrop_system)) + equipment.visible_message(SPAN_NOTICE("[equipment] hums as it locks to a signal.")) + break return TRUE /obj/structure/machinery/computer/dropship_weapons/proc/clear_locked_turf_and_lock_aft() SIGNAL_HANDLER - var/obj/docking_port/mobile/marine_dropship/linked_shuttle = SSshuttle.getShuttle(shuttle_tag) - if(!linked_shuttle) + var/obj/docking_port/mobile/marine_dropship/shuttle = SSshuttle.getShuttle(shuttle_tag) + if(!shuttle) return - linked_shuttle.door_control.control_doors("force-lock", "aft", TRUE) - visible_message("[src] displays an alert as it loses the target signal.") - UnregisterSignal(linked_shuttle.paradrop_signal, COMSIG_PARENT_QDELETING) - UnregisterSignal(linked_shuttle, COMSIG_SHUTTLE_SETMODE) - linked_shuttle.paradrop_signal = null + shuttle.door_control.control_doors("force-lock", "aft", TRUE) + visible_message(SPAN_WARNING("[src] displays an alert as it loses the paradrop target.")) + for(var/obj/structure/dropship_equipment/paradrop_system/parad in shuttle.equipments) + parad.visible_message(SPAN_WARNING("[parad] displays an alert as it loses the paradrop target.")) + UnregisterSignal(shuttle.paradrop_signal, COMSIG_PARENT_QDELETING) + UnregisterSignal(shuttle, COMSIG_SHUTTLE_SETMODE) + shuttle.paradrop_signal = null /obj/structure/machinery/computer/dropship_weapons/proc/get_weapon(eqp_tag) var/obj/docking_port/mobile/marine_dropship/dropship = SSshuttle.getShuttle(shuttle_tag) diff --git a/code/game/objects/items/misc.dm b/code/game/objects/items/misc.dm index 1699cb24ef39..8ce4ddc83abe 100644 --- a/code/game/objects/items/misc.dm +++ b/code/game/objects/items/misc.dm @@ -293,8 +293,8 @@ new /obj/item/evidencebag(src) /obj/item/rappel_harness - name = "rappel harness" - desc = "A simple, uncomfortable rappel harness with just enough safety straps to make RnD pass health and safety. It comes with an in-built descender, but has no pouches for ammunition." + name = "paradrop harness" + desc = "A simple, uncomfortable harness with just enough safety straps to make RnD pass health and safety. It comes with an in-built descender, but has no pouches for ammunition. You won't be able to paradrop without this thing." icon = 'icons/obj/items/clothing/belts.dmi' icon_state = "rappel_harness" item_state = "rappel_harness" diff --git a/code/game/turfs/transit.dm b/code/game/turfs/transit.dm index 9a17d45806fe..a1a24890a9b4 100644 --- a/code/game/turfs/transit.dm +++ b/code/game/turfs/transit.dm @@ -24,6 +24,8 @@ /turf/open/space/transit/proc/handle_crosser(atom/movable/crosser) if(QDELETED(crosser)) return + if(crosser.can_paradrop()) //let's not delete people who arent meant to be deleted... This shouldn't happen normally, but if it does, congratulations, you gamed the system + return qdel(crosser) /turf/open/space/transit/dropship @@ -44,14 +46,7 @@ if(!length(ground_z_levels)) return ..() - var/paradrop = FALSE - - if(ishuman(crosser)) - var/mob/living/carbon/human/crossing_human = crosser - if(istype(crossing_human.belt, /obj/item/rappel_harness)) - paradrop = TRUE - else if(istype(crosser, /obj/structure/closet/crate)) - paradrop = TRUE + var/failed_drop = FALSE if(dropship.paradrop_signal) //if dropship in paradrop mode, drop them near the signal. Whether they have a parachute or not var/list/valid_turfs = list() @@ -73,13 +68,17 @@ continue valid_turfs += T - if(!length(valid_turfs)) - to_chat(crosser, SPAN_WARNING("You couldn't find a fitting landing spot at desinated zone and had to find another place to land.")) - else + if(length(valid_turfs)) //if we found a fitting place near the landing zone... var/turf/deploy_turf = pick(valid_turfs) - INVOKE_ASYNC(src, PROC_REF(handle_drop), crosser, deploy_turf, dropship.name, paradrop) + if(crosser.can_paradrop()) + INVOKE_ASYNC(crosser, TYPE_PROC_REF(/atom/movable, handle_paradrop), deploy_turf, dropship.name) + return + INVOKE_ASYNC(crosser, TYPE_PROC_REF(/atom/movable, handle_airdrop), deploy_turf, dropship.name) return + failed_drop = TRUE //If we don't (which hopefully won't happen) we will try to just drop them somewhere else, emergency gameplay? + + //find a random spot to drop them var/list/area/potential_areas = shuffle(SSmapping.areas_in_z["[ground_z_levels[1]]"]) for(var/area/maybe_this_area in potential_areas) @@ -99,99 +98,106 @@ if(!istype(possible_turf) || is_blocked_turf(possible_turf) || istype(possible_turf, /turf/open/space)) continue // couldnt find one in 10 loops, check another area + if(failed_drop) + to_chat(crosser, SPAN_BOLDWARNING("You got carried away from the dropping zone by the wind!")) + // we found a good turf, lets drop em - INVOKE_ASYNC(src, PROC_REF(handle_drop), crosser, possible_turf, dropship.name, paradrop) + if(crosser.can_paradrop()) + INVOKE_ASYNC(crosser, TYPE_PROC_REF(/atom/movable, handle_paradrop), possible_turf, dropship.name) + return + INVOKE_ASYNC(crosser, TYPE_PROC_REF(/atom/movable, handle_airdrop), possible_turf, dropship.name) return //we didn't find a turf to drop them... This shouldn't happen usually - if(paradrop) //don't delete them if they have a parachute - to_chat(crosser, "Your backpack hanged on a string to the dropship, get back inside until it's too late!") + if(crosser.can_paradrop()) //don't delete them if they were supposed to paradrop + to_chat(crosser, SPAN_BOLDWARNING("Your harness got stuck and you got thrown back in the dropship.")) + var/turf/projected = get_ranged_target_turf(crosser.loc, turn(dir, 180), 15) + INVOKE_ASYNC(crosser, TYPE_PROC_REF(/atom/movable, throw_atom), projected, 50, SPEED_FAST, null, TRUE) return return ..() // they couldn't be dropped, just delete them -/turf/open/space/transit/dropship/proc/handle_paradrop(atom/movable/crosser, turf/target, dropship_name) - if(QDELETED(crosser)) - return - ADD_TRAIT(crosser, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) - ADD_TRAIT(crosser, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION) - to_chat(world, "test") - var/image/cables = image('icons/obj/structures/droppod_32x64.dmi', crosser, "chute_cables_static") - crosser.overlays += cables - var/image/chute = image('icons/obj/structures/droppod_64x64.dmi', crosser, "chute_static") + +/atom/movable/proc/can_paradrop() + return FALSE + +/mob/living/carbon/human/can_paradrop() + if(istype(belt, /obj/item/rappel_harness)) + return TRUE + ..() + +/obj/structure/closet/crate/can_paradrop() //for now all crates can be paradropped + return TRUE + +/atom/movable/proc/handle_paradrop(turf/target, dropship_name) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) + ADD_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION) + var/image/cables = image('icons/obj/structures/droppod_32x64.dmi', src, "chute_cables_static") + src.overlays += cables + var/image/chute = image('icons/obj/structures/droppod_64x64.dmi', src, "chute_static") chute.pixel_x -= 16 chute.pixel_y += 16 - crosser.overlays += chute - crosser.pixel_z = 360 - crosser.forceMove(target) - animate(crosser, time = 40, pixel_z = 0, flags = ANIMATION_PARALLEL) - addtimer(CALLBACK(target, PROC_REF(ceiling_debris)), 2 SECONDS) - addtimer(CALLBACK(src, PROC_REF(clear_parachute), crosser, cables, chute), 4 SECONDS) + src.overlays += chute + src.pixel_z = 360 + src.forceMove(target) + animate(src, time = 3.5 SECONDS, pixel_z = 0, flags = ANIMATION_PARALLEL) + addtimer(CALLBACK(target, TYPE_PROC_REF(/turf, ceiling_debris)), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(clear_parachute), cables, chute), 3.5 SECONDS) -/turf/open/space/transit/dropship/proc/clear_parachute(atom/movable/crosser, image/cables, image/chute) - if(QDELETED(crosser)) - return - REMOVE_TRAIT(crosser, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) - REMOVE_TRAIT(crosser, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION) - crosser.overlays -= cables - crosser.overlays -= chute - -/turf/open/space/transit/dropship/proc/handle_drop(atom/movable/crosser, turf/target, dropship_name, paradrop) - if(paradrop) - handle_paradrop(crosser, target, dropship_name) - return - if(QDELETED(crosser)) +/atom/movable/proc/clear_parachute(image/cables, image/chute) + if(QDELETED(src)) return - ADD_TRAIT(crosser, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) - - crosser.pixel_z = 360 - crosser.forceMove(target) - crosser.visible_message(SPAN_WARNING("[crosser] falls out of the sky."), SPAN_HIGHDANGER("As you fall out of the [dropship_name], you plummet towards the ground.")) - animate(crosser, time = 6, pixel_z = 0, flags = ANIMATION_PARALLEL) - target.ceiling_debris() - REMOVE_TRAIT(crosser, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) - if(isitem(crosser)) - var/obj/item/item = crosser - item.explosion_throw(200) // give it a bit of a kick + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) + REMOVE_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION) + overlays -= cables + overlays -= chute + +/atom/movable/proc/handle_airdrop(turf/target, dropship_name) + ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) + pixel_z = 360 + forceMove(target) + visible_message(SPAN_WARNING("[src] falls out of the sky."), SPAN_HIGHDANGER("As you fall out of the [dropship_name], you plummet towards the ground.")) + animate(src, time = 6, pixel_z = 0, flags = ANIMATION_PARALLEL) + INVOKE_ASYNC(target, TYPE_PROC_REF(/turf, ceiling_debris)) + REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) + +/obj/handle_airdrop(turf/target, dropship_name) + ..() + if(!indestructible && prob(30)) // throwing objects from the air is not always a good idea + deconstruct(FALSE) + +/obj/item/handle_airdrop(turf/target, dropship_name) + ..() + if(QDELETED(src)) return + src.explosion_throw(200) // give it a bit of a kick - if(isobj(crosser)) - var/obj/obj = crosser - obj.ex_act(500) - return - - if(!isliving(crosser)) - return // don't know how you got here, but you shouldnt be here. - var/mob/living/fallen_mob = crosser - +/mob/living/handle_airdrop(turf/target, dropship_name) + ..() playsound(target, "punch", rand(20, 70), TRUE) playsound(target, "punch", rand(20, 70), TRUE) playsound(target, "bone_break", rand(20, 70), TRUE) playsound(target, "bone_break", rand(20, 70), TRUE) - fallen_mob.KnockDown(10) // 10 seconds - fallen_mob.Stun(3) // 3 seconds - - // if(isxeno(fallen_mob)) - // var/mob/living/carbon/xenomorph/xeno = fallen_mob - // xeno.gib(create_cause_data("falling from [dropship_name]", xeno)) - // return - - if(ishuman(fallen_mob)) - var/mob/living/carbon/human/human = fallen_mob - human.last_damage_data = create_cause_data("falling from [dropship_name]", human) - // I'd say falling from space is pretty much like getting hit by an explosion - human.take_overall_armored_damage(300, ARMOR_BOMB, limb_damage_chance = 100) - // but just in case, you will still take a ton of damage. - human.take_overall_damage(200, used_weapon = "falling", limb_damage_chance = 100) - if(human.stat != DEAD) - human.death(human.last_damage_data) - fallen_mob.status_flags |= PERMANENTLY_DEAD - return + KnockDown(10) // 10 seconds + Stun(3) // 3 seconds // take a little bit more damage otherwise - fallen_mob.take_overall_damage(400, used_weapon = "falling", limb_damage_chance = 100) + take_overall_damage(400, used_weapon = "falling", limb_damage_chance = 100) + +/mob/living/carbon/human/handle_airdrop(turf/target, dropship_name) + ..() + last_damage_data = create_cause_data("falling from [dropship_name]", src) + // I'd say falling from space is pretty much like getting hit by an explosion + take_overall_armored_damage(300, ARMOR_BOMB, limb_damage_chance = 100) + // but just in case, you will still take a ton of damage. + take_overall_damage(200, used_weapon = "falling", limb_damage_chance = 100) + if(stat != DEAD) + death(last_damage_data) + status_flags |= PERMANENTLY_DEAD + return + /turf/open/space/transit/dropship/alamo shuttle_tag = DROPSHIP_ALAMO diff --git a/code/modules/cm_marines/dropship_equipment.dm b/code/modules/cm_marines/dropship_equipment.dm index 911d27e787cb..64778a9ddb25 100644 --- a/code/modules/cm_marines/dropship_equipment.dm +++ b/code/modules/cm_marines/dropship_equipment.dm @@ -1296,9 +1296,9 @@ fulton_cooldown = world.time + 50 // Rappel deployment system -/obj/structure/dropship_equipment/rappel_system - name = "\improper HPU-1 Rappel Deployment System" - shorthand = "Rappel" +/obj/structure/dropship_equipment/paradrop_system + name = "\improper HPU-1 Paradrop Deployment System" + shorthand = "PDS" equip_categories = list(DROPSHIP_CREW_WEAPON) icon_state = "rappel_module_packaged" point_cost = 50 @@ -1306,73 +1306,20 @@ var/harness = /obj/item/rappel_harness -/obj/structure/dropship_equipment/rappel_system/ui_data(mob/user) +/obj/structure/dropship_equipment/paradrop_system/ui_data(mob/user) . = list() .["signal"] = (linked_shuttle.paradrop_signal != null ? linked_shuttle.paradrop_signal : null) .["locked"] = (linked_shuttle.paradrop_signal != null) -/obj/structure/dropship_equipment/rappel_system/update_equipment() +/obj/structure/dropship_equipment/paradrop_system/update_equipment() if(ship_base) icon_state = "rappel_hatch_closed" density = FALSE else icon_state = "rappel_module_packaged" -/obj/effect/warning/rappel - color = "#17d17a" - -/obj/structure/dropship_equipment/rappel_system/attack_hand(mob/living/carbon/human/user) - var/datum/cas_iff_group/cas_group = GLOB.cas_groups[FACTION_MARINE] - var/list/targets = cas_group.cas_signals - - if(!LAZYLEN(targets)) - to_chat(user, SPAN_NOTICE("No CAS signals found.")) - return - - if(!can_use(user)) - return - - var/user_input = tgui_input_list(user, "Choose a target to jump to.", name, targets) - if(!user_input) - return - - if(!can_use(user)) - return - - var/datum/cas_signal/LT = user_input - if(!istype(LT) || !LT.valid_signal()) - return - - var/turf/location = get_turf(LT.signal_loc) - var/area/location_area = get_area(location) - if(CEILING_IS_PROTECTED(location_area.ceiling, CEILING_PROTECTION_TIER_1)) - to_chat(user, SPAN_WARNING("You cannot find the target. It is probably underground.")) - return - - linked_shuttle.paradrop_signal = LT - linked_shuttle.door_control.control_doors("force-unlock", "aft", TRUE) - RegisterSignal(linked_shuttle.paradrop_signal, COMSIG_PARENT_QDELETING, PROC_REF(clear_locked_turf_and_lock_aft)) - RegisterSignal(linked_shuttle, COMSIG_SHUTTLE_SETMODE, PROC_REF(clear_locked_turf_and_lock_aft)) - -/obj/structure/dropship_equipment/rappel_system/proc/clear_locked_turf_and_lock_aft() - SIGNAL_HANDLER - linked_shuttle.door_control.control_doors("force-lock", "aft", TRUE) - visible_message("[src] displays an alert as it loses the target signal.") - UnregisterSignal(linked_shuttle.paradrop_signal, COMSIG_PARENT_QDELETING) - UnregisterSignal(linked_shuttle, COMSIG_SHUTTLE_SETMODE) - linked_shuttle.paradrop_signal = null - - -/obj/structure/dropship_equipment/rappel_system/proc/can_use(mob/living/carbon/human/user) - if(linked_shuttle.mode != SHUTTLE_CALL) - to_chat(user, SPAN_WARNING("\The [src] can only be used while in flight.")) - return FALSE - - if(user.is_mob_incapacitated()) - to_chat(user, SPAN_WARNING("You are in no state to do that!")) - return FALSE - - return TRUE +/obj/structure/dropship_equipment/paradrop_system/attack_hand(mob/living/carbon/human/user) + return // used in the simulation room for cas runs, removed the sound and ammo depletion methods. // copying code is definitely bad, but adding an unnecessary sim or not sim boolean check in the open_fire_firemission just doesn't seem right. diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index 8ccad6d6cca2..0322a3fc2ef6 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -30249,7 +30249,7 @@ }, /area/almayer/engineering/upper_engineering/starboard) "gpi" = ( -/obj/structure/dropship_equipment/rappel_system, +/obj/structure/dropship_equipment/paradrop_system, /turf/open/floor/almayer{ icon_state = "test_floor4" }, diff --git a/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx b/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx index 679b78efe843..7466942aa141 100644 --- a/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx +++ b/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx @@ -86,10 +86,13 @@ const DropshipDoorControl = () => { <> {x.value === DoorStatusEnum.SHUTTLE_DOOR_BROKEN && ( - + )} {x.value === DoorStatusEnum.SHUTTLE_DOOR_UNLOCKED && (