From 55a61bc38fa0949507f688f6377b0efac1d62705 Mon Sep 17 00:00:00 2001 From: Kashargul <144968721+Kashargul@users.noreply.github.com> Date: Sat, 1 Mar 2025 18:09:35 +0100 Subject: [PATCH] up ports incorp and proximity handling (#17106) * up ports inCorp and proximity handling * anim size * bullets no longer hit shadekin * fix throwing and clicking * use the proc * and add the proc * . * No moving when you can't move * fixes portal runtime * No bonk when throwing at incorporeal entities * MAR - I coded in picking yourself up years ago and someone broke it (by adding a lying check). This unbreaks it. Additionally, picking yourself up was made immediate instead of a 0.5 delay since before hitting the U key was slow and doing it this way was quicker. That's not the case anymore. - Makes attack_hand not happen if the person is incorporeal - Makes you not contract touch spread viruses when you click one someone and don't do an interaction (you will now always do an interaction) - Makes it so you can't mousedrop items while phased. * no more spreading viruses while phased / to phased * F --------- Co-authored-by: C.L. --- code/_onclick/item_attack.dm | 2 + code/datums/diseases/_disease.dm | 4 ++ .../diseases/advance/symptoms/sneeze.dm | 2 +- code/datums/observation/turf_enterexit.dm | 4 +- code/game/area/areas.dm | 4 +- code/game/atoms.dm | 3 +- code/game/atoms_movable.dm | 9 ++++- code/game/machinery/camera/motion.dm | 9 ++++- code/game/machinery/camera/presets.dm | 2 +- code/game/machinery/flasher.dm | 10 ++++- .../objects/effects/map_effects/portal.dm | 2 - code/game/objects/effects/portals.dm | 7 +++- code/game/objects/items.dm | 2 +- .../objects/items/devices/transfer_valve.dm | 14 +++++-- .../game/objects/items/weapons/tanks/tanks.dm | 15 +++++-- code/modules/assembly/holder.dm | 13 +++++-- code/modules/assembly/proximity.dm | 10 +++-- code/modules/clothing/spacesuits/rig/rig.dm | 2 +- code/modules/economy/vending.dm | 3 ++ .../hydroponics/spreading/spreading.dm | 4 +- .../spreading/spreading_response.dm | 12 +++++- .../integrated_electronics/subtypes/input.dm | 34 +++++++++------- code/modules/mob/living/carbon/carbon.dm | 4 +- code/modules/mob/living/carbon/give.dm | 2 +- .../living/carbon/human/human_attackhand.dm | 6 ++- .../mob/living/carbon/human/human_defense.dm | 4 +- .../mob/living/carbon/human/human_powers.dm | 2 +- .../carbon/human/species/shadekin/shadekin.dm | 1 + .../species/shadekin/shadekin_abilities.dm | 39 +++++++++++++++++-- .../station/station_special_abilities_vr.dm | 2 +- code/modules/mob/living/inventory.dm | 2 +- code/modules/mob/living/living_defense.dm | 2 + code/modules/mob/living/living_movement.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- .../mob/living/simple_mob/simple_mob_vr.dm | 6 +++ .../subtypes/animal/passive/cockroach.dm | 2 + .../subtypes/vore/shadekin/ability_procs.dm | 10 ++++- .../subtypes/vore/shadekin/shadekin.dm | 1 + code/modules/mob/mob.dm | 5 +++ code/modules/mob/mob_helpers.dm | 16 ++++++++ code/modules/mob/mob_movement.dm | 24 ++++++++---- code/modules/multiz/movement_vr.dm | 2 + .../power/singularity/containment_field.dm | 15 +++++-- code/modules/power/supermatter/supermatter.dm | 2 +- code/modules/power/tesla/energy_ball.dm | 2 +- code/modules/projectiles/projectile.dm | 3 ++ .../projectiles/targeting/targeting_gun.dm | 4 +- code/modules/tables/interactions.dm | 2 + code/modules/vore/eating/living_vr.dm | 4 +- code/modules/vore/eating/simple_animal_vr.dm | 2 +- code/modules/vore/eating/slipvore_vr.dm | 6 ++- code/modules/vore/eating/stumblevore_vr.dm | 8 +++- code/modules/vore/eating/vertical_nom_vr.dm | 2 +- code/modules/vore/resizing/resize_vr.dm | 4 ++ 54 files changed, 270 insertions(+), 85 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index c55ec430e3d..ba18e153c14 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -96,6 +96,8 @@ avoid code duplication. This includes items that may sometimes act as a standard return 0 if(M == user && user.a_intent != I_HURT) return 0 + if(M.is_incorporeal()) // No attacking phased entities :) + return 0 ///////////////////////// user.lastattacked = M diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 290dc1a4d80..8e99e5c21d7 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -110,6 +110,8 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) /datum/disease/proc/spread(force_spread = 0) if(!affected_mob) return + if(affected_mob.is_incorporeal()) + return if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread) return @@ -128,6 +130,8 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) var/turf/target = affected_mob.loc if(istype(target)) for(var/mob/living/carbon/human/C in oview(spread_range, affected_mob)) + if(C.is_incorporeal()) + continue var/turf/current = get_turf(C) if(current) while(TRUE) diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 571af4c6b19..e1f226049f9 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -108,7 +108,7 @@ Bonus var/mob/living/unlucky = locate() in place - if(unlucky) + if(unlucky && !unlucky.is_incorporeal()) if(unlucky.can_be_drop_pred && mob.can_be_drop_prey && mob.devourable) place = unlucky.vore_selected else if(unlucky.devourable && unlucky.can_be_drop_prey && mob.can_be_drop_pred) diff --git a/code/datums/observation/turf_enterexit.dm b/code/datums/observation/turf_enterexit.dm index 3f591986f07..5a6667cb5c2 100644 --- a/code/datums/observation/turf_enterexit.dm +++ b/code/datums/observation/turf_enterexit.dm @@ -30,8 +30,8 @@ GLOBAL_DATUM_INIT(turf_exited_event, /decl/observ/turf_exited, new) /turf/Entered(var/atom/movable/am, var/atom/old_loc) . = ..() - SEND_SIGNAL(src, COMSIG_OBSERVER_TURF_ENTERED, am, old_loc) + SEND_SIGNAL(src, COMSIG_OBSERVER_TURF_ENTERED, WEAKREF(am), old_loc) /turf/Exited(var/atom/movable/am, var/atom/new_loc) . = ..() - SEND_SIGNAL(src, COMSIG_OBSERVER_TURF_EXITED, am, new_loc) + SEND_SIGNAL(src, COMSIG_OBSERVER_TURF_EXITED, WEAKREF(am), new_loc) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 9a35493bf5f..faebc3545d8 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -445,7 +445,7 @@ var/list/mob/living/forced_ambiance_list = new return // Being buckled to something solid keeps you in place. if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.item_flags & NOSLIP)) return - if(H.incorporeal_move) // VOREstation edit - Phaseshifted beings should not be affected by gravity + if(H.is_incorporeal()) // VOREstation edit - Phaseshifted beings should not be affected by gravity return if(H.species.can_zero_g_move || H.species.can_space_freemove) return @@ -558,7 +558,7 @@ GLOBAL_DATUM(spoiler_obfuscation_image, /image) // RS Port #658 Start /area/proc/check_phase_shift(var/mob/ourmob) - if(!flag_check(AREA_BLOCK_PHASE_SHIFT) || !ourmob.incorporeal_move) + if(!flag_check(AREA_BLOCK_PHASE_SHIFT) || !ourmob.is_incorporeal()) return if(!isliving(ourmob)) return diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 3a88f2854d1..0fbe1e841e3 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -154,7 +154,8 @@ // Used to be for the PROXMOVE flag, but that was terrible, so instead it's just here as a stub for // all the atoms that still have the proc, but get events other ways. -/atom/proc/HasProximity(turf/T, atom/movable/AM, old_loc) +/atom/proc/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER return //Register listeners on turfs in a certain range diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 34e349df0d0..b7833d22915 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -420,9 +420,14 @@ /atom/movable/proc/hit_check(var/speed) if(src.throwing) for(var/atom/A in get_turf(src)) - if(A == src) continue + if(A == src) + continue + if(A.is_incorporeal()) + continue if(isliving(A)) - if(A:lying) continue + var/mob/living/M = A + if(M.lying) + continue src.throw_impact(A,speed) if(isobj(A)) if(!A.density || A.throwpass) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index aebee15e3c5..b3074983924 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -54,7 +54,14 @@ detectTime = -1 return 1 -/obj/machinery/camera/HasProximity(turf/T, atom/movable/AM, old_loc) +/obj/machinery/camera/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + return // Motion cameras outside of an "ai monitored" area will use this to detect stuff. if (!area_motion) if(isliving(AM)) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 6507b0187bc..c6fe8aef25f 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -228,7 +228,7 @@ var/global/list/engineering_networks = list( assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly)) setPowerUsage() START_MACHINE_PROCESSING(src) - sense_proximity(callback = /atom/proc/HasProximity) + sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) update_coverage() /obj/machinery/camera/proc/setPowerUsage() diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 62e59175ae9..8e197f5a782 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -97,7 +97,15 @@ flash() ..(severity) -/obj/machinery/flasher/portable/HasProximity(turf/T, atom/movable/AM, oldloc) +/obj/machinery/flasher/portable/HasProximity(turf/T, datum/weakref/WF, oldloc) + SIGNAL_HANDLER + if(isnull(WF)) + return + + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + return if(disable || !anchored || (last_flash && world.time < last_flash + 150)) return diff --git a/code/game/objects/effects/map_effects/portal.dm b/code/game/objects/effects/map_effects/portal.dm index 339314dc321..935c6c74715 100644 --- a/code/game/objects/effects/map_effects/portal.dm +++ b/code/game/objects/effects/map_effects/portal.dm @@ -71,8 +71,6 @@ when portals are shortly lived, or when portals are made to be obvious with spec // Called when something touches the portal, and usually teleports them to the other side. /obj/effect/map_effect/portal/Crossed(atom/movable/AM) - if(AM.is_incorporeal()) - return ..() if(!AM) return diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 132cfbfd67f..e4682708904 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -11,6 +11,7 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal) var/obj/item/target = null var/creator = null anchored = TRUE + var/event = FALSE /obj/effect/portal/Bumped(mob/M as mob|obj) if(ismob(M) && !(isliving(M))) @@ -22,7 +23,11 @@ GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal) /obj/effect/portal/Crossed(atom/movable/AM as mob|obj) if(AM.is_incorporeal()) - return + if(!event) + return + if(iscarbon(AM)) + var/mob/living/carbon/human/H = AM + H.attack_dephase(null, src) if(ismob(AM) && !(isliving(AM))) return //do not send ghosts, zshadows, ai eyes, etc spawn(0) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 2e9ef20dde9..fc02ad713c8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -366,7 +366,7 @@ /obj/item/throw_impact(atom/hit_atom) ..() - if(isliving(hit_atom)) //Living mobs handle hit sounds differently. + if(isliving(hit_atom) && !hit_atom.is_incorporeal()) //Living mobs handle hit sounds differently. var/volume = get_volume_by_throwforce_and_or_w_class() if (throwforce > 0) if (mob_throw_hit_sound) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index a0fa8fdb361..5d393b949d7 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -56,15 +56,21 @@ return -/obj/item/transfer_valve/HasProximity(turf/T, atom/movable/AM, old_loc) - attached_device?.HasProximity(T, AM, old_loc) +/obj/item/transfer_valve/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + attached_device?.HasProximity(T, WEAKREF(AM), old_loc) /obj/item/transfer_valve/Moved(old_loc, direction, forced) . = ..() if(isturf(old_loc)) - unsense_proximity(callback = /atom/proc/HasProximity, center = old_loc) + unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc) if(isturf(loc)) - sense_proximity(callback = /atom/proc/HasProximity) + sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) /obj/item/transfer_valve/attack_self(mob/user) tgui_interact(user) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 731c007f010..55b0a329c93 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -661,13 +661,20 @@ var/list/global/tank_gauge_cache = list() tank.update_icon() tank.cut_overlay("bomb_assembly") -/obj/item/tankassemblyproxy/HasProximity(turf/T, atom/movable/AM, old_loc) - assembly?.HasProximity(T, AM, old_loc) +/obj/item/tankassemblyproxy/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + return + assembly?.HasProximity(T, WEAKREF(AM), old_loc) /obj/item/tankassemblyproxy/Moved(old_loc, direction, forced) if(isturf(old_loc)) - unsense_proximity(callback = /atom/proc/HasProximity, center = old_loc) + unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc) if(isturf(loc)) - sense_proximity(callback = /atom/proc/HasProximity) + sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) #undef TANK_IDEAL_PRESSURE diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 2066647d73b..9a3e55a93cd 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -66,11 +66,18 @@ /obj/item/assembly_holder/Moved(atom/old_loc, direction, forced = FALSE) . = ..() if(isturf(old_loc)) - unsense_proximity(callback = /atom/proc/HasProximity, center = old_loc) + unsense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity), center = old_loc) if(isturf(loc)) - sense_proximity(callback = /atom/proc/HasProximity) + sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) -/obj/item/assembly_holder/HasProximity(turf/T, atom/movable/AM, old_loc) +/obj/item/assembly_holder/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + return if(a_left) a_left.HasProximity(T, AM, old_loc) if(a_right) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 2be487ed34a..f7476a07d10 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -32,9 +32,13 @@ update_icon() return secured -/obj/item/assembly/prox_sensor/HasProximity(turf/T, atom/movable/AM, old_loc) - if(!istype(AM)) - log_debug("DEBUG: HasProximity called with [AM] on [src] ([usr]).") +/obj/item/assembly/prox_sensor/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") return if (istype(AM, /obj/effect/beam)) return diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 74b86407d4e..ca4d57b2dba 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -576,7 +576,7 @@ var/mob/living/carbon/human/H = user if(istype(H) && (H.back != src && H.belt != src)) fail_msg = span_warning("You must be wearing \the [src] to do this.") - else if(user.incorporeal_move) + else if(user.is_incorporeal()) fail_msg = span_warning("You must be solid to do this.") if(sealing) fail_msg = span_warning("The hardsuit is in the process of adjusting seals and cannot be activated.") diff --git a/code/modules/economy/vending.dm b/code/modules/economy/vending.dm index 33c80a4264c..9d8afd42512 100644 --- a/code/modules/economy/vending.dm +++ b/code/modules/economy/vending.dm @@ -785,6 +785,9 @@ GLOBAL_LIST_EMPTY(vending_products) if(!target) return 0 + if(target.is_incorporeal()) // Don't shoot at things that aren't there. + return 0 + for(var/datum/stored_item/vending_product/R in shuffle(product_records)) throw_item = R.get_product(loc) if(!throw_item) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index aa7d0476dab..c39b27178c9 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -67,7 +67,7 @@ /obj/effect/plant/Destroy() neighbors.Cut() if(seed.get_trait(TRAIT_SPREAD)==2) - unsense_proximity(callback = /atom/proc/HasProximity, center = get_turf(src)) + unsense_proximity(callback = TYPE_PROC_REF(/atom, HasProximity), center = get_turf(src)) SSplants.remove_plant(src) for(var/obj/effect/plant/neighbor in range(1,src)) SSplants.add_plant(neighbor) @@ -105,7 +105,7 @@ name = seed.display_name max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2) if(seed.get_trait(TRAIT_SPREAD)==2) - sense_proximity(callback = /atom/proc/HasProximity) // Grabby + sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) // Grabby max_growth = VINE_GROWTH_STAGES growth_threshold = max_health/VINE_GROWTH_STAGES icon = 'icons/obj/hydroponics_vines.dmi' diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm index 8a56e37e9be..e13f99fe97c 100644 --- a/code/modules/hydroponics/spreading/spreading_response.dm +++ b/code/modules/hydroponics/spreading/spreading_response.dm @@ -1,4 +1,11 @@ -/obj/effect/plant/HasProximity(turf/T, atom/movable/AM, old_loc) +/obj/effect/plant/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + return if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2) return @@ -7,6 +14,9 @@ if(!istype(M)) return + if(M.is_incorporeal()) // Don't buckle phased entities. + return + if(!has_buckled_mobs() && !M.buckled && !M.anchored && (issmall(M) || prob(round(seed.get_trait(TRAIT_POTENCY)/3)))) //wait a tick for the Entered() proc that called HasProximity() to finish (and thus the moving animation), //so we don't appear to teleport from two tiles away when moving into a turf adjacent to vines. diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 019db4a31a3..f80f0f46505 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -270,6 +270,8 @@ for(var/atom/thing in nearby_things) if(thing.type != desired_type) continue + if(thing.is_incorporeal()) + continue valid_things.Add(thing) if(valid_things.len) O.data = WEAKREF(pick(valid_things)) @@ -313,11 +315,15 @@ var/desired_type = A.type if(desired_type) for(var/atom/thing in nearby_things) + if(thing.is_incorporeal()) + continue if(thing.type == desired_type) valid_things.Add(thing) else if(istext(I.data)) var/DT = I.data for(var/atom/thing in nearby_things) + if(thing.is_incorporeal()) + continue if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) ) valid_things.Add(thing) if(valid_things.len) @@ -526,6 +532,7 @@ complexity = 8 inputs = list() outputs = list( + "speaker ref", "speaker" = IC_PINTYPE_STRING, "message" = IC_PINTYPE_STRING ) @@ -551,8 +558,9 @@ // as a translation, when it is not. if(S.speaking && !istype(S.speaking, /datum/language/common)) translated = TRUE - set_pin_data(IC_OUTPUT, 1, M.GetVoice()) - set_pin_data(IC_OUTPUT, 2, msg) + set_pin_data(IC_OUTPUT , 1, WEAKREF(M)) + set_pin_data(IC_OUTPUT, 2, M.GetVoice()) + set_pin_data(IC_OUTPUT, 3, msg) push_data() activate_pin(1) @@ -570,6 +578,7 @@ complexity = 12 inputs = list() outputs = list( + "speaker ref", "speaker" = IC_PINTYPE_STRING, "message" = IC_PINTYPE_STRING ) @@ -596,16 +605,14 @@ /obj/item/integrated_circuit/input/microphone/sign/hear_talk(mob/M, list/message_pieces, verb) var/msg = multilingual_to_message(message_pieces) - var/translated = FALSE + var/translated = TRUE if(M && msg) for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking) - if(!((S.speaking.flags & NONVERBAL) || (S.speaking.flags & SIGNLANG))) - translated = TRUE - msg = stars(msg) - break - set_pin_data(IC_OUTPUT, 1, M.GetVoice()) - set_pin_data(IC_OUTPUT, 2, msg) + if(!((S.speaking.flags & NONVERBAL) || (S.speaking.flags & SIGNLANG))||S.speaking.name == LANGUAGE_ECHOSONG) //Ignore verbal languages + return + set_pin_data(IC_OUTPUT , 1, WEAKREF(M)) + set_pin_data(IC_OUTPUT, 2, M.GetVoice()) + set_pin_data(IC_OUTPUT, 3, msg) push_data() if(!translated) @@ -614,12 +621,11 @@ activate_pin(2) /obj/item/integrated_circuit/input/microphone/sign/hear_signlang(text, verb, datum/language/speaking, mob/M as mob) - var/translated = FALSE + var/translated = TRUE if(M && text) if(speaking) - if(!((speaking.flags & NONVERBAL) || (speaking.flags & SIGNLANG))) - translated = TRUE - text = speaking.scramble(text, my_langs) + if(!((speaking.flags & NONVERBAL) || (speaking.flags & SIGNLANG))||speaking.name == LANGUAGE_ECHOSONG) + return set_pin_data(IC_OUTPUT, 1, M.GetVoice()) set_pin_data(IC_OUTPUT, 2, text) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 86f42db31b4..d9ce4a96f0a 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -302,8 +302,8 @@ M.adjust_fire_stacks(-1) if(M.on_fire) src.IgniteMob() - if(do_after(M, 0.5 SECONDS)) //.5 second delay. Makes it a bit stronger than just typing rest. - M.resting = 0 //Hoist yourself up up off the ground. No para/stunned/weakened removal. + M.resting = 0 //Hoist yourself up up off the ground. No para/stunned/weakened removal. + update_canmove() else if(istype(hugger)) hugger.species.hug(hugger,src) else diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 8392bcf01c9..b76275f8a9a 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -1,4 +1,4 @@ -/mob/living/verb/give(var/mob/living/target in living_mobs(1)) +/mob/living/verb/give(var/mob/living/target in living_mobs_in_view(1)) set category = "IC.Game" set name = "Give" diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 65bec440d28..649167e5ae5 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -35,6 +35,10 @@ /mob/living/carbon/human/attack_hand(mob/living/M as mob) var/datum/gender/TT = gender_datums[M.get_visible_gender()] var/mob/living/carbon/human/H = M + + if(is_incorporeal()) + return + var/has_hands = TRUE if(istype(H)) var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] @@ -53,8 +57,6 @@ if(D.IsSpreadByTouch()) ContractDisease(D) - if(H.lying) - return M.break_cloak() ..() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 5aae096b7e1..ae7e39c6b00 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -390,6 +390,8 @@ emp_act //this proc handles being hit by a thrown atom /mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR) + if(src.is_incorporeal()) + return // if(buckled && buckled == AM) // return // Don't get hit by the thing we're buckled to. @@ -431,7 +433,7 @@ emp_act I.forceMove(vore_selected) return if(in_throw_mode && speed <= THROWFORCE_SPEED_DIVISOR) //empty active hand and we're in throw mode - if(canmove && !restrained()) + if(canmove && !restrained() && !src.is_incorporeal()) if(isturf(O.loc)) if(can_catch(O)) put_in_active_hand(O) diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 3d43b7d8c58..3a50153469c 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -263,7 +263,7 @@ to_chat(src, span_notice("You take a moment to listen in to your environment...")) for(var/mob/living/L in range(client.view, src)) var/turf/T = get_turf(L) - if(!T || L == src || L.stat == DEAD || is_below_sound_pressure(T)) + if(!T || L == src || L.stat == DEAD || is_below_sound_pressure(T) || L.is_incorporeal()) continue heard_something = TRUE var/feedback = list() diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm index d907cb7d5d3..d5be08ec6d8 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin.dm @@ -73,6 +73,7 @@ breath_type = null poison_type = null water_breather = TRUE //They don't quite breathe + var/doing_phase = FALSE // Prevent bugs when spamming phase button vision_flags = SEE_SELF|SEE_MOBS appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_UNDERWEAR diff --git a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm index 1054e4fec76..c64479ce647 100644 --- a/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm +++ b/code/modules/mob/living/carbon/human/species/shadekin/shadekin_abilities.dm @@ -71,6 +71,9 @@ else if(stat) to_chat(src, span_warning("Can't use that ability in your state!")) return FALSE + else if(SK.doing_phase) + to_chat(src, span_warning("You are already trying to phase!")) + return FALSE else if(shadekin_get_energy() < ability_cost && !(ability_flags & AB_PHASE_SHIFTED)) to_chat(src, span_warning("Not enough energy for that ability!")) return FALSE @@ -83,12 +86,14 @@ to_chat(src,span_warning("You can't use that here!")) return FALSE + SK.doing_phase = TRUE // Prevent bugs when spamming phase button //Shifting in if(ability_flags & AB_PHASE_SHIFTED) phase_in(T) //Shifting out else phase_out(T) + SK.doing_phase = FALSE // Prevent bugs when spamming phase button /mob/living/carbon/human/proc/phase_in(var/turf/T) @@ -109,7 +114,7 @@ canmove = FALSE ability_flags &= ~AB_PHASE_SHIFTED ability_flags |= AB_PHASE_SHIFTING - mouse_opacity = 1 + throwpass = FALSE name = get_visible_name() for(var/obj/belly/B as anything in vore_organs) B.escapable = initial(B.escapable) @@ -124,6 +129,8 @@ //Cosmetics mostly var/obj/effect/temp_visual/shadekin/phase_in/phaseanim = new /obj/effect/temp_visual/shadekin/phase_in(src.loc) + phaseanim.pixel_y = (src.size_multiplier - 1) * 16 // Pixel shift for the animation placement + phaseanim.adjust_scale(src.size_multiplier, src.size_multiplier) phaseanim.dir = dir alpha = 0 custom_emote(1,"phases in!") @@ -173,7 +180,7 @@ // change ability_flags |= AB_PHASE_SHIFTED ability_flags |= AB_PHASE_SHIFTING - mouse_opacity = 0 + throwpass = TRUE custom_emote(1,"phases out!") name = get_visible_name() @@ -181,12 +188,15 @@ B.escapable = FALSE var/obj/effect/temp_visual/shadekin/phase_out/phaseanim = new /obj/effect/temp_visual/shadekin/phase_out(src.loc) + phaseanim.pixel_y = (src.size_multiplier - 1) * 16 // Pixel shift for the animation placement + phaseanim.adjust_scale(src.size_multiplier, src.size_multiplier) phaseanim.dir = dir alpha = 0 add_modifier(/datum/modifier/shadekin_phase_vision) sleep(5) - invisibility = INVISIBILITY_LEVEL_TWO - see_invisible = INVISIBILITY_LEVEL_TWO + invisibility = INVISIBILITY_SHADEKIN + see_invisible = INVISIBILITY_SHADEKIN + see_invisible_default = INVISIBILITY_SHADEKIN // Allow seeing phased entities while phased. //cut_overlays() update_icon() alpha = 127 @@ -335,3 +345,24 @@ holder.glow_color = initial(holder.glow_color) holder.set_light(0) my_kin = null + +// force dephase proc, to be called by other procs to dephase the shadekin. T is the target to force dephase them to. +/mob/living/carbon/human/proc/attack_dephase(var/turf/T = null, atom/dephaser) + var/datum/species/shadekin/SK = species + + // no assigned dephase-target, just use our own + if(!T) + T = get_turf(src) + + // make sure it's possible to be dephased (and we're in phase) + if(!istype(SK) || SK.doing_phase || !T.CanPass(src,T) || loc != T || !(ability_flags & AB_PHASE_SHIFTED) ) + return FALSE + + + log_admin("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast].") + message_admins("[key_name_admin(src)] was stunned out of phase at [T.x],[T.y],[T.z] by [dephaser.name], last touched by [dephaser.fingerprintslast]. (JMP)", 1) + // start the dephase + phase_in(T) + shadekin_adjust_energy(-20) // loss of energy for the interception + // apply a little extra stun for good measure + src.Weaken(3) diff --git a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm index 7a537ae0bed..0d31b901cfe 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_special_abilities_vr.dm @@ -1262,7 +1262,7 @@ set category = "Abilities.Vore" set desc = "Grab a target with any of your appendages!" - if(stat || paralysis || weakened || stunned || world.time < last_special) //No tongue flicking while stunned. + if(stat || paralysis || weakened || stunned || world.time < last_special || is_incorporeal()) //No tongue flicking while stunned. to_chat(src, span_warning("You can't do that in your current state.")) return diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index 2ddea51a17f..e8c72835741 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -183,7 +183,7 @@ // This handles the drag-open inventory panel. /mob/living/MouseDrop(atom/over_object) var/mob/living/L = over_object - if(istype(L) && L != src && L == usr && Adjacent(L)) + if(istype(L) && L != src && L == usr && Adjacent(L) && !L.is_incorporeal()) show_inventory_panel(L) . = ..() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 6c9a5101610..8da9ccd9be5 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -255,6 +255,8 @@ //this proc handles being hit by a thrown atom /mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve + if(is_incorporeal()) + return if(istype(AM,/obj/)) var/obj/O = AM if(stat != DEAD && istype(O,/obj/item) && trash_catching && vore_selected) //ported from chompstation diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 08382380abf..e08c85180e4 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -9,7 +9,7 @@ if(istype(mover, /obj/item/projectile)) var/obj/item/projectile/P = mover return !P.can_hit_target(src, P.permutated, src == P.original, TRUE) - return (!mover.density || !density || lying) + return (!mover.density || !density || lying || is_incorporeal()) /mob/CanZASPass(turf/T, is_zone) return ATMOS_PASS_YES diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 84719998e6e..daffbce8789 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1326,7 +1326,7 @@ update_icon() -/mob/living/silicon/robot/verb/robot_nom(var/mob/living/T in living_mobs(1)) +/mob/living/silicon/robot/verb/robot_nom(var/mob/living/T in living_mobs_in_view(1)) set name = "Robot Nom" set category = "Abilities.Vore" set desc = "Allows you to eat someone." diff --git a/code/modules/mob/living/simple_mob/simple_mob_vr.dm b/code/modules/mob/living/simple_mob/simple_mob_vr.dm index e99602186a6..66098286c43 100644 --- a/code/modules/mob/living/simple_mob/simple_mob_vr.dm +++ b/code/modules/mob/living/simple_mob/simple_mob_vr.dm @@ -102,6 +102,10 @@ if(src == M) //Don't eat YOURSELF dork //ai_log("vr/won't eat [M] because it's me!", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 + if(!M.devourable) // Why was there never a check for edibility to begin with + return 0 + if(M.is_incorporeal()) // No eating the phased ones + return 0 if(vore_ignores_undigestable && !M.digestable) //Don't eat people with nogurgle prefs //ai_log("vr/wont eat [M] because I am picky", 3) //VORESTATION AI TEMPORARY REMOVAL return 0 @@ -145,6 +149,8 @@ /mob/living/simple_mob/proc/CanPounceTarget(var/mob/living/M) //returns either FALSE or a %chance of success if(!M.canmove || issilicon(M) || world.time < vore_pounce_cooldown) //eliminate situations where pouncing CANNOT happen return FALSE + if(M.is_incorporeal()) + return FALSE if(!prob(vore_pounce_chance) || !will_eat(M)) //mob doesn't want to pounce return FALSE if(vore_standing_too) //100% chance of hitting people we can eat on the spot diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm index 3b0143d335a..1786771b20f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/cockroach.dm @@ -52,6 +52,8 @@ if(ismob(AM)) if(isliving(AM)) var/mob/living/A = AM + if(A.is_incorporeal()) // Bad kin, no squishing the roach + return if(A.mob_size > MOB_SMALL) if(prob(squish_chance)) A.visible_message(span_notice("[A] squashed [src]."), span_notice("You squashed [src].")) diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm index 552060e3138..e1834d3943b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/ability_procs.dm @@ -11,12 +11,18 @@ return FALSE //RS Port #658 End + else if(doing_phase) + to_chat(src, span_warning("You are already trying to phase!")) + return FALSE + + doing_phase = TRUE //Shifting in if(ability_flags & AB_PHASE_SHIFTED) phase_in(T) //Shifting out else phase_out(T) + doing_phase = FALSE /mob/living/simple_mob/shadekin/proc/phase_in(var/turf/T) if(ability_flags & AB_PHASE_SHIFTED) @@ -35,7 +41,7 @@ // change ability_flags &= ~AB_PHASE_SHIFTED - mouse_opacity = 1 + throwpass = FALSE name = real_name for(var/obj/belly/B as anything in vore_organs) B.escapable = initial(B.escapable) @@ -100,7 +106,7 @@ // change ability_flags |= AB_PHASE_SHIFTED - mouse_opacity = 0 + throwpass = TRUE custom_emote(1,"phases out!") real_name = name name = "Something" diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm index e407d22070a..6c7622abf5b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/shadekin/shadekin.dm @@ -78,6 +78,7 @@ var/list/shadekin_abilities var/check_for_observer = FALSE var/check_timer = 0 + var/doing_phase = FALSE // Prevent bugs when spamming phase button /mob/living/simple_mob/shadekin/Initialize() //You spawned the prototype, and want a totally random one. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index fec32f347c3..749c51fdd61 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1308,3 +1308,8 @@ GLOBAL_LIST_EMPTY_TYPED(living_players_by_zlevel, /list) /mob/proc/grab_ghost(force) if(mind) return mind.grab_ghost(force = force) + +/mob/is_incorporeal() + if(incorporeal_move) + return 1 + return ..() diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index b85f6b24865..cb628a237fd 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -690,6 +690,22 @@ var/global/image/backplane /mob/proc/can_feed() return TRUE + +/atom/proc/living_mobs_in_view(var/range = world.view, var/count_held = FALSE) + var/list/viewers = oviewers(src, range) + if(count_held) + viewers = viewers(src,range) + var/list/living = list() + for(var/mob/living/L in viewers) + if(L.is_incorporeal()) + continue + living += L + if(count_held) + for(var/obj/item/holder/H in L.contents) + if(istype(H.held_mob, /mob/living)) + living += H.held_mob + return living + /proc/censor_swears(t) /* Bleeps our swearing */ var/static/swear_censoring_list = list("fuck", diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 2992b3a8675..7996364e2fb 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -145,12 +145,22 @@ Move_object(direct) // Ghosty mob movement - if(my_mob.incorporeal_move && isobserver(my_mob)) - Process_Incorpmove(direct) - DEBUG_INPUT("--------") - next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up. - next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists. - return + if(my_mob.is_incorporeal()) + if(isobserver(my_mob)) //We're an observer! Don't worry about any more checks. Be free! + Process_Incorpmove(direct) + DEBUG_INPUT("--------") + next_move_dir_add = 0 // This one I *think* exists so you can tap move and it will move even if delay isn't quite up. + next_move_dir_sub = 0 // I'm not really sure why next_move_dir_sub even exists. + return + else //We are anything BUT an observer. + if(!my_mob.canmove)//If you want to be very restrictive, add my_mob.restrained() and it'll stop people cuffed/straight jacketed. For now, that's too restrictive for a bugfix PR. + return + else //Proceed like normal. + Process_Incorpmove(direct) + DEBUG_INPUT("--------") + next_move_dir_add = 0 + next_move_dir_sub = 0 + return // We're in the middle of another move we've already decided to do if(moving) @@ -183,7 +193,7 @@ if(isliving(my_mob)) var/mob/living/L = my_mob - if(L.incorporeal_move)//Move though walls + if(L.is_incorporeal())//Move though walls Process_Incorpmove(direct) return /* TODO observer unzoom diff --git a/code/modules/multiz/movement_vr.dm b/code/modules/multiz/movement_vr.dm index aab026ed683..275e3bc9e17 100644 --- a/code/modules/multiz/movement_vr.dm +++ b/code/modules/multiz/movement_vr.dm @@ -32,6 +32,8 @@ return 0 var/mob/living/pred = hit_atom + if(pred.is_incorporeal()) + return var/safe_fall = FALSE if(pred.softfall || (isanimal(pred) && pred.mob_size <= MOB_SMALL)) // TODO: add ability for mob below to be 'soft' and cushion fall safe_fall = TRUE diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index f57ac672dc6..56d4e9704f0 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -21,7 +21,7 @@ /obj/machinery/containment_field/Initialize() . = ..() shockdirs = list(turn(dir,90),turn(dir,-90)) - sense_proximity(callback = /atom/proc/HasProximity) + sense_proximity(callback = TYPE_PROC_REF(/atom,HasProximity)) /obj/machinery/containment_field/set_dir(new_dir) . = ..() @@ -48,12 +48,19 @@ return 0 /obj/machinery/containment_field/Crossed(mob/living/L) - if(!istype(L) || L.incorporeal_move) + if(!istype(L) || L.is_incorporeal()) return shock(L) -/obj/machinery/containment_field/HasProximity(turf/T, atom/movable/AM, old_loc) - if(!isliving(AM) || AM:incorporeal_move) +/obj/machinery/containment_field/HasProximity(turf/T, datum/weakref/WF, old_loc) + SIGNAL_HANDLER + if(isnull(WF)) + return + var/atom/movable/AM = WF.resolve() + if(isnull(AM)) + log_debug("DEBUG: HasProximity called without reference on [src].") + return + if(!isliving(AM) || AM.is_incorporeal()) return 0 if(!(get_dir(src,AM) in shockdirs)) return 0 diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index a76f37b43a1..3a9b3348773 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -388,7 +388,7 @@ env.merge(removed) for(var/mob/living/carbon/human/l in view(src, min(7, round(sqrt(power/6))))) // If they can see it without mesons on. Bad on them. - if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) // VOREStation Edit - Only mesons can protect you! + if(!istype(l.glasses, /obj/item/clothing/glasses/meson) || l.is_incorporeal()) // VOREStation Edit - Only mesons can protect you! OR if they're not in the same plane of existence l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) ) SSradiation.radiate(src, max(power * 1.5, 50) ) //Better close those shutters! diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index a88e8998d6e..c88ee5cb713 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -156,7 +156,7 @@ /obj/singularity/energy_ball/proc/dust_mob(mob/living/L) - if(!istype(L) || L.incorporeal_move) + if(!istype(L) || L.is_incorporeal()) return // L.dust() - Changing to do fatal elecrocution instead L.electrocute_act(500, src, def_zone = BP_TORSO) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 2244530bd8f..2bd59698f61 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -679,6 +679,9 @@ if(!istype(target_mob)) return + if(target_mob.is_incorporeal()) + return + if(target_mob in impacted_mobs) return diff --git a/code/modules/projectiles/targeting/targeting_gun.dm b/code/modules/projectiles/targeting/targeting_gun.dm index b97027e2206..cec51cc5690 100644 --- a/code/modules/projectiles/targeting/targeting_gun.dm +++ b/code/modules/projectiles/targeting/targeting_gun.dm @@ -17,7 +17,7 @@ user.face_atom(A) if(ismob(A) && user.aiming) user.aiming.aim_at(A, src) - if(!isliving(A)) + if(!isliving(A) || A.is_incorporeal()) // Phase out can't be targetted when phased return 0 return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 9f9739c2347..2b6069fefed 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -61,6 +61,8 @@ return 1 /obj/structure/table/MouseDrop_T(obj/O, mob/user, src_location, over_location, src_control, over_control, params) + if(user.is_incorporeal()) + return if(ismob(O.loc)) //If placing an item if(!isitem(O) || user.get_active_hand() != O) return ..() diff --git a/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living_vr.dm index 303b775bdc8..a9afebacf00 100644 --- a/code/modules/vore/eating/living_vr.dm +++ b/code/modules/vore/eating/living_vr.dm @@ -454,7 +454,7 @@ // // Clearly super important. Obviously. // -/mob/living/proc/lick(mob/living/tasted in living_mobs(1)) +/mob/living/proc/lick(mob/living/tasted in living_mobs_in_view(1)) set name = "Lick" set category = "IC.Game" set desc = "Lick someone nearby!" @@ -829,6 +829,8 @@ /mob/living/proc/feed_grabbed_to_self_falling_nom(var/mob/living/user, var/mob/living/prey) + if(user.is_incorporeal()) + return FALSE var/belly = user.vore_selected return perform_the_nom(user, prey, user, belly, delay = 1) //1/10th of a second is probably fine. diff --git a/code/modules/vore/eating/simple_animal_vr.dm b/code/modules/vore/eating/simple_animal_vr.dm index a75aa55f282..ea14e535a42 100644 --- a/code/modules/vore/eating/simple_animal_vr.dm +++ b/code/modules/vore/eating/simple_animal_vr.dm @@ -12,7 +12,7 @@ // // Simple nom proc for if you get ckey'd into a simple_mob mob! Avoids grabs. // -/mob/living/simple_mob/proc/animal_nom(mob/living/T in living_mobs(1)) +/mob/living/simple_mob/proc/animal_nom(mob/living/T in living_mobs_in_view(1)) set name = "Animal Nom" set category = "Abilities.Vore" // Moving this to abilities from IC as it's more fitting there set desc = "Since you can't grab, you get a verb!" diff --git a/code/modules/vore/eating/slipvore_vr.dm b/code/modules/vore/eating/slipvore_vr.dm index 134ff453794..b6013f2d228 100644 --- a/code/modules/vore/eating/slipvore_vr.dm +++ b/code/modules/vore/eating/slipvore_vr.dm @@ -8,6 +8,8 @@ /mob/living/proc/can_slip_vore(var/mob/living/target) if(!target.is_slipping) //Obviously they have to be slipping to get slip vored return FALSE + if(is_incorporeal()) + return FALSE if(world.time <= target.slip_protect) return FALSE if(!(src.can_be_drop_pred && target.devourable && target.can_be_drop_prey)) //Make sure both of their prefs align with what we're gonna do. @@ -23,6 +25,8 @@ /mob/living/proc/can_be_slip_vored_by(var/mob/living/target) if(!target.is_slipping) //Obviously they have to be slipping to get slip vored return FALSE + if(is_incorporeal()) + return FALSE if(world.time <= target.slip_protect) return FALSE if(!(target.can_be_drop_pred && src.devourable && src.can_be_drop_prey)) //Make sure both of their prefs align with what we're gonna do. @@ -38,7 +42,7 @@ /mob/living/Crossed(var/atom/movable/AM) ..() var/mob/living/target = AM - if(istype(target) && !target.incorporeal_move && !src.incorporeal_move) //The slip vore begins + if(istype(target) && !target.is_incorporeal() && !src.is_incorporeal()) //The slip vore begins if(can_slip_vore(target) && !src.slip_vore_in_progress && !target.slip_vore_in_progress) //If we can vore them go for it perform_the_nom(src,target,src,src.vore_selected,1) target.slip_vore_in_progress = FALSE diff --git a/code/modules/vore/eating/stumblevore_vr.dm b/code/modules/vore/eating/stumblevore_vr.dm index 53474a660f9..6f52634fad7 100644 --- a/code/modules/vore/eating/stumblevore_vr.dm +++ b/code/modules/vore/eating/stumblevore_vr.dm @@ -1,6 +1,8 @@ /mob/living/proc/CanStumbleVore(mob/living/target) if(!can_be_drop_pred) return FALSE + if(is_incorporeal() || target.is_incorporeal()) + return FALSE if(!is_vore_predator(src)) return FALSE if(!target.devourable) @@ -14,8 +16,10 @@ /mob/living/Bump(atom/movable/AM) //. = ..() if(isliving(AM)) - if(buckled != AM && (((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent==I_RUN) || flying && flight_vore)) - AM.stumble_into(src) + var/mob/living/L = AM + if(!L.is_incorporeal()) + if(buckled != AM && (((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent==I_RUN) || flying && flight_vore)) + AM.stumble_into(src) return ..() // Because flips toggle density /mob/living/Crossed(var/atom/movable/AM) diff --git a/code/modules/vore/eating/vertical_nom_vr.dm b/code/modules/vore/eating/vertical_nom_vr.dm index e47c1f00d95..80dc10f9e03 100644 --- a/code/modules/vore/eating/vertical_nom_vr.dm +++ b/code/modules/vore/eating/vertical_nom_vr.dm @@ -3,7 +3,7 @@ set desc = "Allows you to eat people who are below your tile or adjacent one. Requires passability." set category = "Abilities.Vore" - if(stat == DEAD || paralysis || weakened || stunned) + if(stat == DEAD || paralysis || weakened || stunned || is_incorporeal()) to_chat(src, span_notice("You cannot do that while in your current state.")) return diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index 9747f41baa5..00fa6286ebe 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -212,6 +212,8 @@ * @return false if normal code should continue, true to prevent normal code. */ /mob/living/proc/handle_micro_bump_helping(mob/living/tmob) + if(is_incorporeal() || tmob.is_incorporeal()) + return FALSE //Riding and being moved to us or something similar if(tmob in buckled_mobs) return TRUE @@ -271,6 +273,8 @@ //We can't be stepping on anyone if(!canmove || buckled) return + if(is_incorporeal() || tmob.is_incorporeal()) + return //Riding and being moved to us or something similar if(tmob in buckled_mobs)