|
|
1.1 root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2: /* hack.makemon.c - version 1.0.2 */
3:
4: #include "hack.h"
5: extern char fut_geno[];
6: extern char *index();
7: extern struct obj *mkobj_at();
8: struct monst zeromonst;
9:
10: /*
11: * called with [x,y] = coordinates;
12: * [0,0] means anyplace
13: * [u.ux,u.uy] means: call mnexto (if !in_mklev)
14: *
15: * In case we make an Orc or killer bee, we make an entire horde (swarm);
16: * note that in this case we return only one of them (the one at [x,y]).
17: */
18: struct monst *
19: makemon(ptr,x,y)
20: register struct permonst *ptr;
21: {
22: register struct monst *mtmp;
23: register tmp, ct;
24: boolean anything = (!ptr);
25: extern boolean in_mklev;
26:
27: if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
28: if(ptr){
29: if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
30: } else {
31: ct = CMNUM - strlen(fut_geno);
32: if(index(fut_geno, 'm')) ct++; /* make only 1 minotaur */
33: if(index(fut_geno, '@')) ct++;
34: if(ct <= 0) return(0); /* no more monsters! */
35: tmp = rn2(ct*dlevel/24 + 7);
36: if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
37: if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
38: for(ct = 0; ct < CMNUM; ct++){
39: ptr = &mons[ct];
40: if(index(fut_geno, ptr->mlet))
41: continue;
42: if(!tmp--) goto gotmon;
43: }
44: panic("makemon?");
45: }
46: gotmon:
47: mtmp = newmonst(ptr->pxlth);
48: *mtmp = zeromonst; /* clear all entries in structure */
49: for(ct = 0; ct < ptr->pxlth; ct++)
50: ((char *) &(mtmp->mextra[0]))[ct] = 0;
51: mtmp->nmon = fmon;
52: fmon = mtmp;
53: mtmp->m_id = flags.ident++;
54: mtmp->data = ptr;
55: mtmp->mxlth = ptr->pxlth;
56: if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
57: else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
58: else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
59: mtmp->mx = x;
60: mtmp->my = y;
61: mtmp->mcansee = 1;
62: if(ptr->mlet == 'M'){
63: mtmp->mimic = 1;
64: mtmp->mappearance = ']';
65: }
66: if(!in_mklev) {
67: if(x == u.ux && y == u.uy && ptr->mlet != ' ')
68: mnexto(mtmp);
69: if(x == 0 && y == 0)
70: rloc(mtmp);
71: }
72: if(ptr->mlet == 's' || ptr->mlet == 'S') {
73: mtmp->mhide = mtmp->mundetected = 1;
74: if(in_mklev)
75: if(mtmp->mx && mtmp->my)
76: (void) mkobj_at(0, mtmp->mx, mtmp->my);
77: }
78: if(ptr->mlet == ':') {
79: mtmp->cham = 1;
80: (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
81: }
82: if(ptr->mlet == 'I' || ptr->mlet == ';')
83: mtmp->minvis = 1;
84: if(ptr->mlet == 'L' || ptr->mlet == 'N'
85: || (in_mklev && index("&w;", ptr->mlet) && rn2(5))
86: ) mtmp->msleep = 1;
87:
88: #ifndef NOWORM
89: if(ptr->mlet == 'w' && getwn(mtmp))
90: initworm(mtmp);
91: #endif NOWORM
92:
93: if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
94: coord enexto();
95: coord mm;
96: register int cnt = rnd(10);
97: mm.x = x;
98: mm.y = y;
99: while(cnt--) {
100: mm = enexto(mm.x, mm.y);
101: (void) makemon(ptr, mm.x, mm.y);
102: }
103: }
104:
105: return(mtmp);
106: }
107:
108: coord
109: enexto(xx,yy)
110: register xchar xx,yy;
111: {
112: register xchar x,y;
113: coord foo[15], *tfoo;
114: int range;
115:
116: tfoo = foo;
117: range = 1;
118: do { /* full kludge action. */
119: for(x = xx-range; x <= xx+range; x++)
120: if(goodpos(x, yy-range)) {
121: tfoo->x = x;
122: tfoo++->y = yy-range;
123: if(tfoo == &foo[15]) goto foofull;
124: }
125: for(x = xx-range; x <= xx+range; x++)
126: if(goodpos(x,yy+range)) {
127: tfoo->x = x;
128: tfoo++->y = yy+range;
129: if(tfoo == &foo[15]) goto foofull;
130: }
131: for(y = yy+1-range; y < yy+range; y++)
132: if(goodpos(xx-range,y)) {
133: tfoo->x = xx-range;
134: tfoo++->y = y;
135: if(tfoo == &foo[15]) goto foofull;
136: }
137: for(y = yy+1-range; y < yy+range; y++)
138: if(goodpos(xx+range,y)) {
139: tfoo->x = xx+range;
140: tfoo++->y = y;
141: if(tfoo == &foo[15]) goto foofull;
142: }
143: range++;
144: } while(tfoo == foo);
145: foofull:
146: return( foo[rn2(tfoo-foo)] );
147: }
148:
149: goodpos(x,y) /* used only in mnexto and rloc */
150: {
151: return(
152: ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
153: m_at(x,y) || !ACCESSIBLE(levl[x][y].typ)
154: || (x == u.ux && y == u.uy)
155: || sobj_at(ENORMOUS_ROCK, x, y)
156: ));
157: }
158:
159: rloc(mtmp)
160: struct monst *mtmp;
161: {
162: register tx,ty;
163: register char ch = mtmp->data->mlet;
164:
165: #ifndef NOWORM
166: if(ch == 'w' && mtmp->mx) return; /* do not relocate worms */
167: #endif NOWORM
168: do {
169: tx = rn1(COLNO-3,2);
170: ty = rn2(ROWNO);
171: } while(!goodpos(tx,ty));
172: mtmp->mx = tx;
173: mtmp->my = ty;
174: if(u.ustuck == mtmp){
175: if(u.uswallow) {
176: u.ux = tx;
177: u.uy = ty;
178: docrt();
179: } else u.ustuck = 0;
180: }
181: pmon(mtmp);
182: }
183:
184: struct monst *
185: mkmon_at(let,x,y)
186: char let;
187: register int x,y;
188: {
189: register int ct;
190: register struct permonst *ptr;
191:
192: for(ct = 0; ct < CMNUM; ct++) {
193: ptr = &mons[ct];
194: if(ptr->mlet == let)
195: return(makemon(ptr,x,y));
196: }
197: return(0);
198: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.