From edd94fb931b039ff32e2b75bca81a496dadbe380 Mon Sep 17 00:00:00 2001 From: ac-stef Date: Thu, 21 May 2015 18:28:03 +0200 Subject: [PATCH] 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. --- source/src/entities.cpp | 44 +++++++++++++++++++++++++---------------- source/src/entity.h | 4 ++-- source/src/physics.cpp | 24 +++++++++++++++++++--- source/src/server.h | 8 ++++---- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/source/src/entities.cpp b/source/src/entities.cpp index ab80264e..d2bc611e 100644 --- a/source/src/entities.cpp +++ b/source/src/entities.cpp @@ -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); } diff --git a/source/src/entity.h b/source/src/entity.h index 46a362c8..45187305 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -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 }; diff --git a/source/src/physics.cpp b/source/src/physics.cpp index 1c3975ab..696f05a4 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -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(czlo) lo = cz+ch; if(hi-lo < playerheight) return true; diff --git a/source/src/server.h b/source/src/server.h index 5dd8dc40..6df77eb9 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -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; };