summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mods/theme/scpt/monsters.lua125
-rw-r--r--src/defines.h32
-rw-r--r--src/generate.c1
-rw-r--r--src/modules.c391
-rw-r--r--src/monster2.c6
-rw-r--r--src/types.h5
6 files changed, 437 insertions, 123 deletions
diff --git a/lib/mods/theme/scpt/monsters.lua b/lib/mods/theme/scpt/monsters.lua
index df9c641d..0f4c8cda 100644
--- a/lib/mods/theme/scpt/monsters.lua
+++ b/lib/mods/theme/scpt/monsters.lua
@@ -1,30 +1,5 @@
-- This file holds various things that govern monster behaviour with respect to the player
--- Monster vs. Player Race alignment script
--- From T-Plus by Ingeborg S. Norden
-
-monst_al = {}
-
-function monst_al_add(status, mrs, prs)
-for i,v in mrs do
--- added end
-if not monst_al[v] then monst_al[v] = {} end
-for j, w in prs do
-monst_al[v][w] = status
-end
-end
-end
-
-function monst_al_get(mr,pr)
- if monst_al[mr] then return monst_al[mr][pr]
- else return end
-end
-
--- Maia aggravation for evil beings (provided that no demonic corruptions are present)
--- Based on parts of angel.lua from T-Plus by Ingeborg S. Norden
-
--- cast dispel evil with 0 damage every 10 turns
-
add_hooks{
[HOOK_GAME_START] = function()
@@ -35,102 +10,6 @@ add_hooks{
(player_has_corruption(CORRUPT_BALROG_FORM) ~= TRUE)) then
-- "Proper" Maiar aggravate evil beings
timer_aggravate_evil_enable()
- -- Good beings (except swans, GWoPs, Wyrm Spirits, and some joke uniques) are coaligned with Maiar
-
- monst_al_add(MSTATUS_FRIEND, {25, 29, 45, 97, 109, 147, 225, 335, 346, 443, 581, 629, 699, 853, 984, 1007, 1017}, {21})
-
- -- Non-evil humanoids are neutral to Humans, Dunedain, Druedain, Rohirrim
- elseif ((get_race_name() == "Human") or
- (get_race_name() == "Dunadan") or
- (get_race_name() == "Druadan") or
- (get_race_name() == "RohanKnight")) then
- monst_al_add(MSTATUS_NEUTRAL, {43, 45, 46, 83, 93, 97, 109, 110, 142, 147, 216, 225, 293, 345, 346, 693, 699, 937, 988, 997, 998, 1000},{0, 8, 12, 16})
-
- -- Non-evil sentient (and non-animal) creatures are neutral to Hobbits, Elves, Wood-Elves
- elseif ((get_race_name() == "Hobbit") or
- (get_race_name() == "Elf") or
- (get_race_name() == "Wood-Elf")) then
- monst_al_add(MSTATUS_NEUTRAL, {43, 45, 46, 83, 93, 97, 109, 110, 142, 147, 216, 225, 293, 345, 346, 693, 699, 937, 988, 997, 998, 1000, 74, 103, 882, 1017},{2, 3, 20})
-
- -- Gnome monsters are neutral to Gnomes
- elseif get_race_name() == "Gnome" then
- monst_al_add(MSTATUS_NEUTRAL, {103, 281, 680, 984, 1001, 1003, 1007, 1011, 1014, 1016},{4})
-
- -- Dwarven monsters are neutral to Petty-dwarves and Dwarves
- elseif ((get_race_name() == "Dwarf") or
- (get_race_name() == "Petty-Dwarf")) then
- monst_al_add(MSTATUS_NEUTRAL, {111, 112, 179, 180, 181, 182},{5, 13})
-
- -- If an Orc character worships Melkor, lower-level Orcs are neutral (not Uruk-hai, however)
- elseif ((get_race_name() == "Orc") and
- (player.pgod == GOD_MELKOR)) then
- monst_al_add(MSTATUS_FRIEND, {87, 118, 126, 149, 244, 251, 264},{6})
-
- -- If a Troll character worships Melkor, Trolls are neutral (not Eldraks, Ettins, and War trolls, though)
- elseif ((get_race_name() == "Troll") and
- (player.pgod == GOD_MELKOR)) then
- monst_al_add(MSTATUS_NEUTRAL, {297, 401, 403, 424, 454, 491, 496, 509, 538},{7})
-
- -- Ogres are neutral to Half-Ogres
- elseif get_race_name() == "Half-Ogre" then
- monst_al_add(MSTATUS_NEUTRAL, {262, 285, 415, 430, 479, 745, 918},{10})
-
- -- Bears are neutral to Beornings, except werebears.
- elseif get_race_name() == "Beorning" then
- monst_al_add(MSTATUS_NEUTRAL, {160, 173, 191, 854, 855, 867, 873},{11})
-
- -- Dark elven monsters are coaligned with Dark Elves
- elseif get_race_name() == "Dark-Elf" then
- monst_al_add(MSTATUS_FRIEND, {122, 178, 183, 226, 348, 375, 400, 657},{14})
-
- -- Plants are coaligned with Ents
- elseif get_race_name() == "Ent" then
- monst_al_add(MSTATUS_FRIEND, {248, 266, 317, 329, 396},{15})
-
- -- And since the above is largely useless except out in the wild...
- -- If an Ent worships Yavanna, lower-level animals are coaligned
- -- should make the early game a bit easier for Ents.
- elseif ((get_race_name() == "Ent") and
- (player.pgod == GOD_YAVANNA)) then
- monst_al_add(MSTATUS_FRIEND, {21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 49, 50, 52, 56, 57, 58, 59, 60, 61, 62, 69, 70, 75, 77, 78, 79, 86, 88, 89, 90, 95, 96, 105, 106, 114, 119, 120, 121, 123, 127, 134, 141, 143, 151, 154, 155, 156, 160, 161, 168, 171, 173, 174, 175, 176, 187, 191, 196, 197, 198, 210, 211, 213, 230, 236, 250, 259},{15})
-
- -- All non-evil non-neutral birds are coaligned with Eagles
- elseif get_race_name() == "Eagle" then
- monst_al_add(MSTATUS_FRIEND, {61, 141, 151, 279},{17})
-
- -- Hatchling dragons are coaligned with Dragons
- elseif get_race_name() == "Dragon" then
- monst_al_add(MSTATUS_FRIEND, {163, 164, 165, 166, 167, 204, 218, 219, 911},{18})
-
- -- Yeeks are neutral to Yeeks
- elseif get_race_name() == "Yeek" then
- monst_al_add(MSTATUS_NEUTRAL, {580, 583, 594, 653, 655, 659, 661},{19})
-
- -- Oathbreakers are coaligned if player is wielding Anduril
- -- It's dirty, but it works, and it doesn't bother checking demons and the races who can't wield weapons.
- elseif get_object(INVEN_WIELD).name1 == 83 then
- monst_al_add(MSTATUS_FRIEND, {731},{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23})
- end
+ end
end,
-
-[HOOK_LEVEL_END_GEN] = function()
-
-for i=0,m_max-1 do
- local monst = monster(i)
- local s = monst_al_get(monst.r_idx, player.prace)
- if s then monst.status = s end
-end
-
-end,
-
-[HOOK_NEW_MONSTER] = function()
-
-for i=0,m_max-1 do
- local monst = monster(i)
- local s = monst_al_get(monst.r_idx, player.prace)
- if s then monst.status = s end
-end
-
-end,
-
-} \ No newline at end of file
+}
diff --git a/src/defines.h b/src/defines.h
index aad4614e..7e4321a1 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -4456,6 +4456,37 @@
#define CORRUPTIONS_MAX 34
/*
+ * Races
+ */
+#define RACE_HUMAN 0
+#define RACE_HALF_ELF 1
+#define RACE_ELF 2
+#define RACE_HOBBIT 3
+#define RACE_GNOME 4
+#define RACE_DWARF 5
+#define RACE_ORC 6
+#define RACE_TROLL 7
+#define RACE_DUNADAN 8
+#define RACE_HIGH_ELF 9
+#define RACE_HALF_OGRE 10
+#define RACE_BEORNING 11
+#define RACE_KOBOLD 12 /* ToME */
+#define RACE_DRUADAN 12 /* Theme */
+#define RACE_PETTY_DWARF 13
+#define RACE_DARK_ELF 14
+#define RACE_ENT 15
+#define RACE_ROHANKNIGHT 16
+#define RACE_THUNDERLORD 17 /* ToME */
+#define RACE_EAGLE 17 /* Theme */
+#define RACE_DEATHMOLD 18 /* ToME */
+#define RACE_DRAGON 18 /* Theme */
+#define RACE_YEEK 19
+#define RACE_WOOD_ELF 20
+#define RACE_MAIA 21
+#define RACE_EASTERLING 22 /* Theme */
+#define RACE_DEMON 23 /* Theme */
+
+/*
* Hooks
*/
#define HOOK_MONSTER_DEATH 0
@@ -4480,6 +4511,7 @@
#define HOOK_MONSTER_AI 19
#define HOOK_PLAYER_LEVEL 20
#define HOOK_WIELD 21
+#define HOOK_NEW_MONSTER_END 22
#define HOOK_AIM 24
#define HOOK_USE 25
#define HOOK_ACTIVATE 26
diff --git a/src/generate.c b/src/generate.c
index 6d83c321..bedd169d 100644
--- a/src/generate.c
+++ b/src/generate.c
@@ -8347,6 +8347,7 @@ static void finalise_special_level(void)
if (!dun_level) return;
process_hooks(HOOK_LEVEL_END_GEN, "()");
+ process_hooks_new(HOOK_LEVEL_END_GEN, NULL, NULL);
/* Calculate relative depth */
level = dun_level - d_info[dungeon_type].mindepth;
diff --git a/src/modules.c b/src/modules.c
index 3368691a..98839d34 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -743,6 +743,387 @@ bool_ theme_push_past(void *data, void *in_, void *out_)
return FALSE;
}
+/*
+ * Check if monster race is in list. The list is terminated
+ * with a -1.
+ */
+static bool_ race_in_list(int r_idx, int race_idxs[])
+{
+ int i;
+
+ for (i = 0; race_idxs[i] >= 0; i++)
+ {
+ if (r_idx == race_idxs[i])
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/*
+ * Monster racial alignment from Theme.
+ */
+static s16b *compute_monster_status(int r_idx)
+{
+ static s16b FRIEND_ = MSTATUS_FRIEND;
+ static s16b *FRIEND = &FRIEND_;
+ static s16b NEUTRAL_ = MSTATUS_NEUTRAL;
+ static s16b *NEUTRAL = &NEUTRAL_;
+
+ object_type *o_ptr = NULL;
+
+ switch (p_ptr->prace)
+ {
+ case RACE_MAIA:
+ {
+ int good_race_idxs[] = {
+ 25, 29, 45, 97, 109,
+ 147, 225, 335, 346, 443,
+ 581, 629, 699, 853, 984,
+ 1007, 1017, -1
+ };
+
+ if (!(player_has_corruption(CORRUPT_BALROG_AURA)) &&
+ !(player_has_corruption(CORRUPT_BALROG_WINGS)) &&
+ !(player_has_corruption(CORRUPT_BALROG_STRENGTH)) &&
+ !(player_has_corruption(CORRUPT_BALROG_FORM)) &&
+ race_in_list(r_idx, good_race_idxs))
+ {
+ /* Good beings (except swans, GWoPs, Wyrm
+ * Spirits, and some joke uniques) are
+ * coaligned with Maiar */
+ return FRIEND;
+ }
+
+ break;
+ }
+
+ case RACE_HUMAN:
+ case RACE_DUNADAN:
+ case RACE_DRUADAN:
+ case RACE_ROHANKNIGHT:
+ {
+ int nonevil_humanoid_race_idxs[] = {
+ 43, 45, 46, 83, 93,
+ 97, 109, 110, 142, 147,
+ 216, 225, 293, 345, 346,
+ 693, 699, 937, 988, 997,
+ 998, 1000, -1
+ };
+
+ if (race_in_list(r_idx, nonevil_humanoid_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_ELF:
+ case RACE_HOBBIT:
+ case RACE_WOOD_ELF:
+ {
+ int nonevil_sentient_race_idxs[] = {
+ 43, 45, 46, 83, 93,
+ 97, 109, 110, 142, 147,
+ 216, 225, 293, 345, 346,
+ 693, 699, 937, 988, 997,
+ 998, 1000, 74, 103, 882,
+ 1017, -1
+ };
+
+ if (race_in_list(r_idx, nonevil_sentient_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_GNOME:
+ {
+ int gnomish_race_idxs[] = {
+ 103, 281, 680, 984, 1001,
+ 1003, 1007, 1011, 1014, 1016,
+ -1
+ };
+
+ if (race_in_list(r_idx, gnomish_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_DWARF:
+ case RACE_PETTY_DWARF:
+ {
+ int dwarvish_race_idxs[] = {
+ 111, 112, 179, 180, 181,
+ 182, -1
+ };
+
+ if (race_in_list(r_idx, dwarvish_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_ORC:
+ {
+ int low_orc_race_idxs[] = {
+ 87, 118, 126, 149, 244,
+ 251, 264, -1
+ };
+
+ if ((p_ptr->pgod == GOD_MELKOR) &&
+ race_in_list(r_idx, low_orc_race_idxs))
+ {
+ return FRIEND;
+ }
+
+ break;
+ }
+
+ case RACE_TROLL:
+ {
+ int low_troll_race_idxs[] = {
+ 297, 401, 403, 424, 454,
+ 491, 496, 509, 538, -1
+ };
+
+ if ((p_ptr->pgod == GOD_MELKOR) &&
+ race_in_list(r_idx, low_troll_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_HALF_OGRE:
+ {
+ int ogre_race_idxs[] = {
+ 262, 285, 415, 430, 479,
+ 745, 918, -1
+ };
+
+ if (race_in_list(r_idx, ogre_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_BEORNING:
+ {
+ /* Bears; not werebears. */
+ int bear_race_idxs[] = {
+ 160, 173, 191, 854,
+ 855, 867, 873, -1
+ };
+
+ if (race_in_list(r_idx, bear_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ case RACE_DARK_ELF:
+ {
+ int dark_elven_race_idxs[] = {
+ 122, 178, 183, 226, 348,
+ 375, 400, 657, -1
+ };
+
+ if (race_in_list(r_idx, dark_elven_race_idxs))
+ {
+ return FRIEND;
+ }
+
+ break;
+ }
+
+ case RACE_ENT:
+ {
+ int plant_race_idxs[] = {
+ 248, 266, 317, 329, 396,
+ -1
+ };
+
+ if (race_in_list(r_idx, plant_race_idxs))
+ {
+ return FRIEND;
+ }
+
+ /* And since the above is largely useless except out
+ in the wild... If an Ent worships Yavanna,
+ lower-level animals are coaligned should make the
+ early game a bit easier for Ents. */
+
+ if (p_ptr->pgod == GOD_YAVANNA)
+ {
+ int lower_animal_race_idxs[] = {
+ 21, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31,
+ 33, 35, 36, 37, 38,
+ 39, 41, 49, 50, 52,
+ 56, 57, 58, 59, 60,
+ 61, 62, 69, 70, 75,
+ 77, 78, 79, 86, 88,
+ 89, 90, 95, 96, 105,
+ 106, 114, 119, 120, 121,
+ 123, 127, 134, 141, 143,
+ 151, 154, 155, 156, 160,
+ 161, 168, 171, 173, 174,
+ 175, 176, 187, 191, 196,
+ 197, 198, 210, 211, 213,
+ 230, 236, 250, 259, -1
+ };
+
+ if (race_in_list(r_idx, lower_animal_race_idxs))
+ {
+ return FRIEND;
+ }
+ }
+
+ break;
+ }
+
+ case RACE_EAGLE:
+ {
+ int nonevil_nonneurtal_bird_race_idxs[] = {
+ 61, 141, 151, 279, -1
+ };
+
+ if (race_in_list(r_idx, nonevil_nonneurtal_bird_race_idxs))
+ {
+ return FRIEND;
+ }
+
+ break;
+ }
+
+ case RACE_DRAGON:
+ {
+ int hatchling_dragon_race_idxs[] = {
+ 163, 164, 165, 166, 167,
+ 204, 218, 219, 911, -1
+ };
+
+ if (race_in_list(r_idx, hatchling_dragon_race_idxs))
+ {
+ return FRIEND;
+ }
+
+ break;
+ }
+
+ case RACE_YEEK:
+ {
+ int yeek_race_idxs[] = {
+ 580, 583, 594, 653, 655,
+ 659, 661, -1
+ };
+
+ if (race_in_list(r_idx, yeek_race_idxs))
+ {
+ return NEUTRAL;
+ }
+
+ break;
+ }
+
+ };
+
+ /* Oathbreakers are coaligned if player is wielding Anduril.
+ It's dirty, but it works, and it doesn't bother checking
+ demons and the races who can't wield weapons. */
+ o_ptr = get_object(INVEN_WIELD);
+ if (o_ptr != NULL &&
+ o_ptr->name1 == ART_ANDURIL)
+ {
+ switch (p_ptr->prace)
+ {
+ case RACE_HUMAN:
+ case RACE_HALF_ELF:
+ case RACE_ELF:
+ case RACE_HOBBIT:
+ case RACE_GNOME:
+ case RACE_DWARF:
+ case RACE_ORC:
+ case RACE_TROLL:
+ case RACE_DUNADAN:
+ case RACE_HIGH_ELF:
+ case RACE_HALF_OGRE:
+ case RACE_BEORNING:
+ case RACE_DRUADAN:
+ case RACE_PETTY_DWARF:
+ case RACE_DARK_ELF:
+ case RACE_ENT:
+ case RACE_ROHANKNIGHT:
+ case RACE_YEEK:
+ case RACE_WOOD_ELF:
+ case RACE_MAIA:
+ case RACE_EASTERLING:
+ case RACE_DEMON:
+ {
+ int oathbreaker_race_idxs[] = {
+ 731, -1
+ };
+
+ if (race_in_list(r_idx, oathbreaker_race_idxs))
+ {
+ return FRIEND;
+ }
+
+ break;
+ }
+ }
+ }
+
+ /* No status override */
+ return NULL;
+}
+
+static bool_ theme_level_end_gen(void *data, void *in, void *out)
+{
+ int i = 0;
+
+ for (i = 0; i < m_max; i++)
+ {
+ monster_type *m_ptr = &m_list[i];
+ int r_idx = m_ptr->r_idx;
+ s16b *status = compute_monster_status(r_idx);
+ if (status)
+ {
+ m_ptr->status = *status;
+ }
+ }
+
+ return FALSE;
+}
+
+static bool_ theme_new_monster_end(void *data, void *in_, void *out)
+{
+ hook_new_monster_end_in *in = (hook_new_monster_end_in *) in_;
+ s16b *status = compute_monster_status(in->m_ptr->r_idx);
+
+ if (status)
+ {
+ in->m_ptr->status = *status;
+ }
+
+ return FALSE;
+}
void init_hooks_module()
{
@@ -806,6 +1187,16 @@ void init_hooks_module()
"__hook_push_past",
NULL);
+ add_hook_new(HOOK_LEVEL_END_GEN,
+ theme_level_end_gen,
+ "theme_level_end_gen",
+ NULL);
+
+ add_hook_new(HOOK_NEW_MONSTER_END,
+ theme_new_monster_end,
+ "theme_new_monster_end",
+ NULL);
+
break;
}
diff --git a/src/monster2.c b/src/monster2.c
index b0753244..cdef75d4 100644
--- a/src/monster2.c
+++ b/src/monster2.c
@@ -2657,6 +2657,12 @@ s16b place_monster_one(int y, int x, int r_idx, int ego, bool_ slp, int status)
place_monster_one_race = NULL;
+ /* Processs hooks */
+ {
+ hook_new_monster_end_in in = { m_ptr };
+ process_hooks_new(HOOK_NEW_MONSTER_END, &in, NULL);
+ }
+
/* Success */
place_monster_result = c_ptr->m_idx;
return c_ptr->m_idx;
diff --git a/src/types.h b/src/types.h
index ea383ff7..cb6d8e73 100644
--- a/src/types.h
+++ b/src/types.h
@@ -2315,6 +2315,11 @@ struct hook_stair_out {
bool_ allow;
};
+typedef struct hook_new_monster_end_in hook_new_monster_end_in;
+struct hook_new_monster_end_in {
+ monster_type *m_ptr;
+};
+
/*
* Structure for the "quests"
*/