p_mobj.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2004 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Moving object handling. Spawn functions.
  31. *
  32. *-----------------------------------------------------------------------------*/
  33. #include "doomdef.h"
  34. #include "doomstat.h"
  35. #include "m_random.h"
  36. #include "r_main.h"
  37. #include "p_maputl.h"
  38. #include "p_map.h"
  39. #include "p_tick.h"
  40. #include "sounds.h"
  41. #include "st_stuff.h"
  42. #include "hu_stuff.h"
  43. #include "s_sound.h"
  44. #include "info.h"
  45. #include "g_game.h"
  46. #include "p_inter.h"
  47. #include "lprintf.h"
  48. #include "r_demo.h"
  49. //
  50. // P_SetMobjState
  51. // Returns true if the mobj is still present.
  52. //
  53. boolean P_SetMobjState(mobj_t* mobj,statenum_t state)
  54. {
  55. state_t* st;
  56. // killough 4/9/98: remember states seen, to detect cycles:
  57. static statenum_t seenstate_tab[NUMSTATES]; // fast transition table
  58. statenum_t *seenstate = seenstate_tab; // pointer to table
  59. static int recursion; // detects recursion
  60. statenum_t i = state; // initial state
  61. boolean ret = true; // return value
  62. statenum_t tempstate[NUMSTATES]; // for use with recursion
  63. if (recursion++) // if recursion detected,
  64. memset(seenstate=tempstate,0,sizeof tempstate); // clear state table
  65. do
  66. {
  67. if (state == S_NULL)
  68. {
  69. mobj->state = (state_t *) S_NULL;
  70. P_RemoveMobj (mobj);
  71. ret = false;
  72. break; // killough 4/9/98
  73. }
  74. st = &states[state];
  75. mobj->state = st;
  76. mobj->tics = st->tics;
  77. mobj->sprite = st->sprite;
  78. mobj->frame = st->frame;
  79. // Modified handling.
  80. // Call action functions when the state is set
  81. if (st->action)
  82. st->action(mobj);
  83. seenstate[state] = 1 + st->nextstate; // killough 4/9/98
  84. state = st->nextstate;
  85. } while (!mobj->tics && !seenstate[state]); // killough 4/9/98
  86. if (ret && !mobj->tics) // killough 4/9/98: detect state cycles
  87. doom_printf("Warning: State Cycle Detected");
  88. if (!--recursion)
  89. for (;(state=seenstate[i]);i=state-1)
  90. seenstate[i] = 0; // killough 4/9/98: erase memory of states
  91. return ret;
  92. }
  93. //
  94. // P_ExplodeMissile
  95. //
  96. void P_ExplodeMissile (mobj_t* mo)
  97. {
  98. mo->momx = mo->momy = mo->momz = 0;
  99. P_SetMobjState (mo, mobjinfo[mo->type].deathstate);
  100. mo->tics -= P_Random(pr_explode)&3;
  101. if (mo->tics < 1)
  102. mo->tics = 1;
  103. mo->flags &= ~MF_MISSILE;
  104. if (mo->info->deathsound)
  105. S_StartSound (mo, mo->info->deathsound);
  106. }
  107. //
  108. // P_XYMovement
  109. //
  110. // Attempts to move something if it has momentum.
  111. //
  112. static void P_XYMovement (mobj_t* mo)
  113. {
  114. player_t *player;
  115. fixed_t xmove, ymove;
  116. //e6y
  117. fixed_t oldx,oldy; // phares 9/10/98: reducing bobbing/momentum on ice
  118. #if 0
  119. fixed_t ptryx;
  120. fixed_t ptryy;
  121. fixed_t xmove;
  122. fixed_t ymove;
  123. fixed_t oldx,oldy; // phares 9/10/98: reducing bobbing/momentum on ice
  124. // when up against walls
  125. #endif
  126. if (!(mo->momx | mo->momy)) // Any momentum?
  127. {
  128. if (mo->flags & MF_SKULLFLY)
  129. {
  130. // the skull slammed into something
  131. mo->flags &= ~MF_SKULLFLY;
  132. mo->momz = 0;
  133. P_SetMobjState (mo, mo->info->spawnstate);
  134. }
  135. return;
  136. }
  137. player = mo->player;
  138. if (mo->momx > MAXMOVE)
  139. mo->momx = MAXMOVE;
  140. else if (mo->momx < -MAXMOVE)
  141. mo->momx = -MAXMOVE;
  142. if (mo->momy > MAXMOVE)
  143. mo->momy = MAXMOVE;
  144. else if (mo->momy < -MAXMOVE)
  145. mo->momy = -MAXMOVE;
  146. xmove = mo->momx;
  147. ymove = mo->momy;
  148. oldx = mo->x; // phares 9/10/98: new code to reduce bobbing/momentum
  149. oldy = mo->y; // when on ice & up against wall. These will be compared
  150. // to your x,y values later to see if you were able to move
  151. do
  152. {
  153. fixed_t ptryx, ptryy;
  154. // killough 8/9/98: fix bug in original Doom source:
  155. // Large negative displacements were never considered.
  156. // This explains the tendency for Mancubus fireballs
  157. // to pass through walls.
  158. // CPhipps - compatibility optioned
  159. if (xmove > MAXMOVE/2 || ymove > MAXMOVE/2 ||
  160. (!comp[comp_moveblock]
  161. && (xmove < -MAXMOVE/2 || ymove < -MAXMOVE/2)))
  162. {
  163. ptryx = mo->x + xmove/2;
  164. ptryy = mo->y + ymove/2;
  165. xmove >>= 1;
  166. ymove >>= 1;
  167. }
  168. else
  169. {
  170. ptryx = mo->x + xmove;
  171. ptryy = mo->y + ymove;
  172. xmove = ymove = 0;
  173. }
  174. // killough 3/15/98: Allow objects to drop off
  175. if (!P_TryMove (mo, ptryx, ptryy, true))
  176. {
  177. // blocked move
  178. // killough 8/11/98: bouncing off walls
  179. // killough 10/98:
  180. // Add ability for objects other than players to bounce on ice
  181. if (!(mo->flags & MF_MISSILE) &&
  182. mbf_features &&
  183. (mo->flags & MF_BOUNCES ||
  184. (!player && blockline &&
  185. variable_friction && mo->z <= mo->floorz &&
  186. P_GetFriction(mo, NULL) > ORIG_FRICTION)))
  187. {
  188. if (blockline)
  189. {
  190. fixed_t r = ((blockline->dx >> FRACBITS) * mo->momx +
  191. (blockline->dy >> FRACBITS) * mo->momy) /
  192. ((blockline->dx >> FRACBITS)*(blockline->dx >> FRACBITS)+
  193. (blockline->dy >> FRACBITS)*(blockline->dy >> FRACBITS));
  194. fixed_t x = FixedMul(r, blockline->dx);
  195. fixed_t y = FixedMul(r, blockline->dy);
  196. // reflect momentum away from wall
  197. mo->momx = x*2 - mo->momx;
  198. mo->momy = y*2 - mo->momy;
  199. // if under gravity, slow down in
  200. // direction perpendicular to wall.
  201. if (!(mo->flags & MF_NOGRAVITY))
  202. {
  203. mo->momx = (mo->momx + x)/2;
  204. mo->momy = (mo->momy + y)/2;
  205. }
  206. }
  207. else
  208. mo->momx = mo->momy = 0;
  209. }
  210. else
  211. if (player) // try to slide along it
  212. P_SlideMove (mo);
  213. else
  214. if (mo->flags & MF_MISSILE)
  215. {
  216. // explode a missile
  217. if (ceilingline &&
  218. ceilingline->backsector &&
  219. ceilingline->backsector->ceilingpic == skyflatnum)
  220. if (demo_compatibility || // killough
  221. mo->z > ceilingline->backsector->ceilingheight)
  222. {
  223. // Hack to prevent missiles exploding
  224. // against the sky.
  225. // Does not handle sky floors.
  226. P_RemoveMobj (mo);
  227. return;
  228. }
  229. P_ExplodeMissile (mo);
  230. }
  231. else // whatever else it is, it is now standing still in (x,y)
  232. mo->momx = mo->momy = 0;
  233. }
  234. } while (xmove || ymove);
  235. // slow down
  236. #if 0 /* killough 10/98: this is unused code (except maybe in .deh files?) */
  237. if (player && player->cheats & CF_NOMOMENTUM)
  238. {
  239. // debug option for no sliding at all
  240. mo->momx = mo->momy = 0;
  241. player->momx = player->momy = 0; /* killough 10/98 */
  242. return;
  243. }
  244. #endif
  245. /* no friction for missiles or skulls ever, no friction when airborne */
  246. if (mo->flags & (MF_MISSILE | MF_SKULLFLY) || mo->z > mo->floorz)
  247. return;
  248. /* killough 8/11/98: add bouncers
  249. * killough 9/15/98: add objects falling off ledges
  250. * killough 11/98: only include bouncers hanging off ledges
  251. */
  252. if (((mo->flags & MF_BOUNCES && mo->z > mo->dropoffz) ||
  253. mo->flags & MF_CORPSE || mo->intflags & MIF_FALLING) &&
  254. (mo->momx > FRACUNIT/4 || mo->momx < -FRACUNIT/4 ||
  255. mo->momy > FRACUNIT/4 || mo->momy < -FRACUNIT/4) &&
  256. mo->floorz != mo->subsector->sector->floorheight)
  257. return; // do not stop sliding if halfway off a step with some momentum
  258. // killough 11/98:
  259. // Stop voodoo dolls that have come to rest, despite any
  260. // moving corresponding player, except in old demos:
  261. if (mo->momx > -STOPSPEED && mo->momx < STOPSPEED &&
  262. mo->momy > -STOPSPEED && mo->momy < STOPSPEED &&
  263. (!player || !(player->cmd.forwardmove | player->cmd.sidemove) ||
  264. (player->mo != mo && compatibility_level >= lxdoom_1_compatibility)))
  265. {
  266. // if in a walking frame, stop moving
  267. // killough 10/98:
  268. // Don't affect main player when voodoo dolls stop, except in old demos:
  269. // if ( player&&(unsigned)((player->mo->state - states)- S_PLAY_RUN1) < 4)
  270. // P_SetMobjState (player->mo, S_PLAY);
  271. if (player && (unsigned)(player->mo->state - states - S_PLAY_RUN1) < 4
  272. && (player->mo == mo || compatibility_level >= lxdoom_1_compatibility))
  273. P_SetMobjState(player->mo, S_PLAY);
  274. mo->momx = mo->momy = 0;
  275. /* killough 10/98: kill any bobbing momentum too (except in voodoo dolls)
  276. * cph - DEMOSYNC - needs compatibility check?
  277. */
  278. if (player && player->mo == mo)
  279. player->momx = player->momy = 0;
  280. }
  281. else
  282. {
  283. /* phares 3/17/98
  284. *
  285. * Friction will have been adjusted by friction thinkers for
  286. * icy or muddy floors. Otherwise it was never touched and
  287. * remained set at ORIG_FRICTION
  288. *
  289. * killough 8/28/98: removed inefficient thinker algorithm,
  290. * instead using touching_sectorlist in P_GetFriction() to
  291. * determine friction (and thus only when it is needed).
  292. *
  293. * killough 10/98: changed to work with new bobbing method.
  294. * Reducing player momentum is no longer needed to reduce
  295. * bobbing, so ice works much better now.
  296. *
  297. * cph - DEMOSYNC - need old code for Boom demos?
  298. */
  299. //e6y
  300. if (compatibility_level <= boom_201_compatibility)
  301. {
  302. // phares 3/17/98
  303. // Friction will have been adjusted by friction thinkers for icy
  304. // or muddy floors. Otherwise it was never touched and
  305. // remained set at ORIG_FRICTION
  306. mo->momx = FixedMul(mo->momx,mo->friction);
  307. mo->momy = FixedMul(mo->momy,mo->friction);
  308. mo->friction = ORIG_FRICTION; // reset to normal for next tic
  309. }
  310. else if (compatibility_level <= lxdoom_1_compatibility)
  311. {
  312. // phares 9/10/98: reduce bobbing/momentum when on ice & up against wall
  313. if ((oldx == mo->x) && (oldy == mo->y)) // Did you go anywhere?
  314. { // No. Use original friction. This allows you to not bob so much
  315. // if you're on ice, but keeps enough momentum around to break free
  316. // when you're mildly stuck in a wall.
  317. mo->momx = FixedMul(mo->momx,ORIG_FRICTION);
  318. mo->momy = FixedMul(mo->momy,ORIG_FRICTION);
  319. }
  320. else
  321. { // Yes. Use stored friction.
  322. mo->momx = FixedMul(mo->momx,mo->friction);
  323. mo->momy = FixedMul(mo->momy,mo->friction);
  324. }
  325. mo->friction = ORIG_FRICTION; // reset to normal for next tic
  326. }
  327. else
  328. {
  329. fixed_t friction = P_GetFriction(mo, NULL);
  330. mo->momx = FixedMul(mo->momx, friction);
  331. mo->momy = FixedMul(mo->momy, friction);
  332. /* killough 10/98: Always decrease player bobbing by ORIG_FRICTION.
  333. * This prevents problems with bobbing on ice, where it was not being
  334. * reduced fast enough, leading to all sorts of kludges being developed.
  335. */
  336. if (player && player->mo == mo) /* Not voodoo dolls */
  337. {
  338. player->momx = FixedMul(player->momx, ORIG_FRICTION);
  339. player->momy = FixedMul(player->momy, ORIG_FRICTION);
  340. }
  341. }
  342. }
  343. }
  344. //
  345. // P_ZMovement
  346. //
  347. // Attempt vertical movement.
  348. static void P_ZMovement (mobj_t* mo)
  349. {
  350. /* killough 7/11/98:
  351. * BFG fireballs bounced on floors and ceilings in Pre-Beta Doom
  352. * killough 8/9/98: added support for non-missile objects bouncing
  353. * (e.g. grenade, mine, pipebomb)
  354. */
  355. if (mo->flags & MF_BOUNCES && mo->momz) {
  356. mo->z += mo->momz;
  357. if (mo->z <= mo->floorz) { /* bounce off floors */
  358. mo->z = mo->floorz;
  359. if (mo->momz < 0) {
  360. mo->momz = -mo->momz;
  361. if (!(mo->flags & MF_NOGRAVITY)) { /* bounce back with decay */
  362. mo->momz = mo->flags & MF_FLOAT ? // floaters fall slowly
  363. mo->flags & MF_DROPOFF ? // DROPOFF indicates rate
  364. FixedMul(mo->momz, (fixed_t)(FRACUNIT*.85)) :
  365. FixedMul(mo->momz, (fixed_t)(FRACUNIT*.70)) :
  366. FixedMul(mo->momz, (fixed_t)(FRACUNIT*.45)) ;
  367. /* Bring it to rest below a certain speed */
  368. if (D_abs(mo->momz) <= mo->info->mass*(GRAVITY*4/256))
  369. mo->momz = 0;
  370. }
  371. /* killough 11/98: touchy objects explode on impact */
  372. if (mo->flags & MF_TOUCHY && mo->intflags & MIF_ARMED
  373. && mo->health > 0)
  374. P_DamageMobj(mo, NULL, NULL, mo->health);
  375. else if (mo->flags & MF_FLOAT && sentient(mo))
  376. goto floater;
  377. return;
  378. }
  379. } else if (mo->z >= mo->ceilingz - mo->height) {
  380. /* bounce off ceilings */
  381. mo->z = mo->ceilingz - mo->height;
  382. if (mo->momz > 0) {
  383. if (mo->subsector->sector->ceilingpic != skyflatnum)
  384. mo->momz = -mo->momz; /* always bounce off non-sky ceiling */
  385. else if (mo->flags & MF_MISSILE)
  386. P_RemoveMobj(mo); /* missiles don't bounce off skies */
  387. else if (mo->flags & MF_NOGRAVITY)
  388. mo->momz = -mo->momz; // bounce unless under gravity
  389. if (mo->flags & MF_FLOAT && sentient(mo))
  390. goto floater;
  391. return;
  392. }
  393. } else {
  394. if (!(mo->flags & MF_NOGRAVITY)) /* free-fall under gravity */
  395. mo->momz -= mo->info->mass*(GRAVITY/256);
  396. if (mo->flags & MF_FLOAT && sentient(mo)) goto floater;
  397. return;
  398. }
  399. /* came to a stop */
  400. mo->momz = 0;
  401. if (mo->flags & MF_MISSILE) {
  402. if (ceilingline &&
  403. ceilingline->backsector &&
  404. ceilingline->backsector->ceilingpic == skyflatnum &&
  405. mo->z > ceilingline->backsector->ceilingheight)
  406. P_RemoveMobj(mo); /* don't explode on skies */
  407. else
  408. P_ExplodeMissile(mo);
  409. }
  410. if (mo->flags & MF_FLOAT && sentient(mo)) goto floater;
  411. return;
  412. }
  413. /* killough 8/9/98: end bouncing object code */
  414. // check for smooth step up
  415. if (mo->player &&
  416. mo->player->mo == mo && // killough 5/12/98: exclude voodoo dolls
  417. mo->z < mo->floorz)
  418. {
  419. mo->player->viewheight -= mo->floorz-mo->z;
  420. mo->player->deltaviewheight = (VIEWHEIGHT - mo->player->viewheight)>>3;
  421. }
  422. // adjust altitude
  423. mo->z += mo->momz;
  424. floater:
  425. if ((mo->flags & MF_FLOAT) && mo->target)
  426. // float down towards target if too close
  427. if (!((mo->flags ^ MF_FLOAT) & (MF_FLOAT | MF_SKULLFLY | MF_INFLOAT)) &&
  428. mo->target) /* killough 11/98: simplify */
  429. {
  430. fixed_t delta;
  431. if (P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y) <
  432. D_abs(delta = mo->target->z + (mo->height>>1) - mo->z)*3)
  433. mo->z += delta < 0 ? -FLOATSPEED : FLOATSPEED;
  434. }
  435. // clip movement
  436. if (mo->z <= mo->floorz)
  437. {
  438. // hit the floor
  439. /* Note (id):
  440. * somebody left this after the setting momz to 0,
  441. * kinda useless there.
  442. * cph - This was the a bug in the linuxdoom-1.10 source which
  443. * caused it not to sync Doom 2 v1.9 demos. Someone
  444. * added the above comment and moved up the following code. So
  445. * demos would desync in close lost soul fights.
  446. * cph - revised 2001/04/15 -
  447. * This was a bug in the Doom/Doom 2 source; the following code
  448. * is meant to make charging lost souls bounce off of floors, but it
  449. * was incorrectly placed after momz was set to 0.
  450. * However, this bug was fixed in Doom95, Final/Ultimate Doom, and
  451. * the v1.10 source release (which is one reason why it failed to sync
  452. * some Doom2 v1.9 demos)
  453. * I've added a comp_soul compatibility option to make this behavior
  454. * selectable for PrBoom v2.3+. For older demos, we do this here only
  455. * if we're in a compatibility level above Doom 2 v1.9 (in which case we
  456. * mimic the bug and do it further down instead)
  457. */
  458. if (mo->flags & MF_SKULLFLY &&
  459. (!comp[comp_soul] ||
  460. (compatibility_level > doom2_19_compatibility &&
  461. compatibility_level < prboom_4_compatibility)
  462. ))
  463. mo->momz = -mo->momz; // the skull slammed into something
  464. if (mo->momz < 0)
  465. {
  466. /* killough 11/98: touchy objects explode on impact */
  467. if (mo->flags & MF_TOUCHY && mo->intflags & MIF_ARMED && mo->health > 0)
  468. P_DamageMobj(mo, NULL, NULL, mo->health);
  469. else
  470. if (mo->player && /* killough 5/12/98: exclude voodoo dolls */
  471. mo->player->mo == mo && mo->momz < -GRAVITY*8)
  472. {
  473. // Squat down.
  474. // Decrease viewheight for a moment
  475. // after hitting the ground (hard),
  476. // and utter appropriate sound.
  477. mo->player->deltaviewheight = mo->momz>>3;
  478. /* cph - prevent "oof" when dead */
  479. if (comp[comp_sound] || mo->health > 0)
  480. S_StartSound (mo, sfx_oof);
  481. }
  482. mo->momz = 0;
  483. }
  484. mo->z = mo->floorz;
  485. /* cph 2001/04/15 -
  486. * This is the buggy lost-soul bouncing code referenced above.
  487. * We've already set momz = 0 normally by this point, so it's useless.
  488. * However we might still have upward momentum, in which case this will
  489. * incorrectly reverse it, so we might still need this for demo sync
  490. */
  491. if (mo->flags & MF_SKULLFLY &&
  492. compatibility_level <= doom2_19_compatibility)
  493. mo->momz = -mo->momz; // the skull slammed into something
  494. if ( (mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP) )
  495. {
  496. P_ExplodeMissile (mo);
  497. return;
  498. }
  499. }
  500. else // still above the floor // phares
  501. if (!(mo->flags & MF_NOGRAVITY))
  502. {
  503. if (!mo->momz)
  504. mo->momz = -GRAVITY;
  505. mo->momz -= GRAVITY;
  506. }
  507. if (mo->z + mo->height > mo->ceilingz)
  508. {
  509. /* cph 2001/04/15 -
  510. * Lost souls were meant to bounce off of ceilings;
  511. * new comp_soul compatibility option added
  512. */
  513. if (!comp[comp_soul] && mo->flags & MF_SKULLFLY)
  514. mo->momz = -mo->momz; // the skull slammed into something
  515. // hit the ceiling
  516. if (mo->momz > 0)
  517. mo->momz = 0;
  518. mo->z = mo->ceilingz - mo->height;
  519. /* cph 2001/04/15 -
  520. * We might have hit a ceiling but had downward momentum (e.g. ceiling is
  521. * lowering on us), so for old demos we must still do the buggy
  522. * momentum reversal here
  523. */
  524. if (comp[comp_soul] && mo->flags & MF_SKULLFLY)
  525. mo->momz = -mo->momz; // the skull slammed into something
  526. if ( (mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP) )
  527. {
  528. P_ExplodeMissile (mo);
  529. return;
  530. }
  531. }
  532. }
  533. //
  534. // P_NightmareRespawn
  535. //
  536. static void P_NightmareRespawn(mobj_t* mobj)
  537. {
  538. fixed_t x;
  539. fixed_t y;
  540. fixed_t z;
  541. subsector_t* ss;
  542. mobj_t* mo;
  543. mapthing_t* mthing;
  544. x = mobj->spawnpoint.x << FRACBITS;
  545. y = mobj->spawnpoint.y << FRACBITS;
  546. /* haleyjd: stupid nightmare respawning bug fix
  547. *
  548. * 08/09/00: compatibility added, time to ramble :)
  549. * This fixes the notorious nightmare respawning bug that causes monsters
  550. * that didn't spawn at level startup to respawn at the point (0,0)
  551. * regardless of that point's nature. SMMU and Eternity need this for
  552. * script-spawned things like Halif Swordsmythe, as well.
  553. *
  554. * cph - copied from eternity, except comp_respawnfix becomes comp_respawn
  555. * and the logic is reversed (i.e. like the rest of comp_ it *disables*
  556. * the fix)
  557. */
  558. if(!comp[comp_respawn] && !x && !y)
  559. {
  560. // spawnpoint was zeroed out, so use point of death instead
  561. x = mobj->x;
  562. y = mobj->y;
  563. }
  564. // something is occupying its position?
  565. if (!P_CheckPosition (mobj, x, y) )
  566. return; // no respwan
  567. // spawn a teleport fog at old spot
  568. // because of removal of the body?
  569. mo = P_SpawnMobj (mobj->x,
  570. mobj->y,
  571. mobj->subsector->sector->floorheight,
  572. MT_TFOG);
  573. // initiate teleport sound
  574. S_StartSound (mo, sfx_telept);
  575. // spawn a teleport fog at the new spot
  576. ss = R_PointInSubsector (x,y);
  577. mo = P_SpawnMobj (x, y, ss->sector->floorheight , MT_TFOG);
  578. S_StartSound (mo, sfx_telept);
  579. // spawn the new monster
  580. mthing = &mobj->spawnpoint;
  581. if (mobj->info->flags & MF_SPAWNCEILING)
  582. z = ONCEILINGZ;
  583. else
  584. z = ONFLOORZ;
  585. // inherit attributes from deceased one
  586. mo = P_SpawnMobj (x,y,z, mobj->type);
  587. mo->spawnpoint = mobj->spawnpoint;
  588. mo->angle = ANG45 * (mthing->angle/45);
  589. if (mthing->options & MTF_AMBUSH)
  590. mo->flags |= MF_AMBUSH;
  591. /* killough 11/98: transfer friendliness from deceased */
  592. mo->flags = (mo->flags & ~MF_FRIEND) | (mobj->flags & MF_FRIEND);
  593. mo->reactiontime = 18;
  594. // remove the old monster,
  595. P_RemoveMobj (mobj);
  596. }
  597. //
  598. // P_MobjThinker
  599. //
  600. void P_MobjThinker (mobj_t* mobj)
  601. {
  602. // killough 11/98:
  603. // removed old code which looked at target references
  604. // (we use pointer reference counting now)
  605. mobj->PrevX = mobj->x;
  606. mobj->PrevY = mobj->y;
  607. mobj->PrevZ = mobj->z;
  608. // momentum movement
  609. if (mobj->momx | mobj->momy || mobj->flags & MF_SKULLFLY)
  610. {
  611. P_XYMovement(mobj);
  612. if (mobj->thinker.function != P_MobjThinker) // cph - Must've been removed
  613. return; // killough - mobj was removed
  614. }
  615. if (mobj->z != mobj->floorz || mobj->momz)
  616. {
  617. P_ZMovement(mobj);
  618. if (mobj->thinker.function != P_MobjThinker) // cph - Must've been removed
  619. return; // killough - mobj was removed
  620. }
  621. else
  622. if (!(mobj->momx | mobj->momy) && !sentient(mobj))
  623. { // non-sentient objects at rest
  624. mobj->intflags |= MIF_ARMED; // arm a mine which has come to rest
  625. // killough 9/12/98: objects fall off ledges if they are hanging off
  626. // slightly push off of ledge if hanging more than halfway off
  627. if (mobj->z > mobj->dropoffz && // Only objects contacting dropoff
  628. !(mobj->flags & MF_NOGRAVITY) && // Only objects which fall
  629. !comp[comp_falloff]) // Not in old demos
  630. P_ApplyTorque(mobj); // Apply torque
  631. else
  632. mobj->intflags &= ~MIF_FALLING, mobj->gear = 0; // Reset torque
  633. }
  634. // cycle through states,
  635. // calling action functions at transitions
  636. if (mobj->tics != -1)
  637. {
  638. mobj->tics--;
  639. // you can cycle through multiple states in a tic
  640. if (!mobj->tics)
  641. if (!P_SetMobjState (mobj, mobj->state->nextstate) )
  642. return; // freed itself
  643. }
  644. else
  645. {
  646. // check for nightmare respawn
  647. if (! (mobj->flags & MF_COUNTKILL) )
  648. return;
  649. if (!respawnmonsters)
  650. return;
  651. mobj->movecount++;
  652. if (mobj->movecount < 12*35)
  653. return;
  654. if (leveltime & 31)
  655. return;
  656. if (P_Random (pr_respawn) > 4)
  657. return;
  658. P_NightmareRespawn (mobj);
  659. }
  660. }
  661. //
  662. // P_SpawnMobj
  663. //
  664. mobj_t* P_SpawnMobj(fixed_t x,fixed_t y,fixed_t z,mobjtype_t type)
  665. {
  666. mobj_t* mobj;
  667. state_t* st;
  668. mobjinfo_t* info;
  669. mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
  670. memset (mobj, 0, sizeof (*mobj));
  671. info = &mobjinfo[type];
  672. mobj->type = type;
  673. mobj->info = info;
  674. mobj->x = x;
  675. mobj->y = y;
  676. mobj->radius = info->radius;
  677. mobj->height = info->height; // phares
  678. mobj->flags = info->flags;
  679. /* killough 8/23/98: no friends, bouncers, or touchy things in old demos */
  680. if (!mbf_features)
  681. mobj->flags &= ~(MF_BOUNCES | MF_FRIEND | MF_TOUCHY);
  682. else
  683. if (type == MT_PLAYER) // Except in old demos, players
  684. mobj->flags |= MF_FRIEND; // are always friends.
  685. mobj->health = info->spawnhealth;
  686. if (gameskill != sk_nightmare)
  687. mobj->reactiontime = info->reactiontime;
  688. mobj->lastlook = P_Random (pr_lastlook) % MAXPLAYERS;
  689. // do not set the state with P_SetMobjState,
  690. // because action routines can not be called yet
  691. st = &states[info->spawnstate];
  692. mobj->state = st;
  693. mobj->tics = st->tics;
  694. mobj->sprite = st->sprite;
  695. mobj->frame = st->frame;
  696. mobj->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98
  697. // set subsector and/or block links
  698. P_SetThingPosition (mobj);
  699. mobj->dropoffz = /* killough 11/98: for tracking dropoffs */
  700. mobj->floorz = mobj->subsector->sector->floorheight;
  701. mobj->ceilingz = mobj->subsector->sector->ceilingheight;
  702. mobj->z = z == ONFLOORZ ? mobj->floorz : z == ONCEILINGZ ?
  703. mobj->ceilingz - mobj->height : z;
  704. mobj->PrevX = mobj->x;
  705. mobj->PrevY = mobj->y;
  706. mobj->PrevZ = mobj->z;
  707. mobj->thinker.function = P_MobjThinker;
  708. //e6y
  709. mobj->friction = ORIG_FRICTION; // phares 3/17/98
  710. mobj->target = mobj->tracer = mobj->lastenemy = NULL;
  711. P_AddThinker (&mobj->thinker);
  712. if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL)))
  713. totallive++;
  714. return mobj;
  715. }
  716. static mapthing_t itemrespawnque[ITEMQUESIZE];
  717. static int itemrespawntime[ITEMQUESIZE];
  718. int iquehead;
  719. int iquetail;
  720. //
  721. // P_RemoveMobj
  722. //
  723. void P_RemoveMobj (mobj_t* mobj)
  724. {
  725. if ((mobj->flags & MF_SPECIAL)
  726. && !(mobj->flags & MF_DROPPED)
  727. && (mobj->type != MT_INV)
  728. && (mobj->type != MT_INS))
  729. {
  730. itemrespawnque[iquehead] = mobj->spawnpoint;
  731. itemrespawntime[iquehead] = leveltime;
  732. iquehead = (iquehead+1)&(ITEMQUESIZE-1);
  733. // lose one off the end?
  734. if (iquehead == iquetail)
  735. iquetail = (iquetail+1)&(ITEMQUESIZE-1);
  736. }
  737. // unlink from sector and block lists
  738. P_UnsetThingPosition (mobj);
  739. // Delete all nodes on the current sector_list phares 3/16/98
  740. if (sector_list)
  741. {
  742. P_DelSeclist(sector_list);
  743. sector_list = NULL;
  744. }
  745. // stop any playing sound
  746. S_StopSound (mobj);
  747. // killough 11/98:
  748. //
  749. // Remove any references to other mobjs.
  750. //
  751. // Older demos might depend on the fields being left alone, however,
  752. // if multiple thinkers reference each other indirectly before the
  753. // end of the current tic.
  754. // CPhipps - only leave dead references in old demos; I hope lxdoom_1 level
  755. // demos are rare and don't rely on this. I hope.
  756. if ((compatibility_level >= lxdoom_1_compatibility) ||
  757. (!demorecording && !demoplayback)) {
  758. P_SetTarget(&mobj->target, NULL);
  759. P_SetTarget(&mobj->tracer, NULL);
  760. P_SetTarget(&mobj->lastenemy, NULL);
  761. }
  762. // free block
  763. P_RemoveThinker (&mobj->thinker);
  764. }
  765. /*
  766. * P_FindDoomedNum
  767. *
  768. * Finds a mobj type with a matching doomednum
  769. *
  770. * killough 8/24/98: rewrote to use hashing
  771. */
  772. static PUREFUNC int P_FindDoomedNum(unsigned type)
  773. {
  774. static struct { int first, next; } *hash;
  775. register int i;
  776. if (!hash)
  777. {
  778. hash = Z_Malloc(sizeof *hash * NUMMOBJTYPES, PU_CACHE, (void **) &hash);
  779. for (i=0; i<NUMMOBJTYPES; i++)
  780. hash[i].first = NUMMOBJTYPES;
  781. for (i=0; i<NUMMOBJTYPES; i++)
  782. if (mobjinfo[i].doomednum != -1)
  783. {
  784. unsigned h = (unsigned) mobjinfo[i].doomednum % NUMMOBJTYPES;
  785. hash[i].next = hash[h].first;
  786. hash[h].first = i;
  787. }
  788. }
  789. i = hash[type % NUMMOBJTYPES].first;
  790. while ((i < NUMMOBJTYPES) && ((unsigned)mobjinfo[i].doomednum != type))
  791. i = hash[i].next;
  792. return i;
  793. }
  794. //
  795. // P_RespawnSpecials
  796. //
  797. void P_RespawnSpecials (void)
  798. {
  799. fixed_t x;
  800. fixed_t y;
  801. fixed_t z;
  802. subsector_t* ss;
  803. mobj_t* mo;
  804. mapthing_t* mthing;
  805. int i;
  806. // only respawn items in deathmatch
  807. if (deathmatch != 2 && deathmatch != 3) // JDC: added deathmatch 3 for weapons stay, items respawn
  808. return;
  809. // nothing left to respawn?
  810. if (iquehead == iquetail)
  811. return;
  812. // wait at least 30 seconds
  813. if (leveltime - itemrespawntime[iquetail] < 30*35)
  814. return;
  815. mthing = &itemrespawnque[iquetail];
  816. x = mthing->x << FRACBITS;
  817. y = mthing->y << FRACBITS;
  818. // spawn a teleport fog at the new spot
  819. ss = R_PointInSubsector (x,y);
  820. mo = P_SpawnMobj (x, y, ss->sector->floorheight , MT_IFOG);
  821. S_StartSound (mo, sfx_itmbk);
  822. // find which type to spawn
  823. /* killough 8/23/98: use table for faster lookup */
  824. i = P_FindDoomedNum(mthing->type);
  825. // spawn it
  826. if (mobjinfo[i].flags & MF_SPAWNCEILING)
  827. z = ONCEILINGZ;
  828. else
  829. z = ONFLOORZ;
  830. mo = P_SpawnMobj (x,y,z, i);
  831. mo->spawnpoint = *mthing;
  832. mo->angle = ANG45 * (mthing->angle/45);
  833. // pull it from the queue
  834. iquetail = (iquetail+1)&(ITEMQUESIZE-1);
  835. }
  836. //
  837. // P_SpawnPlayer
  838. // Called when a player is spawned on the level.
  839. // Most of the player structure stays unchanged
  840. // between levels.
  841. //
  842. extern byte playernumtotrans[MAXPLAYERS];
  843. void P_SpawnPlayer (int n, const mapthing_t* mthing)
  844. {
  845. player_t* p;
  846. fixed_t x;
  847. fixed_t y;
  848. fixed_t z;
  849. mobj_t* mobj;
  850. int i;
  851. // not playing?
  852. if (!playeringame[n])
  853. return;
  854. p = &players[n];
  855. if (p->playerstate == PST_REBORN)
  856. G_PlayerReborn (mthing->type-1);
  857. /* cph 2001/08/14 - use the options field of memorised player starts to
  858. * indicate whether the start really exists in the level.
  859. */
  860. if (!mthing->options)
  861. I_Error("P_SpawnPlayer: attempt to spawn player at unavailable start point");
  862. x = mthing->x << FRACBITS;
  863. y = mthing->y << FRACBITS;
  864. z = ONFLOORZ;
  865. mobj = P_SpawnMobj (x,y,z, MT_PLAYER);
  866. // set color translations for player sprites
  867. mobj->flags |= playernumtotrans[n]<<MF_TRANSSHIFT;
  868. mobj->angle = ANG45 * (mthing->angle/45);
  869. mobj->player = p;
  870. mobj->health = p->health;
  871. p->mo = mobj;
  872. p->playerstate = PST_LIVE;
  873. p->refire = 0;
  874. p->message = NULL;
  875. p->damagecount = 0;
  876. p->bonuscount = 0;
  877. p->extralight = 0;
  878. p->fixedcolormap = 0;
  879. p->viewheight = VIEWHEIGHT;
  880. p->momx = p->momy = 0; // killough 10/98: initialize bobbing to 0.
  881. // setup gun psprite
  882. P_SetupPsprites (p);
  883. // give all cards in death match mode
  884. if (deathmatch)
  885. for (i = 0 ; i < NUMCARDS ; i++)
  886. p->cards[i] = true;
  887. if (mthing->type-1 == consoleplayer)
  888. {
  889. ST_Start(); // wake up the status bar
  890. HU_Start(); // wake up the heads up text
  891. }
  892. R_SmoothPlaying_Reset(p); // e6y
  893. }
  894. /*
  895. * P_IsDoomnumAllowed()
  896. * Based on code taken from P_LoadThings() in src/p_setup.c Return TRUE
  897. * if the thing in question is expected to be available in the gamemode used.
  898. */
  899. boolean P_IsDoomnumAllowed(int doomnum)
  900. {
  901. // Do not spawn cool, new monsters if !commercial
  902. if (gamemode != commercial)
  903. switch(doomnum)
  904. {
  905. case 64: // Archvile
  906. case 65: // Former Human Commando
  907. case 66: // Revenant
  908. case 67: // Mancubus
  909. case 68: // Arachnotron
  910. case 69: // Hell Knight
  911. case 71: // Pain Elemental
  912. case 84: // Wolf SS
  913. case 88: // Boss Brain
  914. case 89: // Boss Shooter
  915. return false;
  916. }
  917. return true;
  918. }
  919. //
  920. // P_SpawnMapThing
  921. // The fields of the mapthing should
  922. // already be in host byte order.
  923. //
  924. void P_SpawnMapThing (const mapthing_t* mthing)
  925. {
  926. int i;
  927. //int bit;
  928. mobj_t* mobj;
  929. fixed_t x;
  930. fixed_t y;
  931. fixed_t z;
  932. int options = mthing->options; /* cph 2001/07/07 - make writable copy */
  933. // killough 2/26/98: Ignore type-0 things as NOPs
  934. // phares 5/14/98: Ignore Player 5-8 starts (for now)
  935. switch(mthing->type)
  936. {
  937. case 0:
  938. case DEN_PLAYER5:
  939. case DEN_PLAYER6:
  940. case DEN_PLAYER7:
  941. case DEN_PLAYER8:
  942. return;
  943. }
  944. // killough 11/98: clear flags unused by Doom
  945. //
  946. // We clear the flags unused in Doom if we see flag mask 256 set, since
  947. // it is reserved to be 0 under the new scheme. A 1 in this reserved bit
  948. // indicates it's a Doom wad made by a Doom editor which puts 1's in
  949. // bits that weren't used in Doom (such as HellMaker wads). So we should
  950. // then simply ignore all upper bits.
  951. if (demo_compatibility ||
  952. (compatibility_level >= lxdoom_1_compatibility &&
  953. options & MTF_RESERVED)) {
  954. if (!demo_compatibility) // cph - Add warning about bad thing flags
  955. lprintf(LO_WARN, "P_SpawnMapThing: correcting bad flags (%u) (thing type %d)\n",
  956. options, mthing->type);
  957. options &= MTF_EASY|MTF_NORMAL|MTF_HARD|MTF_AMBUSH|MTF_NOTSINGLE;
  958. }
  959. // count deathmatch start positions
  960. // doom2.exe has at most 10 deathmatch starts
  961. if (mthing->type == 11)
  962. {
  963. if (!(!compatibility || deathmatch_p-deathmatchstarts < 10)) {
  964. return;
  965. } else {
  966. // 1/11/98 killough -- new code removes limit on deathmatch starts:
  967. size_t offset = deathmatch_p - deathmatchstarts;
  968. if (offset >= num_deathmatchstarts)
  969. {
  970. num_deathmatchstarts = num_deathmatchstarts ?
  971. num_deathmatchstarts*2 : 16;
  972. deathmatchstarts = realloc(deathmatchstarts,
  973. num_deathmatchstarts *
  974. sizeof(*deathmatchstarts));
  975. deathmatch_p = deathmatchstarts + offset;
  976. }
  977. memcpy(deathmatch_p++, mthing, sizeof(*mthing));
  978. (deathmatch_p-1)->options = 1;
  979. return;
  980. }
  981. }
  982. // check for players specially
  983. if (mthing->type <= 4 && mthing->type > 0) // killough 2/26/98 -- fix crashes
  984. {
  985. #ifdef DOGS
  986. // killough 7/19/98: Marine's best friend :)
  987. if (!netgame && mthing->type > 1 && mthing->type <= dogs+1 &&
  988. !players[mthing->type-1].secretcount)
  989. { // use secretcount to avoid multiple dogs in case of multiple starts
  990. players[mthing->type-1].secretcount = 1;
  991. // killough 10/98: force it to be a friend
  992. options |= MTF_FRIEND;
  993. if(HelperThing != -1) // haleyjd 9/22/99: deh substitution
  994. {
  995. int type = HelperThing - 1;
  996. if(type >= 0 && type < NUMMOBJTYPES)
  997. {
  998. i = type;
  999. }
  1000. else
  1001. {
  1002. doom_printf("Invalid value %i for helper, ignored.", HelperThing);
  1003. i = MT_DOGS;
  1004. }
  1005. }
  1006. else {
  1007. i = MT_DOGS;
  1008. }
  1009. goto spawnit;
  1010. }
  1011. #endif
  1012. // save spots for respawning in coop games
  1013. playerstarts[mthing->type-1] = *mthing;
  1014. /* cph 2006/07/24 - use the otherwise-unused options field to flag that
  1015. * this start is present (so we know which elements of the array are filled
  1016. * in, in effect). Also note that the call below to P_SpawnPlayer must use
  1017. * the playerstarts version with this field set */
  1018. playerstarts[mthing->type-1].options = 1;
  1019. if (!deathmatch)
  1020. P_SpawnPlayer (mthing->type-1, &playerstarts[mthing->type-1]);
  1021. return;
  1022. }
  1023. // check for apropriate skill level
  1024. /* jff "not single" thing flag */
  1025. if (!netgame && options & MTF_NOTSINGLE)
  1026. return;
  1027. //jff 3/30/98 implement "not deathmatch" thing flag
  1028. if (netgame && deathmatch && options & MTF_NOTDM)
  1029. return;
  1030. //jff 3/30/98 implement "not cooperative" thing flag
  1031. if (netgame && !deathmatch && options & MTF_NOTCOOP)
  1032. return;
  1033. // killough 11/98: simplify
  1034. if (gameskill == sk_baby || gameskill == sk_easy ?
  1035. !(options & MTF_EASY) :
  1036. gameskill == sk_hard || gameskill == sk_nightmare ?
  1037. !(options & MTF_HARD) : !(options & MTF_NORMAL))
  1038. return;
  1039. // find which type to spawn
  1040. // killough 8/23/98: use table for faster lookup
  1041. i = P_FindDoomedNum(mthing->type);
  1042. // phares 5/16/98:
  1043. // Do not abort because of an unknown thing. Ignore it, but post a
  1044. // warning message for the player.
  1045. if (i == NUMMOBJTYPES)
  1046. {
  1047. doom_printf("Unknown Thing type %i at (%i, %i)",mthing->type,mthing->x,mthing->y);
  1048. return;
  1049. }
  1050. // don't spawn keycards and players in deathmatch
  1051. if (deathmatch && mobjinfo[i].flags & MF_NOTDMATCH)
  1052. return;
  1053. // don't spawn any monsters if -nomonsters
  1054. if (nomonsters && (i == MT_SKULL || (mobjinfo[i].flags & MF_COUNTKILL)))
  1055. return;
  1056. // spawn it
  1057. #ifdef DOGS
  1058. spawnit:
  1059. #endif
  1060. x = mthing->x << FRACBITS;
  1061. y = mthing->y << FRACBITS;
  1062. if (mobjinfo[i].flags & MF_SPAWNCEILING)
  1063. z = ONCEILINGZ;
  1064. else
  1065. z = ONFLOORZ;
  1066. mobj = P_SpawnMobj (x,y,z, i);
  1067. mobj->spawnpoint = *mthing;
  1068. if (mobj->tics > 0)
  1069. mobj->tics = 1 + (P_Random (pr_spawnthing) % mobj->tics);
  1070. if (!(mobj->flags & MF_FRIEND) &&
  1071. options & MTF_FRIEND &&
  1072. mbf_features)
  1073. {
  1074. mobj->flags |= MF_FRIEND; // killough 10/98:
  1075. P_UpdateThinker(&mobj->thinker); // transfer friendliness flag
  1076. }
  1077. /* killough 7/20/98: exclude friends */
  1078. if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL)))
  1079. totalkills++;
  1080. if (mobj->flags & MF_COUNTITEM)
  1081. totalitems++;
  1082. mobj->angle = ANG45 * (mthing->angle/45);
  1083. if (options & MTF_AMBUSH)
  1084. mobj->flags |= MF_AMBUSH;
  1085. }
  1086. //
  1087. // GAME SPAWN FUNCTIONS
  1088. //
  1089. //
  1090. // P_SpawnPuff
  1091. //
  1092. extern fixed_t attackrange;
  1093. void P_SpawnPuff(fixed_t x,fixed_t y,fixed_t z)
  1094. {
  1095. mobj_t* th;
  1096. // killough 5/5/98: remove dependence on order of evaluation:
  1097. int t = P_Random(pr_spawnpuff);
  1098. z += (t - P_Random(pr_spawnpuff))<<10;
  1099. th = P_SpawnMobj (x,y,z, MT_PUFF);
  1100. th->momz = FRACUNIT;
  1101. th->tics -= P_Random(pr_spawnpuff)&3;
  1102. if (th->tics < 1)
  1103. th->tics = 1;
  1104. // don't make punches spark on the wall
  1105. if (attackrange == MELEERANGE)
  1106. P_SetMobjState (th, S_PUFF3);
  1107. }
  1108. //
  1109. // P_SpawnBlood
  1110. //
  1111. void P_SpawnBlood(fixed_t x,fixed_t y,fixed_t z,int damage)
  1112. {
  1113. mobj_t* th;
  1114. // killough 5/5/98: remove dependence on order of evaluation:
  1115. int t = P_Random(pr_spawnblood);
  1116. z += (t - P_Random(pr_spawnblood))<<10;
  1117. th = P_SpawnMobj(x,y,z, MT_BLOOD);
  1118. th->momz = FRACUNIT*2;
  1119. th->tics -= P_Random(pr_spawnblood)&3;
  1120. if (th->tics < 1)
  1121. th->tics = 1;
  1122. if (damage <= 12 && damage >= 9)
  1123. P_SetMobjState (th,S_BLOOD2);
  1124. else if (damage < 9)
  1125. P_SetMobjState (th,S_BLOOD3);
  1126. }
  1127. //
  1128. // P_CheckMissileSpawn
  1129. // Moves the missile forward a bit
  1130. // and possibly explodes it right there.
  1131. //
  1132. void P_CheckMissileSpawn (mobj_t* th)
  1133. {
  1134. th->tics -= P_Random(pr_missile)&3;
  1135. if (th->tics < 1)
  1136. th->tics = 1;
  1137. // move a little forward so an angle can
  1138. // be computed if it immediately explodes
  1139. th->x += (th->momx>>1);
  1140. th->y += (th->momy>>1);
  1141. th->z += (th->momz>>1);
  1142. // killough 8/12/98: for non-missile objects (e.g. grenades)
  1143. if (!(th->flags & MF_MISSILE) && mbf_features)
  1144. return;
  1145. // killough 3/15/98: no dropoff (really = don't care for missiles)
  1146. if (!P_TryMove (th, th->x, th->y, false))
  1147. P_ExplodeMissile (th);
  1148. }
  1149. //
  1150. // P_SpawnMissile
  1151. //
  1152. mobj_t* P_SpawnMissile(mobj_t* source,mobj_t* dest,mobjtype_t type)
  1153. {
  1154. mobj_t* th;
  1155. angle_t an;
  1156. int dist;
  1157. th = P_SpawnMobj (source->x,source->y,source->z + 4*8*FRACUNIT,type);
  1158. if (th->info->seesound)
  1159. S_StartSound (th, th->info->seesound);
  1160. P_SetTarget(&th->target, source); // where it came from
  1161. an = R_PointToAngle2 (source->x, source->y, dest->x, dest->y);
  1162. // fuzzy player
  1163. if (dest->flags & MF_SHADOW)
  1164. { // killough 5/5/98: remove dependence on order of evaluation:
  1165. int t = P_Random(pr_shadow);
  1166. an += (t - P_Random(pr_shadow))<<20;
  1167. }
  1168. th->angle = an;
  1169. an >>= ANGLETOFINESHIFT;
  1170. th->momx = FixedMul (th->info->speed, finecosine[an]);
  1171. th->momy = FixedMul (th->info->speed, finesine[an]);
  1172. dist = P_AproxDistance (dest->x - source->x, dest->y - source->y);
  1173. dist = dist / th->info->speed;
  1174. if (dist < 1)
  1175. dist = 1;
  1176. th->momz = (dest->z - source->z) / dist;
  1177. P_CheckMissileSpawn (th);
  1178. return th;
  1179. }
  1180. //
  1181. // P_SpawnPlayerMissile
  1182. // Tries to aim at a nearby monster
  1183. //
  1184. void P_SpawnPlayerMissile(mobj_t* source,mobjtype_t type)
  1185. {
  1186. mobj_t *th;
  1187. fixed_t x, y, z, slope = 0;
  1188. // see which target is to be aimed at
  1189. angle_t an = source->angle;
  1190. // killough 7/19/98: autoaiming was not in original beta
  1191. {
  1192. // killough 8/2/98: prefer autoaiming at enemies
  1193. uint_64_t mask = mbf_features ? MF_FRIEND : 0;
  1194. do
  1195. {
  1196. slope = P_AimLineAttack(source, an, 16*64*FRACUNIT, mask);
  1197. if (!linetarget)
  1198. slope = P_AimLineAttack(source, an += 1<<26, 16*64*FRACUNIT, mask);
  1199. if (!linetarget)
  1200. slope = P_AimLineAttack(source, an -= 2<<26, 16*64*FRACUNIT, mask);
  1201. if (!linetarget)
  1202. an = source->angle, slope = 0;
  1203. }
  1204. while (mask && (mask=0, !linetarget)); // killough 8/2/98
  1205. }
  1206. x = source->x;
  1207. y = source->y;
  1208. z = source->z + 4*8*FRACUNIT;
  1209. th = P_SpawnMobj (x,y,z, type);
  1210. if (th->info->seesound)
  1211. S_StartSound (th, th->info->seesound);
  1212. P_SetTarget(&th->target, source);
  1213. th->angle = an;
  1214. th->momx = FixedMul(th->info->speed,finecosine[an>>ANGLETOFINESHIFT]);
  1215. th->momy = FixedMul(th->info->speed,finesine[an>>ANGLETOFINESHIFT]);
  1216. th->momz = FixedMul(th->info->speed,slope);
  1217. P_CheckMissileSpawn(th);
  1218. }