mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 12:35:33 +01:00
snails (#90505)
## About The Pull Request adds snails to the game  these are harmless critters you can find in maints. they love eating all variety of fruits, and are gravitated towards snail people, where they'll dance around them. you can also pick them up and put them on your head. finally, you can also grab them and put them in hydrotrays (they will swim around in it very slowly). they'll help ur plants grow as they act as natural weed-repellants, as they'll eat weeds that grow in trays.  ## Why It's Good For The Game there's not that many mobs you can usually find in maints, currently there's only mice and cockroaches, this helps expand the pools a bit. ## Changelog 🆑 add: adds snails to the game. (keep them away from salt!) /🆑
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/mob/living/basic/snail
|
||||
name = "snail"
|
||||
desc = "Is petting this thing sanitary?"
|
||||
icon_state = "snail"
|
||||
icon_living = "snail"
|
||||
icon_dead = "snail_dead"
|
||||
base_icon_state = "snail"
|
||||
held_state = "snail"
|
||||
head_icon = 'icons/mob/clothing/head/pets_head.dmi'
|
||||
icon = 'icons/mob/simple/pets.dmi'
|
||||
butcher_results = list(/obj/item/food/meat/slab/bugmeat = 1)
|
||||
mob_biotypes = MOB_ORGANIC
|
||||
health = 30
|
||||
maxHealth = 30
|
||||
speed = 6
|
||||
verb_say = "gurgles"
|
||||
verb_ask = "gurgles curiously"
|
||||
can_be_held = TRUE
|
||||
verb_exclaim = "gurgles loudly"
|
||||
verb_yell = "gurgles loudly"
|
||||
worn_slot_flags = ITEM_SLOT_HEAD
|
||||
faction = list(FACTION_NEUTRAL, FACTION_MAINT_CREATURES)
|
||||
ai_controller = /datum/ai_controller/basic_controller/snail
|
||||
|
||||
/mob/living/basic/snail/Initialize(mapload)
|
||||
. = ..()
|
||||
var/static/list/loc_connections = list(COMSIG_ATOM_ENTERED = PROC_REF(on_entered))
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
var/static/list/eatable_food = list(
|
||||
/obj/item/food/grown,
|
||||
/obj/item/food/appleslice,
|
||||
)
|
||||
|
||||
var/static/list/innate_actions = list(
|
||||
/datum/action/cooldown/mob_cooldown/shell_retreat = BB_SNAIL_RETREAT_ABILITY,
|
||||
)
|
||||
|
||||
grant_actions_by_list(innate_actions)
|
||||
AddElement(/datum/element/ai_retaliate)
|
||||
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(eatable_food))
|
||||
AddElement(/datum/element/basic_eating, food_types = eatable_food)
|
||||
create_reagents(100, REAGENT_HOLDER_ALIVE)
|
||||
RegisterSignal(reagents, COMSIG_REAGENTS_HOLDER_UPDATED, PROC_REF(on_reagents_update))
|
||||
|
||||
/mob/living/basic/snail/proc/on_entered(datum/source, obj/effect/decal/cleanable/food/salt/potential_salt)
|
||||
SIGNAL_HANDLER
|
||||
if(istype(potential_salt))
|
||||
on_salt_exposure() //immediately perish
|
||||
|
||||
/mob/living/basic/snail/proc/on_reagents_update(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
if(reagents.has_reagent(/datum/reagent/consumable/salt))
|
||||
on_salt_exposure()
|
||||
|
||||
/mob/living/basic/snail/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
|
||||
. = ..()
|
||||
if(!isturf(loc))
|
||||
return
|
||||
if(locate(/obj/effect/decal/cleanable/food/salt) in loc.contents)
|
||||
on_salt_exposure()
|
||||
|
||||
/mob/living/basic/snail/proc/on_salt_exposure()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
visible_message(
|
||||
span_danger("[src] shows a strong reaction after tasting some salt!"),
|
||||
span_userdanger("You show a strong reaction after tasting some salt."),
|
||||
)
|
||||
apply_damage(500) //ouch
|
||||
|
||||
|
||||
/mob/living/basic/snail/mob_pickup(mob/living/user)
|
||||
var/obj/item/clothing/head/mob_holder/snail/holder = new(get_turf(src), src, held_state, head_icon, held_lh, held_rh, worn_slot_flags)
|
||||
var/display_message = "[user] [HAS_TRAIT(src, TRAIT_MOVE_FLOATING) ? "scoops up [src]" : "peels [src] off the ground"]!"
|
||||
user.visible_message(span_warning(display_message))
|
||||
user.put_in_hands(holder)
|
||||
|
||||
|
||||
/mob/living/basic/snail/update_icon_state()
|
||||
if(stat != DEAD)
|
||||
icon_state = HAS_TRAIT(src, TRAIT_SHELL_RETREATED) ? "[base_icon_state]_shell" : "[base_icon_state][(faction.Find(FACTION_RAT)) ? "_maints" : ""]"
|
||||
return ..()
|
||||
|
||||
///snail's custom holder object
|
||||
/obj/item/clothing/head/mob_holder/snail
|
||||
|
||||
/obj/item/clothing/head/mob_holder/snail/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
|
||||
if(!istype(interacting_with, /obj/machinery/hydroponics))
|
||||
return NONE
|
||||
|
||||
. = ITEM_INTERACT_BLOCKING
|
||||
if(held_mob.stat == DEAD)
|
||||
user.balloon_alert(user, "it's dead!")
|
||||
return
|
||||
|
||||
if(locate(type) in interacting_with)
|
||||
user.balloon_alert(user, "already has snail!")
|
||||
return
|
||||
|
||||
if(!do_after(user, 2 SECONDS, interacting_with))
|
||||
return
|
||||
|
||||
forceMove(interacting_with)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum/action/cooldown/mob_cooldown/shell_retreat
|
||||
name = "Shell Retreat"
|
||||
desc = "Retreat to your shell!"
|
||||
cooldown_time = 5 SECONDS
|
||||
click_to_activate = FALSE
|
||||
button_icon = 'icons/mob/simple/pets.dmi'
|
||||
button_icon_state = "snail_shell"
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/shell_retreat/Activate(atom/target)
|
||||
. = ..()
|
||||
HAS_TRAIT(owner, TRAIT_SHELL_RETREATED) ? unretreat_from_shell() : retreat_into_shell()
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/shell_retreat/proc/unretreat_from_shell()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
owner.visible_message(
|
||||
span_danger("[owner] slowly pops its head out of its shell!"),
|
||||
span_userdanger("You pop your head out of your shell."),
|
||||
)
|
||||
REMOVE_TRAIT(owner, TRAIT_SHELL_RETREATED, REF(src))
|
||||
UnregisterSignal(owner, list(COMSIG_MOVABLE_ATTEMPTED_MOVE, COMSIG_LIVING_DEATH))
|
||||
owner.update_appearance(UPDATE_ICON_STATE)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/shell_retreat/proc/retreat_into_shell()
|
||||
owner.visible_message(
|
||||
span_danger("[owner] quickly escapes into its shell!"),
|
||||
span_userdanger("You hide in your shell.."),
|
||||
)
|
||||
RegisterSignals(owner, list(COMSIG_LIVING_DEATH, COMSIG_MOVABLE_ATTEMPTED_MOVE), PROC_REF(unretreat_from_shell))
|
||||
ADD_TRAIT(owner, TRAIT_SHELL_RETREATED, REF(src))
|
||||
owner.update_appearance(UPDATE_ICON_STATE)
|
||||
@@ -0,0 +1,67 @@
|
||||
/datum/ai_controller/basic_controller/snail
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
)
|
||||
|
||||
ai_movement = /datum/ai_movement/basic_avoidance
|
||||
idle_behavior = /datum/idle_behavior/idle_random_walk
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee,
|
||||
/datum/ai_planning_subtree/use_mob_ability/snail_retreat,
|
||||
/datum/ai_planning_subtree/find_food,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/snail_people,
|
||||
)
|
||||
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/snail_people
|
||||
target_key = BB_LOW_PRIORITY_HUNTING_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target/snail_people
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/snail_people
|
||||
hunt_targets = list(
|
||||
/mob/living/carbon,
|
||||
)
|
||||
hunt_range = 5
|
||||
hunt_chance = 45
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/snail_people
|
||||
action_cooldown = 1 MINUTES
|
||||
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/snail_people/valid_dinner(mob/living/source, mob/living/carbon/potential_snail, radius, datum/ai_controller/controller, seconds_per_tick)
|
||||
if(!istype(potential_snail))
|
||||
return FALSE
|
||||
if(potential_snail.stat != CONSCIOUS)
|
||||
return FALSE
|
||||
if(!is_species(potential_snail, /datum/species/snail))
|
||||
return FALSE
|
||||
return can_see(source, potential_snail, radius)
|
||||
|
||||
/datum/ai_behavior/hunt_target/snail_people
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/snail_people/target_caught(mob/living/hunter, atom/hunted)
|
||||
hunter.manual_emote("Celebrates around [hunted]!")
|
||||
hunter.SpinAnimation(speed = 1, loops = 3)
|
||||
|
||||
/datum/ai_planning_subtree/use_mob_ability/snail_retreat
|
||||
ability_key = BB_SNAIL_RETREAT_ABILITY
|
||||
finish_planning = TRUE
|
||||
|
||||
/datum/ai_planning_subtree/use_mob_ability/snail_retreat/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
|
||||
var/shell_retreated = HAS_TRAIT(controller.pawn, TRAIT_SHELL_RETREATED)
|
||||
var/has_target = controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)
|
||||
if((has_target && shell_retreated) || (!has_target && !shell_retreated))
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/ai_controller/basic_controller/snail/trash
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic,
|
||||
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
|
||||
)
|
||||
|
||||
planning_subtrees = list(
|
||||
/datum/ai_planning_subtree/pet_planning,
|
||||
/datum/ai_planning_subtree/simple_find_target,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree,
|
||||
)
|
||||
Reference in New Issue
Block a user