Source:SLASH'EM 0.0.7E7F2/mplayer.c

Below is the full text to mplayer.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mplayer.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

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. */ 4.     5.    #include "hack.h"  6. 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)); 10.   11.   /* These are the names of those who 12.   * contributed to the development of NetHack 3.2/3.3/3.4. 13.   *  14.    * Keep in alphabetical order within teams. 15.   * Same first name is entered once within each team. 16.   */  17.   static const char *developers[] = { 18.  	/* devteam */ 19.  	"Dave", "Dean", "Eric", "Izchak", "Janet", "Jessie", 20.  	"Ken", "Kevin", "Michael", "Mike", "Pat", "Paul", "Steve", "Timo", 21.  	"Warwick", 22.  	/* PC team */ 23.  	"Bill", "Eric", "Keizo", "Ken", "Kevin", "Michael", "Mike", "Paul", 24.  	"Stephen", "Steve", "Timo", "Yitzhak", 25.  	/* Amiga team */ 26.  	"Andy", "Gregg", "Janne", "Keni", "Mike", "Olaf", "Richard", 27.  	/* Mac team */ 28.  	"Andy", "Chris", "Dean", "Jon", "Jonathan", "Kevin", "Wang", 29.  	/* Atari team */ 30.  	"Eric", "Marvin", "Warwick", 31.  	/* NT team */ 32.  	"Alex", "Dion", "Michael", 33.  	/* OS/2 team */ 34.  	"Helge", "Ron", "Timo", 35.  	/* VMS team */ 36.  	"Joshua", "Pat", 37.  	""};  38.    39.    40.   /* return a randomly chosen developer name */ 41.  STATIC_OVL const char * 42.  dev_name 43.  {  44.   	register int i, m = 0, n = SIZE(developers); 45.  	register struct monst *mtmp; 46.  	register boolean match; 47.   48.   	do { 49.  	    match = FALSE; 50.  	    i = rn2(n); 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]))) { 55.  		    match = TRUE; 56.  		    break; 57.  	        }  58.   	    }  59.   	    m++; 60.  	} while (match && m < 100); /* m for insurance */ 61.   62.   	if (match) return (const char *)0; 63.  	return(developers[i]); 64.  }  65.    66.   STATIC_OVL void 67.  get_mplname(mtmp, nam) 68.  register struct monst *mtmp; 69.  char *nam; 70.  {  71.   	boolean fmlkind = is_female(mtmp->data); 72.  	const char *devnam; 73.   74.   	devnam = dev_name; 75.  	if (!devnam) 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); 80.   81.   	if (fmlkind || !strcmp(nam, "Janet")) 82.  	    mtmp->female = 1; 83.  	else 84.  	    mtmp->female = 0; 85.  	Strcat(nam, " the "); 86.  	Strcat(nam, rank_of((int)mtmp->m_lev, 87.  			    monsndx(mtmp->data), 88.  			    (boolean)mtmp->female)); 89.  }  90.    91.   STATIC_OVL void 92.  mk_mplayer_armor(mon, typ) 93.  struct monst *mon; 94.  short typ; 95.  {  96.   	struct obj *obj; 97.   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....  106. */ 107.  	obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4,4)) : -rnd(3); 108. 	(void) mpickobj(mon, obj); 109. }  110.   111.  struct monst * 112. mk_mplayer(ptr, x, y, special) 113. register struct permonst *ptr; 114. xchar x, y;  115. register boolean special; 116. {  117.  	register struct monst *mtmp; 118. 	char nam[PL_NSIZ]; 119.  120.  	if(!is_mplayer(ptr)) 121. 		return((struct monst *)0); 122.  123.  	if(MON_AT(x, y)) 124. 		(void) rloc(m_at(x, y), FALSE); /* insurance */ 125.  126.  	if(!In_endgame(&u.uz)) special = FALSE; 127.  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); 137. 	    int quan; 138. 	    struct obj *otmp; 139.  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); 143. 	    if(special) { 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);  148.  	    }  149.  	    mtmp->mpeaceful = 0;  150.  	    set_malign(mtmp); /* peaceful may have changed again */  151.   152.  	    switch(monsndx(ptr)) {  153.  		case PM_ARCHEOLOGIST:  154.  		    if (rn2(2)) weapon = BULLWHIP;  155.  		    break;  156.  		case PM_BARBARIAN:  157.  		    if (rn2(2)) {  158.  		    	weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;  159.  		    	shield = STRANGE_OBJECT;  160.  		    }  161.  		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);  162.  		    if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT;  163.  		    break;  164.  		case PM_CAVEMAN:  165.  		case PM_CAVEWOMAN:  166.  		    if (rn2(4)) weapon = MACE;  167.  		    else if (rn2(2)) weapon = CLUB;  168.  		    if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT; 169. 		    break; 170. 		case PM_HEALER: 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; 175. 		    break; 176. #ifdef YEOMAN 177. 		case PM_YEOMAN: 178. #endif 179. 		case PM_KNIGHT: 180. 		    if (rn2(4)) weapon = LONG_SWORD; 181. 		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL); 182. 		    break; 183. 		case PM_MONK: 184. 		    weapon = STRANGE_OBJECT; 185. 		    armor = STRANGE_OBJECT; 186. 		    cloak = ROBE; 187. 		    if (rn2(2)) shield = STRANGE_OBJECT; 188. 		    break; 189. 		case PM_PRIEST: 190. 		case PM_PRIESTESS: 191. 		    if (rn2(2)) weapon = MACE; 192. 		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL); 193. 		    if (rn2(4)) cloak = ROBE; 194. 		    if (rn2(4)) helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY; 195. 		    if (rn2(2)) shield = STRANGE_OBJECT; 196. 		    break; 197. 		case PM_RANGER: 198. 		    if (rn2(2)) weapon = ELVEN_DAGGER; 199. 		    break; 200. 		case PM_ROGUE: 201. 		    weapon = SHORT_SWORD; 202. 		    armor = LEATHER_ARMOR; 203. 		    break; 204. 		case PM_SAMURAI: 205. 		    if (rn2(2)) weapon = KATANA; 206. 		    break; 207. #ifdef TOURIST 208. 		case PM_TOURIST: 209. 		    /* Defaults are just fine */ 210. 		    break; 211. #endif 212. 		case PM_UNDEAD_SLAYER: 213. 		    if (rn2(2)) weapon = SILVER_SPEAR; 214. 		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL); 215. 		    break; 216. 		case PM_VALKYRIE: 217. 		    if (rn2(2)) weapon = WAR_HAMMER; 218. 		    if (rn2(2)) armor = rnd_class(PLATE_MAIL, CHAIN_MAIL); 219. 		    break; 220. 		case PM_FLAME_MAGE: 221. 		case PM_ICE_MAGE: 222. 		case PM_NECROMANCER: 223. 		case PM_WIZARD: 224. 		    if (rn2(4)) weapon = rn2(2) ? QUARTERSTAFF : ATHAME; 225. 		    if (rn2(2)) { 226. 		    	armor = rn2(2) ? BLACK_DRAGON_SCALE_MAIL : 227. 		    			SILVER_DRAGON_SCALE_MAIL; 228. 		    	cloak = CLOAK_OF_MAGIC_RESISTANCE; 229. 		    }  230.  		    if (rn2(4)) helm = HELM_OF_BRILLIANCE; 231. 		    shield = STRANGE_OBJECT; 232. 		    break; 233. 		default: impossible("bad mplayer monster"); 234. 		    weapon = 0; 235. 		    break; 236. 	    }  237.   238.  	    if (weapon != STRANGE_OBJECT) { 239. 		otmp = mksobj(weapon, TRUE, FALSE); 240. 		otmp->spe = (special ? rn1(5,4) : rn2(4)); 241. 		if (!rn2(3)) otmp->oerodeproof = 1; 242. 		else if (!rn2(2)) otmp->greased = 1; 243. 		if (special && rn2(2)) 244. 		    otmp = mk_artifact(otmp, A_NONE); 245. 		/* mplayers knew better than to overenchant Magicbane */ 246. 		if (otmp->oartifact == ART_MAGICBANE) 247. 		    otmp->spe = rnd(4); 248. 		(void) mpickobj(mtmp, otmp); 249. 	    }  250.   251.  	    if(special) { 252. 		if (!rn2(10)) 253. 		    (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE); 254. 		mk_mplayer_armor(mtmp, armor); 255. 		mk_mplayer_armor(mtmp, cloak); 256. 		mk_mplayer_armor(mtmp, helm); 257. 		mk_mplayer_armor(mtmp, shield); 258. 		if (rn2(8)) 259. 		    mk_mplayer_armor(mtmp, rnd_class(LEATHER_GLOVES, 260. 					       GAUNTLETS_OF_DEXTERITY)); 261. 		if (rn2(8)) 262. 		    mk_mplayer_armor(mtmp, rnd_class(LOW_BOOTS, LEVITATION_BOOTS)); 263. 		m_dowear(mtmp, TRUE); 264.  265.  		quan = rn2(3) ? rn2(3) : rn2(16); 266. 		while(quan--) 267. 		    (void)mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE)); 268. 		/* To get the gold "right" would mean a player can double his */ 269. 		/* gold supply by killing one mplayer. Not good. */ 270.  #ifndef GOLDOBJ 271. 		mtmp->mgold = rn2(1000); 272. #else 273. 		mkmonmoney(mtmp, rn2(1000)); 274. #endif 275. 		quan = rn2(10); 276. 		while(quan--) 277. 		    (void) mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE)); 278. 	    } else { /* wandering characters... */ 279.  #ifndef GOLDOBJ 280. 	       mtmp->mgold = rn2((mtmp->m_lev)*100); 281. #else 282. 	       mkmonmoney(mtmp, rn2((mtmp->m_lev)*100)); 283. #endif 284. 	    }  285.  	    quan = rnd(3); 286. 	    while(quan--) 287. 		(void)mongets(mtmp, rnd_offensive_item(mtmp)); 288. 	    quan = rnd(3); 289. 	    while(quan--) 290. 		(void)mongets(mtmp, rnd_defensive_item(mtmp)); 291. 	    quan = rnd(3); 292. 	    while(quan--) 293. 		(void)mongets(mtmp, rnd_misc_item(mtmp)); 294. 	}  295.   296.  	return(mtmp); 297. }  298.   299.  /* create the indicated number (num) of monster-players, 300.  * randomly chosen, and in randomly chosen (free) locations 301.  * on the level. If "special", the size of num should not 302.  * be bigger than the number of _non-repeated_ names in the 303.  * developers array, otherwise a bunch of Adams and Eves will 304.  * fill up the overflow. 305.  */  306.  void 307. create_mplayers(num, special) 308. register int num; 309. boolean special; 310. {  311.  	int pm, x, y;  312. struct monst fakemon; 313.  314.  	while(num) { 315. 		int tryct = 0; 316.  317.  		/* roll for character class */ 318. 		pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1); 319. 		fakemon.data = &mons[pm]; 320.  321.  		/* roll for an available location */ 322. 		do { 323. 		    x = rn1(COLNO-4, 2); 324. 		    y = rnd(ROWNO-2); 325. 		} while(!goodpos(x, y, &fakemon, 0) && tryct++ <= 50); 326.  327.  		/* if pos not found in 50 tries, don't bother to continue */ 328. 		if(tryct > 50) return; 329.  330.  		(void) mk_mplayer(&mons[pm], (xchar)x, (xchar)y, special); 331. 		num--; 332. 	}  333.  }  334.   335.  void 336. mplayer_talk(mtmp) 337. register struct monst *mtmp; 338. {  339.  	static const char *same_class_msg[3] = { 340. 		"I can't win, and neither will you!", 341. 		"You don't deserve to win!", 342. 		"Mine should be the honor, not yours!", 343. 	},		  *other_class_msg[3] = { 344. 		"The low-life wants to talk, eh?", 345. 		"Fight, scum!", 346. 		"Here is what I have to say!", 347. 	};  348.   349.  	if(mtmp->mpeaceful) return; /* will drop to humanoid talk */ 350.  351.  	pline("Talk? -- %s",  352.  		(mtmp->data == &mons[urole.malenum] || 353. 		mtmp->data == &mons[urole.femalenum]) ?  354.  		same_class_msg[rn2(3)] : other_class_msg[rn2(3)]); 355. }  356.   357.  /*mplayer.c*/