diff --git a/data/json/monsters/mammal.json b/data/json/monsters/mammal.json index 4fc2344c6597..64ba8ba76d41 100644 --- a/data/json/monsters/mammal.json +++ b/data/json/monsters/mammal.json @@ -1668,7 +1668,6 @@ "material": [ "flesh" ], "symbol": "H", "color": "brown", - "morale": 20, "melee_skill": 6, "melee_dice": 2, "melee_dice_sides": 12, @@ -1676,7 +1675,7 @@ "dodge": 2, "armor_bash": 2, "anger_triggers": [ "FRIEND_ATTACKED" ], - "fear_triggers": [ "SOUND", "PLAYER_CLOSE" ], + "fear_triggers": [ "PLAYER_CLOSE" ], "placate_triggers": [ "PLAYER_WEAK" ], "death_function": [ "NORMAL" ], "harvest": "mammal_large_leather", diff --git a/src/character.cpp b/src/character.cpp index 0c8c71393c57..82848a0a339f 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -10598,4 +10598,4 @@ bool has_psy_protection( const Character &c, int partial_chance ) { return c.has_artifact_with( AEP_PSYSHIELD ) || ( c.worn_with_flag( "PSYSHIELD_PARTIAL" ) && one_in( partial_chance ) ); -} \ No newline at end of file +} diff --git a/src/monmove.cpp b/src/monmove.cpp index 9976ebdc8088..f9844873a06a 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -581,12 +581,33 @@ void monster::plan() } else if( friendly > 0 && one_in( 3 ) ) { // Grow restless with no targets friendly--; - } else if( friendly < 0 && sees( g->u ) && !has_flag( MF_PET_WONT_FOLLOW ) ) { - if( rl_dist( pos(), g->u.pos() ) > 2 ) { - set_dest( g->u.pos() ); + // if no target, and friendly pet sees the player + } else if( friendly < 0 && sees( g->u ) ) { + // eg dogs + if( !has_flag( MF_PET_WONT_FOLLOW ) ) { + // if too far from the player, go to him + if( rl_dist( pos(), g->u.pos() ) > 2 ) { + set_dest( g->u.pos() ); + } else { + unset_dest(); + } + // eg cows, horses } else { unset_dest(); } + // when the players is close to their pet, it calms them + // it helps them reach an homeostatic state, for morale and anger + const int distance_from_friend = rl_dist( pos(), get_avatar().pos() ); + if( distance_from_friend < 12 ) { + if( one_in( distance_from_friend * 3 ) ) { + if( morale != type->morale ) { + morale += ( morale < type->morale ) ? 1 : -1; + } + if( anger != type->agro ) { + anger += ( anger < type->agro ) ? 1 : -1; + } + } + } } // being led by a leash override other movements decisions diff --git a/src/monster.cpp b/src/monster.cpp index f6aa90c3f1ba..36d351909e62 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -1190,7 +1190,7 @@ monster_attitude monster::attitude( const Character *u ) const } if( effective_anger <= 0 ) { - if( get_hp() != get_hp_max() ) { + if( get_hp() <= 0.6 * get_hp_max() ) { return MATT_FLEE; } else { return MATT_IGNORE; @@ -2587,8 +2587,8 @@ void monster::process_effects_internal() } } - //Monster will regen morale and aggression if it is on max HP - //It regens more morale and aggression if is currently fleeing. + // Monster will regen morale and aggression if it is on max HP + // It regens more morale and aggression if is currently fleeing. if( type->regen_morale && hp >= type->hp ) { if( is_fleeing( g->u ) ) { morale = type->morale; @@ -2959,6 +2959,7 @@ void monster::hear_sound( const tripoint &source, const int vol, const int dist // target_z will require some special check due to soil muffling sounds int wander_turns = volume * ( goodhearing ? 6 : 1 ); + process_trigger( mon_trigger::SOUND, volume ); if( morale >= 0 && anger >= 10 ) { // TODO: Add a proper check for fleeing attitude