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