diff --git a/code/datums/action.dm b/code/datums/action.dm
index 60a0722f0f..721d67044d 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -403,59 +403,6 @@
return
return ..()
-/datum/action/item_action/initialize_ninja_suit
- name = "Toggle ninja suit"
-
-/datum/action/item_action/ninjasmoke
- name = "Smoke Bomb"
- desc = "Blind your enemies momentarily with a well-placed smoke bomb."
- button_icon_state = "smoke"
- icon_icon = 'icons/mob/actions/actions_spells.dmi'
-
-/datum/action/item_action/ninjaboost
- check_flags = NONE
- name = "Adrenaline Boost"
- desc = "Inject a secret chemical that will counteract all movement-impairing effect."
- button_icon_state = "repulse"
- icon_icon = 'icons/mob/actions/actions_spells.dmi'
-
-/datum/action/item_action/ninjapulse
- name = "EM Burst (25E)"
- desc = "Disable any nearby technology with an electro-magnetic pulse."
- button_icon_state = "emp"
- icon_icon = 'icons/mob/actions/actions_spells.dmi'
-
-/datum/action/item_action/ninjastar
- name = "Create Throwing Stars (1E)"
- desc = "Creates some throwing stars"
- button_icon_state = "throwingstar"
- icon_icon = 'icons/obj/items_and_weapons.dmi'
-
-/datum/action/item_action/ninjanet
- name = "Energy Net (20E)"
- desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
- button_icon_state = "energynet"
- icon_icon = 'icons/effects/effects.dmi'
-
-/datum/action/item_action/ninja_sword_recall
- name = "Recall Energy Katana (Variable Cost)"
- desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance."
- button_icon_state = "energy_katana"
- icon_icon = 'icons/obj/items_and_weapons.dmi'
-
-/datum/action/item_action/ninja_stealth
- name = "Toggle Stealth"
- desc = "Toggles stealth mode on and off."
- button_icon_state = "ninja_cloak"
- icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
-
-/datum/action/item_action/toggle_glove
- name = "Toggle interaction"
- desc = "Switch between normal interaction and drain mode."
- button_icon_state = "s-ninjan"
- icon_icon = 'icons/obj/clothing/gloves.dmi'
-
-
/datum/action/item_action/organ_action
check_flags = AB_CHECK_CONSCIOUS
diff --git a/code/datums/actions/flightsuit.dm b/code/datums/actions/flightsuit.dm
new file mode 100644
index 0000000000..3e78fa5332
--- /dev/null
+++ b/code/datums/actions/flightsuit.dm
@@ -0,0 +1,119 @@
+
+
+/datum/action/item_action/flightsuit
+ icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
+
+/datum/action/item_action/flightsuit/toggle_boots
+ name = "Toggle Boots"
+ button_icon_state = "flightsuit_shoes"
+ background_icon_state = "bg_tech"
+
+/datum/action/item_action/flightsuit/toggle_boots/Trigger()
+ var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target
+ if(istype(FS))
+ FS.deployedshoes? FS.retract_flightshoes() : FS.extend_flightshoes()
+ return ..()
+
+/datum/action/item_action/flightsuit/toggle_helmet
+ name = "Toggle Helmet"
+ button_icon_state = "flightsuit_helmet"
+ background_icon_state = "bg_tech"
+
+/datum/action/item_action/flightsuit/toggle_helmet/Trigger()
+ var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target
+ if(istype(FS))
+ FS.ToggleHelmet()
+ return ..()
+
+/datum/action/item_action/flightsuit/toggle_flightpack
+ name = "Toggle Flightpack"
+ button_icon_state = "flightsuit_pack"
+ background_icon_state = "bg_tech"
+
+/datum/action/item_action/flightsuit/toggle_flightpack/Trigger()
+ var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target
+ if(istype(FS))
+ FS.deployedpack? FS.retract_flightpack() : FS.extend_flightpack()
+ return ..()
+
+/datum/action/item_action/flightsuit/lock_suit
+ name = "Lock Suit"
+ button_icon_state = "flightsuit_lock"
+ background_icon_state = "bg_tech"
+
+/datum/action/item_action/flightsuit/lock_suit/Trigger()
+ var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target
+ if(istype(FS))
+ FS.locked? FS.unlock_suit(owner) : FS.lock_suit(owner)
+ return ..()
+
+/datum/action/item_action/flightpack
+ icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
+
+/datum/action/item_action/flightpack/toggle_flight
+ name = "Toggle Flight"
+ button_icon_state = "flightpack_fly"
+ background_icon_state = "bg_tech_blue"
+
+/datum/action/item_action/flightpack/toggle_flight/Trigger()
+ var/obj/item/device/flightpack/F = target
+ if(istype(F))
+ F.flight? F.disable_flight() : F.enable_flight()
+ return ..()
+
+/datum/action/item_action/flightpack/engage_boosters
+ name = "Toggle Boosters"
+ button_icon_state = "flightpack_boost"
+ background_icon_state = "bg_tech_blue"
+
+/datum/action/item_action/flightpack/engage_boosters/Trigger()
+ var/obj/item/device/flightpack/F = target
+ if(istype(F))
+ F.boost? F.deactivate_booster() : F.activate_booster()
+ return ..()
+
+/datum/action/item_action/flightpack/toggle_stabilizers
+ name = "Toggle Stabilizers"
+ button_icon_state = "flightpack_stabilizer"
+ background_icon_state = "bg_tech_blue"
+
+/datum/action/item_action/flightpack/toggle_stabilizers/Trigger()
+ var/obj/item/device/flightpack/F = target
+ if(istype(F))
+ F.stabilizer? F.disable_stabilizers() : F.enable_stabilizers()
+ return ..()
+
+/datum/action/item_action/flightpack/change_power
+ name = "Flight Power Setting"
+ button_icon_state = "flightpack_power"
+ background_icon_state = "bg_tech_blue"
+
+/datum/action/item_action/flightpack/change_power/Trigger()
+ var/obj/item/device/flightpack/F = target
+ if(istype(F))
+ F.cycle_power()
+ return ..()
+
+/datum/action/item_action/flightpack/toggle_airbrake
+ name = "Toggle Airbrake"
+ button_icon_state = "flightpack_airbrake"
+ background_icon_state = "bg_tech_blue"
+
+/datum/action/item_action/flightpack/toggle_airbrake/Trigger()
+ var/obj/item/device/flightpack/F = target
+ if(istype(F))
+ F.brake? F.disable_airbrake() : F.enable_airbrake()
+ return ..()
+
+/datum/action/item_action/flightpack/zoom
+ name = "Helmet Smart Zoom"
+ icon_icon = 'icons/mob/actions.dmi'
+ background_icon_state = "bg_tech_blue"
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
+ button_icon_state = "sniper_zoom"
+
+/datum/action/item_action/flightpack/zoom/Trigger()
+ var/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/FH = target
+ if(istype(FH))
+ FH.toggle_zoom(owner)
+ return ..()
diff --git a/code/datums/actions/ninja.dm b/code/datums/actions/ninja.dm
new file mode 100644
index 0000000000..830dad77e8
--- /dev/null
+++ b/code/datums/actions/ninja.dm
@@ -0,0 +1,51 @@
+/datum/action/item_action/initialize_ninja_suit
+ name = "Toggle ninja suit"
+
+/datum/action/item_action/ninjasmoke
+ name = "Smoke Bomb"
+ desc = "Blind your enemies momentarily with a well-placed smoke bomb."
+ button_icon_state = "smoke"
+ icon_icon = 'icons/mob/actions/actions_spells.dmi'
+
+/datum/action/item_action/ninjaboost
+ check_flags = NONE
+ name = "Adrenaline Boost"
+ desc = "Inject a secret chemical that will counteract all movement-impairing effect."
+ button_icon_state = "repulse"
+ icon_icon = 'icons/mob/actions/actions_spells.dmi'
+
+/datum/action/item_action/ninjapulse
+ name = "EM Burst (25E)"
+ desc = "Disable any nearby technology with an electro-magnetic pulse."
+ button_icon_state = "emp"
+ icon_icon = 'icons/mob/actions/actions_spells.dmi'
+
+/datum/action/item_action/ninjastar
+ name = "Create Throwing Stars (1E)"
+ desc = "Creates some throwing stars"
+ button_icon_state = "throwingstar"
+ icon_icon = 'icons/obj/items_and_weapons.dmi'
+
+/datum/action/item_action/ninjanet
+ name = "Energy Net (20E)"
+ desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds."
+ button_icon_state = "energynet"
+ icon_icon = 'icons/effects/effects.dmi'
+
+/datum/action/item_action/ninja_sword_recall
+ name = "Recall Energy Katana (Variable Cost)"
+ desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance."
+ button_icon_state = "energy_katana"
+ icon_icon = 'icons/obj/items_and_weapons.dmi'
+
+/datum/action/item_action/ninja_stealth
+ name = "Toggle Stealth"
+ desc = "Toggles stealth mode on and off."
+ button_icon_state = "ninja_cloak"
+ icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
+
+/datum/action/item_action/toggle_glove
+ name = "Toggle interaction"
+ desc = "Switch between normal interaction and drain mode."
+ button_icon_state = "s-ninjan"
+ icon_icon = 'icons/obj/clothing/gloves.dmi'
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 053ff34589..f2f04ea00c 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -460,14 +460,14 @@ GLOBAL_LIST_EMPTY(teleportlocs)
T = get_turf(src)
var/area/A = get_area(T)
if(isspaceturf(T)) // Turf never has gravity
- return 0
+ return FALSE
else if(A && A.has_gravity) // Areas which always has gravity
- return 1
+ return TRUE
else
// There's a gravity generator on our z level
if(T && GLOB.gravity_generators["[T.z]"] && length(GLOB.gravity_generators["[T.z]"]))
- return 1
- return 0
+ return TRUE
+ return FALSE
/area/proc/setup(a_name)
name = a_name
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index a880a44fa6..a43b88efe5 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -115,8 +115,8 @@
. = 0
//Called after a successful Move(). By this point, we've already moved
-/atom/movable/proc/Moved(atom/OldLoc, Dir)
- SendSignal(COMSIG_MOVABLE_MOVED, OldLoc, Dir)
+/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
+ SendSignal(COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
if (!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
newtonian_move(Dir)
@@ -219,7 +219,7 @@
if(A)
if(throwing)
throwing.hit_atom(A)
- . = 1
+ . = TRUE
if(!A || QDELETED(A))
return
A.CollidedWith(src)
@@ -260,8 +260,7 @@
if(AM == src)
continue
AM.Crossed(src, oldloc)
-
- Moved(oldloc, 0)
+ Moved(oldloc, NONE, TRUE)
. = TRUE
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
@@ -277,9 +276,9 @@
/mob/living/forceMove(atom/destination)
stop_pulling()
if(buckled)
- buckled.unbuckle_mob(src,force=1)
+ buckled.unbuckle_mob(src, force = TRUE)
if(has_buckled_mobs())
- unbuckle_all_mobs(force=1)
+ unbuckle_all_mobs(force = TRUE)
. = ..()
if(.)
if(client)
@@ -534,6 +533,7 @@
acted_explosions += ex_id
return TRUE
+//TODO: Better floating
/atom/movable/proc/float(on)
if(throwing)
return
diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm
index 99b9461689..983c30da75 100644
--- a/code/game/objects/effects/effect_system/effects_other.dm
+++ b/code/game/objects/effects/effect_system/effects_other.dm
@@ -8,8 +8,13 @@
/datum/effect_system/trail_follow
var/turf/oldposition
- var/processing = TRUE
- var/on = TRUE
+ var/active = FALSE
+ var/allow_overlap = FALSE
+ var/auto_process = TRUE
+ var/qdel_in_time = 10
+ var/fadetype = "ion_fade"
+ var/fade = TRUE
+ var/nograv_required = FALSE
/datum/effect_system/trail_follow/set_up(atom/atom)
attach(atom)
@@ -17,37 +22,49 @@
/datum/effect_system/trail_follow/Destroy()
oldposition = null
+ stop()
return ..()
/datum/effect_system/trail_follow/proc/stop()
- processing = FALSE
- on = FALSE
oldposition = null
+ STOP_PROCESSING(SSfastprocess, src)
+ active = FALSE
+ return TRUE
+
+/datum/effect_system/trail_follow/start()
+ oldposition = get_turf(holder)
+ if(!check_conditions())
+ return FALSE
+ if(auto_process)
+ START_PROCESSING(SSfastprocess, src)
+ active = TRUE
+ return TRUE
+
+/datum/effect_system/trail_follow/process()
+ generate_effect()
+
+/datum/effect_system/trail_follow/generate_effect()
+ if(!check_conditions())
+ return stop()
+ if(oldposition && !(oldposition == get_turf(holder)))
+ if(!oldposition.has_gravity() || !nograv_required)
+ var/obj/effect/E = new effect_type(oldposition)
+ set_dir(E)
+ if(fade)
+ flick(fadetype, E)
+ E.icon_state = ""
+ if(qdel_in_time)
+ QDEL_IN(E, qdel_in_time)
+ oldposition = get_turf(holder)
+
+/datum/effect_system/trail_follow/proc/check_conditions()
+ if(!get_turf(holder))
+ return FALSE
+ return TRUE
/datum/effect_system/trail_follow/steam
effect_type = /obj/effect/particle_effect/steam
-/datum/effect_system/trail_follow/steam/start()
- if(!on)
- on = TRUE
- processing = TRUE
- if(!oldposition)
- oldposition = get_turf(holder)
- if(processing)
- processing = FALSE
- if(number < 3)
- var/obj/effect/particle_effect/steam/I = new /obj/effect/particle_effect/steam(oldposition)
- number++
- I.setDir(holder.dir)
- oldposition = get_turf(holder)
- spawn(10)
- qdel(I)
- number--
- spawn(2)
- if(on)
- processing = TRUE
- start()
-
/obj/effect/particle_effect/ion_trails
name = "ion trails"
icon_state = "ion_trails"
@@ -58,47 +75,23 @@
/datum/effect_system/trail_follow/ion
effect_type = /obj/effect/particle_effect/ion_trails
- var/fadetype = "ion_fade"
- var/fade = 1
- var/nograv_required = 1
+ nograv_required = TRUE
+ qdel_in_time = 20
-/datum/effect_system/trail_follow/ion/start() //Whoever is responsible for this abomination of code should become an hero
- if(!on)
- on = TRUE
- processing = TRUE
- if(!oldposition)
- oldposition = get_turf(holder)
- if(processing)
- processing = FALSE
- var/turf/T = get_turf(holder)
- if(T != oldposition)
- if(!T.has_gravity() || !nograv_required)
- var/obj/effect/particle_effect/ion_trails/I = new effect_type(oldposition)
- set_dir(I)
- if(fade)
- flick(fadetype, I)
- I.icon_state = ""
- spawn(20)
- qdel(I)
- oldposition = T
- spawn(2)
- if(on)
- processing = TRUE
- start()
-
-/datum/effect_system/trail_follow/ion/proc/set_dir(obj/effect/particle_effect/ion_trails/I)
+/datum/effect_system/trail_follow/proc/set_dir(obj/effect/particle_effect/ion_trails/I)
I.setDir(holder.dir)
/datum/effect_system/trail_follow/ion/flight
effect_type = /obj/effect/particle_effect/ion_trails/flight
fadetype = "ion_fade_flight"
- nograv_required = 0
+ nograv_required = FALSE
+ auto_process = FALSE
/datum/effect_system/trail_follow/ion/flight/set_dir(obj/effect/particle_effect/ion_trails/I)
if(istype(holder, /obj/item/device/flightpack))
var/obj/item/device/flightpack/F = holder
- I.setDir(F.suit.user.dir)
-
+ if(istype(F.wearer))
+ I.setDir(F.wearer.dir)
//Reagent-based explosion effect
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index fb5a4344f0..e95a81822c 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -189,7 +189,7 @@
/obj/proc/check_uplink_validity()
return 1
-/obj/proc/on_mob_move(dir, mob, oldLoc)
+/obj/proc/on_mob_move(dir, mob, oldLoc, forced)
return
/obj/proc/on_mob_turn(dir, mob)
diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm
index d6094d1c1f..30e959c7e2 100644
--- a/code/modules/clothing/spacesuits/flightsuit.dm
+++ b/code/modules/clothing/spacesuits/flightsuit.dm
@@ -1,4 +1,9 @@
+#define FLIGHTPACK_SPRITE_ON_APPEND "_on"
+#define FLIGHTPACK_SPRITE_BOOST_APPEND "_boost"
+#define FLIGHTPACK_SPRITE_OFF_APPEND "_off"
+#define FLIGHTPACK_SPRITE_BASE "flightpack"
+
//So how this is planned to work is it is an item that allows you to fly with some interesting movement mechanics.
//You will still move instantly like usual, but when you move in a direction you gain "momentum" towards that direction
//Momentum will have a maximum value that it will be capped to, and will go down over time
@@ -11,21 +16,20 @@
/obj/item/device/flightpack
name = "flight pack"
desc = "An advanced back-worn system that has dual ion engines powerful enough to grant a humanoid flight. Contains an internal self-recharging high-current capacitor for short, powerful boosts."
- icon_state = "flightpack_off"
- item_state = "flightpack_off"
- var/icon_state_active = "flightpack_on"
- var/item_state_active = "flightpack_on"
- var/icon_state_boost = "flightpack_boost"
- var/item_state_boost = "flightpack_boost"
+ icon_state = FLIGHTPACK_SPRITE_BASE
+ item_state = FLIGHTPACK_SPRITE_BASE
actions_types = list(/datum/action/item_action/flightpack/toggle_flight, /datum/action/item_action/flightpack/engage_boosters, /datum/action/item_action/flightpack/toggle_stabilizers, /datum/action/item_action/flightpack/change_power, /datum/action/item_action/flightpack/toggle_airbrake)
+<<<<<<< HEAD
armor = list(melee = 0, bullet = 0, laser = 0, energy = 10, bomb = 30, bio = 100, rad = 10, fire = 50, acid = 35)
+=======
+ armor = list(melee = 20, bullet = 20, laser = 20, energy = 10, bomb = 30, bio = 100, rad = 75, fire = 100, acid = 75)
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
resistance_flags = FIRE_PROOF
var/processing_mode = FLIGHTSUIT_PROCESSING_FULL
-
var/obj/item/clothing/suit/space/hardsuit/flightsuit/suit = null
var/mob/living/carbon/human/wearer = null
var/slowdown_ground = 1
@@ -73,17 +77,17 @@
var/resync = FALSE //Used to resync the flight-suit every 30 seconds or so.
var/disabled = FALSE //Whether it is disabled from crashes/emps/whatever
- var/crash_disable_message = FALSE //To not spam the user with messages
var/emp_disable_message = FALSE
//This is probably too much code just for EMP damage.
var/emp_damage = 0 //One hit should make it hard to control, continuous hits will cripple it and then simply shut it off/make it crash. Direct hits count more.
- var/emp_strong_damage = 1.5
- var/emp_weak_damage = 1
+ var/emp_strong_damage = 2
+ var/emp_weak_damage = 1.1
var/emp_heal_amount = 0.06 //How much emp damage to heal per process.
var/emp_disable_threshold = 3 //3 weak ion, 2 strong ion hits.
var/emp_disabled = FALSE
+<<<<<<< HEAD
var/crash_damage = 10 //Same thing, but for crashes. This is in addition to possible amounts of brute damage to the wearer.
var/crash_damage_low = 1
var/crash_damage_high = 2.5
@@ -92,6 +96,8 @@
var/crash_disabled = FALSE
var/crash_dampening = 0
+=======
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
var/requires_suit = TRUE
var/datum/effect_system/trail_follow/ion/flight/ion_trail
@@ -106,24 +112,31 @@
var/crashing = FALSE //Are we currently getting wrecked?
+<<<<<<< HEAD
var/s_delay = 50 // cell replacement delay
+=======
+ var/atom/movable/cached_pull //recipe for disaster again.
+ var/afterForceMove = FALSE
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
/obj/item/device/flightpack/proc/changeWearer(mob/changeto)
if(wearer)
LAZYREMOVE(wearer.user_movement_hooks, src)
wearer = null
+ cached_pull = null
if(istype(changeto))
wearer = changeto
LAZYADD(wearer.user_movement_hooks, src)
+ cached_pull = changeto.pulling
-//Start/Stop processing the item to use momentum and flight mechanics.
/obj/item/device/flightpack/Initialize()
ion_trail = new
ion_trail.set_up(src)
START_PROCESSING(SSflightpacks, src)
update_parts()
sync_processing(SSflightpacks)
+ update_icon()
..()
/obj/item/device/flightpack/full/Initialize()
@@ -163,30 +176,22 @@
boost_drain = initial(boost_drain)
powersetting_high = initial(powersetting_high)
emp_disable_threshold = initial(emp_disable_threshold)
- crash_disable_threshold = initial(crash_disable_threshold)
stabilizer_decay_amount = initial(stabilizer_decay_amount)
airbrake_decay_amount = initial(airbrake_decay_amount)
- var/manip = 0 //Efficiency
- var/scan = 0 //Damage avoidance/other
- var/cap = 0 //Charging
- var/laser = 0 //Power
- var/bin = 0 //Stability
assembled = FALSE //Ready?
if(part_manip && part_scan && part_cap && part_laser && part_bin)
- manip = part_manip.rating
- scan = part_scan.rating
- cap = part_cap.rating
- laser = part_laser.rating
- bin = part_bin.rating
+ var/manip = part_manip.rating
+ var/scan = part_scan.rating
+ var/cap = part_cap.rating
+ var/laser = part_laser.rating
+ var/bin = part_bin.rating
assembled = TRUE
boost_chargerate *= cap
boost_drain -= manip
powersetting_high = Clamp(laser, 0, 3)
emp_disable_threshold = bin*1.25
- crash_disable_threshold = bin*2
stabilizer_decay_amount = scan*3.5
airbrake_decay_amount = manip*8
- crash_dampening = bin
/obj/item/device/flightpack/Destroy()
if(suit)
@@ -207,34 +212,7 @@
if(emp_damage <= (emp_disable_threshold * 1.5))
emp_damage += damage
usermessage("WARNING: Class [severity] EMP detected! Circuit damage at [(emp_damage/emp_disable_threshold)*100]%!", "boldwarning")
-
-//action BUTTON CODE
-/obj/item/device/flightpack/ui_action_click(owner, action)
- if(!suit && requires_suit)
- usermessage("The flightpack will not work without being attached to a suit first!", "boldwarning")
- return FALSE
- if(istype(action, /datum/action/item_action/flightpack/toggle_flight))
- if(!flight)
- enable_flight()
- else
- disable_flight()
- if(istype(action, /datum/action/item_action/flightpack/engage_boosters))
- if(!boost)
- activate_booster()
- else
- deactivate_booster()
- if(istype(action, /datum/action/item_action/flightpack/toggle_stabilizers))
- if(!stabilizer)
- enable_stabilizers()
- else
- disable_stabilizers()
- if(istype(action, /datum/action/item_action/flightpack/change_power))
- cycle_power()
- if(istype(action, /datum/action/item_action/flightpack/toggle_airbrake))
- if(!brake)
- enable_airbrake()
- else
- disable_airbrake()
+ return ..()
//Proc to change amount of momentum the wearer has, or dampen all momentum by a certain amount.
/obj/item/device/flightpack/proc/adjust_momentum(amountx, amounty, reduce_amount_total = 0)
@@ -270,10 +248,11 @@
adjust_momentum(momentum_increment, 0)
if(WEST)
adjust_momentum(-momentum_increment, 0)
+ return ..()
//The wearer has momentum left. Move them and take some away, while negating the momentum that moving the wearer would gain. Or force the wearer to lose control if they are incapacitated.
/obj/item/device/flightpack/proc/momentum_drift()
- if(!flight || !wearer)
+ if(!flight || !wearer || (momentum_speed == 0))
return FALSE
else if(!wearer.canmove)
losecontrol()
@@ -281,14 +260,12 @@
var/drift_dir_y = 0
if(momentum_x > 0)
drift_dir_x = EAST
- if(momentum_x < 0)
+ else if(momentum_x < 0)
drift_dir_x = WEST
if(momentum_y > 0)
drift_dir_y = NORTH
- if(momentum_y < 0)
+ else if(momentum_y < 0)
drift_dir_y = SOUTH
- if(momentum_speed == 0)
- return FALSE
momentum_decay()
for(var/i in 1 to momentum_speed)
if(momentum_speed_x >= i)
@@ -296,58 +273,59 @@
if(momentum_speed_y >= i)
step(wearer, drift_dir_y)
sleep(1)
+ if(prob(emp_damage * 15))
+ step(wearer, pick(GLOB.alldirs))
+
+/obj/item/device/flightpack/on_mob_move(dir, mob/mob, turf/oldLoc, forced)
+ if(forced)
+ if(cached_pull && istype(oldLoc) && (get_dist(oldLoc, loc) <= 1) && !oldLoc.density)
+ cached_pull.forceMove(oldLoc)
+ mob.start_pulling(cached_pull, TRUE)
+ afterForceMove = TRUE
+ else
+ cached_pull = null
+ else
+ if(afterForceMove && !oldLoc.density)
+ cached_pull.forceMove(oldLoc)
+ wearer.start_pulling(cached_pull, TRUE)
+ cached_pull = null
+ else
+ cached_pull = wearer.pulling
+ afterForceMove = FALSE
+ if(flight)
+ ion_trail.generate_effect()
+ . = ..()
//Make the wearer lose some momentum.
/obj/item/device/flightpack/proc/momentum_decay()
- if(brake)
- adjust_momentum(0, 0, airbrake_decay_amount)
- if(gravity)
- adjust_momentum(0, 0, gravity_decay_amount)
- if(stabilizer)
- adjust_momentum(0, 0, stabilizer_decay_amount)
- if(pressure)
- adjust_momentum(0, 0, pressure_decay_amount)
- adjust_momentum(0, 0, momentum_passive_loss)
+ var/amt = momentum_passive_loss
+ brake? (amt += airbrake_decay_amount) : 0
+ gravity? (amt += gravity_decay_amount) : 0
+ stabilizer? (amt += stabilizer_decay_amount) : 0
+ pressure? (amt += pressure_decay_amount) : 0
+ adjust_momentum(0, 0, amt)
//Check for gravity, air pressure, and whether this is still linked to a suit. Also, resync the flightpack/flight suit every minute.
/obj/item/device/flightpack/proc/check_conditions()
- if(wearer)
- if(wearer.has_gravity())
- gravity = 1
- else
- gravity = 0
- var/turf/T = get_turf(wearer)
+ if(flight && (!assembled || !wearer || (!suit && requires_suit)))
+ disable_flight(TRUE)
+ var/turf/T = get_turf(src)
+ if(T)
+ gravity = has_gravity()
var/datum/gas_mixture/gas = T.return_air()
- var/envpressure = gas.return_pressure()
- if(envpressure >= pressure_threshold)
- pressure = 1
- else
- pressure = 0
- if(flight)
- if(!assembled)
- disable_flight(1)
- if(!suit)
- disable_flight(1)
- if(!wearer) //Oh god our user fell off!
- disable_flight(1)
+ var/envpressure = gas.return_pressure()
+ pressure = envpressure >= pressure_threshold
if(!pressure && brake)
brake = FALSE
usermessage("Airbrakes deactivated due to lack of pressure!", "boldwarning")
- if(suit)
- if(!suit.deployedshoes)
- if(brake || stabilizer)
- brake = FALSE
- stabilizer = FALSE
- usermessage("Warning: Sensor data is not being recieved from flight shoes. Stabilizers and airbrake modules OFFLINE!", "boldwarning")
+ if(suit && !suit.deployedshoes && (brake || stabilizer))
+ brake = FALSE
+ stabilizer = FALSE
+ usermessage("Warning: Sensor data is not being recieved from flight shoes. Stabilizers and airbrake modules deactivated!", "boldwarning")
-/obj/item/device/flightpack/proc/update_slowdown()
- if(!flight)
- slowdown = slowdown_ground
- else
- slowdown = slowdown_air
/obj/item/device/flightpack/process()
- if((!suit && requires_suit) || (processing_mode == FLIGHTSUIT_PROCESSING_NONE))
+ if(processing_mode == FLIGHTSUIT_PROCESSING_NONE)
return FALSE
check_conditions()
calculate_momentum_speed()
@@ -355,15 +333,10 @@
handle_boost()
handle_damage()
+/obj/item/device/flightpack/proc/update_slowdown()
+ flight? (slowdown = slowdown_air) : (slowdown = slowdown_ground)
+
/obj/item/device/flightpack/proc/handle_damage()
- if(crash_damage)
- crash_damage = Clamp(crash_damage-crash_heal_amount, 0, crash_disable_threshold*10)
- if(crash_damage >= crash_disable_threshold)
- crash_disabled = TRUE
- if(crash_disabled && (crash_damage <= 1))
- crash_disabled = FALSE
- crash_disable_message = FALSE
- usermessage("Gyroscopic sensors recalibrated. Flight systems re-enabled.")
if(emp_damage)
emp_damage = Clamp(emp_damage-emp_heal_amount, 0, emp_disable_threshold * 10)
if(emp_damage >= emp_disable_threshold)
@@ -372,12 +345,8 @@
emp_disabled = FALSE
emp_disable_message = FALSE
usermessage("Electromagnetic deflection system re-activated. Flight systems re-enabled.")
- disabled = crash_disabled + emp_disabled
+ disabled = emp_disabled
if(disabled)
- if(crash_disabled && (!crash_disable_message))
- usermessage("Internal gyroscopes scrambled from excessive impacts.", "boldwarning")
- usermessage("Deactivating to recalibrate flight systems!", "boldwarning")
- crash_disable_message = TRUE
if(emp_disabled && (!emp_disable_message))
usermessage("Electromagnetic deflectors overloaded. Short circuit detected in internal systems!", "boldwarning")
usermessage("Deactivating to prevent fatal power overload!", "boldwarning")
@@ -387,14 +356,15 @@
/obj/item/device/flightpack/update_icon()
if(!flight)
- icon_state = initial(icon_state)
- item_state = initial(item_state)
+ icon_state = "[FLIGHTPACK_SPRITE_BASE][FLIGHTPACK_SPRITE_OFF_APPEND]"
+ item_state = "[FLIGHTPACK_SPRITE_BASE][FLIGHTPACK_SPRITE_OFF_APPEND]"
if(flight)
- icon_state = icon_state_active
- item_state = item_state_active
- if(boost)
- icon_state = icon_state_boost
- item_state = item_state_boost
+ if(!boost)
+ icon_state = "[FLIGHTPACK_SPRITE_BASE][FLIGHTPACK_SPRITE_ON_APPEND]"
+ item_state = "[FLIGHTPACK_SPRITE_BASE][FLIGHTPACK_SPRITE_ON_APPEND]"
+ else
+ icon_state = "[FLIGHTPACK_SPRITE_BASE][FLIGHTPACK_SPRITE_BOOST_APPEND]"
+ item_state = "[FLIGHTPACK_SPRITE_BASE][FLIGHTPACK_SPRITE_BOOST_APPEND]"
if(wearer)
wearer.update_inv_wear_suit()
wearer.update_inv_back()
@@ -408,47 +378,29 @@
boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge)
/obj/item/device/flightpack/proc/cycle_power()
- if(powersetting < powersetting_high)
- powersetting++
- else
- powersetting = 1
+ powersetting < powersetting_high? (powersetting++) : (powersetting = 1)
momentum_gain = powersetting * 10
usermessage("Engine output set to [momentum_gain].")
momentum_drift_coeff = ((momentum_gain)*(drift_tolerance*1.1))/momentum_max
/obj/item/device/flightpack/proc/crash_damage(density, anchored, speed, victim_name)
var/crashmessagesrc = "[wearer] violently crashes into [victim_name], "
- var/userdamage = 10
- userdamage -= stabilizer*3
- userdamage -= part_bin.rating
- userdamage -= part_scan.rating
- userdamage -= part_manip.rating
- userdamage += anchored*2
- userdamage += boost*2
- userdamage += speed*2
- if(userdamage < 0)
- userdamage = 0
- if(userdamage)
+ var/userdamage = 10 - stabilizer * 3 - part_bin.rating - part_scan.rating * part_manip.rating + anchored * 2 + boost * 2 + speed * 2
+ if(userdamage > 0)
crashmessagesrc += "that really must have hurt!"
+ wearer.adjustBruteLoss(userdamage)
else
crashmessagesrc += "but luckily [wearer]'s impact was absorbed by their suit's stabilizers!"
- wearer.adjustBruteLoss(userdamage)
- usermessage("WARNING: Stabilizers taking damage!", "boldwarning")
wearer.visible_message(crashmessagesrc)
- crash_damage = Clamp(crash_damage + crash_damage_high, 0, crash_disable_threshold*1.5)
/obj/item/device/flightpack/proc/userknockback(density, anchored, speed, dir)
- var/angle = dir2angle(dir)
- angle += 180
- if(angle > 360)
- angle -= 360
- dir = angle2dir(angle)
+ dir = turn(dir, 180)
var/turf/target = get_edge_target_turf(get_turf(wearer), dir)
- wearer.throw_at(target, (speed+density+anchored), 2, wearer)
wearer.visible_message("[wearer] is knocked flying by the impact!")
+ wearer.throw_at(target, speed * 2 + density * 2 + anchored * 2, 2, wearer)
-/obj/item/device/flightpack/proc/flight_impact(atom/unmovablevictim, crashdir) //Yes, victim.
- if((unmovablevictim == wearer) || crashing || (processing_mode == FLIGHTSUIT_PROCESSING_NONE))
+/obj/item/device/flightpack/proc/flight_impact(atom/impacted_atom, crashdir) //Yes, victim.
+ if(!flight || (impacted_atom == wearer) || crashing || (processing_mode == FLIGHTSUIT_PROCESSING_NONE))
return FALSE
crashing = TRUE
var/crashpower = 0
@@ -456,82 +408,43 @@
crashpower = momentum_speed_y
else if(crashdir == EAST || crashdir == WEST)
crashpower = momentum_speed_x
- if(!flight)
- crashing = FALSE
- return FALSE
if(boost)
crashpower = 3
if(!crashpower)
crashing = FALSE
return FALSE
- //crashdirs..
var/density = FALSE
var/anchored = TRUE //Just in case...
var/damage = FALSE
- if(ismob(unmovablevictim))
- var/mob/living/L = unmovablevictim
- if(L.throwing || (L.pulledby == wearer))
- crashing = FALSE
- return FALSE
- if(L.buckled)
- wearer.visible_message("[wearer] reflexively flies over [L]!")
- wearer.forceMove(get_turf(L))
- crashing = FALSE
- return FALSE
- wearer.forceMove(get_turf(unmovablevictim))
- crashing = FALSE
- mobknockback(L, crashpower, crashdir)
- damage = FALSE
- density = TRUE
- anchored = FALSE
- else if(istype(unmovablevictim, /obj/structure/grille))
- if(crashpower > 1)
- var/obj/structure/grille/S = unmovablevictim
- crash_grille(S)
- crashing = FALSE
- return FALSE
- else if((istype(unmovablevictim, /obj/machinery/door)) && (!istype(unmovablevictim, /obj/machinery/door/poddoor)))
- var/obj/machinery/door/D = unmovablevictim
- if(!airlock_hit(D))
- crashing = FALSE
- return FALSE
- else if(momentum_speed < 3)
- crashing = FALSE
- return FALSE
- damage = TRUE
- anchored = TRUE
- density = FALSE
- else if(istype(unmovablevictim, /obj/structure/mineral_door))
- var/obj/structure/mineral_door/D = unmovablevictim
- door_hit(D)
- crashing = FALSE
- return FALSE
- else if(isclosedturf(unmovablevictim))
- if(crashpower < 3)
- crashing = FALSE
- return FALSE
- damage = TRUE
- density = TRUE
- anchored = TRUE
- else if(ismovableatom(unmovablevictim))
- var/atom/movable/victim = unmovablevictim
- if(crashpower < 3 || victim.throwing)
- crashing = FALSE
- return FALSE
- density = victim.density
- anchored = victim.anchored
- victimknockback(victim, crashpower, crashdir)
- if(anchored)
+ if(istype(impacted_atom, /obj/structure/grille) && (crashpower > 1))
+ crash_grille(impacted_atom)
+ else if((istype(impacted_atom, /obj/machinery/door)) && (!istype(impacted_atom, /obj/machinery/door/poddoor)))
+ var/obj/machinery/door/D = impacted_atom
+ if(!airlock_pass(D) && (momentum_speed >= 3))
damage = TRUE
+ anchored = TRUE
+ density = FALSE
+ else if(istype(impacted_atom, /obj/structure/mineral_door))
+ door_pass(impacted_atom)
+ else if(isclosedturf(impacted_atom) && (crashpower >= 3))
+ damage = TRUE
+ density = TRUE
+ anchored = TRUE
+ else if(ismovableatom(impacted_atom))
+ var/atom/movable/impacted_AM = impacted_atom
+ if(!impacted_AM.throwing && (crashpower >= 3))
+ density = impacted_AM.density
+ anchored = impacted_AM.anchored
+ damage = anchored
+ atom_impact(impacted_AM, crashpower, crashdir)
if(damage)
- crash_damage(density, anchored, momentum_speed, unmovablevictim.name)
- userknockback(density, anchored, momentum_speed, dir)
+ crash_damage(density, anchored, momentum_speed, impacted_atom.name)
+ userknockback(density, anchored, momentum_speed, crashdir)
losecontrol(knockdown = FALSE, move = FALSE)
crashing = FALSE
-/obj/item/device/flightpack/proc/door_hit(obj/structure/mineral_door/door)
- spawn()
- door.Open()
+/obj/item/device/flightpack/proc/door_pass(obj/structure/mineral_door/door)
+ INVOKE_ASYNC(door, /obj/structure/mineral_door.proc/Open)
var/turf/T = get_turf(door)
wearer.forceMove(T)
wearer.visible_message("[wearer] rolls to their sides and slips past [door]!")
@@ -542,71 +455,40 @@
if(wearer.Move(target.loc))
wearer.visible_message("[wearer] smashes straight past [target]!")
-/obj/item/device/flightpack/proc/airlock_hit(obj/machinery/door/A)
- var/pass = 0
- if(A.density) //Is it closed?
- pass += A.locked
- pass += A.stat //No power, no automatic open
- pass += A.emagged
- pass += A.welded
- if(A.requiresID())
- if((!A.allowed(wearer)) && !A.emergency)
- pass += 1
- else
- return pass
- if(!pass)
- spawn()
- A.open()
+/obj/item/device/flightpack/proc/airlock_pass(obj/machinery/door/A)
+ var/nopass = FALSE
+ if(!A.density)
+ return TRUE
+ nopass = (A.locked || A.stat || A.emagged || A.welded)
+ if(A.requiresID())
+ if((!A.allowed(wearer)) && !A.emergency)
+ nopass = TRUE
+ if(!nopass)
+ INVOKE_ASYNC(A, /obj/machinery/door.proc/open)
wearer.visible_message("[wearer] rolls sideways and slips past [A]")
var/turf/target = get_turf(A)
if(istype(A, /obj/machinery/door/window) && (get_turf(wearer) == get_turf(A)))
target = get_step(A, A.dir)
wearer.forceMove(target)
- return pass
+ return !nopass
-
-/obj/item/device/flightpack/proc/mobknockback(mob/living/victim, power, direction)
- if(!ismob(victim))
- return FALSE
- var/turf/T = get_turf(victim)
- wearer.forceMove(T)
- wearer.visible_message("[wearer] flies over [victim]!")
-
-/obj/item/device/flightpack/proc/victimknockback(atom/movable/victim, power, direction)
+/obj/item/device/flightpack/proc/atom_impact(atom/movable/victim, power, direction)
if(!victim)
return FALSE
- var/knockback = 0
- var/damage = 0
- knockback -= (density * 2)
- knockback += power
- knockback += (part_manip.rating / 2)
- knockback += (part_bin.rating / 2)
- knockback *= 4
- if(victim.anchored)
- knockback = 0
- damage = power*14 //I mean, if you REALLY want to break your skull to break an airlock...
- if(ismob(victim)) //Why the hell didn't it proc the mob one instead?
- mobknockback(victim, power, direction)
- return FALSE
- if(anchored)
- knockback = 0
- victim.visible_message("[victim.name] is sent flying by the impact!")
- var/turf/target = get_turf(victim)
- for(var/i in 1 to knockback)
- target = get_step(target, direction)
- for(var/i in 1 to knockback/3)
- target = get_step(target, pick(GLOB.alldirs))
- if(knockback)
+ if(!victim.anchored)
+ var/knockback = (power + ((part_manip.rating + part_bin.rating) / 2) - (victim.density * 2)) * 2
+ victim.visible_message("[victim.name] is sent flying by the impact!")
+ var/turf/target = get_turf(victim)
+ for(var/i in 1 to knockback)
+ target = get_step(target, direction)
+ for(var/i in 1 to knockback/3)
+ target = get_step(target, pick(GLOB.alldirs))
victim.throw_at(target, knockback, part_manip.rating)
if(isobj(victim))
var/obj/O = victim
- O.take_damage(damage)
+ O.take_damage(power * 14)
/obj/item/device/flightpack/proc/losecontrol(knockdown = FALSE, move = TRUE)
- if(!move)
- momentum_x = 0
- momentum_y = 0
- calculate_momentum_speed()
usermessage("Warning: Control system not responding. Deactivating!", "boldwarning")
wearer.visible_message("[wearer]'s flight suit abruptly shuts off and they lose control!")
if(wearer)
@@ -621,6 +503,7 @@
wearer.Knockdown(80)
momentum_x = 0
momentum_y = 0
+ calculate_momentum_speed()
if(flight)
disable_flight(FALSE)
@@ -638,9 +521,7 @@
wearer.movement_type |= FLYING
wearer.pass_flags |= flight_passflags
usermessage("ENGAGING FLIGHT ENGINES.")
- wearer.floating = TRUE
wearer.visible_message("[wearer]'s flight engines activate as they lift into the air!")
- //I DONT HAVE SOUND EFFECTS YET playsound(
flight = TRUE
update_slowdown()
update_icon()
@@ -650,18 +531,19 @@
if(forced)
losecontrol(knockdown = TRUE)
return TRUE
- if(momentum_speed <= 1)
+ calculate_momentum_speed()
+ if(momentum_speed == 0)
momentum_x = 0
momentum_y = 0
+ calculate_momentum_speed()
usermessage("DISENGAGING FLIGHT ENGINES.")
- wearer.floating = FALSE
wearer.visible_message("[wearer] drops to the ground as their flight engines cut out!")
- //NO SOUND YET playsound(
- ion_trail.stop()
wearer.movement_type &= ~FLYING
wearer.pass_flags &= ~flight_passflags
flight = FALSE
update_slowdown()
+ update_icon()
+ ion_trail.stop()
if(suit && suit.shoes)
suit.shoes.toggle(FALSE)
if(isturf(wearer.loc))
@@ -675,7 +557,6 @@
override_safe = TRUE
addtimer(CALLBACK(src, .proc/enable_safe), 50)
return FALSE
- update_icon()
/obj/item/device/flightpack/proc/enable_safe()
if(override_safe)
@@ -690,8 +571,7 @@
return TRUE
/obj/item/device/flightpack/equipped(mob/user, slot)
- if(ishuman(user))
- changeWearer(user)
+ changeWearer(user)
..()
/obj/item/device/flightpack/proc/calculate_momentum_speed()
@@ -714,14 +594,12 @@
momentum_speed = max(momentum_speed_x, momentum_speed_y)
/obj/item/device/flightpack/item_action_slot_check(slot)
- if(slot == slot_back)
- return TRUE
+ return slot == slot_back
/obj/item/device/flightpack/proc/enable_stabilizers()
- if(requires_suit)
- if(suit && !suit.deployedshoes)
- usermessage("Stabilizers requires flight shoes to be attached and deployed!", "boldwarning")
- return FALSE
+ if(requires_suit && suit && !suit.deployedshoes)
+ usermessage("Stabilizers requires flight shoes to be attached and deployed!", "boldwarning")
+ return FALSE
usermessage("Activating automatic stabilization controller and enabling maneuvering assistance.")
stabilizer = TRUE
return TRUE
@@ -887,8 +765,7 @@
src.flags_1 &= ~NOSLIP_1
/obj/item/clothing/shoes/flightshoes/item_action_slot_check(slot)
- if(slot == slot_shoes)
- return TRUE
+ return slot == slot_shoes
/obj/item/clothing/shoes/flightshoes/proc/delink_suit()
if(suit)
@@ -916,14 +793,22 @@
icon_state = "flightsuit"
item_state = "flightsuit"
strip_delay = 30
- var/locked_strip_delay = 80
w_class = WEIGHT_CLASS_BULKY
+ resistance_flags = FIRE_PROOF | ACID_PROOF
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/flightsuit
+ jetpack = null
+ allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals, /obj/item/gun, /obj/item/reagent_containers/spray/pepper, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs)
+ actions_types = list(/datum/action/item_action/flightsuit/toggle_helmet, /datum/action/item_action/flightsuit/toggle_boots, /datum/action/item_action/flightsuit/toggle_flightpack, /datum/action/item_action/flightsuit/lock_suit)
+ armor = list(melee = 20, bullet = 20, laser = 20, energy = 10, bomb = 30, bio = 100, rad = 75, fire = 100, acid = 100)
+ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
+ var/locked_strip_delay = 80
var/obj/item/device/flightpack/pack = null
var/obj/item/clothing/shoes/flightshoes/shoes = null
var/mob/living/carbon/human/user = null
var/deployedpack = FALSE
var/deployedshoes = FALSE
var/locked = FALSE
+<<<<<<< HEAD
resistance_flags = FIRE_PROOF
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/flightsuit
jetpack = null
@@ -939,13 +824,24 @@
/obj/item/clothing/suit/space/hardsuit/flightsuit/get_cell()
return cell
+=======
+ var/flightpack
+ var/flight = FALSE
+ var/maint_panel = FALSE
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
/obj/item/clothing/suit/space/hardsuit/flightsuit/full/Initialize()
- . = ..()
makepack()
makeshoes()
resync()
+<<<<<<< HEAD
get_cell()
+=======
+ return ..()
+
+/obj/item/clothing/suit/space/hardsuit/flightsuit/ui_action_click()
+ return //Handled in action datums.
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
/obj/item/clothing/suit/space/hardsuit/flightsuit/proc/usermessage(message, span = "boldnotice")
var/mob/targ = user
@@ -966,7 +862,7 @@
dropped()
QDEL_NULL(pack)
QDEL_NULL(shoes)
- . = ..()
+ return ..()
/obj/item/clothing/suit/space/hardsuit/flightsuit/proc/resync()
if(pack)
@@ -992,25 +888,6 @@
return
..()
-/obj/item/clothing/suit/space/hardsuit/flightsuit/ui_action_click(owner, action)
- if(istype(action, /datum/action/item_action/flightsuit/lock_suit))
- if(!locked)
- lock_suit(owner)
- else
- unlock_suit(owner)
- if(istype(action, /datum/action/item_action/flightsuit/toggle_flightpack))
- if(!deployedpack)
- extend_flightpack()
- else
- retract_flightpack()
- if(istype(action, /datum/action/item_action/flightsuit/toggle_boots))
- if(!deployedshoes)
- extend_flightshoes()
- else
- retract_flightshoes()
- if(istype(action, /datum/action/item_action/flightsuit/toggle_helmet))
- ToggleHelmet()
-
/obj/item/clothing/suit/space/hardsuit/flightsuit/dropped()
if(deployedpack)
retract_flightpack(TRUE)
@@ -1093,7 +970,7 @@
user.transferItemToLoc(pack, src, TRUE)
user.update_inv_wear_suit()
user.visible_message("[user]'s [pack.name] detaches from their back and retracts into their [src]!")
- pack.loc = src
+ pack.forceMove(src)
playsound(src.loc, 'sound/mecha/mechmove03.ogg', 50, 1)
deployedpack = FALSE
@@ -1124,7 +1001,7 @@
user.transferItemToLoc(shoes, src, TRUE)
user.update_inv_wear_suit()
user.visible_message("[user]'s [shoes.name] retracts back into their [name]!")
- shoes.loc = src
+ shoes.forceMove(src)
deployedshoes = FALSE
/obj/item/clothing/suit/space/hardsuit/flightsuit/proc/makepack()
@@ -1152,7 +1029,7 @@
/obj/item/clothing/suit/space/hardsuit/flightsuit/proc/detach_pack()
pack.delink_suit()
- pack.loc = get_turf(src)
+ pack.forceMove(get_turf(src))
pack = null
usermessage("You detach the flightpack.")
@@ -1164,7 +1041,7 @@
/obj/item/clothing/suit/space/hardsuit/flightsuit/proc/detach_shoes()
shoes.delink_suit()
- shoes.loc = get_turf(src)
+ shoes.forceMove(get_turf(src))
shoes = null
usermessage("You detach the flight shoes.")
@@ -1277,11 +1154,6 @@
if(zoom)
toggle_zoom(wearer, TRUE)
-/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/ui_action_click(owner, action)
- if(istype(action, /datum/action/item_action/flightpack/zoom))
- toggle_zoom(owner)
- . = ..()
-
/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/proc/toggle_zoom(mob/living/user, force_off = FALSE)
if(zoom || force_off)
user.client.change_view(world.view)
@@ -1293,63 +1165,3 @@
to_chat(user, "Enabling smart zooming image enhancement!")
zoom = TRUE
return TRUE
-
-//ITEM actionS------------------------------------------------------------------------------------------------------------------------------------------------------
-//TODO: TOGGLED BUTTON SPRITES
-/datum/action/item_action/flightsuit
- icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
-
-/datum/action/item_action/flightsuit/toggle_boots
- name = "Toggle Boots"
- button_icon_state = "flightsuit_shoes"
- background_icon_state = "bg_tech"
-
-/datum/action/item_action/flightsuit/toggle_helmet
- name = "Toggle Helmet"
- button_icon_state = "flightsuit_helmet"
- background_icon_state = "bg_tech"
-
-/datum/action/item_action/flightsuit/toggle_flightpack
- name = "Toggle Flightpack"
- button_icon_state = "flightsuit_pack"
- background_icon_state = "bg_tech"
-
-/datum/action/item_action/flightsuit/lock_suit
- name = "Lock Suit"
- button_icon_state = "flightsuit_lock"
- background_icon_state = "bg_tech"
-
-/datum/action/item_action/flightpack
- icon_icon = 'icons/mob/actions/actions_flightsuit.dmi'
-
-/datum/action/item_action/flightpack/toggle_flight
- name = "Toggle Flight"
- button_icon_state = "flightpack_fly"
- background_icon_state = "bg_tech_blue"
-
-/datum/action/item_action/flightpack/engage_boosters
- name = "Toggle Boosters"
- button_icon_state = "flightpack_boost"
- background_icon_state = "bg_tech_blue"
-
-/datum/action/item_action/flightpack/toggle_stabilizers
- name = "Toggle Stabilizers"
- button_icon_state = "flightpack_stabilizer"
- background_icon_state = "bg_tech_blue"
-
-/datum/action/item_action/flightpack/change_power
- name = "Flight Power Setting"
- button_icon_state = "flightpack_power"
- background_icon_state = "bg_tech_blue"
-
-/datum/action/item_action/flightpack/toggle_airbrake
- name = "Toggle Airbrake"
- button_icon_state = "flightpack_airbrake"
- background_icon_state = "bg_tech_blue"
-
-/datum/action/item_action/flightpack/zoom
- name = "Helmet Smart Zoom"
- icon_icon = 'icons/mob/actions.dmi'
- background_icon_state = "bg_tech_blue"
- icon_icon = 'icons/mob/actions/actions_items.dmi'
- button_icon_state = "sniper_zoom"
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 62cf6a535a..542a3a222c 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -66,9 +66,12 @@
var/obj/item/organ/lungs/mutantlungs = null
var/breathid = "o2"
+<<<<<<< HEAD
//Flight and floating
var/override_float = 0
+=======
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
var/obj/item/organ/brain/mutant_brain = /obj/item/organ/brain
var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes
var/obj/item/organ/ears/mutantears = /obj/item/organ/ears
@@ -77,6 +80,7 @@
var/obj/item/organ/liver/mutantliver
var/obj/item/organ/stomach/mutantstomach
+ var/override_float = FALSE
//Citadel snowflake
var/fixed_mut_color2 = ""
diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm
index dbab6b94eb..c9748f85ac 100644
--- a/code/modules/mob/living/carbon/human/species_types/angel.dm
+++ b/code/modules/mob/living/carbon/human/species_types/angel.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/datum/species/angel
name = "Angel"
id = "angel"
@@ -136,4 +137,144 @@
H.movement_type &= ~FLYING
override_float = 0
H.pass_flags &= ~PASSTABLE
+=======
+/datum/species/angel
+ name = "Angel"
+ id = "angel"
+ default_color = "FFFFFF"
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS)
+ mutant_bodyparts = list("tail_human", "ears", "wings")
+ default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "Angel")
+ use_skintones = 1
+ no_equip = list(slot_back)
+ blacklisted = 1
+ limbs_id = "human"
+ skinned_type = /obj/item/stack/sheet/animalhide/human
+
+ var/datum/action/innate/flight/fly
+
+/datum/species/angel/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
+ ..()
+ if(H.dna && H.dna.species &&((H.dna.features["wings"] != "Angel") && ("wings" in H.dna.species.mutant_bodyparts)))
+ H.dna.features["wings"] = "Angel"
+ H.update_body()
+ if(ishuman(H) && !fly)
+ fly = new
+ fly.Grant(H)
+
+/datum/species/angel/on_species_loss(mob/living/carbon/human/H)
+ if(fly)
+ fly.Remove(H)
+ if(H.movement_type & FLYING)
+ H.movement_type &= ~FLYING
+ ToggleFlight(H,0)
+ if(H.dna && H.dna.species &&((H.dna.features["wings"] != "None") && ("wings" in H.dna.species.mutant_bodyparts)))
+ H.dna.features["wings"] = "None"
+ H.update_body()
+ ..()
+
+/datum/species/angel/spec_life(mob/living/carbon/human/H)
+ HandleFlight(H)
+
+/datum/species/angel/proc/HandleFlight(mob/living/carbon/human/H)
+ if(H.movement_type & FLYING)
+ if(!CanFly(H))
+ ToggleFlight(H,0)
+ return 0
+ return 1
+ else
+ return 0
+
+/datum/species/angel/proc/CanFly(mob/living/carbon/human/H)
+ if(H.stat || H.IsStun() || H.IsKnockdown())
+ return 0
+ if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too
+ to_chat(H, "Your suit blocks your wings from extending!")
+ return 0
+ var/turf/T = get_turf(H)
+ if(!T)
+ return 0
+
+ var/datum/gas_mixture/environment = T.return_air()
+ if(environment && !(environment.return_pressure() > 30))
+ to_chat(H, "The atmosphere is too thin for you to fly!")
+ return 0
+ else
+ return 1
+
+/datum/action/innate/flight
+ name = "Toggle Flight"
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ icon_icon = 'icons/mob/actions/actions_items.dmi'
+ button_icon_state = "flight"
+
+/datum/action/innate/flight/Activate()
+ var/mob/living/carbon/human/H = owner
+ var/datum/species/angel/A = H.dna.species
+ if(A.CanFly(H))
+ if(H.movement_type & FLYING)
+ to_chat(H, "You settle gently back onto the ground...")
+ A.ToggleFlight(H,0)
+ H.update_canmove()
+ else
+ to_chat(H, "You beat your wings and begin to hover gently above the ground...")
+ H.resting = 0
+ A.ToggleFlight(H,1)
+ H.update_canmove()
+
+/datum/species/angel/proc/flyslip(mob/living/carbon/human/H)
+ var/obj/buckled_obj
+ if(H.buckled)
+ buckled_obj = H.buckled
+
+ to_chat(H, "Your wings spazz out and launch you!")
+
+ playsound(H.loc, 'sound/misc/slip.ogg', 50, 1, -3)
+
+ for(var/obj/item/I in H.held_items)
+ H.accident(I)
+
+ var/olddir = H.dir
+
+ H.stop_pulling()
+ if(buckled_obj)
+ buckled_obj.unbuckle_mob(H)
+ step(buckled_obj, olddir)
+ else
+ for(var/i=1, i<5, i++)
+ spawn (i)
+ step(H, olddir)
+ H.spin(1,1)
+ return 1
+
+
+/datum/species/angel/spec_stun(mob/living/carbon/human/H,amount)
+ if(H.movement_type & FLYING)
+ ToggleFlight(H,0)
+ flyslip(H)
+ . = ..()
+
+/datum/species/angel/negates_gravity(mob/living/carbon/human/H)
+ if(H.movement_type & FLYING)
+ return 1
+
+/datum/species/angel/space_move(mob/living/carbon/human/H)
+ if(H.movement_type & FLYING)
+ return 1
+
+/datum/species/angel/proc/ToggleFlight(mob/living/carbon/human/H,flight)
+ if(flight && CanFly(H))
+ stunmod = 2
+ speedmod = -0.35
+ H.movement_type |= FLYING
+ override_float = TRUE
+ H.pass_flags |= PASSTABLE
+ H.OpenWings()
+ else
+ stunmod = 1
+ speedmod = 0
+ H.movement_type &= ~FLYING
+ override_float = FALSE
+ H.pass_flags &= ~PASSTABLE
+>>>>>>> 8d647ff... Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes (#30570)
H.CloseWings()
\ No newline at end of file
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index acbdea29c1..04a10a9ad6 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -5,6 +5,9 @@
if(digitalinvis)
handle_diginvis() //AI becomes unable to see mob
+ if((movement_type & FLYING) && !floating) //TODO: Better floating
+ float(on = TRUE)
+
if (notransform)
return
if(!loc)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index eae437caf6..e79a3b111f 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -105,8 +105,6 @@
//Called when we bump onto a mob
/mob/living/proc/MobCollide(mob/M)
- //Even if we don't push/swap places, we "touched" them, so spread fire
- spreadFire(M)
//Also diseases
for(var/thing in viruses)
@@ -120,7 +118,31 @@
ContactContractDisease(D)
if(now_pushing)
- return 1
+ return TRUE
+
+ //TODO FOR LATER PRS: Make passing tables an automatic thing for flying and passable objects be determined better to prevent huge amounts of flags being set when mobs fly.
+ if((movement_type) ^ (M.movement_type)) //Fly past each other.
+ now_pushing = TRUE
+ var/old = pass_flags & PASSMOB
+ var/old_p = pulling? (pulling.pass_flags & PASSMOB) : NONE
+ var/atom/movable/cached = pulling
+ pass_flags |= PASSMOB
+ var/obj/item/I = cached
+ if(cached && (isliving(cached) || (istype(I) && (I.w_class < WEIGHT_CLASS_BULKY))))
+ var/mob/living/l = cached
+ if(l.mob_size <= mob_size)
+ cached.pass_flags |= PASSMOB
+ Move(get_turf(M))
+ if(!old)
+ pass_flags &= ~PASSMOB
+ if(cached && !old_p)
+ cached.pass_flags &= ~PASSMOB
+ cached = null
+ now_pushing = FALSE
+ return TRUE
+
+ //Even if we don't push/swap places, we "touched" them, so spread fire
+ spreadFire(M)
//Should stop you pushing a restrained person out of the way
if(isliving(M))
@@ -1018,4 +1040,4 @@
/mob/living/proc/add_abilities_to_panel()
for(var/obj/effect/proc_holder/A in abilities)
- statpanel("[A.panel]",A.get_panel_text(),A)
\ No newline at end of file
+ statpanel("[A.panel]",A.get_panel_text(),A)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index a66b45d4a2..e99a4e0ae8 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -192,10 +192,10 @@
return .
-/mob/Moved(oldLoc, dir)
+/mob/Moved(oldLoc, dir, Forced = FALSE)
. = ..()
for(var/obj/O in contents)
- O.on_mob_move(dir, src, oldLoc)
+ O.on_mob_move(dir, src, oldLoc, Forced)
/mob/setDir(newDir)
. = ..()
diff --git a/tgstation.dme b/tgstation.dme
index e93c702505..86bc2ed0c4 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -291,6 +291,8 @@
#include "code\datums\soullink.dm"
#include "code\datums\spawners_menu.dm"
#include "code\datums\verbs.dm"
+#include "code\datums\actions\flightsuit.dm"
+#include "code\datums\actions\ninja.dm"
#include "code\datums\world_topic.dm"
#include "code\datums\antagonists\antag_datum.dm"
#include "code\datums\antagonists\datum_abductor.dm"