FANDOM


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

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


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)priest.c	3.4	2002/11/06	*/
2.    /* Copyright (c) Izchak Miller, Steve Linhart, 1989.		  */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    #include "mfndpos.h"
7.    #include "eshk.h"
8.    #include "epri.h"
9.    #include "emin.h"
10.   
11.   /* this matches the categorizations shown by enlightenment */
12.   #define ALGN_SINNED	(-4)	/* worse than strayed */
13.   
14.   #ifdef OVLB
15.   
16.   STATIC_DCL boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
17.   STATIC_DCL boolean FDECL(has_shrine,(struct monst *));
18.   
19.   /*
20.    * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
21.    * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
22.    */
23.   int
24.   move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
25.   register struct monst *mtmp;
26.   boolean in_his_shop;
27.   schar appr;
28.   boolean uondoor,avoid;
29.   register xchar omx,omy,gx,gy;
30.   {
31.   	register xchar nx,ny,nix,niy;
32.   	register schar i;
33.   	schar chcnt,cnt;
34.   	coord poss[9];
35.   	long info[9];
36.   	long allowflags;
37.   	struct obj *ib = (struct obj *)0;
38.   
39.   	if(omx == gx && omy == gy)
40.   		return(0);
41.   	if(mtmp->mconf) {
42.   		avoid = FALSE;
43.   		appr = 0;
44.   	}
45.   
46.   	nix = omx;
47.   	niy = omy;
48.   	if (mtmp->isshk) allowflags = ALLOW_SSM;
49.   	else allowflags = ALLOW_SSM | ALLOW_SANCT;
50.   	if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
51.   	if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
52.   	if (tunnels(mtmp->data)) allowflags |= ALLOW_DIG;
53.   	if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
54.   		allowflags |= OPENDOOR;
55.   		if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
56.   	}
57.   	if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
58.   	cnt = mfndpos(mtmp, poss, info, allowflags);
59.   
60.   	if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
61.   		for(i=0; i<cnt; i++)
62.   		    if(!(info[i] & NOTONL)) goto pick_move;
63.   		avoid = FALSE;
64.   	}
65.   
66.   #define GDIST(x,y)	(dist2(x,y,gx,gy))
67.   pick_move:
68.   	chcnt = 0;
69.   	for(i=0; i<cnt; i++) {
70.   		nx = poss[i].x;
71.   		ny = poss[i].y;
72.   		if(levl[nx][ny].typ == ROOM ||
73.   			(mtmp->ispriest &&
74.   			    levl[nx][ny].typ == ALTAR) ||
75.   			(mtmp->isshk &&
76.   			    (!in_his_shop || ESHK(mtmp)->following))) {
77.   		    if(avoid && (info[i] & NOTONL))
78.   			continue;
79.   		    if((!appr && !rn2(++chcnt)) ||
80.   			(appr && GDIST(nx,ny) < GDIST(nix,niy))) {
81.   			    nix = nx;
82.   			    niy = ny;
83.   		    }
84.   		}
85.   	}
86.   	if(mtmp->ispriest && avoid &&
87.   			nix == omx && niy == omy && onlineu(omx,omy)) {
88.   		/* might as well move closer as long it's going to stay
89.   		 * lined up */
90.   		avoid = FALSE;
91.   		goto pick_move;
92.   	}
93.   
94.   	if(nix != omx || niy != omy) {
95.   		remove_monster(omx, omy);
96.   		place_monster(mtmp, nix, niy);
97.   		newsym(nix,niy);
98.   		if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
99.   		    check_special_room(FALSE);
100.  		if(ib) {
101.  			if (cansee(mtmp->mx,mtmp->my))
102.  			    pline("%s picks up %s.", Monnam(mtmp),
103.  				distant_name(ib,doname));
104.  			obj_extract_self(ib);
105.  			(void) mpickobj(mtmp, ib);
106.  		}
107.  		return(1);
108.  	}
109.  	return(0);
110.  }
111.  
112.  #endif /* OVLB */
113.  
114.  #ifdef OVL0
115.  
116.  char
117.  temple_occupied(array)
118.  register char *array;
119.  {
120.  	register char *ptr;
121.  
122.  	for (ptr = array; *ptr; ptr++)
123.  		if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
124.  			return(*ptr);
125.  	return('\0');
126.  }
127.  
128.  #endif /* OVL0 */
129.  #ifdef OVLB
130.  
131.  STATIC_OVL boolean
132.  histemple_at(priest, x, y)
133.  register struct monst *priest;
134.  register xchar x, y;
135.  {
136.  	return((boolean)((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) &&
137.  	       on_level(&(EPRI(priest)->shrlevel), &u.uz)));
138.  }
139.  
140.  /*
141.   * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
142.   */
143.  int
144.  pri_move(priest)
145.  register struct monst *priest;
146.  {
147.  	register xchar gx,gy,omx,omy;
148.  	schar temple;
149.  	boolean avoid = TRUE;
150.  
151.  	omx = priest->mx;
152.  	omy = priest->my;
153.  
154.  	if(!histemple_at(priest, omx, omy)) return(-1);
155.  
156.  	temple = EPRI(priest)->shroom;
157.  
158.  	gx = EPRI(priest)->shrpos.x;
159.  	gy = EPRI(priest)->shrpos.y;
160.  
161.  	gx += rn1(3,-1);	/* mill around the altar */
162.  	gy += rn1(3,-1);
163.  
164.  	if(!priest->mpeaceful ||
165.  	   (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
166.  		if(monnear(priest, u.ux, u.uy)) {
167.  			if(Displaced)
168.  				Your("displaced image doesn't fool %s!",
169.  					mon_nam(priest));
170.  			(void) mattacku(priest);
171.  			return(0);
172.  		} else if(index(u.urooms, temple)) {
173.  			/* chase player if inside temple & can see him */
174.  			if(priest->mcansee && m_canseeu(priest)) {
175.  				gx = u.ux;
176.  				gy = u.uy;
177.  			}
178.  			avoid = FALSE;
179.  		}
180.  	} else if(Invis) avoid = FALSE;
181.  
182.  	return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy));
183.  }
184.  
185.  /* exclusively for mktemple() */
186.  void
187.  priestini(lvl, sroom, sx, sy, sanctum)
188.  d_level	*lvl;
189.  struct mkroom *sroom;
190.  int sx, sy;
191.  boolean sanctum;   /* is it the seat of the high priest? */
192.  {
193.  	struct monst *priest;
194.  	struct obj *otmp = NULL;
195.  	int cnt;
196.  
197.  	if(MON_AT(sx+1, sy))
198.  		(void) rloc(m_at(sx+1, sy), FALSE); /* insurance */
199.  
200.  	priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
201.  			 sx + 1, sy, NO_MM_FLAGS);
202.  	if (priest) {
203.  		EPRI(priest)->shroom = (sroom - rooms) + ROOMOFFSET;
204.  		EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
205.  		EPRI(priest)->shrpos.x = sx;
206.  		EPRI(priest)->shrpos.y = sy;
207.  		assign_level(&(EPRI(priest)->shrlevel), lvl);
208.  		priest->mtrapseen = ~0;	/* traps are known */
209.  		priest->mpeaceful = 1;
210.  		priest->ispriest = 1;
211.  		priest->msleeping = 0;
212.  		set_malign(priest); /* mpeaceful may have changed */
213.  
214.  		/* now his/her goodies... */
215.  		if(sanctum && EPRI(priest)->shralign == A_NONE &&
216.  		     on_level(&sanctum_level, &u.uz)) {
217.  			(void) mongets(priest, AMULET_OF_YENDOR);
218.  		}
219.  		/* 2 to 4 spellbooks */
220.  		for (cnt = rn1(3,2); cnt > 0; --cnt) {
221.  		    (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE));
222.  		}
223.  		/* [ALI] Upgrade existing robe or aquire new */
224.  		if (rn2(2) || (otmp = which_armor(priest, W_ARM)) == 0) {
225.  		    struct obj *obj;
226.  		    obj = mksobj(rn2(p_coaligned(priest) ? 2 : 5) ?
227.  			    ROBE_OF_PROTECTION : ROBE_OF_POWER, TRUE, FALSE);
228.  		    if (p_coaligned(priest))
229.  			uncurse(obj);
230.  		    else
231.  			curse(obj);
232.  		    (void) mpickobj(priest, obj);
233.  		    m_dowear(priest, TRUE);
234.  		    if (!(obj->owornmask & W_ARM)) {
235.  			obj_extract_self(obj);
236.  			obfree(obj, (struct obj *)0);
237.  		    } else if (otmp) {
238.  			obj_extract_self(otmp);
239.  			obfree(otmp, (struct obj *)0);
240.  		    }
241.  		}
242.  	}
243.  }
244.  
245.  /*
246.   * Specially aligned monsters are named specially.
247.   *	- aligned priests with ispriest and high priests have shrines
248.   *		they retain ispriest and epri when polymorphed
249.   *	- aligned priests without ispriest and Angels are roamers
250.   *		they retain isminion and access epri as emin when polymorphed
251.   *		(coaligned Angels are also created as minions, but they
252.   *		use the same naming convention)
253.   *	- minions do not have ispriest but have isminion and emin
254.   *	- caller needs to inhibit Hallucination if it wants to force
255.   *		the true name even when under that influence
256.   */
257.  char *
258.  priestname(mon, pname)
259.  register struct monst *mon;
260.  char *pname;		/* caller-supplied output buffer */
261.  {
262.  	const char *what = Hallucination ? rndmonnam() : mon->data->mname;
263.  
264.  	Strcpy(pname, "the ");
265.  	if (mon->minvis) Strcat(pname, "invisible ");
266.  	if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] ||
267.  					mon->data == &mons[PM_ANGEL]) {
268.  		/* use epri */
269.  		if (mon->mtame && mon->data == &mons[PM_ANGEL])
270.  			Strcat(pname, "guardian ");
271.  		if (mon->data != &mons[PM_ALIGNED_PRIEST] &&
272.  				mon->data != &mons[PM_HIGH_PRIEST]) {
273.  			Strcat(pname, what);
274.  			Strcat(pname, " ");
275.  		}
276.  		if (mon->data != &mons[PM_ANGEL]) {
277.  			if (!mon->ispriest && EPRI(mon)->renegade)
278.  				Strcat(pname, "renegade ");
279.  			if (mon->data == &mons[PM_HIGH_PRIEST])
280.  				Strcat(pname, "high ");
281.  			if (Hallucination)
282.  				Strcat(pname, "poohbah ");
283.  			else if (mon->female)
284.  				Strcat(pname, "priestess ");
285.  			else
286.  				Strcat(pname, "priest ");
287.  		}
288.  		Strcat(pname, "of ");
289.  		Strcat(pname, halu_gname((int)EPRI(mon)->shralign));
290.  		return(pname);
291.  	}
292.  	/* use emin instead of epri */
293.  	Strcat(pname, what);
294.  	Strcat(pname, " of ");
295.  	Strcat(pname, halu_gname(EMIN(mon)->min_align));
296.  	return(pname);
297.  }
298.  
299.  boolean
300.  p_coaligned(priest)
301.  struct monst *priest;
302.  {
303.  	return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign)));
304.  }
305.  
306.  STATIC_OVL boolean
307.  has_shrine(pri)
308.  struct monst *pri;
309.  {
310.  	struct rm *lev;
311.  
312.  	if(!pri)
313.  		return(FALSE);
314.  	lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
315.  	if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
316.  		return(FALSE);
317.  	return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
318.  }
319.  
320.  struct monst *
321.  findpriest(roomno)
322.  char roomno;
323.  {
324.  	register struct monst *mtmp;
325.  
326.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
327.  	    if (DEADMONSTER(mtmp)) continue;
328.  	    if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
329.  	       histemple_at(mtmp,mtmp->mx,mtmp->my))
330.  		return(mtmp);
331.  	}
332.  	return (struct monst *)0;
333.  }
334.  
335.  /* called from check_special_room() when the player enters the temple room */
336.  void
337.  intemple(roomno)
338.  register int roomno;
339.  {
340.  	register struct monst *priest = findpriest((char)roomno);
341.  	boolean tended = (priest != (struct monst *)0);
342.  	boolean shrined, sanctum, can_speak;
343.  	const char *msg1, *msg2;
344.  	char buf[BUFSZ];
345.  
346.  	if(!temple_occupied(u.urooms0)) {
347.  	    if(tended) {
348.  		shrined = has_shrine(priest);
349.  		sanctum = (priest->data == &mons[PM_HIGH_PRIEST] &&
350.  			   (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
351.  		can_speak = (priest->mcanmove && !priest->msleeping &&
352.  			     flags.soundok);
353.  		if (can_speak) {
354.  		    unsigned save_priest = priest->ispriest;
355.  		    /* don't reveal the altar's owner upon temple entry in
356.  		       the endgame; for the Sanctum, the next message names
357.  		       Moloch so suppress the "of Moloch" for him here too */
358.  		    if (sanctum && !Hallucination) priest->ispriest = 0;
359.  		    pline("%s intones:",
360.  			canseemon(priest) ? Monnam(priest) : "A nearby voice");
361.  		    priest->ispriest = save_priest;
362.  		}
363.  		msg2 = 0;
364.  		if(sanctum && Is_sanctum(&u.uz)) {
365.  		    if(priest->mpeaceful) {
366.  			msg1 = "Infidel, you have entered Moloch's Sanctum!";
367.  			msg2 = "Be gone!";
368.  			priest->mpeaceful = 0;
369.  			set_malign(priest);
370.  		    } else
371.  			msg1 = "You desecrate this place by your presence!";
372.  		} else {
373.  		    Sprintf(buf, "Pilgrim, you enter a %s place!",
374.  			    !shrined ? "desecrated" : "sacred");
375.  		    msg1 = buf;
376.  		}
377.  		if (can_speak) {
378.  		    verbalize(msg1);
379.  		    if (msg2) verbalize(msg2);
380.  		}
381.  		if(!sanctum) {
382.  		    /* !tended -> !shrined */
383.  		    if (!shrined || !p_coaligned(priest) ||
384.  			    u.ualign.record <= ALGN_SINNED)
385.  			You("have a%s forbidding feeling...",
386.  				(!shrined) ? "" : " strange");
387.  		    else You("experience a strange sense of peace.");
388.  		}
389.  	    } else {
390.  		switch(rn2(3)) {
391.  		  case 0: You("have an eerie feeling..."); break;
392.  		  case 1: You_feel("like you are being watched."); break;
393.  		  default: pline("A shiver runs down your %s.",
394.  			body_part(SPINE)); break;
395.  		}
396.  		if(!rn2(5)) {
397.  		    struct monst *mtmp;
398.  
399.  		    if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy,NO_MM_FLAGS)))
400.  			return;
401.  		    if (!Blind || sensemon(mtmp))
402.  			pline("An enormous ghost appears next to you!");
403.  		    else You("sense a presence close by!");
404.  		    mtmp->mpeaceful = 0;
405.  		    set_malign(mtmp);
406.  		    if(flags.verbose)
407.  			You("are frightened to death, and unable to move.");
408.  		    nomul(-3);
409.  		    nomovemsg = "You regain your composure.";
410.  	       }
411.  	   }
412.         }
413.  }
414.  
415.  void
416.  priest_talk(priest)
417.  register struct monst *priest;
418.  {
419.  	boolean coaligned = p_coaligned(priest);
420.  	boolean strayed = (u.ualign.record < 0);
421.  
422.  	/* KMH, conduct */
423.  	u.uconduct.gnostic++;
424.  
425.  	if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
426.  	    pline("%s doesn't want anything to do with you!",
427.  				Monnam(priest));
428.  	    priest->mpeaceful = 0;
429.  	    return;
430.  	}
431.  
432.  	/* priests don't chat unless peaceful and in their own temple */
433.  	if(!histemple_at(priest,priest->mx,priest->my) ||
434.  		 !priest->mpeaceful || !priest->mcanmove || priest->msleeping) {
435.  	    static const char *cranky_msg[3] = {
436.  		"Thou wouldst have words, eh?  I'll give thee a word or two!",
437.  		"Talk?  Here is what I have to say!",
438.  		"Pilgrim, I would speak no longer with thee."
439.  	    };
440.  
441.  	    if(!priest->mcanmove || priest->msleeping) {
442.  		pline("%s breaks out of %s reverie!",
443.  		      Monnam(priest), mhis(priest));
444.  		priest->mfrozen = priest->msleeping = 0;
445.  		priest->mcanmove = 1;
446.  	    }
447.  	    priest->mpeaceful = 0;
448.  	    verbalize(cranky_msg[rn2(3)]);
449.  	    return;
450.  	}
451.  
452.  	/* you desecrated the temple and now you want to chat? */
453.  	if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) &&
454.  		  !has_shrine(priest)) {
455.  	    verbalize("Begone!  Thou desecratest this holy place with thy presence.");
456.  	    priest->mpeaceful = 0;
457.  	    return;
458.  	}
459.  #ifndef GOLDOBJ
460.  	if(!u.ugold) {
461.  	    if(coaligned && !strayed) {
462.  		if (priest->mgold > 0L) {
463.  		    /* Note: two bits is actually 25 cents.  Hmm. */
464.  		    pline("%s gives you %s for an ale.", Monnam(priest),
465.  			(priest->mgold == 1L) ? "one bit" : "two bits");
466.  		    if (priest->mgold > 1L)
467.  			u.ugold = 2L;
468.  		    else
469.  			u.ugold = 1L;
470.  		    priest->mgold -= u.ugold;
471.  		    flags.botl = 1;
472.  #else
473.  	if(!money_cnt(invent)) {
474.  	    if(coaligned && !strayed) {
475.                  long pmoney = money_cnt(priest->minvent);
476.  		if (pmoney > 0L) {
477.  		    /* Note: two bits is actually 25 cents.  Hmm. */
478.  		    pline("%s gives you %s for an ale.", Monnam(priest),
479.  			(pmoney == 1L) ? "one bit" : "two bits");
480.  		     money2u(priest, pmoney > 1L ? 2 : 1);
481.  #endif
482.  		} else
483.  		    pline("%s preaches the virtues of poverty.", Monnam(priest));
484.  		exercise(A_WIS, TRUE);
485.  	    } else
486.  		pline("%s is not interested.", Monnam(priest));
487.  	    return;
488.  	} else {
489.  	    long offer;
490.  
491.  	    pline("%s asks you for a contribution for the temple.",
492.  			Monnam(priest));
493.  	    if((offer = bribe(priest)) == 0) {
494.  		verbalize("Thou shalt regret thine action!");
495.  		if(coaligned) adjalign(-1);
496.  	    } else if(offer < (u.ulevel * 200)) {
497.  #ifndef GOLDOBJ
498.  		if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
499.  #else
500.  		if(money_cnt(invent) > (offer * 2L)) verbalize("Cheapskate.");
501.  #endif
502.  		else {
503.  		    verbalize("I thank thee for thy contribution.");
504.  		    /*  give player some token  */
505.  		    exercise(A_WIS, TRUE);
506.  		}
507.  	    } else if(offer < (u.ulevel * 400)) {
508.  		verbalize("Thou art indeed a pious individual.");
509.  #ifndef GOLDOBJ
510.  		if(u.ugold < (offer * 2L)) {
511.  #else
512.  		if(money_cnt(invent) < (offer * 2L)) {
513.  #endif
514.  		    if (coaligned && u.ualign.record <= ALGN_SINNED)
515.  			adjalign(1);
516.  		    verbalize("I bestow upon thee a blessing.");
517.  		    /* KMH, intrinsic patch */
518.  		    incr_itimeout(&HClairvoyant, rn1(500,500));
519.  		}
520.  	    } else if(offer < (u.ulevel * 600) &&
521.  		      u.ublessed < 20 &&
522.  		      (u.ublessed < 9 || !rn2(u.ublessed))) {
523.  		verbalize("Thy devotion has been rewarded.");
524.  		if (!(HProtection & INTRINSIC))  {
525.  			HProtection |= FROMOUTSIDE;
526.  			if (!u.ublessed)  u.ublessed = rn1(3, 2);
527.  		} else u.ublessed++;
528.  	    } else {
529.  		verbalize("Thy selfless generosity is deeply appreciated.");
530.  #ifndef GOLDOBJ
531.  		if(u.ugold < (offer * 2L) && coaligned) {
532.  #else
533.  		if(money_cnt(invent) < (offer * 2L) && coaligned) {
534.  #endif
535.  		    if(strayed && (moves - u.ucleansed) > 5000L) {
536.  			u.ualign.record = 0; /* cleanse thee */
537.  			u.ucleansed = moves;
538.  		    } else {
539.  			adjalign(2);
540.  		    }
541.  		}
542.  	    }
543.  	}
544.  }
545.  
546.  struct monst *
547.  mk_roamer(ptr, alignment, x, y, peaceful)
548.  register struct permonst *ptr;
549.  aligntyp alignment;
550.  xchar x, y;
551.  boolean peaceful;
552.  {
553.  	register struct monst *roamer;
554.  	register boolean coaligned = (u.ualign.type == alignment);
555.  
556.  	if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
557.  		return((struct monst *)0);
558.  	
559.  	if (MON_AT(x, y)) (void) rloc(m_at(x, y), FALSE);	/* insurance */
560.  
561.  	if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS)))
562.  		return((struct monst *)0);
563.  
564.  	EPRI(roamer)->shralign = alignment;
565.  	if (coaligned && !peaceful)
566.  		EPRI(roamer)->renegade = TRUE;
567.  	/* roamer->ispriest == FALSE naturally */
568.  	roamer->isminion = TRUE;	/* borrowing this bit */
569.  	roamer->mtrapseen = ~0;		/* traps are known */
570.  	roamer->mpeaceful = peaceful;
571.  	roamer->msleeping = 0;
572.  	set_malign(roamer); /* peaceful may have changed */
573.  
574.  	/* MORE TO COME */
575.  	return(roamer);
576.  }
577.  
578.  void
579.  reset_hostility(roamer)
580.  register struct monst *roamer;
581.  {
582.  	if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] ||
583.  				  roamer->data == &mons[PM_ANGEL])))
584.  	        return;
585.  
586.  	if(EPRI(roamer)->shralign != u.ualign.type) {
587.  	    roamer->mpeaceful = roamer->mtame = 0;
588.  	    set_malign(roamer);
589.  	}
590.  	newsym(roamer->mx, roamer->my);
591.  }
592.  
593.  boolean
594.  in_your_sanctuary(mon, x, y)
595.  struct monst *mon;	/* if non-null, <mx,my> overrides <x,y> */
596.  xchar x, y;
597.  {
598.  	register char roomno;
599.  	register struct monst *priest;
600.  
601.  	if (mon) {
602.  	    if (is_minion(mon->data) || is_rider(mon->data)) return FALSE;
603.  	    x = mon->mx, y = mon->my;
604.  	}
605.  	if (u.ualign.record <= ALGN_SINNED)	/* sinned or worse */
606.  	    return FALSE;
607.  	if ((roomno = temple_occupied(u.urooms)) == 0 ||
608.  		roomno != *in_rooms(x, y, TEMPLE))
609.  	    return FALSE;
610.  	if ((priest = findpriest(roomno)) == 0)
611.  	    return FALSE;
612.  	return (boolean)(has_shrine(priest) &&
613.  			 p_coaligned(priest) &&
614.  			 priest->mpeaceful);
615.  }
616.  
617.  void
618.  ghod_hitsu(priest)	/* when attacking "priest" in his temple */
619.  struct monst *priest;
620.  {
621.  	int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
622.  	int x1, y1, x2, y2, n;
623.  	coord poss[4];
624.  	int stpx = sgn(u.ux - priest->mx), stpy = sgn(u.uy - priest->my);
625.  		/* gods avoid hitting the temple priest */
626.  	struct mkroom *troom;
627.  
628.  	if (!roomno || !has_shrine(priest))
629.  		return;
630.  
631.  	ax = x = EPRI(priest)->shrpos.x;
632.  	ay = y = EPRI(priest)->shrpos.y;
633.  	troom = &rooms[roomno - ROOMOFFSET];
634.  
635.  	/*
636.  	 * Determine the source of the lightning bolt according to the
637.  	 * following rules:
638.  	 *	1. The source cannot be directly under the player
639.  	 *	2. Don't zap through the temple priest
640.  	 *	3. First choice of source is the altar itself
641.  	 *	4. Otherwise use a wall, prefering orthogonal to diagonal paths
642.  	 *	5. Choose randomly from equally preferred sources
643.  	 * Note that if the hero is not standing on either the altar or
644.  	 * a door then (u.ux, u.uy) may be counted as a possible source which
645.  	 * is later rejected by linedup() letting the hero off the hook.
646.  	 */
647.  	if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y) ||
648.  		stpx == sgn(tbx) && stpy == sgn(tby)) {
649.  	    if(IS_DOOR(levl[u.ux][u.uy].typ)) {
650.  
651.  		if(u.ux == troom->lx - 1) {
652.  		    if (stpx != sgn(u.ux - troom->hx) || stpy != 0) {
653.  			x = troom->hx;
654.  			y = u.uy;
655.  		    } else {
656.  			/* Diagonal required */
657.  			x1 = u.ux + u.uy - troom->ly;
658.  			y1 = troom->ly;
659.  			x2 = u.ux + troom->hy - u.uy;
660.  			y2 = troom->hy;
661.  			if (x1 > troom->hx && x2 > troom->hx)
662.  			    return;
663.  			else if (x2 > troom->hx || x1 <= troom->hx && !rn2(2)) {
664.  			    x = x1;
665.  			    y = y1;
666.  			} else {
667.  			    x = x2;
668.  			    y = y2;
669.  			}
670.  		    }
671.  		} else if(u.ux == troom->hx + 1) {
672.  		    if (stpx != sgn(u.ux - troom->lx) || stpy != 0) {
673.  			x = troom->lx;
674.  			y = u.uy;
675.  		    } else {
676.  			/* Diagonal required */
677.  			x1 = u.ux - (u.uy - troom->ly);
678.  			y1 = troom->ly;
679.  			x2 = u.ux - (troom->hy - u.uy);
680.  			y2 = troom->hy;
681.  			if (x1 < troom->lx && x2 < troom->lx)
682.  			    return;
683.  			else if (x2 < troom->lx || x1 >= troom->lx && !rn2(2)) {
684.  			    x = x1;
685.  			    y = y1;
686.  			} else {
687.  			    x = x2;
688.  			    y = y2;
689.  			}
690.  		    }
691.  		} else if(u.uy == troom->ly - 1) {
692.  		    if (stpx != 0 || stpy != sgn(u.uy - troom->hy)) {
693.  			x = u.ux;
694.  			y = troom->hy;
695.  		    } else {
696.  			/* Diagonal required */
697.  			x1 = troom->lx;
698.  			y1 = u.uy + u.ux - troom->lx;
699.  			x2 = troom->hx;
700.  			y2 = u.uy + troom->hx - u.ux;
701.  			if (y1 > troom->hy && y2 > troom->hy)
702.  			    return;
703.  			else if (y2 > troom->hy || y1 <= troom->hy && !rn2(2)) {
704.  			    x = x1;
705.  			    y = y1;
706.  			} else {
707.  			    x = x2;
708.  			    y = y2;
709.  			}
710.  		    }
711.  		} else if(u.uy == troom->hy + 1) {
712.  		    if (stpx != 0 || stpy != sgn(u.uy - troom->ly)) {
713.  			x = u.ux;
714.  			y = troom->ly;
715.  		    } else {
716.  			/* Diagonal required */
717.  			x1 = troom->lx;
718.  			y1 = u.uy - (u.ux - troom->lx);
719.  			x2 = troom->hx;
720.  			y2 = u.uy - (troom->hx - u.ux);
721.  			if (y1 < troom->ly && y2 < troom->ly)
722.  			    return;
723.  			else if (y2 < troom->ly || y1 >= troom->ly && !rn2(2)) {
724.  			    x = x1;
725.  			    y = y1;
726.  			} else {
727.  			    x = x2;
728.  			    y = y2;
729.  			}
730.  		    }
731.  		}
732.  	    } else {
733.  		/* Calculate the possible orthogonal paths */
734.  		n = 0;
735.  		if (stpx != 0 || stpy != sgn(u.uy - troom->ly)) {
736.  		    poss[n].x = u.ux;
737.  		    poss[n++].y = troom->ly;
738.  		}
739.  		if (stpx != 0 || stpy != sgn(u.uy - troom->hy)) {
740.  		    poss[n].x = u.ux;
741.  		    poss[n++].y = troom->hy;
742.  		}
743.  		if (stpx != sgn(u.ux - troom->lx) || stpy != 0) {
744.  		    poss[n].x = troom->lx;
745.  		    poss[n++].y = u.uy;
746.  		}
747.  		if (stpx != sgn(u.ux - troom->hx) || stpy != 0) {
748.  		    poss[n].x = troom->hx;
749.  		    poss[n++].y = u.uy;
750.  		}
751.  		if (n) {
752.  		    n = rn2(n);
753.  		    x = poss[n].x;
754.  		    y = poss[n].y;
755.  		} else {
756.  		    impossible("Omnipresent priest?");
757.  		    return;
758.  		}
759.  	    }
760.  	    if(!linedup(u.ux, u.uy, x, y))
761.  		return;
762.  	}
763.  
764.  	switch(rn2(3)) {
765.  	case 0:
766.  	    pline("%s roars in anger:  \"Thou shalt suffer!\"",
767.  			a_gname_at(ax, ay));
768.  	    break;
769.  	case 1:
770.  	    pline("%s voice booms:  \"How darest thou harm my servant!\"",
771.  			s_suffix(a_gname_at(ax, ay)));
772.  	    break;
773.  	default:
774.  	    pline("%s roars:  \"Thou dost profane my shrine!\"",
775.  			a_gname_at(ax, ay));
776.  	    break;
777.  	}
778.  
779.  	buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
780.  	exercise(A_WIS, FALSE);
781.  }
782.  
783.  void
784.  angry_priest()
785.  {
786.  	register struct monst *priest;
787.  	struct rm *lev;
788.  
789.  	if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
790.  	    wakeup(priest);
791.  	    /*
792.  	     * If the altar has been destroyed or converted, let the
793.  	     * priest run loose.
794.  	     * (When it's just a conversion and there happens to be
795.  	     *	a fresh corpse nearby, the priest ought to have an
796.  	     *	opportunity to try converting it back; maybe someday...)
797.  	     */
798.  	    lev = &levl[EPRI(priest)->shrpos.x][EPRI(priest)->shrpos.y];
799.  	    if (!IS_ALTAR(lev->typ) ||
800.  		((aligntyp)Amask2align(lev->altarmask & AM_MASK) !=
801.  			EPRI(priest)->shralign)) {
802.  		priest->ispriest = 0;		/* now a roamer */
803.  		priest->isminion = 1;		/* but still aligned */
804.  		/* this overloads the `shroom' field, which is now clobbered */
805.  		EPRI(priest)->renegade = 0;
806.  	    }
807.  	}
808.  }
809.  
810.  /*
811.   * When saving bones, find priests that aren't on their shrine level,
812.   * and remove them.   This avoids big problems when restoring bones.
813.   */
814.  void
815.  clearpriests()
816.  {
817.      register struct monst *mtmp, *mtmp2;
818.  
819.      for(mtmp = fmon; mtmp; mtmp = mtmp2) {
820.  	mtmp2 = mtmp->nmon;
821.  	if (!DEADMONSTER(mtmp) && mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
822.  	    mongone(mtmp);
823.      }
824.  }
825.  
826.  /* munge priest-specific structure when restoring -dlc */
827.  void
828.  restpriest(mtmp, ghostly)
829.  register struct monst *mtmp;
830.  boolean ghostly;
831.  {
832.      if(u.uz.dlevel) {
833.  	if (ghostly)
834.  	    assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
835.      }
836.  }
837.  
838.  #endif /* OVLB */
839.  
840.  /*priest.c*/

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.