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; };