From 0e36ba080869dba24cea094c1cce4e478a91509e Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Mon, 5 Aug 2024 06:59:12 +0300 Subject: [PATCH] converts most pet behavior into elements (#85290) ## About The Pull Request refactors pet behaviors, such as collars and pet cultists into elements. also this is a first step to completely removing the pet subtype ## Why It's Good For The Game this means itll be alot easier for coders to make their tameable mobs able to wear pet collars without having to make them of the pet subtype, which i also plan to do ## Changelog :cl: refactor: refactors pet collars and cultist pets into elements /:cl: --- code/datums/elements/pet_collar.dm | 95 +++++++++++++ code/datums/elements/pet_cult.dm | 127 +++++++++++++++++ code/modules/mob/living/basic/pets/cat/cat.dm | 14 +- .../modules/mob/living/basic/pets/dog/_dog.dm | 6 + .../mob/living/basic/pets/dog/corgi.dm | 2 +- .../living/basic/pets/dog/strippable_items.dm | 16 +-- code/modules/mob/living/basic/pets/fox.dm | 2 + code/modules/mob/living/basic/pets/penguin.dm | 2 + code/modules/mob/living/basic/pets/pet.dm | 134 ------------------ .../living/basic/pets/pet_cult/pet_cult.dm | 85 ----------- tgstation.dme | 3 +- 11 files changed, 247 insertions(+), 239 deletions(-) create mode 100644 code/datums/elements/pet_collar.dm create mode 100644 code/datums/elements/pet_cult.dm delete mode 100644 code/modules/mob/living/basic/pets/pet_cult/pet_cult.dm diff --git a/code/datums/elements/pet_collar.dm b/code/datums/elements/pet_collar.dm new file mode 100644 index 00000000000..5c49de2eceb --- /dev/null +++ b/code/datums/elements/pet_collar.dm @@ -0,0 +1,95 @@ +/datum/element/wears_collar + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + ///our icon's pathfile + var/collar_icon + ///our collar's icon state + var/collar_icon_state + ///iconstate of our collar while resting + var/collar_resting_icon_state + +/datum/element/wears_collar/Attach(datum/target, collar_icon = 'icons/mob/simple/pets.dmi', collar_resting_icon_state = FALSE, collar_icon_state) + . = ..() + + if(!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.collar_icon = collar_icon + src.collar_icon_state = collar_icon_state + src.collar_resting_icon_state = collar_resting_icon_state + + RegisterSignal(target, COMSIG_ATOM_ATTACKBY, PROC_REF(attach_collar)) + RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_overlays_updated)) + RegisterSignal(target, COMSIG_ATOM_EXITED, PROC_REF(on_content_exit)) + RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_content_enter)) + RegisterSignal(target, COMSIG_LIVING_RESTING, PROC_REF(on_rest)) + RegisterSignal(target, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change)) + +/datum/element/wears_collar/Detach(datum/target) + . = ..() + UnregisterSignal(target, list( + COMSIG_ATOM_ATTACKBY, + COMSIG_ATOM_UPDATE_OVERLAYS, + COMSIG_ATOM_EXITED, + COMSIG_ATOM_ENTERED, + COMSIG_LIVING_RESTING, + COMSIG_MOB_STATCHANGE, + )) + +/datum/element/wears_collar/proc/on_stat_change(mob/living/source) + SIGNAL_HANDLER + + if(collar_icon_state) + source.update_icon(UPDATE_OVERLAYS) + +/datum/element/wears_collar/proc/on_content_exit(mob/living/source, atom/moved) + SIGNAL_HANDLER + + if(!istype(moved, /obj/item/clothing/neck/petcollar)) + return + source.fully_replace_character_name(null, source::name) + if(collar_icon_state) + source.update_appearance() + +/datum/element/wears_collar/proc/on_content_enter(mob/living/source, obj/item/clothing/neck/petcollar/new_collar) + SIGNAL_HANDLER + + if(!istype(new_collar)) + return + + source.fully_replace_character_name(null, "\proper [new_collar.tagname]") + if(collar_icon_state) + source.update_appearance() + +/datum/element/wears_collar/proc/attach_collar(atom/source, atom/movable/attacking_item, atom/user, params) + SIGNAL_HANDLER + + if(!istype(attacking_item, /obj/item/clothing/neck/petcollar)) + return NONE + if(locate(/obj/item/clothing/neck/petcollar) in source) + user.balloon_alert(source, "already wearing a collar!") + return NONE + attacking_item.forceMove(source) + return COMPONENT_NO_AFTERATTACK + +/datum/element/wears_collar/proc/on_overlays_updated(mob/living/source, list/overlays) + SIGNAL_HANDLER + + if(!locate(/obj/item/clothing/neck/petcollar) in source) + return + + var/icon_tag = "" + + if(source.stat == DEAD || HAS_TRAIT(source, TRAIT_FAKEDEATH)) + icon_tag = "_dead" + else if(collar_resting_icon_state && source.resting) + icon_tag = "_rest" + + overlays += mutable_appearance(collar_icon, "[collar_icon_state][icon_tag]collar") + overlays += mutable_appearance(collar_icon, "[collar_icon_state][icon_tag]tag") + + +/datum/element/wears_collar/proc/on_rest(atom/movable/source) + SIGNAL_HANDLER + + source.update_icon(UPDATE_OVERLAYS) diff --git a/code/datums/elements/pet_cult.dm b/code/datums/elements/pet_cult.dm new file mode 100644 index 00000000000..36941e7b742 --- /dev/null +++ b/code/datums/elements/pet_cult.dm @@ -0,0 +1,127 @@ +#define PET_CULT_ATTACK_UPPER 15 +#define PET_CULT_HEALTH 50 + +/datum/element/cultist_pet + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + ///our pet cult icon's pathfile + var/pet_cult_icon + ///our pet cult icon state + var/pet_cult_icon_state + +/datum/element/cultist_pet/Attach(datum/target, pet_cult_icon = 'icons/mob/simple/pets.dmi', pet_cult_icon_state) + . = ..() + + if(!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.pet_cult_icon = pet_cult_icon + src.pet_cult_icon_state = pet_cult_icon_state + + RegisterSignal(target, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(become_cultist)) + RegisterSignal(target, COMSIG_MOB_CLIENT_LOGIN, PROC_REF(on_login)) + RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(on_icon_state_updated)) + RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_overlays_updated)) + +/datum/element/cultist_pet/Detach(datum/target) + . = ..() + UnregisterSignal(target, list( + COMSIG_MOB_LOGIN, + COMSIG_LIVING_CULT_SACRIFICED, + COMSIG_ATOM_UPDATE_ICON_STATE, + COMSIG_ATOM_UPDATE_OVERLAYS, + )) + +/datum/element/cultist_pet/proc/on_overlays_updated(mob/living/basic/source, list/overlays) + SIGNAL_HANDLER + + if(isnull(source.mind) && (FACTION_CULT in source.faction)) //cult indicator we show for non sentient pets + var/image/cult_indicator = image(icon = 'icons/mob/simple/pets.dmi', icon_state = "pet_cult_indicator", layer = ABOVE_GAME_PLANE) + overlays += cult_indicator + +/datum/element/cultist_pet/proc/on_icon_state_updated(mob/living/basic/source) + SIGNAL_HANDLER + + if(pet_cult_icon_state && (FACTION_CULT in source.faction)) + source.icon_state = pet_cult_icon_state + source.icon_living = pet_cult_icon_state + +///turn into terrifying beasts +/datum/element/cultist_pet/proc/become_cultist(mob/living/basic/source, list/invokers, datum/team) + SIGNAL_HANDLER + + if(source.stat == DEAD) + return + + if(FACTION_CULT in source.faction) + return STOP_SACRIFICE + + source.mind?.add_antag_datum(/datum/antagonist/cult, team) + qdel(source.GetComponent(/datum/component/obeys_commands)) //if we obey commands previously, forget about them + source.melee_damage_lower = max(PET_CULT_ATTACK_UPPER - 5, source::melee_damage_lower) + source.melee_damage_upper = max(PET_CULT_ATTACK_UPPER, source::melee_damage_upper) + source.maxHealth = max(PET_CULT_HEALTH, source::maxHealth) + source.fully_heal() + + source.faction = list(FACTION_CULT) //we only serve the cult + + if(isnull(pet_cult_icon_state)) + source.add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY) + + var/static/list/cult_appetite = list( + /obj/item/organ, + /obj/effect/decal/cleanable/blood, + ) + + var/static/list/death_loot = list( + /obj/effect/gibspawner/generic, + /obj/item/soulstone, + ) + + source.AddElement(/datum/element/basic_eating, heal_amt = 15, food_types = cult_appetite) + source.AddElement(/datum/element/death_drops, death_loot) + + source.basic_mob_flags &= DEL_ON_DEATH + qdel(source.ai_controller) + source.ai_controller = new /datum/ai_controller/basic_controller/pet_cult(source) + var/datum/action/cooldown/spell/conjure/revive_rune/rune_ability = new(source) + rune_ability.Grant(source) + source.ai_controller.set_blackboard_key(BB_RUNE_ABILITY, rune_ability) + source.ai_controller.set_blackboard_key(BB_CULT_TEAM, team) + + var/static/list/new_pet_commands = list( + /datum/pet_command/point_targeting/attack, + /datum/pet_command/follow, + /datum/pet_command/free, + /datum/pet_command/idle, + /datum/pet_command/untargeted_ability/draw_rune, + ) + source.AddComponent(/datum/component/obeys_commands, new_pet_commands) + RegisterSignal(source, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(activate_rune)) + source.update_appearance() + return STOP_SACRIFICE + + +/datum/element/cultist_pet/proc/activate_rune(datum/source, atom/target) + SIGNAL_HANDLER + + if(!istype(target, /obj/effect/rune/raise_dead)) //we can only revive people... + return NONE + + INVOKE_ASYNC(target, TYPE_PROC_REF(/atom, attack_hand), source) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/element/cultist_pet/proc/on_login(mob/living/source) + SIGNAL_HANDLER + + if(!(FACTION_CULT in source.faction)) + return + var/datum/team/cult_team = source.ai_controller.blackboard[BB_CULT_TEAM] + if(isnull(cult_team)) + return + source.mind.add_antag_datum(/datum/antagonist/cult, cult_team) + source.update_appearance(UPDATE_OVERLAYS) + + +#undef PET_CULT_ATTACK_UPPER +#undef PET_CULT_HEALTH diff --git a/code/modules/mob/living/basic/pets/cat/cat.dm b/code/modules/mob/living/basic/pets/cat/cat.dm index 400bd9ac9f1..2bcd715d7f5 100644 --- a/code/modules/mob/living/basic/pets/cat/cat.dm +++ b/code/modules/mob/living/basic/pets/cat/cat.dm @@ -24,8 +24,6 @@ response_harm_simple = "kick" mobility_flags = MOBILITY_FLAGS_REST_CAPABLE_DEFAULT gold_core_spawnable = FRIENDLY_SPAWN - collar_icon_state = "cat" - has_collar_resting_icon_state = TRUE can_be_held = TRUE ai_controller = /datum/ai_controller/basic_controller/cat held_state = "cat2" @@ -33,7 +31,8 @@ attack_verb_simple = "claw" attack_sound = 'sound/weapons/slash.ogg' attack_vis_effect = ATTACK_EFFECT_CLAW - cult_icon_state = "cat_cult" + ///icon of the collar we can wear + var/collar_icon_state = "cat" ///can this cat breed? var/can_breed = TRUE ///can hold items? @@ -50,9 +49,13 @@ var/obj/item/held_food ///mutable appearance for held item var/mutable_appearance/held_item_overlay + ///icon state of our cult icon + var/cult_icon_state = "cat_cult" /mob/living/basic/pet/cat/Initialize(mapload) . = ..() + AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state) + AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state, collar_resting_icon_state = TRUE) AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/pet_bonus, "purrs!") AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) @@ -147,7 +150,6 @@ icon_living = "breadcat" icon_dead = "breadcat_dead" ai_controller = /datum/ai_controller/basic_controller/cat/bread - collar_icon_state = null held_state = "breadcat" can_interact_with_stove = TRUE butcher_results = list( @@ -156,6 +158,7 @@ /obj/item/organ/external/tail/cat = 1, /obj/item/food/breadslice/plain = 1 ) + collar_icon_state = null /mob/living/basic/pet/cat/breadcat/add_cell_sample() return @@ -167,7 +170,6 @@ icon_state = "original" icon_living = "original" icon_dead = "original_dead" - collar_icon_state = null unique_pet = TRUE held_state = "original" @@ -183,10 +185,10 @@ density = FALSE pass_flags = PASSMOB mob_size = MOB_SIZE_SMALL - collar_icon_state = "kitten" can_breed = FALSE ai_controller = /datum/ai_controller/basic_controller/cat/kitten can_hold_item = FALSE + collar_icon_state = "kitten" /mob/living/basic/pet/cat/kitten/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm index 5cd970575ec..b1c2c5e486f 100644 --- a/code/modules/mob/living/basic/pets/dog/_dog.dm +++ b/code/modules/mob/living/basic/pets/dog/_dog.dm @@ -44,9 +44,15 @@ /datum/pet_command/point_targeting/fetch, /datum/pet_command/play_dead, ) + ///icon state of the collar we can wear + var/collar_icon_state + ///icon state of our cult icon + var/cult_icon_state /mob/living/basic/pet/dog/Initialize(mapload) . = ..() + AddElement(/datum/element/cultist_pet, pet_cult_icon_state = cult_icon_state) + AddElement(/datum/element/wears_collar, collar_icon_state = collar_icon_state) ADD_TRAIT(src, TRAIT_WOUND_LICKER, INNATE_TRAIT) AddElement(/datum/element/pet_bonus, "woofs happily!") AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) diff --git a/code/modules/mob/living/basic/pets/dog/corgi.dm b/code/modules/mob/living/basic/pets/dog/corgi.dm index 7e13c792d28..e1f05b33d81 100644 --- a/code/modules/mob/living/basic/pets/dog/corgi.dm +++ b/code/modules/mob/living/basic/pets/dog/corgi.dm @@ -544,9 +544,9 @@ pass_flags = PASSMOB ai_controller = /datum/ai_controller/basic_controller/dog/puppy mob_size = MOB_SIZE_SMALL - collar_icon_state = "puppy" strippable_inventory_slots = list(/datum/strippable_item/pet_collar, /datum/strippable_item/corgi_id) //puppies are too small to handle hats and back slot items can_breed = FALSE + collar_icon_state = "puppy" //PUPPY IAN! SQUEEEEEEEEE~ /mob/living/basic/pet/dog/corgi/puppy/ian diff --git a/code/modules/mob/living/basic/pets/dog/strippable_items.dm b/code/modules/mob/living/basic/pets/dog/strippable_items.dm index 2799ca38b97..c92948e2b6f 100644 --- a/code/modules/mob/living/basic/pets/dog/strippable_items.dm +++ b/code/modules/mob/living/basic/pets/dog/strippable_items.dm @@ -38,11 +38,11 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( key = STRIPPABLE_ITEM_PET_COLLAR /datum/strippable_item/pet_collar/get_item(atom/source) - var/mob/living/basic/pet/pet_source = source + var/mob/living/basic/pet_source = source if(!istype(pet_source)) return - return pet_source.collar + return (locate(/obj/item/clothing/neck/petcollar) in source) /datum/strippable_item/pet_collar/try_equip(atom/source, obj/item/equipping, mob/user) . = ..() @@ -56,18 +56,10 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list( return TRUE /datum/strippable_item/pet_collar/finish_equip(atom/source, obj/item/equipping, mob/user) - var/mob/living/basic/pet/pet_source = source - if(!istype(pet_source)) - return - - pet_source.add_collar(equipping, user) + user.transferItemToLoc(equipping, source) /datum/strippable_item/pet_collar/finish_unequip(atom/source, mob/user) - var/mob/living/basic/pet/pet_source = source - if(!istype(pet_source)) - return - - var/obj/collar = pet_source.remove_collar(user.drop_location()) + var/obj/item/clothing/neck/petcollar/collar = locate() in source user.put_in_hands(collar) /datum/strippable_item/corgi_back diff --git a/code/modules/mob/living/basic/pets/fox.dm b/code/modules/mob/living/basic/pets/fox.dm index 03ac2be54be..e4e978568a0 100644 --- a/code/modules/mob/living/basic/pets/fox.dm +++ b/code/modules/mob/living/basic/pets/fox.dm @@ -31,6 +31,8 @@ /mob/living/basic/pet/fox/Initialize(mapload) . = ..() + AddElement(/datum/element/cultist_pet) + AddElement(/datum/element/wears_collar) AddElement(/datum/element/pet_bonus, "pants and yaps happily!") AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) AddElement(/datum/element/tiny_mob_hunter, MOB_SIZE_SMALL) diff --git a/code/modules/mob/living/basic/pets/penguin.dm b/code/modules/mob/living/basic/pets/penguin.dm index 1bf3adec557..a597bd70cbb 100644 --- a/code/modules/mob/living/basic/pets/penguin.dm +++ b/code/modules/mob/living/basic/pets/penguin.dm @@ -20,6 +20,8 @@ /mob/living/basic/pet/penguin/Initialize(mapload) . = ..() + AddElement(/datum/element/cultist_pet) + AddElement(/datum/element/wears_collar) AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) AddElement(/datum/element/pet_bonus, "honks happily!") diff --git a/code/modules/mob/living/basic/pets/pet.dm b/code/modules/mob/living/basic/pets/pet.dm index de5ad59eb1f..64896a3f2ab 100644 --- a/code/modules/mob/living/basic/pets/pet.dm +++ b/code/modules/mob/living/basic/pets/pet.dm @@ -3,146 +3,12 @@ mob_size = MOB_SIZE_SMALL mob_biotypes = MOB_ORGANIC|MOB_BEAST blood_volume = BLOOD_VOLUME_NORMAL - /// if the mob is protected from being renamed by collars. var/unique_pet = FALSE - /// If the mob has collar sprites, this is the base of the icon states. - var/collar_icon_state = null - /// We have a seperate _rest collar icon state when the pet is resting. - var/has_collar_resting_icon_state = FALSE - /// Our collar - var/obj/item/clothing/neck/petcollar/collar - ///can we become cultists? - var/can_cult_convert = TRUE - ///whether we have a custom icon state when we get culted - var/cult_icon_state -/mob/living/basic/pet/Initialize(mapload) - . = ..() - - /// Can set the collar var beforehand to start the pet with a collar. - if(collar) - collar = new(src) - - update_icon(UPDATE_OVERLAYS) - if(can_cult_convert) - RegisterSignal(src, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(become_cultist)) - -/mob/living/basic/pet/Destroy() - . = ..() - - QDEL_NULL(collar) - -/mob/living/basic/pet/attackby(obj/item/thing, mob/user, params) - if(istype(thing, /obj/item/clothing/neck/petcollar) && !collar) - add_collar(thing, user) - return TRUE - - if(istype(thing, /obj/item/newspaper) && !stat) - user.visible_message(span_notice("[user] baps [name] on the nose with the rolled up [thing].")) - dance_rotate(src) - return TRUE - - return ..() - -/mob/living/basic/pet/update_overlays() - . = ..() - - if(isnull(mind) && (FACTION_CULT in faction)) - var/image/cult_indicator = image(icon = 'icons/mob/simple/pets.dmi', icon_state = "pet_cult_indicator", layer = ABOVE_GAME_PLANE) - . += cult_indicator - - if(!collar || !collar_icon_state) - return - - // Determine which status tag to add to the middle of the icon state. - var/dead_tag = (stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH)) ? "_dead" : null - var/rest_tag = has_collar_resting_icon_state && resting ? "_rest" : null - var/stat_tag = dead_tag || rest_tag || "" - - . += mutable_appearance(icon, "[collar_icon_state][stat_tag]collar") - . += mutable_appearance(icon, "[collar_icon_state][stat_tag]tag") - -/mob/living/basic/pet/update_icon_state() - if(cult_icon_state && (FACTION_CULT in faction)) - icon_state = cult_icon_state - icon_living = cult_icon_state - return ..() - -/mob/living/basic/pet/gib() - remove_collar(drop_location(), update_visuals = FALSE) - return ..() - -/mob/living/basic/pet/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) - . = ..() - if(!.) - return - - update_icon(UPDATE_OVERLAYS) /mob/living/basic/pet/death(gibbed) . = ..() add_memory_in_range(src, 7, /datum/memory/pet_died, deuteragonist = src) //Protagonist is the person memorizing it -/mob/living/basic/pet/Exited(atom/movable/gone, direction) - . = ..() - if(gone != collar) - return - collar = null - - if(QDELETED(src)) - return - - update_icon(UPDATE_OVERLAYS) - -/mob/living/basic/pet/update_stat() - . = ..() - - update_icon(UPDATE_OVERLAYS) - -/mob/living/basic/pet/set_resting(new_resting, silent, instant) - . = ..() - - if(!has_collar_resting_icon_state) - return - - update_icon(UPDATE_OVERLAYS) - -/** - * Add a collar to the pet. - * - * Arguments: - * * new_collar - the collar. - * * user - the user that did it. - */ -/mob/living/basic/pet/proc/add_collar(obj/item/clothing/neck/petcollar/new_collar, mob/user) - if(QDELETED(new_collar) || collar) - return - if(!user.transferItemToLoc(new_collar, src)) - return - - collar = new_collar - if(collar_icon_state) - update_icon(UPDATE_OVERLAYS) - - to_chat(user, span_notice("You put [new_collar] around [src]'s neck.")) - if(new_collar.tagname && !unique_pet) - fully_replace_character_name(null, "\proper [new_collar.tagname]") - -/** - * Remove the collar from the pet. - */ -/mob/living/basic/pet/proc/remove_collar(atom/new_loc, update_visuals = TRUE) - if(!collar) - return - - var/obj/old_collar = collar - - collar.forceMove(new_loc) - collar = null - - if(collar_icon_state && update_visuals) - update_icon(UPDATE_OVERLAYS) - - return old_collar diff --git a/code/modules/mob/living/basic/pets/pet_cult/pet_cult.dm b/code/modules/mob/living/basic/pets/pet_cult/pet_cult.dm deleted file mode 100644 index 438737a1ad2..00000000000 --- a/code/modules/mob/living/basic/pets/pet_cult/pet_cult.dm +++ /dev/null @@ -1,85 +0,0 @@ -#define PET_CULT_ATTACK 10 -#define PET_CULT_HEALTH 50 - -///turn into terrifying beasts -/mob/living/basic/pet/proc/become_cultist(datum/source, list/invokers, datum/team) - SIGNAL_HANDLER - - if(stat == DEAD || !can_cult_convert) - return - - if(FACTION_CULT in faction) - return STOP_SACRIFICE - - mind?.add_antag_datum(/datum/antagonist/cult, team) - qdel(GetComponent(/datum/component/obeys_commands)) - melee_damage_lower = max(PET_CULT_ATTACK, initial(melee_damage_lower)) - melee_damage_upper = max(PET_CULT_ATTACK + 5, initial(melee_damage_upper)) - maxHealth = max(PET_CULT_HEALTH, initial(maxHealth)) - fully_heal() - - faction = list(FACTION_CULT) //we only serve the cult - - if(isnull(cult_icon_state)) - add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY) - - var/static/list/cult_appetite = list( - /obj/item/organ, - /obj/effect/decal/cleanable/blood, - ) - - var/static/list/death_loot = list( - /obj/effect/gibspawner/generic, - /obj/item/soulstone, - ) - - AddElement(/datum/element/basic_eating, heal_amt = 15, food_types = cult_appetite) - AddElement(/datum/element/death_drops, death_loot) - - basic_mob_flags &= DEL_ON_DEATH - qdel(ai_controller) - ai_controller = new /datum/ai_controller/basic_controller/pet_cult(src) - var/datum/action/cooldown/spell/conjure/revive_rune/rune_ability = new(src) - rune_ability.Grant(src) - ai_controller.set_blackboard_key(BB_RUNE_ABILITY, rune_ability) - ai_controller.set_blackboard_key(BB_CULT_TEAM, team) - - var/static/list/new_pet_commands = list( - /datum/pet_command/point_targeting/attack, - /datum/pet_command/follow, - /datum/pet_command/free, - /datum/pet_command/idle, - /datum/pet_command/untargeted_ability/draw_rune, - ) - AddComponent(/datum/component/obeys_commands, new_pet_commands) - RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(activate_rune), override = TRUE) - update_appearance() - return STOP_SACRIFICE - - -/mob/living/basic/pet/proc/activate_rune(datum/source, atom/target) - SIGNAL_HANDLER - - if(!istype(target, /obj/effect/rune/raise_dead)) - return NONE - - target.attack_hand(src) - - return COMPONENT_CANCEL_ATTACK_CHAIN - -/mob/living/basic/pet/Login() - . = ..() - if(!. || !client) - return FALSE - - if(!(FACTION_CULT in faction)) - return - var/datum/team/cult_team = locate(/datum/team/cult) in GLOB.antagonist_teams - if(isnull(cult_team)) - return - mind.add_antag_datum(/datum/antagonist/cult, cult_team) - update_appearance(UPDATE_OVERLAYS) - - -#undef PET_CULT_ATTACK -#undef PET_CULT_HEALTH diff --git a/tgstation.dme b/tgstation.dme index 988f95e1fb9..d20a3527245 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1510,6 +1510,8 @@ #include "code\datums\elements\organ_set_bonus.dm" #include "code\datums\elements\permanent_fire_overlay.dm" #include "code\datums\elements\pet_bonus.dm" +#include "code\datums\elements\pet_collar.dm" +#include "code\datums\elements\pet_cult.dm" #include "code\datums\elements\plant_backfire.dm" #include "code\datums\elements\point_of_interest.dm" #include "code\datums\elements\poster_tearer.dm" @@ -4912,7 +4914,6 @@ #include "code\modules\mob\living\basic\pets\parrot\parrot_ai\parrot_hoarding.dm" #include "code\modules\mob\living\basic\pets\parrot\parrot_ai\parrot_perching.dm" #include "code\modules\mob\living\basic\pets\parrot\parrot_ai\parroting_action.dm" -#include "code\modules\mob\living\basic\pets\pet_cult\pet_cult.dm" #include "code\modules\mob\living\basic\pets\pet_cult\pet_cult_abilities.dm" #include "code\modules\mob\living\basic\pets\pet_cult\pet_cult_ai.dm" #include "code\modules\mob\living\basic\ruin_defender\cybersun_aicore.dm"