mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00: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:
@@ -326,3 +326,7 @@
|
||||
#define BB_TURTLE_FLORA_TARGET "turtle_flora_target"
|
||||
|
||||
#define BB_GUNMIMIC_GUN_EMPTY "BB_GUNMIMIC_GUN_EMPTY"
|
||||
|
||||
//snails
|
||||
///snails retreat ability
|
||||
#define BB_SNAIL_RETREAT_ABILITY "snail_retreat_ability"
|
||||
|
||||
@@ -1493,4 +1493,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
/// Demolition modifier when hitting this object is inverted (ie, 1 / demolition)
|
||||
#define TRAIT_INVERTED_DEMOLITION "demolition_inverted"
|
||||
|
||||
/// Trait given when we escape into our shell
|
||||
#define TRAIT_SHELL_RETREATED "shell_retreated"
|
||||
// END TRAIT DEFINES
|
||||
|
||||
@@ -493,6 +493,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE,
|
||||
"TRAIT_SETTLER" = TRAIT_SETTLER,
|
||||
"TRAIT_SHAVED" = TRAIT_SHAVED,
|
||||
"TRAIT_SHELL_RETREATED" = TRAIT_SHELL_RETREATED,
|
||||
"TRAIT_SHIFTY_EYES" = TRAIT_SHIFTY_EYES,
|
||||
"TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE,
|
||||
"TRAIT_SIGHT_BYPASS" = TRAIT_SIGHT_BYPASS,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#define PROB_MOUSE_SPAWN 98
|
||||
#define PROB_SPIDER_REPLACEMENT 50
|
||||
|
||||
SUBSYSTEM_DEF(minor_mapping)
|
||||
@@ -8,6 +7,12 @@ SUBSYSTEM_DEF(minor_mapping)
|
||||
/datum/controller/subsystem/atoms,
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
///a list of vermin we pick from to spawn.
|
||||
var/list/vermin_chances = list(
|
||||
/mob/living/basic/mouse = 80,
|
||||
/mob/living/basic/snail = 18,
|
||||
/mob/living/basic/regal_rat/controlled = 2,
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/minor_mapping/Initialize()
|
||||
// This whole subsystem just introduces a lot of odd confounding variables into unit test situations,
|
||||
@@ -30,14 +35,14 @@ SUBSYSTEM_DEF(minor_mapping)
|
||||
continue
|
||||
|
||||
to_spawn--
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_SPIDER_INFESTATION) && prob(PROB_SPIDER_REPLACEMENT))
|
||||
new /mob/living/basic/spider/maintenance(proposed_turf)
|
||||
return
|
||||
|
||||
if (prob(PROB_MOUSE_SPAWN))
|
||||
new /mob/living/basic/mouse(proposed_turf)
|
||||
var/picked_path
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_SPIDER_INFESTATION) && prob(PROB_SPIDER_REPLACEMENT))
|
||||
picked_path = /mob/living/basic/spider/maintenance
|
||||
else
|
||||
new /mob/living/basic/regal_rat/controlled(proposed_turf)
|
||||
picked_path = pick_weight(vermin_chances)
|
||||
|
||||
new picked_path(proposed_turf)
|
||||
|
||||
/// Returns true if a mouse won't die if spawned on this turf
|
||||
/datum/controller/subsystem/minor_mapping/proc/valid_mouse_turf(turf/open/proposed_turf)
|
||||
@@ -91,5 +96,4 @@ SUBSYSTEM_DEF(minor_mapping)
|
||||
|
||||
return shuffle(suitable)
|
||||
|
||||
#undef PROB_MOUSE_SPAWN
|
||||
#undef PROB_SPIDER_REPLACEMENT
|
||||
|
||||
@@ -56,6 +56,10 @@
|
||||
enemies_list += potential_target
|
||||
|
||||
if(!length(enemies_list))
|
||||
|
||||
if(existing_target)
|
||||
controller.clear_blackboard_key(target_key)
|
||||
|
||||
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
|
||||
|
||||
var/atom/new_target = pick_final_target(controller, enemies_list)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
/obj/item/reagent_containers/cup/soda_cans/grey_bull = 1,
|
||||
/obj/effect/spawner/random/engineering/tool = 1,
|
||||
/mob/living/basic/mouse = 1,
|
||||
/mob/living/basic/snail = 1,
|
||||
/obj/item/food/grown/cannabis = 1,
|
||||
/obj/item/reagent_containers/cup/rag = 1,
|
||||
/obj/effect/spawner/random/entertainment/drugs= 1,
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
/mob/living/basic/cockroach,
|
||||
/mob/living/basic/spider/maintenance,
|
||||
/mob/living/basic/mouse,
|
||||
/mob/living/basic/snail,
|
||||
)
|
||||
return pick(mob_list)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
description = "A scientist needs vermin to test on, use the cytology equipment to grow some of these simple critters!"
|
||||
total_requirement = 3
|
||||
max_requirement_per_type = 2
|
||||
possible_types = list(/mob/living/basic/cockroach, /mob/living/basic/mouse)
|
||||
possible_types = list(/mob/living/basic/cockroach, /mob/living/basic/mouse, /mob/living/basic/snail)
|
||||
|
||||
/datum/experiment/scanning/random/cytology/medium
|
||||
name = "Advanced Cytology Scanning Experiment"
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
var/being_pollinated = FALSE
|
||||
///The light level on the tray tile
|
||||
var/light_level = 0
|
||||
///our snail overlay, if any
|
||||
var/obj/effect/overlay/vis_effect/snail/our_snail
|
||||
|
||||
/obj/machinery/hydroponics/Initialize(mapload)
|
||||
//ALRIGHT YOU DEGENERATES. YOU HAD REAGENT HOLDERS FOR AT LEAST 4 YEARS AND NONE OF YOU MADE HYDROPONICS TRAYS HOLD NUTRIENT CHEMS INSTEAD OF USING "Points".
|
||||
@@ -212,6 +214,16 @@
|
||||
. = ..()
|
||||
if(!QDELETED(src) && gone == myseed)
|
||||
set_seed(null, FALSE)
|
||||
if(!istype(gone, /obj/item/clothing/head/mob_holder/snail))
|
||||
return
|
||||
var/obj/item/clothing/head/mob_holder/snail_object = gone
|
||||
if(snail_object.held_mob)
|
||||
UnregisterSignal(snail_object.held_mob, list(
|
||||
COMSIG_LIVING_DEATH,
|
||||
COMSIG_MOVABLE_ATTEMPTED_MOVE,
|
||||
))
|
||||
QDEL_NULL(our_snail)
|
||||
|
||||
|
||||
/obj/machinery/hydroponics/constructable/attackby(obj/item/I, mob/living/user, list/modifiers)
|
||||
if (!user.combat_mode)
|
||||
@@ -313,6 +325,9 @@
|
||||
/obj/machinery/hydroponics/process(seconds_per_tick)
|
||||
var/needs_update = FALSE // Checks if the icon needs updating so we don't redraw empty trays every time
|
||||
|
||||
if(!isnull(our_snail))
|
||||
handle_snail()
|
||||
|
||||
if(self_sustaining)
|
||||
if(powered())
|
||||
adjust_waterlevel(rand(1,2) * seconds_per_tick * 0.5)
|
||||
@@ -646,6 +661,17 @@
|
||||
/obj/machinery/hydroponics/proc/adjust_pestlevel(amt)
|
||||
set_pestlevel(clamp(pestlevel + amt, 0, MAX_TRAY_PESTS), FALSE)
|
||||
|
||||
/obj/machinery/hydroponics/proc/remove_snail(mob/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/atom/movable/mob_holder = source.loc
|
||||
mob_holder.forceMove(drop_location())
|
||||
|
||||
/obj/machinery/hydroponics/proc/handle_snail()
|
||||
if(prob(15))
|
||||
our_snail.handle_animation() //our snail waddles throughout the tray
|
||||
if(prob(5))
|
||||
adjust_weedlevel(-2)
|
||||
|
||||
/**
|
||||
* Adjust Weeds.
|
||||
@@ -1110,11 +1136,17 @@
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
var/warning = tgui_alert(user, "Are you sure you wish to empty the tray's nutrient beaker?","Empty Tray Nutrients?", list("Yes", "No"))
|
||||
if(warning == "Yes" && user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
|
||||
reagents.clear_reagents()
|
||||
to_chat(user, span_warning("You empty [src]'s nutrient tank."))
|
||||
empty_tray(user)
|
||||
update_appearance()
|
||||
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
||||
|
||||
|
||||
/obj/machinery/hydroponics/proc/empty_tray(mob/user)
|
||||
reagents.clear_reagents()
|
||||
for(var/obj/item/clothing/head/mob_holder/snail/possible_snail in contents)
|
||||
possible_snail.forceMove(drop_location())
|
||||
to_chat(user, span_warning("You empty [src]'s nutrient tank."))
|
||||
|
||||
/**
|
||||
* Update Tray Proc
|
||||
* Handles plant harvesting on the tray side, by clearing the seed, names, description, and dead stat.
|
||||
@@ -1243,6 +1275,17 @@
|
||||
plant_health = add_output_port("Plant Health", PORT_TYPE_NUMBER)
|
||||
reagents_level = add_output_port("Reagents Level", PORT_TYPE_NUMBER)
|
||||
|
||||
/obj/machinery/hydroponics/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
||||
. = ..()
|
||||
if(!istype(arrived, /obj/item/clothing/head/mob_holder/snail))
|
||||
return
|
||||
our_snail = new
|
||||
vis_contents += our_snail
|
||||
our_snail.layer = layer + 0.01
|
||||
var/obj/item/clothing/head/mob_holder/snail = arrived
|
||||
RegisterSignals(snail.held_mob, list(COMSIG_MOVABLE_ATTEMPTED_MOVE, COMSIG_LIVING_DEATH), PROC_REF(remove_snail)) //rip
|
||||
|
||||
|
||||
/obj/item/circuit_component/hydroponics/register_usb_parent(atom/movable/parent)
|
||||
. = ..()
|
||||
if(istype(parent, /obj/machinery/hydroponics))
|
||||
|
||||
22
code/modules/hydroponics/snail_overlay.dm
Normal file
22
code/modules/hydroponics/snail_overlay.dm
Normal file
@@ -0,0 +1,22 @@
|
||||
#define SNAIL_MOVEMENT_DISTANCE 5
|
||||
#define SNAIL_MOVEMENT_TIME 10 SECONDS
|
||||
|
||||
/obj/effect/overlay/vis_effect/snail
|
||||
name = "snail"
|
||||
vis_flags = VIS_INHERIT_PLANE
|
||||
icon = 'icons/obj/service/hydroponics/equipment.dmi'
|
||||
icon_state = "snail_hydrotray"
|
||||
///are we currently walking?
|
||||
var/is_waddling = FALSE
|
||||
|
||||
/obj/effect/overlay/vis_effect/snail/proc/handle_animation()
|
||||
if(is_waddling)
|
||||
return
|
||||
is_waddling = TRUE
|
||||
var/movement_direction = pixel_x >= 0 ? -1 : 1
|
||||
transform = transform.Scale(-1, 1) //face the other direction
|
||||
animate(src, pixel_x = movement_direction * SNAIL_MOVEMENT_DISTANCE, time = SNAIL_MOVEMENT_TIME)
|
||||
addtimer(VARSET_CALLBACK(src, is_waddling, FALSE), SNAIL_MOVEMENT_TIME)
|
||||
|
||||
#undef SNAIL_MOVEMENT_DISTANCE
|
||||
#undef SNAIL_MOVEMENT_TIME
|
||||
104
code/modules/mob/living/basic/snails/snail.dm
Normal file
104
code/modules/mob/living/basic/snails/snail.dm
Normal file
@@ -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
|
||||
31
code/modules/mob/living/basic/snails/snail_ability.dm
Normal file
31
code/modules/mob/living/basic/snails/snail_ability.dm
Normal file
@@ -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)
|
||||
67
code/modules/mob/living/basic/snails/snail_ai.dm
Normal file
67
code/modules/mob/living/basic/snails/snail_ai.dm
Normal file
@@ -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,
|
||||
)
|
||||
@@ -99,7 +99,7 @@
|
||||
*/
|
||||
/datum/action/cooldown/mob_cooldown/riot/proc/riot()
|
||||
var/uplifted_mice = FALSE
|
||||
for (var/mob/living/basic/mouse/nearby_mouse in oview(owner, range))
|
||||
for(var/mob/living/basic/mouse/nearby_mouse in oview(owner, range))
|
||||
uplifted_mice = convert_mouse(nearby_mouse) || uplifted_mice
|
||||
if (uplifted_mice)
|
||||
owner.visible_message(span_warning("[owner] commands their army to action, mutating them into rats!"))
|
||||
@@ -120,6 +120,13 @@
|
||||
owner.visible_message(span_warning("[owner] commands their army to action, mutating them into trash frogs!"))
|
||||
return
|
||||
|
||||
var/uplifted_snail = FALSE
|
||||
for(var/mob/living/basic/snail/nearby_snail in oview(owner, range))
|
||||
uplifted_snail = convert_snail(nearby_snail, converted_check_list) || uplifted_snail
|
||||
if(uplifted_snail)
|
||||
owner.visible_message(span_warning("[owner] commands their army to action, mutating them into death snails!"))
|
||||
return
|
||||
|
||||
var/rat_cap = CONFIG_GET(number/ratcap)
|
||||
if (LAZYLEN(SSmobs.cheeserats) >= rat_cap)
|
||||
to_chat(owner,span_warning("There's too many mice on this station to beckon a new one! Find them first!"))
|
||||
@@ -210,6 +217,27 @@
|
||||
make_minion(nearby_frog, crazy_frog_desc, minion_commands)
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/riot/proc/convert_snail(mob/living/basic/snail/nearby_snail, list/converted_check_list)
|
||||
// No need to convert when not on the same team.
|
||||
if(faction_check(nearby_snail.faction, converted_check_list) || nearby_snail.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
|
||||
nearby_snail.icon_state = "[nearby_snail.base_icon_state]_maints"
|
||||
nearby_snail.icon_living = "[nearby_snail.base_icon_state]_maints"
|
||||
nearby_snail.icon_dead = "[nearby_snail.base_icon_state]_maints_dead"
|
||||
nearby_snail.maxHealth += 10
|
||||
nearby_snail.health += 10
|
||||
nearby_snail.melee_damage_lower += 5
|
||||
nearby_snail.melee_damage_upper += 8
|
||||
nearby_snail.can_be_held = FALSE
|
||||
nearby_snail.obj_damage += 8
|
||||
nearby_snail.fully_replace_character_name(nearby_snail.name, "trash [nearby_snail.name]")
|
||||
nearby_snail.ai_controller = new /datum/ai_controller/basic_controller/snail/trash(nearby_snail)
|
||||
make_minion(nearby_snail, " ...This one doesn't look as timid.", mouse_commands)
|
||||
nearby_snail.update_appearance()
|
||||
return TRUE
|
||||
|
||||
// Command you can give to a mouse to make it kill someone
|
||||
/datum/pet_command/attack/mouse
|
||||
speech_commands = list("attack", "sic", "kill", "cheese em")
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 92 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 30 KiB |
@@ -4412,6 +4412,7 @@
|
||||
#include "code\modules\hydroponics\plant_genes.dm"
|
||||
#include "code\modules\hydroponics\seed_extractor.dm"
|
||||
#include "code\modules\hydroponics\seeds.dm"
|
||||
#include "code\modules\hydroponics\snail_overlay.dm"
|
||||
#include "code\modules\hydroponics\unique_plant_genes.dm"
|
||||
#include "code\modules\hydroponics\beekeeping\bee_smoker.dm"
|
||||
#include "code\modules\hydroponics\beekeeping\beebox.dm"
|
||||
@@ -5189,6 +5190,9 @@
|
||||
#include "code\modules\mob\living\basic\slime\ai\controller.dm"
|
||||
#include "code\modules\mob\living\basic\slime\ai\pet_command.dm"
|
||||
#include "code\modules\mob\living\basic\slime\ai\subtrees.dm"
|
||||
#include "code\modules\mob\living\basic\snails\snail.dm"
|
||||
#include "code\modules\mob\living\basic\snails\snail_ability.dm"
|
||||
#include "code\modules\mob\living\basic\snails\snail_ai.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\ant.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\cat_surgeon.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\faithless.dm"
|
||||
|
||||
Reference in New Issue
Block a user