diff --git a/config/fxdata/rules.cfg b/config/fxdata/rules.cfg index 1ed441bdbd..7dd9301444 100644 --- a/config/fxdata/rules.cfg +++ b/config/fxdata/rules.cfg @@ -247,3 +247,4 @@ NegSpellAll = SPELL_SLOW VAMPIRE DEMONSPAWN ;MkGoodHero = AVATAR KNIGHT SAMURAI WIZARD GIANT MONK ;NegUniqFunc = COSTLIER_IMPS TUNNELLER ;NegUniqFunc = ALL_CREATRS_VER_ANGRY VAMPIRE HORNY +;PosUniqFunc = ALL_CREATRS_HAPPY TIME_MAGE FAIRY diff --git a/src/config_rules.c b/src/config_rules.c index 71770bf47f..4ba0fb6881 100644 --- a/src/config_rules.c +++ b/src/config_rules.c @@ -217,6 +217,7 @@ const struct NamedCommand rules_sacrifices_commands[] = { const struct NamedCommand sacrifice_unique_desc[] = { {"ALL_CREATRS_ANGRY", UnqF_MkAllAngry}, + {"ALL_CREATRS_HAPPY", UnqF_MkAllHappy}, {"COMPLETE_RESEARCH", UnqF_ComplResrch}, {"COMPLETE_MANUFACTR", UnqF_ComplManufc}, {"KILL_ALL_CHICKENS", UnqF_KillChickns}, diff --git a/src/config_rules.h b/src/config_rules.h index 953f923c43..13ea5683a6 100644 --- a/src/config_rules.h +++ b/src/config_rules.h @@ -52,6 +52,7 @@ enum UniqueFunctions { UnqF_KillChickns, UnqF_CheaperImp, UnqF_CostlierImp, + UnqF_MkAllHappy, }; enum SacrificeReturn { diff --git a/src/creature_states_pray.c b/src/creature_states_pray.c index ffa3f4cf3c..b48dd510a5 100644 --- a/src/creature_states_pray.c +++ b/src/creature_states_pray.c @@ -269,6 +269,51 @@ TbBool make_all_players_creatures_angry(long plyr_idx) return true; } +TbBool anger_make_creature_happy(struct Thing* creatng) +{ + struct CreatureStats* crstat = creature_stats_get_from_thing(creatng); + if ((crstat->annoy_level <= 0)) + return false; + if (!anger_free_for_anger_decrease(creatng)) + { + return false; + } + creature_be_happy(creatng); + anger_set_creature_anger_all_types(creatng, 0); + return true; +} + +TbBool make_all_players_creatures_happy(long plyr_idx) +{ + SYNCDBG(8, "Starting"); + struct Dungeon* dungeon = get_players_num_dungeon(plyr_idx); + unsigned long k = 0; + int i = dungeon->creatr_list_start; + while (i != 0) + { + struct Thing* thing = thing_get(i); + TRACE_THING(thing); + struct CreatureControl* cctrl = creature_control_get_from_thing(thing); + if (thing_is_invalid(thing) || creature_control_invalid(cctrl)) + { + ERRORLOG("Jump to invalid creature detected"); + break; + } + i = cctrl->players_next_creature_idx; + // Thing list loop body + anger_make_creature_happy(thing); + // Thing list loop body ends + k++; + if (k > CREATURES_COUNT) + { + ERRORLOG("Infinite loop detected when sweeping creatures list"); + break; + } + } + SYNCDBG(19, "Finished"); + return true; +} + long force_complete_current_manufacturing(long plyr_idx) { struct Dungeon* dungeon = get_players_num_dungeon(plyr_idx); @@ -461,6 +506,9 @@ long create_sacrifice_unique_award(struct Coord3d *pos, PlayerNumber plyr_idx, l case UnqF_CostlierImp: tally_sacrificed_imps(plyr_idx, -1); return SacR_AngryWarn; + case UnqF_MkAllHappy: + make_all_players_creatures_happy(plyr_idx); + return SacR_Awarded; default: ERRORLOG("Unsupported unique sacrifice award!"); return SacR_AngryWarn;