Files
Bubberstation/code/datums/elements/unfriend_attacker.dm
Jacquerel 583f65f28b Dogs become tamed when given bones (#72363)
## About The Pull Request

Previous to this PR Ian (and any other dog) would swear allegiance and
kill (or at least growl aggressively) in the name of anyone who clicked
on them sufficiently with combat mode disabled, which is boring.
Now instead Ian wants Jumbo Dog Bones.
The HoP and Warden (as dog owners) both start with one of these mythical
items which otherwise can be ordered from cargo if you want to get into
a dog's heart, but they're not cheap.
You can also use regular bones of the kind you may harvest from Lavaland
animals or Skeleton crew members but these dogs are picky and so you
have significantly less chance of success than if you buy the premium
package.

Jumbo Dog Bones also fully heal dogs, as a bonus.

Additionally to this, I added functionality to the `tameable` component
to allow it to not delete itself upon successful taming, to preserve
Ian's ability to have more than one friend.
Additionally to that, I split the "stop being friends if you attack me"
behaviour into its own element rather than being part of the "start
being friends if you pet me a lot" one, so he could also keep doing
that.
And finally I added a new signal `COMSIG_ATOM_AFTER_ATTACKEDBY` which is
sent by an atom after an item attacks it (so if it manages to get
through the attack chain and is probably actually being used for an
attack) and registered to this in the `relay_attackers` element in place
of `COMSIG_PARENT_ATTACKBY`. This means that dogs can now recognise that
when you use a bone on them you are trying to feed them, not attack
them.

## Why It's Good For The Game

The loyalty of Ian and McGriff will now be most easily available to
their owners rather than anyone with access to their office.
... which doesn't really effect very much, I just think spam-clicking
Ian was boring as a solution and spending money is at least marginally
better.
Gives you something to spend money on if you want to befriend a dog, for
instance if you're a mailperson or felinid who is tired of getting
growled at by one. Or if you bought a dog from cargo.
Removes some unintuitive edge cases where a mob might get mad at you
doing something helpful to them.

## Changelog

🆑
balance: While Ian still enjoys being petted, his heart will now most
closely belong to anyone who gives him an expensive luxury dog bone.
code: Using an item which _can_ deal damage on a mob tracking hostile
actions (such as a dog) won't automatically be considered to be a
hostile action if you aren't actually hitting it with the item.
/🆑
2023-01-06 12:44:39 -08:00

48 lines
1.5 KiB
Plaintext

#define UNFRIEND_REPLACE_KEY_SOURCE "%SOURCE%"
#define UNFRIEND_REPLACE_KEY_TARGET "%TARGET%"
/**
* # Unfriend Attacker
*
* Element which makes a mob remove you from its friends list you if you hurt it.
* Doesn't make a callout post because we don't have twitter integration.
*/
/datum/element/unfriend_attacker
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
/// Message to print if we remove a friend. String %SOURCE% and %TARGET% are replaced by names if present.
var/untamed_reaction
/datum/element/unfriend_attacker/Attach(datum/target, untamed_reaction)
. = ..()
if (!isliving(target))
return ELEMENT_INCOMPATIBLE
src.untamed_reaction = untamed_reaction
target.AddElement(/datum/element/ai_retaliate)
RegisterSignal(target, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_hurt))
/datum/element/unfriend_attacker/Detach(datum/target)
. = ..()
UnregisterSignal(target, COMSIG_ATOM_WAS_ATTACKED)
/// If it's a bad touch make enemies
/datum/element/unfriend_attacker/proc/on_hurt(mob/living/owner, atom/attacker)
SIGNAL_HANDLER
if (owner.stat != CONSCIOUS)
return
if (!isliving(attacker))
return
var/mob/living/living_attacker = attacker
if (!owner.unfriend(living_attacker))
return
if (!untamed_reaction)
return
var/display_message = replacetext(untamed_reaction, UNFRIEND_REPLACE_KEY_SOURCE, "[owner]")
display_message = replacetext(display_message, UNFRIEND_REPLACE_KEY_TARGET, "[attacker]")
owner.visible_message(span_notice(display_message))
#undef UNFRIEND_REPLACE_KEY_SOURCE
#undef UNFRIEND_REPLACE_KEY_TARGET