diff --git a/code/datums/components/xeno/ai_behavior_overrides/attack_override_behavior.dm b/code/datums/components/xeno/ai_behavior_overrides/attack_override_behavior.dm index 16cefe6721..30ec893db3 100644 --- a/code/datums/components/xeno/ai_behavior_overrides/attack_override_behavior.dm +++ b/code/datums/components/xeno/ai_behavior_overrides/attack_override_behavior.dm @@ -1,17 +1,21 @@ /datum/component/ai_behavior_override/attack + behavior_icon_state = "attack_order" /datum/component/ai_behavior_override/attack/check_behavior_validity(mob/living/carbon/xenomorph/checked_xeno, distance) . = ..() + if(!.) + return if(distance > 10) return FALSE return TRUE - /datum/component/ai_behavior_override/attack/process_override_behavior(mob/living/carbon/xenomorph/processing_xeno, delta_time) . = ..() + if(!.) + return if(processing_xeno.current_target == parent) return FALSE diff --git a/code/datums/components/xeno/ai_behavior_overrides/base_override_behavior.dm b/code/datums/components/xeno/ai_behavior_overrides/base_override_behavior.dm index 2a5ee7a7f5..a5bb0728de 100644 --- a/code/datums/components/xeno/ai_behavior_overrides/base_override_behavior.dm +++ b/code/datums/components/xeno/ai_behavior_overrides/base_override_behavior.dm @@ -3,14 +3,20 @@ GLOBAL_LIST_EMPTY(all_ai_behavior_overrides) /datum/component/ai_behavior_override /// Icon file for the behavior attached to parent as game masters will see it - var/behavior_icon = 'icons/landmarks.dmi' + var/behavior_icon = 'icons/effects/game_master_xeno_behaviors.dmi' /// Specific icon state for the behavior attached to parent as game masters will see it - var/behavior_icon_state = "x2" + var/behavior_icon_state = "should_not_see_this" /// The actual image holder that sits on parent for game masters var/image/behavior_image + /// The xenos currently handling this task + var/currently_assigned + + /// How many xenos we want assigned to this task at max + var/max_assigned = 3 + /datum/component/ai_behavior_override/Initialize(...) . = ..() @@ -19,7 +25,9 @@ GLOBAL_LIST_EMPTY(all_ai_behavior_overrides) behavior_image = new(behavior_icon, parent, behavior_icon_state, layer = ABOVE_FLY_LAYER) for(var/client/game_master in GLOB.game_masters) - game_master.images += behavior_image + game_master.images |= behavior_image + + currently_assigned = list() /datum/component/ai_behavior_override/Destroy(force, silent, ...) GLOB.all_ai_behavior_overrides -= src @@ -28,15 +36,21 @@ GLOBAL_LIST_EMPTY(all_ai_behavior_overrides) game_master.images -= behavior_image QDEL_NULL(behavior_image) + currently_assigned = null . = ..() /// Override this to check if we want our behavior to be valid for the checked_xeno, passes the common factor of "distance" which is the distance between the checked_xeno and src parent /datum/component/ai_behavior_override/proc/check_behavior_validity(mob/living/carbon/xenomorph/checked_xeno, distance) - return FALSE + if(length(currently_assigned) >= max_assigned && !(checked_xeno in currently_assigned)) + return FALSE + + return TRUE /// Processes what we want this behavior to do, return FALSE if we want to continue in the process_ai() proc or TRUE if we want to handle everything and have process_ai() return /datum/component/ai_behavior_override/proc/process_override_behavior(mob/living/carbon/xenomorph/processing_xeno, delta_time) SHOULD_NOT_SLEEP(TRUE) - return FALSE + currently_assigned |= processing_xeno + + return TRUE diff --git a/code/datums/components/xeno/ai_behavior_overrides/capture_override_behavior.dm b/code/datums/components/xeno/ai_behavior_overrides/capture_override_behavior.dm new file mode 100644 index 0000000000..3651ca25ed --- /dev/null +++ b/code/datums/components/xeno/ai_behavior_overrides/capture_override_behavior.dm @@ -0,0 +1,75 @@ + +/datum/component/ai_behavior_override/capture + behavior_icon_state = "capture_order" + + max_assigned = 1 + +/datum/component/ai_behavior_override/capture/Initialize(...) + . = ..() + + if(!istype(parent, /mob)) + return COMPONENT_INCOMPATIBLE + + if(isxeno(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/ai_behavior_override/capture/check_behavior_validity(mob/living/carbon/xenomorph/checked_xeno, distance) + . = ..() + if(!.) + return + + var/mob/parent_mob = parent + + var/stat = parent_mob.stat + var/mob/pulledby = parent_mob.pulledby + + if(stat == DEAD) + qdel(src) + return FALSE + + if(HAS_TRAIT(parent, TRAIT_NESTED)) + qdel(src) + return FALSE + + if(!length(GLOB.ai_hives)) + for(var/client/game_master in GLOB.game_masters) + to_chat(game_master, SPAN_XENOBOLDNOTICE("Capture behavior requires a valid hive placed")) + + qdel(src) + return FALSE + + if(distance > 10) + return FALSE + + if(stat == CONSCIOUS) + return FALSE + + if(isxeno(pulledby) && pulledby != checked_xeno) + return FALSE + + return TRUE + +/datum/component/ai_behavior_override/capture/process_override_behavior(mob/living/carbon/xenomorph/processing_xeno, delta_time) + . = ..() + if(!.) + return + + processing_xeno.current_target = parent + processing_xeno.resting = FALSE + + if(processing_xeno.get_active_hand()) + processing_xeno.swap_hand() + + var/datum/xeno_ai_movement/processing_xeno_movement = processing_xeno.ai_movement_handler + if(processing_xeno.pulling == parent) + processing_xeno_movement.ai_move_hive(delta_time) + return TRUE + + var/atom/movable/target = processing_xeno.current_target + if(get_dist(processing_xeno, target) <= 1) + INVOKE_ASYNC(processing_xeno, TYPE_PROC_REF(/mob, start_pulling), target) + processing_xeno.face_atom(target) + processing_xeno.swap_hand() + + processing_xeno.ai_move_target(delta_time) + return TRUE diff --git a/code/datums/components/xeno/ai_behavior_overrides/hive_override_behavior.dm b/code/datums/components/xeno/ai_behavior_overrides/hive_override_behavior.dm new file mode 100644 index 0000000000..3fb5923a71 --- /dev/null +++ b/code/datums/components/xeno/ai_behavior_overrides/hive_override_behavior.dm @@ -0,0 +1,34 @@ + +// Just try not to think about this too much. + + +GLOBAL_LIST_EMPTY(ai_hives) + +/datum/component/ai_behavior_override/hive + behavior_icon_state = "core" + + max_assigned = 0 + + var/hive_radius = 7 + +/datum/component/ai_behavior_override/hive/Initialize(...) + . = ..() + + if(!istype(parent, /turf/open) && !istype(parent, /obj/effect/alien)) + return COMPONENT_INCOMPATIBLE + + GLOB.ai_hives += src + + if(!istype(parent, /obj/effect/alien)) + new /obj/effect/alien/weeds/node(get_turf(parent)) + +/datum/component/ai_behavior_override/hive/Destroy(force, silent, ...) + GLOB.ai_hives -= src + + . = ..() + +/datum/component/ai_behavior_override/hive/check_behavior_validity(mob/living/carbon/xenomorph/checked_xeno, distance) + return FALSE + +/datum/component/ai_behavior_override/hive/process_override_behavior(mob/living/carbon/xenomorph/processing_xeno, delta_time) + return FALSE diff --git a/code/game/area/areas_event.dm b/code/game/area/areas_event.dm index c43dae3a65..8fc66afd4d 100644 --- a/code/game/area/areas_event.dm +++ b/code/game/area/areas_event.dm @@ -42,7 +42,7 @@ structure: icon_state = "event" //no bioscan and no tunnels allowed - flags_area = AREA_AVOID_BIOSCAN|AREA_NOTUNNEL + flags_area = AREA_AVOID_BIOSCAN //events are not part of regular gameplay, therefore, no statistics statistic_exempt = TRUE diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index 08de865815..fb1262ec74 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -94,6 +94,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "stool" anchored = TRUE + unslashable = TRUE flags_atom = FPRINT @@ -111,6 +112,7 @@ density = TRUE layer = WINDOW_LAYER anchored = TRUE + unslashable = TRUE flags_atom = ON_BORDER /obj/structure/holowindow/initialize_pass_flags(datum/pass_flags_container/PF) @@ -134,6 +136,7 @@ icon_state = "hoop" anchored = TRUE density = TRUE + unslashable = TRUE throwpass = 1 var/side = "" var/id = "" diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 07c9608072..23fe98994c 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -3,6 +3,7 @@ /obj/structure/computerframe density = FALSE anchored = FALSE + unslashable = TRUE name = "Computer-frame" icon = 'icons/obj/structures/machinery/stock_parts.dmi' icon_state = "0" diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 86bb5f79a0..e13b282cbc 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -145,6 +145,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li icon_state = "cryo_rear" anchored = TRUE density = TRUE + unslashable = TRUE var/orient_right = null //Flips the sprite. diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index b2d836ee47..5a4fee7f23 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -53,6 +53,9 @@ return XENO_ATTACK_ACTION /obj/structure/machinery/door/poddoor/proc/pry_open(mob/living/carbon/xenomorph/X, time = 4 SECONDS) + if(X.action_busy) + return + X.visible_message(SPAN_DANGER("[X] begins prying [src] open."),\ SPAN_XENONOTICE("You start prying [src] open."), max_distance = 3) diff --git a/code/game/objects/effects/acid_hole.dm b/code/game/objects/effects/acid_hole.dm index 415df0e7e5..1b320a9d26 100644 --- a/code/game/objects/effects/acid_hole.dm +++ b/code/game/objects/effects/acid_hole.dm @@ -44,10 +44,8 @@ qdel(src) //no wall?! then cease existence... return - if(!use_wall_hole(user)) - if(user.mob_size >= MOB_SIZE_BIG) - expand_hole(user) - return XENO_NO_DELAY_ACTION + expand_hole(user) + return XENO_NO_DELAY_ACTION /obj/effect/acid_hole/proc/expand_hole(mob/living/carbon/xenomorph/user) if(user.action_busy || user.lying) @@ -55,9 +53,11 @@ playsound(src, "pry", 25, 1) xeno_attack_delay(user) + user.freeze() if(do_after(user, 60, INTERRUPT_ALL, BUSY_ICON_GENERIC) && !QDELETED(src) && holed_wall && !user.lying && istype(holed_wall)) holed_wall.take_damage(rand(2000,3500)) user.emote("roar") + user.unfreeze() /obj/effect/acid_hole/proc/use_wall_hole(mob/user) diff --git a/code/game/objects/items/props/rocks.dm b/code/game/objects/items/props/rocks.dm index 1f040a473e..131fb23dda 100644 --- a/code/game/objects/items/props/rocks.dm +++ b/code/game/objects/items/props/rocks.dm @@ -10,6 +10,7 @@ icon_state = "rock"//go figure desc = "A solidified collection of local minerals. When melted, becomes a substance best known as lava." + unslashable = TRUE opacity = FALSE density = TRUE var/dir_list_full = list(1,2,4,8,5,6,9,10) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index a4666c633a..0289397b45 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -83,6 +83,7 @@ LINEN BINS desc = "A linen bin. It looks rather cosy." icon = 'icons/obj/structures/structures.dmi' icon_state = "linenbin-full" + unslashable = TRUE anchored = TRUE var/amount = 20 var/list/sheets = list() diff --git a/code/game/objects/structures/bookcase.dm b/code/game/objects/structures/bookcase.dm index becb0906e3..6d6ee9ffa3 100644 --- a/code/game/objects/structures/bookcase.dm +++ b/code/game/objects/structures/bookcase.dm @@ -6,6 +6,7 @@ anchored = TRUE density = TRUE opacity = TRUE + unslashable = TRUE /obj/structure/bookcase/Initialize() . = ..() diff --git a/code/game/objects/structures/cargo_container.dm b/code/game/objects/structures/cargo_container.dm index b5c38874cf..2ea0f4e730 100644 --- a/code/game/objects/structures/cargo_container.dm +++ b/code/game/objects/structures/cargo_container.dm @@ -8,6 +8,7 @@ health = 200 opacity = TRUE anchored = TRUE + unslashable = TRUE //Note, for Watatsumi, Grant, and Arious, "left" and "leftmid" are both the left end of the container, but "left" is generic and "leftmid" has the Sat Mover mark on it /obj/structure/cargo_container/watatsumi name = "Watatsumi Cargo Container" diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 00db652049..6aa696d6c7 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -7,6 +7,7 @@ var/covered = 1 //1 for theres the cover, 0 if there isn't. unslashable = TRUE unacidable = TRUE + unslashable = TRUE layer = CATWALK_LAYER /obj/structure/catwalk/Initialize() diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index a2c0d213cc..05e9b8191e 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -3,6 +3,7 @@ desc = "Rack that holds coats." icon = 'icons/obj/structures/props/misc.dmi' icon_state = "coatrack0" + unslashable = TRUE var/obj/item/clothing/suit/coat var/list/allowed = list(/obj/item/clothing/suit/storage/labcoat, /obj/item/clothing/suit/storage/det_suit, /obj/item/clothing/suit/storage/bomber, /obj/item/clothing/suit/storage/bomber/alt) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 8439a887e5..735e91aa53 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -6,6 +6,7 @@ density = TRUE anchored = TRUE unacidable = FALSE + unslashable = TRUE health = 30 var/occupied = 1 var/destroyed = 0 diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 7b54f0447f..7175dd9358 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -5,6 +5,7 @@ icon_state = "extinguisher" anchored = TRUE density = FALSE + unslashable = TRUE var/obj/item/tool/extinguisher/has_extinguisher = new/obj/item/tool/extinguisher var/opened = 0 var/base_icon diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 9c1f46de50..0f4ba9f6bd 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -32,6 +32,7 @@ PLANT_CUT_MACHETE = 3 = Needs at least a machete to be cut down name = "plant" anchored = TRUE density = TRUE + unslashable = TRUE var/icon_tag = null var/variations = 1 var/cut_level = PLANT_NO_CUT diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 2d7f2b4682..e60a7f67be 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -7,6 +7,7 @@ desc = "A spike for collecting meat from animals" density = TRUE anchored = TRUE + unslashable = TRUE var/meat = 0 var/occupied = 0 var/meattype = 0 // 0 - Nothing, 1 - Monkey, 2 - Xeno diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm index fbae7a387a..8751c3f3aa 100644 --- a/code/game/objects/structures/lamarr_cage.dm +++ b/code/game/objects/structures/lamarr_cage.dm @@ -6,6 +6,7 @@ density = TRUE anchored = TRUE unacidable = FALSE + unslashable = TRUE health = 30 var/occupied = 1 var/destroyed = 0 diff --git a/code/game/objects/structures/landing_signs.dm b/code/game/objects/structures/landing_signs.dm index 9e9e83928c..f92148e344 100644 --- a/code/game/objects/structures/landing_signs.dm +++ b/code/game/objects/structures/landing_signs.dm @@ -6,6 +6,7 @@ bound_width = 64 bound_height = 64 density = TRUE + unslashable = TRUE /obj/structure/lz_sign/lazarus_sign name = "Lazarus Landing Sign" diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index d2b3d36b59..81ec524026 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -5,6 +5,7 @@ icon_state = "latticefull" density = FALSE anchored = TRUE + unslashable = TRUE layer = LATTICE_LAYER plane = FLOOR_PLANE // flags = CONDUCT diff --git a/code/game/objects/structures/lawnmower.dm b/code/game/objects/structures/lawnmower.dm index af169139f6..2d4a25c08d 100644 --- a/code/game/objects/structures/lawnmower.dm +++ b/code/game/objects/structures/lawnmower.dm @@ -7,6 +7,7 @@ dir = WEST anchored = FALSE density = TRUE + unslashable = TRUE layer = ABOVE_LYING_MOB_LAYER /obj/structure/lawnmower/Move(atom/NewLoc, dir) diff --git a/code/game/objects/structures/misc.dm b/code/game/objects/structures/misc.dm index 89bc3da6ab..971f22a5e5 100644 --- a/code/game/objects/structures/misc.dm +++ b/code/game/objects/structures/misc.dm @@ -5,6 +5,7 @@ desc = "A stand with the empty body of a cyborg bolted to it." density = TRUE anchored = TRUE + unslashable = TRUE health = 250 /obj/structure/showcase/initialize_pass_flags(datum/pass_flags_container/PF) @@ -53,6 +54,7 @@ icon = 'icons/obj/objects.dmi' icon_state = "target_a" density = FALSE + unslashable = TRUE health = 5000 /obj/structure/target/syndicate @@ -71,6 +73,7 @@ icon_state = "monorail" density = FALSE anchored = TRUE + unslashable = TRUE layer = ATMOS_PIPE_LAYER + 0.01 @@ -80,6 +83,7 @@ name = "Research thingies" icon = 'icons/obj/structures/props/alien_autopsy.dmi' icon_state = "jarshelf_9" + unslashable = TRUE /obj/structure/xenoautopsy/jar_shelf name = "jar shelf" @@ -167,6 +171,7 @@ desc = "A heavy box used for storing ore." density = TRUE anchored = FALSE + unslashable = TRUE /obj/structure/ore_box/initialize_pass_flags(datum/pass_flags_container/PF) ..() @@ -176,6 +181,7 @@ /obj/structure/computer3frame density = TRUE anchored = FALSE + unslashable = TRUE name = "computer frame" icon = 'icons/obj/structures/machinery/stock_parts.dmi' icon_state = "0" @@ -273,7 +279,7 @@ . = ..() if(over_object != usr || !Adjacent(usr)) return - + if(!ishuman(usr)) return diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index dc8cf08d13..b05990725e 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -139,6 +139,7 @@ layer = OBJ_LAYER var/obj/structure/morgue/linked_morgue = null anchored = TRUE + unslashable = TRUE throwpass = 1 var/bloody = FALSE diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index a9f00a50d4..78a07cc17f 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -12,6 +12,7 @@ icon_state = "pianobroken" anchored = TRUE density = TRUE + unslashable = TRUE /obj/structure/device/broken_moog name = "broken vintage synthesizer" @@ -20,3 +21,4 @@ icon_state = "minimoogbroken" anchored = TRUE density = TRUE + unslashable = TRUE diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index 9d007a0c8c..73314bf91d 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -5,6 +5,7 @@ icon_state = "nboard00" density = FALSE anchored = TRUE + unslashable = TRUE var/notices = 0 /obj/structure/noticeboard/Initialize() diff --git a/code/game/objects/structures/pipes/pipes.dm b/code/game/objects/structures/pipes/pipes.dm index 9f2b70c706..8459b9c100 100644 --- a/code/game/objects/structures/pipes/pipes.dm +++ b/code/game/objects/structures/pipes/pipes.dm @@ -4,6 +4,7 @@ anchored = TRUE layer = ATMOS_DEVICE_LAYER plane = FLOOR_PLANE + unslashable = TRUE var/list/connected_to = list() var/list/valid_directions = list(NORTH, SOUTH, EAST, WEST) diff --git a/code/game/objects/structures/platforms.dm b/code/game/objects/structures/platforms.dm index cfffbc90fb..ad1c88928f 100644 --- a/code/game/objects/structures/platforms.dm +++ b/code/game/objects/structures/platforms.dm @@ -14,6 +14,7 @@ breakable = FALSE flags_atom = ON_BORDER unacidable = TRUE + unslashable = TRUE climb_delay = CLIMB_DELAY_SHORT projectile_coverage = PROJECTILE_COVERAGE_NONE @@ -91,6 +92,7 @@ breakable = FALSE flags_atom = ON_BORDER unacidable = TRUE + unslashable = TRUE /obj/structure/platform_decoration/Initialize() . = ..() diff --git a/code/game/objects/structures/props.dm b/code/game/objects/structures/props.dm index bd5610487e..9e5a70dc80 100644 --- a/code/game/objects/structures/props.dm +++ b/code/game/objects/structures/props.dm @@ -11,6 +11,7 @@ /obj/structure/prop/dam density = TRUE + unslashable = TRUE /obj/structure/prop/dam/drill name = "mining drill" @@ -448,6 +449,7 @@ desc = "A rack full of hard drives, micro-computers, and ethernet cables." icon = 'icons/obj/structures/props/server_equipment.dmi' icon_state = "rackframe" + unslashable = TRUE density = TRUE health = 150 @@ -553,6 +555,7 @@ bound_width = 64 bound_height = 64 desc = "A passive electrical component that controls where and which circuits power flows into." + unslashable = TRUE //cash registers @@ -562,6 +565,7 @@ icon = 'icons/obj/structures/props/cash_register.dmi' icon_state = "cash_register" density = TRUE + unslashable = TRUE health = 50 /obj/structure/prop/cash_register/open @@ -584,6 +588,7 @@ desc = "Like rebar, but in space." icon = 'icons/obj/structures/structures.dmi' icon_state = "structure_lattice" + unslashable = TRUE density = TRUE //impassable by default /obj/structure/prop/resin_prop @@ -591,6 +596,7 @@ desc = "Well, it's useless now." icon = 'icons/obj/resin_objects.dmi' icon_state = "watertank" + unslashable = TRUE //industructible props /obj/structure/prop/invuln @@ -652,6 +658,7 @@ health = 150 light_range = 6 light_on = TRUE + unslashable = TRUE /// What obj this becomes when it gets to its next stage of construction / ignition var/frame_type /// What is used to progress to the next stage @@ -855,6 +862,7 @@ desc = "Call a coder (or a mapper) you shouldn't be seeing this!" icon = 'icons/obj/structures/props/ice_colony/props.dmi' projectile_coverage = 10 + unslashable = TRUE /obj/structure/prop/ice_colony/soil_net name = "soil net" @@ -945,6 +953,7 @@ layer = 4 health = 50 anchored = TRUE + unslashable = TRUE /obj/structure/prop/holidays/string_lights name = "M1 pattern festive bulb strings" @@ -1007,6 +1016,7 @@ icon = 'icons/obj/structures/props/generic_props.dmi' icon_state = "tank" density = TRUE + unslashable = TRUE /obj/structure/prop/static_tank/fuel desc = "It contains Decatuxole-Hypospaldirol. A non-volatile liquid fuel type that tastes like oranges. Can't really be used for anything outside of atmos-rocket boosters." @@ -1291,6 +1301,7 @@ desc = "A console designed by the Hunters to assist in flight pathing and navigation." icon = 'icons/obj/structures/machinery/computer.dmi' icon_state = "overwatch" + unslashable = TRUE density = TRUE /obj/structure/prop/invuln/joey diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index ec277929fa..6c1582f112 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -3,6 +3,7 @@ anchored = TRUE opacity = FALSE density = FALSE + unslashable = TRUE layer = WALL_OBJ_LAYER /obj/structure/sign/ex_act(severity) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index cccc1211bf..27fdf94dac 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -8,6 +8,7 @@ density = FALSE anchored = TRUE can_buckle = TRUE + unslashable = TRUE var/open = 0 //if the lid is up var/cistern = 0 //if the cistern bit is open var/w_items = 0 //the combined w_class of all the items in the cistern @@ -177,6 +178,7 @@ icon_state = "urinal" density = FALSE anchored = TRUE + unslashable = TRUE /obj/structure/urinal/attackby(obj/item/I, mob/living/user) if(istype(I, /obj/item/grab)) @@ -424,6 +426,7 @@ icon_state = "sink_emptied_animation" desc = "A sink used for washing one's hands and face." anchored = TRUE + unslashable = TRUE var/busy = FALSE //Something's being washed at the moment /obj/structure/sink/Initialize() diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 7957c86e76..64f1c0fdec 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -14,6 +14,7 @@ name = "Windoor Assembly" icon_state = "l_windoor_assembly01" + unslashable = TRUE anchored = FALSE density = FALSE dir = NORTH diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index e8f40c1d52..873d4b8c98 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -50,6 +50,7 @@ var/datum/controller/supply/supply_controller = new() gender = PLURAL density = FALSE anchored = TRUE + unslashable = TRUE layer = MOB_LAYER var/collide_message_busy // Timer to stop collision spam diff --git a/code/game/turfs/walls/r_wall.dm b/code/game/turfs/walls/r_wall.dm index 8933ad31c0..d903324b0f 100644 --- a/code/game/turfs/walls/r_wall.dm +++ b/code/game/turfs/walls/r_wall.dm @@ -13,6 +13,11 @@ claws_minimum = CLAW_TYPE_VERY_SHARP /turf/closed/wall/r_wall/attackby(obj/item/W, mob/user) + if(isxeno(user) && istype(W, /obj/item/grab)) + var/obj/item/grab/attacker_grab = W + var/mob/living/carbon/xenomorph/user_as_xenomorph = user + user_as_xenomorph.do_nesting_host(attacker_grab.grabbed_thing, src) + if(hull) return @@ -199,9 +204,6 @@ walltype = WALL_REINFORCED hull = 1 -/turf/closed/wall/r_wall/unmeltable/attackby() //This should fix everything else. No cables, etc - return - //Chigusa /turf/closed/wall/r_wall/chigusa @@ -244,15 +246,6 @@ walltype = WALL_REINFORCED hull = 1 -/turf/closed/wall/r_wall/prison_unmeltable/ex_act(severity) //Should make it indestructible - return - -/turf/closed/wall/r_wall/prison_unmeltable/fire_act(exposed_temperature, exposed_volume) - return - -/turf/closed/wall/r_wall/prison_unmeltable/attackby() //This should fix everything else. No cables, etc - return - //Biodome /turf/closed/wall/r_wall/biodome @@ -267,16 +260,6 @@ icon_state = "h_dome" hull = TRUE -/turf/closed/wall/r_wall/biodome/biodome_unmeltable/ex_act(severity) //Should make it indestructible - return - -/turf/closed/wall/r_wall/biodome/biodome_unmeltable/fire_act(exposed_temperature, exposed_volume) - return - -/turf/closed/wall/r_wall/biodome/biodome_unmeltable/attackby() //This should fix everything else. No cables, etc - return - - /// Destructible elevator walls, for when you want the elevator to act as a prop rather than an actual elevator /turf/closed/wall/r_wall/elevator icon = 'icons/turf/elevator.dmi' diff --git a/code/game/turfs/walls/walls.dm b/code/game/turfs/walls/walls.dm index 2387a20861..229311325b 100644 --- a/code/game/turfs/walls/walls.dm +++ b/code/game/turfs/walls/walls.dm @@ -116,7 +116,10 @@ acided_hole.expand_hole(user) //This proc applies the attack delay itself. return XENO_NO_DELAY_ACTION - if(!hull && user.claw_type >= claws_minimum && !acided_hole) + if(!hull && user.claw_type >= claws_minimum) + if(acided_hole) + acided_hole.attack_alien(user) + return XENO_NO_DELAY_ACTION user.animation_attack_on(src) playsound(src, 'sound/effects/metalhit.ogg', 25, 1) if(damage >= (damage_cap - (damage_cap / XENO_HITS_TO_DESTROY_WALL))) diff --git a/code/modules/admin/game_master/game_master.dm b/code/modules/admin/game_master/game_master.dm index 71ee29d603..aed0016429 100644 --- a/code/modules/admin/game_master/game_master.dm +++ b/code/modules/admin/game_master/game_master.dm @@ -35,8 +35,8 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) // Behavior stuff #define DEFAULT_BEHAVIOR_STRING "Attack" -#define SELECTABLE_XENO_BEHAVIORS list("Attack") -#define SELECTABLE_XENO_BEHAVIORS_ASSOC list("Attack" = /datum/component/ai_behavior_override/attack) +#define SELECTABLE_XENO_BEHAVIORS list("Attack", "Capture", "Hive") +#define SELECTABLE_XENO_BEHAVIORS_ASSOC list("Attack" = /datum/component/ai_behavior_override/attack, "Capture" = /datum/component/ai_behavior_override/capture, "Hive" = /datum/component/ai_behavior_override/hive) // Objective stuff #define OBJECTIVE_NUMBER_OPTIONS list("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine") @@ -118,7 +118,7 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) for(var/datum/component/ai_behavior_override/override in GLOB.all_ai_behavior_overrides) game_master_client.images += override.behavior_image - GLOB.game_masters += game_master_client + GLOB.game_masters |= game_master_client /datum/game_master/Destroy(force, ...) . = ..() @@ -274,6 +274,9 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) behavior_click_intercept = FALSE current_click_intercept_action = null + for(var/datum/component/ai_behavior_override/override in GLOB.all_ai_behavior_overrides) + game_master_client.images -= override.behavior_image + /datum/game_master/ui_status(mob/user, datum/ui_state/state) return UI_INTERACTIVE @@ -285,6 +288,9 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) user.client?.click_intercept = src + for(var/datum/component/ai_behavior_override/override in GLOB.all_ai_behavior_overrides) + game_master_client.images |= override.behavior_image + /datum/game_master/proc/InterceptClickOn(mob/user, params, atom/object) var/list/modifiers = params2list(params) @@ -313,7 +319,7 @@ GLOBAL_VAR_INIT(radio_communication_clarity, 100) var/behavior_type = SELECTABLE_XENO_BEHAVIORS_ASSOC[selected_behavior] if(LAZYACCESS(modifiers, MIDDLE_CLICK)) - if(object.datum_components[behavior_type]) + if(object.datum_components?[behavior_type]) var/component_to_remove = object.datum_components[behavior_type] qdel(component_to_remove) return TRUE diff --git a/code/modules/almayer/machinery.dm b/code/modules/almayer/machinery.dm index 6c3944498d..90bbd6ef9a 100644 --- a/code/modules/almayer/machinery.dm +++ b/code/modules/almayer/machinery.dm @@ -113,6 +113,7 @@ desc = "THIS SHOULDN'T BE VISIBLE, AHELP 'ART-P02' IF SEEN IN ROUND WITH LOCATION" density = TRUE anchored = TRUE + unslashable = TRUE /obj/structure/prop/almayer/minigun_crate name = "30mm ammo crate" diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index b3ec6c800c..41d9482ba8 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -164,6 +164,7 @@ anchored = TRUE opacity = TRUE density = TRUE + unslashable = TRUE icon = 'icons/obj/apc.dmi' icon_state = "apc" diff --git a/code/modules/cm_marines/orbital_cannon.dm b/code/modules/cm_marines/orbital_cannon.dm index 1d49c42f5e..05ed5d57c6 100644 --- a/code/modules/cm_marines/orbital_cannon.dm +++ b/code/modules/cm_marines/orbital_cannon.dm @@ -16,6 +16,7 @@ var/list/ob_type_fuel_requirements bound_height = 64 bound_y = 64 unacidable = TRUE + unslashable = TRUE var/obj/structure/orbital_tray/tray var/chambered_tray = FALSE var/loaded_tray = FALSE @@ -244,6 +245,7 @@ var/list/ob_type_fuel_requirements bound_width = 64 bound_height = 32 unacidable = TRUE + unslashable = TRUE pixel_y = -9 pixel_x = -6 var/obj/structure/ob_ammo/warhead/warhead @@ -328,6 +330,7 @@ var/list/ob_type_fuel_requirements throwpass = TRUE climbable = TRUE unacidable = TRUE // issue: being used for defences, solution: abomb + unslashable = TRUE icon = 'icons/obj/structures/props/almayer_props.dmi' var/is_solid_fuel = 0 var/source_mob diff --git a/code/modules/cm_phone/phone_base.dm b/code/modules/cm_phone/phone_base.dm index 4b74262b9e..d5f252846b 100644 --- a/code/modules/cm_phone/phone_base.dm +++ b/code/modules/cm_phone/phone_base.dm @@ -3,6 +3,7 @@ icon = 'icons/obj/structures/structures.dmi' icon_state = "wall_phone" desc = "It is a wall mounted telephone. The fine text reads: To log your details with the mainframe please insert your keycard into the slot below. Unfortunately the slot is jammed. You can still use the phone, however." + unslashable = TRUE var/phone_category = "Uncategorised" var/phone_color = "white" diff --git a/code/modules/cm_tech/droppod/droppod.dm b/code/modules/cm_tech/droppod/droppod.dm index 030dd11474..ebaa4f7ae3 100644 --- a/code/modules/cm_tech/droppod/droppod.dm +++ b/code/modules/cm_tech/droppod/droppod.dm @@ -10,6 +10,7 @@ density = FALSE wrenchable = TRUE + unslashable = TRUE var/droppod_flags = NO_FLAGS diff --git a/code/modules/desert_dam/filtration/floodgates.dm b/code/modules/desert_dam/filtration/floodgates.dm index 1e91a83bc9..9c361f9158 100644 --- a/code/modules/desert_dam/filtration/floodgates.dm +++ b/code/modules/desert_dam/filtration/floodgates.dm @@ -9,4 +9,4 @@ icon = 'icons/turf/walls/bunker.dmi' icon_state = "gate_west" density = TRUE - + unslashable = TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index 3fd8e53024..f0961f3802 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -732,11 +732,7 @@ var/turf/supplier_turf = get_turf(nest_structural_base) var/obj/effect/alien/weeds/supplier_weeds = locate(/obj/effect/alien/weeds) in supplier_turf if(!supplier_weeds) - to_chat(src, SPAN_XENOBOLDNOTICE("There are no weeds here! Nesting hosts requires hive weeds.")) - return - - if(supplier_weeds.weed_strength < WEED_LEVEL_HIVE) - to_chat(src, SPAN_XENOBOLDNOTICE("The weeds here are not strong enough for nesting hosts.")) + to_chat(src, SPAN_XENOBOLDNOTICE("There are no weeds here! Nesting hosts requires any sort of weeds.")) return if(!supplier_turf.density) @@ -749,15 +745,18 @@ if(!host_to_nest.Adjacent(supplier_turf)) to_chat(src, SPAN_XENONOTICE("The host must be directly next to the wall its being nested on!")) + step(host_to_nest, dir_to_nest) return if(!locate(dir_to_nest) in GLOB.cardinals) to_chat(src, SPAN_XENONOTICE("The host must be directly next to the wall its being nested on!")) + step_to(host_to_nest, src) return for(var/obj/structure/bed/nest/preexisting_nest in get_turf(host_to_nest)) if(preexisting_nest.dir == dir_to_nest) to_chat(src, SPAN_XENONOTICE("There is already a host nested here!")) + step_to(host_to_nest, src) return var/obj/structure/bed/nest/applicable_nest = new(get_turf(host_to_nest)) diff --git a/code/modules/mob/living/carbon/xenomorph/ai/movement/base_define.dm b/code/modules/mob/living/carbon/xenomorph/ai/movement/base_define.dm index bb90128dc3..9219c78e32 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/movement/base_define.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/movement/base_define.dm @@ -68,3 +68,97 @@ if(!X.move_to_next_turf(T)) X.current_target = null return TRUE + +/datum/xeno_ai_movement/proc/ai_move_hive(delta_time) + SHOULD_NOT_SLEEP(TRUE) + var/mob/living/carbon/xenomorph/retreating_xeno = parent + + if(retreating_xeno.throwing) + return + + var/shortest_distance = INFINITY + var/turf/closest_hive + var/hive_radius + for(var/datum/component/ai_behavior_override/hive/hive_component as anything in GLOB.ai_hives) + var/turf/potential_hive = hive_component.parent + hive_radius = hive_component.hive_radius + + if(potential_hive.z != retreating_xeno.z) + continue + + var/xeno_to_potential_hive_distance = get_dist(retreating_xeno, potential_hive) + if(xeno_to_potential_hive_distance > shortest_distance) + continue + + closest_hive = potential_hive + shortest_distance = xeno_to_potential_hive_distance + + if(!closest_hive) + return + + if(get_dist(retreating_xeno, closest_hive) <= hive_radius) + return ai_strap_host(closest_hive, hive_radius, delta_time) + + var/turf/hive_turf = get_turf(closest_hive) + if(retreating_xeno.move_to_next_turf(hive_turf, world.maxx)) + return TRUE + +/datum/xeno_ai_movement/proc/ai_strap_host(turf/closest_hive, hive_radius, delta_time) + SHOULD_NOT_SLEEP(TRUE) + var/mob/living/carbon/xenomorph/capping_xeno = parent + + if(capping_xeno.throwing) + return + + var/turf/nest_turf + var/turf/weeded_wall + + var/shortest_distance = INFINITY + for(var/turf/potential_nest as anything in shuffle(RANGE_TURFS(hive_radius, closest_hive))) + if(potential_nest.density) + continue + + if(!potential_nest.weeds) + continue + + var/mob/living/carbon/xenomorph/xeno = locate() in potential_nest + if(xeno && xeno != capping_xeno) + continue + + var/obj/structure/bed/nest/preexisting_nest = locate() in potential_nest + if(preexisting_nest && preexisting_nest.buckled_mob) + continue + + var/turf/potential_weeded_wall + for(var/turf/closed/touching_turf in orange(1, potential_nest)) + if(!touching_turf.weeds) + continue + + if(get_dir(potential_nest, touching_turf) in diagonals) + continue + + potential_weeded_wall = touching_turf + break + + if(!potential_weeded_wall) + continue + + var/xeno_to_potential_nest_distance = get_dist(capping_xeno, potential_nest) + if(xeno_to_potential_nest_distance > shortest_distance) + continue + + nest_turf = potential_nest + weeded_wall = potential_weeded_wall + shortest_distance = xeno_to_potential_nest_distance + + if(!nest_turf) + return + + if(get_dist(capping_xeno, nest_turf) < 1) + if(capping_xeno.get_inactive_hand()) + capping_xeno.swap_hand() + INVOKE_ASYNC(capping_xeno, TYPE_PROC_REF(/mob, do_click), weeded_wall, "", list()) + return TRUE + + if(capping_xeno.move_to_next_turf(nest_turf)) + return TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm b/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm index 5682062cea..086000bed4 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/movement/drone.dm @@ -54,6 +54,8 @@ idle_xeno.lay_down() return + idle_xeno.resting = FALSE + if(home_turf == last_home_turf) blacklisted_turfs += home_turf addtimer(CALLBACK(src, PROC_REF(unblacklist_turf), home_turf), BLACKLIST_TURF_TIMEOUT) diff --git a/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm b/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm index 1f1f654ee2..08684b2cd9 100644 --- a/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm +++ b/code/modules/mob/living/carbon/xenomorph/ai/xeno_ai.dm @@ -222,9 +222,16 @@ GLOBAL_LIST_INIT(ai_target_limbs, list( var/datum/component/ai_behavior_override/closest_valid_override for(var/datum/component/ai_behavior_override/cycled_override in GLOB.all_ai_behavior_overrides) var/distance = get_dist(src, cycled_override.parent) - if(cycled_override.check_behavior_validity(src, distance) && distance < shortest_distance) - shortest_distance = distance - closest_valid_override = cycled_override + var/validity = cycled_override.check_behavior_validity(src, distance) + + if(!validity) + continue + + if(distance >= shortest_distance) + continue + + shortest_distance = distance + closest_valid_override = cycled_override return closest_valid_override @@ -318,6 +325,9 @@ GLOBAL_LIST_INIT(ai_target_limbs, list( if(checked_human.species.flags & IS_SYNTHETIC) return FALSE + if(HAS_TRAIT(checked_human, TRAIT_NESTED)) + return FALSE + if(FACTION_XENOMORPH in checked_human.faction_group) return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm index 25f6108c14..e3dfccbf88 100644 --- a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm +++ b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm @@ -893,6 +893,7 @@ //Crates, closets, other paraphernalia /obj/structure/closet/attack_alien(mob/living/carbon/xenomorph/M) if(!unacidable) + playsound(src, 'sound/effects/metalhit.ogg', 25, 1) M.animation_attack_on(src) if(!opened) var/difficulty = 70 //if its just closed we can smash open quite easily diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_ai_interaction.dm b/code/modules/mob/living/carbon/xenomorph/xeno_ai_interaction.dm index 8aa80e9c22..9d0eb37c1b 100644 --- a/code/modules/mob/living/carbon/xenomorph/xeno_ai_interaction.dm +++ b/code/modules/mob/living/carbon/xenomorph/xeno_ai_interaction.dm @@ -1,3 +1,21 @@ +/* + +Just as a note, eventually it may be prudent to convert most of attack_alien() checks into two parts. + +attack_alien() gets called as usual by normal sources but then immediately goes into: +Can we do the attack_alien(), probably like can_attack_alien() or some such +And then the usual attack_alien() effect + +This way we can keep our obstacle checks up to date with any future attack_alien() changes by calling can_attack_alien() + +Future problem for the time being and maybe not worth pursuing :shrug: + +As a second note, please god follow the xeno_ai_obstacle chain to atom if possible, things like if(get_turf(src) == target) NEEDING to return 0 most times is very important. +At bare minimum, make sure the relevant checks from parent types gets copied in if you need to snowflake something. + +*/// - Morrow + + // MINERAL DOOR /obj/structure/mineral_door/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction, turf/target) return DOOR_PENALTY @@ -15,10 +33,32 @@ acting_xeno.a_intent = INTENT_HELP . = ..() +// Poddoors/shutters +/obj/structure/machinery/door/poddoor/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction, turf/target) + . = ..() + if(!.) + return + + if(!(stat & NOPOWER)) + return + + if(operating) + return + + if(unacidable) + return + + return DOOR_PENALTY + // AIRLOCK /obj/structure/machinery/door/airlock/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction, turf/target) + . = ..() + if(!.) + return + if(locked || welded || isElectrified()) - return ..() + return INFINITY + return DOOR_PENALTY /obj/structure/machinery/door/xeno_ai_act(mob/living/carbon/xenomorph/X) @@ -27,11 +67,16 @@ // OBJECTS /obj/structure/xeno_ai_obstacle(mob/living/carbon/xenomorph/X, direction, turf/target) + . = ..() + if(!.) + return + if(!density) return 0 if(unslashable && !climbable) - return ..() + return + return OBJECT_PENALTY /obj/structure/xeno_ai_act(mob/living/carbon/xenomorph/X) @@ -92,3 +137,8 @@ return 0 return FIRE_PENALTY + +// HOLES +/obj/effect/acid_hole/xeno_ai_act(mob/living/carbon/xenomorph/X) + X.do_click(src, "", list()) + return TRUE diff --git a/code/modules/projectiles/ammo_boxes/box_structures.dm b/code/modules/projectiles/ammo_boxes/box_structures.dm index cb119e1a21..77020baab5 100644 --- a/code/modules/projectiles/ammo_boxes/box_structures.dm +++ b/code/modules/projectiles/ammo_boxes/box_structures.dm @@ -4,6 +4,7 @@ name = "\improper magazine_box" icon = 'icons/obj/items/weapons/guns/ammo_boxes/boxes_and_lids.dmi' icon_state = "base_m41" + unslashable = TRUE var/obj/item/ammo_box/magazine/item_box var/can_explode = TRUE var/burning = FALSE diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 98d4c9348b..a4ff0ec018 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -9,6 +9,7 @@ icon_state = "conpipe-s" anchored = FALSE density = FALSE + unslashable = TRUE matter = list("metal" = 1850) level = 2 var/ptype = 0 diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 2c7401ac27..1baab6b617 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -463,6 +463,7 @@ ///Virtual disposal object, travels through pipes in lieu of actual items ///Contents will be items flushed by the disposal, this allows the gas flushed to be tracked /obj/structure/disposalholder + unslashable = TRUE invisibility = 101 var/active = 0 //True if the holder is moving, otherwise inactive dir = 0 @@ -618,6 +619,7 @@ desc = "An underfloor disposal pipe." anchored = TRUE density = FALSE + unslashable = TRUE level = 1 //Underfloor only var/dpdir = 0 //Bitmask of pipe directions diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index e61357188a..3168bd8533 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -12,6 +12,7 @@ var/label_x var/tag_x anchored = FALSE + unslashable = TRUE /obj/structure/bigDelivery/attack_hand(mob/user as mob) if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0 diff --git a/colonialmarines.dme b/colonialmarines.dme index 06d41c4922..5fb39db056 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -400,6 +400,8 @@ #include "code\datums\components\xeno\shield_slash.dm" #include "code\datums\components\xeno\ai_behavior_overrides\attack_override_behavior.dm" #include "code\datums\components\xeno\ai_behavior_overrides\base_override_behavior.dm" +#include "code\datums\components\xeno\ai_behavior_overrides\capture_override_behavior.dm" +#include "code\datums\components\xeno\ai_behavior_overrides\hive_override_behavior.dm" #include "code\datums\construction\construction_template.dm" #include "code\datums\construction\xenomorph\construction_template_xenomorph.dm" #include "code\datums\decorators\decorator.dm" diff --git a/icons/effects/game_master_xeno_behaviors.dmi b/icons/effects/game_master_xeno_behaviors.dmi new file mode 100644 index 0000000000..ea6f04a987 Binary files /dev/null and b/icons/effects/game_master_xeno_behaviors.dmi differ