1 /* SCCS Id: @(#)mplayer.c 3.4 1997/02/04 */
2 /* Copyright (c) Izchak Miller, 1992. */
3 /* NetHack may be freely redistributed. See license for details. */
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.
14 * Keep in alphabetical order within teams.
15 * Same first name is entered once within each team.
17 static const char *developers[] = {
19 "Dave", "Dean", "Eric", "Izchak", "Janet", "Jessie",
20 "Ken", "Kevin", "Michael", "Mike", "Pat", "Paul", "Steve", "Timo",
23 "Bill", "Eric", "Keizo", "Ken", "Kevin", "Michael", "Mike", "Paul",
24 "Stephen", "Steve", "Timo", "Yitzhak",
26 "Andy", "Gregg", "Janne", "Keni", "Mike", "Olaf", "Richard",
28 "Andy", "Chris", "Dean", "Jon", "Jonathan", "Kevin", "Wang",
30 "Eric", "Marvin", "Warwick",
32 "Alex", "Dion", "Michael",
34 "Helge", "Ron", "Timo",
40 /* return a randomly chosen developer name */
41 STATIC_OVL const char *
44 register int i, m = 0, n = SIZE(developers);
45 register struct monst *mtmp;
46 register boolean match;
51 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
52 if(!is_mplayer(mtmp->data)) continue;
53 if(!strncmp(developers[i], NAME(mtmp),
54 strlen(developers[i]))) {
60 } while (match && m < 100); /* m for insurance */
62 if (match) return (const char *)0;
63 return(developers[i]);
67 get_mplname(mtmp, nam)
68 register struct monst *mtmp;
71 boolean fmlkind = is_female(mtmp->data);
76 Strcpy(nam, fmlkind ? "Eve" : "Adam");
77 else if (fmlkind && !!strcmp(devnam, "Janet"))
78 Strcpy(nam, rn2(2) ? "Maud" : "Eve");
79 else Strcpy(nam, devnam);
81 if (fmlkind || !strcmp(nam, "Janet"))
86 Strcat(nam, rank_of((int)mtmp->m_lev,
88 (boolean)mtmp->female));
92 mk_mplayer_armor(mon, typ)
98 if (typ == STRANGE_OBJECT) return;
99 obj = mksobj(typ, FALSE, FALSE);
100 if (!rn2(3)) obj->oerodeproof = 1;
101 if (!rn2(3)) curse(obj);
102 if (!rn2(3)) bless(obj);
103 /* Most players who get to the endgame who have cursed equipment
104 * have it because the wizard or other monsters cursed it, so its
105 * chances of having plusses is the same as usual....
107 obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4,4)) : -rnd(3);
108 (void) mpickobj(mon, obj);
112 mk_mplayer(ptr, x, y, special)
113 register struct permonst *ptr;
115 register boolean special;
117 register struct monst *mtmp;
121 return((struct monst *)0);
124 (void) rloc(m_at(x, y), FALSE); /* insurance */
126 if(!In_endgame(&u.uz)) special = FALSE;
128 if ((mtmp = makemon(ptr, x, y, NO_MM_FLAGS)) != 0) {
129 short weapon = rn2(2) ? LONG_SWORD : rnd_class(SPEAR, BULLWHIP);
130 short armor = rnd_class(GRAY_DRAGON_SCALE_MAIL, YELLOW_DRAGON_SCALE_MAIL);
131 short cloak = !rn2(8) ? STRANGE_OBJECT :
132 rnd_class(OILSKIN_CLOAK, CLOAK_OF_DISPLACEMENT);
133 short helm = !rn2(8) ? STRANGE_OBJECT :
134 rnd_class(ELVEN_LEATHER_HELM, HELM_OF_TELEPATHY);
135 short shield = !rn2(8) ? STRANGE_OBJECT :
136 rnd_class(ELVEN_SHIELD, SHIELD_OF_REFLECTION);
140 mtmp->m_lev = (special ? rn1(16,15) : rnd(16));
141 mtmp->mhp = mtmp->mhpmax = d((int)mtmp->m_lev,10) +
142 (special ? (30 + rnd(30)) : 30);
144 get_mplname(mtmp, nam);
145 mtmp = christen_monst(mtmp, nam);
146 /* that's why they are "stuck" in the endgame :-) */
147 (void)mongets(mtmp, FAKE_AMULET_OF_YENDOR);
150 set_malign(mtmp); /* peaceful may have changed again */
152 switch(monsndx(ptr)) {
153 case PM_ARCHEOLOGIST:
154 if (rn2(2)) weapon = BULLWHIP;
158 weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
159 shield = STRANGE_OBJECT;
161 if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
162 if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT;
166 if (rn2(4)) weapon = MACE;
167 else if (rn2(2)) weapon = CLUB;
168 if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT;
171 if (rn2(4)) weapon = QUARTERSTAFF;
172 else if (rn2(2)) weapon = rn2(2) ? UNICORN_HORN : SCALPEL;
173 if (rn2(4)) helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
174 if (rn2(2)) shield = STRANGE_OBJECT;
177 if (rn2(4)) weapon = LONG_SWORD;
178 if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
181 weapon = STRANGE_OBJECT;
182 armor = STRANGE_OBJECT;
184 if (rn2(2)) shield = STRANGE_OBJECT;
188 if (rn2(2)) weapon = MACE;
189 if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
190 if (rn2(4)) cloak = ROBE;
191 if (rn2(4)) helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
192 if (rn2(2)) shield = STRANGE_OBJECT;
195 if (rn2(2)) weapon = ELVEN_DAGGER;
198 if (rn2(2)) weapon = SHORT_SWORD;
201 if (rn2(2)) weapon = KATANA;
205 /* Defaults are just fine */
209 if (rn2(2)) weapon = WAR_HAMMER;
210 if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
213 if (rn2(4)) weapon = rn2(2) ? QUARTERSTAFF : ATHAME;
215 armor = rn2(2) ? BLACK_DRAGON_SCALE_MAIL :
216 SILVER_DRAGON_SCALE_MAIL;
217 cloak = CLOAK_OF_MAGIC_RESISTANCE;
219 if (rn2(4)) helm = HELM_OF_BRILLIANCE;
220 shield = STRANGE_OBJECT;
222 default: impossible("bad mplayer monster");
227 if (weapon != STRANGE_OBJECT) {
228 otmp = mksobj(weapon, TRUE, FALSE);
229 otmp->spe = (special ? rn1(5,4) : rn2(4));
230 if (!rn2(3)) otmp->oerodeproof = 1;
231 else if (!rn2(2)) otmp->greased = 1;
232 if (special && rn2(2))
233 otmp = mk_artifact(otmp, A_NONE);
234 /* mplayers knew better than to overenchant Magicbane */
235 if (otmp->oartifact == ART_MAGICBANE)
237 (void) mpickobj(mtmp, otmp);
242 (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
243 mk_mplayer_armor(mtmp, armor);
244 mk_mplayer_armor(mtmp, cloak);
245 mk_mplayer_armor(mtmp, helm);
246 mk_mplayer_armor(mtmp, shield);
248 mk_mplayer_armor(mtmp, rnd_class(LEATHER_GLOVES,
249 GAUNTLETS_OF_DEXTERITY));
251 mk_mplayer_armor(mtmp, rnd_class(LOW_BOOTS, LEVITATION_BOOTS));
252 m_dowear(mtmp, TRUE);
254 quan = rn2(3) ? rn2(3) : rn2(16);
256 (void)mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
257 /* To get the gold "right" would mean a player can double his */
258 /* gold supply by killing one mplayer. Not good. */
260 mtmp->mgold = rn2(1000);
262 mkmonmoney(mtmp, rn2(1000));
266 (void) mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
270 (void)mongets(mtmp, rnd_offensive_item(mtmp));
273 (void)mongets(mtmp, rnd_defensive_item(mtmp));
276 (void)mongets(mtmp, rnd_misc_item(mtmp));
282 /* create the indicated number (num) of monster-players,
283 * randomly chosen, and in randomly chosen (free) locations
284 * on the level. If "special", the size of num should not
285 * be bigger than the number of _non-repeated_ names in the
286 * developers array, otherwise a bunch of Adams and Eves will
287 * fill up the overflow.
290 create_mplayers(num, special)
295 struct monst fakemon;
300 /* roll for character class */
301 pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
302 fakemon.data = &mons[pm];
304 /* roll for an available location */
308 } while(!goodpos(x, y, &fakemon, 0) && tryct++ <= 50);
310 /* if pos not found in 50 tries, don't bother to continue */
311 if(tryct > 50) return;
313 (void) mk_mplayer(&mons[pm], (xchar)x, (xchar)y, special);
320 register struct monst *mtmp;
322 static const char *same_class_msg[3] = {
323 "I can't win, and neither will you!",
324 "You don't deserve to win!",
325 "Mine should be the honor, not yours!",
326 }, *other_class_msg[3] = {
327 "The low-life wants to talk, eh?",
329 "Here is what I have to say!",
332 if(mtmp->mpeaceful) return; /* will drop to humanoid talk */
335 (mtmp->data == &mons[urole.malenum] ||
336 mtmp->data == &mons[urole.femalenum]) ?
337 same_class_msg[rn2(3)] : other_class_msg[rn2(3)]);