︙ | | | ︙ | |
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
monstertotal++;
};
};
};
bool
los(float lx, float ly, float lz, float bx, float by, float bz,
vec &v) // height-correct line of sight for monster shooting/seeing
{
if (OUTBORD((int)lx, (int)ly) || OUTBORD((int)bx, (int)by))
return false;
float dx = bx - lx;
float dy = by - ly;
int steps = (int)(sqrt(dx * dx + dy * dy) / 0.9);
if (!steps)
|
|
|
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
monstertotal++;
};
};
};
bool
los(float lx, float ly, float lz, float bx, float by, float bz,
OFVector3D &v) // height-correct line of sight for monster shooting/seeing
{
if (OUTBORD((int)lx, (int)ly) || OUTBORD((int)bx, (int)by))
return false;
float dx = bx - lx;
float dy = by - ly;
int steps = (int)(sqrt(dx * dx + dy * dy) / 0.9);
if (!steps)
|
︙ | | | ︙ | |
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
y += dy / (float)steps;
i++;
};
return i >= steps;
};
bool
enemylos(dynent *m, vec &v)
{
v = m->o;
return los(m->o.x, m->o.y, m->o.z, m->enemy->o.x, m->enemy->o.y,
m->enemy->o.z, v);
};
// monster AI is sequenced using transitions: they are in a particular state
|
|
|
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
y += dy / (float)steps;
i++;
};
return i >= steps;
};
bool
enemylos(dynent *m, OFVector3D &v)
{
v = m->o;
return los(m->o.x, m->o.y, m->o.z, m->enemy->o.x, m->enemy->o.y,
m->enemy->o.z, v);
};
// monster AI is sequenced using transitions: they are in a particular state
|
︙ | | | ︙ | |
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
if (m->trigger < lastmillis)
transition(m, M_HOME, 1, 100, 200);
break;
case M_SLEEP: // state classic sp monster start in, wait for visual
// contact
{
vec target;
if (editmode || !enemylos(m, target))
return; // skip running physics
normalise(m, enemyyaw);
float angle = (float)fabs(enemyyaw - m->yaw);
if (disttoenemy < 8 // the better the angle to the player, the
// further the monster can see/hear
|| (disttoenemy < 16 && angle < 135) ||
|
|
|
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
if (m->trigger < lastmillis)
transition(m, M_HOME, 1, 100, 200);
break;
case M_SLEEP: // state classic sp monster start in, wait for visual
// contact
{
OFVector3D target;
if (editmode || !enemylos(m, target))
return; // skip running physics
normalise(m, enemyyaw);
float angle = (float)fabs(enemyyaw - m->yaw);
if (disttoenemy < 8 // the better the angle to the player, the
// further the monster can see/hear
|| (disttoenemy < 16 && angle < 135) ||
|
︙ | | | ︙ | |
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
};
break;
case M_HOME: // monster has visual contact, heads straight for player
// and may want to shoot at any time
m->targetyaw = enemyyaw;
if (m->trigger < lastmillis) {
vec target;
if (!enemylos(
m, target)) // no visual contact anymore, let
// monster get as close as possible
// then search for player
{
transition(m, M_HOME, 1, 800, 500);
} else // the closer the monster is the more likely he
|
|
|
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
};
break;
case M_HOME: // monster has visual contact, heads straight for player
// and may want to shoot at any time
m->targetyaw = enemyyaw;
if (m->trigger < lastmillis) {
OFVector3D target;
if (!enemylos(
m, target)) // no visual contact anymore, let
// monster get as close as possible
// then search for player
{
transition(m, M_HOME, 1, 800, 500);
} else // the closer the monster is the more likely he
|
︙ | | | ︙ | |
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
// used
{
entity &e = ents[i];
if (e.type != TELEPORT)
continue;
if (OUTBORD(e.x, e.y))
continue;
vec v = {(float)e.x, (float)e.y, (float)S(e.x, e.y)->floor};
loopv(monsters) if (monsters[i]->state == CS_DEAD)
{
if (lastmillis - monsters[i]->lastaction < 2000) {
monsters[i]->move = 0;
moveplayer(monsters[i], 1, false);
};
}
|
>
|
|
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
|
// used
{
entity &e = ents[i];
if (e.type != TELEPORT)
continue;
if (OUTBORD(e.x, e.y))
continue;
OFVector3D v =
OFMakeVector3D(e.x, e.y, (float)S(e.x, e.y)->floor);
loopv(monsters) if (monsters[i]->state == CS_DEAD)
{
if (lastmillis - monsters[i]->lastaction < 2000) {
monsters[i]->move = 0;
moveplayer(monsters[i], 1, false);
};
}
|
︙ | | | ︙ | |