From 77d6420db0f6d31c6bad6a47a0a2a0ee57a232c2 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Fri, 13 Oct 2017 17:09:20 -0700 Subject: [PATCH] Flying mobs now clip past non flying mobs, various flightsuit/iontrail/movement tweaks/code improvements/bugfixes --- code/datums/action.dm | 53 -- code/datums/actions/flightsuit.dm | 119 ++++ code/datums/actions/ninja.dm | 51 ++ code/game/area/areas.dm | 8 +- code/game/atoms_movable.dm | 14 +- .../effects/effect_system/effects_other.dm | 105 ++-- code/game/objects/objs.dm | 2 +- .../modules/clothing/spacesuits/flightsuit.dm | 542 ++++++------------ .../mob/living/carbon/human/species.dm | 4 + .../carbon/human/species_types/angel.dm | 141 +++++ code/modules/mob/living/life.dm | 3 + code/modules/mob/living/living.dm | 30 +- code/modules/mob/mob_movement.dm | 4 +- tgstation.dme | 2 + 14 files changed, 586 insertions(+), 492 deletions(-) create mode 100644 code/datums/actions/flightsuit.dm create mode 100644 code/datums/actions/ninja.dm 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"