diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm index b36c9c867e4..aecf79a010e 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm @@ -6,7 +6,7 @@ /obj/structure/chair/sofa/right/brown{ dir = 4 }, -/mob/living/simple_animal/hostile/gorilla{ +/mob/living/basic/gorilla{ anchored = 1; dir = 4; faction = list("neutral") diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index 3877bc689d5..7ed8518e66f 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -11,6 +11,11 @@ ///How close a mob must be for us to select it as a target, if that is less than how far we can maintain it as a target #define BB_AGGRO_RANGE "BB_aggro_range" +/// Store a single or list of emotes at this key +#define BB_EMOTE_KEY "BB_emotes" +/// Chance to perform an emote per second +#define BB_EMOTE_CHANCE "BB_EMOTE_CHANCE" + ///Turf we want a mob to move to #define BB_TRAVEL_DESTINATION "BB_travel_destination" @@ -105,4 +110,4 @@ #define BB_EMOTE_HEAR "emote_hear" #define BB_EMOTE_SEE "emote_see" #define BB_EMOTE_SOUND "emote_sound" -#define BB_EMOTE_CHANCE "emote_chance" +#define BB_SPEAK_CHANCE "emote_chance" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 7dffe24331a..51211f5ad6d 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -31,6 +31,9 @@ /// From base of /mob/living/simple_animal/bot/proc/bot_step() #define COMSIG_MOB_BOT_STEP "mob_bot_step" +/// From base of /mob/proc/update_held_items +#define COMSIG_MOB_UPDATE_HELD_ITEMS "mob_update_held_items" + /// From base of /client/Move(): (list/move_args) #define COMSIG_MOB_CLIENT_PRE_LIVING_MOVE "mob_client_pre_living_move" /// Should we stop the current living movement attempt diff --git a/code/__DEFINES/drone.dm b/code/__DEFINES/drone.dm index 8907d172194..0d31e3caf41 100644 --- a/code/__DEFINES/drone.dm +++ b/code/__DEFINES/drone.dm @@ -2,9 +2,8 @@ /// If drones are blacklisted from certain sensitive machines GLOBAL_VAR_INIT(drone_machine_blacklist_enabled, FALSE) -#define DRONE_HANDS_LAYER 1 -#define DRONE_HEAD_LAYER 2 -#define DRONE_TOTAL_LAYERS 2 +#define DRONE_HEAD_LAYER 1 +#define DRONE_TOTAL_LAYERS 1 /// Message displayed when new drone spawns in drone network #define DRONE_NET_CONNECT span_notice("DRONE NETWORK: [name] connected.") diff --git a/code/__DEFINES/guardian_defines.dm b/code/__DEFINES/guardian_defines.dm index d7aae6965a7..e7961368fee 100644 --- a/code/__DEFINES/guardian_defines.dm +++ b/code/__DEFINES/guardian_defines.dm @@ -3,6 +3,5 @@ #define GUARDIAN_THEME_CARP "carp" #define GUARDIAN_THEME_MINER "miner" -#define GUARDIAN_COLOR_LAYER 2 -#define GUARDIAN_HANDS_LAYER 1 -#define GUARDIAN_TOTAL_LAYERS 2 +#define GUARDIAN_COLOR_LAYER 1 +#define GUARDIAN_TOTAL_LAYERS 1 diff --git a/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm b/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm new file mode 100644 index 00000000000..6f2f5cdc203 --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm @@ -0,0 +1,33 @@ +/// Intermittently run an emote +/datum/ai_planning_subtree/run_emote + var/emote_key = BB_EMOTE_KEY + var/emote_chance_key = BB_EMOTE_CHANCE + +/datum/ai_planning_subtree/run_emote/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/emote_chance = controller.blackboard[emote_chance_key] || 0 + if (!SPT_PROB(emote_chance, seconds_per_tick)) + return + controller.queue_behavior(/datum/ai_behavior/run_emote, emote_key) + +/// Emote from a blackboard key +/datum/ai_behavior/run_emote + +/datum/ai_behavior/run_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote_key) + var/mob/living/living_pawn = controller.pawn + if (!isliving(living_pawn)) + finish_action(controller, FALSE) + return + + var/list/emote_list = controller.blackboard[emote_key] + var/emote + if (islist(emote_list)) + emote = length(emote_list) ? pick(emote_list) : null + else + emote = emote_list + + if(isnull(emote)) + finish_action(controller, FALSE) + return + + living_pawn.emote(emote) + finish_action(controller, TRUE) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm index 52f4a3459bf..7a3d5470b1a 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm @@ -228,6 +228,6 @@ emote_see = speech_lines[BB_EMOTE_SEE] || list() emote_hear = speech_lines[BB_EMOTE_HEAR] || list() sound = speech_lines[BB_EMOTE_SOUND] || list() - speech_chance = speech_lines[BB_EMOTE_CHANCE] ? speech_lines[BB_EMOTE_CHANCE] : initial(speech_chance) + speech_chance = speech_lines[BB_SPEAK_CHANCE] ? speech_lines[BB_SPEAK_CHANCE] : initial(speech_chance) return ..() diff --git a/code/datums/components/basic_inhands.dm b/code/datums/components/basic_inhands.dm new file mode 100644 index 00000000000..ac50f618861 --- /dev/null +++ b/code/datums/components/basic_inhands.dm @@ -0,0 +1,50 @@ +/** + * Basic handling for showing held items in a mob's hands + */ +/datum/component/basic_inhands + /// Layer index we show our inhands upon + var/display_layer + /// Y offset to apply to inhands + var/y_offset + /// X offset to apply to inhands, is inverted for the left hand + var/x_offset + /// What overlays are we currently showing? + var/list/cached_overlays + +/datum/component/basic_inhands/Initialize(display_layer = 1, y_offset = 0, x_offset = 0) + . = ..() + if (!isliving(parent)) + return COMPONENT_INCOMPATIBLE + src.display_layer = display_layer + src.y_offset = y_offset + src.x_offset = x_offset + cached_overlays = list() + +/datum/component/basic_inhands/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_updated_overlays)) + RegisterSignal(parent, COMSIG_MOB_UPDATE_HELD_ITEMS, PROC_REF(on_updated_held_items)) + +/datum/component/basic_inhands/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_MOB_UPDATE_HELD_ITEMS)) + +/// When your overlays update, add your held overlays +/datum/component/basic_inhands/proc/on_updated_overlays(atom/parent_atom, list/overlays) + SIGNAL_HANDLER + overlays += cached_overlays + +/// When your number of held items changes, regenerate held icons +/datum/component/basic_inhands/proc/on_updated_held_items(mob/living/holding_mob) + SIGNAL_HANDLER + var/list/held_overlays = list() + for(var/obj/item/held in holding_mob.held_items) + var/is_right = holding_mob.get_held_index_of_item(held) % 2 == 0 + var/icon_file = is_right ? held.righthand_file : held.lefthand_file + var/mutable_appearance/held_overlay = held.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) + held_overlay.pixel_y += y_offset + held_overlay.pixel_x += x_offset * (is_right ? 1 : -1) + held_overlays += held_overlay + + cached_overlays = held_overlays + holding_mob.update_appearance(UPDATE_OVERLAYS) diff --git a/code/datums/elements/amputating_limbs.dm b/code/datums/elements/amputating_limbs.dm index f7e3d08fcc4..65397e33fe6 100644 --- a/code/datums/elements/amputating_limbs.dm +++ b/code/datums/elements/amputating_limbs.dm @@ -68,7 +68,7 @@ /// Chop one off /datum/element/amputating_limbs/proc/amputate(mob/living/surgeon, mob/living/carbon/victim, obj/item/bodypart/to_remove) - surgeon.visible_message(span_warning("[surgeon] begins [surgery_verb] [to_remove] off of [victim]!")) + surgeon.visible_message(span_warning("[surgeon] [surgery_verb] [to_remove] off of [victim]!")) if (surgery_time > 0 && !do_after(surgeon, delay = surgery_time, target = victim)) return to_remove.dismember() diff --git a/code/datums/memory/_memory.dm b/code/datums/memory/_memory.dm index e3f161d5f0e..2b3e250a3fb 100644 --- a/code/datums/memory/_memory.dm +++ b/code/datums/memory/_memory.dm @@ -257,6 +257,7 @@ /mob/living/basic/cow/wisdom, /mob/living/basic/crab, /mob/living/basic/goat, + /mob/living/basic/gorilla, /mob/living/basic/headslug, /mob/living/basic/killer_tomato, /mob/living/basic/lizard, @@ -274,7 +275,6 @@ /mob/living/basic/statue, /mob/living/basic/stickman, /mob/living/basic/stickman/dog, - /mob/living/simple_animal/hostile/gorilla, /mob/living/simple_animal/hostile/megafauna/dragon/lesser, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet/cat, diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 26bbc689afa..8402c70236b 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -148,7 +148,7 @@ show_in_report = FALSE // Selective attention test. Did you spot the gorilla? /// The gorilla we created, we only hold this ref until the round starts. - var/mob/living/simple_animal/hostile/gorilla/cargo_domestic/cargorilla + var/mob/living/basic/gorilla/cargorilla/cargorilla /datum/station_trait/cargorilla/New() . = ..() @@ -189,7 +189,7 @@ cargorilla = null /// Get us a ghost for the gorilla. -/datum/station_trait/cargorilla/proc/get_ghost_for_gorilla(mob/living/simple_animal/hostile/gorilla/cargo_domestic/gorilla) +/datum/station_trait/cargorilla/proc/get_ghost_for_gorilla(mob/living/basic/gorilla/cargorilla/gorilla) if(QDELETED(gorilla)) return diff --git a/code/game/objects/items/food/monkeycube.dm b/code/game/objects/items/food/monkeycube.dm index 5cf9db79fd0..c5f19460d69 100644 --- a/code/game/objects/items/food/monkeycube.dm +++ b/code/game/objects/items/food/monkeycube.dm @@ -62,7 +62,7 @@ /datum/reagent/medicine/strange_reagent = 5, ) tastes = list("the jungle" = 1, "bananas" = 1, "jimmies" = 1) - spawned_mob = /mob/living/simple_animal/hostile/gorilla + spawned_mob = /mob/living/basic/gorilla /obj/item/food/monkeycube/chicken name = "chicken cube" diff --git a/code/modules/antagonists/traitor/objectives/kill_pet.dm b/code/modules/antagonists/traitor/objectives/kill_pet.dm index f90599e6c35..ae28f5dbf4c 100644 --- a/code/modules/antagonists/traitor/objectives/kill_pet.dm +++ b/code/modules/antagonists/traitor/objectives/kill_pet.dm @@ -26,9 +26,9 @@ JOB_CHIEF_MEDICAL_OFFICER = /mob/living/simple_animal/pet/cat/runtime, JOB_CHIEF_ENGINEER = /mob/living/simple_animal/parrot/poly, JOB_QUARTERMASTER = list( + /mob/living/basic/gorilla/cargorilla, /mob/living/basic/sloth/citrus, /mob/living/basic/sloth/paperwork, - /mob/living/simple_animal/hostile/gorilla/cargo_domestic, ) ) /// The head that we are targetting diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 7e288ebcee5..4660a1b0546 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -286,6 +286,10 @@ I.dropped(src) return FALSE +/// Returns true if a mob is holding something +/mob/proc/is_holding_items() + return !!locate(/obj/item) in held_items + /mob/proc/drop_all_held_items() . = FALSE for(var/obj/item/I in held_items) diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index aebb54770d7..2954c2779d0 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -260,3 +260,28 @@ else if(on_fire && !isnull(last_icon_state)) return last_icon_state return null +<<<<<<< HEAD +======= + +/mob/living/basic/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, ignore_animation = TRUE) + . = ..() + if (.) + update_held_items() + +/mob/living/basic/update_held_items() + . = ..() + if(isnull(client) || isnull(hud_used) || hud_used.hud_version == HUD_STYLE_NOHUD) + return + var/turf/our_turf = get_turf(src) + for(var/obj/item/held in held_items) + var/index = get_held_index_of_item(held) + SET_PLANE(held, ABOVE_HUD_PLANE, our_turf) + held.screen_loc = ui_hand_position(index) + client.screen |= held + +/mob/living/basic/get_body_temp_heat_damage_limit() + return maximum_survivable_temperature + +/mob/living/basic/get_body_temp_cold_damage_limit() + return minimum_survivable_temperature +>>>>>>> b2ccdeab8b9 ([MIRROR] Basic Mob Gorillas [MDB IGNORE] (#24284)) diff --git a/code/modules/mob/living/basic/clown/clown.dm b/code/modules/mob/living/basic/clown/clown.dm index 78715361356..5682edf9339 100644 --- a/code/modules/mob/living/basic/clown/clown.dm +++ b/code/modules/mob/living/basic/clown/clown.dm @@ -37,7 +37,7 @@ BB_EMOTE_SAY = list("HONK", "Honk!", "Welcome to clown planet!"), BB_EMOTE_HEAR = list("honks", "squeaks"), BB_EMOTE_SOUND = list('sound/items/bikehorn.ogg'), //WE LOVE TO PARTY - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) ///do we waddle (honk) var/waddles = TRUE @@ -150,9 +150,9 @@ ), BB_EMOTE_HEAR = list("honks", "contemplates its existence"), BB_EMOTE_SEE = list("sweats", "jiggles"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) - + /mob/living/basic/clown/fleshclown/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) @@ -185,7 +185,7 @@ emotes = list( BB_EMOTE_SAY = list("YA-HONK!!!"), BB_EMOTE_HEAR = list("honks", "squeaks"), - BB_EMOTE_CHANCE = 60, + BB_SPEAK_CHANCE = 60, ) /mob/living/basic/clown/clownhulk @@ -221,7 +221,7 @@ BB_EMOTE_SAY = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!"), BB_EMOTE_HEAR = list("honks", "grunts"), BB_EMOTE_SEE = list("sweats"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) /mob/living/basic/clown/clownhulk/chlown @@ -252,7 +252,7 @@ emotes = list( BB_EMOTE_SAY = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?"), BB_EMOTE_SEE = list("asserts his dominance", "emasculates everyone implicitly"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) /mob/living/basic/clown/clownhulk/honkmunculus @@ -318,7 +318,7 @@ BB_EMOTE_SAY = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!"), BB_EMOTE_HEAR = list("honks", "grunts"), BB_EMOTE_SEE = list("sweats"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) /mob/living/basic/clown/mutant @@ -354,7 +354,7 @@ emotes = list( BB_EMOTE_SAY = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK"), BB_EMOTE_SEE = list("squirms", "writhes", "pulsates", "froths", "oozes"), - BB_EMOTE_CHANCE = 10, + BB_SPEAK_CHANCE = 10, ) /mob/living/basic/clown/mutant/slow diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm new file mode 100644 index 00000000000..b0926b41811 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -0,0 +1,181 @@ +/// Where do we draw gorilla held overlays? +#define GORILLA_HANDS_LAYER 1 + +/** + * Like a bigger monkey + * They make a lot of noise and punch limbs off unconscious folks + */ +/mob/living/basic/gorilla + name = "Gorilla" + desc = "A ground-dwelling, predominantly herbivorous ape which usually inhabits the forests of central Africa but today is quite far away from there." + icon = 'icons/mob/simple/gorilla.dmi' + icon_state = "crawling" + icon_living = "crawling" + icon_dead = "dead" + health_doll_icon = "crawling" + mob_biotypes = MOB_ORGANIC|MOB_HUMANOID + maxHealth = 220 + health = 220 + response_help_continuous = "prods" + response_help_simple = "prod" + response_disarm_continuous = "challenges" + response_disarm_simple = "challenge" + response_harm_continuous = "thumps" + response_harm_simple = "thump" + speed = 0.5 + melee_damage_lower = 15 + melee_damage_upper = 18 + damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, CLONE = 0, STAMINA = 0, OXY = 1.5) + obj_damage = 20 + attack_verb_continuous = "pummels" + attack_verb_simple = "pummel" + attack_sound = 'sound/weapons/punch1.ogg' + unique_name = TRUE + ai_controller = /datum/ai_controller/basic_controller/gorilla + faction = list(FACTION_MONKEY, FACTION_JUNGLE) + butcher_results = list(/obj/item/food/meat/slab/gorilla = 4, /obj/effect/gibspawner/generic/animal = 1) + /// How likely our meaty fist is to stun someone + var/paralyze_chance = 20 + /// A counter for when we can scream again + var/oogas = 0 + /// Types of things we want to find and eat + var/static/list/gorilla_food = list( + /obj/item/food/bread/banana, + /obj/item/food/breadslice/banana, + /obj/item/food/cnds/banana_honk, + /obj/item/food/grown/banana, + /obj/item/food/popsicle/topsicle/banana, + /obj/item/food/salad/fruit, + /obj/item/food/salad/jungle, + /obj/item/food/sundae, + ) + +/mob/living/basic/gorilla/Initialize(mapload) + . = ..() + add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT) + AddElement(/datum/element/wall_smasher) + AddElement(/datum/element/dextrous) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_BAREFOOT) + AddElement(/datum/element/basic_eating, heal_amt = 10, food_types = gorilla_food) + AddElement( + /datum/element/amputating_limbs, \ + surgery_time = 0 SECONDS, \ + surgery_verb = "punches",\ + ) + AddComponent(/datum/component/personal_crafting) + AddComponent(/datum/component/basic_inhands, y_offset = -1) + ai_controller?.set_blackboard_key(BB_BASIC_FOODS, gorilla_food) + +/mob/living/basic/gorilla/update_overlays() + . = ..() + if (is_holding_items()) + . += "standing_overlay" + +/mob/living/basic/gorilla/update_icon_state() + . = ..() + if (stat == DEAD) + return + icon_state = is_holding_items() ? "standing" : "crawling" + +/mob/living/basic/gorilla/update_held_items() + . = ..() + update_appearance(UPDATE_ICON) + if (is_holding_items()) + add_movespeed_modifier(/datum/movespeed_modifier/gorilla_standing) + else + remove_movespeed_modifier(/datum/movespeed_modifier/gorilla_standing) + +/mob/living/basic/gorilla/melee_attack(mob/living/target, list/modifiers, ignore_cooldown) + . = ..() + if (!. || !isliving(target)) + return + ooga_ooga() + if (prob(paralyze_chance)) + target.Paralyze(2 SECONDS) + visible_message(span_danger("[src] knocks [target] down!")) + else + target.throw_at(get_edge_target_turf(target, dir), range = rand(1, 2), speed = 7, thrower = src) + +/mob/living/basic/gorilla/gib(drop_bitflags = DROP_BRAIN) + if(!(drop_bitflags & DROP_BRAIN)) + return ..() + var/mob/living/brain/gorilla_brain = new(drop_location()) + gorilla_brain.name = real_name + gorilla_brain.real_name = real_name + mind?.transfer_to(gorilla_brain) + return ..() + +/mob/living/basic/gorilla/can_use_guns(obj/item/gun) + to_chat(src, span_warning("Your meaty finger is much too large for the trigger guard!")) + return FALSE + +/// Assert your dominance with audio cues +/mob/living/basic/gorilla/proc/ooga_ooga() + if (isnull(client)) + return // Sorry NPCs + oogas -= 1 + if(oogas > 0) + return + oogas = rand(2,6) + emote("ooga") + +/// Gorillas are slower when carrying something +/datum/movespeed_modifier/gorilla_standing + blacklisted_movetypes = (FLYING|FLOATING) + multiplicative_slowdown = 0.5 + +/// A smaller gorilla summoned via magic +/mob/living/basic/gorilla/lesser + name = "lesser Gorilla" + desc = "An adolescent Gorilla. It may not be fully grown but, much like a banana, that just means it's sturdier and harder to chew!" + maxHealth = 120 + health = 120 + speed = 0.35 + melee_damage_lower = 10 + melee_damage_upper = 15 + obj_damage = 15 + ai_controller = /datum/ai_controller/basic_controller/gorilla/lesser + butcher_results = list(/obj/item/food/meat/slab/gorilla = 2) + +/mob/living/basic/gorilla/lesser/Initialize(mapload) + . = ..() + transform *= 0.75 + +/// Cargo's wonderful mascot, the tranquil box-carrying ape +/mob/living/basic/gorilla/cargorilla + name = "Cargorilla" // Overriden, normally + icon = 'icons/mob/simple/cargorillia.dmi' + desc = "Cargo's pet gorilla. They seem to have an 'I love Mom' tattoo." + maxHealth = 200 + health = 200 + faction = list(FACTION_NEUTRAL, FACTION_MONKEY, FACTION_JUNGLE) + unique_name = FALSE + ai_controller = null + +/mob/living/basic/gorilla/cargorilla/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT) + AddComponent(/datum/component/crate_carrier) + +/** + * Poll ghosts for control of the gorilla. Not added in init because we only want to poll when the round starts. + * Preferably in future we can replace this with a popup on the lobby to queue to become a gorilla. + */ +/mob/living/basic/gorilla/cargorilla/proc/poll_for_gorilla() + AddComponent(\ + /datum/component/ghost_direct_control,\ + poll_candidates = TRUE,\ + poll_length = 30 SECONDS,\ + role_name = "Cargorilla",\ + assumed_control_message = "You are Cargorilla, a pacifist friend of the station and carrier of freight.",\ + poll_ignore_key = POLL_IGNORE_CARGORILLA,\ + after_assumed_control = CALLBACK(src, PROC_REF(became_player_controlled)),\ + ) + +/// Called once a ghost assumes control +/mob/living/basic/gorilla/cargorilla/proc/became_player_controlled() + mind.set_assigned_role(SSjob.GetJobType(/datum/job/cargo_technician)) + mind.special_role = "Cargorilla" + to_chat(src, span_notice("You can pick up crates by clicking on them, and drop them by clicking on the ground.")) + +#undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_accessories.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_accessories.dm new file mode 100644 index 00000000000..814e56487bf --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_accessories.dm @@ -0,0 +1,5 @@ +/// Cargorilla's ID card +/obj/item/card/id/advanced/cargo_gorilla + name = "cargorilla ID" + desc = "A card used to provide ID and determine access across the station. A gorilla-sized ID for a gorilla-sized cargo technician." + trim = /datum/id_trim/job/cargo_technician diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_ai.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_ai.dm new file mode 100644 index 00000000000..c6230754277 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_ai.dm @@ -0,0 +1,35 @@ +/// Pretty basic, just click people to death. Also hunt and eat bananas. +/datum/ai_controller/basic_controller/gorilla + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items/gorilla, + BB_EMOTE_KEY = "ooga", + BB_EMOTE_CHANCE = 40, + ) + + ai_traits = STOP_MOVING_WHEN_PULLED + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + + planning_subtrees = list( + /datum/ai_planning_subtree/run_emote, + /datum/ai_planning_subtree/find_food, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path/gorilla, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/targetting_datum/basic/allow_items/gorilla + stat_attack = UNCONSCIOUS + +/datum/ai_planning_subtree/attack_obstacle_in_path/gorilla + attack_behaviour = /datum/ai_behavior/attack_obstructions/gorilla + +/datum/ai_behavior/attack_obstructions/gorilla + can_attack_turfs = TRUE + +/datum/ai_controller/basic_controller/gorilla/lesser + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items, + BB_EMOTE_KEY = "ooga", + BB_EMOTE_CHANCE = 60, + ) diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/emotes.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_emotes.dm similarity index 78% rename from code/modules/mob/living/simple_animal/hostile/gorilla/emotes.dm rename to code/modules/mob/living/basic/farm_animals/gorilla/gorilla_emotes.dm index 20166d81391..94133336c4d 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/emotes.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_emotes.dm @@ -1,5 +1,5 @@ /datum/emote/gorilla - mob_type_allowed_typecache = /mob/living/simple_animal/hostile/gorilla + mob_type_allowed_typecache = /mob/living/basic/gorilla mob_type_blacklist_typecache = list() /datum/emote/gorilla/ooga @@ -9,4 +9,3 @@ message_param = "oogas at %t." emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE sound = 'sound/creatures/gorilla.ogg' - diff --git a/code/modules/mob/living/basic/heretic/flesh_worm.dm b/code/modules/mob/living/basic/heretic/flesh_worm.dm index 05ef707faf4..3c60a9b653c 100644 --- a/code/modules/mob/living/basic/heretic/flesh_worm.dm +++ b/code/modules/mob/living/basic/heretic/flesh_worm.dm @@ -38,7 +38,7 @@ AddElement(\ /datum/element/amputating_limbs,\ surgery_time = 0 SECONDS,\ - surgery_verb = "tearing",\ + surgery_verb = "tears",\ minimum_stat = CONSCIOUS,\ snip_chance = 10,\ target_zones = GLOB.arm_zones,\ diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index f7feaa88265..a048fe77ab1 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -39,7 +39,7 @@ AddElement(/datum/element/basic_eating, food_types = target_foods) AddElement(\ /datum/element/amputating_limbs,\ - surgery_verb = "snipping",\ + surgery_verb = "begins snipping",\ target_zones = GLOB.arm_zones,\ ) charge = new(src) diff --git a/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm b/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm index 8c211151123..bbfd68f8186 100644 --- a/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm +++ b/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm @@ -76,7 +76,7 @@ //Royals have bigger sprites, so inhand things must be handled differently. /mob/living/carbon/alien/adult/royal/update_held_items() - ..() + . = ..() remove_overlay(HANDS_LAYER) var/list/hands = list() diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 2aab0a5e2bb..d4fa006957e 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -282,11 +282,17 @@ update_body() /mob/living/carbon/update_held_items() + . = ..() remove_overlay(HANDS_LAYER) if (handcuffed) drop_all_held_items() return + overlays_standing[HANDS_LAYER] = get_held_overlays() + apply_overlay(HANDS_LAYER) + +/// Generate held item overlays +/mob/living/carbon/proc/get_held_overlays() var/list/hands = list() for(var/obj/item/I in held_items) if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) @@ -307,9 +313,7 @@ icon_file = I.righthand_file hands += I.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) - - overlays_standing[HANDS_LAYER] = hands - apply_overlay(HANDS_LAYER) + return hands /mob/living/carbon/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") var/fire_icon = "[dna?.species.fire_overlay || "human"]_[stacks > MOB_BIG_FIRE_STACK_THRESHOLD ? "big_fire" : "small_fire"][suffix]" diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index d1ecdfaa7aa..42eb727a83d 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -656,12 +656,7 @@ There are several things that need to be remembered: apply_overlay(LEGCUFF_LAYER) throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = src.legcuffed) -/mob/living/carbon/human/update_held_items() - remove_overlay(HANDS_LAYER) - if (handcuffed) - drop_all_held_items() - return - +/mob/living/carbon/human/get_held_overlays() var/list/hands = list() for(var/obj/item/worn_item in held_items) var/held_index = get_held_index_of_item(worn_item) @@ -690,8 +685,7 @@ There are several things that need to be remembered: held_in_hand?.held_hand_offset?.apply_offset(hand_overlay) hands += hand_overlay - overlays_standing[HANDS_LAYER] = hands - apply_overlay(HANDS_LAYER) + return hands /proc/wear_female_version(t_color, icon, layer, type, greyscale_colors, mutant_styles) // SKYRAT EDIT CHANGE - Digi female gender shaping - ORIGINAL: /proc/wear_female_version(t_color, icon, layer, type, greyscale_colors) var/index = "[t_color]-[greyscale_colors][(mutant_styles & STYLE_DIGI) ? "-d" : ""]" // SKYRAT EDIT CHANGE - Digi female gender shaping - Original: var/index = "[t_color]-[greyscale_colors]]" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3e93bc6314b..472f5c08a50 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1489,6 +1489,7 @@ /mob/living/basic/cow, /mob/living/basic/crab, /mob/living/basic/goat, + /mob/living/basic/gorilla, /mob/living/basic/headslug, /mob/living/basic/killer_tomato, /mob/living/basic/lizard, @@ -1506,7 +1507,6 @@ /mob/living/basic/statue, /mob/living/basic/stickman, /mob/living/basic/stickman/dog, - /mob/living/simple_animal/hostile/gorilla, /mob/living/simple_animal/hostile/megafauna/dragon/lesser, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet/cat, diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index a0f078acd92..75471c3cc30 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -173,6 +173,7 @@ . = ..() GLOB.drones_list += src access_card = new /obj/item/card/id/advanced/simple_bot(src) + AddComponent(/datum/component/basic_inhands, y_offset = getItemPixelShiftY()) // Doing this hurts my soul, but simple_animal access reworks are for another day. var/datum/id_trim/job/cap_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/captain] diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm index 69c2ac3e8cf..90391dff585 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm @@ -27,45 +27,6 @@ if(slot_flags & (ITEM_SLOT_HANDS|ITEM_SLOT_BACKPACK|ITEM_SLOT_DEX_STORAGE)) update_inv_internal_storage() -/mob/living/simple_animal/drone/update_held_items() - remove_overlay(DRONE_HANDS_LAYER) - var/list/hands_overlays = list() - - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - - var/y_shift = getItemPixelShiftY() - - if(r_hand) - var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = DRONE_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - if(y_shift) - r_hand_overlay.pixel_y += y_shift - - hands_overlays += r_hand_overlay - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(r_hand, ABOVE_HUD_PLANE, src) - r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) - client.screen |= r_hand - - if(l_hand) - var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = DRONE_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - if(y_shift) - l_hand_overlay.pixel_y += y_shift - - hands_overlays += l_hand_overlay - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(l_hand, ABOVE_HUD_PLANE, src) - l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) - client.screen |= l_hand - - - if(hands_overlays.len) - drone_overlays[DRONE_HANDS_LAYER] = hands_overlays - apply_overlay(DRONE_HANDS_LAYER) - - /mob/living/simple_animal/drone/proc/update_inv_internal_storage() if(internal_storage && client && hud_used?.hud_shown) internal_storage.screen_loc = ui_drone_storage diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index ea5e0685b53..9bc7ab80a0c 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -89,6 +89,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians GLOB.parasites += src update_theme(theme) AddElement(/datum/element/simple_flying) + AddComponent(/datum/component/basic_inhands) manifest_effects() /mob/living/simple_animal/hostile/guardian/Destroy() //if deleted by admins or something random, cut from the summoner @@ -461,32 +462,6 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians cut_overlay(overlay) guardian_overlays[cache_index] = null -/mob/living/simple_animal/hostile/guardian/update_held_items() - remove_overlay(GUARDIAN_HANDS_LAYER) - var/list/hands_overlays = list() - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - - if(r_hand) - hands_overlays += r_hand.build_worn_icon(default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(r_hand, ABOVE_HUD_PLANE, src) - r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) - client.screen |= r_hand - - if(l_hand) - hands_overlays += l_hand.build_worn_icon(default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(l_hand, ABOVE_HUD_PLANE, src) - l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) - client.screen |= l_hand - - if(length(hands_overlays)) - guardian_overlays[GUARDIAN_HANDS_LAYER] = hands_overlays - apply_overlay(GUARDIAN_HANDS_LAYER) - /mob/living/simple_animal/hostile/guardian/regenerate_icons() update_held_items() diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/visuals_icons.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/visuals_icons.dm deleted file mode 100644 index 39dfe8f7d89..00000000000 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/visuals_icons.dm +++ /dev/null @@ -1,56 +0,0 @@ -#define GORILLA_HANDS_LAYER 1 - -/mob/living/simple_animal/hostile/gorilla/proc/apply_overlay(cache_index) - . = gorilla_overlays[cache_index] - if(.) - add_overlay(.) - -/mob/living/simple_animal/hostile/gorilla/proc/remove_overlay(cache_index) - var/I = gorilla_overlays[cache_index] - if(I) - cut_overlay(I) - gorilla_overlays[cache_index] = null - -/mob/living/simple_animal/hostile/gorilla/update_held_items() - cut_overlays("standing_overlay") - remove_overlay(GORILLA_HANDS_LAYER) - - var/standing = FALSE - for(var/I in held_items) - if(I) - standing = TRUE - break - if(!standing) - if(stat != DEAD) - icon_state = "crawling" - set_varspeed(0.5) - return ..() - if(stat != DEAD) - icon_state = "standing" - set_varspeed(1) // Gorillas are slow when standing up. - - var/list/hands_overlays = list() - - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - - if(r_hand) - var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = GORILLA_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - r_hand_overlay.pixel_y -= 1 - hands_overlays += r_hand_overlay - - if(l_hand) - var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = GORILLA_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - l_hand_overlay.pixel_y -= 1 - hands_overlays += l_hand_overlay - - if(hands_overlays.len) - gorilla_overlays[GORILLA_HANDS_LAYER] = hands_overlays - apply_overlay(GORILLA_HANDS_LAYER) - add_overlay("standing_overlay") - return ..() - -/mob/living/simple_animal/hostile/gorilla/regenerate_icons() - update_held_items() - -#undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3b16ab685eb..8fdc7acaf42 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -603,6 +603,7 @@ update_held_items() /mob/living/simple_animal/update_held_items() + . = ..() if(!client || !hud_used || hud_used.hud_version == HUD_STYLE_NOHUD) return var/turf/our_turf = get_turf(src) diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm index 8a6464ee182..b8b84f8782a 100644 --- a/code/modules/mob/mob_update_icons.dm +++ b/code/modules/mob/mob_update_icons.dm @@ -26,7 +26,8 @@ ///Updates the held items overlay(s) & HUD element. /mob/proc/update_held_items() - return + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOB_UPDATE_HELD_ITEMS) ///Updates the mask overlay & HUD element. /mob/proc/update_worn_mask() diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 09ce3b3c65c..ed7e336f875 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -298,7 +298,7 @@ regenerate_icons() icon = null invisibility = INVISIBILITY_MAXIMUM - var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src)) + var/mob/living/basic/gorilla/new_gorilla = new (get_turf(src)) new_gorilla.set_combat_mode(TRUE) if(mind) mind.transfer_to(new_gorilla) diff --git a/code/modules/spells/spell_types/conjure/simian.dm b/code/modules/spells/spell_types/conjure/simian.dm index 556a78e5012..aa9aabc6810 100644 --- a/code/modules/spells/spell_types/conjure/simian.dm +++ b/code/modules/spells/spell_types/conjure/simian.dm @@ -14,14 +14,18 @@ invocation_type = INVOCATION_SHOUT summon_radius = 2 - summon_type = list(/mob/living/carbon/human/species/monkey/angry, /mob/living/carbon/human/species/monkey/angry, /mob/living/simple_animal/hostile/gorilla/lesser) + summon_type = list( + /mob/living/basic/gorilla/lesser, + /mob/living/carbon/human/species/monkey/angry, + /mob/living/carbon/human/species/monkey/angry, // Listed twice so it's twice as likely, this class doesn't use pick weight + ) summon_amount = 4 /datum/action/cooldown/spell/conjure/simian/level_spell(bypass_cap) . = ..() summon_amount++ // MORE, MOOOOORE if(spell_level == spell_max_level) // We reward the faithful. - summon_type = list(/mob/living/carbon/human/species/monkey/angry, /mob/living/simple_animal/hostile/gorilla) + summon_type = list(/mob/living/carbon/human/species/monkey/angry, /mob/living/basic/gorilla) spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC // Max level lets you cast it naked, for monkey larp. to_chat(owner, span_notice("Your simian power has reached maximum capacity! You can now cast this spell naked, and you will create adult Gorillas with each cast.")) diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 92416001b79..4066926f7a5 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -87,9 +87,6 @@ /mob/living/simple_animal/hostile/construct/wraith/mystic, /mob/living/simple_animal/hostile/construct/wraith/noncult, /mob/living/simple_animal/hostile/dark_wizard, - /mob/living/simple_animal/hostile/gorilla, - /mob/living/simple_animal/hostile/gorilla/lesser, - /mob/living/simple_animal/hostile/gorilla/cargo_domestic, /mob/living/simple_animal/hostile/guardian, /mob/living/simple_animal/hostile/guardian/assassin, /mob/living/simple_animal/hostile/guardian/charger, diff --git a/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm b/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm index 422a2d16c01..b3486f40ba7 100644 --- a/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm +++ b/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm @@ -11,7 +11,7 @@ JOB_QUARTERMASTER = list( /mob/living/basic/sloth/citrus, /mob/living/basic/sloth/paperwork, - /mob/living/simple_animal/hostile/gorilla/cargo_domestic, + /mob/living/basic/gorilla/cargorilla, ), // Non-heads like the warden, these are automatically medium-risk at minimum // They are also the only two modular additions so far diff --git a/modular_skyrat/modules/emotes/code/scream_emote.dm b/modular_skyrat/modules/emotes/code/scream_emote.dm index dd07e81cec8..50619d1bd85 100644 --- a/modular_skyrat/modules/emotes/code/scream_emote.dm +++ b/modular_skyrat/modules/emotes/code/scream_emote.dm @@ -24,7 +24,7 @@ return 'modular_skyrat/modules/emotes/sound/voice/scream_silicon.ogg' if(ismonkey(user)) return 'modular_skyrat/modules/emotes/sound/voice/scream_monkey.ogg' - if(istype(user, /mob/living/simple_animal/hostile/gorilla)) + if(istype(user, /mob/living/basic/gorilla)) return 'sound/creatures/gorilla.ogg' if(isalien(user)) return 'sound/voice/hiss6.ogg' diff --git a/strings/sillytips.txt b/strings/sillytips.txt index 752a09b25cb..5aa7af7ba00 100644 --- a/strings/sillytips.txt +++ b/strings/sillytips.txt @@ -37,3 +37,4 @@ To defeat the slaughter demon, shoot at it until it dies. When a round ends nearly everything about it is lost forever, leave your salt behind with it. You can win a pulse rifle from the arcade machine. Honest. Your sprite represents your hitbox, so that afro makes you easier to kill. The sacrifices we make for style. +Gorillas can be killed by land mines placed along forest paths. diff --git a/tgstation.dme b/tgstation.dme index 006c2049ec3..36fd50e4ba4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -921,6 +921,7 @@ #include "code\datums\ai\basic_mobs\basic_subtrees\move_to_cardinal.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\opportunistic_ventcrawler.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\ranged_skirmish.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\run_emote.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\shapechange_ambush.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_attack_target.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_find_nearest_target_to_flee.dm" @@ -1029,6 +1030,7 @@ #include "code\datums\components\attached_sticker.dm" #include "code\datums\components\aura_healing.dm" #include "code\datums\components\bakeable.dm" +#include "code\datums\components\basic_inhands.dm" #include "code\datums\components\basic_mob_attack_telegraph.dm" #include "code\datums\components\basic_ranged_ready_overlay.dm" #include "code\datums\components\beetlejuice.dm" @@ -4469,6 +4471,10 @@ #include "code\modules\mob\living\basic\farm_animals\goat\_goat.dm" #include "code\modules\mob\living\basic\farm_animals\goat\goat_ai.dm" #include "code\modules\mob\living\basic\farm_animals\goat\goat_subtypes.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla_accessories.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla_ai.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla_emotes.dm" #include "code\modules\mob\living\basic\heretic\ash_spirit.dm" #include "code\modules\mob\living\basic\heretic\fire_shark.dm" #include "code\modules\mob\living\basic\heretic\flesh_stalker.dm" @@ -4826,9 +4832,6 @@ #include "code\modules\mob\living\simple_animal\hostile\constructs\harvester.dm" #include "code\modules\mob\living\simple_animal\hostile\constructs\juggernaut.dm" #include "code\modules\mob\living\simple_animal\hostile\constructs\wraith.dm" -#include "code\modules\mob\living\simple_animal\hostile\gorilla\emotes.dm" -#include "code\modules\mob\living\simple_animal\hostile\gorilla\gorilla.dm" -#include "code\modules\mob\living\simple_animal\hostile\gorilla\visuals_icons.dm" #include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm" #include "code\modules\mob\living\simple_animal\hostile\jungle\mook.dm" diff --git a/tools/UpdatePaths/Scripts/78918_simple_to_basic_gorilla.txt b/tools/UpdatePaths/Scripts/78918_simple_to_basic_gorilla.txt new file mode 100644 index 00000000000..a22b7848d35 --- /dev/null +++ b/tools/UpdatePaths/Scripts/78918_simple_to_basic_gorilla.txt @@ -0,0 +1,2 @@ +/mob/living/simple_animal/hostile/gorilla/cargo_domestic : /mob/living/basic/gorilla/cargorilla{@OLD} +/mob/living/simple_animal/hostile/gorilla : /mob/living/basic/gorilla/@SUBTYPES{@OLD}