Skip to content

Commit

Permalink
[MIRROR] Refactor icemoon wolves into basic mobs and add taming + pac…
Browse files Browse the repository at this point in the history
…k behavior [MDB IGNORE] (#25126)

* Refactor icemoon wolves into basic mobs and add taming + pack behavior (#79736)

## About The Pull Request

Ports icemoon wolves over to the basic mob framework with a bit of extra
stuff:

- Wolves call for help when attacked within a decently large radius.
Because you know, pack animals.
- Wolves can now be tamed with a slab of meat
- When tamed, wolves can be ridden like goliath mounts. Ride wolf, life
good. Pretend you're playing ARK and start shivering to death in thatch
huts for that High Roleplay experience.
- Tamed wolves have access to a bunch of pet commands (following, point
fetching, point attacking, play dead, etc) and will also defend their
owners vehemently if they're attacked.

You can probably tame multiple if you wanted to.

## Why It's Good For The Game

What part about riding wolves isn't entertaining? I don't really play
/tg/ that much so I can't argue too much about the balance implications
this might pose, but it's undoubtedly a stupid little gimmick and is
likely to be used by bored assistants and miners with too much time on
their hands.

Especially robust individuals will probably find a million things to do
with a basic mob capable of fetching, attacking on command and generally
being able to defend themselves decently well.

## Changelog

:cl: yooriss
refactor: Icemoon wolves now use the basic mob framework and should act
more intelligently, defending their pack.
add: Icemoon wolves can be tamed with slabs of meat and can be ridden as
mounts once friendly. Being rather large dogs, they also have access to
most of the pet commands you'd expect, such as fetching things, and
violently mauling people their owners point at.
/:cl:

---------

Co-authored-by: san7890 <the@ san7890.com>

* Refactor icemoon wolves into basic mobs and add taming + pack behavior

---------

Co-authored-by: Ephemeralis <Ephemeralis@users.noreply.github.com>
Co-authored-by: san7890 <the@ san7890.com>
  • Loading branch information
3 people committed Nov 19, 2023
1 parent 609a799 commit 8f3d103
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@
/turf/open/lava/plasma/ice_moon,
/area/icemoon/underground/explored)
"gd" = (
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/underground/explored)
"gj" = (
Expand Down Expand Up @@ -1263,7 +1263,7 @@
/obj/effect/turf_decal/box/corners{
dir = 4
},
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/floor/iron/smooth{
initial_gas_mix = "ICEMOON_ATMOS"
},
Expand Down Expand Up @@ -1819,7 +1819,7 @@
/turf/open/floor/plating/icemoon,
/area/ruin/plasma_facility/commons)
"Hz" = (
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
"HA" = (
Expand Down Expand Up @@ -2655,7 +2655,7 @@
id = "fire_facility_car";
name = "Garage Door"
},
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/floor/plating/icemoon,
/area/ruin/plasma_facility/operations)
"VD" = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/turf/open/genturf,
/area/icemoon/underground/unexplored/rivers)
"bh" = (
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/underground/explored)
"cv" = (
Expand Down Expand Up @@ -69,7 +69,7 @@
},
/area/ruin/powered/shuttle)
"oD" = (
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/floor/iron/showroomfloor{
initial_gas_mix = "ICEMOON_ATMOS"
},
Expand Down Expand Up @@ -99,7 +99,7 @@
},
/area/ruin/powered/shuttle)
"rn" = (
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/turf/open/floor/plating/icemoon,
/area/ruin/powered/shuttle)
"rS" = (
Expand Down Expand Up @@ -249,7 +249,7 @@
/turf/open/floor/plating/icemoon,
/area/ruin/powered/shuttle)
"FK" = (
/mob/living/simple_animal/hostile/asteroid/wolf,
/mob/living/basic/mining/wolf,
/obj/machinery/light/small/broken/directional/north,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/ruin/powered/shuttle)
Expand Down
3 changes: 2 additions & 1 deletion code/datums/components/pet_commands/pet_commands_basic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@
var/mob/living/victim = controller.blackboard[BB_CURRENT_PET_TARGET]
if(QDELETED(victim))
return
if(victim.stat > controller.blackboard[BB_TARGET_MINIMUM_STAT])
// cancel the action if they're below our given crit stat, OR if we're trying to attack ourselves (this can happen on tamed mobs w/ protect subtree rarely)
if(victim.stat > controller.blackboard[BB_TARGET_MINIMUM_STAT] || victim == controller.pawn)
controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
return
controller.queue_behavior(protect_behavior, BB_CURRENT_PET_TARGET, BB_PET_TARGETING_STRATEGY)
Expand Down
4 changes: 2 additions & 2 deletions code/datums/mapgen/Cavegens/IcemoonCaves.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@


weighted_mob_spawn_list = list(
/mob/living/basic/mining/goldgrub = 10,
/mob/living/basic/mining/legion/snow = 50,
/mob/living/basic/mining/lobstrosity = 15,
/mob/living/basic/mining/goldgrub = 10,
/mob/living/basic/mining/wolf = 50,
/mob/living/simple_animal/hostile/asteroid/polarbear = 30,
/mob/living/simple_animal/hostile/asteroid/wolf = 50,
/obj/structure/spawner/ice_moon = 3,
/obj/structure/spawner/ice_moon/polarbear = 3,
)
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/icemoon/cave_entrance.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(ore_probability, list(
faction = list(FACTION_MINING)
max_mobs = 3
max_integrity = 250
mob_types = list(/mob/living/simple_animal/hostile/asteroid/wolf)
mob_types = list(/mob/living/basic/mining/wolf)
move_resist = INFINITY
anchored = TRUE
scanner_taggable = TRUE
Expand Down
91 changes: 91 additions & 0 deletions code/modules/mob/living/basic/icemoon/wolf/wolf.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/mob/living/basic/mining/wolf
name = "white wolf"
desc = "Pack hunters of the Icemoon wastes. While a mere nuisance individually, they become fearsome foes in larger groups."
icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi'
icon_state = "whitewolf"
icon_living = "whitewolf"
icon_dead = "whitewolf_dead"
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
speak_emote = list("howls")
friendly_verb_continuous = "howls at"
friendly_verb_simple = "howl at"

butcher_results = list(
/obj/item/food/meat/slab = 2,
/obj/item/stack/sheet/sinew/wolf = 2,
/obj/item/stack/sheet/bone = 2
)
crusher_loot = /obj/item/crusher_trophy/wolf_ear

maxHealth = 130
health = 130
obj_damage = 15
melee_damage_lower = 7.5
melee_damage_upper = 7.5
attack_vis_effect = ATTACK_EFFECT_BITE
melee_attack_cooldown = 1.2 SECONDS

attack_verb_continuous = "bites"
attack_verb_simple = "bite"
death_message = "snarls its last and perishes."

attack_sound = 'sound/weapons/bite.ogg'
move_force = MOVE_FORCE_WEAK
move_resist = MOVE_FORCE_WEAK
pull_force = MOVE_FORCE_WEAK

ai_controller = /datum/ai_controller/basic_controller/wolf

//can we tame this wolf?
var/can_tame = TRUE

//commands to give when tamed
var/static/list/pet_commands = list(
/datum/pet_command/idle,
/datum/pet_command/free,
/datum/pet_command/good_boy/wolf,
/datum/pet_command/follow/wolf,
/datum/pet_command/point_targeting/attack,
/datum/pet_command/point_targeting/fetch,
/datum/pet_command/play_dead,
/datum/pet_command/protect_owner,
)

/mob/living/basic/mining/wolf/Initialize(mapload)
. = ..()

AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW)
AddElement(/datum/element/ai_flee_while_injured)
AddElement(/datum/element/ai_retaliate)
AddComponent(/datum/component/basic_mob_ability_telegraph)
AddComponent(/datum/component/basic_mob_attack_telegraph, telegraph_duration = 0.6 SECONDS)

if(can_tame)
make_tameable()

/mob/living/basic/mining/wolf/proc/make_tameable()
AddComponent(\
/datum/component/tameable,\
food_types = list(/obj/item/food/meat/slab),\
tame_chance = 15,\
bonus_tame_chance = 5,\
after_tame = CALLBACK(src, PROC_REF(tame_wolf)),\
)

/mob/living/basic/mining/wolf/proc/tame_wolf()
new /obj/effect/temp_visual/heart(src.loc)
// ride wolf, life good
AddElement(/datum/element/ridable, /datum/component/riding/creature/wolf)
AddComponent(/datum/component/obeys_commands, pet_commands)
// this is purely a convenience thing once tamed so you can drag them away from shit
ai_controller.ai_traits = STOP_MOVING_WHEN_PULLED
// makes tamed wolves run away far less
ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEE_DISTANCE, 7)

//port the faction fix from goliath basicmob to make the wildlife hostile when tamed (and also help defuckulate reinforcements ai)
//this should also produce interesting behavior where tamed wolves defend other tamed wolves.
/mob/living/basic/mining/wolf/befriend(mob/living/new_friend)
. = ..()
faction = new_friend.faction.Copy()
visible_message(span_notice("[src] lowers [src.p_their()] snout at [new_friend]'s offering and begins to wag [src.p_their()] tail."))
36 changes: 36 additions & 0 deletions code/modules/mob/living/basic/icemoon/wolf/wolf_ai.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//This mimicks the old simple_animal wolf behavior fairly closely.
//The 30 tiles fleeing is pretty wild and may need toning back under basicmob behavior, we'll have to see.
/datum/ai_controller/basic_controller/wolf
blackboard = list(
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items,
BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends,
BB_BASIC_MOB_FLEE_DISTANCE = 30,
BB_VISION_RANGE = 9,
BB_TARGET_MINIMUM_STAT = HARD_CRIT,
BB_REINFORCEMENTS_EMOTE = "unleashes a chilling howl, calling for aid!"
)

ai_movement = /datum/ai_movement/basic_avoidance
idle_behavior = /datum/idle_behavior/idle_random_walk

//reinforcements needs to be skipped over entirely on tamed wolves because it causes them to attack their owner and then themselves
planning_subtrees = list(
/datum/ai_planning_subtree/pet_planning,
/datum/ai_planning_subtree/call_reinforcements/wolf,
/datum/ai_planning_subtree/simple_find_nearest_target_to_flee,
/datum/ai_planning_subtree/flee_target,
/datum/ai_planning_subtree/target_retaliate,
/datum/ai_planning_subtree/simple_find_target,
/datum/ai_planning_subtree/attack_obstacle_in_path,
/datum/ai_planning_subtree/basic_melee_attack_subtree,
)

/datum/ai_planning_subtree/call_reinforcements/wolf

/datum/ai_planning_subtree/call_reinforcements/wolf/decide_to_call(datum/ai_controller/controller)
//only call reinforcements if the person who just smacked us isn't a friend to avoid hitting them once, then killing ourselves if we've been tamed
if (controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET) && istype(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET], /mob))
return !(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] in controller.blackboard[BB_FRIENDS_LIST])
else
return FALSE

18 changes: 18 additions & 0 deletions code/modules/mob/living/basic/icemoon/wolf/wolf_extras.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Some flavor additions for wolf-related pet commands
/datum/pet_command/good_boy/wolf
speech_commands = list("good wolf")

/datum/pet_command/follow/wolf
// Nordic-themed for a bit of extra flavor
speech_commands = list("heel", "follow", "fylgja", "fyl")

// Contains pixel offset data for sprites riding wolves
/datum/component/riding/creature/wolf

/datum/component/riding/creature/wolf/handle_specials()
. = ..()
set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(1, 9), TEXT_SOUTH = list(1, 9), TEXT_EAST = list(0, 9), TEXT_WEST = list(2, 9)))
set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
set_vehicle_dir_layer(NORTH, OBJ_LAYER)
set_vehicle_dir_layer(EAST, OBJ_LAYER)
set_vehicle_dir_layer(WEST, OBJ_LAYER)
3 changes: 3 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -4611,6 +4611,9 @@
#include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp.dm"
#include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp_abilities.dm"
#include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp_ai.dm"
#include "code\modules\mob\living\basic\icemoon\wolf\wolf.dm"
#include "code\modules\mob\living\basic\icemoon\wolf\wolf_ai.dm"
#include "code\modules\mob\living\basic\icemoon\wolf\wolf_extras.dm"
#include "code\modules\mob\living\basic\jungle\venus_human_trap.dm"
#include "code\modules\mob\living\basic\jungle\leaper\leaper.dm"
#include "code\modules\mob\living\basic\jungle\leaper\leaper_abilities.dm"
Expand Down
1 change: 1 addition & 0 deletions tools/UpdatePaths/Scripts/79736_icemoon_wolf_basic.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/mob/living/simple_animal/hostile/asteroid/wolf : /mob/living/basic/mining/wolf{@OLD}

0 comments on commit 8f3d103

Please sign in to comment.