conjuring a demonic chicken
---------------------------
for a warm-nup, we're going to be adding in a new monster to the game:
a demonic chicken. this should help you get a feel for the modding process,
plus it's fun and doesn't require as much planning as the next things we'll
be adding later in this tutorial.
the monster catalog
it's time to open src/brogue/Globals.c, which holds tons of variable
definitions. Globals.c is similar to the file src/brogue/Rogue.h, but the latter
has global constants and header files, while the former holds global variables.
a good deal of our modding will take place in these two files.
let's jump down to the monsterCatalog array (search "monsterCatalog["). each
entry (and yeah, the entries are spaced out really strangely) is a
definition for a type of creature, with important stats like the creature's
blood type and attack skills. the definitions are in the form of
{ index, (seems to always be 0)
name,
character,
char color,
health,
defense,
accuracy,
damage, (random range in form of {lower, upper, clumpfactor})
regeneration,
speed, (lower = faster)
attack frequency, (high = slower)
blood color,
light color,
dfchance, (df = dungeon feature)
dftype,
bolts,
behavior,
ability }
,
although some entries lack a few of the final fields. this is because those will
default to 0, which usually means "no special abilities." the values used for each
field can be kind of cryptic, but it usually works to just pick it up as you go along.
another important note: most constant values (the ones in all caps) come from Rogue.h.
anyway, let's define that demon chicken! here are its attributes:
name: "demon chicken"
character: 'c'
color: &insectBloodColor
health: 20
defense: 30
accuracy: 100%
damage: {2, 8, 2}
regeneration: 20
speed: 100
attack: 100
blood: DF_ECTOPLASM_BLOOD
light: BURNING_CREATURE_LIGHT
dfchance: 100
dftype: DF_METHANE_GAS_PUFF
bolts: BOLT_SPARK, BOLT_LIGHTNING, BOLT_BLINKING
behavior: MONST_MAINTAINS_DISTANCE, MONST_FLEES_NEAR_DEATH
ability: MA_AVOID_CORRIDORS
here's what that looks like in code:
{ 0, "demon chicken", 'c', &insectBloodColor, 20, 30, 100, {2,8,2}, 20, 100, 100, DF_ECTOPLASM_BLOOD,
BURNING_CREATURE_LIGHT, 100, DF_METHANE_GAS_PUFF, 0,
(MONST_MAINTAINS_DISTANCE|MONST_FLEES_NEAR_DEATH), MA_AVOID_CORRIDORS }
adding the monster type
near line 910 of Rogue.h, you'll find the declaration of enum monsterTypes.
add MK_DEMON_CHICKEN into this enum (anywhere will do, as long as it's not
the last element because that's used to track how many monster types are defined). this type name is
used to refer to the monster throughout other parts of the code, as we'll see shortly.
biology time
monsters are classified into groups based on common characteristics. these groups are
mainly used for armor/weapon runes, so you can have runes that will instantly slay undead
monsters, or provide immunity from animal-type monsters, etc. chickens are animals, so
go to ~line 2197 of Globals.c and modify the "animal" slot of the monsterClassCatalog
so it looks like this:
{"animal", 10, 10, {MK_RAT, MK_MONKEY, MK_JACKAL, MK_EEL, MK_TOAD,
MK_VAMPIRE_BAT, MK_CENTIPEDE, MK_SPIDER, MK_DEMON_CHICKEN}},
spawning
monsters spawn in what's called a horde, which is basically just a group of
monsters with a specific depth/number of members/etc. like with the monster catalogue,
there's a horde catalog complete with another weird table-like format. it's defined as
hordeCatalog near line 1984 in Globals.c. the horde for spawning a chicken will be pretty
simple, with the following properties:
leader: MK_DEMON_CHICKEN
#members: 0
member list: []
member numbers: [[]]
min depth: 1
max depth: 40
frequency: 150
spawns in: everywhere
machine: none
flags: none
by the way, the field "machine" describes which special structures (if any) the horde spawns in,
and the field "flags" holds flags that determine spawning behavior, such as whether or not the horde
spawns multiple times while a level is being played. also, note that the member lists are empty because
there's already one member of the chicken horde implicitly.
as like before, here's the code for our demon chicken:
{MK_DEMON_CHICKEN, 0, {0}, {{0}}, 1, 40, 150},
you thought we were done?
there's one last thing to add: the description. near line 1731 of Globals.c, there's another
table thing called monsterText, with descriptions of the monster and text to display when
the monster does something. here's what this data looks like for our monster chicken:
description: "A demonic chicken. Looking at it makes you uncomfortable."
absorbing message: "pecking at"
absorbing status: "Mauling"
attack: ["brutalizes", "slices"]
df: none
summon: none
aaaand it looks like this when translated into code:
{"A demonic chicken. Looking at it makes you uncomfortable.",
"pecking at", "Mauling",
{"brutalizes", "slices", {0}}},
one final thing to note is that the chicken's description has to be at the same
index at which it occurs in the monsterCatalog and monsterTypes tables.
testing this thing out
compile it, run it, give it a go. if it works, then great! you can move on
to the next step. if not, then either try this step again or contact me if
you think my tutorial is incorrect about something.