1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64: #include <sys/cdefs.h>
65: #ifndef lint
66: __RCSID("$NetBSD: hack.makemon.c,v 1.6 2003/04/02 18:36:37 jsm Exp $");
67: #endif
68:
69: #include "hack.h"
70: #include "extern.h"
71:
72: struct monst zeromonst;
73:
74:
75:
76:
77:
78:
79:
80:
81:
82: struct monst *
83: makemon(const struct permonst *ptr, int x, int y)
84: {
85: struct monst *mtmp;
86: int tmp, ct;
87: boolean anything = (!ptr);
88:
89: if (x != 0 || y != 0)
90: if (m_at(x, y))
91: return ((struct monst *) 0);
92: if (ptr) {
93: if (strchr(fut_geno, ptr->mlet))
94: return ((struct monst *) 0);
95: } else {
96: ct = CMNUM - strlen(fut_geno);
97: if (strchr(fut_geno, 'm'))
98: ct++;
99: if (strchr(fut_geno, '@'))
100: ct++;
101: if (ct <= 0)
102: return (0);
103: tmp = rn2(ct * dlevel / 24 + 7);
104: if (tmp < dlevel - 4)
105: tmp = rn2(ct * dlevel / 24 + 12);
106: if (tmp >= ct)
107: tmp = rn1(ct - ct / 2, ct / 2);
108: for (ct = 0; ct < CMNUM; ct++) {
109: ptr = &mons[ct];
110: if (strchr(fut_geno, ptr->mlet))
111: continue;
112: if (!tmp--)
113: goto gotmon;
114: }
115: panic("makemon?");
116: }
117: gotmon:
118: mtmp = newmonst(ptr->pxlth);
119: *mtmp = zeromonst;
120: for (ct = 0; ct < (int)ptr->pxlth; ct++)
121: ((char *) &(mtmp->mextra[0]))[ct] = 0;
122: mtmp->nmon = fmon;
123: fmon = mtmp;
124: mtmp->m_id = flags.ident++;
125: mtmp->data = ptr;
126: mtmp->mxlth = ptr->pxlth;
127: if (ptr->mlet == 'D')
128: mtmp->mhpmax = mtmp->mhp = 80;
129: else if (!ptr->mlevel)
130: mtmp->mhpmax = mtmp->mhp = rnd(4);
131: else
132: mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
133: mtmp->mx = x;
134: mtmp->my = y;
135: mtmp->mcansee = 1;
136: if (ptr->mlet == 'M') {
137: mtmp->mimic = 1;
138: mtmp->mappearance = ']';
139: }
140: if (!in_mklev) {
141: if (x == u.ux && y == u.uy && ptr->mlet != ' ')
142: mnexto(mtmp);
143: if (x == 0 && y == 0)
144: rloc(mtmp);
145: }
146: if (ptr->mlet == 's' || ptr->mlet == 'S') {
147: mtmp->mhide = mtmp->mundetected = 1;
148: if (in_mklev)
149: if (mtmp->mx && mtmp->my)
150: (void) mkobj_at(0, mtmp->mx, mtmp->my);
151: }
152: if (ptr->mlet == ':') {
153: mtmp->cham = 1;
154: (void) newcham(mtmp, &mons[dlevel + 14 + rn2(CMNUM - 14 - dlevel)]);
155: }
156: if (ptr->mlet == 'I' || ptr->mlet == ';')
157: mtmp->minvis = 1;
158: if (ptr->mlet == 'L' || ptr->mlet == 'N'
159: || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5))
160: )
161: mtmp->msleep = 1;
162:
163: #ifndef NOWORM
164: if (ptr->mlet == 'w' && getwn(mtmp))
165: initworm(mtmp);
166: #endif
167:
168: if (anything)
169: if (ptr->mlet == 'O' || ptr->mlet == 'k') {
170: coord mm;
171: int cnt = rnd(10);
172: mm.x = x;
173: mm.y = y;
174: while (cnt--) {
175: mm = enexto(mm.x, mm.y);
176: (void) makemon(ptr, mm.x, mm.y);
177: }
178: }
179: return (mtmp);
180: }
181:
182: coord
183: enexto(xx, yy)
184: xchar xx, yy;
185: {
186: xchar x, y;
187: coord foo[15], *tfoo;
188: int range;
189:
190: tfoo = foo;
191: range = 1;
192: do {
193: for (x = xx - range; x <= xx + range; x++)
194: if (goodpos(x, yy - range)) {
195: tfoo->x = x;
196: tfoo++->y = yy - range;
197: if (tfoo == &foo[15])
198: goto foofull;
199: }
200: for (x = xx - range; x <= xx + range; x++)
201: if (goodpos(x, yy + range)) {
202: tfoo->x = x;
203: tfoo++->y = yy + range;
204: if (tfoo == &foo[15])
205: goto foofull;
206: }
207: for (y = yy + 1 - range; y < yy + range; y++)
208: if (goodpos(xx - range, y)) {
209: tfoo->x = xx - range;
210: tfoo++->y = y;
211: if (tfoo == &foo[15])
212: goto foofull;
213: }
214: for (y = yy + 1 - range; y < yy + range; y++)
215: if (goodpos(xx + range, y)) {
216: tfoo->x = xx + range;
217: tfoo++->y = y;
218: if (tfoo == &foo[15])
219: goto foofull;
220: }
221: range++;
222: } while (tfoo == foo);
223: foofull:
224: return (foo[rn2(tfoo - foo)]);
225: }
226:
227: int
228: goodpos(int x, int y)
229: {
230: return (
231: !(x < 1 || x > COLNO - 2 || y < 1 || y > ROWNO - 2 ||
232: m_at(x, y) || !ACCESSIBLE(levl[x][y].typ)
233: || (x == u.ux && y == u.uy)
234: || sobj_at(ENORMOUS_ROCK, x, y)
235: ));
236: }
237:
238: void
239: rloc(mtmp)
240: struct monst *mtmp;
241: {
242: int tx, ty;
243: char ch = mtmp->data->mlet;
244:
245: #ifndef NOWORM
246: if (ch == 'w' && mtmp->mx)
247: return;
248: #endif
249: do {
250: tx = rn1(COLNO - 3, 2);
251: ty = rn2(ROWNO);
252: } while (!goodpos(tx, ty));
253: mtmp->mx = tx;
254: mtmp->my = ty;
255: if (u.ustuck == mtmp) {
256: if (u.uswallow) {
257: u.ux = tx;
258: u.uy = ty;
259: docrt();
260: } else
261: u.ustuck = 0;
262: }
263: pmon(mtmp);
264: }
265:
266: struct monst *
267: mkmon_at(let, x, y)
268: char let;
269: int x, y;
270: {
271: int ct;
272: const struct permonst *ptr;
273:
274: for (ct = 0; ct < CMNUM; ct++) {
275: ptr = &mons[ct];
276: if (ptr->mlet == let)
277: return (makemon(ptr, x, y));
278: }
279: return (0);
280: }