tilted and rotated clip entities

Attribute 7 of clip- and plclip-entities now allows four different shapes
for the clips:

  0: basic rectangular (like in older AC versions)
  1: tilted in direction of x-axis
  2: tilted in direction of y-axis
  3: rotated by 45 degrees

The shapes 1 and 2 use the value of attr6 as slope angle.

The player only can walk upwards a tilted clip, if the height (attr4) is
at least 0.6 cubes. Slopes steeper than 5.0 can not be walked up (same
maximum step size as for sloped map geometry).

Mappers, please keep in mind: especially tilted clips are more expensive
than regular clips, but they are much cheaper than stairs built from a
bunch of regular clips. Large and small clips cost exactly the same, so
try to combine clips to keep the total number down.
This commit is contained in:
ac-stef
2015-05-27 15:47:05 +02:00
parent 8fa90bef67
commit edd94fb931
4 changed files with 54 additions and 26 deletions
+27 -17
View File
@@ -28,9 +28,28 @@ void renderent(entity &e)
void renderclip(entity &e)
{
float xradius = max(float(e.attr2) / ENTSCALE5, 0.1f), yradius = max(float(e.attr3) / ENTSCALE5, 0.1f);
float xradius = max(float(e.attr2) / ENTSCALE5, 0.05f), yradius = max(float(e.attr3) / ENTSCALE5, 0.05f), h = max(float(e.attr4) / ENTSCALE5, 0.1f);
vec bbmin(e.x - xradius, e.y - yradius, float(S(e.x, e.y)->floor + float(e.attr1) / ENTSCALE10)),
bbmax(e.x + xradius, e.y + yradius, bbmin.z + max(float(e.attr4) / ENTSCALE5, 0.1f));
bbmax(e.x + xradius, e.y + yradius, bbmin.z + h);
vec bb[4];
loopi(4) bb[i] = bbmin;
bb[2].x = bb[1].x = bbmax.x;
bb[2].y = bb[3].y = bbmax.y;
vec o(e.x, e.y, bbmin.z);
float tx = 0, ty = 0, angle = 0;
switch(e.attr7 & 3)
{
case 1: tx = float(e.attr6) / (4 * ENTSCALE10); break; // tilt x
case 2: ty = float(e.attr6) / (4 * ENTSCALE10); break; // tilt y
case 3: angle = PI/4; break; // rotate 45°
}
loopi(4)
{
bb[i].sub(o).rotate_around_z(angle); // rotate
bb[i].z += bb[i].x * tx + bb[i].y * ty; // tilt
bb[i].add(o);
}
glDisable(GL_TEXTURE_2D);
switch(e.type)
@@ -40,21 +59,12 @@ void renderclip(entity &e)
case PLCLIP: linestyle(1, 0xFF, 0, 0xFF); break; // magenta
}
glBegin(GL_LINES);
glVertex3f(bbmin.x, bbmin.y, bbmin.z);
loopi(2) glVertex3f(bbmax.x, bbmin.y, bbmin.z);
loopi(2) glVertex3f(bbmax.x, bbmax.y, bbmin.z);
loopi(2) glVertex3f(bbmin.x, bbmax.y, bbmin.z);
glVertex3f(bbmin.x, bbmin.y, bbmin.z);
glVertex3f(bbmin.x, bbmin.y, bbmax.z);
loopi(2) glVertex3f(bbmax.x, bbmin.y, bbmax.z);
loopi(2) glVertex3f(bbmax.x, bbmax.y, bbmax.z);
loopi(2) glVertex3f(bbmin.x, bbmax.y, bbmax.z);
glVertex3f(bbmin.x, bbmin.y, bbmax.z);
loopi(8) glVertex3f(i&2 ? bbmax.x : bbmin.x, i&4 ? bbmax.y : bbmin.y, i&1 ? bbmax.z : bbmin.z);
loopi(16)
{
int j = ((i + 1) % 8) / 2;
glVertex3f(bb[j].x, bb[j].y, bb[j].z + (i > 7 ? h : 0));
}
loopi(8) glVertex3f(bb[i / 2].x, bb[i / 2].y, bb[i / 2].z + (i & 1 ? h : 0));
glEnd();
glEnable(GL_TEXTURE_2D);
}
+2 -2
View File
@@ -10,8 +10,8 @@ enum // static entity types
LADDER, // attr1 = height
CTF_FLAG, // attr1 = angle, attr2 = red/blue
SOUND, // attr1 = idx, attr2 = radius, attr3 = size, attr4 = volume
CLIP, // attr1 = elevation, attr2 = xradius, attr3 = yradius, attr4 = height
PLCLIP, // attr1 = elevation, attr2 = xradius, attr3 = yradius, attr4 = height
CLIP, // attr1 = elevation, attr2 = xradius, attr3 = yradius, attr4 = height, attr6 = slope, attr7 = shape
PLCLIP, // attr1 = elevation, attr2 = xradius, attr3 = yradius, attr4 = height, attr6 = slope, attr7 = shape
MAXENTTYPES
};
+21 -3
View File
@@ -139,10 +139,28 @@ bool mmcollide(physent *d, float &hi, float &lo) // collide with a map
// if(e.type==CLIP || (e.type == PLCLIP && d->type == ENT_PLAYER))
if (e.type==CLIP || (e.type == PLCLIP && (d->type == ENT_BOT || d->type == ENT_PLAYER || (d->type == ENT_BOUNCE && ((bounceent *)d)->plclipped)))) // don't allow bots to hack themselves into plclips - Bukz 2011/04/14
{
if(fabs(e.x-d->o.x) < float(e.attr2) / ENTSCALE5 + d->radius && fabs(e.y-d->o.y) < float(e.attr3) / ENTSCALE5 + d->radius)
bool hitarea = false;
switch(e.attr7 & 3)
{
const float cz = float(S(e.x, e.y)->floor + float(e.attr1) / ENTSCALE10), ch = float(e.attr4) / ENTSCALE5;
const float dz = d->o.z-d->eyeheight;
default: // classic unrotated clip, possibly tilted
hitarea = fabs(e.x - d->o.x) < float(e.attr2) / ENTSCALE5 + d->radius && fabs(e.y - d->o.y) < float(e.attr3) / ENTSCALE5 + d->radius;
break;
case 3: // clip rotated 45°
{
float rx = (e.x - d->o.x) * 0.707106781f, ry = (e.y - d->o.y) * 0.707106781f, rr = d->radius * 1.414213562f; // rotate player instead of clip (adjust player radius to compensate)
hitarea = fabs(rx - ry) < float(e.attr3) / ENTSCALE5 + rr && fabs(rx + ry) < float(e.attr2) / ENTSCALE5 + rr;
break;
}
}
if(hitarea)
{
float cz = float(S(e.x, e.y)->floor + float(e.attr1) / ENTSCALE10), ch = float(e.attr4) / ENTSCALE5;
if(e.attr6) switch(e.attr7 & 3)
{ // incredibly ugly solution - but it only applies on the one tilted clip we stand on
case 1: cz += (floor(0.5f + clamp(d->o.x - e.x + d->radius * (e.attr6 > 0 ? 1 : -1), -float(e.attr2) / ENTSCALE5, float(e.attr2) / ENTSCALE5))) * float(e.attr6) / (4 * ENTSCALE10); break; // tilt x
case 2: cz += (floor(0.5f + clamp(d->o.y - e.y + d->radius * (e.attr6 > 0 ? 1 : -1), -float(e.attr3) / ENTSCALE5, float(e.attr3) / ENTSCALE5))) * float(e.attr6) / (4 * ENTSCALE10); break; // tilt y
}
const float dz = d->o.z - d->eyeheight;
if(dz < cz - 0.42) { if(cz<hi) hi = cz; }
else if(cz+ch>lo) lo = cz+ch;
if(hi-lo < playerheight) return true;
+4 -4
View File
@@ -469,8 +469,8 @@ short entwraparound[MAXENTTYPES][7] =
{ 0, 0, 0, 0, 0, 0, 0 }, // ladder
{ -3600, 0, 0, 0, 0, 0, 0 }, // ctf-flag
{ 256, 0, 0, 0, 0, 0, 0 }, // sound
{ 0, 0, 0, 0, 0, 0, 0 }, // clip
{ 0, 0, 0, 0, 0, 0, 0 } // plclip
{ 0, 0, 0, 0, 0, 0, 4 }, // clip
{ 0, 0, 0, 0, 0, 0, 4 } // plclip
};
uchar entscale[MAXENTTYPES][7] =
@@ -490,8 +490,8 @@ uchar entscale[MAXENTTYPES][7] =
{ 1, 1, 1, 1, 1, 1, 1 }, // ladder
{ 10, 1, 1, 1, 1, 1, 1 }, // ctf-flag
{ 1, 1, 1, 1, 1, 1, 1 }, // sound
{ 10, 5, 5, 5, 1, 1, 1 }, // clip
{ 10, 5, 5, 5, 1, 1, 1 } // plclip
{ 10, 5, 5, 5, 1, 10, 1 }, // clip
{ 10, 5, 5, 5, 1, 10, 1 } // plclip
};
// see entity.h:61: struct itemstat { int add, start, max, sound; };