diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 51579b4d88d..a579a787eda 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -70,6 +70,7 @@ // /atom/movable signals #define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) #define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) +#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable) #define COMSIG_MOVABLE_COLLIDE "movable_collide" //from base of atom/movable/Collide(): (/atom) #define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom, throwingdatum) #define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force) diff --git a/code/datums/components/swarming.dm b/code/datums/components/swarming.dm new file mode 100644 index 00000000000..ee7bee30e46 --- /dev/null +++ b/code/datums/components/swarming.dm @@ -0,0 +1,44 @@ +/datum/component/swarming + var/offset_x = 0 + var/offset_y = 0 + var/is_swarming = FALSE + var/list/swarm_members = list() + +/datum/component/swarming/Initialize(max_x = 24, max_y = 24) + offset_x = rand(-max_x, max_x) + offset_y = rand(-max_y, max_y) + + RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/join_swarm) + RegisterSignal(COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm) + +/datum/component/swarming/proc/join_swarm(atom/movable/AM) + GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM) + if(!other_swarm) + return + swarm() + swarm_members |= other_swarm + other_swarm.swarm() + other_swarm.swarm_members |= src + +/datum/component/swarming/proc/leave_swarm(atom/movable/AM) + GET_COMPONENT_FROM(other_swarm, /datum/component/swarming, AM) + if(!other_swarm || !other_swarm in swarm_members) + return + swarm_members -= other_swarm + if(!swarm_members.len) + unswarm() + other_swarm.swarm_members -= src + if(!other_swarm.swarm_members.len) + other_swarm.unswarm() + +/datum/component/swarming/proc/swarm() + var/atom/movable/owner = parent + if(!is_swarming) + is_swarming = TRUE + animate(owner, pixel_x = owner.pixel_x + offset_x, pixel_y = owner.pixel_y + offset_y, time = 2) + +/datum/component/swarming/proc/unswarm() + var/atom/movable/owner = parent + if(is_swarming) + animate(owner, pixel_x = owner.pixel_x - offset_x, pixel_y = owner.pixel_y - offset_y, time = 2) + is_swarming = FALSE \ No newline at end of file diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 957ee01a6a9..1a78a3b870e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -292,6 +292,8 @@ /atom/movable/Crossed(atom/movable/AM, oldloc) SendSignal(COMSIG_MOVABLE_CROSSED, AM) +/atom/movable/Uncrossed(atom/movable/AM) + SendSignal(COMSIG_MOVABLE_UNCROSSED, AM) //This is tg's equivalent to the byond bump, it used to be called bump with a second arg //to differentiate it, naturally everyone forgot about this immediately and so some things @@ -531,7 +533,7 @@ return -/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && (visual_effect_icon || used_item)) do_item_attack_animation(A, visual_effect_icon, used_item) @@ -539,9 +541,6 @@ return //don't do an animation if attacking self var/pixel_x_diff = 0 var/pixel_y_diff = 0 - var/final_pixel_y = initial(pixel_y) - if(end_pixel_y) - final_pixel_y = end_pixel_y var/direction = get_dir(src, A) if(direction & NORTH) @@ -555,7 +554,7 @@ pixel_x_diff = -8 animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) - animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2) + animate(src, pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, time = 2) /atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item) var/image/I diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index bb0eb3c2e76..cb22b3fe546 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -319,7 +319,7 @@ if(L) L.ratvar_act() -/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect) if(selected) used_item = selected diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 83d24a26eee..723852f162a 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -99,10 +99,11 @@ . = ..() /obj/structure/spider/spiderling/Initialize() + . = ..() pixel_x = rand(6,-6) pixel_y = rand(6,-6) START_PROCESSING(SSobj, src) - . = ..() + AddComponent(/datum/component/swarming) /obj/structure/spider/spiderling/hunter grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index 36ed5ec8840..6c42e687a9c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -62,7 +62,7 @@ -/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && !visual_effect_icon) visual_effect_icon = ATTACK_EFFECT_CLAW ..() diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index 62c00ca8ed5..c3cee567a24 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -25,7 +25,7 @@ new /datum/forced_movement(src, get_step_away(user,src, 30), 1) return 1 -/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && !visual_effect_icon) visual_effect_icon = ATTACK_EFFECT_BITE ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 560d28a66b9..4630279a607 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -699,7 +699,7 @@ clear_alert("weightless") else throw_alert("weightless", /obj/screen/alert/weightless) - if(!override) + if(!override && !is_flying()) float(!has_gravity) /mob/living/float(on) @@ -712,10 +712,10 @@ animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) sleep(10) animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) - floating = 1 + floating = TRUE else if(((!on || fixed) && floating)) animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10) - floating = 0 + floating = FALSE // The src mob is trying to strip an item from someone // Override if a certain type of mob should be behave differently when stripping items (can't, for example) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 6450c13bb76..330c15efc10 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -387,9 +387,7 @@ return -/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) - if(A != src) - end_pixel_y = get_standard_pixel_y_offset(lying) +/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!used_item) used_item = get_active_held_item() ..() diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 69ccee5cb3a..c945c207b93 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -134,7 +134,7 @@ adjustBruteLoss(20) return -/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) +/mob/living/simple_animal/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect) if(!no_effect && !visual_effect_icon && melee_damage_upper) if(melee_damage_upper < 10) visual_effect_icon = ATTACK_EFFECT_PUNCH diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index ef2e393a7dc..eb134463707 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -35,6 +35,7 @@ environment_smash = ENVIRONMENT_SMASH_NONE mouse_opacity = MOUSE_OPACITY_OPAQUE pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + density = FALSE mob_size = MOB_SIZE_TINY movement_type = FLYING gold_core_spawnable = HOSTILE_SPAWN @@ -56,7 +57,7 @@ /mob/living/simple_animal/hostile/poison/bees/Initialize() . = ..() generate_bee_visuals() - + AddComponent(/datum/component/swarming) /mob/living/simple_animal/hostile/poison/bees/Destroy() if(beehome) @@ -291,5 +292,5 @@ if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM)) toggle_ai(AI_ON) forceMove(beehome.drop_location()) - else + else ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 8e285c0b4cd..d5ecd0e9851 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -129,7 +129,7 @@ Difficulty: Medium INVOKE_ASYNC(src, .proc/quick_attack_loop) return TRUE -/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y) +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!used_item && !isturf(A)) used_item = miner_saw ..() diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 8cfc5784e9d..d6e061ffb16 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -160,7 +160,8 @@ desc = "A small, twin-bladed machine capable of inflicting very deadly lacerations." icon_state = "viscerator_attack" icon_living = "viscerator_attack" - pass_flags = PASSTABLE + pass_flags = PASSTABLE | PASSMOB + a_intent = INTENT_HARM health = 25 maxHealth = 25 melee_damage_lower = 15 @@ -180,3 +181,7 @@ gold_core_spawnable = HOSTILE_SPAWN del_on_death = 1 deathmessage = "is smashed into pieces!" + +/mob/living/simple_animal/hostile/viscerator/Initialize() + . = ..() + AddComponent(/datum/component/swarming) diff --git a/tgstation.dme b/tgstation.dme index a47202de4ce..5e2b591f0c1 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -328,6 +328,7 @@ #include "code\datums\components\slippery.dm" #include "code\datums\components\spooky.dm" #include "code\datums\components\squeek.dm" +#include "code\datums\components\swarming.dm" #include "code\datums\components\thermite.dm" #include "code\datums\components\wet_floor.dm" #include "code\datums\components\decals\blood.dm"