sv_phys.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // sv_phys.c
  16. #include "quakedef.h"
  17. /*
  18. pushmove objects do not obey gravity, and do not interact with each other or trigger fields, but block normal movement and push normal objects when they move.
  19. onground is set for toss objects when they come to a complete rest. it is set for steping or walking objects
  20. doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH
  21. bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS
  22. corpses are SOLID_NOT and MOVETYPE_TOSS
  23. crates are SOLID_BBOX and MOVETYPE_TOSS
  24. walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP
  25. flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY
  26. solid_edge items only clip against bsp models.
  27. */
  28. cvar_t sv_friction = {"sv_friction","4",false,true};
  29. cvar_t sv_stopspeed = {"sv_stopspeed","100"};
  30. cvar_t sv_gravity = {"sv_gravity","800",false,true};
  31. cvar_t sv_maxvelocity = {"sv_maxvelocity","2000"};
  32. cvar_t sv_nostep = {"sv_nostep","0"};
  33. #ifdef QUAKE2
  34. static vec3_t vec_origin = {0.0, 0.0, 0.0};
  35. #endif
  36. #define MOVE_EPSILON 0.01
  37. void SV_Physics_Toss (edict_t *ent);
  38. /*
  39. ================
  40. SV_CheckAllEnts
  41. ================
  42. */
  43. void SV_CheckAllEnts (void)
  44. {
  45. int e;
  46. edict_t *check;
  47. // see if any solid entities are inside the final position
  48. check = NEXT_EDICT(sv.edicts);
  49. for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
  50. {
  51. if (check->free)
  52. continue;
  53. if (check->v.movetype == MOVETYPE_PUSH
  54. || check->v.movetype == MOVETYPE_NONE
  55. #ifdef QUAKE2
  56. || check->v.movetype == MOVETYPE_FOLLOW
  57. #endif
  58. || check->v.movetype == MOVETYPE_NOCLIP)
  59. continue;
  60. if (SV_TestEntityPosition (check))
  61. Con_Printf ("entity in invalid position\n");
  62. }
  63. }
  64. /*
  65. ================
  66. SV_CheckVelocity
  67. ================
  68. */
  69. void SV_CheckVelocity (edict_t *ent)
  70. {
  71. int i;
  72. //
  73. // bound velocity
  74. //
  75. for (i=0 ; i<3 ; i++)
  76. {
  77. if (IS_NAN(ent->v.velocity[i]))
  78. {
  79. Con_Printf ("Got a NaN velocity on %s\n", pr_strings + ent->v.classname);
  80. ent->v.velocity[i] = 0;
  81. }
  82. if (IS_NAN(ent->v.origin[i]))
  83. {
  84. Con_Printf ("Got a NaN origin on %s\n", pr_strings + ent->v.classname);
  85. ent->v.origin[i] = 0;
  86. }
  87. if (ent->v.velocity[i] > sv_maxvelocity.value)
  88. ent->v.velocity[i] = sv_maxvelocity.value;
  89. else if (ent->v.velocity[i] < -sv_maxvelocity.value)
  90. ent->v.velocity[i] = -sv_maxvelocity.value;
  91. }
  92. }
  93. /*
  94. =============
  95. SV_RunThink
  96. Runs thinking code if time. There is some play in the exact time the think
  97. function will be called, because it is called before any movement is done
  98. in a frame. Not used for pushmove objects, because they must be exact.
  99. Returns false if the entity removed itself.
  100. =============
  101. */
  102. qboolean SV_RunThink (edict_t *ent)
  103. {
  104. float thinktime;
  105. thinktime = ent->v.nextthink;
  106. if (thinktime <= 0 || thinktime > sv.time + host_frametime)
  107. return true;
  108. if (thinktime < sv.time)
  109. thinktime = sv.time; // don't let things stay in the past.
  110. // it is possible to start that way
  111. // by a trigger with a local time.
  112. ent->v.nextthink = 0;
  113. pr_global_struct->time = thinktime;
  114. pr_global_struct->self = EDICT_TO_PROG(ent);
  115. pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
  116. PR_ExecuteProgram (ent->v.think);
  117. return !ent->free;
  118. }
  119. /*
  120. ==================
  121. SV_Impact
  122. Two entities have touched, so run their touch functions
  123. ==================
  124. */
  125. void SV_Impact (edict_t *e1, edict_t *e2)
  126. {
  127. int old_self, old_other;
  128. old_self = pr_global_struct->self;
  129. old_other = pr_global_struct->other;
  130. pr_global_struct->time = sv.time;
  131. if (e1->v.touch && e1->v.solid != SOLID_NOT)
  132. {
  133. pr_global_struct->self = EDICT_TO_PROG(e1);
  134. pr_global_struct->other = EDICT_TO_PROG(e2);
  135. PR_ExecuteProgram (e1->v.touch);
  136. }
  137. if (e2->v.touch && e2->v.solid != SOLID_NOT)
  138. {
  139. pr_global_struct->self = EDICT_TO_PROG(e2);
  140. pr_global_struct->other = EDICT_TO_PROG(e1);
  141. PR_ExecuteProgram (e2->v.touch);
  142. }
  143. pr_global_struct->self = old_self;
  144. pr_global_struct->other = old_other;
  145. }
  146. /*
  147. ==================
  148. ClipVelocity
  149. Slide off of the impacting object
  150. returns the blocked flags (1 = floor, 2 = step / wall)
  151. ==================
  152. */
  153. #define STOP_EPSILON 0.1
  154. int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
  155. {
  156. float backoff;
  157. float change;
  158. int i, blocked;
  159. blocked = 0;
  160. if (normal[2] > 0)
  161. blocked |= 1; // floor
  162. if (!normal[2])
  163. blocked |= 2; // step
  164. backoff = DotProduct (in, normal) * overbounce;
  165. for (i=0 ; i<3 ; i++)
  166. {
  167. change = normal[i]*backoff;
  168. out[i] = in[i] - change;
  169. if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
  170. out[i] = 0;
  171. }
  172. return blocked;
  173. }
  174. /*
  175. ============
  176. SV_FlyMove
  177. The basic solid body movement clip that slides along multiple planes
  178. Returns the clipflags if the velocity was modified (hit something solid)
  179. 1 = floor
  180. 2 = wall / step
  181. 4 = dead stop
  182. If steptrace is not NULL, the trace of any vertical wall hit will be stored
  183. ============
  184. */
  185. #define MAX_CLIP_PLANES 5
  186. int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
  187. {
  188. int bumpcount, numbumps;
  189. vec3_t dir;
  190. float d;
  191. int numplanes;
  192. vec3_t planes[MAX_CLIP_PLANES];
  193. vec3_t primal_velocity, original_velocity, new_velocity;
  194. int i, j;
  195. trace_t trace;
  196. vec3_t end;
  197. float time_left;
  198. int blocked;
  199. numbumps = 4;
  200. blocked = 0;
  201. VectorCopy (ent->v.velocity, original_velocity);
  202. VectorCopy (ent->v.velocity, primal_velocity);
  203. numplanes = 0;
  204. time_left = time;
  205. for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
  206. {
  207. if (!ent->v.velocity[0] && !ent->v.velocity[1] && !ent->v.velocity[2])
  208. break;
  209. for (i=0 ; i<3 ; i++)
  210. end[i] = ent->v.origin[i] + time_left * ent->v.velocity[i];
  211. trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
  212. if (trace.allsolid)
  213. { // entity is trapped in another solid
  214. VectorCopy (vec3_origin, ent->v.velocity);
  215. return 3;
  216. }
  217. if (trace.fraction > 0)
  218. { // actually covered some distance
  219. VectorCopy (trace.endpos, ent->v.origin);
  220. VectorCopy (ent->v.velocity, original_velocity);
  221. numplanes = 0;
  222. }
  223. if (trace.fraction == 1)
  224. break; // moved the entire distance
  225. if (!trace.ent)
  226. Sys_Error ("SV_FlyMove: !trace.ent");
  227. if (trace.plane.normal[2] > 0.7)
  228. {
  229. blocked |= 1; // floor
  230. if (trace.ent->v.solid == SOLID_BSP)
  231. {
  232. ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
  233. ent->v.groundentity = EDICT_TO_PROG(trace.ent);
  234. }
  235. }
  236. if (!trace.plane.normal[2])
  237. {
  238. blocked |= 2; // step
  239. if (steptrace)
  240. *steptrace = trace; // save for player extrafriction
  241. }
  242. //
  243. // run the impact function
  244. //
  245. SV_Impact (ent, trace.ent);
  246. if (ent->free)
  247. break; // removed by the impact function
  248. time_left -= time_left * trace.fraction;
  249. // cliped to another plane
  250. if (numplanes >= MAX_CLIP_PLANES)
  251. { // this shouldn't really happen
  252. VectorCopy (vec3_origin, ent->v.velocity);
  253. return 3;
  254. }
  255. VectorCopy (trace.plane.normal, planes[numplanes]);
  256. numplanes++;
  257. //
  258. // modify original_velocity so it parallels all of the clip planes
  259. //
  260. for (i=0 ; i<numplanes ; i++)
  261. {
  262. ClipVelocity (original_velocity, planes[i], new_velocity, 1);
  263. for (j=0 ; j<numplanes ; j++)
  264. if (j != i)
  265. {
  266. if (DotProduct (new_velocity, planes[j]) < 0)
  267. break; // not ok
  268. }
  269. if (j == numplanes)
  270. break;
  271. }
  272. if (i != numplanes)
  273. { // go along this plane
  274. VectorCopy (new_velocity, ent->v.velocity);
  275. }
  276. else
  277. { // go along the crease
  278. if (numplanes != 2)
  279. {
  280. // Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
  281. VectorCopy (vec3_origin, ent->v.velocity);
  282. return 7;
  283. }
  284. CrossProduct (planes[0], planes[1], dir);
  285. d = DotProduct (dir, ent->v.velocity);
  286. VectorScale (dir, d, ent->v.velocity);
  287. }
  288. //
  289. // if original velocity is against the original velocity, stop dead
  290. // to avoid tiny occilations in sloping corners
  291. //
  292. if (DotProduct (ent->v.velocity, primal_velocity) <= 0)
  293. {
  294. VectorCopy (vec3_origin, ent->v.velocity);
  295. return blocked;
  296. }
  297. }
  298. return blocked;
  299. }
  300. /*
  301. ============
  302. SV_AddGravity
  303. ============
  304. */
  305. void SV_AddGravity (edict_t *ent)
  306. {
  307. float ent_gravity;
  308. #ifdef QUAKE2
  309. if (ent->v.gravity)
  310. ent_gravity = ent->v.gravity;
  311. else
  312. ent_gravity = 1.0;
  313. #else
  314. eval_t *val;
  315. val = GetEdictFieldValue(ent, "gravity");
  316. if (val && val->_float)
  317. ent_gravity = val->_float;
  318. else
  319. ent_gravity = 1.0;
  320. #endif
  321. ent->v.velocity[2] -= ent_gravity * sv_gravity.value * host_frametime;
  322. }
  323. /*
  324. ===============================================================================
  325. PUSHMOVE
  326. ===============================================================================
  327. */
  328. /*
  329. ============
  330. SV_PushEntity
  331. Does not change the entities velocity at all
  332. ============
  333. */
  334. trace_t SV_PushEntity (edict_t *ent, vec3_t push)
  335. {
  336. trace_t trace;
  337. vec3_t end;
  338. VectorAdd (ent->v.origin, push, end);
  339. if (ent->v.movetype == MOVETYPE_FLYMISSILE)
  340. trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, ent);
  341. else if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT)
  342. // only clip against bmodels
  343. trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent);
  344. else
  345. trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
  346. VectorCopy (trace.endpos, ent->v.origin);
  347. SV_LinkEdict (ent, true);
  348. if (trace.ent)
  349. SV_Impact (ent, trace.ent);
  350. return trace;
  351. }
  352. /*
  353. ============
  354. SV_PushMove
  355. ============
  356. */
  357. void SV_PushMove (edict_t *pusher, float movetime)
  358. {
  359. int i, e;
  360. edict_t *check, *block;
  361. vec3_t mins, maxs, move;
  362. vec3_t entorig, pushorig;
  363. int num_moved;
  364. edict_t *moved_edict[MAX_EDICTS];
  365. vec3_t moved_from[MAX_EDICTS];
  366. if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
  367. {
  368. pusher->v.ltime += movetime;
  369. return;
  370. }
  371. for (i=0 ; i<3 ; i++)
  372. {
  373. move[i] = pusher->v.velocity[i] * movetime;
  374. mins[i] = pusher->v.absmin[i] + move[i];
  375. maxs[i] = pusher->v.absmax[i] + move[i];
  376. }
  377. VectorCopy (pusher->v.origin, pushorig);
  378. // move the pusher to it's final position
  379. VectorAdd (pusher->v.origin, move, pusher->v.origin);
  380. pusher->v.ltime += movetime;
  381. SV_LinkEdict (pusher, false);
  382. // see if any solid entities are inside the final position
  383. num_moved = 0;
  384. check = NEXT_EDICT(sv.edicts);
  385. for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
  386. {
  387. if (check->free)
  388. continue;
  389. if (check->v.movetype == MOVETYPE_PUSH
  390. || check->v.movetype == MOVETYPE_NONE
  391. #ifdef QUAKE2
  392. || check->v.movetype == MOVETYPE_FOLLOW
  393. #endif
  394. || check->v.movetype == MOVETYPE_NOCLIP)
  395. continue;
  396. // if the entity is standing on the pusher, it will definately be moved
  397. if ( ! ( ((int)check->v.flags & FL_ONGROUND)
  398. && PROG_TO_EDICT(check->v.groundentity) == pusher) )
  399. {
  400. if ( check->v.absmin[0] >= maxs[0]
  401. || check->v.absmin[1] >= maxs[1]
  402. || check->v.absmin[2] >= maxs[2]
  403. || check->v.absmax[0] <= mins[0]
  404. || check->v.absmax[1] <= mins[1]
  405. || check->v.absmax[2] <= mins[2] )
  406. continue;
  407. // see if the ent's bbox is inside the pusher's final position
  408. if (!SV_TestEntityPosition (check))
  409. continue;
  410. }
  411. // remove the onground flag for non-players
  412. if (check->v.movetype != MOVETYPE_WALK)
  413. check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
  414. VectorCopy (check->v.origin, entorig);
  415. VectorCopy (check->v.origin, moved_from[num_moved]);
  416. moved_edict[num_moved] = check;
  417. num_moved++;
  418. // try moving the contacted entity
  419. pusher->v.solid = SOLID_NOT;
  420. SV_PushEntity (check, move);
  421. pusher->v.solid = SOLID_BSP;
  422. // if it is still inside the pusher, block
  423. block = SV_TestEntityPosition (check);
  424. if (block)
  425. { // fail the move
  426. if (check->v.mins[0] == check->v.maxs[0])
  427. continue;
  428. if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
  429. { // corpse
  430. check->v.mins[0] = check->v.mins[1] = 0;
  431. VectorCopy (check->v.mins, check->v.maxs);
  432. continue;
  433. }
  434. VectorCopy (entorig, check->v.origin);
  435. SV_LinkEdict (check, true);
  436. VectorCopy (pushorig, pusher->v.origin);
  437. SV_LinkEdict (pusher, false);
  438. pusher->v.ltime -= movetime;
  439. // if the pusher has a "blocked" function, call it
  440. // otherwise, just stay in place until the obstacle is gone
  441. if (pusher->v.blocked)
  442. {
  443. pr_global_struct->self = EDICT_TO_PROG(pusher);
  444. pr_global_struct->other = EDICT_TO_PROG(check);
  445. PR_ExecuteProgram (pusher->v.blocked);
  446. }
  447. // move back any entities we already moved
  448. for (i=0 ; i<num_moved ; i++)
  449. {
  450. VectorCopy (moved_from[i], moved_edict[i]->v.origin);
  451. SV_LinkEdict (moved_edict[i], false);
  452. }
  453. return;
  454. }
  455. }
  456. }
  457. #ifdef QUAKE2
  458. /*
  459. ============
  460. SV_PushRotate
  461. ============
  462. */
  463. void SV_PushRotate (edict_t *pusher, float movetime)
  464. {
  465. int i, e;
  466. edict_t *check, *block;
  467. vec3_t move, a, amove;
  468. vec3_t entorig, pushorig;
  469. int num_moved;
  470. edict_t *moved_edict[MAX_EDICTS];
  471. vec3_t moved_from[MAX_EDICTS];
  472. vec3_t org, org2;
  473. vec3_t forward, right, up;
  474. if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] && !pusher->v.avelocity[2])
  475. {
  476. pusher->v.ltime += movetime;
  477. return;
  478. }
  479. for (i=0 ; i<3 ; i++)
  480. amove[i] = pusher->v.avelocity[i] * movetime;
  481. VectorSubtract (vec3_origin, amove, a);
  482. AngleVectors (a, forward, right, up);
  483. VectorCopy (pusher->v.angles, pushorig);
  484. // move the pusher to it's final position
  485. VectorAdd (pusher->v.angles, amove, pusher->v.angles);
  486. pusher->v.ltime += movetime;
  487. SV_LinkEdict (pusher, false);
  488. // see if any solid entities are inside the final position
  489. num_moved = 0;
  490. check = NEXT_EDICT(sv.edicts);
  491. for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
  492. {
  493. if (check->free)
  494. continue;
  495. if (check->v.movetype == MOVETYPE_PUSH
  496. || check->v.movetype == MOVETYPE_NONE
  497. || check->v.movetype == MOVETYPE_FOLLOW
  498. || check->v.movetype == MOVETYPE_NOCLIP)
  499. continue;
  500. // if the entity is standing on the pusher, it will definately be moved
  501. if ( ! ( ((int)check->v.flags & FL_ONGROUND)
  502. && PROG_TO_EDICT(check->v.groundentity) == pusher) )
  503. {
  504. if ( check->v.absmin[0] >= pusher->v.absmax[0]
  505. || check->v.absmin[1] >= pusher->v.absmax[1]
  506. || check->v.absmin[2] >= pusher->v.absmax[2]
  507. || check->v.absmax[0] <= pusher->v.absmin[0]
  508. || check->v.absmax[1] <= pusher->v.absmin[1]
  509. || check->v.absmax[2] <= pusher->v.absmin[2] )
  510. continue;
  511. // see if the ent's bbox is inside the pusher's final position
  512. if (!SV_TestEntityPosition (check))
  513. continue;
  514. }
  515. // remove the onground flag for non-players
  516. if (check->v.movetype != MOVETYPE_WALK)
  517. check->v.flags = (int)check->v.flags & ~FL_ONGROUND;
  518. VectorCopy (check->v.origin, entorig);
  519. VectorCopy (check->v.origin, moved_from[num_moved]);
  520. moved_edict[num_moved] = check;
  521. num_moved++;
  522. // calculate destination position
  523. VectorSubtract (check->v.origin, pusher->v.origin, org);
  524. org2[0] = DotProduct (org, forward);
  525. org2[1] = -DotProduct (org, right);
  526. org2[2] = DotProduct (org, up);
  527. VectorSubtract (org2, org, move);
  528. // try moving the contacted entity
  529. pusher->v.solid = SOLID_NOT;
  530. SV_PushEntity (check, move);
  531. pusher->v.solid = SOLID_BSP;
  532. // if it is still inside the pusher, block
  533. block = SV_TestEntityPosition (check);
  534. if (block)
  535. { // fail the move
  536. if (check->v.mins[0] == check->v.maxs[0])
  537. continue;
  538. if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
  539. { // corpse
  540. check->v.mins[0] = check->v.mins[1] = 0;
  541. VectorCopy (check->v.mins, check->v.maxs);
  542. continue;
  543. }
  544. VectorCopy (entorig, check->v.origin);
  545. SV_LinkEdict (check, true);
  546. VectorCopy (pushorig, pusher->v.angles);
  547. SV_LinkEdict (pusher, false);
  548. pusher->v.ltime -= movetime;
  549. // if the pusher has a "blocked" function, call it
  550. // otherwise, just stay in place until the obstacle is gone
  551. if (pusher->v.blocked)
  552. {
  553. pr_global_struct->self = EDICT_TO_PROG(pusher);
  554. pr_global_struct->other = EDICT_TO_PROG(check);
  555. PR_ExecuteProgram (pusher->v.blocked);
  556. }
  557. // move back any entities we already moved
  558. for (i=0 ; i<num_moved ; i++)
  559. {
  560. VectorCopy (moved_from[i], moved_edict[i]->v.origin);
  561. VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles);
  562. SV_LinkEdict (moved_edict[i], false);
  563. }
  564. return;
  565. }
  566. else
  567. {
  568. VectorAdd (check->v.angles, amove, check->v.angles);
  569. }
  570. }
  571. }
  572. #endif
  573. /*
  574. ================
  575. SV_Physics_Pusher
  576. ================
  577. */
  578. void SV_Physics_Pusher (edict_t *ent)
  579. {
  580. float thinktime;
  581. float oldltime;
  582. float movetime;
  583. oldltime = ent->v.ltime;
  584. thinktime = ent->v.nextthink;
  585. if (thinktime < ent->v.ltime + host_frametime)
  586. {
  587. movetime = thinktime - ent->v.ltime;
  588. if (movetime < 0)
  589. movetime = 0;
  590. }
  591. else
  592. movetime = host_frametime;
  593. if (movetime)
  594. {
  595. #ifdef QUAKE2
  596. if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2])
  597. SV_PushRotate (ent, movetime);
  598. else
  599. #endif
  600. SV_PushMove (ent, movetime); // advances ent->v.ltime if not blocked
  601. }
  602. if (thinktime > oldltime && thinktime <= ent->v.ltime)
  603. {
  604. ent->v.nextthink = 0;
  605. pr_global_struct->time = sv.time;
  606. pr_global_struct->self = EDICT_TO_PROG(ent);
  607. pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
  608. PR_ExecuteProgram (ent->v.think);
  609. if (ent->free)
  610. return;
  611. }
  612. }
  613. /*
  614. ===============================================================================
  615. CLIENT MOVEMENT
  616. ===============================================================================
  617. */
  618. /*
  619. =============
  620. SV_CheckStuck
  621. This is a big hack to try and fix the rare case of getting stuck in the world
  622. clipping hull.
  623. =============
  624. */
  625. void SV_CheckStuck (edict_t *ent)
  626. {
  627. int i, j;
  628. int z;
  629. vec3_t org;
  630. if (!SV_TestEntityPosition(ent))
  631. {
  632. VectorCopy (ent->v.origin, ent->v.oldorigin);
  633. return;
  634. }
  635. VectorCopy (ent->v.origin, org);
  636. VectorCopy (ent->v.oldorigin, ent->v.origin);
  637. if (!SV_TestEntityPosition(ent))
  638. {
  639. Con_DPrintf ("Unstuck.\n");
  640. SV_LinkEdict (ent, true);
  641. return;
  642. }
  643. for (z=0 ; z< 18 ; z++)
  644. for (i=-1 ; i <= 1 ; i++)
  645. for (j=-1 ; j <= 1 ; j++)
  646. {
  647. ent->v.origin[0] = org[0] + i;
  648. ent->v.origin[1] = org[1] + j;
  649. ent->v.origin[2] = org[2] + z;
  650. if (!SV_TestEntityPosition(ent))
  651. {
  652. Con_DPrintf ("Unstuck.\n");
  653. SV_LinkEdict (ent, true);
  654. return;
  655. }
  656. }
  657. VectorCopy (org, ent->v.origin);
  658. Con_DPrintf ("player is stuck.\n");
  659. }
  660. /*
  661. =============
  662. SV_CheckWater
  663. =============
  664. */
  665. qboolean SV_CheckWater (edict_t *ent)
  666. {
  667. vec3_t point;
  668. int cont;
  669. #ifdef QUAKE2
  670. int truecont;
  671. #endif
  672. point[0] = ent->v.origin[0];
  673. point[1] = ent->v.origin[1];
  674. point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;
  675. ent->v.waterlevel = 0;
  676. ent->v.watertype = CONTENTS_EMPTY;
  677. cont = SV_PointContents (point);
  678. if (cont <= CONTENTS_WATER)
  679. {
  680. #ifdef QUAKE2
  681. truecont = SV_TruePointContents (point);
  682. #endif
  683. ent->v.watertype = cont;
  684. ent->v.waterlevel = 1;
  685. point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2])*0.5;
  686. cont = SV_PointContents (point);
  687. if (cont <= CONTENTS_WATER)
  688. {
  689. ent->v.waterlevel = 2;
  690. point[2] = ent->v.origin[2] + ent->v.view_ofs[2];
  691. cont = SV_PointContents (point);
  692. if (cont <= CONTENTS_WATER)
  693. ent->v.waterlevel = 3;
  694. }
  695. #ifdef QUAKE2
  696. if (truecont <= CONTENTS_CURRENT_0 && truecont >= CONTENTS_CURRENT_DOWN)
  697. {
  698. static vec3_t current_table[] =
  699. {
  700. {1, 0, 0},
  701. {0, 1, 0},
  702. {-1, 0, 0},
  703. {0, -1, 0},
  704. {0, 0, 1},
  705. {0, 0, -1}
  706. };
  707. VectorMA (ent->v.basevelocity, 150.0*ent->v.waterlevel/3.0, current_table[CONTENTS_CURRENT_0 - truecont], ent->v.basevelocity);
  708. }
  709. #endif
  710. }
  711. return ent->v.waterlevel > 1;
  712. }
  713. /*
  714. ============
  715. SV_WallFriction
  716. ============
  717. */
  718. void SV_WallFriction (edict_t *ent, trace_t *trace)
  719. {
  720. vec3_t forward, right, up;
  721. float d, i;
  722. vec3_t into, side;
  723. AngleVectors (ent->v.v_angle, forward, right, up);
  724. d = DotProduct (trace->plane.normal, forward);
  725. d += 0.5;
  726. if (d >= 0)
  727. return;
  728. // cut the tangential velocity
  729. i = DotProduct (trace->plane.normal, ent->v.velocity);
  730. VectorScale (trace->plane.normal, i, into);
  731. VectorSubtract (ent->v.velocity, into, side);
  732. ent->v.velocity[0] = side[0] * (1 + d);
  733. ent->v.velocity[1] = side[1] * (1 + d);
  734. }
  735. /*
  736. =====================
  737. SV_TryUnstick
  738. Player has come to a dead stop, possibly due to the problem with limited
  739. float precision at some angle joins in the BSP hull.
  740. Try fixing by pushing one pixel in each direction.
  741. This is a hack, but in the interest of good gameplay...
  742. ======================
  743. */
  744. int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
  745. {
  746. int i;
  747. vec3_t oldorg;
  748. vec3_t dir;
  749. int clip;
  750. trace_t steptrace;
  751. VectorCopy (ent->v.origin, oldorg);
  752. VectorCopy (vec3_origin, dir);
  753. for (i=0 ; i<8 ; i++)
  754. {
  755. // try pushing a little in an axial direction
  756. switch (i)
  757. {
  758. case 0: dir[0] = 2; dir[1] = 0; break;
  759. case 1: dir[0] = 0; dir[1] = 2; break;
  760. case 2: dir[0] = -2; dir[1] = 0; break;
  761. case 3: dir[0] = 0; dir[1] = -2; break;
  762. case 4: dir[0] = 2; dir[1] = 2; break;
  763. case 5: dir[0] = -2; dir[1] = 2; break;
  764. case 6: dir[0] = 2; dir[1] = -2; break;
  765. case 7: dir[0] = -2; dir[1] = -2; break;
  766. }
  767. SV_PushEntity (ent, dir);
  768. // retry the original move
  769. ent->v.velocity[0] = oldvel[0];
  770. ent->v. velocity[1] = oldvel[1];
  771. ent->v. velocity[2] = 0;
  772. clip = SV_FlyMove (ent, 0.1, &steptrace);
  773. if ( fabs(oldorg[1] - ent->v.origin[1]) > 4
  774. || fabs(oldorg[0] - ent->v.origin[0]) > 4 )
  775. {
  776. //Con_DPrintf ("unstuck!\n");
  777. return clip;
  778. }
  779. // go back to the original pos and try again
  780. VectorCopy (oldorg, ent->v.origin);
  781. }
  782. VectorCopy (vec3_origin, ent->v.velocity);
  783. return 7; // still not moving
  784. }
  785. /*
  786. =====================
  787. SV_WalkMove
  788. Only used by players
  789. ======================
  790. */
  791. #define STEPSIZE 18
  792. void SV_WalkMove (edict_t *ent)
  793. {
  794. vec3_t upmove, downmove;
  795. vec3_t oldorg, oldvel;
  796. vec3_t nosteporg, nostepvel;
  797. int clip;
  798. int oldonground;
  799. trace_t steptrace, downtrace;
  800. //
  801. // do a regular slide move unless it looks like you ran into a step
  802. //
  803. oldonground = (int)ent->v.flags & FL_ONGROUND;
  804. ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
  805. VectorCopy (ent->v.origin, oldorg);
  806. VectorCopy (ent->v.velocity, oldvel);
  807. clip = SV_FlyMove (ent, host_frametime, &steptrace);
  808. if ( !(clip & 2) )
  809. return; // move didn't block on a step
  810. if (!oldonground && ent->v.waterlevel == 0)
  811. return; // don't stair up while jumping
  812. if (ent->v.movetype != MOVETYPE_WALK)
  813. return; // gibbed by a trigger
  814. if (sv_nostep.value)
  815. return;
  816. if ( (int)sv_player->v.flags & FL_WATERJUMP )
  817. return;
  818. VectorCopy (ent->v.origin, nosteporg);
  819. VectorCopy (ent->v.velocity, nostepvel);
  820. //
  821. // try moving up and forward to go up a step
  822. //
  823. VectorCopy (oldorg, ent->v.origin); // back to start pos
  824. VectorCopy (vec3_origin, upmove);
  825. VectorCopy (vec3_origin, downmove);
  826. upmove[2] = STEPSIZE;
  827. downmove[2] = -STEPSIZE + oldvel[2]*host_frametime;
  828. // move up
  829. SV_PushEntity (ent, upmove); // FIXME: don't link?
  830. // move forward
  831. ent->v.velocity[0] = oldvel[0];
  832. ent->v. velocity[1] = oldvel[1];
  833. ent->v. velocity[2] = 0;
  834. clip = SV_FlyMove (ent, host_frametime, &steptrace);
  835. // check for stuckness, possibly due to the limited precision of floats
  836. // in the clipping hulls
  837. if (clip)
  838. {
  839. if ( fabs(oldorg[1] - ent->v.origin[1]) < 0.03125
  840. && fabs(oldorg[0] - ent->v.origin[0]) < 0.03125 )
  841. { // stepping up didn't make any progress
  842. clip = SV_TryUnstick (ent, oldvel);
  843. }
  844. }
  845. // extra friction based on view angle
  846. if ( clip & 2 )
  847. SV_WallFriction (ent, &steptrace);
  848. // move down
  849. downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link?
  850. if (downtrace.plane.normal[2] > 0.7)
  851. {
  852. if (ent->v.solid == SOLID_BSP)
  853. {
  854. ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
  855. ent->v.groundentity = EDICT_TO_PROG(downtrace.ent);
  856. }
  857. }
  858. else
  859. {
  860. // if the push down didn't end up on good ground, use the move without
  861. // the step up. This happens near wall / slope combinations, and can
  862. // cause the player to hop up higher on a slope too steep to climb
  863. VectorCopy (nosteporg, ent->v.origin);
  864. VectorCopy (nostepvel, ent->v.velocity);
  865. }
  866. }
  867. /*
  868. ================
  869. SV_Physics_Client
  870. Player character actions
  871. ================
  872. */
  873. void SV_Physics_Client (edict_t *ent, int num)
  874. {
  875. if ( ! svs.clients[num-1].active )
  876. return; // unconnected slot
  877. //
  878. // call standard client pre-think
  879. //
  880. pr_global_struct->time = sv.time;
  881. pr_global_struct->self = EDICT_TO_PROG(ent);
  882. PR_ExecuteProgram (pr_global_struct->PlayerPreThink);
  883. //
  884. // do a move
  885. //
  886. SV_CheckVelocity (ent);
  887. //
  888. // decide which move function to call
  889. //
  890. switch ((int)ent->v.movetype)
  891. {
  892. case MOVETYPE_NONE:
  893. if (!SV_RunThink (ent))
  894. return;
  895. break;
  896. case MOVETYPE_WALK:
  897. if (!SV_RunThink (ent))
  898. return;
  899. if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
  900. SV_AddGravity (ent);
  901. SV_CheckStuck (ent);
  902. #ifdef QUAKE2
  903. VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
  904. #endif
  905. SV_WalkMove (ent);
  906. #ifdef QUAKE2
  907. VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
  908. #endif
  909. break;
  910. case MOVETYPE_TOSS:
  911. case MOVETYPE_BOUNCE:
  912. SV_Physics_Toss (ent);
  913. break;
  914. case MOVETYPE_FLY:
  915. if (!SV_RunThink (ent))
  916. return;
  917. SV_FlyMove (ent, host_frametime, NULL);
  918. break;
  919. case MOVETYPE_NOCLIP:
  920. if (!SV_RunThink (ent))
  921. return;
  922. VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin);
  923. break;
  924. default:
  925. Sys_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype);
  926. }
  927. //
  928. // call standard player post-think
  929. //
  930. SV_LinkEdict (ent, true);
  931. pr_global_struct->time = sv.time;
  932. pr_global_struct->self = EDICT_TO_PROG(ent);
  933. PR_ExecuteProgram (pr_global_struct->PlayerPostThink);
  934. }
  935. //============================================================================
  936. /*
  937. =============
  938. SV_Physics_None
  939. Non moving objects can only think
  940. =============
  941. */
  942. void SV_Physics_None (edict_t *ent)
  943. {
  944. // regular thinking
  945. SV_RunThink (ent);
  946. }
  947. #ifdef QUAKE2
  948. /*
  949. =============
  950. SV_Physics_Follow
  951. Entities that are "stuck" to another entity
  952. =============
  953. */
  954. void SV_Physics_Follow (edict_t *ent)
  955. {
  956. // regular thinking
  957. SV_RunThink (ent);
  958. VectorAdd (PROG_TO_EDICT(ent->v.aiment)->v.origin, ent->v.v_angle, ent->v.origin);
  959. SV_LinkEdict (ent, true);
  960. }
  961. #endif
  962. /*
  963. =============
  964. SV_Physics_Noclip
  965. A moving object that doesn't obey physics
  966. =============
  967. */
  968. void SV_Physics_Noclip (edict_t *ent)
  969. {
  970. // regular thinking
  971. if (!SV_RunThink (ent))
  972. return;
  973. VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles);
  974. VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin);
  975. SV_LinkEdict (ent, false);
  976. }
  977. /*
  978. ==============================================================================
  979. TOSS / BOUNCE
  980. ==============================================================================
  981. */
  982. /*
  983. =============
  984. SV_CheckWaterTransition
  985. =============
  986. */
  987. void SV_CheckWaterTransition (edict_t *ent)
  988. {
  989. int cont;
  990. #ifdef QUAKE2
  991. vec3_t point;
  992. point[0] = ent->v.origin[0];
  993. point[1] = ent->v.origin[1];
  994. point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;
  995. cont = SV_PointContents (point);
  996. #else
  997. cont = SV_PointContents (ent->v.origin);
  998. #endif
  999. if (!ent->v.watertype)
  1000. { // just spawned here
  1001. ent->v.watertype = cont;
  1002. ent->v.waterlevel = 1;
  1003. return;
  1004. }
  1005. if (cont <= CONTENTS_WATER)
  1006. {
  1007. if (ent->v.watertype == CONTENTS_EMPTY)
  1008. { // just crossed into water
  1009. SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
  1010. }
  1011. ent->v.watertype = cont;
  1012. ent->v.waterlevel = 1;
  1013. }
  1014. else
  1015. {
  1016. if (ent->v.watertype != CONTENTS_EMPTY)
  1017. { // just crossed into water
  1018. SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
  1019. }
  1020. ent->v.watertype = CONTENTS_EMPTY;
  1021. ent->v.waterlevel = cont;
  1022. }
  1023. }
  1024. /*
  1025. =============
  1026. SV_Physics_Toss
  1027. Toss, bounce, and fly movement. When onground, do nothing.
  1028. =============
  1029. */
  1030. void SV_Physics_Toss (edict_t *ent)
  1031. {
  1032. trace_t trace;
  1033. vec3_t move;
  1034. float backoff;
  1035. #ifdef QUAKE2
  1036. edict_t *groundentity;
  1037. groundentity = PROG_TO_EDICT(ent->v.groundentity);
  1038. if ((int)groundentity->v.flags & FL_CONVEYOR)
  1039. VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity);
  1040. else
  1041. VectorCopy(vec_origin, ent->v.basevelocity);
  1042. SV_CheckWater (ent);
  1043. #endif
  1044. // regular thinking
  1045. if (!SV_RunThink (ent))
  1046. return;
  1047. #ifdef QUAKE2
  1048. if (ent->v.velocity[2] > 0)
  1049. ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
  1050. if ( ((int)ent->v.flags & FL_ONGROUND) )
  1051. //@@
  1052. if (VectorCompare(ent->v.basevelocity, vec_origin))
  1053. return;
  1054. SV_CheckVelocity (ent);
  1055. // add gravity
  1056. if (! ((int)ent->v.flags & FL_ONGROUND)
  1057. && ent->v.movetype != MOVETYPE_FLY
  1058. && ent->v.movetype != MOVETYPE_BOUNCEMISSILE
  1059. && ent->v.movetype != MOVETYPE_FLYMISSILE)
  1060. SV_AddGravity (ent);
  1061. #else
  1062. // if onground, return without moving
  1063. if ( ((int)ent->v.flags & FL_ONGROUND) )
  1064. return;
  1065. SV_CheckVelocity (ent);
  1066. // add gravity
  1067. if (ent->v.movetype != MOVETYPE_FLY
  1068. && ent->v.movetype != MOVETYPE_FLYMISSILE)
  1069. SV_AddGravity (ent);
  1070. #endif
  1071. // move angles
  1072. VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles);
  1073. // move origin
  1074. #ifdef QUAKE2
  1075. VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
  1076. #endif
  1077. VectorScale (ent->v.velocity, host_frametime, move);
  1078. trace = SV_PushEntity (ent, move);
  1079. #ifdef QUAKE2
  1080. VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
  1081. #endif
  1082. if (trace.fraction == 1)
  1083. return;
  1084. if (ent->free)
  1085. return;
  1086. if (ent->v.movetype == MOVETYPE_BOUNCE)
  1087. backoff = 1.5;
  1088. #ifdef QUAKE2
  1089. else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE)
  1090. backoff = 2.0;
  1091. #endif
  1092. else
  1093. backoff = 1;
  1094. ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff);
  1095. // stop if on ground
  1096. if (trace.plane.normal[2] > 0.7)
  1097. {
  1098. #ifdef QUAKE2
  1099. if (ent->v.velocity[2] < 60 || (ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_BOUNCEMISSILE))
  1100. #else
  1101. if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE)
  1102. #endif
  1103. {
  1104. ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
  1105. ent->v.groundentity = EDICT_TO_PROG(trace.ent);
  1106. VectorCopy (vec3_origin, ent->v.velocity);
  1107. VectorCopy (vec3_origin, ent->v.avelocity);
  1108. }
  1109. }
  1110. // check for in water
  1111. SV_CheckWaterTransition (ent);
  1112. }
  1113. /*
  1114. ===============================================================================
  1115. STEPPING MOVEMENT
  1116. ===============================================================================
  1117. */
  1118. /*
  1119. =============
  1120. SV_Physics_Step
  1121. Monsters freefall when they don't have a ground entity, otherwise
  1122. all movement is done with discrete steps.
  1123. This is also used for objects that have become still on the ground, but
  1124. will fall if the floor is pulled out from under them.
  1125. =============
  1126. */
  1127. #ifdef QUAKE2
  1128. void SV_Physics_Step (edict_t *ent)
  1129. {
  1130. qboolean wasonground;
  1131. qboolean inwater;
  1132. qboolean hitsound = false;
  1133. float *vel;
  1134. float speed, newspeed, control;
  1135. float friction;
  1136. edict_t *groundentity;
  1137. groundentity = PROG_TO_EDICT(ent->v.groundentity);
  1138. if ((int)groundentity->v.flags & FL_CONVEYOR)
  1139. VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity);
  1140. else
  1141. VectorCopy(vec_origin, ent->v.basevelocity);
  1142. //@@
  1143. pr_global_struct->time = sv.time;
  1144. pr_global_struct->self = EDICT_TO_PROG(ent);
  1145. PF_WaterMove();
  1146. SV_CheckVelocity (ent);
  1147. wasonground = (int)ent->v.flags & FL_ONGROUND;
  1148. // ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
  1149. // add gravity except:
  1150. // flying monsters
  1151. // swimming monsters who are in the water
  1152. inwater = SV_CheckWater(ent);
  1153. if (! wasonground)
  1154. if (!((int)ent->v.flags & FL_FLY))
  1155. if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0)))
  1156. {
  1157. if (ent->v.velocity[2] < sv_gravity.value*-0.1)
  1158. hitsound = true;
  1159. if (!inwater)
  1160. SV_AddGravity (ent);
  1161. }
  1162. if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin))
  1163. {
  1164. ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
  1165. // apply friction
  1166. // let dead monsters who aren't completely onground slide
  1167. if (wasonground)
  1168. if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent)))
  1169. {
  1170. vel = ent->v.velocity;
  1171. speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
  1172. if (speed)
  1173. {
  1174. friction = sv_friction.value;
  1175. control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
  1176. newspeed = speed - host_frametime*control*friction;
  1177. if (newspeed < 0)
  1178. newspeed = 0;
  1179. newspeed /= speed;
  1180. vel[0] = vel[0] * newspeed;
  1181. vel[1] = vel[1] * newspeed;
  1182. }
  1183. }
  1184. VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
  1185. SV_FlyMove (ent, host_frametime, NULL);
  1186. VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
  1187. // determine if it's on solid ground at all
  1188. {
  1189. vec3_t mins, maxs, point;
  1190. int x, y;
  1191. VectorAdd (ent->v.origin, ent->v.mins, mins);
  1192. VectorAdd (ent->v.origin, ent->v.maxs, maxs);
  1193. point[2] = mins[2] - 1;
  1194. for (x=0 ; x<=1 ; x++)
  1195. for (y=0 ; y<=1 ; y++)
  1196. {
  1197. point[0] = x ? maxs[0] : mins[0];
  1198. point[1] = y ? maxs[1] : mins[1];
  1199. if (SV_PointContents (point) == CONTENTS_SOLID)
  1200. {
  1201. ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
  1202. break;
  1203. }
  1204. }
  1205. }
  1206. SV_LinkEdict (ent, true);
  1207. if ((int)ent->v.flags & FL_ONGROUND)
  1208. if (!wasonground)
  1209. if (hitsound)
  1210. SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
  1211. }
  1212. // regular thinking
  1213. SV_RunThink (ent);
  1214. SV_CheckWaterTransition (ent);
  1215. }
  1216. #else
  1217. void SV_Physics_Step (edict_t *ent)
  1218. {
  1219. qboolean hitsound;
  1220. // freefall if not onground
  1221. if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) )
  1222. {
  1223. if (ent->v.velocity[2] < sv_gravity.value*-0.1)
  1224. hitsound = true;
  1225. else
  1226. hitsound = false;
  1227. SV_AddGravity (ent);
  1228. SV_CheckVelocity (ent);
  1229. SV_FlyMove (ent, host_frametime, NULL);
  1230. SV_LinkEdict (ent, true);
  1231. if ( (int)ent->v.flags & FL_ONGROUND ) // just hit ground
  1232. {
  1233. if (hitsound)
  1234. SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
  1235. }
  1236. }
  1237. // regular thinking
  1238. SV_RunThink (ent);
  1239. SV_CheckWaterTransition (ent);
  1240. }
  1241. #endif
  1242. //============================================================================
  1243. /*
  1244. ================
  1245. SV_Physics
  1246. ================
  1247. */
  1248. void SV_Physics (void)
  1249. {
  1250. int i;
  1251. edict_t *ent;
  1252. // let the progs know that a new frame has started
  1253. pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
  1254. pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
  1255. pr_global_struct->time = sv.time;
  1256. PR_ExecuteProgram (pr_global_struct->StartFrame);
  1257. //SV_CheckAllEnts ();
  1258. //
  1259. // treat each object in turn
  1260. //
  1261. ent = sv.edicts;
  1262. for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
  1263. {
  1264. if (ent->free)
  1265. continue;
  1266. if (pr_global_struct->force_retouch)
  1267. {
  1268. SV_LinkEdict (ent, true); // force retouch even for stationary
  1269. }
  1270. if (i > 0 && i <= svs.maxclients)
  1271. SV_Physics_Client (ent, i);
  1272. else if (ent->v.movetype == MOVETYPE_PUSH)
  1273. SV_Physics_Pusher (ent);
  1274. else if (ent->v.movetype == MOVETYPE_NONE)
  1275. SV_Physics_None (ent);
  1276. #ifdef QUAKE2
  1277. else if (ent->v.movetype == MOVETYPE_FOLLOW)
  1278. SV_Physics_Follow (ent);
  1279. #endif
  1280. else if (ent->v.movetype == MOVETYPE_NOCLIP)
  1281. SV_Physics_Noclip (ent);
  1282. else if (ent->v.movetype == MOVETYPE_STEP)
  1283. SV_Physics_Step (ent);
  1284. else if (ent->v.movetype == MOVETYPE_TOSS
  1285. || ent->v.movetype == MOVETYPE_BOUNCE
  1286. #ifdef QUAKE2
  1287. || ent->v.movetype == MOVETYPE_BOUNCEMISSILE
  1288. #endif
  1289. || ent->v.movetype == MOVETYPE_FLY
  1290. || ent->v.movetype == MOVETYPE_FLYMISSILE)
  1291. SV_Physics_Toss (ent);
  1292. else
  1293. Sys_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);
  1294. }
  1295. if (pr_global_struct->force_retouch)
  1296. pr_global_struct->force_retouch--;
  1297. sv.time += host_frametime;
  1298. }
  1299. #ifdef QUAKE2
  1300. trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore)
  1301. {
  1302. edict_t tempent, *tent;
  1303. trace_t trace;
  1304. vec3_t move;
  1305. vec3_t end;
  1306. double save_frametime;
  1307. // extern particle_t *active_particles, *free_particles;
  1308. // particle_t *p;
  1309. save_frametime = host_frametime;
  1310. host_frametime = 0.05;
  1311. memcpy(&tempent, ent, sizeof(edict_t));
  1312. tent = &tempent;
  1313. while (1)
  1314. {
  1315. SV_CheckVelocity (tent);
  1316. SV_AddGravity (tent);
  1317. VectorMA (tent->v.angles, host_frametime, tent->v.avelocity, tent->v.angles);
  1318. VectorScale (tent->v.velocity, host_frametime, move);
  1319. VectorAdd (tent->v.origin, move, end);
  1320. trace = SV_Move (tent->v.origin, tent->v.mins, tent->v.maxs, end, MOVE_NORMAL, tent);
  1321. VectorCopy (trace.endpos, tent->v.origin);
  1322. // p = free_particles;
  1323. // if (p)
  1324. // {
  1325. // free_particles = p->next;
  1326. // p->next = active_particles;
  1327. // active_particles = p;
  1328. //
  1329. // p->die = 256;
  1330. // p->color = 15;
  1331. // p->type = pt_static;
  1332. // VectorCopy (vec3_origin, p->vel);
  1333. // VectorCopy (tent->v.origin, p->org);
  1334. // }
  1335. if (trace.ent)
  1336. if (trace.ent != ignore)
  1337. break;
  1338. }
  1339. // p->color = 224;
  1340. host_frametime = save_frametime;
  1341. return trace;
  1342. }
  1343. #endif