diff --git a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm index 9a6ba2b97df..1e073292fb1 100644 --- a/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm +++ b/_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm @@ -42,7 +42,7 @@ /area/ruin/unpowered/xenonest) "n" = ( /obj/structure/alien/weeds, -/mob/living/simple_animal/hostile/alien/lavaland, +/mob/living/basic/alien/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) "o" = ( @@ -60,7 +60,7 @@ /area/ruin/unpowered/xenonest) "t" = ( /obj/structure/alien/weeds, -/mob/living/simple_animal/hostile/alien/sentinel/lavaland, +/mob/living/basic/alien/sentinel/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) "u" = ( @@ -108,12 +108,12 @@ /area/ruin/unpowered/xenonest) "E" = ( /obj/structure/alien/weeds, -/mob/living/simple_animal/hostile/alien/drone/lavaland, +/mob/living/basic/alien/drone/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) "F" = ( /obj/structure/alien/weeds, -/mob/living/simple_animal/hostile/alien/queen/large/lavaland, +/mob/living/basic/alien/queen/large/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) "G" = ( @@ -135,7 +135,7 @@ /area/ruin/unpowered/xenonest) "K" = ( /obj/structure/alien/weeds/node, -/mob/living/simple_animal/hostile/alien/drone/lavaland, +/mob/living/basic/alien/drone/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) "M" = ( @@ -155,7 +155,7 @@ "Q" = ( /obj/structure/alien/weeds, /obj/effect/decal/cleanable/blood, -/mob/living/simple_animal/hostile/alien/drone/lavaland, +/mob/living/basic/alien/drone/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) "R" = ( @@ -164,7 +164,7 @@ /area/ruin/unpowered/xenonest) "X" = ( /obj/structure/alien/weeds/node, -/mob/living/simple_animal/hostile/alien/lavaland, +/mob/living/basic/alien/lavaland, /turf/simulated/floor/plating/asteroid/basalt/lava_land_surface, /area/ruin/unpowered/xenonest) diff --git a/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm b/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm index 97cf1402ced..320266f046e 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm @@ -73,7 +73,7 @@ /obj/structure/alien/weeds, /obj/structure/bed/nest, /obj/effect/decal/remains/xeno, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plating/airless, /area/ruin/space/unpowered) "v" = ( @@ -85,13 +85,13 @@ /area/space/nearstation) "F" = ( /obj/structure/alien/weeds/node, -/mob/living/simple_animal/hostile/alien/maid, +/mob/living/basic/alien/maid, /turf/simulated/floor/plating/airless, /area/ruin/space/unpowered) "G" = ( /obj/structure/alien/weeds, /obj/structure/bed/nest, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plating/airless, /area/ruin/space/unpowered) "I" = ( @@ -104,7 +104,7 @@ /obj/structure/alien/weeds, /obj/structure/bed/nest, /obj/effect/decal/remains/human, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plating/airless, /area/ruin/space/unpowered) diff --git a/_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm b/_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm index 7277cfc6a9f..0b67401fe01 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm @@ -57,7 +57,7 @@ /area/ruin/space/moonbase19) "aj" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plating{ icon_state = "asteroidplating" }, @@ -1859,7 +1859,7 @@ /area/ruin/space/moonbase19) "gh" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "gi" = ( @@ -2140,7 +2140,7 @@ /area/ruin/space/moonbase19) "hc" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -2583,7 +2583,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel{ icon_state = "white"; dir = 8 @@ -2739,7 +2739,7 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel{ dir = 1; icon_state = "caution" @@ -3062,7 +3062,7 @@ /area/ruin/space/moonbase19) "jC" = ( /obj/effect/mapping_helpers/turfs/damage, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plating, /area/ruin/space/moonbase19) "jD" = ( @@ -3517,7 +3517,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "lc" = ( @@ -3983,7 +3983,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "mW" = ( @@ -4251,7 +4251,7 @@ /obj/machinery/light/small{ dir = 1 }, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "nZ" = ( @@ -4309,7 +4309,7 @@ /obj/structure/cable{ icon_state = "1-2" }, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "on" = ( @@ -4327,7 +4327,7 @@ }, /area/ruin/space/moonbase19) "op" = ( -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -4773,7 +4773,7 @@ /area/ruin/space/moonbase19) "qc" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/simulated/floor/plasteel{ icon_state = "caution"; dir = 8 @@ -5700,7 +5700,7 @@ /area/ruin/space/moonbase19) "uf" = ( /obj/structure/window/reinforced, -/mob/living/simple_animal/hostile/alien/drone, +/mob/living/basic/alien/drone, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -6963,7 +6963,7 @@ }, /area/ruin/space/moonbase19) "Aj" = ( -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "Ak" = ( @@ -7925,7 +7925,7 @@ pixel_x = -1; pixel_y = -5 }, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /obj/structure/cable{ icon_state = "4-8" }, @@ -8085,7 +8085,7 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/supply{ dir = 4 }, -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "Fe" = ( @@ -8158,7 +8158,7 @@ /area/ruin/space/moonbase19) "Ft" = ( /obj/effect/turf_decal/stripes/corner, -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /obj/effect/decal/cleanable/blood/splatter, /turf/simulated/floor/plasteel{ dir = 5; @@ -8322,7 +8322,7 @@ /obj/structure/railing/cap{ dir = 9 }, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel{ dir = 5; icon_state = "cafeteria" @@ -10451,7 +10451,7 @@ /turf/simulated/floor/carpet, /area/ruin/space/moonbase19) "Qk" = ( -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "Ql" = ( @@ -11119,7 +11119,7 @@ /area/ruin/space/moonbase19) "Tr" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel{ icon_state = "white"; dir = 8 @@ -11429,7 +11429,7 @@ }, /area/ruin/space/moonbase19) "UD" = ( -/mob/living/simple_animal/hostile/alien/drone, +/mob/living/basic/alien/drone, /turf/simulated/floor/plasteel, /area/ruin/space/moonbase19) "UF" = ( @@ -12275,7 +12275,7 @@ "Yu" = ( /obj/structure/toilet/directional/north, /obj/effect/decal/cleanable/vomit/green, -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/simulated/floor/plasteel{ icon_state = "freezerfloor" }, @@ -12342,7 +12342,7 @@ /obj/structure/railing{ dir = 8 }, -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/simulated/floor/catwalk, /area/ruin/space/moonbase19) "YL" = ( @@ -12424,7 +12424,7 @@ /area/ruin/space/moonbase19) "Zf" = ( /obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien/queen/large{ +/mob/living/basic/alien/queen/large{ melee_damage_upper = 35; melee_damage_lower = 30 }, @@ -12527,7 +12527,7 @@ "Zw" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /obj/machinery/atmospherics/pipe/simple/hidden/supply, -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /obj/structure/cable{ icon_state = "1-2" }, diff --git a/_maps/map_files/RandomRuins/SpaceRuins/submaps/telecomns_returns_submap.dmm b/_maps/map_files/RandomRuins/SpaceRuins/submaps/telecomns_returns_submap.dmm index 494b8068d6f..dc8bea108bf 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/submaps/telecomns_returns_submap.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/submaps/telecomns_returns_submap.dmm @@ -10,14 +10,14 @@ /turf/simulated/floor/engine, /area/template_noop) "cl" = ( -/mob/living/simple_animal/hostile/alien/queen/large, +/mob/living/basic/alien/queen/large, /turf/template_noop, /area/template_noop) "da" = ( /turf/simulated/wall/mineral/plastitanium/nodiagonal, /area/template_noop) "dD" = ( -/mob/living/simple_animal/hostile/alien/sentinel, +/mob/living/basic/alien/sentinel, /turf/template_noop, /area/template_noop) "fm" = ( @@ -369,7 +369,7 @@ /turf/template_noop, /area/template_noop) "RE" = ( -/mob/living/simple_animal/hostile/alien/drone, +/mob/living/basic/alien/drone, /turf/template_noop, /area/template_noop) "RH" = ( @@ -387,7 +387,7 @@ /turf/simulated/floor/mineral/plastitanium/red, /area/template_noop) "Ul" = ( -/mob/living/simple_animal/hostile/alien, +/mob/living/basic/alien, /turf/template_noop, /area/template_noop) "Vd" = ( diff --git a/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm b/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm index e9985212a92..736647381b7 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm @@ -391,27 +391,6 @@ icon_state = "floorgrime" }, /area/ruin/space/syndicakefactory) -"qx" = ( -/obj/effect/decal/cleanable/dirt, -/mob/living/simple_animal/hostile/alien/sentinel{ - animal_species = /mob/living/simple_animal/pet/dog; - attack_sound = 'sound/weapons/bite.ogg'; - attacktext = "bites"; - damage_coeff = list("brute" = 1, "fire" = 1, "tox" = 1, "clone" = 1, "stamina" = 1, "oxy" = 1); - death_sound = null; - deathmessage = ""; - desc = "This is no longer a goodboy. Not anymore. He has seen too much."; - icon = 'icons/mob/pets.dmi'; - icon_living = "corgi"; - icon_state = "corgi"; - name = "angry corgi"; - retreat_distance = 2; - icon_dead = "corgi_dead" - }, -/turf/simulated/floor/plasteel{ - icon_state = "cafeteria" - }, -/area/ruin/space/syndicakefactory) "qX" = ( /obj/machinery/conveyor/east{ id = "garbage"; @@ -1016,6 +995,12 @@ icon_state = "floorgrime" }, /area/ruin/space/syndicakefactory) +"MK" = ( +/mob/living/basic/alien/sentinel/corgi, +/turf/simulated/floor/plasteel{ + icon_state = "cafeteria" + }, +/area/ruin/space/syndicakefactory) "MV" = ( /obj/structure/table/glass/reinforced/plastitanium, /obj/item/storage/box/papersack{ @@ -1101,26 +1086,6 @@ }, /turf/simulated/floor/engine/airless, /area/ruin/space/syndicakefactory) -"OU" = ( -/mob/living/simple_animal/hostile/alien/sentinel{ - animal_species = /mob/living/simple_animal/pet/dog; - attack_sound = 'sound/weapons/bite.ogg'; - attacktext = "bites"; - damage_coeff = list("brute" = 1, "fire" = 1, "tox" = 1, "clone" = 1, "stamina" = 1, "oxy" = 1); - death_sound = null; - deathmessage = ""; - desc = "This is no longer a goodboy. Not anymore. He has seen too much."; - icon = 'icons/mob/pets.dmi'; - icon_living = "corgi"; - icon_state = "corgi"; - name = "angry corgi"; - retreat_distance = 2; - icon_dead = "corgi_dead" - }, -/turf/simulated/floor/plasteel{ - icon_state = "cafeteria" - }, -/area/ruin/space/syndicakefactory) "PH" = ( /obj/structure/railing, /turf/simulated/floor/plasteel{ @@ -1298,21 +1263,7 @@ }, /area/ruin/space/syndicakefactory) "YR" = ( -/mob/living/simple_animal/hostile/alien/sentinel{ - animal_species = /mob/living/simple_animal/pet/dog; - attack_sound = 'sound/weapons/bite.ogg'; - attacktext = "bites"; - damage_coeff = list("brute" = 1, "fire" = 1, "tox" = 1, "clone" = 1, "stamina" = 1, "oxy" = 1); - death_sound = null; - deathmessage = ""; - desc = "This is no longer a goodboy. Not anymore. He has seen too much."; - icon = 'icons/mob/pets.dmi'; - icon_living = "corgi"; - icon_state = "corgi"; - name = "angry corgi"; - retreat_distance = 2; - icon_dead = "corgi_dead" - }, +/mob/living/basic/alien/sentinel/corgi, /turf/simulated/floor/grass, /area/ruin/space/syndicakefactory) "Zs" = ( @@ -1675,7 +1626,7 @@ oB bn bn Iz -qx +oB Kr bG TM @@ -1716,7 +1667,7 @@ Vt gx DY XZ -bn +MK bG uA bG @@ -1794,7 +1745,7 @@ wC bn Qv oB -bn +MK bn bn bn @@ -1802,9 +1753,9 @@ oB bn bn Kr -bn +MK yV -OU +bn oB RO wI @@ -1830,7 +1781,7 @@ EJ EJ rJ bn -OU +bn bn oH EJ diff --git a/code/__DEFINES/ai/blackboard_defines.dm b/code/__DEFINES/ai/blackboard_defines.dm index cf9f76fd1dd..27c543720d5 100644 --- a/code/__DEFINES/ai/blackboard_defines.dm +++ b/code/__DEFINES/ai/blackboard_defines.dm @@ -165,6 +165,9 @@ // Misc +/// Target define for cleaning +#define BB_CLEAN_TARGET "BB_clean_target" + /// For /datum/ai_behavior/find_potential_targets, what if any field are we using currently #define BB_FIND_TARGETS_FIELD(type) "BB_FIND_TARGETS_FIELD_[type]" diff --git a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm index a99be14545f..fcd8e460392 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm @@ -19,7 +19,7 @@ /// How often will we try to perform our ranged attack? /datum/ai_behavior/ranged_skirmish action_cooldown = 0.5 SECONDS - ///do we care about avoiding friendly fire? + /// Do we care about shooting friends? var/avoid_friendly_fire = FALSE /datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range) @@ -44,6 +44,8 @@ var/distance = get_dist(controller.pawn, target) if(distance > max_range || distance < min_range) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED + if(avoid_friendly_fire && check_friendly_in_path(controller.pawn, target, targeting_strategy)) + return AI_BEHAVIOR_DELAY if(avoid_friendly_fire && check_friendly_in_path(controller.pawn, target, targeting_strategy)) return AI_BEHAVIOR_DELAY diff --git a/code/datums/ai/basic_mobs/hunting_behavior/find_and_hunt_target.dm b/code/datums/ai/basic_mobs/hunting_behavior/find_and_hunt_target.dm index 6aae13f7b4b..77aeef11270 100644 --- a/code/datums/ai/basic_mobs/hunting_behavior/find_and_hunt_target.dm +++ b/code/datums/ai/basic_mobs/hunting_behavior/find_and_hunt_target.dm @@ -50,3 +50,10 @@ hunt_targets = list(/obj/item/stack/ore) hunt_chance = 90 hunt_range = 9 + +/// Find and clean things +/datum/ai_planning_subtree/find_and_hunt_target/clean + target_key = BB_CLEAN_TARGET + hunting_behavior = /datum/ai_behavior/hunt_target/interact_with_target/clean + hunt_targets = list(/obj/effect/decal/cleanable) + hunt_range = 4 diff --git a/code/datums/ai/basic_mobs/hunting_behavior/hunt_target.dm b/code/datums/ai/basic_mobs/hunting_behavior/hunt_target.dm index 4de9964d17b..8673b3addec 100644 --- a/code/datums/ai/basic_mobs/hunting_behavior/hunt_target.dm +++ b/code/datums/ai/basic_mobs/hunting_behavior/hunt_target.dm @@ -61,3 +61,8 @@ always_reset_target = TRUE hunt_cooldown = 2 SECONDS behavior_intent = INTENT_HELP + +/datum/ai_behavior/hunt_target/interact_with_target/clean + always_reset_target = TRUE + hunt_cooldown = 2 SECONDS + behavior_intent = INTENT_HELP diff --git a/code/modules/mob/living/basic/basic_mob.dm b/code/modules/mob/living/basic/basic_mob.dm index edc91d3a2c7..0bf5f76c411 100644 --- a/code/modules/mob/living/basic/basic_mob.dm +++ b/code/modules/mob/living/basic/basic_mob.dm @@ -162,7 +162,6 @@ RESTRICT_TYPE(/mob/living/basic) var/ranged_burst_interval = 0.2 SECONDS /// Time between bursts var/ranged_cooldown = 2 SECONDS - /// What casing type is the projectile? var/casing_type /// What projectile do we shoot? diff --git a/code/modules/mob/living/basic/hostile/alien/alien_mob_ai.dm b/code/modules/mob/living/basic/hostile/alien/alien_mob_ai.dm new file mode 100644 index 00000000000..9c85b7ffa74 --- /dev/null +++ b/code/modules/mob/living/basic/hostile/alien/alien_mob_ai.dm @@ -0,0 +1,91 @@ +/datum/ai_controller/basic_controller/alien + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + ) + + planning_subtrees = list( + /datum/ai_planning_subtree/random_speech/alien, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + ai_traits = AI_FLAG_PAUSE_DURING_DO_AFTER + movement_delay = 0.8 SECONDS + +/datum/ai_controller/basic_controller/alien/sentinel + planning_subtrees = list( + /datum/ai_planning_subtree/random_speech/alien, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/maintain_distance, + /datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic, + /datum/ai_planning_subtree/ranged_skirmish, + ) + +/datum/ai_controller/basic_controller/alien/corgi + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/maintain_distance, + /datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic, + /datum/ai_planning_subtree/ranged_skirmish, + ) + +/datum/ai_controller/basic_controller/alien/drone + idle_behavior = /datum/idle_behavior/idle_random_walk/plant_weeds + +/datum/ai_controller/basic_controller/alien/queen + idle_behavior = /datum/idle_behavior/idle_random_walk/plant_weeds/queen + + planning_subtrees = list( + /datum/ai_planning_subtree/random_speech/alien, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/maintain_distance, + /datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic, + /datum/ai_planning_subtree/ranged_skirmish, + ) + +/datum/ai_controller/basic_controller/alien/maid + planning_subtrees = list( + /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee, + /datum/ai_planning_subtree/flee_target, + /datum/ai_planning_subtree/find_and_hunt_target/clean, + ) + +/** + * Alien projectile + * Try to avoid friendly fire, and has a 3 second delay. + */ + +/datum/idle_behavior/idle_random_walk/plant_weeds + var/plant_cooldown = 30 + var/plants_off = 0 + +/datum/idle_behavior/idle_random_walk/plant_weeds/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) + . = ..() + if(!.) + return . + plant_cooldown-- + var/mob/living/basic/alien/alien_pawn = controller.pawn + if(alien_pawn.can_plant_weeds && !plants_off && plant_cooldown <= 0) + plant_cooldown = initial(plant_cooldown) + alien_pawn.spread_plants() + +/datum/idle_behavior/idle_random_walk/plant_weeds/queen + var/eggs_off = 0 + var/egg_cooldown = 30 + +/datum/idle_behavior/idle_random_walk/plant_weeds/queen/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) + . = ..() + if(!.) + return . + egg_cooldown-- + var/mob/living/basic/alien/alien_pawn = controller.pawn + if(alien_pawn.can_lay_eggs && !eggs_off && egg_cooldown <= 0) + egg_cooldown = initial(egg_cooldown) + alien_pawn.lay_eggs() + +/datum/ai_planning_subtree/random_speech/alien + speech_chance = 2 + sound = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg') + emote_hear = list("hisses.") diff --git a/code/modules/mob/living/basic/hostile/alien/alien_mob_drone.dm b/code/modules/mob/living/basic/hostile/alien/alien_mob_drone.dm new file mode 100644 index 00000000000..ac6ea807e8d --- /dev/null +++ b/code/modules/mob/living/basic/hostile/alien/alien_mob_drone.dm @@ -0,0 +1,12 @@ +/mob/living/basic/alien/drone + name = "alien drone" + icon_state = "aliend_running" + icon_living = "aliend_running" + icon_dead = "aliend_dead" + melee_damage_lower = 15 + melee_damage_upper = 15 + + ai_controller = /datum/ai_controller/basic_controller/alien/drone + +/mob/living/basic/alien/drone/lavaland + maximum_survivable_temperature = INFINITY diff --git a/code/modules/mob/living/basic/hostile/alien/alien_mob_hunter.dm b/code/modules/mob/living/basic/hostile/alien/alien_mob_hunter.dm new file mode 100644 index 00000000000..590d46fcb7d --- /dev/null +++ b/code/modules/mob/living/basic/hostile/alien/alien_mob_hunter.dm @@ -0,0 +1,71 @@ +/mob/living/basic/alien + name = "alien hunter" + desc = "Hiss!" + icon = 'icons/mob/alien.dmi' + icon_state = "alienh_running" + icon_living = "alienh_running" + icon_dead = "alienh_dead" + icon_gib = "syndicate_gib" + gender = FEMALE + speed = 0 + status_flags = CANPUSH + basic_mob_flags = FLAMMABLE_MOB + butcher_results = list(/obj/item/food/monstermeat/xenomeat= 3, /obj/item/stack/sheet/animalhide/xeno = 1) + maxHealth = 125 + health = 125 + harm_intent_damage = 5 + obj_damage = 60 + + melee_attack_cooldown_min = 1.5 SECONDS + melee_attack_cooldown_max = 2.5 SECONDS + speak_emote = list("hisses") + melee_damage_lower = 25 + melee_damage_upper = 25 + attack_verb_continuous = "slashes" + attack_verb_simple = "slash" + environment_smash = ENVIRONMENT_SMASH_STRUCTURES + + bubble_icon = "alien" + a_intent = INTENT_HARM + attack_sound = 'sound/weapons/bladeslice.ogg' + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + unsuitable_atmos_damage = 15 + unsuitable_heat_damage = 20 + faction = list("alien") + minimum_survivable_temperature = 0 + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + death_sound = 'sound/voice/hiss6.ogg' + deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw..." + step_type = FOOTSTEP_MOB_CLAW + loot = list(/obj/effect/decal/cleanable/blood/gibs/xeno/limb, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/xeno/splatter, /obj/effect/decal/cleanable/blood/gibs/xeno/body, /obj/effect/decal/cleanable/blood/gibs/xeno/down) + + ai_controller = /datum/ai_controller/basic_controller/alien + + /// Boolean on whether the xeno can plant weeds. + var/can_plant_weeds = TRUE + /// Boolean on whether the xeno can lay eggs. + var/can_lay_eggs = FALSE + +/mob/living/basic/alien/Initialize(mapload) + . = ..() + AddComponent(/datum/component/aggro_emote, emote_list = list("flutters"), emote_chance = 20) + +/mob/living/basic/alien/proc/spread_plants() + if(!isturf(loc) || isspaceturf(loc)) + return + if(locate(/obj/structure/alien/weeds/node) in get_turf(src)) + return + visible_message("[src] has planted some alien weeds!") + new /obj/structure/alien/weeds/node(loc) + +/mob/living/basic/alien/proc/lay_eggs() + if(!isturf(loc) || isspaceturf(loc)) + return + if(locate(/obj/structure/alien/egg) in get_turf(src)) + return + visible_message("[src] has laid an egg!") + new /obj/structure/alien/egg(loc) + +/mob/living/basic/alien/lavaland + maximum_survivable_temperature = INFINITY diff --git a/code/modules/mob/living/basic/hostile/alien/alien_mob_maid.dm b/code/modules/mob/living/basic/hostile/alien/alien_mob_maid.dm new file mode 100644 index 00000000000..a476d5f5b94 --- /dev/null +++ b/code/modules/mob/living/basic/hostile/alien/alien_mob_maid.dm @@ -0,0 +1,43 @@ +/mob/living/basic/alien/maid + name = "lusty xenomorph maid" + melee_damage_lower = 0 + melee_damage_upper = 0 + a_intent = INTENT_HELP + friendly_verb_continuous = "caresses" + friendly_verb_simple = "caress" + obj_damage = 0 + environment_smash = ENVIRONMENT_SMASH_NONE + gold_core_spawnable = HOSTILE_SPAWN + ai_controller = /datum/ai_controller/basic_controller/alien/maid + icon_state = "maid" + icon_living = "maid" + icon_dead = "maid_dead" + /// How fast do we clean? + var/cleanspeed = 15 + +/mob/living/basic/alien/maid/Initialize(mapload) + . = ..() + AddElement(/datum/element/ai_retaliate) + +/// Clean instead of attack. +/mob/living/basic/alien/maid/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) + . = ..() + if(!.) + return FALSE + + clean_target(target) + return FALSE + +/mob/living/basic/alien/maid/proc/clean_target(atom/target) + if(ishuman(target)) + var/atom/movable/H = target + H.clean_blood() + visible_message("\The [src] polishes \the [target].") + return FALSE + target.cleaning_act(src, src, cleanspeed, text_description = ".") // LXM is both the user and the cleaning implement itself. Wow! + +/mob/living/basic/alien/maid/can_clean() + return TRUE + +/mob/living/basic/alien/maid/lavaland + maximum_survivable_temperature = INFINITY diff --git a/code/modules/mob/living/basic/hostile/alien/alien_mob_queen.dm b/code/modules/mob/living/basic/hostile/alien/alien_mob_queen.dm new file mode 100644 index 00000000000..242441696df --- /dev/null +++ b/code/modules/mob/living/basic/hostile/alien/alien_mob_queen.dm @@ -0,0 +1,34 @@ +/mob/living/basic/alien/queen + name = "alien queen" + icon_state = "alienq_running" + icon_living = "alienq_running" + icon_dead = "alienq_dead" + health = 250 + maxHealth = 250 + melee_damage_lower = 15 + melee_damage_upper = 15 + status_flags = NONE // can't shove the queen, kiddo. + + ai_controller = /datum/ai_controller/basic_controller/alien/queen + + is_ranged = TRUE + projectile_type = /obj/item/projectile/neurotox + projectile_sound = 'sound/weapons/pierce.ogg' + ranged_cooldown = 3 SECONDS + +/mob/living/basic/alien/queen/lavaland + maximum_survivable_temperature = INFINITY + +/mob/living/basic/alien/queen/large + name = "alien empress" + icon = 'icons/mob/alienlarge.dmi' + icon_state = "queen_s" + icon_living = "queen_s" + icon_dead = "queen_dead" + bubble_icon = "alienroyal" + maxHealth = 400 + health = 400 + mob_size = MOB_SIZE_LARGE + +/mob/living/basic/alien/queen/large/lavaland + maximum_survivable_temperature = INFINITY diff --git a/code/modules/mob/living/basic/hostile/alien/alien_mob_sentinel.dm b/code/modules/mob/living/basic/hostile/alien/alien_mob_sentinel.dm new file mode 100644 index 00000000000..3514258cf9b --- /dev/null +++ b/code/modules/mob/living/basic/hostile/alien/alien_mob_sentinel.dm @@ -0,0 +1,37 @@ +/mob/living/basic/alien/sentinel + name = "alien sentinel" + icon_state = "aliens_running" + icon_living = "aliens_running" + icon_dead = "aliens_dead" + health = 150 + maxHealth = 150 + melee_damage_lower = 15 + melee_damage_upper = 15 + + ai_controller = /datum/ai_controller/basic_controller/alien/sentinel + + is_ranged = TRUE + projectile_type = /obj/item/projectile/neurotox + projectile_sound = 'sound/weapons/pierce.ogg' + ranged_cooldown = 3 SECONDS + +/mob/living/basic/alien/sentinel/corgi + name = "angry corgi" + real_name = "angry corgi" + desc = "It's a corgi." + icon_state = "corgi" + icon_living = "corgi" + icon_dead = "corgi_dead" + icon = 'icons/mob/pets.dmi'; + desc = "This is no longer a goodboy. Not anymore. He has seen too much."; + attack_sound = 'sound/weapons/bite.ogg'; + attack_verb_continuous = "bites"; + attack_verb_simple = "bites"; + damage_coeff = list("brute" = 1, "fire" = 1, "tox" = 1, "clone" = 1, "stamina" = 1, "oxy" = 1); + death_sound = null; + deathmessage = ""; + + ai_controller = /datum/ai_controller/basic_controller/alien/corgi + +/mob/living/basic/alien/sentinel/lavaland + maximum_survivable_temperature = INFINITY diff --git a/code/modules/mob/living/simple_animal/hostile/alien_types.dm b/code/modules/mob/living/simple_animal/hostile/alien_types.dm deleted file mode 100644 index ab66a947f94..00000000000 --- a/code/modules/mob/living/simple_animal/hostile/alien_types.dm +++ /dev/null @@ -1,180 +0,0 @@ -/mob/living/simple_animal/hostile/alien - name = "alien hunter" - desc = "Hiss!" - icon = 'icons/mob/alien.dmi' - icon_state = "alienh_running" - icon_living = "alienh_running" - icon_dead = "alienh_dead" - icon_gib = "syndicate_gib" - gender = FEMALE - speed = 0 - butcher_results = list(/obj/item/food/monstermeat/xenomeat= 3, /obj/item/stack/sheet/animalhide/xeno = 1) - maxHealth = 125 - health = 125 - harm_intent_damage = 5 - obj_damage = 60 - melee_damage_lower = 25 - melee_damage_upper = 25 - attacktext = "slashes" - speak_emote = list("hisses") - bubble_icon = "alien" - a_intent = INTENT_HARM - attack_sound = 'sound/weapons/bladeslice.ogg' - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - unsuitable_atmos_damage = 15 - heat_damage_per_tick = 20 - faction = list("alien") - minbodytemp = 0 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - death_sound = 'sound/voice/hiss6.ogg' - deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw..." - footstep_type = FOOTSTEP_MOB_CLAW - loot = list(/obj/effect/decal/cleanable/blood/gibs/xeno/limb, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/xeno/splatter, /obj/effect/decal/cleanable/blood/gibs/xeno/body, /obj/effect/decal/cleanable/blood/gibs/xeno/down) - -/mob/living/simple_animal/hostile/alien/ListTargetsLazy() - return ListTargets() - -/mob/living/simple_animal/hostile/alien/Aggro() - . = ..() - if(target) - playsound(loc, 'sound/voice/hiss4.ogg', 70, TRUE) - -/mob/living/simple_animal/hostile/alien/drone - name = "alien drone" - icon_state = "aliend_running" - icon_living = "aliend_running" - icon_dead = "aliend_dead" - melee_damage_lower = 15 - melee_damage_upper = 15 - var/plant_cooldown = 30 - var/plants_off = 0 - -/mob/living/simple_animal/hostile/alien/drone/handle_automated_action() - if(!..()) //AIStatus is off - return - plant_cooldown-- - if(AIStatus == AI_IDLE) - if(!plants_off && prob(10) && plant_cooldown<=0) - plant_cooldown = initial(plant_cooldown) - SpreadPlants() - -/mob/living/simple_animal/hostile/alien/sentinel - name = "alien sentinel" - icon_state = "aliens_running" - icon_living = "aliens_running" - icon_dead = "aliens_dead" - health = 150 - maxHealth = 150 - melee_damage_lower = 15 - melee_damage_upper = 15 - ranged = TRUE - retreat_distance = 5 - minimum_distance = 5 - projectiletype = /obj/item/projectile/neurotox - projectilesound = 'sound/weapons/pierce.ogg' - -/mob/living/simple_animal/hostile/alien/queen - name = "alien queen" - icon_state = "alienq_running" - icon_living = "alienq_running" - icon_dead = "alienq_dead" - health = 250 - maxHealth = 250 - melee_damage_lower = 15 - melee_damage_upper = 15 - ranged = TRUE - retreat_distance = 5 - minimum_distance = 5 - move_to_delay = 4 - butcher_results = list(/obj/item/food/monstermeat/xenomeat= 4, /obj/item/stack/sheet/animalhide/xeno = 1) - projectiletype = /obj/item/projectile/neurotox - projectilesound = 'sound/weapons/pierce.ogg' - status_flags = 0 - var/sterile = 1 - var/plants_off = 0 - var/egg_cooldown = 30 - var/plant_cooldown = 30 - -/mob/living/simple_animal/hostile/alien/queen/handle_automated_action() - if(!..()) - return - egg_cooldown-- - plant_cooldown-- - if(AIStatus == AI_IDLE) - if(!plants_off && prob(10) && plant_cooldown<=0) - plant_cooldown = initial(plant_cooldown) - SpreadPlants() - if(!sterile && prob(10) && egg_cooldown<=0) - egg_cooldown = initial(egg_cooldown) - LayEggs() - -/mob/living/simple_animal/hostile/alien/proc/SpreadPlants() - if(!isturf(loc) || isspaceturf(loc)) - return - if(locate(/obj/structure/alien/weeds/node) in get_turf(src)) - return - visible_message("[src] has planted some alien weeds!") - new /obj/structure/alien/weeds/node(loc) - -/mob/living/simple_animal/hostile/alien/proc/LayEggs() - if(!isturf(loc) || isspaceturf(loc)) - return - if(locate(/obj/structure/alien/egg) in get_turf(src)) - return - visible_message("[src] has laid an egg!") - new /obj/structure/alien/egg(loc) - -/mob/living/simple_animal/hostile/alien/queen/large - name = "alien empress" - icon = 'icons/mob/alienlarge.dmi' - icon_state = "queen_s" - icon_living = "queen_s" - icon_dead = "queen_dead" - bubble_icon = "alienroyal" - maxHealth = 400 - health = 400 - butcher_results = list(/obj/item/food/monstermeat/xenomeat= 10, /obj/item/stack/sheet/animalhide/xeno = 2) - mob_size = MOB_SIZE_LARGE - -/obj/item/projectile/neurotox - name = "neurotoxin" - damage = 30 - icon_state = "toxin" - -/mob/living/simple_animal/hostile/alien/maid - name = "lusty xenomorph maid" - melee_damage_lower = 0 - melee_damage_upper = 0 - a_intent = INTENT_HELP - friendly = "caresses" - obj_damage = 0 - environment_smash = ENVIRONMENT_SMASH_NONE - gold_core_spawnable = HOSTILE_SPAWN - icon_state = "maid" - icon_living = "maid" - icon_dead = "maid_dead" - var/cleanspeed = 15 - -/mob/living/simple_animal/hostile/alien/maid/AttackingTarget() - if(ishuman(target)) - var/atom/movable/H = target - H.clean_blood() - visible_message("\The [src] polishes \the [target].") - return TRUE - target.cleaning_act(src, src, cleanspeed, text_description = ".") //LXM is both the user and the cleaning implement itself. Wow! - -/mob/living/simple_animal/hostile/alien/maid/can_clean() - return TRUE - -/mob/living/simple_animal/hostile/alien/lavaland - maxbodytemp = INFINITY - -/mob/living/simple_animal/hostile/alien/drone/lavaland - maxbodytemp = INFINITY - -/mob/living/simple_animal/hostile/alien/sentinel/lavaland - maxbodytemp = INFINITY - -/mob/living/simple_animal/hostile/alien/queen/large/lavaland - maxbodytemp = INFINITY diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index a1196b3a676..0893c4471c8 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -159,7 +159,7 @@ temp_img = icon('icons/obj/butts.dmi', "drone") else if(isnymph(copymob)) temp_img = icon('icons/obj/butts.dmi', "nymph") - else if(isalien(copymob) || istype(copymob,/mob/living/simple_animal/hostile/alien)) //Xenos have their own asses, thanks to Pybro. + else if(isalien(copymob) || istype(copymob,/mob/living/basic/alien)) //Xenos have their own asses, thanks to Pybro. temp_img = icon('icons/obj/butts.dmi', "xeno") else return diff --git a/code/modules/projectiles/projectile/spit.dm b/code/modules/projectiles/projectile/spit.dm new file mode 100644 index 00000000000..e61049179a2 --- /dev/null +++ b/code/modules/projectiles/projectile/spit.dm @@ -0,0 +1,4 @@ +/obj/item/projectile/neurotox + name = "neurotoxin" + damage = 30 + icon_state = "toxin" diff --git a/paradise.dme b/paradise.dme index a07f3462628..2786e0d195e 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2445,6 +2445,12 @@ #include "code\modules\mob\living\basic\hostile\hivebot_ai.dm" #include "code\modules\mob\living\basic\hostile\killertomato.dm" #include "code\modules\mob\living\basic\hostile\skeleton_mob.dm" +#include "code\modules\mob\living\basic\hostile\alien\alien_mob_ai.dm" +#include "code\modules\mob\living\basic\hostile\alien\alien_mob_drone.dm" +#include "code\modules\mob\living\basic\hostile\alien\alien_mob_hunter.dm" +#include "code\modules\mob\living\basic\hostile\alien\alien_mob_maid.dm" +#include "code\modules\mob\living\basic\hostile\alien\alien_mob_queen.dm" +#include "code\modules\mob\living\basic\hostile\alien\alien_mob_sentinel.dm" #include "code\modules\mob\living\basic\mining\basilisk.dm" #include "code\modules\mob\living\basic\mining\basilisk_ai.dm" #include "code\modules\mob\living\basic\mining\hivelord.dm" @@ -2651,7 +2657,6 @@ #include "code\modules\mob\living\simple_animal\friendly\nian_caterpillar.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" #include "code\modules\mob\living\simple_animal\friendly\spiderbot.dm" -#include "code\modules\mob\living\simple_animal\hostile\alien_types.dm" #include "code\modules\mob\living\simple_animal\hostile\angel_statue.dm" #include "code\modules\mob\living\simple_animal\hostile\bees.dm" #include "code\modules\mob\living\simple_animal\hostile\deathsquid.dm" @@ -2928,6 +2933,7 @@ #include "code\modules\projectiles\projectile\magic_projectiles.dm" #include "code\modules\projectiles\projectile\reusable.dm" #include "code\modules\projectiles\projectile\special_projectiles.dm" +#include "code\modules\projectiles\projectile\spit.dm" #include "code\modules\reagents\chem_splash.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm"