00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "../game/q_shared.h"
00033 #include "l_memory.h"
00034 #include "l_script.h"
00035 #include "l_precomp.h"
00036 #include "l_struct.h"
00037 #include "l_libvar.h"
00038 #include "aasfile.h"
00039 #include "../game/botlib.h"
00040 #include "../game/be_aas.h"
00041 #include "be_aas_funcs.h"
00042 #include "be_aas_def.h"
00043
00044 extern botlib_import_t botimport;
00045
00046 aas_settings_t aassettings;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 int AAS_DropToFloor(vec3_t origin, vec3_t mins, vec3_t maxs)
00057 {
00058 vec3_t end;
00059 bsp_trace_t trace;
00060
00061 VectorCopy(origin, end);
00062 end[2] -= 100;
00063 trace = AAS_Trace(origin, mins, maxs, end, 0, CONTENTS_SOLID);
00064 if (trace.startsolid) return qfalse;
00065 VectorCopy(trace.endpos, origin);
00066 return qtrue;
00067 }
00068
00069
00070
00071
00072
00073
00074 void AAS_InitSettings(void)
00075 {
00076 aassettings.phys_gravitydirection[0] = 0;
00077 aassettings.phys_gravitydirection[1] = 0;
00078 aassettings.phys_gravitydirection[2] = -1;
00079 aassettings.phys_friction = LibVarValue("phys_friction", "6");
00080 aassettings.phys_stopspeed = LibVarValue("phys_stopspeed", "100");
00081 aassettings.phys_gravity = LibVarValue("phys_gravity", "800");
00082 aassettings.phys_waterfriction = LibVarValue("phys_waterfriction", "1");
00083 aassettings.phys_watergravity = LibVarValue("phys_watergravity", "400");
00084 aassettings.phys_maxvelocity = LibVarValue("phys_maxvelocity", "320");
00085 aassettings.phys_maxwalkvelocity = LibVarValue("phys_maxwalkvelocity", "320");
00086 aassettings.phys_maxcrouchvelocity = LibVarValue("phys_maxcrouchvelocity", "100");
00087 aassettings.phys_maxswimvelocity = LibVarValue("phys_maxswimvelocity", "150");
00088 aassettings.phys_walkaccelerate = LibVarValue("phys_walkaccelerate", "10");
00089 aassettings.phys_airaccelerate = LibVarValue("phys_airaccelerate", "1");
00090 aassettings.phys_swimaccelerate = LibVarValue("phys_swimaccelerate", "4");
00091 aassettings.phys_maxstep = LibVarValue("phys_maxstep", "19");
00092 aassettings.phys_maxsteepness = LibVarValue("phys_maxsteepness", "0.7");
00093 aassettings.phys_maxwaterjump = LibVarValue("phys_maxwaterjump", "18");
00094 aassettings.phys_maxbarrier = LibVarValue("phys_maxbarrier", "33");
00095 aassettings.phys_jumpvel = LibVarValue("phys_jumpvel", "270");
00096 aassettings.phys_falldelta5 = LibVarValue("phys_falldelta5", "40");
00097 aassettings.phys_falldelta10 = LibVarValue("phys_falldelta10", "60");
00098 aassettings.rs_waterjump = LibVarValue("rs_waterjump", "400");
00099 aassettings.rs_teleport = LibVarValue("rs_teleport", "50");
00100 aassettings.rs_barrierjump = LibVarValue("rs_barrierjump", "100");
00101 aassettings.rs_startcrouch = LibVarValue("rs_startcrouch", "300");
00102 aassettings.rs_startgrapple = LibVarValue("rs_startgrapple", "500");
00103 aassettings.rs_startwalkoffledge = LibVarValue("rs_startwalkoffledge", "70");
00104 aassettings.rs_startjump = LibVarValue("rs_startjump", "300");
00105 aassettings.rs_rocketjump = LibVarValue("rs_rocketjump", "500");
00106 aassettings.rs_bfgjump = LibVarValue("rs_bfgjump", "500");
00107 aassettings.rs_jumppad = LibVarValue("rs_jumppad", "250");
00108 aassettings.rs_aircontrolledjumppad = LibVarValue("rs_aircontrolledjumppad", "300");
00109 aassettings.rs_funcbob = LibVarValue("rs_funcbob", "300");
00110 aassettings.rs_startelevator = LibVarValue("rs_startelevator", "50");
00111 aassettings.rs_falldamage5 = LibVarValue("rs_falldamage5", "300");
00112 aassettings.rs_falldamage10 = LibVarValue("rs_falldamage10", "500");
00113 aassettings.rs_maxfallheight = LibVarValue("rs_maxfallheight", "0");
00114 aassettings.rs_maxjumpfallheight = LibVarValue("rs_maxjumpfallheight", "450");
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 int AAS_AgainstLadder(vec3_t origin)
00124 {
00125 int areanum, i, facenum, side;
00126 vec3_t org;
00127 aas_plane_t *plane;
00128 aas_face_t *face;
00129 aas_area_t *area;
00130
00131 VectorCopy(origin, org);
00132 areanum = AAS_PointAreaNum(org);
00133 if (!areanum)
00134 {
00135 org[0] += 1;
00136 areanum = AAS_PointAreaNum(org);
00137 if (!areanum)
00138 {
00139 org[1] += 1;
00140 areanum = AAS_PointAreaNum(org);
00141 if (!areanum)
00142 {
00143 org[0] -= 2;
00144 areanum = AAS_PointAreaNum(org);
00145 if (!areanum)
00146 {
00147 org[1] -= 2;
00148 areanum = AAS_PointAreaNum(org);
00149 }
00150 }
00151 }
00152 }
00153
00154 if (!areanum) return qfalse;
00155
00156 if (!(aasworld.areasettings[areanum].areaflags & AREA_LADDER)) return qfalse;
00157
00158 if (!(aasworld.areasettings[areanum].presencetype & PRESENCE_NORMAL)) return qfalse;
00159
00160 area = &aasworld.areas[areanum];
00161 for (i = 0; i < area->numfaces; i++)
00162 {
00163 facenum = aasworld.faceindex[area->firstface + i];
00164 side = facenum < 0;
00165 face = &aasworld.faces[abs(facenum)];
00166
00167 if (!(face->faceflags & FACE_LADDER)) continue;
00168
00169 plane = &aasworld.planes[face->planenum ^ side];
00170
00171 if (abs(DotProduct(plane->normal, origin) - plane->dist) < 3)
00172 {
00173 if (AAS_PointInsideFace(abs(facenum), origin, 0.1f)) return qtrue;
00174 }
00175 }
00176 return qfalse;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185 int AAS_OnGround(vec3_t origin, int presencetype, int passent)
00186 {
00187 aas_trace_t trace;
00188 vec3_t end, up = {0, 0, 1};
00189 aas_plane_t *plane;
00190
00191 VectorCopy(origin, end);
00192 end[2] -= 10;
00193
00194 trace = AAS_TraceClientBBox(origin, end, presencetype, passent);
00195
00196
00197 if (trace.startsolid) return qfalse;
00198
00199 if (trace.fraction >= 1.0) return qfalse;
00200
00201 if (origin[2] - trace.endpos[2] > 10) return qfalse;
00202
00203 plane = AAS_PlaneFromNum(trace.planenum);
00204 if (DotProduct(plane->normal, up) < aassettings.phys_maxsteepness) return qfalse;
00205
00206 return qtrue;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 int AAS_Swimming(vec3_t origin)
00216 {
00217 vec3_t testorg;
00218
00219 VectorCopy(origin, testorg);
00220 testorg[2] -= 2;
00221 if (AAS_PointContents(testorg) & (CONTENTS_LAVA|CONTENTS_SLIME|CONTENTS_WATER)) return qtrue;
00222 return qfalse;
00223 }
00224
00225
00226
00227
00228
00229
00230 static vec3_t VEC_UP = {0, -1, 0};
00231 static vec3_t MOVEDIR_UP = {0, 0, 1};
00232 static vec3_t VEC_DOWN = {0, -2, 0};
00233 static vec3_t MOVEDIR_DOWN = {0, 0, -1};
00234
00235 void AAS_SetMovedir(vec3_t angles, vec3_t movedir)
00236 {
00237 if (VectorCompare(angles, VEC_UP))
00238 {
00239 VectorCopy(MOVEDIR_UP, movedir);
00240 }
00241 else if (VectorCompare(angles, VEC_DOWN))
00242 {
00243 VectorCopy(MOVEDIR_DOWN, movedir);
00244 }
00245 else
00246 {
00247 AngleVectors(angles, movedir, NULL, NULL);
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256 void AAS_JumpReachRunStart(aas_reachability_t *reach, vec3_t runstart)
00257 {
00258 vec3_t hordir, start, cmdmove;
00259 aas_clientmove_t move;
00260
00261
00262 hordir[0] = reach->start[0] - reach->end[0];
00263 hordir[1] = reach->start[1] - reach->end[1];
00264 hordir[2] = 0;
00265 VectorNormalize(hordir);
00266
00267 VectorCopy(reach->start, start);
00268 start[2] += 1;
00269
00270 VectorScale(hordir, 400, cmdmove);
00271
00272 AAS_PredictClientMovement(&move, -1, start, PRESENCE_NORMAL, qtrue,
00273 vec3_origin, cmdmove, 1, 2, 0.1f,
00274 SE_ENTERWATER|SE_ENTERSLIME|SE_ENTERLAVA|
00275 SE_HITGROUNDDAMAGE|SE_GAP, 0, qfalse);
00276 VectorCopy(move.endpos, runstart);
00277
00278 if (move.stopevent & (SE_ENTERSLIME|SE_ENTERLAVA|SE_HITGROUNDDAMAGE))
00279 {
00280 VectorCopy(start, runstart);
00281 }
00282 }
00283
00284
00285
00286
00287
00288
00289
00290 float AAS_WeaponJumpZVelocity(vec3_t origin, float radiusdamage)
00291 {
00292 vec3_t kvel, v, start, end, forward, right, viewangles, dir;
00293 float mass, knockback, points;
00294 vec3_t rocketoffset = {8, 8, -8};
00295 vec3_t botmins = {-16, -16, -24};
00296 vec3_t botmaxs = {16, 16, 32};
00297 bsp_trace_t bsptrace;
00298
00299
00300 viewangles[PITCH] = 90;
00301 viewangles[YAW] = 0;
00302 viewangles[ROLL] = 0;
00303
00304 VectorCopy(origin, start);
00305 start[2] += 8;
00306 AngleVectors(viewangles, forward, right, NULL);
00307 start[0] += forward[0] * rocketoffset[0] + right[0] * rocketoffset[1];
00308 start[1] += forward[1] * rocketoffset[0] + right[1] * rocketoffset[1];
00309 start[2] += forward[2] * rocketoffset[0] + right[2] * rocketoffset[1] + rocketoffset[2];
00310
00311 VectorMA(start, 500, forward, end);
00312
00313 bsptrace = AAS_Trace(start, NULL, NULL, end, 1, CONTENTS_SOLID);
00314
00315 VectorAdd(botmins, botmaxs, v);
00316 VectorMA(origin, 0.5, v, v);
00317 VectorSubtract(bsptrace.endpos, v, v);
00318
00319 points = radiusdamage - 0.5 * VectorLength(v);
00320 if (points < 0) points = 0;
00321
00322 points *= 0.5;
00323
00324 mass = 200;
00325
00326 knockback = points;
00327
00328 VectorSubtract(origin, bsptrace.endpos, dir);
00329 VectorNormalize(dir);
00330
00331 VectorScale(dir, 1600.0 * (float)knockback / mass, kvel);
00332
00333 return kvel[2] + aassettings.phys_jumpvel;
00334 }
00335
00336
00337
00338
00339
00340
00341 float AAS_RocketJumpZVelocity(vec3_t origin)
00342 {
00343
00344 return AAS_WeaponJumpZVelocity(origin, 120);
00345 }
00346
00347
00348
00349
00350
00351
00352 float AAS_BFGJumpZVelocity(vec3_t origin)
00353 {
00354
00355 return AAS_WeaponJumpZVelocity(origin, 120);
00356 }
00357
00358
00359
00360
00361
00362
00363
00364 void AAS_Accelerate(vec3_t velocity, float frametime, vec3_t wishdir, float wishspeed, float accel)
00365 {
00366
00367 int i;
00368 float addspeed, accelspeed, currentspeed;
00369
00370 currentspeed = DotProduct(velocity, wishdir);
00371 addspeed = wishspeed - currentspeed;
00372 if (addspeed <= 0) {
00373 return;
00374 }
00375 accelspeed = accel*frametime*wishspeed;
00376 if (accelspeed > addspeed) {
00377 accelspeed = addspeed;
00378 }
00379
00380 for (i=0 ; i<3 ; i++) {
00381 velocity[i] += accelspeed*wishdir[i];
00382 }
00383 }
00384
00385
00386
00387
00388
00389
00390 void AAS_AirControl(vec3_t start, vec3_t end, vec3_t velocity, vec3_t cmdmove)
00391 {
00392 vec3_t dir;
00393
00394 VectorSubtract(end, start, dir);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403 void AAS_ApplyFriction(vec3_t vel, float friction, float stopspeed,
00404 float frametime)
00405 {
00406 float speed, control, newspeed;
00407
00408
00409 speed = sqrt(vel[0] * vel[0] + vel[1] * vel[1]);
00410 if (speed)
00411 {
00412 control = speed < stopspeed ? stopspeed : speed;
00413 newspeed = speed - frametime * control * friction;
00414 if (newspeed < 0) newspeed = 0;
00415 newspeed /= speed;
00416 vel[0] *= newspeed;
00417 vel[1] *= newspeed;
00418 }
00419 }
00420
00421
00422
00423
00424
00425
00426 int AAS_ClipToBBox(aas_trace_t *trace, vec3_t start, vec3_t end, int presencetype, vec3_t mins, vec3_t maxs)
00427 {
00428 int i, j, side;
00429 float front, back, frac, planedist;
00430 vec3_t bboxmins, bboxmaxs, absmins, absmaxs, dir, mid;
00431
00432 AAS_PresenceTypeBoundingBox(presencetype, bboxmins, bboxmaxs);
00433 VectorSubtract(mins, bboxmaxs, absmins);
00434 VectorSubtract(maxs, bboxmins, absmaxs);
00435
00436 VectorCopy(end, trace->endpos);
00437 trace->fraction = 1;
00438 for (i = 0; i < 3; i++)
00439 {
00440 if (start[i] < absmins[i] && end[i] < absmins[i]) return qfalse;
00441 if (start[i] > absmaxs[i] && end[i] > absmaxs[i]) return qfalse;
00442 }
00443
00444 VectorSubtract(end, start, dir);
00445 frac = 1;
00446 for (i = 0; i < 3; i++)
00447 {
00448
00449 if (dir[i] > 0) planedist = absmins[i];
00450 else planedist = absmaxs[i];
00451
00452 front = start[i] - planedist;
00453 back = end[i] - planedist;
00454 frac = front / (front-back);
00455
00456 side = i + 1;
00457 if (side > 2) side = 0;
00458 mid[side] = start[side] + dir[side] * frac;
00459 if (mid[side] > absmins[side] && mid[side] < absmaxs[side])
00460 {
00461
00462 side++;
00463 if (side > 2) side = 0;
00464 mid[side] = start[side] + dir[side] * frac;
00465 if (mid[side] > absmins[side] && mid[side] < absmaxs[side])
00466 {
00467 mid[i] = planedist;
00468 break;
00469 }
00470 }
00471 }
00472
00473 if (i != 3)
00474 {
00475 trace->startsolid = qfalse;
00476 trace->fraction = frac;
00477 trace->ent = 0;
00478 trace->planenum = 0;
00479 trace->area = 0;
00480 trace->lastarea = 0;
00481
00482 for (j = 0; j < 3; j++) trace->endpos[j] = start[j] + dir[j] * frac;
00483 return qtrue;
00484 }
00485 return qfalse;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 int AAS_ClientMovementPrediction(struct aas_clientmove_s *move,
00506 int entnum, vec3_t origin,
00507 int presencetype, int onground,
00508 vec3_t velocity, vec3_t cmdmove,
00509 int cmdframes,
00510 int maxframes, float frametime,
00511 int stopevent, int stopareanum,
00512 vec3_t mins, vec3_t maxs, int visualize)
00513 {
00514 float phys_friction, phys_stopspeed, phys_gravity, phys_waterfriction;
00515 float phys_watergravity;
00516 float phys_walkaccelerate, phys_airaccelerate, phys_swimaccelerate;
00517 float phys_maxwalkvelocity, phys_maxcrouchvelocity, phys_maxswimvelocity;
00518 float phys_maxstep, phys_maxsteepness, phys_jumpvel, friction;
00519 float gravity, delta, maxvel, wishspeed, accelerate;
00520
00521 int n, i, j, pc, step, swimming, ax, crouch, event, jump_frame, areanum;
00522 int areas[20], numareas;
00523 vec3_t points[20];
00524 vec3_t org, end, feet, start, stepend, lastorg, wishdir;
00525 vec3_t frame_test_vel, old_frame_test_vel, left_test_vel;
00526 vec3_t up = {0, 0, 1};
00527 aas_plane_t *plane, *plane2;
00528 aas_trace_t trace, steptrace;
00529
00530 if (frametime <= 0) frametime = 0.1f;
00531
00532 phys_friction = aassettings.phys_friction;
00533 phys_stopspeed = aassettings.phys_stopspeed;
00534 phys_gravity = aassettings.phys_gravity;
00535 phys_waterfriction = aassettings.phys_waterfriction;
00536 phys_watergravity = aassettings.phys_watergravity;
00537 phys_maxwalkvelocity = aassettings.phys_maxwalkvelocity;
00538 phys_maxcrouchvelocity = aassettings.phys_maxcrouchvelocity;
00539 phys_maxswimvelocity = aassettings.phys_maxswimvelocity;
00540 phys_walkaccelerate = aassettings.phys_walkaccelerate;
00541 phys_airaccelerate = aassettings.phys_airaccelerate;
00542 phys_swimaccelerate = aassettings.phys_swimaccelerate;
00543 phys_maxstep = aassettings.phys_maxstep;
00544 phys_maxsteepness = aassettings.phys_maxsteepness;
00545 phys_jumpvel = aassettings.phys_jumpvel * frametime;
00546
00547 Com_Memset(move, 0, sizeof(aas_clientmove_t));
00548 Com_Memset(&trace, 0, sizeof(aas_trace_t));
00549
00550 VectorCopy(origin, org);
00551 org[2] += 0.25;
00552
00553 VectorScale(velocity, frametime, frame_test_vel);
00554
00555 jump_frame = -1;
00556
00557 for (n = 0; n < maxframes; n++)
00558 {
00559 swimming = AAS_Swimming(org);
00560
00561 gravity = swimming ? phys_watergravity : phys_gravity;
00562
00563 frame_test_vel[2] = frame_test_vel[2] - (gravity * 0.1 * frametime);
00564
00565 if (onground || swimming)
00566 {
00567 friction = swimming ? phys_friction : phys_waterfriction;
00568
00569 VectorScale(frame_test_vel, 1/frametime, frame_test_vel);
00570 AAS_ApplyFriction(frame_test_vel, friction, phys_stopspeed, frametime);
00571 VectorScale(frame_test_vel, frametime, frame_test_vel);
00572 }
00573 crouch = qfalse;
00574
00575 if (n < cmdframes)
00576 {
00577 ax = 0;
00578 maxvel = phys_maxwalkvelocity;
00579 accelerate = phys_airaccelerate;
00580 VectorCopy(cmdmove, wishdir);
00581 if (onground)
00582 {
00583 if (cmdmove[2] < -300)
00584 {
00585 crouch = qtrue;
00586 maxvel = phys_maxcrouchvelocity;
00587 }
00588
00589 if (!swimming && cmdmove[2] > 1)
00590 {
00591
00592 frame_test_vel[2] = phys_jumpvel - (gravity * 0.1 * frametime) + 5;
00593 jump_frame = n;
00594
00595 accelerate = phys_airaccelerate;
00596 }
00597 else
00598 {
00599 accelerate = phys_walkaccelerate;
00600 }
00601 ax = 2;
00602 }
00603 if (swimming)
00604 {
00605 maxvel = phys_maxswimvelocity;
00606 accelerate = phys_swimaccelerate;
00607 ax = 3;
00608 }
00609 else
00610 {
00611 wishdir[2] = 0;
00612 }
00613
00614 wishspeed = VectorNormalize(wishdir);
00615 if (wishspeed > maxvel) wishspeed = maxvel;
00616 VectorScale(frame_test_vel, 1/frametime, frame_test_vel);
00617 AAS_Accelerate(frame_test_vel, frametime, wishdir, wishspeed, accelerate);
00618 VectorScale(frame_test_vel, frametime, frame_test_vel);
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 }
00633 if (crouch)
00634 {
00635 presencetype = PRESENCE_CROUCH;
00636 }
00637 else if (presencetype == PRESENCE_CROUCH)
00638 {
00639 if (AAS_PointPresenceType(org) & PRESENCE_NORMAL)
00640 {
00641 presencetype = PRESENCE_NORMAL;
00642 }
00643 }
00644
00645 VectorCopy(org, lastorg);
00646
00647 VectorCopy(frame_test_vel, left_test_vel);
00648 j = 0;
00649 do
00650 {
00651 VectorAdd(org, left_test_vel, end);
00652
00653 trace = AAS_TraceClientBBox(org, end, presencetype, entnum);
00654
00655
00656 if (visualize)
00657 {
00658 if (trace.startsolid) botimport.Print(PRT_MESSAGE, "PredictMovement: start solid\n");
00659 AAS_DebugLine(org, trace.endpos, LINECOLOR_RED);
00660 }
00661
00662
00663 if (stopevent & (SE_ENTERAREA|SE_TOUCHJUMPPAD|SE_TOUCHTELEPORTER|SE_TOUCHCLUSTERPORTAL))
00664 {
00665 numareas = AAS_TraceAreas(org, trace.endpos, areas, points, 20);
00666 for (i = 0; i < numareas; i++)
00667 {
00668 if (stopevent & SE_ENTERAREA)
00669 {
00670 if (areas[i] == stopareanum)
00671 {
00672 VectorCopy(points[i], move->endpos);
00673 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00674 move->endarea = areas[i];
00675 move->trace = trace;
00676 move->stopevent = SE_ENTERAREA;
00677 move->presencetype = presencetype;
00678 move->endcontents = 0;
00679 move->time = n * frametime;
00680 move->frames = n;
00681 return qtrue;
00682 }
00683 }
00684
00685 if ((stopevent & SE_TOUCHJUMPPAD) && n)
00686 {
00687 if (aasworld.areasettings[areas[i]].contents & AREACONTENTS_JUMPPAD)
00688 {
00689 VectorCopy(points[i], move->endpos);
00690 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00691 move->endarea = areas[i];
00692 move->trace = trace;
00693 move->stopevent = SE_TOUCHJUMPPAD;
00694 move->presencetype = presencetype;
00695 move->endcontents = 0;
00696 move->time = n * frametime;
00697 move->frames = n;
00698 return qtrue;
00699 }
00700 }
00701 if (stopevent & SE_TOUCHTELEPORTER)
00702 {
00703 if (aasworld.areasettings[areas[i]].contents & AREACONTENTS_TELEPORTER)
00704 {
00705 VectorCopy(points[i], move->endpos);
00706 move->endarea = areas[i];
00707 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00708 move->trace = trace;
00709 move->stopevent = SE_TOUCHTELEPORTER;
00710 move->presencetype = presencetype;
00711 move->endcontents = 0;
00712 move->time = n * frametime;
00713 move->frames = n;
00714 return qtrue;
00715 }
00716 }
00717 if (stopevent & SE_TOUCHCLUSTERPORTAL)
00718 {
00719 if (aasworld.areasettings[areas[i]].contents & AREACONTENTS_CLUSTERPORTAL)
00720 {
00721 VectorCopy(points[i], move->endpos);
00722 move->endarea = areas[i];
00723 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00724 move->trace = trace;
00725 move->stopevent = SE_TOUCHCLUSTERPORTAL;
00726 move->presencetype = presencetype;
00727 move->endcontents = 0;
00728 move->time = n * frametime;
00729 move->frames = n;
00730 return qtrue;
00731 }
00732 }
00733 }
00734 }
00735
00736 if (stopevent & SE_HITBOUNDINGBOX)
00737 {
00738 if (AAS_ClipToBBox(&trace, org, trace.endpos, presencetype, mins, maxs))
00739 {
00740 VectorCopy(trace.endpos, move->endpos);
00741 move->endarea = AAS_PointAreaNum(move->endpos);
00742 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00743 move->trace = trace;
00744 move->stopevent = SE_HITBOUNDINGBOX;
00745 move->presencetype = presencetype;
00746 move->endcontents = 0;
00747 move->time = n * frametime;
00748 move->frames = n;
00749 return qtrue;
00750 }
00751 }
00752
00753 VectorCopy(trace.endpos, org);
00754
00755 if (trace.fraction < 1.0)
00756 {
00757
00758 plane = AAS_PlaneFromNum(trace.planenum);
00759
00760 if (stopevent & SE_HITGROUNDAREA)
00761 {
00762 if (DotProduct(plane->normal, up) > phys_maxsteepness)
00763 {
00764 VectorCopy(org, start);
00765 start[2] += 0.5;
00766 if (AAS_PointAreaNum(start) == stopareanum)
00767 {
00768 VectorCopy(start, move->endpos);
00769 move->endarea = stopareanum;
00770 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00771 move->trace = trace;
00772 move->stopevent = SE_HITGROUNDAREA;
00773 move->presencetype = presencetype;
00774 move->endcontents = 0;
00775 move->time = n * frametime;
00776 move->frames = n;
00777 return qtrue;
00778 }
00779 }
00780 }
00781
00782 step = qfalse;
00783
00784 if (plane->normal[2] == 0 && (jump_frame < 0 || n - jump_frame > 2))
00785 {
00786
00787 VectorMA(org, -0.25, plane->normal, start);
00788 VectorCopy(start, stepend);
00789 start[2] += phys_maxstep;
00790 steptrace = AAS_TraceClientBBox(start, stepend, presencetype, entnum);
00791
00792 if (!steptrace.startsolid)
00793 {
00794 plane2 = AAS_PlaneFromNum(steptrace.planenum);
00795 if (DotProduct(plane2->normal, up) > phys_maxsteepness)
00796 {
00797 VectorSubtract(end, steptrace.endpos, left_test_vel);
00798 left_test_vel[2] = 0;
00799 frame_test_vel[2] = 0;
00800
00801 if (visualize)
00802 {
00803 if (steptrace.endpos[2] - org[2] > 0.125)
00804 {
00805 VectorCopy(org, start);
00806 start[2] = steptrace.endpos[2];
00807 AAS_DebugLine(org, start, LINECOLOR_BLUE);
00808 }
00809 }
00810
00811 org[2] = steptrace.endpos[2];
00812 step = qtrue;
00813 }
00814 }
00815 }
00816
00817 if (!step)
00818 {
00819
00820
00821 VectorMA(left_test_vel, -DotProduct(left_test_vel, plane->normal),
00822 plane->normal, left_test_vel);
00823
00824 VectorCopy(frame_test_vel, old_frame_test_vel);
00825
00826
00827 VectorMA(frame_test_vel, -DotProduct(frame_test_vel, plane->normal),
00828 plane->normal, frame_test_vel);
00829
00830 if (DotProduct(plane->normal, up) > phys_maxsteepness)
00831 {
00832 onground = qtrue;
00833 }
00834 if (stopevent & SE_HITGROUNDDAMAGE)
00835 {
00836 delta = 0;
00837 if (old_frame_test_vel[2] < 0 &&
00838 frame_test_vel[2] > old_frame_test_vel[2] &&
00839 !onground)
00840 {
00841 delta = old_frame_test_vel[2];
00842 }
00843 else if (onground)
00844 {
00845 delta = frame_test_vel[2] - old_frame_test_vel[2];
00846 }
00847 if (delta)
00848 {
00849 delta = delta * 10;
00850 delta = delta * delta * 0.0001;
00851 if (swimming) delta = 0;
00852
00853
00854
00855
00856
00857
00858 if (delta > 40)
00859 {
00860 VectorCopy(org, move->endpos);
00861 move->endarea = AAS_PointAreaNum(org);
00862 VectorCopy(frame_test_vel, move->velocity);
00863 move->trace = trace;
00864 move->stopevent = SE_HITGROUNDDAMAGE;
00865 move->presencetype = presencetype;
00866 move->endcontents = 0;
00867 move->time = n * frametime;
00868 move->frames = n;
00869 return qtrue;
00870 }
00871 }
00872 }
00873 }
00874 }
00875
00876 if (++j > 20) return qfalse;
00877
00878 } while(trace.fraction < 1.0);
00879
00880 if (frame_test_vel[2] <= 10)
00881 {
00882
00883 VectorCopy(org, feet);
00884 feet[2] -= 22;
00885 pc = AAS_PointContents(feet);
00886
00887 event = SE_NONE;
00888 if (pc & CONTENTS_LAVA) event |= SE_ENTERLAVA;
00889 if (pc & CONTENTS_SLIME) event |= SE_ENTERSLIME;
00890 if (pc & CONTENTS_WATER) event |= SE_ENTERWATER;
00891
00892 areanum = AAS_PointAreaNum(org);
00893 if (aasworld.areasettings[areanum].contents & AREACONTENTS_LAVA)
00894 event |= SE_ENTERLAVA;
00895 if (aasworld.areasettings[areanum].contents & AREACONTENTS_SLIME)
00896 event |= SE_ENTERSLIME;
00897 if (aasworld.areasettings[areanum].contents & AREACONTENTS_WATER)
00898 event |= SE_ENTERWATER;
00899
00900 if (event & stopevent)
00901 {
00902 VectorCopy(org, move->endpos);
00903 move->endarea = areanum;
00904 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00905 move->stopevent = event & stopevent;
00906 move->presencetype = presencetype;
00907 move->endcontents = pc;
00908 move->time = n * frametime;
00909 move->frames = n;
00910 return qtrue;
00911 }
00912 }
00913
00914 onground = AAS_OnGround(org, presencetype, entnum);
00915
00916 if (onground)
00917 {
00918 if (stopevent & SE_HITGROUND)
00919 {
00920 VectorCopy(org, move->endpos);
00921 move->endarea = AAS_PointAreaNum(org);
00922 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00923 move->trace = trace;
00924 move->stopevent = SE_HITGROUND;
00925 move->presencetype = presencetype;
00926 move->endcontents = 0;
00927 move->time = n * frametime;
00928 move->frames = n;
00929 return qtrue;
00930 }
00931 }
00932 else if (stopevent & SE_LEAVEGROUND)
00933 {
00934 VectorCopy(org, move->endpos);
00935 move->endarea = AAS_PointAreaNum(org);
00936 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00937 move->trace = trace;
00938 move->stopevent = SE_LEAVEGROUND;
00939 move->presencetype = presencetype;
00940 move->endcontents = 0;
00941 move->time = n * frametime;
00942 move->frames = n;
00943 return qtrue;
00944 }
00945 else if (stopevent & SE_GAP)
00946 {
00947 aas_trace_t gaptrace;
00948
00949 VectorCopy(org, start);
00950 VectorCopy(start, end);
00951 end[2] -= 48 + aassettings.phys_maxbarrier;
00952 gaptrace = AAS_TraceClientBBox(start, end, PRESENCE_CROUCH, -1);
00953
00954 if (!gaptrace.startsolid)
00955 {
00956
00957 if (gaptrace.endpos[2] < org[2] - aassettings.phys_maxstep - 1)
00958 {
00959 if (!(AAS_PointContents(end) & CONTENTS_WATER))
00960 {
00961 VectorCopy(lastorg, move->endpos);
00962 move->endarea = AAS_PointAreaNum(lastorg);
00963 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00964 move->trace = trace;
00965 move->stopevent = SE_GAP;
00966 move->presencetype = presencetype;
00967 move->endcontents = 0;
00968 move->time = n * frametime;
00969 move->frames = n;
00970 return qtrue;
00971 }
00972 }
00973 }
00974 }
00975 }
00976
00977 VectorCopy(org, move->endpos);
00978 move->endarea = AAS_PointAreaNum(org);
00979 VectorScale(frame_test_vel, 1/frametime, move->velocity);
00980 move->stopevent = SE_NONE;
00981 move->presencetype = presencetype;
00982 move->endcontents = 0;
00983 move->time = n * frametime;
00984 move->frames = n;
00985
00986 return qtrue;
00987 }
00988
00989
00990
00991
00992
00993
00994 int AAS_PredictClientMovement(struct aas_clientmove_s *move,
00995 int entnum, vec3_t origin,
00996 int presencetype, int onground,
00997 vec3_t velocity, vec3_t cmdmove,
00998 int cmdframes,
00999 int maxframes, float frametime,
01000 int stopevent, int stopareanum, int visualize)
01001 {
01002 vec3_t mins, maxs;
01003 return AAS_ClientMovementPrediction(move, entnum, origin, presencetype, onground,
01004 velocity, cmdmove, cmdframes, maxframes,
01005 frametime, stopevent, stopareanum,
01006 mins, maxs, visualize);
01007 }
01008
01009
01010
01011
01012
01013
01014 int AAS_ClientMovementHitBBox(struct aas_clientmove_s *move,
01015 int entnum, vec3_t origin,
01016 int presencetype, int onground,
01017 vec3_t velocity, vec3_t cmdmove,
01018 int cmdframes,
01019 int maxframes, float frametime,
01020 vec3_t mins, vec3_t maxs, int visualize)
01021 {
01022 return AAS_ClientMovementPrediction(move, entnum, origin, presencetype, onground,
01023 velocity, cmdmove, cmdframes, maxframes,
01024 frametime, SE_HITBOUNDINGBOX, 0,
01025 mins, maxs, visualize);
01026 }
01027
01028
01029
01030
01031
01032
01033 void AAS_TestMovementPrediction(int entnum, vec3_t origin, vec3_t dir)
01034 {
01035 vec3_t velocity, cmdmove;
01036 aas_clientmove_t move;
01037
01038 VectorClear(velocity);
01039 if (!AAS_Swimming(origin)) dir[2] = 0;
01040 VectorNormalize(dir);
01041 VectorScale(dir, 400, cmdmove);
01042 cmdmove[2] = 224;
01043 AAS_ClearShownDebugLines();
01044 AAS_PredictClientMovement(&move, entnum, origin, PRESENCE_NORMAL, qtrue,
01045 velocity, cmdmove, 13, 13, 0.1f, SE_HITGROUND, 0, qtrue);
01046 if (move.stopevent & SE_LEAVEGROUND)
01047 {
01048 botimport.Print(PRT_MESSAGE, "leave ground\n");
01049 }
01050 }
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 int AAS_HorizontalVelocityForJump(float zvel, vec3_t start, vec3_t end, float *velocity)
01063 {
01064 float phys_gravity, phys_maxvelocity;
01065 float maxjump, height2fall, t, top;
01066 vec3_t dir;
01067
01068 phys_gravity = aassettings.phys_gravity;
01069 phys_maxvelocity = aassettings.phys_maxvelocity;
01070
01071
01072 maxjump = 0.5 * phys_gravity * (zvel / phys_gravity) * (zvel / phys_gravity);
01073
01074 top = start[2] + maxjump;
01075
01076 height2fall = top - end[2];
01077
01078 if (height2fall < 0)
01079 {
01080 *velocity = phys_maxvelocity;
01081 return 0;
01082 }
01083
01084 t = sqrt(height2fall / (0.5 * phys_gravity));
01085
01086 VectorSubtract(end, start, dir);
01087
01088 if ( (t + zvel / phys_gravity) == 0.0f ) {
01089 *velocity = phys_maxvelocity;
01090 return 0;
01091 }
01092
01093 *velocity = sqrt(dir[0]*dir[0] + dir[1]*dir[1]) / (t + zvel / phys_gravity);
01094
01095 if (*velocity > phys_maxvelocity)
01096 {
01097 *velocity = phys_maxvelocity;
01098 return 0;
01099 }
01100 return 1;
01101 }