Skip to content

Commit

Permalink
TGS Test Merge (#6150)
Browse files Browse the repository at this point in the history
  • Loading branch information
cm13-github committed May 5, 2024
2 parents ac54086 + 8fead53 commit 4f139c8
Show file tree
Hide file tree
Showing 19 changed files with 363 additions and 164 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/equipment.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
#define IGNITING_ITEM (1<<13)
/// Overrides NODROP in some cases (stripping)
#define FORCEDROP_CONDITIONAL (1<<14)
/// Overrides smartgunner not being able to wear backpacks
#define SMARTGUNNER_BACKPACK_OVERRIDE (1<<15)
//==========================================================================================


Expand Down
29 changes: 29 additions & 0 deletions code/datums/supply_packs/gear.dm
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,32 @@
containertype = /obj/structure/closet/crate/ammo
containername = "fulton recovery device crate"
group = "Gear"

/datum/supply_packs/parachute
name = "parachute crate (x20)"
contains = list(
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
/obj/item/parachute,
)
cost = 40
containertype = /obj/structure/closet/crate/supply
containername = "parachute crate"
group = "Gear"
55 changes: 55 additions & 0 deletions code/game/machinery/computer/dropship_weapons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,61 @@

initiate_firemission(user, fm_tag, direction, text2num(offset_x_value), text2num(offset_y_value))
return TRUE
if("paradrop-lock")
var/obj/docking_port/mobile/marine_dropship/linked_shuttle = SSshuttle.getShuttle(shuttle_tag)
if(!linked_shuttle)
return FALSE
if(linked_shuttle.mode != SHUTTLE_CALL)
return FALSE
if(linked_shuttle.paradrop_signal)
clear_locked_turf_and_lock_aft()
return TRUE
var/datum/cas_signal/sig = get_cas_signal(camera_target_id)
if(!sig)
to_chat(user, SPAN_WARNING("No signal chosen."))
return FALSE
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))
to_chat(user, SPAN_WARNING("Target is obscured."))
return FALSE
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))
var/obj/structure/dropship_equipment/paradrop_system/paradrop_system = equipment
if(paradrop_system.system_cooldown > world.time)
to_chat(user, SPAN_WARNING("You toggled the system too recently."))
return
paradrop_system.system_cooldown = world.time + 5 SECONDS
paradrop_system.visible_message(SPAN_NOTICE("[equipment] hums as it locks to a signal."))
break
linked_shuttle.paradrop_signal = sig
addtimer(CALLBACK(src, PROC_REF(open_aft_for_paradrop)), 2 SECONDS)
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))
return TRUE

/obj/structure/machinery/computer/dropship_weapons/proc/open_aft_for_paradrop()
var/obj/docking_port/mobile/marine_dropship/shuttle = SSshuttle.getShuttle(shuttle_tag)
if(!shuttle || !shuttle.paradrop_signal || shuttle.mode != SHUTTLE_CALL)
return
shuttle.door_control.control_doors("force-unlock", "aft", TRUE)

/obj/structure/machinery/computer/dropship_weapons/proc/clear_locked_turf_and_lock_aft()
SIGNAL_HANDLER
var/obj/docking_port/mobile/marine_dropship/shuttle = SSshuttle.getShuttle(shuttle_tag)
if(!shuttle)
return
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)
Expand Down
7 changes: 5 additions & 2 deletions code/game/machinery/doors/multi_tile.dm
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@
return
..()

/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/unlock()
if(is_reserved_level(z))
/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/unlock(forced=FALSE)
if(is_reserved_level(z) && !forced)
return // in orbit
..()

Expand All @@ -294,6 +294,9 @@
if(xeno.action_busy)
return

if(is_reserved_level(z)) //no prying in space even though it's funny
return

var/direction
switch(id)
if("starboard_door")
Expand Down
2 changes: 1 addition & 1 deletion code/game/machinery/vending/vendor_types/requisitions.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
list("Technician Welder-Satchel", round(scale * 5), /obj/item/storage/backpack/marine/engineerpack/satchel, VENDOR_ITEM_REGULAR),
list("IMP Ammo Rack", round(scale * 2), /obj/item/storage/backpack/marine/ammo_rack, VENDOR_ITEM_REGULAR),
list("Radio Telephone Pack", round(scale * 2), /obj/item/storage/backpack/marine/satchel/rto, VENDOR_ITEM_REGULAR),
list("Parachute", round(scale * 20), /obj/item/parachute, VENDOR_ITEM_REGULAR),

list("BELTS", -1, null, null),
list("G8-A General Utility Pouch", round(scale * 2), /obj/item/storage/backpack/general_belt, VENDOR_ITEM_REGULAR),
Expand All @@ -89,7 +90,6 @@
list("M276 M82F Holster Rig", round(scale * 2), /obj/item/storage/belt/gun/flaregun, VENDOR_ITEM_REGULAR),
list("M276 Shotgun Shell Loading Rig", round(scale * 10), /obj/item/storage/belt/shotgun, VENDOR_ITEM_REGULAR),
list("M276 Mortar Operator Belt", round(scale * 2), /obj/item/storage/belt/gun/mortarbelt, VENDOR_ITEM_REGULAR),
list("Rappel Harness", round(scale * 20), /obj/item/rappel_harness, VENDOR_ITEM_REGULAR),

list("POUCHES", -1, null, null),
list("Autoinjector Pouch", round(scale * 1), /obj/item/storage/pouch/autoinjector, VENDOR_ITEM_REGULAR),
Expand Down
15 changes: 8 additions & 7 deletions code/game/objects/items/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,12 @@
new /obj/item/evidencebag(src)
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."
icon = 'icons/obj/items/clothing/belts.dmi'
icon_state = "rappel_harness"
item_state = "rappel_harness"
/obj/item/parachute
name = "parachute"
desc = "A surprisingly small yet bulky pack with just enough safety straps to make RnD pass health and safety. The label says the pack comes with two parachutes - main and reserve, but you doubt the pack can fit even one."
icon = 'icons/obj/items/clothing/backpacks.dmi'
icon_state = "parachute_pack"
item_state = "parachute_pack"
w_class = SIZE_MASSIVE
flags_equip_slot = SLOT_WAIST
flags_equip_slot = SLOT_BACK
flags_item = SMARTGUNNER_BACKPACK_OVERRIDE
190 changes: 154 additions & 36 deletions code/game/turfs/transit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
if(isobserver(crosser) || crosser.anchored)
return

if(!isitem(crosser) && !isliving(crosser))
if(!isobj(crosser) && !isliving(crosser))
return

if(!istype(old_loc, /turf/open/space))
Expand All @@ -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
Expand All @@ -39,14 +41,42 @@
if(!istype(dropship) || dropship.mode != SHUTTLE_CALL)
return ..()

if(dropship.destination.id != DROPSHIP_LZ1 && dropship.destination.id != DROPSHIP_LZ2)
return ..() // we're not heading towards the LZs

// you just jumped out of a dropship heading towards the LZ, have fun living on the way down!
var/list/ground_z_levels = SSmapping.levels_by_trait(ZTRAIT_GROUND)
if(!length(ground_z_levels))
return ..()

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()
var/turf/location = get_turf(dropship.paradrop_signal.signal_loc)
for(var/turf/turf as anything in RANGE_TURFS(crosser.get_paradrop_scatter(), location))
var/area/turf_area = get_area(turf)
if(!turf_area || CEILING_IS_PROTECTED(turf_area.ceiling, CEILING_PROTECTION_TIER_1))
continue
if(turf.density)
continue
var/found_dense = FALSE
for(var/atom/turf_atom in turf)
if(turf_atom.density && turf_atom.can_block_movement)
found_dense = TRUE
break
if(found_dense)
continue
if(protected_by_pylon(TURF_PROTECTION_MORTAR, turf))
continue
valid_turfs += turf
var/turf/deploy_turf
if(length(valid_turfs)) //if we found a fitting place near the landing zone...
deploy_turf = pick(valid_turfs)
else //if we somehow did not. Drop them right on the signal then, there is nothing we can do
deploy_turf = location
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

//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)
Expand All @@ -67,53 +97,141 @@
continue // couldnt find one in 10 loops, check another area

// we found a good turf, lets drop em
INVOKE_ASYNC(src, PROC_REF(handle_drop), crosser, possible_turf, dropship.name)
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(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_drop(atom/movable/crosser, turf/target, dropship_name)
if(QDELETED(crosser))
return
ADD_TRAIT(crosser, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION)
/atom/movable/proc/can_paradrop()
return FALSE

/atom/movable/proc/get_paradrop_scatter()
return 7

/mob/living/carbon/human/can_paradrop()
if(istype(back, /obj/item/parachute))
return TRUE
return ..()

/obj/structure/closet/crate/can_paradrop() //for now all crates can be paradropped
return TRUE

/obj/structure/closet/crate/get_paradrop_scatter() //crates land closer to the signal
return 4

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)
/obj/structure/largecrate/can_paradrop()
return TRUE

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
/obj/structure/largecrate/get_paradrop_scatter()
return 4

/atom/movable/proc/handle_paradrop(turf/target, dropship_name)
clear_active_explosives()
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")
overlays += cables
var/image/chute = image('icons/obj/structures/droppod_64x64.dmi', src, "chute_static")

chute.pixel_x -= 16
chute.pixel_y += 16

overlays += chute
pixel_z = 360
forceMove(target)
playsound(src, 'sound/items/fulton.ogg', 30, 1)
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)

/mob/living/carbon/handle_paradrop(turf/target, dropship_name)
..()
if(client)
playsound_client(client, 'sound/items/fulton.ogg', src, 50, 1) //for some reason you don't hear the sound while dropping, maybe because of force move?

/atom/movable/proc/clear_parachute(image/cables, image/chute)
if(QDELETED(src))
return
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/clear_active_explosives()
for(var/obj/item/explosive/explosive in contents)
if(!explosive.active)
continue
explosive.deconstruct(FALSE)

/atom/movable/proc/handle_airdrop(turf/target, dropship_name)
clear_active_explosives()
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION)
pixel_z = 360
forceMove(target)
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/structure/closet/handle_airdrop(turf/target, dropship_name) // good idea but no
if(!opened)
for(var/atom/movable/content in src)
INVOKE_ASYNC(content, TYPE_PROC_REF(/atom/movable, handle_airdrop), target, dropship_name)
open()
. = ..()

if(!isliving(crosser))
return // don't know how you got here, but you shouldnt be here.
var/mob/living/fallen_mob = crosser
/obj/item/handle_airdrop(turf/target, dropship_name)
..()
if(QDELETED(src))
return
if(!indestructible && w_class < SIZE_MEDIUM) //tiny and small items will be lost, good riddance
deconstruct(FALSE)
return
explosion_throw(200) // give it a bit of a kick

/obj/item/explosive/handle_airdrop(turf/target, dropship_name)
if(active)
deconstruct(FALSE)
return
..()

/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(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)
Stun(3)
// 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)
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."))

/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


/turf/open/space/transit/dropship/alamo
shuttle_tag = DROPSHIP_ALAMO
Expand Down
Loading

0 comments on commit 4f139c8

Please sign in to comment.