Add missing symbols to Blank symset and Guidebook
[aNetHack.git] / src / mplayer.c
blobde5a2d680692b4f46ebf4b72c8d177123435ceca
1 /* NetHack 3.6 mplayer.c $NHDT-Date: 1458949461 2016/03/25 23:44:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.21 $ */
2 /* Copyright (c) Izchak Miller, 1992. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
7 STATIC_DCL const char *NDECL(dev_name);
8 STATIC_DCL void FDECL(get_mplname, (struct monst *, char *));
9 STATIC_DCL void FDECL(mk_mplayer_armor, (struct monst *, SHORT_P));
11 /* These are the names of those who
12 * contributed to the development of NetHack 3.2/3.3/3.4/3.6.
14 * Keep in alphabetical order within teams.
15 * Same first name is entered once within each team.
17 static const char *developers[] = {
18 /* devteam */
19 "Dave", "Dean", "Eric", "Izchak", "Janet", "Jessie",
20 "Ken", "Kevin", "Michael", "Mike", "Pat", "Paul",
21 "Steve", "Timo", "Warwick",
22 /* PC team */
23 "Bill", "Eric", "Keizo", "Ken", "Kevin", "Michael",
24 "Mike", "Paul", "Stephen", "Steve", "Timo", "Yitzhak",
25 /* Amiga team */
26 "Andy", "Gregg", "Janne", "Keni", "Mike", "Olaf",
27 "Richard",
28 /* Mac team */
29 "Andy", "Chris", "Dean", "Jon", "Jonathan", "Kevin",
30 "Wang",
31 /* Atari team */
32 "Eric", "Marvin", "Warwick",
33 /* NT team */
34 "Alex", "Dion", "Michael",
35 /* OS/2 team */
36 "Helge", "Ron", "Timo",
37 /* VMS team */
38 "Joshua", "Pat", ""
41 /* return a randomly chosen developer name */
42 STATIC_OVL const char *
43 dev_name()
45 register int i, m = 0, n = SIZE(developers);
46 register struct monst *mtmp;
47 register boolean match;
49 do {
50 match = FALSE;
51 i = rn2(n);
52 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
53 if (!is_mplayer(mtmp->data))
54 continue;
55 if (!strncmp(developers[i], (has_mname(mtmp)) ? MNAME(mtmp) : "",
56 strlen(developers[i]))) {
57 match = TRUE;
58 break;
61 m++;
62 } while (match && m < 100); /* m for insurance */
64 if (match)
65 return (const char *) 0;
66 return (developers[i]);
69 STATIC_OVL void
70 get_mplname(mtmp, nam)
71 register struct monst *mtmp;
72 char *nam;
74 boolean fmlkind = is_female(mtmp->data);
75 const char *devnam;
77 devnam = dev_name();
78 if (!devnam)
79 Strcpy(nam, fmlkind ? "Eve" : "Adam");
80 else if (fmlkind && !!strcmp(devnam, "Janet"))
81 Strcpy(nam, rn2(2) ? "Maud" : "Eve");
82 else
83 Strcpy(nam, devnam);
85 if (fmlkind || !strcmp(nam, "Janet"))
86 mtmp->female = 1;
87 else
88 mtmp->female = 0;
89 Strcat(nam, " the ");
90 Strcat(nam, rank_of((int) mtmp->m_lev, monsndx(mtmp->data),
91 (boolean) mtmp->female));
94 STATIC_OVL void
95 mk_mplayer_armor(mon, typ)
96 struct monst *mon;
97 short typ;
99 struct obj *obj;
101 if (typ == STRANGE_OBJECT)
102 return;
103 obj = mksobj(typ, FALSE, FALSE);
104 if (!rn2(3))
105 obj->oerodeproof = 1;
106 if (!rn2(3))
107 curse(obj);
108 if (!rn2(3))
109 bless(obj);
110 /* Most players who get to the endgame who have cursed equipment
111 * have it because the wizard or other monsters cursed it, so its
112 * chances of having plusses is the same as usual....
114 obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4, 4)) : -rnd(3);
115 (void) mpickobj(mon, obj);
118 struct monst *
119 mk_mplayer(ptr, x, y, special)
120 register struct permonst *ptr;
121 xchar x, y;
122 register boolean special;
124 register struct monst *mtmp;
125 char nam[PL_NSIZ];
127 if (!is_mplayer(ptr))
128 return ((struct monst *) 0);
130 if (MON_AT(x, y))
131 (void) rloc(m_at(x, y), FALSE); /* insurance */
133 if (!In_endgame(&u.uz))
134 special = FALSE;
136 if ((mtmp = makemon(ptr, x, y, NO_MM_FLAGS)) != 0) {
137 short weapon, armor, cloak, helm, shield;
138 int quan;
139 struct obj *otmp;
141 mtmp->m_lev = (special ? rn1(16, 15) : rnd(16));
142 mtmp->mhp = mtmp->mhpmax = d((int) mtmp->m_lev, 10)
143 + (special ? (30 + rnd(30)) : 30);
144 if (special) {
145 get_mplname(mtmp, nam);
146 mtmp = christen_monst(mtmp, nam);
147 /* that's why they are "stuck" in the endgame :-) */
148 (void) mongets(mtmp, FAKE_AMULET_OF_YENDOR);
150 mtmp->mpeaceful = 0;
151 set_malign(mtmp); /* peaceful may have changed again */
153 /* default equipment; much of it will be overridden below */
154 weapon = !rn2(2) ? LONG_SWORD : rnd_class(SPEAR, BULLWHIP);
155 armor = rnd_class(GRAY_DRAGON_SCALE_MAIL, YELLOW_DRAGON_SCALE_MAIL);
156 cloak = !rn2(8) ? STRANGE_OBJECT
157 : rnd_class(OILSKIN_CLOAK, CLOAK_OF_DISPLACEMENT);
158 helm = !rn2(8) ? STRANGE_OBJECT
159 : rnd_class(ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY);
160 shield = !rn2(8) ? STRANGE_OBJECT
161 : rnd_class(ELVEN_SHIELD, SHIELD_OF_REFLECTION);
163 switch (monsndx(ptr)) {
164 case PM_ARCHEOLOGIST:
165 if (rn2(2))
166 weapon = BULLWHIP;
167 break;
168 case PM_BARBARIAN:
169 if (rn2(2)) {
170 weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
171 shield = STRANGE_OBJECT;
173 if (rn2(2))
174 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
175 if (helm == HELM_OF_BRILLIANCE)
176 helm = STRANGE_OBJECT;
177 break;
178 case PM_CAVEMAN:
179 case PM_CAVEWOMAN:
180 if (rn2(4))
181 weapon = MACE;
182 else if (rn2(2))
183 weapon = CLUB;
184 if (helm == HELM_OF_BRILLIANCE)
185 helm = STRANGE_OBJECT;
186 break;
187 case PM_HEALER:
188 if (rn2(4))
189 weapon = QUARTERSTAFF;
190 else if (rn2(2))
191 weapon = rn2(2) ? UNICORN_HORN : SCALPEL;
192 if (rn2(4))
193 helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
194 if (rn2(2))
195 shield = STRANGE_OBJECT;
196 break;
197 case PM_KNIGHT:
198 if (rn2(4))
199 weapon = LONG_SWORD;
200 if (rn2(2))
201 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
202 break;
203 case PM_MONK:
204 weapon = !rn2(3) ? SHURIKEN : STRANGE_OBJECT;
205 armor = STRANGE_OBJECT;
206 cloak = ROBE;
207 if (rn2(2))
208 shield = STRANGE_OBJECT;
209 break;
210 case PM_PRIEST:
211 case PM_PRIESTESS:
212 if (rn2(2))
213 weapon = MACE;
214 if (rn2(2))
215 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
216 if (rn2(4))
217 cloak = ROBE;
218 if (rn2(4))
219 helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
220 if (rn2(2))
221 shield = STRANGE_OBJECT;
222 break;
223 case PM_RANGER:
224 if (rn2(2))
225 weapon = ELVEN_DAGGER;
226 break;
227 case PM_ROGUE:
228 if (rn2(2))
229 weapon = rn2(2) ? SHORT_SWORD : ORCISH_DAGGER;
230 break;
231 case PM_SAMURAI:
232 if (rn2(2))
233 weapon = KATANA;
234 break;
235 case PM_TOURIST:
236 /* Defaults are just fine */
237 break;
238 case PM_VALKYRIE:
239 if (rn2(2))
240 weapon = WAR_HAMMER;
241 if (rn2(2))
242 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
243 break;
244 case PM_WIZARD:
245 if (rn2(4))
246 weapon = rn2(2) ? QUARTERSTAFF : ATHAME;
247 if (rn2(2)) {
248 armor = rn2(2) ? BLACK_DRAGON_SCALE_MAIL
249 : SILVER_DRAGON_SCALE_MAIL;
250 cloak = CLOAK_OF_MAGIC_RESISTANCE;
252 if (rn2(4))
253 helm = HELM_OF_BRILLIANCE;
254 shield = STRANGE_OBJECT;
255 break;
256 default:
257 impossible("bad mplayer monster");
258 weapon = 0;
259 break;
262 if (weapon != STRANGE_OBJECT) {
263 otmp = mksobj(weapon, TRUE, FALSE);
264 otmp->spe = (special ? rn1(5, 4) : rn2(4));
265 if (!rn2(3))
266 otmp->oerodeproof = 1;
267 else if (!rn2(2))
268 otmp->greased = 1;
269 if (special && rn2(2))
270 otmp = mk_artifact(otmp, A_NONE);
271 /* usually increase stack size if stackable weapon */
272 if (objects[otmp->otyp].oc_merge && !otmp->oartifact)
273 otmp->quan += (long) rn2(is_spear(otmp) ? 4 : 8);
274 /* mplayers knew better than to overenchant Magicbane */
275 if (otmp->oartifact == ART_MAGICBANE)
276 otmp->spe = rnd(4);
277 (void) mpickobj(mtmp, otmp);
280 if (special) {
281 if (!rn2(10))
282 (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
283 mk_mplayer_armor(mtmp, armor);
284 mk_mplayer_armor(mtmp, cloak);
285 mk_mplayer_armor(mtmp, helm);
286 mk_mplayer_armor(mtmp, shield);
287 if (rn2(8))
288 mk_mplayer_armor(mtmp, rnd_class(LEATHER_GLOVES,
289 GAUNTLETS_OF_DEXTERITY));
290 if (rn2(8))
291 mk_mplayer_armor(mtmp, rnd_class(LOW_BOOTS,
292 LEVITATION_BOOTS));
293 m_dowear(mtmp, TRUE);
295 quan = rn2(3) ? rn2(3) : rn2(16);
296 while (quan--)
297 (void) mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
298 /* To get the gold "right" would mean a player can double his
299 gold supply by killing one mplayer. Not good. */
300 mkmonmoney(mtmp, rn2(1000));
301 quan = rn2(10);
302 while (quan--)
303 (void) mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
305 quan = rnd(3);
306 while (quan--)
307 (void) mongets(mtmp, rnd_offensive_item(mtmp));
308 quan = rnd(3);
309 while (quan--)
310 (void) mongets(mtmp, rnd_defensive_item(mtmp));
311 quan = rnd(3);
312 while (quan--)
313 (void) mongets(mtmp, rnd_misc_item(mtmp));
316 return (mtmp);
319 /* create the indicated number (num) of monster-players,
320 * randomly chosen, and in randomly chosen (free) locations
321 * on the level. If "special", the size of num should not
322 * be bigger than the number of _non-repeated_ names in the
323 * developers array, otherwise a bunch of Adams and Eves will
324 * fill up the overflow.
326 void
327 create_mplayers(num, special)
328 register int num;
329 boolean special;
331 int pm, x, y;
332 struct monst fakemon;
334 fakemon = zeromonst;
335 while (num) {
336 int tryct = 0;
338 /* roll for character class */
339 pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
340 set_mon_data(&fakemon, &mons[pm], -1);
342 /* roll for an available location */
343 do {
344 x = rn1(COLNO - 4, 2);
345 y = rnd(ROWNO - 2);
346 } while (!goodpos(x, y, &fakemon, 0) && tryct++ <= 50);
348 /* if pos not found in 50 tries, don't bother to continue */
349 if (tryct > 50)
350 return;
352 (void) mk_mplayer(&mons[pm], (xchar) x, (xchar) y, special);
353 num--;
357 void
358 mplayer_talk(mtmp)
359 register struct monst *mtmp;
361 static const char
362 *same_class_msg[3] = {
363 "I can't win, and neither will you!",
364 "You don't deserve to win!",
365 "Mine should be the honor, not yours!",
367 *other_class_msg[3] = {
368 "The low-life wants to talk, eh?",
369 "Fight, scum!",
370 "Here is what I have to say!",
373 if (mtmp->mpeaceful)
374 return; /* will drop to humanoid talk */
376 pline("Talk? -- %s", (mtmp->data == &mons[urole.malenum]
377 || mtmp->data == &mons[urole.femalenum])
378 ? same_class_msg[rn2(3)]
379 : other_class_msg[rn2(3)]);
382 /*mplayer.c*/