Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parrottai #34

Merged
merged 11 commits into from
Nov 13, 2023
23 changes: 12 additions & 11 deletions _maps/RandomRuins/AnywhereRuins/golem_ship.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,6 @@
},
/turf/open/floor/wood,
/area/ruin/powered/golem_ship)
"mE" = (
/turf/open/water/jungle,
/area/ruin/powered/golem_ship)
"mU" = (
/obj/machinery/power/shuttle_engine/propulsion{
dir = 4
Expand Down Expand Up @@ -503,6 +500,10 @@
},
/turf/open/floor/mineral/titanium,
/area/ruin/powered/golem_ship)
"Cx" = (
/obj/machinery/fishing_portal_generator,
/turf/open/floor/mineral/titanium,
/area/ruin/powered/golem_ship)
"CI" = (
/obj/effect/mob_spawn/ghost_role/human/golem/adamantine,
/obj/structure/sink/directional/west,
Expand Down Expand Up @@ -980,8 +981,8 @@ wN
(10,1,1) = {"
wN
wN
mE
mE
wN
wN
Df
Df
Df
Expand All @@ -997,13 +998,13 @@ wN
"}
(11,1,1) = {"
wN
mE
mE
wN
wN
Df
Df
vr
QX
sS
Cx
sS
sS
At
Expand All @@ -1015,8 +1016,8 @@ Df
"}
(12,1,1) = {"
wN
mE
mE
wN
wN
Df
bO
XR
Expand All @@ -1034,7 +1035,7 @@ Df
(13,1,1) = {"
wN
wN
mE
wN
lF
bO
ir
Expand Down
10 changes: 2 additions & 8 deletions _maps/RandomRuins/IceRuins/icemoon_surface_mining_site.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,6 @@
},
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"Bv" = (
/turf/open/misc/snow,
/area/icemoon/surface/outdoors/nospawn)
"Dd" = (
/turf/closed/mineral/random/snow,
/area/icemoon/surface/outdoors/nospawn)
Expand Down Expand Up @@ -265,9 +262,6 @@
/obj/structure/railing/corner,
/turf/open/floor/plating/snowed/smoothed/icemoon,
/area/icemoon/surface/outdoors/nospawn)
"PT" = (
/turf/template_noop,
/area/icemoon/surface/outdoors/nospawn)
"Qi" = (
/obj/effect/turf_decal/stripes/corner,
/obj/item/flashlight/glowstick/red{
Expand Down Expand Up @@ -414,7 +408,7 @@ fl
fl
"}
(4,1,1) = {"
Bv
lH
eu
jQ
vJ
Expand Down Expand Up @@ -532,7 +526,7 @@ fl
(8,1,1) = {"
Dd
Dd
PT
Dd
nT
kd
yA
Expand Down
17 changes: 8 additions & 9 deletions code/__DEFINES/ai/pets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@
#define BB_PARROT_REPEAT_PROBABILITY "BB_parrot_repeat_probability"
/// The odds that this parrot will choose another string to repeat
#define BB_PARROT_PHRASE_CHANGE_PROBABILITY "BB_parrot_phrase_change_probability"
/// A copy of the string buffer that we end the shift with. DO NOT ACCESS THIS DIRECTLY - YOU SHOULD USE THE ELEMENT IN MOST CASES
/// A copy of the string buffer that we end the shift with. DO NOT ACCESS THIS DIRECTLY - YOU SHOULD USE THE COMPONENT IN MOST CASES
#define BB_EXPORTABLE_STRING_BUFFER_LIST "BB_parrot_repeat_string_buffer"
/// The current INANIMATE perch that we have
#define BB_PARROT_INANIMATE_PERCH "BB_parrot_perch"
/// The target human that we wanna try to perch on
#define BB_PARROT_HUMAN_PERCH "BB_parrot_human_perch"
/// The types of perches we desire to use
#define BB_PARROT_PERCH_TYPES "BB_parrot_perch_types"
/// The current thing that we wanna grab and take back to our perch
#define BB_PARROT_STEAL_TARGET "BB_parrot_steal_target"
/// The person that we wanna steal from
#define BB_PARROT_STEAL_HUMAN "BB_parrot_steal_human"
#define BB_PERCH_TARGET "perch_target"
#define BB_HOARD_ITEM_TARGET "hoard_item_target"
#define BB_THEFT_VICTIM "theft_victim"
#define BB_HOARD_LOCATION "hoard_location"
#define BB_HOARD_LOCATION_RANGE "hoard_location_range"
#define BB_IGNORE_ITEMS "ignore_items"

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
#define COMSIG_MOVABLE_THROW_LANDED "movable_throw_landed"
///from base of atom/movable/on_changed_z_level(): (turf/old_turf, turf/new_turf, same_z_layer)
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit"
///called before hearing a message froma tom/movable/Hear():
#define COMSIG_MOVABLE_PRE_HEAR "movable_pre_hear"
///do not proceed to hear the message
#define COMSIG_MOVABLE_CANCEL_HEARING (1<<0)
///from base of atom/movable/Hear(): (proc args list(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), message_range))
#define COMSIG_MOVABLE_HEAR "movable_hear"
#define HEARING_MESSAGE 1
Expand Down
2 changes: 1 addition & 1 deletion code/_globalvars/phobias.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list(
/mob/living/basic/chick,
/mob/living/basic/chicken,
/mob/living/basic/pet/penguin,
/mob/living/simple_animal/parrot,
/mob/living/basic/parrot,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll alphabetize this

)),
"conspiracies" = typecacheof(list(
/mob/living/basic/drone,
Expand Down
5 changes: 3 additions & 2 deletions code/controllers/subsystem/persistence/_persistence.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ SUBSYSTEM_DEF(persistence)

///Loads up Poly's speech buffer.
/datum/controller/subsystem/persistence/proc/load_poly()
for(var/mob/living/simple_animal/parrot/poly/P in GLOB.alive_mob_list)
twitterize(P.speech_buffer, "polytalk")
for(var/mob/living/basic/parrot/poly/bird in GLOB.alive_mob_list)
var/list/list_to_read = bird.get_static_list_of_phrases()
twitterize(list_to_read, "polytalk")
break //Who's been duping the bird?!

/// Loads up the amount of times maps appeared to alter their appearance in voting and rotation.
Expand Down
11 changes: 11 additions & 0 deletions code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/datum/ai_behavior/basic_melee_attack
action_cooldown = 0.2 SECONDS // We gotta check unfortunately often because we're in a race condition with nextmove
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
///do we finish this action after hitting once?
var/terminate_after_action = FALSE

/datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
Expand Down Expand Up @@ -39,12 +41,21 @@
else
basic_mob.melee_attack(target)

if(terminate_after_action)
finish_action(controller, TRUE, target_key)

/datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
if(!succeeded)
controller.clear_blackboard_key(target_key)

/datum/ai_behavior/basic_melee_attack/interact_once
terminate_after_action = TRUE

/datum/ai_behavior/basic_melee_attack/interact_once/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
controller.clear_blackboard_key(target_key)

/datum/ai_behavior/basic_ranged_attack
action_cooldown = 0.6 SECONDS
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM
Expand Down
13 changes: 13 additions & 0 deletions code/datums/ai/generic/find_and_set.dm
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,16 @@
return pick(customers)

return null

/datum/ai_behavior/find_and_set/nearby_friends
action_cooldown = 2 SECONDS

/datum/ai_behavior/find_and_set/nearby_friends/search_tactic(datum/ai_controller/controller, locate_path, search_range)
var/atom/friend = locate(/mob/living/carbon/human) in oview(search_range, controller.pawn)

if(isnull(friend))
return null

var/mob/living/living_pawn = controller.pawn
var/potential_friend = living_pawn.faction.Find(REF(friend)) ? friend : null
return potential_friend
24 changes: 5 additions & 19 deletions code/datums/components/listen_and_repeat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,26 @@
/// List of things that we've heard and will repeat.
var/list/speech_buffer = null

/datum/component/listen_and_repeat/Initialize(list/desired_phrases, blackboard_key, speech_probability, switch_phrase_probability)
/datum/component/listen_and_repeat/Initialize(list/desired_phrases, blackboard_key)
. = ..()
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE

if(isnull(speech_probability))
src.speech_probability = 20

if(!isnull(desired_phrases))
LAZYADD(speech_buffer, desired_phrases)

src.blackboard_key = blackboard_key

RegisterSignal(parent, COMSIG_MOVABLE_HEAR, PROC_REF(on_hear))
RegisterSignal(parent, COMSIG_MOVABLE_PRE_HEAR, PROC_REF(on_hear))
RegisterSignal(parent, COMSIG_NEEDS_NEW_PHRASE, PROC_REF(set_new_blackboard_phrase))
RegisterSignal(parent, COMSIG_LIVING_WRITE_MEMORY, PROC_REF(on_write_memory))
RegisterSignals(parent, list(COMSIG_AI_BLACKBOARD_KEY_SET(BB_PARROT_REPEAT_PROBABILITY), COMSIG_AI_BLACKBOARD_KEY_SET(BB_PARROT_PHRASE_CHANGE_PROBABILITY)), PROC_REF(update_probabilities))
// register to detach when a client logs in maybe

/// Called when we hear something.
/datum/component/listen_and_repeat/proc/on_hear(datum/source, list/passed_arguments)
SIGNAL_HANDLER
if(!prob(speech_probability))
return

var/message = passed_arguments[HEARING_MESSAGE]
var/message = passed_arguments[HEARING_RAW_MESSAGE]
var/speaker = passed_arguments[HEARING_SPEAKER]
var/over_radio = !!passed_arguments[HEARING_RADIO_FREQ]
if(speaker == source) // don't parrot ourselves
Expand All @@ -63,21 +58,12 @@
var/atom/movable/atom_source = source
var/datum/ai_controller/controller = atom_source.ai_controller
if(!LAZYLEN(speech_buffer))
controller.set_blackboard_key(blackboard_key, null)
controller.clear_blackboard_key(blackboard_key)
return NO_NEW_PHRASE_AVAILABLE

if(!prob(switch_phrase_probability))
return

var/selected_phrase = pick(speech_buffer)
controller.set_blackboard_key(blackboard_key, selected_phrase)

/// Update the probabilities whenever the blackboard changes on us. assume that the controller is sending the signal to be safe
/datum/component/listen_and_repeat/proc/update_probabilities(datum/ai_controller/source)
SIGNAL_HANDLER
speech_probability = source.blackboard[BB_PARROT_REPEAT_PROBABILITY]
switch_phrase_probability = source.blackboard[BB_PARROT_PHRASE_CHANGE_PROBABILITY]

/// Exports all the speech buffer data to a dedicated blackboard key on the source.
/datum/component/listen_and_repeat/proc/on_write_memory(datum/source, dead, gibbed)
SIGNAL_HANDLER
Expand Down
8 changes: 7 additions & 1 deletion code/datums/components/shielded.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

/datum/component/shielded
dupe_mode = COMPONENT_DUPE_UNIQUE
/// The person currently wearing us
var/mob/living/wearer
/// How many charges we can have max, and how many we start with
Expand Down Expand Up @@ -113,7 +114,7 @@
if((slot & ITEM_SLOT_HANDS) && !shield_inhand)
lost_wearer(source, user)
return
set_wearer(source, user)
set_wearer(user)

/// Either we've been dropped or our wearer has been QDEL'd. Either way, they're no longer our problem
/datum/component/shielded/proc/lost_wearer(datum/source, mob/user)
Expand All @@ -125,6 +126,11 @@
wearer = null

/datum/component/shielded/proc/set_wearer(mob/user)
if(wearer == user)
return
if(!isnull(wearer))
CRASH("[type] called set_wearer with [user] but [wearer] was already the wearer!")

wearer = user
RegisterSignal(wearer, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays))
RegisterSignal(wearer, COMSIG_QDELETING, PROC_REF(lost_wearer))
Expand Down
2 changes: 1 addition & 1 deletion code/datums/components/supermatter_crystal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@
message_admins("[atom_source] has consumed [key_name_admin(consumed_mob)] [ADMIN_JMP(atom_source)].")
atom_source.investigate_log("has consumed [key_name(consumed_mob)].", INVESTIGATE_ENGINE)
consumed_mob.investigate_log("has been dusted by [atom_source].", INVESTIGATE_DEATHS)
if(istype(consumed_mob, /mob/living/simple_animal/parrot/poly)) // Dusting Poly creates a power surge
if(istype(consumed_mob, /mob/living/basic/parrot/poly)) // Dusting Poly creates a power surge
force_event(/datum/round_event_control/supermatter_surge/poly, "Poly's revenge")
notify_ghosts(
"[consumed_mob] has been dusted by [atom_source]!",
Expand Down
33 changes: 22 additions & 11 deletions code/datums/diseases/parrotpossession.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,35 @@
severity = DISEASE_SEVERITY_MEDIUM
infectable_biotypes = MOB_ORGANIC|MOB_UNDEAD|MOB_ROBOTIC|MOB_MINERAL
bypasses_immunity = TRUE //2spook
var/mob/living/simple_animal/parrot/poly/ghost/parrot
///chance we speak
var/speak_chance = 5
///list of words we can use
var/list/speech_list = null


/datum/disease/parrot_possession/stage_act(seconds_per_tick, times_fired)
. = ..()

if(!.)
return

if(QDELETED(parrot) || parrot.loc != affected_mob)
cure()
return FALSE

if(length(parrot.speech_buffer) && SPT_PROB(parrot.speak_chance, seconds_per_tick)) // I'm not going to dive into polycode trying to adjust that probability. Enjoy doubled ghost parrot speach
affected_mob.say(pick(parrot.speech_buffer), forced = "parrot possession")
if(LAZYLEN(speech_list) && SPT_PROB(speak_chance, seconds_per_tick)) // I'm not going to dive into polycode trying to adjust that probability. Enjoy doubled ghost parrot speach
affected_mob.say(pick(speech_list), forced = "parrot possession")


/datum/disease/parrot_possession/cure()
if(parrot && parrot.loc == affected_mob)
parrot.forceMove(affected_mob.drop_location())
affected_mob.visible_message(span_danger("[parrot] is violently driven out of [affected_mob]!"), span_userdanger("[parrot] bursts out of your chest!"))
..()
var/atom/movable/inside_parrot = locate(/mob/living/basic/parrot/poly/ghost) in affected_mob
if(inside_parrot)
UnregisterSignal(inside_parrot, list(COMSIG_PREQDELETED, COMSIG_MOVABLE_MOVED))
inside_parrot.forceMove(affected_mob.drop_location())
affected_mob.visible_message(span_danger("[inside_parrot] is violently driven out of [affected_mob]!"), span_userdanger("[inside_parrot] bursts out of your chest!"))
return ..()

/datum/disease/parrot_possession/proc/set_parrot(mob/living/parrot)
speech_list = parrot.ai_controller?.blackboard[BB_EXPORTABLE_STRING_BUFFER_LIST]
RegisterSignals(parrot, list(COMSIG_PREQDELETED, COMSIG_MOVABLE_MOVED), PROC_REF(on_parrot_exit))

/datum/disease/parrot_possession/proc/on_parrot_exit(datum/source)
SIGNAL_HANDLER
UnregisterSignal(source, list(COMSIG_PREQDELETED, COMSIG_MOVABLE_MOVED))
cure()
2 changes: 1 addition & 1 deletion code/datums/memory/_memory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
/mob/living/basic/stickman,
/mob/living/basic/stickman/dog,
/mob/living/simple_animal/hostile/megafauna/dragon/lesser,
/mob/living/simple_animal/parrot,
/mob/living/basic/parrot,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i gotta alphabetize this

/mob/living/simple_animal/pet/cat,
/mob/living/simple_animal/pet/cat/cak,
/obj/item/food/sausage/american,
Expand Down
11 changes: 9 additions & 2 deletions code/modules/antagonists/cult/cult_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,15 @@ Striking a noncultist, however, will tear their flesh."}
fire = 50
acid = 60

/obj/item/clothing/suit/hooded/cultrobes/cult_shield/setup_shielding()
AddComponent(/datum/component/shielded, recharge_start_delay = 0 SECONDS, shield_icon_file = 'icons/effects/cult/effects.dmi', shield_icon = "shield-cult", run_hit_callback = CALLBACK(src, PROC_REF(shield_damaged)))
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/Initialize(mapload)
. = ..()
AddComponent( \
/datum/component/shielded, \
recharge_start_delay = 0 SECONDS, \
shield_icon_file = 'icons/effects/cult/effects.dmi', \
shield_icon = "shield-cult", \
run_hit_callback = CALLBACK(src, PROC_REF(shield_damaged)), \
)

/// A proc for callback when the shield breaks, since cult robes are stupid and have different effects
/obj/item/clothing/suit/hooded/cultrobes/cult_shield/proc/shield_damaged(mob/living/wearer, attack_text, new_current_charges)
Expand Down
4 changes: 2 additions & 2 deletions code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,10 @@
/datum/export/pirate/parrot
cost = 2000
unit_name = "alive parrot"
export_types = list(/mob/living/simple_animal/parrot)
export_types = list(/mob/living/basic/parrot)

/datum/export/pirate/parrot/find_loot()
for(var/mob/living/simple_animal/parrot/current_parrot in GLOB.alive_mob_list)
for(var/mob/living/basic/parrot/current_parrot in GLOB.alive_mob_list)
var/turf/parrot_turf = get_turf(current_parrot)
if(parrot_turf && is_station_level(parrot_turf.z))
return current_parrot
Expand Down
Loading