From ffb6de7cf097ee7ac33e7438baa1fc3bd41cb6b0 Mon Sep 17 00:00:00 2001 From: Constellado Date: Wed, 17 Apr 2024 15:34:58 +1200 Subject: [PATCH] A new robotic pet can be spawned. From Volkan's workshop, meet his new companion! It can fetch, fly around and in general be a good pet. Still under construction. --- maplestation.dme | 1 + .../volkan_equipment/code/volkanpets.dm | 174 ++++++++++++++++++ .../volkan_equipment/icons/companions.dmi | Bin 0 -> 7382 bytes 3 files changed, 175 insertions(+) create mode 100644 maplestation_modules/story_content/volkan_equipment/code/volkanpets.dm create mode 100644 maplestation_modules/story_content/volkan_equipment/icons/companions.dmi diff --git a/maplestation.dme b/maplestation.dme index c7aed02bde8d..54f41b552068 100644 --- a/maplestation.dme +++ b/maplestation.dme @@ -6505,4 +6505,5 @@ #include "maplestation_modules\story_content\story_posters\code\contraband.dm" #include "maplestation_modules\story_content\stranger_equipment\code\strangerclothing.dm" #include "maplestation_modules\story_content\volkan_equipment\code\volkanitems.dm" +#include "maplestation_modules\story_content\volkan_equipment\code\volkanpets.dm" // END_INCLUDE diff --git a/maplestation_modules/story_content/volkan_equipment/code/volkanpets.dm b/maplestation_modules/story_content/volkan_equipment/code/volkanpets.dm new file mode 100644 index 000000000000..a9f6014b6ec7 --- /dev/null +++ b/maplestation_modules/story_content/volkan_equipment/code/volkanpets.dm @@ -0,0 +1,174 @@ +/** + * # Volkan's companion. + * A cool pet for volkan! Basically a better poly. Quiet, efficient, and will sit on his shoulder all the time. + */ +//HOLY MOLY WHAT DID I GET MYSELF INTO?? +/mob/living/basic/volkan/shoulder_pet + name = "Companion" + desc = "An intricate, flying robot. It looks at you inquisitively." + + icon = 'maplestation_modules/story_content/volkan_equipment/icons/companions.dmi' + icon_state = "drone_fly" + icon_living = "drone_fly" + icon_dead = "drone_dead" + + density = FALSE + health = 80 + maxHealth = 80 + pass_flags = PASSTABLE | PASSMOB + mob_size = MOB_SIZE_SMALL + + melee_damage_upper = 10 + melee_damage_lower = 5 + + response_help_continuous = "pets" + response_help_simple = "pet" + + ai_controller = /datum/ai_controller/basic_controller/volkan/shoulder_pet + + //The drone shall be able to perch on things. + var/icon_sit = "drone_perch" + /// Contains all of the perches that the drone will sit on. + var/static/list/desired_perches = typecacheof(list( + /obj/machinery/dna_scannernew, + /obj/machinery/nuclearbomb, + /obj/machinery/recharge_station, + /obj/machinery/suit_storage_unit, + /obj/structure/displaycase, + /obj/structure/filingcabinet, + /obj/structure/rack, + )) + //The command list + var/static/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/perch, + /datum/pet_command/follow/volkan/shoulder_pet, + /datum/pet_command/point_targeting/fetch, + ) + + + +/mob/living/basic/volkan/shoulder_pet/Initialize(mapload) + . = ..() + ai_controller.set_blackboard_key(BB_PARROT_PERCH_TYPES, desired_perches)// uses parrot code to perch + + AddElement(/datum/element/simple_flying) //The thing flys. + AddComponent(/datum/component/tameable, \ + food_types = list(/obj/item/stock_parts/cell, \ + /obj/item/stock_parts/capacitor,), \ + tame_chance = 100, \ + bonus_tame_chance = 15, \ + after_tame = CALLBACK(src, PROC_REF(tamed)), \ + unique = FALSE) + AddComponent(/datum/component/obeys_commands, pet_commands) // follows pet command + +/datum/pet_command/follow/volkan/shoulder_pet + speech_commands = list("heel", "follow", "come") + +///Proc to run once imprinted +/mob/living/basic/volkan/shoulder_pet/proc/tamed(mob/living/tamer) + visible_message(span_notice("[src] beeps and turns it's head toward [tamer] with it's head tilted.")) + new /obj/effect/temp_visual/destabilising_tear(drop_location()) + + +//perching stuff. Since it is not a parrot I need to copy its code over?? Tell me if there is an easier way to do this. + +/mob/living/basic/volkan/shoulder_pet/update_icon_state() + . = ..() + if(stat == DEAD) + return + icon_state = HAS_TRAIT(src, TRAIT_PARROT_PERCHED) ? icon_sit : icon_living + +/mob/living/basic/volkan/shoulder_pet/proc/start_perching(atom/target) + if(HAS_TRAIT(src, TRAIT_PARROT_PERCHED)) + balloon_alert(src, "already perched!") + return FALSE + + if(ishuman(target)) + return perch_on_human(target) + + if(!is_type_in_typecache(target, desired_perches)) + return FALSE + + forceMove(get_turf(target)) + toggle_perched(perched = TRUE) + RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(after_move)) + return TRUE + +/mob/living/basic/volkan/shoulder_pet/proc/after_move(atom/source) + SIGNAL_HANDLER + + UnregisterSignal(src, COMSIG_MOVABLE_MOVED) + toggle_perched(perched = FALSE) + +/mob/living/basic/volkan/shoulder_pet/proc/perch_on_human(mob/living/carbon/human/target) + if(LAZYLEN(target.buckled_mobs) >= target.max_buckled_mobs) + balloon_alert(src, "can't perch on them!") + return FALSE + + forceMove(get_turf(target)) + if(!target.buckle_mob(src, TRUE)) + return FALSE + + to_chat(src, span_notice("You sit on [target]'s shoulder.")) + toggle_perched(perched = TRUE) + RegisterSignal(src, COMSIG_LIVING_SET_BUCKLED, PROC_REF(on_unbuckle)) + return TRUE + +/mob/living/basic/volkan/shoulder_pet/proc/on_unbuckle(mob/living/source, atom/movable/new_buckled) + SIGNAL_HANDLER + + if(new_buckled) + return + UnregisterSignal(src, COMSIG_LIVING_SET_BUCKLED) + toggle_perched(perched = FALSE) + +/mob/living/basic/volkan/shoulder_pet/proc/toggle_perched(perched) + if(!perched) + REMOVE_TRAIT(src, TRAIT_PARROT_PERCHED, TRAIT_GENERIC) + else + ADD_TRAIT(src, TRAIT_PARROT_PERCHED, TRAIT_GENERIC) + update_appearance(UPDATE_ICON_STATE) + +//----------------------------------------AI CONTROLLER-------------------------------------------------- +/datum/ai_controller/basic_controller/volkan/shoulder_pet + blackboard = list() + + ai_traits = STOP_MOVING_WHEN_PULLED + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk/volkan/shoulder_pet + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/allow_items, + ) + + planning_subtrees = list( + /datum/ai_planning_subtree/pet_planning, + /datum/ai_planning_subtree/target_retaliate, + ) + +//perching stuff. perching is using the parrot code :) +/datum/idle_behavior/idle_random_walk/volkan/shoulder_pet + //we do not want it to fly away from your shoulder without an order. + var/walk_chance_when_perched = 0 + +/** + * # Pet Command: Perch + * Tells a pet that can perch, to perch on your shoulder. + */ +/datum/pet_command/perch + command_name = "Perch" + command_desc = "Command your pet to perch on your shoulder." + radial_icon = 'icons/mob/actions/actions_spells.dmi' + radial_icon_state = "repulse" + speech_commands = list("perch") + command_feedback = "flies up to your shoulder!" + var/perch_behavior = /datum/ai_behavior/perch_on_target/ + +/datum/pet_command/perch/set_command_active(mob/living/parent, mob/living/commander) + . = ..() + set_command_target(parent, commander) + +/datum/pet_command/perch/execute_action(datum/ai_controller/controller) + controller.queue_behavior(perch_behavior, BB_CURRENT_PET_TARGET) + return SUBTREE_RETURN_FINISH_PLANNING diff --git a/maplestation_modules/story_content/volkan_equipment/icons/companions.dmi b/maplestation_modules/story_content/volkan_equipment/icons/companions.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7865060fe885ee7b19f84d5c44347ef5a91b1dad GIT binary patch literal 7382 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