diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index ddc990dc182..9aefeff9f84 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -173,3 +173,9 @@ //We will round to this value in damage calculations. #define DAMAGE_PRECISION 0.1 + +//bullet_act() return values +#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting. +#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting. +#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default. +#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs. diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 77ea2a3e98e..d2e462bbaea 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -1,157 +1,158 @@ -/* - These defines are specific to the atom/flags_1 bitmask -*/ -#define ALL (~0) //For convenience. -#define NONE 0 - -//for convenience -#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) -#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) -#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) -#define CHECK_BITFIELD(variable, flag) (variable & flag) - -//check if all bitflags specified are present -#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) ((flagvar & (flags)) == flags) - -GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) - -// for /datum/var/datum_flags -#define DF_USE_TAG (1<<0) -#define DF_VAR_EDITED (1<<1) -#define DF_ISPROCESSING (1<<2) - -//FLAGS BITMASK - -#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not. -#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this. -#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.) -#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff -#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay -#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving -#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows -#define HOLOGRAM_1 (1<<12) -#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity -#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object -#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff. - -//turf-only flags -#define NOJAUNT_1 (1<<0) -#define UNUSED_RESERVATION_TURF_1 (1<<1) -#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas. -#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf -#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf - -/* - These defines are used specifically with the atom/pass_flags bitmask - the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example) -*/ -//flags for pass_flags -#define PASSTABLE (1<<0) -#define PASSGLASS (1<<1) -#define PASSGRILLE (1<<2) -#define PASSBLOB (1<<3) -#define PASSMOB (1<<4) -#define PASSCLOSEDTURF (1<<5) -#define LETPASSTHROW (1<<6) - -//Movement Types -#define GROUND (1<<0) -#define FLYING (1<<1) -#define VENTCRAWLING (1<<2) -#define FLOATING (1<<3) -#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped. - -//Fire and Acid stuff, for resistance_flags -#define LAVA_PROOF (1<<0) -#define FIRE_PROOF (1<<1) //100% immune to fire damage (but not necessarily to lava or heat) -#define FLAMMABLE (1<<2) -#define ON_FIRE (1<<3) -#define UNACIDABLE (1<<4) //acid can't even appear on it, let alone melt it. -#define ACID_PROOF (1<<5) //acid stuck on it doesn't melt it. -#define INDESTRUCTIBLE (1<<6) //doesn't take damage -#define FREEZE_PROOF (1<<7) //can't be frozen - -/obj/item/proc/clothing_resistance_flag_examine_message(mob/user) - if(resistance_flags & INDESTRUCTIBLE) - to_chat(user, "[src] seems extremely robust! It'll probably withstand anything that could happen to it!") - return - if(resistance_flags & LAVA_PROOF) - to_chat(user, "[src] is made of an extremely heat-resistant material, it'd probably be able to withstand lava!") - if(resistance_flags & (ACID_PROOF | UNACIDABLE)) - to_chat(user, "[src] looks pretty robust! It'd probably be able to withstand acid!") - if(resistance_flags & FREEZE_PROOF) - to_chat(user, "[src] is made of cold-resistant materials.") - if(resistance_flags & FIRE_PROOF) - to_chat(user, "[src] is made of fire-retardant materials.") - return TRUE - -/obj/item/clothing/clothing_resistance_flag_examine_message(mob/user) - . = ..() - if(.) - return - if(max_heat_protection_temperature == FIRE_IMMUNITY_MAX_TEMP_PROTECT) - to_chat(user, "[src] is made of fire-retardant materials.") - return TRUE - -/obj/item/clothing/head/clothing_resistance_flag_examine_message(mob/user) - . = ..() - if(.) - return - if(max_heat_protection_temperature == (HELMET_MAX_TEMP_PROTECT || SPACE_HELM_MAX_TEMP_PROTECT || FIRE_HELM_MAX_TEMP_PROTECT)) - to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") - return TRUE - -/obj/item/clothing/gloves/clothing_resistance_flag_examine_message(mob/user) - . = ..() - if(.) - return - if(max_heat_protection_temperature == GLOVES_MAX_TEMP_PROTECT) - to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") - return TRUE - -/obj/item/clothing/shoes/clothing_resistance_flag_examine_message(mob/user) - . = ..() - if(.) - return - if(max_heat_protection_temperature == SHOES_MAX_TEMP_PROTECT) - to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") - return TRUE - -/obj/item/clothing/suit/clothing_resistance_flag_examine_message(mob/user) - . = ..() - if(.) - return - if(max_heat_protection_temperature == SPACE_SUIT_MAX_TEMP_PROTECT) - to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") - return TRUE - -//tesla_zap -#define TESLA_MACHINE_EXPLOSIVE (1<<0) -#define TESLA_ALLOW_DUPLICATES (1<<1) -#define TESLA_OBJ_DAMAGE (1<<2) -#define TESLA_MOB_DAMAGE (1<<3) -#define TESLA_MOB_STUN (1<<4) - -#define TESLA_DEFAULT_FLAGS ALL -#define TESLA_FUSION_FLAGS TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_MOB_STUN - -//EMP protection -#define EMP_PROTECT_SELF (1<<0) -#define EMP_PROTECT_CONTENTS (1<<1) -#define EMP_PROTECT_WIRES (1<<2) - -//Mob mobility var flags -#define MOBILITY_MOVE (1<<0) //can move -#define MOBILITY_STAND (1<<1) //can, and is, standing up -#define MOBILITY_PICKUP (1<<2) //can pickup items -#define MOBILITY_USE (1<<3) //can hold and use items -#define MOBILITY_UI (1<<4) //can use interfaces like machinery -#define MOBILITY_STORAGE (1<<5) //can use storage item -#define MOBILITY_PULL (1<<6) //can pull things - -#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL) -#define MOBILITY_FLAGS_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE) - -// radiation -#define RAD_PROTECT_CONTENTS (1<<0) -#define RAD_NO_CONTAMINATE (1<<1) +/* + These defines are specific to the atom/flags_1 bitmask +*/ +#define ALL (~0) //For convenience. +#define NONE 0 + +//for convenience +#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) +#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) +#define CHECK_BITFIELD(variable, flag) (variable & (flag)) +#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) + + +//check if all bitflags specified are present +#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) ((flagvar & (flags)) == flags) + +GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) + +// for /datum/var/datum_flags +#define DF_USE_TAG (1<<0) +#define DF_VAR_EDITED (1<<1) +#define DF_ISPROCESSING (1<<2) + +//FLAGS BITMASK + +#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not. +#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this. +#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.) +#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff +#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay +#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving +#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows +#define HOLOGRAM_1 (1<<12) +#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity +#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object +#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff. + +//turf-only flags +#define NOJAUNT_1 (1<<0) +#define UNUSED_RESERVATION_TURF_1 (1<<1) +#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas. +#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf +#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf + +/* + These defines are used specifically with the atom/pass_flags bitmask + the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example) +*/ +//flags for pass_flags +#define PASSTABLE (1<<0) +#define PASSGLASS (1<<1) +#define PASSGRILLE (1<<2) +#define PASSBLOB (1<<3) +#define PASSMOB (1<<4) +#define PASSCLOSEDTURF (1<<5) +#define LETPASSTHROW (1<<6) + +//Movement Types +#define GROUND (1<<0) +#define FLYING (1<<1) +#define VENTCRAWLING (1<<2) +#define FLOATING (1<<3) +#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped. + +//Fire and Acid stuff, for resistance_flags +#define LAVA_PROOF (1<<0) +#define FIRE_PROOF (1<<1) //100% immune to fire damage (but not necessarily to lava or heat) +#define FLAMMABLE (1<<2) +#define ON_FIRE (1<<3) +#define UNACIDABLE (1<<4) //acid can't even appear on it, let alone melt it. +#define ACID_PROOF (1<<5) //acid stuck on it doesn't melt it. +#define INDESTRUCTIBLE (1<<6) //doesn't take damage +#define FREEZE_PROOF (1<<7) //can't be frozen + +/obj/item/proc/clothing_resistance_flag_examine_message(mob/user) + if(resistance_flags & INDESTRUCTIBLE) + to_chat(user, "[src] seems extremely robust! It'll probably withstand anything that could happen to it!") + return + if(resistance_flags & LAVA_PROOF) + to_chat(user, "[src] is made of an extremely heat-resistant material, it'd probably be able to withstand lava!") + if(resistance_flags & (ACID_PROOF | UNACIDABLE)) + to_chat(user, "[src] looks pretty robust! It'd probably be able to withstand acid!") + if(resistance_flags & FREEZE_PROOF) + to_chat(user, "[src] is made of cold-resistant materials.") + if(resistance_flags & FIRE_PROOF) + to_chat(user, "[src] is made of fire-retardant materials.") + return TRUE + +/obj/item/clothing/clothing_resistance_flag_examine_message(mob/user) + . = ..() + if(.) + return + if(max_heat_protection_temperature == FIRE_IMMUNITY_MAX_TEMP_PROTECT) + to_chat(user, "[src] is made of fire-retardant materials.") + return TRUE + +/obj/item/clothing/head/clothing_resistance_flag_examine_message(mob/user) + . = ..() + if(.) + return + if(max_heat_protection_temperature == (HELMET_MAX_TEMP_PROTECT || SPACE_HELM_MAX_TEMP_PROTECT || FIRE_HELM_MAX_TEMP_PROTECT)) + to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") + return TRUE + +/obj/item/clothing/gloves/clothing_resistance_flag_examine_message(mob/user) + . = ..() + if(.) + return + if(max_heat_protection_temperature == GLOVES_MAX_TEMP_PROTECT) + to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") + return TRUE + +/obj/item/clothing/shoes/clothing_resistance_flag_examine_message(mob/user) + . = ..() + if(.) + return + if(max_heat_protection_temperature == SHOES_MAX_TEMP_PROTECT) + to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") + return TRUE + +/obj/item/clothing/suit/clothing_resistance_flag_examine_message(mob/user) + . = ..() + if(.) + return + if(max_heat_protection_temperature == SPACE_SUIT_MAX_TEMP_PROTECT) + to_chat(user, "[src] is made of thermally insulated materials and offers some protection to fire.") + return TRUE + +//tesla_zap +#define TESLA_MACHINE_EXPLOSIVE (1<<0) +#define TESLA_ALLOW_DUPLICATES (1<<1) +#define TESLA_OBJ_DAMAGE (1<<2) +#define TESLA_MOB_DAMAGE (1<<3) +#define TESLA_MOB_STUN (1<<4) + +#define TESLA_DEFAULT_FLAGS ALL +#define TESLA_FUSION_FLAGS TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_MOB_STUN + +//EMP protection +#define EMP_PROTECT_SELF (1<<0) +#define EMP_PROTECT_CONTENTS (1<<1) +#define EMP_PROTECT_WIRES (1<<2) + +//Mob mobility var flags +#define MOBILITY_MOVE (1<<0) //can move +#define MOBILITY_STAND (1<<1) //can, and is, standing up +#define MOBILITY_PICKUP (1<<2) //can pickup items +#define MOBILITY_USE (1<<3) //can hold and use items +#define MOBILITY_UI (1<<4) //can use interfaces like machinery +#define MOBILITY_STORAGE (1<<5) //can use storage item +#define MOBILITY_PULL (1<<6) //can pull things + +#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL) +#define MOBILITY_FLAGS_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE) + +// radiation +#define RAD_PROTECT_CONTENTS (1<<0) +#define RAD_NO_CONTAMINATE (1<<1) diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index 109078f804b..fe51b0fc0ad 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -74,6 +74,7 @@ playsound(src, 'sound/weapons/slice.ogg', 50, 1) if(prob(P.damage)) push_over() + return BULLET_ACT_HIT /obj/item/cardboard_cutout/proc/change_appearance(obj/item/toy/crayon/crayon, mob/living/user) if(!crayon || !user) diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 0595463d9fa..ba4e365e982 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -245,7 +245,7 @@ if(Pgun && istype(Pgun)) Pgun.field_connect(src) else - return 0 + return BULLET_ACT_HIT /obj/structure/chrono_field/assume_air() return 0 diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 25d3d63b942..1e9b4959f76 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -146,7 +146,7 @@ master.disrupt() /obj/effect/dummy/chameleon/bullet_act() - ..() + . = ..() master.disrupt() /obj/effect/dummy/chameleon/relaymove(mob/user, direction) diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm index d6142ea2750..eb8359fc358 100644 --- a/code/game/objects/items/latexballoon.dm +++ b/code/game/objects/items/latexballoon.dm @@ -40,8 +40,10 @@ if (prob(50)) qdel(src) -/obj/item/latexballon/bullet_act() - burst() +/obj/item/latexballon/bullet_act(obj/item/projectile/P) + if(!P.nodamage) + burst() + return ..() /obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume) if(temperature > T0C+100) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index e20ed59697d..50de4a8ec1f 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -310,7 +310,8 @@ /obj/item/melee/supermatter_sword/bullet_act(obj/item/projectile/P) visible_message("[P] smacks into [src] and rapidly flashes to ash.",\ "You hear a loud crack as you are washed with a wave of heat.") - consume_everything() + consume_everything(P) + return BULLET_ACT_HIT /obj/item/melee/supermatter_sword/suicide_act(mob/user) user.visible_message("[user] touches [src]'s blade. It looks like [user.p_theyre()] tired of waiting for the radiation to kill [user.p_them()]!") diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 9087d0acc54..3e8ca31f77d 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -60,7 +60,7 @@ #define DECALTYPE_BULLET 2 /obj/item/target/clown/bullet_act(obj/item/projectile/P) - ..() + . = ..() playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1) /obj/item/target/bullet_act(obj/item/projectile/P) @@ -89,8 +89,8 @@ else bullet_hole.icon_state = "dent" add_overlay(bullet_hole) - return - return -1 + return BULLET_ACT_HIT + return BULLET_ACT_FORCE_PIERCE #undef DECALTYPE_SCORCH #undef DECALTYPE_BULLET diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 3c649f15492..5c48f762501 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -106,6 +106,7 @@ take_damage(10, BRUTE, "melee", 1) //Tasers aren't harmful. if(istype(P, /obj/item/projectile/beam/disabler)) take_damage(5, BRUTE, "melee", 1) //Disablers aren't harmful. + return BULLET_ACT_HIT /obj/structure/holosign/barrier/medical name = "\improper PENLITE holobarrier" @@ -151,6 +152,7 @@ /obj/structure/holosign/barrier/cyborg/hacked/bullet_act(obj/item/projectile/P) take_damage(P.damage, BRUTE, "melee", 1) //Yeah no this doesn't get projectile resistance. + return BULLET_ACT_HIT /obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() shockcd = FALSE diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index 11bc62a2a66..c03c0022559 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -67,13 +67,13 @@ return ..() if(auto_reflect(P, pdir, ploc, pangle) != -1) return ..() - return -1 + return BULLET_ACT_FORCE_PIERCE /obj/structure/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle) P.ignore_source_check = TRUE P.range = P.decayedRange P.decayedRange = max(P.decayedRange--, 0) - return -1 + return BULLET_ACT_FORCE_PIERCE /obj/structure/reflector/attackby(obj/item/W, mob/user, params) if(admin) diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index b25c1c555d6..8160bbddf51 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -124,7 +124,7 @@ message_admins("Plasma statue ignited by [Proj]. No known firer, in [ADMIN_VERBOSEJMP(T)]") log_game("Plasma statue ignited by [Proj] in [AREACOORD(T)]. No known firer.") PlasmaBurn(2500) - ..() + . = ..() /obj/structure/statue/plasma/attackby(obj/item/W, mob/user, params) if(W.is_hot() > 300 && !QDELETED(src))//If the temperature of the object is over 300, then ignite diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index b1ad847cc8c..8ce0ffc91c9 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -73,4 +73,4 @@ if(pinned_target) pinned_target.bullet_act(P) else - ..() + . = ..() diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index f9abcc7345f..333146a5462 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -115,13 +115,12 @@ if(exposed_temperature > 300) PlasmaBurn(exposed_temperature) -/turf/closed/wall/mineral/plasma/bullet_act(var/obj/item/projectile/Proj) +/turf/closed/wall/mineral/plasma/bullet_act(obj/item/projectile/Proj) if(istype(Proj, /obj/item/projectile/beam)) PlasmaBurn(2500) else if(istype(Proj, /obj/item/projectile/ion)) PlasmaBurn(500) - ..() - + . = ..() /turf/closed/wall/mineral/wood name = "wooden wall" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 58a95655bfc..571501c8d01 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -204,41 +204,44 @@ stack_trace("Non movable passed to turf CanPass : [mover]") return FALSE +//There's a lot of QDELETED() calls here if someone can figure out how to optimize this but not runtime when something gets deleted by a Bump/CanPass/Cross call, lemme know or go ahead and fix this mess - kevinz000 /turf/Enter(atom/movable/mover, atom/oldloc) // Do not call ..() // Byond's default turf/Enter() doesn't have the behaviour we want with Bump() // By default byond will call Bump() on the first dense object in contents // Here's hoping it doesn't stay like this for years before we finish conversion to step_ var/atom/firstbump - if(!CanPass(mover, src)) - firstbump = src - else + var/canPassSelf = CanPass(mover, src) + if(canPassSelf || CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) for(var/i in contents) + if(QDELETED(mover)) + return FALSE //We were deleted, do not attempt to proceed with movement. if(i == mover || i == mover.loc) // Multi tile objects and moving out of other objects continue - if(QDELETED(mover)) - break var/atom/movable/thing = i if(!thing.Cross(mover)) + if(QDELETED(mover)) //Mover deleted from Cross/CanPass, do not proceed. + return FALSE if(CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) mover.Bump(thing) continue else if(!firstbump || ((thing.layer > firstbump.layer || thing.flags_1 & ON_BORDER_1) && !(firstbump.flags_1 & ON_BORDER_1))) firstbump = thing + if(QDELETED(mover)) //Mover deleted from Cross/CanPass/Bump, do not proceed. + return FALSE + if(!canPassSelf) //Even if mover is unstoppable they need to bump us. + firstbump = src if(firstbump) - if(!QDELETED(mover)) - mover.Bump(firstbump) + mover.Bump(firstbump) return CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE) return TRUE /turf/Exit(atom/movable/mover, atom/newloc) . = ..() - if(!.) + if(!. || QDELETED(mover)) return FALSE for(var/i in contents) - if(QDELETED(mover)) - break if(i == mover) continue var/atom/movable/thing = i @@ -247,6 +250,8 @@ mover.Bump(thing) if(!CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) return FALSE + if(QDELETED(mover)) + return FALSE //We were deleted. /turf/Entered(atom/movable/AM) ..() @@ -549,3 +554,7 @@ //Should return new turf /turf/proc/Melt() return ScrapeAway() + +/turf/bullet_act(obj/item/projectile/P) + . = ..() + return BULLET_ACT_TURF diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index 42ca9e07e2c..3360b0ef5a4 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -82,7 +82,7 @@ /mob/living/simple_animal/hostile/clockwork/marauder/bullet_act(obj/item/projectile/P) if(deflect_projectile(P)) - return + return BULLET_ACT_BLOCK return ..() /mob/living/simple_animal/hostile/clockwork/marauder/proc/deflect_projectile(obj/item/projectile/P) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index ad1900a8e1a..8cabbb322c4 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -244,13 +244,11 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ /obj/item/twohanded/required/gibtonite/bullet_act(obj/item/projectile/P) GibtoniteReaction(P.firer) - ..() + . = ..() /obj/item/twohanded/required/gibtonite/ex_act() GibtoniteReaction(null, 1) - - /obj/item/twohanded/required/gibtonite/proc/GibtoniteReaction(mob/user, triggered_by = 0) if(!primed) primed = TRUE diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index 0139059878a..fd60061284d 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -13,8 +13,9 @@ /obj/effect/dummy/phased_mob/slaughter/ex_act() return + /obj/effect/dummy/phased_mob/slaughter/bullet_act() - return + return BULLET_ACT_FORCE_PIERCE /obj/effect/dummy/phased_mob/slaughter/singularity_act() return diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 8b297333419..c2c69456785 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -80,9 +80,9 @@ if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration)) P.on_hit(src, 100, def_zone) - return 2 + return BULLET_ACT_HIT - return (..(P , def_zone)) + return ..(P, def_zone) /mob/living/carbon/human/proc/check_reflect(def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object if(wear_suit) diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 22f2083807b..01ee56d94e4 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -399,7 +399,7 @@ if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)) if(!Proj.nodamage && Proj.damage < src.health && isliving(Proj.firer)) retaliate(Proj.firer) - ..() + . = ..() /mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item)) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index f4f6fc15596..b548d3c7d72 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -48,7 +48,7 @@ apply_damage(P.damage, P.damage_type, def_zone, armor) if(P.dismemberment) check_projectile_dismemberment(P, def_zone) - return P.on_hit(src, armor) + return P.on_hit(src, armor)? BULLET_ACT_HIT : BULLET_ACT_BLOCK /mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone) return 0 diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 4cf5fd27496..44cdade59f9 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -2,6 +2,23 @@ . = ..() update_turf_movespeed(loc) +/mob/living/CanPass(atom/movable/mover, turf/target) + if((mover.pass_flags & PASSMOB)) + return TRUE + if(istype(mover, /obj/item/projectile)) + var/obj/item/projectile/P = mover + if(P.can_hit_target(src, P.permutated, src == P.original, TRUE)) + P.Bump(src) + return TRUE + if(mover.throwing) + return (!density || !(mobility_flags & MOBILITY_STAND)) + if(buckled == mover) + return TRUE + if(ismob(mover)) + if(mover in buckled_mobs) + return TRUE + return (!mover.density || !density || !(mobility_flags & MOBILITY_STAND)) + /mob/living/toggle_move_intent() . = ..() update_move_intent_slowdown() diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index 7c59c2b791b..eff8c3f0a5f 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -48,9 +48,8 @@ /mob/living/silicon/ai/bullet_act(obj/item/projectile/Proj) - ..(Proj) + . = ..(Proj) updatehealth() - return 2 /mob/living/silicon/ai/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0) return // no eyes, no flashing diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 3c798588e50..f342c90db70 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -178,8 +178,7 @@ adjustBruteLoss(30) /mob/living/silicon/robot/bullet_act(var/obj/item/projectile/Proj, def_zone) - ..() + . = ..() updatehealth() if(prob(75) && Proj.damage > 0) spark_system.start() - return 2 diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 7320e457f12..243f9e78eaf 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -124,7 +124,7 @@ unbuckle_mob(M) M.visible_message("[M] is knocked off of [src] by the [Proj]!") Proj.on_hit(src) - return 2 + return BULLET_ACT_HIT /mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/static) if(affect_silicon) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index a00373c7d78..b31f082f856 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -105,11 +105,9 @@ return TRUE /mob/living/simple_animal/bullet_act(obj/item/projectile/Proj) - if(!Proj) - return apply_damage(Proj.damage, Proj.damage_type) Proj.on_hit(src) - return 0 + return BULLET_ACT_HIT /mob/living/simple_animal/ex_act(severity, target, origin) if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm index 0378b0b9ee9..5dea3f0c63e 100644 --- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm +++ b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm @@ -21,7 +21,7 @@ /mob/living/simple_animal/bot/secbot/grievous/bullet_act(obj/item/projectile/P) visible_message("[src] deflects [P] with its energy swords!") playsound(src, 'sound/weapons/blade1.ogg', 50, TRUE) - return FALSE + return BULLET_ACT_BLOCK /mob/living/simple_animal/bot/secbot/grievous/Crossed(atom/movable/AM) ..() diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index e74b7cfa12c..007b705585d 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -210,7 +210,7 @@ Auto Patrol[]"}, if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)) if(!Proj.nodamage && Proj.damage < src.health && ishuman(Proj.firer)) retaliate(Proj.firer) - ..() + return ..() /mob/living/simple_animal/bot/ed209/handle_automated_action() if(!..()) @@ -510,11 +510,11 @@ Auto Patrol[]"}, spawn(100) disabled = 0 icon_state = "[lasercolor]ed2091" - return 1 + return BULLET_ACT_HIT else - ..(Proj) + . = ..() else - ..(Proj) + . = ..() /mob/living/simple_animal/bot/ed209/bluetag lasercolor = "b" diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 3e00590c4e2..c3d7eeb87a3 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -138,7 +138,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, /mob/living/simple_animal/bot/honkbot/bullet_act(obj/item/projectile/Proj) if((istype(Proj,/obj/item/projectile/beam)) || (istype(Proj,/obj/item/projectile/bullet) && (Proj.damage_type == BURN))||(Proj.damage_type == BRUTE) && (!Proj.nodamage && Proj.damage < health && ishuman(Proj.firer))) retaliate(Proj.firer) - ..() + return ..() /mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A) if(!on) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 7fe2fc97f63..1cc39ca5835 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -149,7 +149,8 @@ return /mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj) - if(..()) + . = ..() + if(.) if(prob(50) && !isnull(load)) unload(0) if(prob(25)) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 487d5f84df6..980d3e75774 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -204,8 +204,7 @@ Auto Patrol: []"}, if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)) if(!Proj.nodamage && Proj.damage < src.health && ishuman(Proj.firer)) retaliate(Proj.firer) - ..() - + return ..() /mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A) if(!on) @@ -219,7 +218,6 @@ Auto Patrol: []"}, else ..() - /mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item)) var/obj/item/I = AM @@ -228,7 +226,6 @@ Auto Patrol: []"}, retaliate(H) ..() - /mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C) mode = BOT_ARREST playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 2ebe0896f85..86c50ec7356 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -173,9 +173,7 @@ return -1 // complete projectile permutation - return (..(P)) - - + return ..() ////////////////////////Wraith///////////////////////////////////////////// /mob/living/simple_animal/hostile/construct/wraith diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 2eb3c05eaec..d9c182b3686 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -117,7 +117,7 @@ Difficulty: Very Hard var/random_y = rand(0, 72) AT.pixel_y += random_y - ..() + return ..() /mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L) if(ishuman(L)) @@ -395,7 +395,7 @@ Difficulty: Very Hard ..() /obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone) - ..() + . = ..() if(istype(P, /obj/item/projectile/magic)) ActivationReaction(P.firer, ACTIVATE_MAGIC, P.damage_type) return diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm index 2041f64154c..d1cbeb2539e 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm @@ -74,7 +74,7 @@ /mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(obj/item/projectile/P) visible_message("The [P.name] was repelled by [name]'s girth!") - return + return BULLET_ACT_BLOCK /mob/living/simple_animal/hostile/asteroid/goldgrub/adjustHealth(amount, updating_health = TRUE, forced = FALSE) vision_range = 9 diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 51913e49b05..9cdeaa2f629 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -177,9 +177,10 @@ if(T.throwforce) Bruise() -/mob/living/simple_animal/hostile/mushroom/bullet_act() - ..() - Bruise() +/mob/living/simple_animal/hostile/mushroom/bullet_act(obj/item/projectile/P) + . = ..() + if(P.nodamage) + Bruise() /mob/living/simple_animal/hostile/mushroom/harvest() var/counter diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 2c45743c55c..26bb9b0c13e 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -84,6 +84,7 @@ attacktext = "slashes" attack_sound = 'sound/weapons/bladeslice.ogg' status_flags = 0 + var/projectile_deflect_chance = 50 /mob/living/simple_animal/hostile/syndicate/melee/space icon_state = "syndicate_space_knife" @@ -128,13 +129,11 @@ return ..() /mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj) - if(!Proj) - return - if(prob(50)) + if(prob(projectile_deflect_chance)) return ..() else visible_message("[src] blocks [Proj] with its shield!") - return 0 + return BULLET_ACT_BLOCK /mob/living/simple_animal/hostile/syndicate/melee/sword/space icon_state = "syndicate_space_sword" diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 6f2120fcb64..11c35a9e4be 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -337,7 +337,7 @@ //Bullets /mob/living/simple_animal/parrot/bullet_act(obj/item/projectile/Proj) - ..() + . = ..() if(!stat && !client) if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched @@ -347,8 +347,6 @@ //parrot_been_shot += 5 icon_state = icon_living drop_held_item(0) - return - /* * AI - Not really intelligent, but I'm calling it AI anyway. diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 1b0d7effc46..ac25431ae2e 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -219,15 +219,13 @@ return ..() //Heals them /mob/living/simple_animal/slime/bullet_act(obj/item/projectile/Proj) - if(!Proj) - return attacked += 10 if((Proj.damage_type == BURN)) adjustBruteLoss(-abs(Proj.damage)) //fire projectiles heals slimes. Proj.on_hit(src) else - ..(Proj) - return 0 + . = ..(Proj) + . = . || BULLET_ACT_BLOCK /mob/living/simple_animal/slime/emp_act(severity) . = ..() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 50228c8310b..be049bbed77 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -1,18 +1,6 @@ /mob/CanPass(atom/movable/mover, turf/target) return TRUE //There's almost no cases where non /living mobs should be used in game as actual mobs, other than ghosts. -/mob/living/CanPass(atom/movable/mover, turf/target) - if((mover.pass_flags & PASSMOB)) - return TRUE - if(istype(mover, /obj/item/projectile) || mover.throwing) - return (!density || !(mobility_flags & MOBILITY_STAND)) - if(buckled == mover) - return TRUE - if(ismob(mover)) - if (mover in buckled_mobs) - return TRUE - return (!mover.density || !density || !(mobility_flags & MOBILITY_STAND)) - //DO NOT USE THIS UNLESS YOU ABSOLUTELY HAVE TO. THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM. //See mob_movespeed.dm /mob/proc/movement_delay() //update /living/movement_delay() if you change this diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index a6808736421..f9e02fd9097 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -79,7 +79,7 @@ addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, get_turf(src), 2, 3, 4, 8), 100) // Not a normal explosion. /obj/machinery/power/rtg/abductor/bullet_act(obj/item/projectile/Proj) - ..() + . = ..() if(!going_kaboom && istype(Proj) && !Proj.nodamage && ((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))) log_bomber(Proj.firer, "triggered a", src, "explosion via projectile") overload() diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 34346a1629b..e94f35f0f11 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -161,7 +161,7 @@ field_generator power level display if(Proj.flag != "bullet") power = min(power + Proj.damage, field_generator_max_power) check_power_level() - ..() + . = ..() /obj/machinery/field/generator/Destroy() @@ -336,7 +336,7 @@ field_generator power level display message_admins("A singulo exists and a containment field has failed at [ADMIN_VERBOSEJMP(T)].") investigate_log("has failed whilst a singulo exists at [AREACOORD(T)].", INVESTIGATE_SINGULO) O.last_warning = world.time - + move_resist = initial(move_resist) /obj/machinery/field/generator/shock(mob/living/user) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index f06f4ed816c..751ee7a8a52 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -113,7 +113,8 @@ /obj/singularity/bullet_act(obj/item/projectile/P) - return 0 //Will there be an impact? Who knows. Will we see it? No. + qdel(P) + return BULLET_ACT_HIT //Will there be an impact? Who knows. Will we see it? No. /obj/singularity/Bump(atom/A) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 6cae62e2408..92e7c7e6b5d 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -489,7 +489,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) has_been_powered = TRUE else if(takes_damage) damage += Proj.damage * config_bullet_energy - return FALSE + return BULLET_ACT_HIT /obj/machinery/power/supermatter_crystal/singularity_act() var/gain = 100 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 680982effc2..06e0d2f4119 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -219,6 +219,7 @@ /obj/item/projectile/Bump(atom/A) var/datum/point/pcache = trajectory.copy_to() + var/turf/T = get_turf(A) if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max) ricochets++ if(A.handle_ricochet(src)) @@ -233,11 +234,11 @@ var/mob/checking = firer if((A == firer) || (((A in firer.buckled_mobs) || (istype(checking) && (A == checking.buckled))) && (A != original)) || (A == firer.loc && ismecha(A))) //cannot shoot yourself or your mech trajectory_ignore_forcemove = TRUE - forceMove(get_turf(A)) + forceMove(T) trajectory_ignore_forcemove = FALSE return FALSE - var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. + var/distance = get_dist(T, starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. if(isturf(A) && hitsound_wall) @@ -246,50 +247,66 @@ volume = 5 playsound(loc, hitsound_wall, volume, 1, -1) - if(!prehit(A)) - return FALSE + return process_hit(T, select_target(T, A)) - var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null - if(permutation == -1) // the bullet passes through a dense object! +#define QDEL_SELF 1 //Delete if we're not UNSTOPPABLE flagged non-temporarily +#define DO_NOT_QDEL 2 //Pass through. +#define FORCE_QDEL 3 //Force deletion. + +/obj/item/projectile/proc/process_hit(turf/T, atom/target, qdel_self, hit_something = FALSE) //probably needs to be reworked entirely when pixel movement is done. + if(QDELETED(src) || !T || !target) //We're done, nothing's left. + if((qdel_self == FORCE_QDEL) || ((qdel_self == QDEL_SELF) && !temporary_unstoppable_movement && !CHECK_BITFIELD(movement_type, UNSTOPPABLE))) + qdel(src) + return hit_something + permutated |= target //Make sure we're never hitting it again. If we ever run into weirdness with piercing projectiles needing to hit something multiple times.. well.. that's a to-do. + if(!prehit(target)) + return process_hit(T, select_target(T), qdel_self, hit_something) //Hit whatever else we can since that didn't work. + var/result = target.bullet_act(src, def_zone) + if(result == BULLET_ACT_FORCE_PIERCE) if(!CHECK_BITFIELD(movement_type, UNSTOPPABLE)) temporary_unstoppable_movement = TRUE ENABLE_BITFIELD(movement_type, UNSTOPPABLE) - if(A) - permutated.Add(A) - return FALSE - else - var/atom/alt = select_target(A) - if(alt) - if(!prehit(alt)) - return FALSE - alt.bullet_act(src, def_zone) - if(!CHECK_BITFIELD(movement_type, UNSTOPPABLE)) + return process_hit(T, select_target(T), qdel_self, TRUE) //Hit whatever else we can since we're piercing through but we're still on the same tile. + else if(result == BULLET_ACT_TURF) //We hit the turf but instead we're going to also hit something else on it. + return process_hit(T, select_target(T), QDEL_SELF, TRUE) + else //Whether it hit or blocked, we're done! + qdel_self = QDEL_SELF + hit_something = TRUE + if((qdel_self == FORCE_QDEL) || ((qdel_self == QDEL_SELF) && !temporary_unstoppable_movement && !CHECK_BITFIELD(movement_type, UNSTOPPABLE))) qdel(src) - return TRUE + return hit_something -/obj/item/projectile/Move() - . = ..() - if(temporary_unstoppable_movement) - DISABLE_BITFIELD(movement_type, UNSTOPPABLE) +#undef QDEL_SELF +#undef DO_NOT_QDEL +#undef FORCE_QDEL -/obj/item/projectile/proc/select_target(atom/A) //Selects another target from a wall if we hit a wall. - if(!A || !A.density || (A.flags_1 & ON_BORDER_1) || ismob(A) || A == original) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs or machines/structures on that tile. - return - var/turf/T = get_turf(A) - if(original in T) +/obj/item/projectile/proc/select_target(turf/T, atom/target) //Select a target from a turf. + if((original in T) && can_hit_target(original, permutated, TRUE, TRUE)) return original - var/list/mob/living/possible_mobs = typecache_filter_list(T, GLOB.typecache_mob) - A + if(target && can_hit_target(target, permutated, target == original, TRUE)) + return target + var/list/mob/living/possible_mobs = typecache_filter_list(T, GLOB.typecache_mob) var/list/mob/mobs = list() for(var/mob/living/M in possible_mobs) - if(!(M.mobility_flags & MOBILITY_STAND)) + if(!can_hit_target(M, permutated, M == original, TRUE)) continue mobs += M var/mob/M = safepick(mobs) if(M) return M.lowest_buckled_mob() - var/obj/O = safepick(typecache_filter_list(T, GLOB.typecache_machine_or_structure) - A) + var/list/obj/possible_objs = typecache_filter_list(T, GLOB.typecache_machine_or_structure) + var/list/obj/objs = list() + for(var/obj/O in possible_objs) + if(!can_hit_target(O, permutated, O == original, TRUE)) + continue + objs += O + var/obj/O = safepick(objs) if(O) return O + //Nothing else is here that we can hit, hit the turf if we haven't. + if(!(T in permutated) && can_hit_target(T, permutated, T == original, TRUE)) + return T + //Returns null if nothing at all was found. /obj/item/projectile/proc/check_ricochet() if(prob(ricochet_chance)) @@ -480,8 +497,6 @@ else if(T != loc) step_towards(src, T) hitscan_last = loc - if(can_hit_target(original, permutated)) - Bump(original) if(!hitscanning && !forcemoved) pixel_x = trajectory.return_px() - trajectory.mpx * trajectory_multiplier * SSprojectiles.global_iterations_per_move pixel_y = trajectory.return_py() - trajectory.mpy * trajectory_multiplier * SSprojectiles.global_iterations_per_move @@ -510,8 +525,25 @@ homing_offset_y = -homing_offset_y //Returns true if the target atom is on our current turf and above the right layer -/obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough) - return (target && ((target.layer >= PROJECTILE_HIT_THRESHHOLD_LAYER) || ismob(target)) && (loc == get_turf(target)) && (!(target in passthrough))) +//If direct target is true it's the originally clicked target. +/obj/item/projectile/proc/can_hit_target(atom/target, list/passthrough, direct_target = FALSE, ignore_loc = FALSE) + if(QDELETED(target)) + return FALSE + if(!ignore_loc && (loc != target.loc)) + return FALSE + if(target in passthrough) + return FALSE + if(target.density) //This thing blocks projectiles, hit it regardless of layer/mob stuns/etc. + return TRUE + if(!isliving(target)) + if(target.layer < PROJECTILE_HIT_THRESHHOLD_LAYER) + return FALSE + else + var/mob/living/L = target + if(!direct_target) + if(!CHECK_BITFIELD(L.mobility_flags, MOBILITY_USE | MOBILITY_STAND | MOBILITY_MOVE) || !(L.stat == CONSCIOUS)) //If they're able to 1. stand or 2. use items or 3. move, AND they are not softcrit, they are not stunned enough to dodge projectiles passing over. + return FALSE + return TRUE //Spread is FORCED! /obj/item/projectile/proc/preparePixelProjectile(atom/target, atom/source, params, spread = 0) @@ -576,13 +608,17 @@ . = ..() if(isliving(AM) && !(pass_flags & PASSMOB)) var/mob/living/L = AM - if(AM == original) //specific aiming for - Bump(AM) - if(AM.density) //blocks projectiles - Bump(AM) - if((L.mobility_flags & MOBILITY_USE|MOBILITY_STAND|MOBILITY_MOVE) & (MOBILITY_USE|MOBILITY_MOVE)) //If they're either able to move or use items, while crawling, they're not stunned enough to avoid projectiles. + if(can_hit_target(L, permutated, (AM == original))) Bump(AM) +/obj/item/projectile/Move(atom/newloc, dir = NONE) + . = ..() + if(.) + if(temporary_unstoppable_movement) + DISABLE_BITFIELD(movement_type, UNSTOPPABLE) + if(fired && can_hit_target(original, permutated, TRUE)) + Bump(original) + /obj/item/projectile/Destroy() if(hitscan) finalize_hitscan_and_generate_tracers() diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 0870c1dbbbe..e5559cace6f 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -81,7 +81,7 @@ boom() /obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P) - ..() + . = ..() if(!QDELETED(src)) //wasn't deleted by the projectile's effects. if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE))) log_bomber(P.firer, "detonated a", src, "via projectile") diff --git a/code/modules/spells/spell_types/ethereal_jaunt.dm b/code/modules/spells/spell_types/ethereal_jaunt.dm index 7d2c7a8e0ec..32aa247a23f 100644 --- a/code/modules/spells/spell_types/ethereal_jaunt.dm +++ b/code/modules/spells/spell_types/ethereal_jaunt.dm @@ -99,5 +99,6 @@ /obj/effect/dummy/phased_mob/spell_jaunt/ex_act(blah) return + /obj/effect/dummy/phased_mob/spell_jaunt/bullet_act(blah) - return + return BULLET_ACT_FORCE_PIERCE diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm index f80c74fec71..a3afdba9ecd 100644 --- a/code/modules/spells/spell_types/shadow_walk.dm +++ b/code/modules/spells/spell_types/shadow_walk.dm @@ -91,7 +91,7 @@ return /obj/effect/dummy/phased_mob/shadow/bullet_act() - return + return BULLET_ACT_FORCE_PIERCE /obj/effect/dummy/phased_mob/shadow/singularity_act() return