C6_WIZ.C 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350
  1. /* Catacomb Apocalypse Source Code
  2. * Copyright (C) 1993-2014 Flat Rock Software
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. // C3_WIZ.C
  19. #include "DEF.H"
  20. #include "gelib.h"
  21. #pragma hdrstop
  22. /*
  23. =============================================================================
  24. LOCAL CONSTANTS
  25. =============================================================================
  26. */
  27. ////////#define NUMSCROLLS 8
  28. #define SHOWITEMS 9
  29. #define NUKETIME 40
  30. #define NUMBOLTS 10
  31. #define BOLTTICS 6
  32. #define STATUSCOLOR 1
  33. #define TEXTCOLOR 14
  34. #define SIDEBARWIDTH 5
  35. #define BODYLINE 8
  36. #define POWERLINE 80
  37. #define SPECTILESTART 0 // 18
  38. #define SHOTDAMAGE 1
  39. #define BIGSHOTDAMAGE 3
  40. #define PLAYERSPEED 5120
  41. #define RUNSPEED (8192<<1)
  42. #define SHOTSPEED 10000
  43. //#define LASTWALLTILE 47
  44. //#define LASTSPECIALTILE 37
  45. #define LASTTILE (LASTWALLPIC-FIRSTWALLPIC) // 47
  46. #define FIRETIME 2
  47. #define HANDPAUSE 30
  48. #define RIGHTEDGE 205;
  49. #define LEFTEDGE 95;
  50. #define PRNY 32;
  51. #define WINX 10;
  52. #define WINY 32;
  53. /*
  54. =============================================================================
  55. GLOBAL VARIABLES
  56. =============================================================================
  57. */
  58. long lastnuke,lasthand;
  59. int lasttext;
  60. int handheight;
  61. int boltsleft,bolttimer;
  62. short RadarXY[MAX_RADAR_BLIPS][3]={-1,-1,-1};
  63. short radarx=RADARX,radary=RADARY,radar_xcenter=RADAR_XCENTER,radar_ycenter=RADAR_YCENTER;
  64. int key_x[4]={24,27,27,24},key_y[4]={30,57,30,57};
  65. boolean redraw_gems,button0down;
  66. /*
  67. =============================================================================
  68. LOCAL VARIABLES
  69. =============================================================================
  70. */
  71. int lastradar;
  72. unsigned lastfiretime;
  73. int strafeangle[9] = {0,90,180,270,45,135,225,315,0};
  74. short RotateAngle = -1; // -1 == No Angle to turn to...
  75. short FreezeTime = 0; // Stops all think (except player)
  76. short RotateSpeed; // Speed (and dir) to rotate..
  77. //===========================================================================
  78. void CalcBounds(objtype *ob);
  79. boolean VerifyGateExit(void);
  80. void DrawNSEWIcons(void);
  81. void DrawGems(void);
  82. void DrawRadar (void);
  83. void DrawChar (unsigned x, unsigned y, unsigned tile);
  84. void RedrawStatusWindow (void);
  85. void GiveBolt (void);
  86. void TakeBolt (void);
  87. void GiveNuke (void);
  88. void TakeNuke (void);
  89. void GivePotion (void);
  90. void TakePotion (void);
  91. void GiveKey (int keytype);
  92. void TakeKey (int keytype);
  93. ////////////void GiveScroll (int scrolltype,boolean show);
  94. ////////////void ReadScroll (int scroll);
  95. ////////////void DrawScrolls(void);
  96. void DrawNum(short x,short y,short value,short maxdigits);
  97. //----------
  98. void Shoot (void);
  99. void BigShoot (void);
  100. void CastBolt (void);
  101. void CastNuke (void);
  102. void DrinkPotion (void);
  103. //----------
  104. void DrawHealth(void);
  105. void SpawnPlayer (int tilex, int tiley, int dir);
  106. void Thrust (int angle, unsigned speed);
  107. void T_Player (objtype *ob);
  108. //void AddPoints (int points);
  109. void ClipMove (objtype *ob, long xmove, long ymove);
  110. boolean ShotClipMove (objtype *ob, long xmove, long ymove);
  111. //===========================================================================
  112. /*
  113. ===============
  114. =
  115. = DrawChar
  116. =
  117. ===============
  118. */
  119. void DrawChar (unsigned x, unsigned y, unsigned tile)
  120. {
  121. unsigned junk = latchpics[0];
  122. EGAWRITEMODE(1);
  123. asm mov bx,[y]
  124. asm shl bx,1
  125. asm mov di,[WORD PTR ylookup+bx]
  126. asm add di,[x]
  127. asm mov si,[tile]
  128. asm shl si,1
  129. asm shl si,1
  130. asm shl si,1
  131. asm add si,[junk] // the damn inline assembler won't reference latchpics
  132. asm mov ax,[screenseg]
  133. asm mov es,ax
  134. asm mov ds,ax
  135. asm mov dx,SCREENWIDTH-1
  136. asm movsb
  137. asm add di,dx
  138. asm movsb
  139. asm add di,dx
  140. asm movsb
  141. asm add di,dx
  142. asm movsb
  143. asm add di,dx
  144. asm movsb
  145. asm add di,dx
  146. asm movsb
  147. asm add di,dx
  148. asm movsb
  149. asm add di,dx
  150. asm movsb
  151. asm mov ax,ss
  152. asm mov ds,ax
  153. EGAWRITEMODE(0);
  154. }
  155. //===========================================================================
  156. /*
  157. ===============
  158. =
  159. = RedrawStatusWindow
  160. =
  161. ===============
  162. */
  163. void RedrawStatusWindow (void)
  164. {
  165. short keytype;
  166. EGABITMASK(0xff);
  167. for (keytype=0; keytype<4; keytype++)
  168. DrawNum(key_x[keytype],key_y[keytype],gamestate.keys[keytype],2);
  169. DrawNum(20,54,gamestate.potions,2);
  170. DrawNum(20,36,gamestate.nukes,2);
  171. DrawNum(20,18,gamestate.bolts,2);
  172. DrawHealth();
  173. DrawRadar();
  174. EGAWRITEMODE(0);
  175. DrawGems();
  176. //////// DrawScrolls();
  177. redraw_gems = false;
  178. }
  179. //===========================================================================
  180. /*
  181. ===============
  182. =
  183. = GiveBolt
  184. =
  185. ===============
  186. */
  187. void GiveBolt (void)
  188. {
  189. if (gamestate.bolts == 99)
  190. return;
  191. SD_PlaySound (GETBOLTSND);
  192. DrawNum(20,18,++gamestate.bolts,2);
  193. }
  194. /*
  195. ===============
  196. =
  197. = TakeBolt
  198. =
  199. ===============
  200. */
  201. void TakeBolt (void)
  202. {
  203. SD_PlaySound (USEBOLTSND);
  204. DrawNum(20,18,--gamestate.bolts,2);
  205. }
  206. //===========================================================================
  207. /*
  208. ===============
  209. =
  210. = GiveNuke
  211. =
  212. ===============
  213. */
  214. void GiveNuke (void)
  215. {
  216. if (gamestate.nukes == 99)
  217. return;
  218. SD_PlaySound (GETNUKESND);
  219. DrawNum(20,36,++gamestate.nukes,2);
  220. }
  221. /*
  222. ===============
  223. =
  224. = TakeNuke
  225. =
  226. ===============
  227. */
  228. void TakeNuke (void)
  229. {
  230. SD_PlaySound (USENUKESND);
  231. DrawNum(20,36,--gamestate.nukes,2);
  232. }
  233. //===========================================================================
  234. /*
  235. ===============
  236. =
  237. = GivePotion
  238. =
  239. ===============
  240. */
  241. void GivePotion (void)
  242. {
  243. if (gamestate.potions == 99)
  244. return;
  245. SD_PlaySound (GETPOTIONSND);
  246. DrawNum(20,54,++gamestate.potions,2);
  247. }
  248. /*
  249. ===============
  250. =
  251. = TakePotion
  252. =
  253. ===============
  254. */
  255. void TakePotion (void)
  256. {
  257. SD_PlaySound (USEPOTIONSND);
  258. DrawNum(20,54,--gamestate.potions,2);
  259. }
  260. //===========================================================================
  261. /*
  262. ===============
  263. =
  264. = GiveKey
  265. =
  266. ===============
  267. */
  268. void GiveKey (int keytype)
  269. {
  270. int i,j,x;
  271. if (gamestate.keys[keytype] == 99)
  272. return;
  273. SD_PlaySound (GETKEYSND);
  274. DrawNum(key_x[keytype],key_y[keytype],++gamestate.keys[keytype],2);
  275. }
  276. /*
  277. ===============
  278. =
  279. = TakeKey
  280. =
  281. ===============
  282. */
  283. void TakeKey (int keytype)
  284. {
  285. int i,j,x;
  286. char *key_colors[] = {"a RED key",
  287. "a YELLOW key",
  288. "a GREEN key",
  289. "a BLUE key"};
  290. SD_PlaySound (USEKEYSND);
  291. DrawNum(key_x[keytype],key_y[keytype],--gamestate.keys[keytype],2);
  292. displayofs = bufferofs = screenloc[screenpage];
  293. CenterWindow(20,5);
  294. US_CPrint("\nYou use\n");
  295. US_CPrint(key_colors[keytype]);
  296. VW_UpdateScreen();
  297. VW_WaitVBL(120);
  298. }
  299. //===========================================================================
  300. /*
  301. ===============
  302. =
  303. = GiveGem
  304. =
  305. ===============
  306. */
  307. void GiveGem (int gemtype)
  308. {
  309. #if 0
  310. int i,j,x;
  311. SD_PlaySound (GETKEYSND);
  312. DrawNum(key_x[keytype],key_y[keytype],++gamestate.keys[keytype],2);
  313. #endif
  314. }
  315. /*
  316. ===============
  317. =
  318. = TakeGem
  319. =
  320. ===============
  321. */
  322. void TakeGem (int gemtype)
  323. {
  324. #if 0
  325. int i,j,x;
  326. SD_PlaySound (USEKEYSND);
  327. DrawNum(key_x[keytype],key_y[keytype],--gamestate.keys[keytype],2);
  328. #endif
  329. }
  330. /*
  331. ===============
  332. =
  333. = DrawGem
  334. =
  335. ===============
  336. */
  337. void DrawGems()
  338. {
  339. short loop;
  340. redraw_gems = false;
  341. bufferofs = 0;
  342. LatchDrawPic (31,51,RADAR_BOTTOMPIC);
  343. for (loop=0; loop<5; loop++)
  344. if (gamestate.gems[loop])
  345. LatchDrawPic (32+loop,53,RADAR_RGEMPIC+loop);
  346. }
  347. //===========================================================================
  348. #if 0
  349. /*
  350. ===============
  351. =
  352. = GiveScroll
  353. =
  354. ===============
  355. */
  356. void GiveScroll (int scrolltype,boolean show)
  357. {
  358. int i,j,x,y,scrollnum;
  359. SD_PlaySound (GETSCROLLSND);
  360. gamestate.scrolls[scrolltype] = true;
  361. y = 30 + ((scrolltype > 3) * 10);
  362. x = 26 + (scrolltype % 4);
  363. DrawChar(x,y,SCROLLCHARS+scrolltype);
  364. if (show)
  365. ReadScroll(scrolltype);
  366. }
  367. /*
  368. ===============
  369. =
  370. = DrawScrolls
  371. =
  372. = Force draw of all scrolls
  373. =
  374. ===============
  375. */
  376. void DrawScrolls()
  377. {
  378. int loop,x,y;
  379. VW_Bar(210,30,30,18,0xf);
  380. for (loop=0;loop<8;loop++)
  381. if (gamestate.scrolls[loop])
  382. {
  383. y = 30 + ((loop > 3) * 10);
  384. x = 26 + (loop % 4);
  385. DrawChar(x,y,SCROLLCHARS+loop);
  386. }
  387. }
  388. #endif
  389. //===========================================================================
  390. #if 0
  391. /*
  392. ===============
  393. =
  394. = GivePoints
  395. =
  396. ===============
  397. */
  398. void GivePoints (int points)
  399. {
  400. pointcount = 1;
  401. pointsleft += points;
  402. }
  403. #endif
  404. //===========================================================================
  405. #if 0
  406. /*
  407. ===============
  408. =
  409. = AddPoints
  410. =
  411. ===============
  412. */
  413. void AddPoints (int points)
  414. {
  415. char str[10];
  416. int len,x,i;
  417. gamestate.score += points;
  418. ltoa (gamestate.score,str,10);
  419. len = strlen (str);
  420. x=24+(8-len);
  421. for (i=0;i<len;i++)
  422. DrawChar(x++,40,NUMBERCHARS+str[i]-'0');
  423. }
  424. #endif
  425. //===========================================================================
  426. /*
  427. ===============
  428. =
  429. = DrawHealth
  430. =
  431. ===============
  432. */
  433. void DrawHealth()
  434. {
  435. char picnum;
  436. int percentage;
  437. percentage = PERCENTAGE(100,MAXBODY,gamestate.body,9);
  438. DrawNum(11,57,percentage,3);
  439. if (percentage > 75)
  440. picnum = FACE1PIC;
  441. else
  442. if (percentage > 50)
  443. picnum = FACE2PIC;
  444. else
  445. if (percentage > 25)
  446. picnum = FACE3PIC;
  447. else
  448. if (percentage)
  449. picnum = FACE4PIC;
  450. else
  451. {
  452. picnum = FACE5PIC;
  453. CA_CacheGrChunk (picnum);
  454. }
  455. bufferofs = 0;
  456. if (!percentage)
  457. {
  458. UNMARKGRCHUNK(picnum);
  459. // VW_DrawPic(8,14,picnum);
  460. VW_DrawPic(10,14,picnum);
  461. }
  462. else
  463. LatchDrawPic(10,14,picnum);
  464. }
  465. //===========================================================================
  466. /*
  467. ===============
  468. =
  469. = DrawFreezeTime
  470. =
  471. ===============
  472. */
  473. void DrawFreezeTime()
  474. {
  475. short temp = fontcolor;
  476. long percentage;
  477. percentage = PERCENTAGE(100,MAXFREEZETIME,(long)FreezeTime,7);
  478. fontcolor = 1 ^ 14;
  479. DrawNum(23,70,percentage,3);
  480. fontcolor = temp;
  481. }
  482. //===========================================================================
  483. /*
  484. ===============
  485. =
  486. = DrawNum
  487. =
  488. ===============
  489. */
  490. void DrawNum(short x,short y,short value,short maxdigits)
  491. {
  492. char str[10],len,i;
  493. itoa(value,str,10);
  494. len=strlen(str);
  495. for (i=len; i<maxdigits; i++)
  496. DrawChar(x++,y,BLANKCHAR);
  497. for (i=0;i<len;i++)
  498. DrawChar(x++,y,NUMBERCHARS+str[i]-'0');
  499. }
  500. //===========================================================================
  501. /*
  502. ===============
  503. =
  504. = GiveChest
  505. =
  506. ===============
  507. */
  508. void GiveChest(void)
  509. {
  510. char i;
  511. for (i=0;i<random(4);i++)
  512. {
  513. GiveBolt();
  514. SD_WaitSoundDone();
  515. }
  516. for (i=0;i<random(3);i++)
  517. {
  518. GiveNuke();
  519. SD_WaitSoundDone();
  520. }
  521. for (i=0;i<random(2);i++)
  522. {
  523. GivePotion();
  524. SD_WaitSoundDone();
  525. }
  526. }
  527. //===========================================================================
  528. /*
  529. ===============
  530. =
  531. = GiveGoal
  532. =
  533. ===============
  534. */
  535. void GiveGoal (void)
  536. {
  537. SD_PlaySound (GETPOINTSSND);
  538. playstate = ex_victorious;
  539. }
  540. //===========================================================================
  541. #if 0
  542. /*
  543. ===============
  544. =
  545. = DrawLevelNumber
  546. =
  547. ===============
  548. */
  549. void DrawLevelNumber (int number)
  550. {
  551. char str[10];
  552. int len;
  553. unsigned temp;
  554. bufferofs = 0;
  555. if (number<9)
  556. PrintX=13;
  557. else
  558. PrintX = 5;
  559. PrintY = 4;
  560. VW_Bar (5,4,16,9,STATUSCOLOR);
  561. temp = fontcolor;
  562. fontcolor = TEXTCOLOR^STATUSCOLOR;
  563. US_PrintUnsigned (number+1);
  564. fontcolor = temp;
  565. }
  566. #endif
  567. //===========================================================================
  568. /*
  569. ===============
  570. =
  571. = DrawText
  572. =
  573. ===============
  574. */
  575. void DrawText (boolean draw_text_whether_it_needs_it_or_not)
  576. {
  577. unsigned number;
  578. char str[80];
  579. char far *text;
  580. unsigned temp;
  581. //
  582. // draw a new text description if needed
  583. //
  584. number = *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex)-NAMESTART;
  585. if ( number>26 )
  586. number = 0;
  587. if ((number == lasttext) && (!draw_text_whether_it_needs_it_or_not))
  588. return;
  589. lasttext = number;
  590. text = (char _seg *)grsegs[LEVEL1TEXT+mapon]+textstarts[number];
  591. if (text[0] == '@')
  592. {
  593. bordertime = 20;//FLASHTICS;
  594. bcolor = 15;
  595. VW_ColorBorder (15 | 56);
  596. text++;
  597. }
  598. _fmemcpy (str,text,80);
  599. DisplayMsg(str,NULL);
  600. }
  601. //===========================================================================
  602. /*
  603. ===============
  604. =
  605. = DisplayMsg
  606. =
  607. ===============
  608. */
  609. char DisplayMsg(char *text,char *choices)
  610. {
  611. char ch=true;
  612. short temp;
  613. bufferofs = 0;
  614. PrintY = 1;
  615. WindowX = 20;
  616. WindowW = 270;
  617. VW_Bar (WindowX,2,WindowW,8,STATUSCOLOR);
  618. temp = fontcolor;
  619. fontcolor = TEXTCOLOR^STATUSCOLOR;
  620. US_CPrintLine (text);
  621. fontcolor = temp;
  622. if (choices)
  623. {
  624. ch=GetKeyChoice(choices,true);
  625. LastScan = 0;
  626. }
  627. return(ch);
  628. }
  629. /*
  630. ===============
  631. =
  632. = DisplaySMsg
  633. =
  634. ===============
  635. */
  636. char DisplaySMsg(char *text,char *choices)
  637. {
  638. char ch=true;
  639. short temp;
  640. bufferofs = 0;
  641. PrintY = 69;
  642. WindowX = 98;
  643. WindowW = 115;
  644. VW_Bar(WindowX,PrintY+1,WindowW,8,STATUSCOLOR);
  645. temp = fontcolor;
  646. fontcolor = TEXTCOLOR^STATUSCOLOR;
  647. US_CPrintLine (text);
  648. fontcolor = temp;
  649. if (choices)
  650. {
  651. ch=GetKeyChoice(choices,true);
  652. LastScan = 0;
  653. }
  654. return(ch);
  655. }
  656. //===========================================================================
  657. /*
  658. ===============
  659. =
  660. = DrawRadar
  661. =
  662. ===============
  663. */
  664. void DrawRadar (void)
  665. {
  666. int angle,number;
  667. short objnum;
  668. bufferofs = 0;
  669. LatchDrawPic (radarx,radary,RADAR_TOPPIC);
  670. asm cli
  671. asm mov dx,GC_INDEX
  672. asm mov ax,2*256+GC_MODE
  673. asm out dx,ax // write mode 2
  674. asm mov ax,GC_DATAROTATE
  675. asm out dx,ax // no rotation / logical operation
  676. asm mov dx,SC_INDEX
  677. asm mov al,SC_MAPMASK
  678. asm mov ah,15
  679. asm out dx,ax // write to all four planes
  680. asm sti
  681. objnum = 0;
  682. while (RadarXY[objnum][2] != -1)
  683. {
  684. RadarBlip(radar_xcenter+RadarXY[objnum][0],radar_ycenter+RadarXY[objnum][1],RadarXY[objnum][2]);
  685. objnum++;
  686. }
  687. asm cli
  688. asm mov dx,GC_INDEX
  689. asm mov ax,255*256+GC_BITMASK
  690. asm out dx,ax // reset bitmask to %11111111
  691. asm sti
  692. }
  693. //===========================================================================
  694. //--------------------------------------------------------------------------
  695. // DrawNSEWIcons(void)
  696. //--------------------------------------------------------------------------
  697. void DrawRadarObj(short dx, short dy, unsigned sprnum,signed long psin,signed long pcos);
  698. void DrawNSEWIcons()
  699. {
  700. signed x,y;
  701. x = -FixedByFrac(RADAR_X_IRADIUS,costable[player->angle]);
  702. y = -FixedByFrac(RADAR_Y_IRADIUS,sintable[player->angle]);
  703. VWB_DrawSprite(radar_xcenter+x-3,radar_ycenter+y-3,NORTHICONSPR);
  704. }
  705. #if 0
  706. /*
  707. ===============
  708. =
  709. = DrawBars
  710. =
  711. ===============
  712. */
  713. void DrawBars (void)
  714. {
  715. int i;
  716. unsigned source,dest,topline;
  717. for (i=0;i<3;i++)
  718. {
  719. bufferofs = screenloc[i];
  720. VW_Bar (34*8,POWERLINE,40,MAXSHOTPOWER,1);
  721. }
  722. EGAWRITEMODE(1);
  723. asm mov es,[screenseg]
  724. //
  725. // shot power
  726. //
  727. if (gamestate.shotpower)
  728. {
  729. topline = MAXSHOTPOWER - gamestate.shotpower;
  730. source = latchpics[SHOTPOWERPIC-FIRSTLATCHPIC]+topline*SIDEBARWIDTH;
  731. dest = (POWERLINE+topline)*SCREENWIDTH+34;
  732. asm mov si,[source]
  733. asm mov di,[dest]
  734. asm mov cx,[WORD PTR gamestate.shotpower]
  735. newline:
  736. asm mov al,[es:si]
  737. asm mov [es:di+PAGE1START],al
  738. asm mov [es:di+PAGE2START],al
  739. asm mov [es:di+PAGE3START],al
  740. asm mov al,[es:si+1]
  741. asm mov [es:di+1+PAGE1START],al
  742. asm mov [es:di+1+PAGE2START],al
  743. asm mov [es:di+1+PAGE3START],al
  744. asm mov al,[es:si+2]
  745. asm mov [es:di+2+PAGE1START],al
  746. asm mov [es:di+2+PAGE2START],al
  747. asm mov [es:di+2+PAGE3START],al
  748. asm mov al,[es:si+3]
  749. asm mov [es:di+3+PAGE1START],al
  750. asm mov [es:di+3+PAGE2START],al
  751. asm mov [es:di+3+PAGE3START],al
  752. asm mov al,[es:si+4]
  753. asm mov [es:di+4+PAGE1START],al
  754. asm mov [es:di+4+PAGE2START],al
  755. asm mov [es:di+4+PAGE3START],al
  756. asm add di,SCREENWIDTH
  757. asm add si,5
  758. asm loop newline
  759. }
  760. //
  761. // body
  762. //
  763. if (gamestate.body)
  764. {
  765. source = latchpics[BODYPIC-FIRSTLATCHPIC];
  766. dest = BODYLINE*SCREENWIDTH+34;
  767. asm mov si,[source]
  768. asm mov di,[dest]
  769. asm mov cx,[WORD PTR gamestate.body]
  770. newline2:
  771. asm mov al,[es:si]
  772. asm mov [es:di+PAGE1START],al
  773. asm mov [es:di+PAGE2START],al
  774. asm mov [es:di+PAGE3START],al
  775. asm mov al,[es:si+1]
  776. asm mov [es:di+1+PAGE1START],al
  777. asm mov [es:di+1+PAGE2START],al
  778. asm mov [es:di+1+PAGE3START],al
  779. asm mov al,[es:si+2]
  780. asm mov [es:di+2+PAGE1START],al
  781. asm mov [es:di+2+PAGE2START],al
  782. asm mov [es:di+2+PAGE3START],al
  783. asm mov al,[es:si+3]
  784. asm mov [es:di+3+PAGE1START],al
  785. asm mov [es:di+3+PAGE2START],al
  786. asm mov [es:di+3+PAGE3START],al
  787. asm mov al,[es:si+4]
  788. asm mov [es:di+4+PAGE1START],al
  789. asm mov [es:di+4+PAGE2START],al
  790. asm mov [es:di+4+PAGE3START],al
  791. asm add di,SCREENWIDTH
  792. asm add si,5
  793. asm loop newline2
  794. }
  795. if (gamestate.body != MAXBODY)
  796. {
  797. source = latchpics[NOBODYPIC-FIRSTLATCHPIC]+gamestate.body*SIDEBARWIDTH;
  798. dest = (BODYLINE+gamestate.body)*SCREENWIDTH+34;
  799. topline = MAXBODY-gamestate.body;
  800. asm mov si,[source]
  801. asm mov di,[dest]
  802. asm mov cx,[WORD PTR topline]
  803. newline3:
  804. asm mov al,[es:si]
  805. asm mov [es:di+PAGE1START],al
  806. asm mov [es:di+PAGE2START],al
  807. asm mov [es:di+PAGE3START],al
  808. asm mov al,[es:si+1]
  809. asm mov [es:di+1+PAGE1START],al
  810. asm mov [es:di+1+PAGE2START],al
  811. asm mov [es:di+1+PAGE3START],al
  812. asm mov al,[es:si+2]
  813. asm mov [es:di+2+PAGE1START],al
  814. asm mov [es:di+2+PAGE2START],al
  815. asm mov [es:di+2+PAGE3START],al
  816. asm mov al,[es:si+3]
  817. asm mov [es:di+3+PAGE1START],al
  818. asm mov [es:di+3+PAGE2START],al
  819. asm mov [es:di+3+PAGE3START],al
  820. asm mov al,[es:si+4]
  821. asm mov [es:di+4+PAGE1START],al
  822. asm mov [es:di+4+PAGE2START],al
  823. asm mov [es:di+4+PAGE3START],al
  824. asm add di,SCREENWIDTH
  825. asm add si,5
  826. asm loop newline3
  827. }
  828. EGAWRITEMODE(0);
  829. }
  830. #endif
  831. /////////////////////////////////////////////////////////////////////////////
  832. //
  833. // Check the object and make sure it is a monster. Used in making the sound
  834. // of a monster being shot.
  835. //
  836. /////////////////////////////////////////////////////////////////////////////
  837. boolean PlayMonsterSound(classtype objclass)
  838. {
  839. switch (objclass)
  840. {
  841. case solidobj:
  842. case realsolidobj:
  843. return false;
  844. default:
  845. return true;
  846. }
  847. }
  848. /*
  849. =============================================================================
  850. SHOTS
  851. =============================================================================
  852. */
  853. void T_Pshot (objtype *ob);
  854. extern statetype s_pshot1;
  855. extern statetype s_pshot2;
  856. //extern statetype s_bigpshot1;
  857. //extern statetype s_bigpshot2;
  858. statetype s_pshot1 = {PSHOT1PIC,8,&T_Pshot,&s_pshot2};
  859. statetype s_pshot2 = {PSHOT2PIC,8,&T_Pshot,&s_pshot1};
  860. statetype s_pshot_exp1 = {PSHOT_EXP1PIC,7,NULL,&s_pshot_exp2};
  861. statetype s_pshot_exp2 = {PSHOT_EXP2PIC,7,NULL,&s_pshot_exp3};
  862. statetype s_pshot_exp3 = {PSHOT_EXP3PIC,7,NULL,NULL};
  863. //statetype s_shotexplode = {PSHOT2PIC,8,NULL,NULL};
  864. //statetype s_bigpshot1 = {BIGPSHOT1PIC,8,&T_Pshot,&s_bigpshot2};
  865. //statetype s_bigpshot2 = {BIGPSHOT2PIC,8,&T_Pshot,&s_bigpshot1};
  866. /*
  867. ===================
  868. =
  869. = SpawnPShot
  870. =
  871. ===================
  872. */
  873. void SpawnPShot (void)
  874. {
  875. DSpawnNewObjFrac (player->x,player->y,&s_pshot1,PIXRADIUS*2);
  876. new->obclass = pshotobj;
  877. new->speed = SHOTSPEED;
  878. new->angle = player->angle;
  879. new->active = always;
  880. }
  881. #if 0
  882. void SpawnBigPShot (void)
  883. {
  884. SpawnNewObjFrac (player->x,player->y,&s_bigpshot1,24*PIXRADIUS);
  885. new->obclass = bigpshotobj;
  886. new->speed = SHOTSPEED;
  887. new->angle = player->angle;
  888. }
  889. #endif
  890. /*
  891. ===================
  892. =
  893. = JimsShotClipMove
  894. =
  895. = Only checks corners, so the object better be less than one tile wide!
  896. =
  897. ===================
  898. */
  899. boolean JimsShotClipMove (objtype *ob, long xmove, long ymove)
  900. {
  901. int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
  902. long intersect,basex,basey,pointx,pointy;
  903. unsigned inside,total,tile;
  904. objtype *check;
  905. boolean moveok;
  906. //
  907. // move player and check to see if any corners are in solid tiles
  908. //
  909. // basex = ob->x;
  910. // basey = ob->y;
  911. // ob->x += xmove;
  912. // ob->y += ymove;
  913. // CalcBounds (ob);
  914. xl = ob->xl>>TILESHIFT;
  915. yl = ob->yl>>TILESHIFT;
  916. xh = ob->xh>>TILESHIFT;
  917. yh = ob->yh>>TILESHIFT;
  918. for (y=yl;y<=yh;y++)
  919. for (x=xl;x<=xh;x++)
  920. {
  921. check = actorat[x][y];
  922. if ((!check) || (check == player) || (!(check->flags & of_shootable)))
  923. continue;
  924. ob->x -= xmove;
  925. ob->y -= ymove;
  926. if (check->obclass != solidobj)
  927. {
  928. if (PlayMonsterSound(check->obclass))
  929. SD_PlaySound (SHOOTMONSTERSND);
  930. if (ob->obclass == bigpshotobj)
  931. ShootActor (check,BIGSHOTDAMAGE);
  932. else
  933. ShootActor (check,SHOTDAMAGE);
  934. }
  935. else
  936. if (check->obclass == solidobj && (check->flags & of_forcefield))
  937. {
  938. if (PlayMonsterSound(check->obclass))
  939. SD_PlaySound (SHOOTMONSTERSND);
  940. if (ob->obclass == bigpshotobj)
  941. ShootActor (check,BIGSHOTDAMAGE);
  942. else
  943. ShootActor (check,SHOTDAMAGE);
  944. }
  945. ob->state = &s_pshot_exp1;
  946. ob->ticcount = ob->state->tictime;
  947. return(true);
  948. }
  949. return(false); // move is OK!
  950. }
  951. /*
  952. ===============
  953. =
  954. = T_Pshot
  955. =
  956. ===============
  957. */
  958. #if 0
  959. void T_Pshot (objtype *ob)
  960. {
  961. objtype *check;
  962. long xmove,ymove,speed;
  963. //
  964. // check current position for monsters having moved into it
  965. //
  966. for (check = player->next; check; check=check->next)
  967. if ((check->flags & of_shootable)
  968. && ob->xl <= check->xh
  969. && ob->xh >= check->xl
  970. && ob->yl <= check->yh
  971. && ob->yh >= check->yl)
  972. {
  973. if (check->obclass != solidobj)
  974. {
  975. if (PlayMonsterSound(check->obclass))
  976. SD_PlaySound (SHOOTMONSTERSND);
  977. if (ob->obclass == bigpshotobj)
  978. ShootActor (check,BIGSHOTDAMAGE);
  979. else
  980. ShootActor (check,SHOTDAMAGE);
  981. }
  982. ob->state = &s_pshot_exp1;
  983. ob->ticcount = ob->state->tictime;
  984. return;
  985. }
  986. //
  987. // move ahead, possibly hitting a wall
  988. //
  989. speed = ob->speed*tics;
  990. xmove = FixedByFrac(speed,costable[ob->angle]);
  991. ymove = -FixedByFrac(speed,sintable[ob->angle]);
  992. if (ShotClipMove(ob,xmove,ymove))
  993. {
  994. ob->state = &s_pshot_exp1;
  995. ob->ticcount = ob->state->tictime;
  996. return;
  997. }
  998. ob->tilex = ob->x >> TILESHIFT;
  999. ob->tiley = ob->y >> TILESHIFT;
  1000. //
  1001. // check final position for monsters hit
  1002. //
  1003. for (check = player->next; check; check=check->next)
  1004. if ((ob->flags & of_shootable)
  1005. && ob->xl <= check->xh
  1006. && ob->xh >= check->xl
  1007. && ob->yl <= check->yh
  1008. && ob->yh >= check->yl)
  1009. {
  1010. ShootActor (check,SHOTDAMAGE);
  1011. ob->state = &s_pshot_exp1;
  1012. ob->ticcount = ob->state->tictime;
  1013. return;
  1014. }
  1015. }
  1016. #endif
  1017. void T_Pshot (objtype *ob)
  1018. {
  1019. objtype *check;
  1020. long xmove,ymove,speed;
  1021. int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
  1022. long intersect,basex,basey,pointx,pointy;
  1023. unsigned inside,total,tile;
  1024. boolean moveok;
  1025. //
  1026. // check current position for monsters having moved into it
  1027. //
  1028. for (check = player->next; check; check=check->next)
  1029. if ((check->flags & of_shootable)
  1030. && ob->xl <= check->xh
  1031. && ob->xh >= check->xl
  1032. && ob->yl <= check->yh
  1033. && ob->yh >= check->yl)
  1034. {
  1035. if (check->obclass != solidobj)
  1036. {
  1037. if (PlayMonsterSound(check->obclass))
  1038. SD_PlaySound (SHOOTMONSTERSND);
  1039. if (ob->obclass == bigpshotobj)
  1040. ShootActor (check,BIGSHOTDAMAGE);
  1041. else
  1042. ShootActor (check,SHOTDAMAGE);
  1043. }
  1044. ob->state = &s_pshot_exp1;
  1045. ob->obclass = expobj;
  1046. ob->ticcount = ob->state->tictime;
  1047. return;
  1048. }
  1049. //
  1050. // move ahead, possibly hitting a wall
  1051. //
  1052. speed = ob->speed*tics;
  1053. xmove = FixedByFrac(speed,costable[ob->angle]);
  1054. ymove = -FixedByFrac(speed,sintable[ob->angle]);
  1055. if (ShotClipMove(ob,xmove,ymove))
  1056. {
  1057. ob->state = &s_pshot_exp1;
  1058. ob->obclass = expobj;
  1059. ob->ticcount = ob->state->tictime;
  1060. return;
  1061. }
  1062. ob->tilex = ob->x >> TILESHIFT;
  1063. ob->tiley = ob->y >> TILESHIFT;
  1064. //
  1065. // check final position for monsters hit
  1066. //
  1067. JimsShotClipMove(obj,xmove,ymove);
  1068. }
  1069. /*
  1070. =============================================================================
  1071. PLAYER ACTIONS
  1072. =============================================================================
  1073. */
  1074. /*
  1075. ===============
  1076. =
  1077. = BuildShotPower
  1078. =
  1079. ===============
  1080. */
  1081. void BuildShotPower (void)
  1082. {
  1083. int newlines,topline;
  1084. long i;
  1085. unsigned source,dest;
  1086. if (gamestate.shotpower == MAXSHOTPOWER)
  1087. return;
  1088. newlines = 0;
  1089. for (i=lasttimecount-realtics;i<lasttimecount;i++)
  1090. newlines += (i&1);
  1091. gamestate.shotpower += newlines;
  1092. if (gamestate.shotpower > MAXSHOTPOWER)
  1093. {
  1094. newlines -= (gamestate.shotpower - MAXSHOTPOWER);
  1095. gamestate.shotpower = MAXSHOTPOWER;
  1096. }
  1097. }
  1098. //===========================================================================
  1099. /*
  1100. ===============
  1101. =
  1102. = ClearShotPower
  1103. =
  1104. ===============
  1105. */
  1106. void ClearShotPower (void)
  1107. {
  1108. unsigned source,dest,topline;
  1109. #if 0
  1110. topline = MAXSHOTPOWER - gamestate.shotpower;
  1111. source = latchpics[L_NOSHOT]+topline*SIDEBARWIDTH;
  1112. dest = (POWERLINE+topline)*SCREENWIDTH+34;
  1113. asm mov es,[screenseg]
  1114. asm mov si,[source]
  1115. asm mov di,[dest]
  1116. if (!gamestate.shotpower)
  1117. return;
  1118. EGAWRITEMODE(1);
  1119. asm mov cx,[WORD PTR gamestate.shotpower]
  1120. newline:
  1121. asm mov al,[es:si]
  1122. asm mov [es:di+PAGE1START],al
  1123. asm mov [es:di+PAGE2START],al
  1124. asm mov [es:di+PAGE3START],al
  1125. asm mov al,[es:si+1]
  1126. asm mov [es:di+1+PAGE1START],al
  1127. asm mov [es:di+1+PAGE2START],al
  1128. asm mov [es:di+1+PAGE3START],al
  1129. asm mov al,[es:si+2]
  1130. asm mov [es:di+2+PAGE1START],al
  1131. asm mov [es:di+2+PAGE2START],al
  1132. asm mov [es:di+2+PAGE3START],al
  1133. asm mov al,[es:si+3]
  1134. asm mov [es:di+3+PAGE1START],al
  1135. asm mov [es:di+3+PAGE2START],al
  1136. asm mov [es:di+3+PAGE3START],al
  1137. asm mov al,[es:si+4]
  1138. asm mov [es:di+4+PAGE1START],al
  1139. asm mov [es:di+4+PAGE2START],al
  1140. asm mov [es:di+4+PAGE3START],al
  1141. asm add di,SCREENWIDTH
  1142. asm add si,5
  1143. asm loop newline
  1144. EGAWRITEMODE(0);
  1145. #endif
  1146. gamestate.shotpower = 0;
  1147. }
  1148. //===========================================================================
  1149. /*
  1150. ===============
  1151. =
  1152. = Shoot
  1153. =
  1154. ===============
  1155. */
  1156. void Shoot (void)
  1157. {
  1158. ClearShotPower ();
  1159. SD_PlaySound (SHOOTSND);
  1160. SpawnPShot ();
  1161. }
  1162. //===========================================================================
  1163. #if 0
  1164. /*
  1165. ===============
  1166. =
  1167. = BigShoot
  1168. =
  1169. ===============
  1170. */
  1171. void BigShoot (void)
  1172. {
  1173. ClearShotPower ();
  1174. SD_PlaySound (BIGSHOOTSND);
  1175. SpawnBigPShot ();
  1176. }
  1177. #endif
  1178. //===========================================================================
  1179. /*
  1180. ===============
  1181. =
  1182. = CastBolt
  1183. =
  1184. ===============
  1185. */
  1186. void CastBolt (void)
  1187. {
  1188. if (!gamestate.bolts)
  1189. {
  1190. SD_PlaySound (NOITEMSND);
  1191. return;
  1192. }
  1193. TakeBolt ();
  1194. boltsleft = NUMBOLTS;
  1195. bolttimer = BOLTTICS;
  1196. Shoot ();
  1197. }
  1198. /*
  1199. ===============
  1200. =
  1201. = ContinueBolt
  1202. =
  1203. ===============
  1204. */
  1205. void ContinueBolt (void)
  1206. {
  1207. bolttimer-=realtics;
  1208. if (bolttimer<0)
  1209. {
  1210. boltsleft--;
  1211. bolttimer = BOLTTICS;
  1212. Shoot ();
  1213. }
  1214. }
  1215. //===========================================================================
  1216. /*
  1217. ===============
  1218. =
  1219. = CastNuke
  1220. =
  1221. ===============
  1222. */
  1223. void CastNuke (void)
  1224. {
  1225. // extern boolean autofire;
  1226. int angle;
  1227. if (!gamestate.nukes)
  1228. {
  1229. SD_PlaySound (NOITEMSND);
  1230. return;
  1231. }
  1232. // if (!autofire)
  1233. TakeNuke ();
  1234. lastnuke = TimeCount;
  1235. for (angle = 0; angle < ANGLES; angle+= ANGLES/16)
  1236. {
  1237. DSpawnNewObjFrac (player->x,player->y,&s_pshot1,24*PIXRADIUS);
  1238. new->obclass = bigpshotobj;
  1239. new->speed = SHOTSPEED;
  1240. new->angle = angle;
  1241. new->active = always;
  1242. }
  1243. }
  1244. //===========================================================================
  1245. /*
  1246. ===============
  1247. =
  1248. = DrinkPotion
  1249. =
  1250. ===============
  1251. */
  1252. void DrinkPotion (void)
  1253. {
  1254. unsigned source,dest,topline;
  1255. if (!gamestate.potions)
  1256. {
  1257. SD_PlaySound (NOITEMSND);
  1258. return;
  1259. }
  1260. DisplaySMsg("Curing", NULL);
  1261. TakePotion ();
  1262. gamestate.body = MAXBODY;
  1263. VW_WaitVBL(30);
  1264. status_flag = S_NONE;
  1265. #if 0
  1266. //
  1267. // draw a full up bar
  1268. //
  1269. source = latchpics[L_BODYBAR];
  1270. dest = BODYLINE*SCREENWIDTH+34;
  1271. asm mov es,[screenseg]
  1272. asm mov si,[source]
  1273. asm mov di,[dest]
  1274. EGAWRITEMODE(1);
  1275. asm mov cx,MAXBODY
  1276. newline:
  1277. asm mov al,[es:si]
  1278. asm mov [es:di+PAGE1START],al
  1279. asm mov [es:di+PAGE2START],al
  1280. asm mov [es:di+PAGE3START],al
  1281. asm mov al,[es:si+1]
  1282. asm mov [es:di+1+PAGE1START],al
  1283. asm mov [es:di+1+PAGE2START],al
  1284. asm mov [es:di+1+PAGE3START],al
  1285. asm mov al,[es:si+2]
  1286. asm mov [es:di+2+PAGE1START],al
  1287. asm mov [es:di+2+PAGE2START],al
  1288. asm mov [es:di+2+PAGE3START],al
  1289. asm mov al,[es:si+3]
  1290. asm mov [es:di+3+PAGE1START],al
  1291. asm mov [es:di+3+PAGE2START],al
  1292. asm mov [es:di+3+PAGE3START],al
  1293. asm mov al,[es:si+4]
  1294. asm mov [es:di+4+PAGE1START],al
  1295. asm mov [es:di+4+PAGE2START],al
  1296. asm mov [es:di+4+PAGE3START],al
  1297. asm add di,SCREENWIDTH
  1298. asm add si,5
  1299. asm loop newline
  1300. EGAWRITEMODE(0);
  1301. #endif
  1302. }
  1303. //===========================================================================
  1304. #if 0
  1305. ////////////////////////////////////////////////////////////////////////////
  1306. //
  1307. // GetScrollText
  1308. //
  1309. // parms - scroll -- the number of the scroll to display
  1310. // returns - a far pointer to the scroll text
  1311. //
  1312. ////////////////////////////////////////////////////////////////////////////
  1313. char far *GetScrollText (int scroll)
  1314. {
  1315. boolean found;
  1316. int i;
  1317. char far *txt;
  1318. unsigned ofset;
  1319. CA_CacheGrChunk(SCROLLTEXT);
  1320. found = false;
  1321. i = 0;
  1322. txt = (char _seg *)grsegs[SCROLLTEXT];
  1323. while (!found)
  1324. {
  1325. while (*txt != '\n')
  1326. {
  1327. if (*txt == '\r')
  1328. *txt = 0;
  1329. txt++;
  1330. }
  1331. txt++;
  1332. if (i == scroll)
  1333. {
  1334. found = true;
  1335. ofset = FP_OFF(txt);
  1336. while (*txt != '\n')
  1337. {
  1338. if (*txt == '\r')
  1339. *txt = 0;
  1340. txt++;
  1341. }
  1342. }
  1343. i++;
  1344. }
  1345. txt = (char _seg *)grsegs[SCROLLTEXT]+ofset;
  1346. UNMARKGRCHUNK(SCROLLTEXT);
  1347. return(txt);
  1348. } //End of GetScrollText
  1349. //===========================================================================
  1350. /*
  1351. ===============
  1352. =
  1353. = ReadScroll
  1354. =
  1355. ===============
  1356. */
  1357. extern boolean tileneeded[NUMFLOORS];
  1358. void ReadScroll (int scroll)
  1359. {
  1360. PresenterInfo pi;
  1361. int i;
  1362. unsigned *skytemp,*gndtemp,blackcolor=0;
  1363. char far *scrolltext;
  1364. DisplaySMsg("Reading Scroll", NULL);
  1365. bufferofs = displayofs = screenloc[screenpage];
  1366. if (status_flag != S_TIMESTOP)
  1367. status_flag = S_NONE;
  1368. FreeUpMemory();
  1369. CA_CacheGrChunk (SCROLLTOPPIC);
  1370. CA_CacheGrChunk (SCROLL1PIC);
  1371. CA_CacheGrChunk (SCROLLBOTTOMPIC);
  1372. skytemp = skycolor;
  1373. gndtemp = groundcolor;
  1374. skycolor = groundcolor = &blackcolor;
  1375. VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);
  1376. VW_DrawPic (10,0,SCROLLTOPPIC);
  1377. VW_DrawPic (10,32,SCROLL1PIC);
  1378. VW_DrawPic (10,88,SCROLLBOTTOMPIC);
  1379. scrolltext = GetScrollText(scroll);
  1380. pi.xl = LEFTEDGE;
  1381. pi.yl = PRNY;
  1382. pi.xh = RIGHTEDGE;
  1383. pi.yh = PRNY+1;
  1384. pi.bgcolor = 7;
  1385. pi.script[0] = (char far *)scrolltext;
  1386. Presenter(&pi);
  1387. skycolor = skytemp;
  1388. groundcolor = gndtemp;
  1389. UNMARKGRCHUNK(SCROLL1PIC);
  1390. UNMARKGRCHUNK(SCROLLTOPPIC);
  1391. UNMARKGRCHUNK(SCROLLBOTTOMPIC);
  1392. MM_FreePtr (&grsegs[SCROLL1PIC]);
  1393. MM_FreePtr (&grsegs[SCROLLTOPPIC]);
  1394. MM_FreePtr (&grsegs[SCROLLBOTTOMPIC]);
  1395. CacheScaleds();
  1396. IN_ClearKeysDown ();
  1397. lasttext = -1;
  1398. DisplayMsg("Press ENTER or ESC to exit.",NULL);
  1399. while ((!Keyboard[sc_Escape]) && (!Keyboard[sc_Enter]));
  1400. IN_ClearKeysDown ();
  1401. if (status_flag == S_TIMESTOP)
  1402. DisplaySMsg("Time Stopped: ",NULL);
  1403. }
  1404. #endif
  1405. //===============
  1406. //
  1407. // StopTime()
  1408. //
  1409. //
  1410. //===============
  1411. void StopTime()
  1412. {
  1413. FreezeTime = MAXFREEZETIME;
  1414. SD_PlaySound(FREEZETIMESND);
  1415. DisplaySMsg("Time Stopped: ",NULL);
  1416. status_flag = S_TIMESTOP;
  1417. }
  1418. /*
  1419. ===============
  1420. =
  1421. = TakeDamage
  1422. =
  1423. ===============
  1424. */
  1425. void TakeDamage (int points)
  1426. {
  1427. unsigned source,dest,topline;
  1428. if (!gamestate.body || (bordertime && bcolor==FLASHCOLOR) || godmode)
  1429. return;
  1430. points = EasyDoDamage(points);
  1431. if (points >= gamestate.body)
  1432. {
  1433. points = gamestate.body;
  1434. Flags |= FL_DEAD;
  1435. }
  1436. bordertime = FLASHTICS<<2;
  1437. bcolor = FLASHCOLOR;
  1438. VW_ColorBorder (FLASHCOLOR);
  1439. DisplaySMsg("Damaging blows!", NULL);
  1440. status_flag = S_NONE;
  1441. status_delay = 80;
  1442. if (gamestate.body<MAXBODY/3)
  1443. SD_PlaySound (TAKEDMGHURTSND);
  1444. else
  1445. SD_PlaySound (TAKEDAMAGESND);
  1446. gamestate.body -= points;
  1447. }
  1448. /*
  1449. =============================================================================
  1450. INTERACTION
  1451. =============================================================================
  1452. */
  1453. #if 0
  1454. /*
  1455. ==================
  1456. =
  1457. = OpenDoor
  1458. =
  1459. ==================
  1460. */
  1461. void OpenDoor (unsigned bx, unsigned by, unsigned doorbase)
  1462. {
  1463. int x,y;
  1464. unsigned far *map;
  1465. x=bx;
  1466. y=by;
  1467. map = mapsegs[0]+farmapylookup[y]+x;
  1468. while (tilemap[x][y]-doorbase<4)
  1469. {
  1470. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1471. map--;
  1472. x--;
  1473. }
  1474. x=bx+1;
  1475. map = mapsegs[0]+farmapylookup[y]+x;
  1476. while (tilemap[x][y]-doorbase<4)
  1477. {
  1478. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1479. map++;
  1480. x++;
  1481. }
  1482. x=bx;
  1483. y=by-1;
  1484. map = mapsegs[0]+farmapylookup[y]+x;
  1485. while (tilemap[x][y]-doorbase<4)
  1486. {
  1487. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1488. map-=mapwidth;
  1489. y--;
  1490. }
  1491. y=by+1;
  1492. map = mapsegs[0]+farmapylookup[y]+x;
  1493. while (tilemap[x][y]-doorbase<4)
  1494. {
  1495. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1496. map+=mapwidth;
  1497. y++;
  1498. }
  1499. }
  1500. #endif
  1501. #if 0
  1502. /*
  1503. ==================
  1504. =
  1505. = RemoveWalls - similar to OpenDoor(), but on a different plane
  1506. =
  1507. ==================
  1508. */
  1509. void RemoveWalls (unsigned bx, unsigned by, unsigned remove_code)
  1510. {
  1511. int x,y;
  1512. unsigned far *map,*p2;
  1513. x=bx;
  1514. y=by;
  1515. p2 = *(mapsegs[2]+farmapylookup[y]+x);
  1516. map = mapsegs[0]+farmapylookup[y]+x;
  1517. while (*p2 == remove_code)
  1518. {
  1519. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1520. map--;
  1521. p2--;
  1522. x--;
  1523. }
  1524. x=bx+1;
  1525. p2 = *(mapsegs[2]+farmapylookup[y]+x);
  1526. map = mapsegs[0]+farmapylookup[y]+x;
  1527. while (*p2 == remove_code)
  1528. {
  1529. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1530. map++;
  1531. p2++;
  1532. x++;
  1533. }
  1534. x=bx;
  1535. y=by-1;
  1536. p2 = *(mapsegs[2]+farmapylookup[y]+x);
  1537. map = mapsegs[0]+farmapylookup[y]+x;
  1538. while (*p2 == remove_code)
  1539. {
  1540. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1541. map-=mapwidth;
  1542. p2 -= mapwidth;
  1543. y--;
  1544. }
  1545. y=by+1;
  1546. p2 = *(mapsegs[2]+farmapylookup[y]+x);
  1547. map = mapsegs[0]+farmapylookup[y]+x;
  1548. while (*p2 == remove_code)
  1549. {
  1550. tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
  1551. map+=mapwidth;
  1552. p2 += mapwidth;
  1553. y++;
  1554. }
  1555. }
  1556. #endif
  1557. /*
  1558. ==================
  1559. =
  1560. = HitSpecialTile
  1561. =
  1562. = Returns true if the move is blocked
  1563. =
  1564. ==================
  1565. */
  1566. boolean HitSpecialTile (unsigned x, unsigned y, unsigned tile)
  1567. {
  1568. objtype *check;
  1569. short keyspot;
  1570. unsigned temp,spot,curmap=gamestate.mapon,newlevel;
  1571. char *key_colors[] = {"a RED key",
  1572. "a YELLOW key",
  1573. "a GREEN key",
  1574. "a BLUE key"};
  1575. switch (tile)
  1576. {
  1577. case 44:
  1578. playstate = ex_victorious;
  1579. break;
  1580. case 17:
  1581. case 30:
  1582. case 31:
  1583. case 35:
  1584. case 46:
  1585. case 47:
  1586. case 48:
  1587. case 49:
  1588. case 57:
  1589. case 58:
  1590. case 71:
  1591. case 85:
  1592. case 94:
  1593. if (!playstate && !FreezeTime)
  1594. {
  1595. // Is this an openable door? (Is "openable" a word?)
  1596. //
  1597. spot = (*(mapsegs[2]+farmapylookup[y]+x)) >> 8;
  1598. if (spot == CANT_OPEN_CODE) // CAN'T EVER OPEN (it's just for looks)
  1599. {
  1600. CenterWindow(30,4);
  1601. US_CPrint("\nThis door is permanently blocked");
  1602. VW_UpdateScreen();
  1603. IN_ClearKeysDown();
  1604. IN_Ack();
  1605. return;
  1606. }
  1607. // make sure player has key to get into door
  1608. //
  1609. if (TILE_FLAGS(tile) & tf_EMBEDDED_KEY_COLOR)
  1610. keyspot = GATE_KEY_COLOR(tile);
  1611. else
  1612. keyspot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;
  1613. if (keyspot--)
  1614. if (!gamestate.keys[keyspot])
  1615. {
  1616. SD_PlaySound(HIT_GATESND);
  1617. CenterWindow(20,5);
  1618. US_CPrint("\nYou need\n");
  1619. US_CPrint(key_colors[keyspot]);
  1620. VW_UpdateScreen();
  1621. IN_ClearKeysDown();
  1622. IN_Ack();
  1623. return;
  1624. }
  1625. //
  1626. // deal with this gate (warp? simply open? whatever...)
  1627. //
  1628. switch (spot)
  1629. {
  1630. case NEXT_LEVEL_CODE: // WARP TO NEXT LEVEL
  1631. newlevel = gamestate.mapon+1;
  1632. playstate = ex_warped;
  1633. break;
  1634. case REMOVE_DOOR_CODE: // REMOVE DOOR
  1635. (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = 0;
  1636. *(mapsegs[2]+farmapylookup[y+1]+x) = 0; // key no longer needed
  1637. if (keyspot>=0)
  1638. TakeKey(keyspot);
  1639. break;
  1640. default: // WARP TO A LEVEL
  1641. newlevel = spot;
  1642. playstate = ex_warped;
  1643. break;
  1644. }
  1645. if (playstate == ex_warped)
  1646. {
  1647. SD_PlaySound(HIT_GATESND);
  1648. // levelinfo *li=&gamestate.levels[curmap];
  1649. // OldAngle = FaceDoor(x,y);
  1650. if (!VerifyGateExit())
  1651. {
  1652. IN_ClearKeysDown ();
  1653. playstate = ex_stillplaying;
  1654. break;
  1655. }
  1656. // FaceAngle(OldAngle);
  1657. if (keyspot>=0)
  1658. TakeKey(keyspot);
  1659. *(mapsegs[2]+farmapylookup[y+1]+x) = 0; // key no longer needed
  1660. gamestate.mapon = newlevel;
  1661. SD_PlaySound(WARPUPSND);
  1662. IN_ClearKeysDown ();
  1663. // li->x = player->tilex;
  1664. // li->y = player->tiley;
  1665. // li->angle = player->angle+180;
  1666. // if (li->angle > 360)
  1667. // li->angle -= 360;
  1668. }
  1669. }
  1670. break;
  1671. }
  1672. return true;
  1673. }
  1674. //-------------------------------------------------------------------------
  1675. // VerifyGateExit()
  1676. //-------------------------------------------------------------------------
  1677. boolean VerifyGateExit()
  1678. {
  1679. char choices[] = {sc_Escape,sc_Y,sc_N,0},ch;
  1680. ch=DisplayMsg("Pass this way? Y/N",choices);
  1681. DrawText(true);
  1682. return(ch == sc_Y);
  1683. }
  1684. /*
  1685. ==================
  1686. =
  1687. = TouchActor
  1688. =
  1689. = Returns true if the move is blocked
  1690. =
  1691. ==================
  1692. */
  1693. boolean TouchActor (objtype *ob, objtype *check)
  1694. {
  1695. if (ob->xh < check->xl || ob->xl > check->xh ||
  1696. ob->yh < check->yl || ob->yl > check->yh)
  1697. return false; // not quite touching
  1698. switch (check->obclass)
  1699. {
  1700. case bonusobj:
  1701. switch (check->temp1)
  1702. {
  1703. case B_BOLT: GiveBolt (); break;
  1704. case B_NUKE: GiveNuke (); break;
  1705. case B_POTION: GivePotion (); break;
  1706. // case B_RKEY2: GiveKey(B_RKEY-B_RKEY); break;
  1707. case B_RKEY:
  1708. case B_YKEY:
  1709. case B_GKEY:
  1710. case B_BKEY: GiveKey (check->temp1-B_RKEY); break;
  1711. #if 0
  1712. case B_SCROLL1:
  1713. case B_SCROLL2:
  1714. case B_SCROLL3:
  1715. case B_SCROLL4:
  1716. case B_SCROLL5:
  1717. case B_SCROLL6:
  1718. case B_SCROLL7:
  1719. case B_SCROLL8: GiveScroll (check->temp1-B_SCROLL1,true); break;
  1720. #endif
  1721. case B_OLDCHEST:
  1722. case B_CHEST: GiveChest (); break;
  1723. case B_RGEM:
  1724. case B_YGEM:
  1725. case B_GGEM:
  1726. case B_BGEM:
  1727. case B_PGEM:
  1728. SD_PlaySound(GETGEMSND);
  1729. gamestate.gems[check->temp1-B_RGEM] = GEM_DELAY_TIME;
  1730. redraw_gems = true;
  1731. break;
  1732. default:
  1733. Quit("TouchActor(): INVALID BONUS");
  1734. break;
  1735. }
  1736. (unsigned)actorat[check->tilex][check->tiley] = 0;
  1737. RemoveObj (check);
  1738. return false;
  1739. case freezeobj:
  1740. StopTime();
  1741. (unsigned)actorat[check->tilex][check->tiley] = 0;
  1742. RemoveObj(check);
  1743. return(false);
  1744. }
  1745. return true;
  1746. }
  1747. /*
  1748. ==================
  1749. =
  1750. = CalcBounds
  1751. =
  1752. ==================
  1753. */
  1754. void CalcBounds (objtype *ob)
  1755. {
  1756. //
  1757. // calculate hit rect
  1758. //
  1759. ob->xl = ob->x - ob->size;
  1760. ob->xh = ob->x + ob->size;
  1761. ob->yl = ob->y - ob->size;
  1762. ob->yh = ob->y + ob->size;
  1763. }
  1764. /*
  1765. ===================
  1766. =
  1767. = LocationInActor
  1768. =
  1769. ===================
  1770. */
  1771. boolean LocationInActor (objtype *ob)
  1772. {
  1773. int x,y,xmin,ymin,xmax,ymax;
  1774. objtype *check;
  1775. CalcBounds (ob);
  1776. xmin = (ob->x >> TILESHIFT)-2;
  1777. ymin = (ob->y >> TILESHIFT)-2;
  1778. xmax = xmin+5;
  1779. ymax = ymin+5;
  1780. for (x=xmin;x<xmax;x++)
  1781. for (y=ymin;y<ymax;y++)
  1782. {
  1783. check = actorat[x][y];
  1784. if (check>(objtype *)LASTTILE
  1785. && (check->flags & of_shootable)
  1786. && (check->obclass != bonusobj)
  1787. && (check->obclass != freezeobj)
  1788. && (check->obclass != solidobj)
  1789. && ob->xl-SIZE_TEST <= check->xh
  1790. && ob->xh+SIZE_TEST >= check->xl
  1791. && ob->yl-SIZE_TEST <= check->yh
  1792. && ob->yh+SIZE_TEST >= check->yl)
  1793. return true;
  1794. }
  1795. return false;
  1796. }
  1797. /*
  1798. ===================
  1799. =
  1800. = ClipXMove
  1801. =
  1802. = Only checks corners, so the object better be less than one tile wide!
  1803. =
  1804. ===================
  1805. */
  1806. void ClipXMove (objtype *ob, long xmove)
  1807. {
  1808. int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
  1809. long intersect,basex,basey,pointx,pointy;
  1810. unsigned inside,total,tile;
  1811. objtype *check;
  1812. boolean moveok;
  1813. boolean invisible_present = false;
  1814. //
  1815. // move player and check to see if any corners are in solid tiles
  1816. //
  1817. basex = ob->x;
  1818. basey = ob->y;
  1819. ob->x += xmove;
  1820. CalcBounds (ob);
  1821. xl = ob->xl>>TILESHIFT;
  1822. yl = ob->yl>>TILESHIFT;
  1823. xh = ob->xh>>TILESHIFT;
  1824. yh = ob->yh>>TILESHIFT;
  1825. for (y=yl;y<=yh;y++)
  1826. for (x=xl;x<=xh;x++)
  1827. {
  1828. check = actorat[x][y];
  1829. if (!check)
  1830. continue; // blank floor, walk ok
  1831. if ((unsigned)check <= LASTTILE)
  1832. {
  1833. if (TILE_FLAGS((unsigned)check) & tf_SPECIAL)
  1834. {
  1835. HitSpecialTile(x,y,(unsigned)check-SPECTILESTART);
  1836. goto blockmove;
  1837. }
  1838. if (TILE_FLAGS((unsigned)check) & tf_INVISIBLE_WALL)
  1839. {
  1840. invisible_present = true;
  1841. goto blockmove;
  1842. }
  1843. if (TILE_FLAGS((unsigned)check) & tf_SOLID)
  1844. {
  1845. goto blockmove; // solid wall
  1846. }
  1847. }
  1848. TouchActor(ob,check); // pick up items
  1849. }
  1850. //
  1851. // check nearby actors
  1852. //
  1853. if (LocationInActor(ob))
  1854. {
  1855. ob->x -= xmove;
  1856. if (LocationInActor(ob))
  1857. {
  1858. ob->x += xmove;
  1859. if (LocationInActor(ob))
  1860. ob->x -= xmove;
  1861. }
  1862. }
  1863. return; // move is OK!
  1864. blockmove:
  1865. // if (!SD_SoundPlaying())
  1866. // SD_PlaySound (HITWALLSND);
  1867. moveok = false;
  1868. do
  1869. {
  1870. xmove /= 2;
  1871. if (moveok)
  1872. {
  1873. ob->x += xmove;
  1874. }
  1875. else
  1876. {
  1877. ob->x -= xmove;
  1878. }
  1879. CalcBounds (ob);
  1880. xl = ob->xl>>TILESHIFT;
  1881. yl = ob->yl>>TILESHIFT;
  1882. xh = ob->xh>>TILESHIFT;
  1883. yh = ob->yh>>TILESHIFT;
  1884. if (tilemap[xl][yl] || tilemap[xh][yl]
  1885. || tilemap[xh][yh] || tilemap[xl][yh] )
  1886. {
  1887. moveok = false;
  1888. if (xmove>=-2048 && xmove <=2048)
  1889. {
  1890. ob->x = basex;
  1891. ob->y = basey;
  1892. return;
  1893. }
  1894. }
  1895. else
  1896. if (invisible_present)
  1897. {
  1898. moveok = false;
  1899. if (xmove>=-2048 && xmove <=2048)
  1900. {
  1901. ob->x = basex;
  1902. ob->y = basey;
  1903. return;
  1904. }
  1905. }
  1906. else
  1907. if (xmove>=-2048 && xmove <=2048)
  1908. return;
  1909. moveok = true;
  1910. } while (1);
  1911. }
  1912. /*
  1913. ===================
  1914. =
  1915. = ClipYMove
  1916. =
  1917. = Only checks corners, so the object better be less than one tile wide!
  1918. =
  1919. ===================
  1920. */
  1921. void ClipYMove (objtype *ob, long ymove)
  1922. {
  1923. int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
  1924. long intersect,basex,basey,pointx,pointy;
  1925. unsigned inside,total,tile;
  1926. objtype *check;
  1927. boolean moveok;
  1928. boolean invisible_present = false;
  1929. //
  1930. // move player and check to see if any corners are in solid tiles
  1931. //
  1932. basex = ob->x;
  1933. basey = ob->y;
  1934. ob->y += ymove;
  1935. CalcBounds (ob);
  1936. xl = ob->xl>>TILESHIFT;
  1937. yl = ob->yl>>TILESHIFT;
  1938. xh = ob->xh>>TILESHIFT;
  1939. yh = ob->yh>>TILESHIFT;
  1940. for (y=yl;y<=yh;y++)
  1941. for (x=xl;x<=xh;x++)
  1942. {
  1943. check = actorat[x][y];
  1944. if (!check)
  1945. continue; // blank floor, walk ok
  1946. if ((unsigned)check <= LASTTILE)
  1947. {
  1948. if (TILE_FLAGS((unsigned)check) & tf_SPECIAL) // <=LASTSPECIALTILE)
  1949. {
  1950. HitSpecialTile (x,y,(unsigned)check-SPECTILESTART);
  1951. goto blockmove;
  1952. }
  1953. if (TILE_FLAGS((unsigned)check) & tf_INVISIBLE_WALL)
  1954. {
  1955. invisible_present = true;
  1956. goto blockmove;
  1957. }
  1958. if (TILE_FLAGS((unsigned)check) & tf_SOLID) // LASTWALLTILE)
  1959. {
  1960. goto blockmove; // solid wall
  1961. }
  1962. }
  1963. TouchActor(ob,check); // pick up items
  1964. }
  1965. //
  1966. // check nearby actors
  1967. //
  1968. if (LocationInActor(ob))
  1969. {
  1970. if (LocationInActor(ob))
  1971. {
  1972. ob->y -= ymove;
  1973. }
  1974. }
  1975. return; // move is OK!
  1976. blockmove:
  1977. // if (!SD_SoundPlaying())
  1978. // SD_PlaySound (HITWALLSND);
  1979. moveok = false;
  1980. do
  1981. {
  1982. ymove /= 2;
  1983. if (moveok)
  1984. {
  1985. ob->y += ymove;
  1986. }
  1987. else
  1988. {
  1989. ob->y -= ymove;
  1990. }
  1991. CalcBounds (ob);
  1992. xl = ob->xl>>TILESHIFT;
  1993. yl = ob->yl>>TILESHIFT;
  1994. xh = ob->xh>>TILESHIFT;
  1995. yh = ob->yh>>TILESHIFT;
  1996. if (tilemap[xl][yl] || tilemap[xh][yl]
  1997. || tilemap[xh][yh] || tilemap[xl][yh] )
  1998. {
  1999. moveok = false;
  2000. if (ymove>=-2048 && ymove <=2048)
  2001. {
  2002. ob->x = basex;
  2003. ob->y = basey;
  2004. return;
  2005. }
  2006. }
  2007. else
  2008. if (invisible_present)
  2009. {
  2010. moveok = false;
  2011. if (ymove>=-2048 && ymove <=2048)
  2012. {
  2013. ob->x = basex;
  2014. ob->y = basey;
  2015. return;
  2016. }
  2017. }
  2018. else
  2019. if (ymove>=-2048 && ymove <=2048)
  2020. return;
  2021. moveok = true;
  2022. } while (1);
  2023. }
  2024. //==========================================================================
  2025. /*
  2026. ===================
  2027. =
  2028. = ShotClipMove
  2029. =
  2030. = Only checks corners, so the object better be less than one tile wide!
  2031. =
  2032. ===================
  2033. */
  2034. boolean ShotClipMove (objtype *ob, long xmove, long ymove)
  2035. {
  2036. int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
  2037. long intersect,basex,basey,pointx,pointy;
  2038. unsigned inside,total,spot,tile;
  2039. objtype *check;
  2040. boolean moveok;
  2041. //
  2042. // move shot and check to see if any corners are in solid tiles
  2043. //
  2044. basex = ob->x;
  2045. basey = ob->y;
  2046. ob->x += xmove;
  2047. ob->y += ymove;
  2048. CalcBounds (ob);
  2049. xl = ob->xl>>TILESHIFT;
  2050. yl = ob->yl>>TILESHIFT;
  2051. xh = ob->xh>>TILESHIFT;
  2052. yh = ob->yh>>TILESHIFT;
  2053. for (y=yl;y<=yh;y++)
  2054. for (x=xl;x<=xh;x++)
  2055. {
  2056. spot = (*(mapsegs[2]+farmapylookup[y]+x)) >> 8;
  2057. if (spot == EXP_WALL_CODE)
  2058. switch (ob->obclass)
  2059. {
  2060. case pshotobj:
  2061. case bigpshotobj:
  2062. ExplodeWall (x,y);
  2063. goto blockmove;
  2064. // break;
  2065. }
  2066. tile = *(mapsegs[0]+farmapylookup[y]+x);
  2067. if (TILE_FLAGS(tile) & tf_SOLID)
  2068. goto blockmove;
  2069. }
  2070. return false; // move is OK!
  2071. blockmove:
  2072. if (ob->obclass == pshotobj)
  2073. SD_PlaySound (SHOOTWALLSND);
  2074. moveok = false;
  2075. do
  2076. {
  2077. xmove /= 2;
  2078. ymove /= 2;
  2079. if (moveok)
  2080. {
  2081. ob->x += xmove;
  2082. ob->y += ymove;
  2083. }
  2084. else
  2085. {
  2086. ob->x -= xmove;
  2087. ob->y -= ymove;
  2088. }
  2089. CalcBounds (ob);
  2090. xl = ob->xl>>TILESHIFT;
  2091. yl = ob->yl>>TILESHIFT;
  2092. xh = ob->xh>>TILESHIFT;
  2093. yh = ob->yh>>TILESHIFT;
  2094. if (tilemap[xl][yl] || tilemap[xh][yl]
  2095. || tilemap[xh][yh] || tilemap[xl][yh] )
  2096. {
  2097. moveok = false;
  2098. if (xmove>=-2048 && xmove <=2048 && ymove>=-2048 && ymove <=2048)
  2099. {
  2100. ob->x = basex;
  2101. ob->y = basey;
  2102. return true;
  2103. }
  2104. }
  2105. else
  2106. {
  2107. if (xmove>=-2048 && xmove <=2048 && ymove>=-2048 && ymove <=2048)
  2108. return true;
  2109. moveok = true;
  2110. }
  2111. } while (1);
  2112. }
  2113. /*
  2114. =============================================================================
  2115. PLAYER CONTROL
  2116. =============================================================================
  2117. */
  2118. void T_Player (objtype *ob);
  2119. statetype s_player = {0,0,&T_Player,&s_player};
  2120. /*
  2121. ===============
  2122. =
  2123. = SpawnPlayer
  2124. =
  2125. ===============
  2126. */
  2127. void SpawnPlayer (int tilex, int tiley, int dir)
  2128. {
  2129. #if 0
  2130. levelinfo *li=&gamestate.levels[gamestate.mapon];
  2131. if (li->x != -1)
  2132. {
  2133. tilex = li->x;
  2134. tiley = li->y;
  2135. player->angle = li->angle;
  2136. }
  2137. else
  2138. player->angle = (1-dir)*90;
  2139. #endif
  2140. player->obclass = playerobj;
  2141. player->active = always;
  2142. player->tilex = tilex;
  2143. player->tiley = tiley;
  2144. player->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
  2145. player->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
  2146. player->state = &s_player;
  2147. player->size = MINDIST;
  2148. CalcBounds(player);
  2149. player->angle = (1-dir)*90;
  2150. if (player->angle<0)
  2151. player->angle += ANGLES;
  2152. }
  2153. /*
  2154. ===================
  2155. =
  2156. = Thrust
  2157. =
  2158. ===================
  2159. */
  2160. void Thrust (int angle, unsigned speed)
  2161. {
  2162. long xmove,ymove;
  2163. if (lasttimecount>>5 != ((lasttimecount-tics)>>5) )
  2164. {
  2165. //
  2166. // walk sound
  2167. //
  2168. if (lasttimecount&32)
  2169. SD_PlaySound (WALK1SND);
  2170. else
  2171. SD_PlaySound (WALK2SND);
  2172. }
  2173. xmove = FixedByFrac(speed,costable[angle]);
  2174. ymove = -FixedByFrac(speed,sintable[angle]);
  2175. ClipXMove(player,xmove);
  2176. ClipYMove(player,ymove);
  2177. player->tilex = player->x >> TILESHIFT;
  2178. player->tiley = player->y >> TILESHIFT;
  2179. }
  2180. /*
  2181. =======================
  2182. =
  2183. = ControlMovement
  2184. =
  2185. =======================
  2186. */
  2187. void ControlMovement (objtype *ob)
  2188. {
  2189. int angle;
  2190. long speed;
  2191. if (control.button1)
  2192. {
  2193. //
  2194. // strafing
  2195. //
  2196. //
  2197. // side to side move
  2198. //
  2199. if (!mousexmove)
  2200. speed = 0;
  2201. else if (mousexmove<0)
  2202. speed = -(long)mousexmove*300;
  2203. else
  2204. speed = -(long)mousexmove*300;
  2205. if (control.xaxis == -1)
  2206. {
  2207. speed += PLAYERSPEED*tics;
  2208. }
  2209. else if (control.xaxis == 1)
  2210. {
  2211. speed -= PLAYERSPEED*tics;
  2212. }
  2213. if (speed > 0)
  2214. {
  2215. if (speed >= TILEGLOBAL)
  2216. speed = TILEGLOBAL-1;
  2217. angle = ob->angle + ANGLES/4;
  2218. if (angle >= ANGLES)
  2219. angle -= ANGLES;
  2220. Thrust (angle,speed); // move to left
  2221. }
  2222. else if (speed < 0)
  2223. {
  2224. if (speed <= -TILEGLOBAL)
  2225. speed = -TILEGLOBAL+1;
  2226. angle = ob->angle - ANGLES/4;
  2227. if (angle < 0)
  2228. angle += ANGLES;
  2229. Thrust (angle,-speed); // move to right
  2230. }
  2231. }
  2232. else
  2233. {
  2234. //
  2235. // not strafing
  2236. //
  2237. //
  2238. // turning
  2239. //
  2240. if (control.xaxis == 1)
  2241. {
  2242. ob->angle -= tics;
  2243. if (running) // fast turn
  2244. ob->angle -= (tics<<1);
  2245. }
  2246. else if (control.xaxis == -1)
  2247. {
  2248. ob->angle+= tics;
  2249. if (running) // fast turn
  2250. ob->angle += (tics<<1);
  2251. }
  2252. ob->angle -= (mousexmove/10);
  2253. if (ob->angle >= ANGLES)
  2254. ob->angle -= ANGLES;
  2255. if (ob->angle < 0)
  2256. ob->angle += ANGLES;
  2257. }
  2258. //
  2259. // forward/backwards move
  2260. //
  2261. if (!mouseymove)
  2262. speed = 0;
  2263. else if (mouseymove<0)
  2264. speed = -(long)mouseymove*500;
  2265. else
  2266. speed = -(long)mouseymove*200;
  2267. if (control.yaxis == -1)
  2268. {
  2269. speed += PLAYERSPEED*tics;
  2270. }
  2271. else if (control.yaxis == 1)
  2272. {
  2273. speed -= PLAYERSPEED*tics;
  2274. }
  2275. if (speed > 0)
  2276. {
  2277. if (speed >= TILEGLOBAL)
  2278. speed = TILEGLOBAL-1;
  2279. Thrust (ob->angle,speed); // move forwards
  2280. }
  2281. else if (speed < 0)
  2282. {
  2283. if (speed <= -TILEGLOBAL)
  2284. speed = -TILEGLOBAL+1;
  2285. angle = ob->angle + ANGLES/2;
  2286. if (angle >= ANGLES)
  2287. angle -= ANGLES;
  2288. Thrust (angle,-speed); // move backwards
  2289. }
  2290. }
  2291. /*
  2292. ===============
  2293. =
  2294. = T_Player
  2295. =
  2296. ===============
  2297. */
  2298. void T_Player (objtype *ob)
  2299. {
  2300. // extern boolean autofire;
  2301. int angle,speed,scroll,loop;
  2302. unsigned text,tilex,tiley;
  2303. long lspeed;
  2304. // boolean radar_moved=false;
  2305. ControlMovement (ob);
  2306. //
  2307. // firing
  2308. //
  2309. if (boltsleft)
  2310. {
  2311. handheight+=(realtics<<2);
  2312. if (handheight>MAXHANDHEIGHT)
  2313. handheight = MAXHANDHEIGHT;
  2314. ContinueBolt ();
  2315. lasthand = lasttimecount;
  2316. }
  2317. else
  2318. {
  2319. if (control.button0)
  2320. {
  2321. handheight+=(realtics<<2);
  2322. if (handheight>MAXHANDHEIGHT)
  2323. handheight = MAXHANDHEIGHT;
  2324. lasthand = lasttimecount;
  2325. if (!button0down)
  2326. Shoot();
  2327. // if (!autofire)
  2328. button0down=true;
  2329. }
  2330. else
  2331. {
  2332. if (lasttimecount > lasthand+HANDPAUSE)
  2333. {
  2334. handheight-=(realtics<<1);
  2335. if (handheight<0)
  2336. handheight = 0;
  2337. }
  2338. button0down = false;
  2339. }
  2340. }
  2341. #if 0
  2342. if (control.button0)
  2343. {
  2344. handheight+=(realtics<<2);
  2345. if (handheight>MAXHANDHEIGHT)
  2346. handheight = MAXHANDHEIGHT;
  2347. if ((unsigned)TimeCount/FIRETIME != lastfiretime)
  2348. BuildShotPower ();
  2349. lasthand = lasttimecount;
  2350. }
  2351. else
  2352. {
  2353. if (lasttimecount > lasthand+HANDPAUSE)
  2354. {
  2355. handheight-=(realtics<<1);
  2356. if (handheight<0)
  2357. handheight = 0;
  2358. }
  2359. if (gamestate.shotpower)
  2360. {
  2361. lastfiretime = (unsigned)TimeCount/FIRETIME;
  2362. Shoot ();
  2363. }
  2364. }
  2365. }
  2366. #endif
  2367. //
  2368. // special actions
  2369. //
  2370. if ((Keyboard[sc_Space] || Keyboard[sc_C]) && gamestate.body != MAXBODY)
  2371. DrinkPotion ();
  2372. if (Keyboard[sc_Z] && !boltsleft)
  2373. CastBolt ();
  2374. if ( (Keyboard[sc_Enter] || Keyboard[sc_X]) && ((TimeCount-lastnuke > NUKETIME))) //|| (autofire)))
  2375. CastNuke ();
  2376. #if 0
  2377. scroll = LastScan-2;
  2378. if ( scroll>=0 && scroll<NUMSCROLLS && gamestate.scrolls[scroll])
  2379. ReadScroll (scroll);
  2380. #endif
  2381. DrawText(false);
  2382. DrawHealth();
  2383. if (FreezeTime)
  2384. DrawFreezeTime();
  2385. DrawRadar();
  2386. EGAWRITEMODE(0);
  2387. DrawNSEWIcons();
  2388. if (redraw_gems)
  2389. DrawGems();
  2390. #if 0
  2391. // gems fade out over time...
  2392. //
  2393. for (loop=0; loop<5; loop++)
  2394. if (gamestate.gems[loop])
  2395. {
  2396. gamestate.gems[loop] -= realtics;
  2397. if (gamestate.gems[loop] < 0)
  2398. {
  2399. gamestate.gems[loop] = 0;
  2400. redraw_gems = true;
  2401. }
  2402. }
  2403. #endif
  2404. }
  2405. #if 0
  2406. //------------------------------------------------------------------------
  2407. // FaceDir() -
  2408. //
  2409. // PARAMS : x,y - pixle coords to bring in to view.
  2410. //
  2411. // NOTE : Params CAN NOT be shifted fracs!
  2412. //------------------------------------------------------------------------
  2413. void FaceDir(short x,short y,boolean StopTime)
  2414. {
  2415. short diff;
  2416. RotateAngle = CalcAngle(x-(player->x>>16l),(player->y>>16l)-y);
  2417. FreezeTime = StopTime;
  2418. diff = player->angle - RotateAngle;
  2419. if (((diff>0) && (diff<180)) || ((diff<0) && (diff>-180)))
  2420. RotateSpeed = -ROTATE_SPEED;
  2421. else
  2422. RotateSpeed = ROTATE_SPEED;
  2423. }
  2424. #endif
  2425. #if 0
  2426. //------------------------------------------------------------------------
  2427. // CalcAngle() -
  2428. //
  2429. // DESC: Calculates the angle from a given dy & dx
  2430. //------------------------------------------------------------------------
  2431. short CalcAngle(short dx,short dy)
  2432. {
  2433. #define degtorad (180/PI)
  2434. float angle;
  2435. short diff;
  2436. float rad_angle;
  2437. if (dx)
  2438. {
  2439. angle = atan((float)dy/dx)* degtorad;
  2440. if (angle<=0)
  2441. angle += 180;
  2442. if (dy>0)
  2443. angle += 180;
  2444. }
  2445. else
  2446. {
  2447. // 90 Deg shift
  2448. if (dy < 0)
  2449. angle = 0 + 90; // Above player (NORTH)
  2450. else
  2451. angle = 180 + 90; // Below player (SOUTH)
  2452. }
  2453. if (!angle) // HACK
  2454. angle++;
  2455. return((short)abs(angle));
  2456. }
  2457. #endif
  2458. #if 0
  2459. //-------------------------------------------------------------------------
  2460. // RotateView() -
  2461. //
  2462. // DESC : Rotates view (current view of game) to a dest angle.
  2463. //-------------------------------------------------------------------------
  2464. void RotateView()
  2465. {
  2466. short LastPos;
  2467. // Store old angle position then change angle...
  2468. //
  2469. LastPos = player->angle;
  2470. player->angle += RotateSpeed;
  2471. // Check to see if we cranked past out dest angle...
  2472. //
  2473. if ((player->angle>ANGLES) || (!player->angle))
  2474. player->angle = 1;
  2475. else
  2476. if (player->angle<1)
  2477. player->angle = ANGLES;
  2478. // Check to see if we over shot our dest angle...
  2479. //
  2480. if (((LastPos < RotateAngle) && (player->angle > RotateAngle) && (RotateSpeed > 0)) ||
  2481. ((LastPos > RotateAngle) && (player->angle < RotateAngle) && (RotateSpeed < 0)))
  2482. player->angle = RotateAngle;
  2483. // Check for ending force turn....
  2484. //
  2485. if (player->angle == RotateAngle)
  2486. RotateAngle = -1;
  2487. }
  2488. //--------------------------------------------------------------------------
  2489. // InitRotate()
  2490. //--------------------------------------------------------------------------
  2491. void InitRotate(short DestAngle)
  2492. {
  2493. if (player->angle != DestAngle)
  2494. {
  2495. RotateAngle = DestAngle;
  2496. if (player->angle > DestAngle)
  2497. RotateSpeed = -ROTATE_SPEED;
  2498. else
  2499. RotateSpeed = ROTATE_SPEED;
  2500. if (abs(player->angle - RotateAngle) > 180)
  2501. RotateSpeed =- RotateSpeed;
  2502. }
  2503. }
  2504. //------------------------------------------------------------------------
  2505. // FaceAngle() -
  2506. //
  2507. // PARAMS : DestAngle - Destination angle to turn to
  2508. //------------------------------------------------------------------------
  2509. void FaceAngle(short DestAngle)
  2510. {
  2511. signed long dx,dy,radius,psin,pcos,newx,newy;
  2512. int give;
  2513. short objnum,LastPos;
  2514. signed long ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy;
  2515. short o_radius;
  2516. void (*think)();
  2517. // Calculate the direction we want to turn to...
  2518. //
  2519. InitRotate(DestAngle);
  2520. RedrawStatusWindow();
  2521. while (RotateAngle != -1)
  2522. {
  2523. RotateView();
  2524. // PollControls();
  2525. objnum=0;
  2526. for (obj = player;obj;obj = obj->next)
  2527. {
  2528. if (obj->active >= yes)
  2529. {
  2530. // keep a list of objects around the player for radar updates
  2531. //
  2532. if (obj == player)
  2533. {
  2534. px = player->x;
  2535. py = player->y;
  2536. psin = sintable[player->angle];
  2537. pcos = costable[player->angle];
  2538. xl = px-((long)RADAR_WIDTH<<TILESHIFT)/2;
  2539. xh = px+((long)RADAR_WIDTH<<TILESHIFT)/2-1;
  2540. yl = py-((long)RADAR_HEIGHT<<TILESHIFT)/2;
  2541. yh = py+((long)RADAR_HEIGHT<<TILESHIFT)/2;
  2542. }
  2543. if (objnum > MAX_RADAR_BLIPS-2)
  2544. objnum = MAX_RADAR_BLIPS-2;
  2545. ox = obj->x;
  2546. oy = obj->y;
  2547. if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh))
  2548. {
  2549. norm_dx = (dx = px-ox)>>TILESHIFT;
  2550. norm_dy = (dy = oy-py)>>TILESHIFT;
  2551. o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy));
  2552. if (o_radius < RADAR_RADIUS)
  2553. {
  2554. newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin);
  2555. newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos);
  2556. RadarXY[objnum][0]=newx>>TILESHIFT;
  2557. RadarXY[objnum][1]=newy>>TILESHIFT;
  2558. // Define color to use for this object...
  2559. //
  2560. switch (obj->obclass)
  2561. {
  2562. case playerobj:
  2563. RadarXY[objnum++][2]=15;
  2564. break;
  2565. // RED GEM
  2566. //
  2567. // STOMPY (DK RED)
  2568. //
  2569. case invisdudeobj:
  2570. case stompyobj:
  2571. RadarXY[objnum++][2]=4;
  2572. break;
  2573. // BLOB (LT RED)
  2574. //
  2575. case blobobj:
  2576. RadarXY[objnum++][2]=12;
  2577. break;
  2578. // BLUE GEM
  2579. //
  2580. // ROBOTANK (LT BLUE)
  2581. //
  2582. case robotankobj:
  2583. case fmageobj:
  2584. RadarXY[objnum++][2]=9;
  2585. break;
  2586. #if 1
  2587. // BLUE DEMON (DK BLUE)
  2588. //
  2589. case demonobj:
  2590. RadarXY[objnum++][2]=1;
  2591. break;
  2592. #endif
  2593. // GREEN GEM
  2594. //
  2595. // WIZARD (LT GREEN)
  2596. //
  2597. case wizardobj:
  2598. RadarXY[objnum++][2]=10;
  2599. break;
  2600. // AQUA MAN (DK GREEN)
  2601. //
  2602. case aquamanobj:
  2603. RadarXY[objnum++][2]=2;
  2604. break;
  2605. // YELLOW GEM
  2606. //
  2607. // EQYPTIAN HEAD (BROWN)
  2608. //
  2609. case headobj:
  2610. RadarXY[objnum++][2]=6;
  2611. break;
  2612. // RAMBONE (YELLOW)
  2613. // TROLL
  2614. case ramboneobj:
  2615. case trollobj:
  2616. RadarXY[objnum++][2]=14;
  2617. break;
  2618. // BUG (LIGHT GRAY)
  2619. case bugobj:
  2620. RadarXY[objnum++][2]=7;
  2621. break;
  2622. // RAY (DARK GRAY)
  2623. case rayobj:
  2624. RadarXY[objnum++][2]=8;
  2625. break;
  2626. // PURPLE GEM
  2627. //
  2628. // MEC DEMON (PURPLE)
  2629. //
  2630. case cyborgdemonobj:
  2631. RadarXY[objnum++][2]=5;
  2632. break;
  2633. // EYE (LT PURPLE)
  2634. //
  2635. case eyeobj:
  2636. case reyeobj:
  2637. RadarXY[objnum++][2]=13;
  2638. break;
  2639. }
  2640. }
  2641. }
  2642. }
  2643. }
  2644. RadarXY[objnum][2]=-1; // Signals end of RadarXY list...
  2645. // refresh all
  2646. //
  2647. ThreeDRefresh();
  2648. DrawRadar();
  2649. EGAWRITEMODE(0);
  2650. DrawNSEWIcons();
  2651. // CheckKeys();
  2652. }
  2653. }
  2654. //-------------------------------------------------------------------------
  2655. // FaceDoor() - Turns the player to face a door (a tile) at a given TILE x & y
  2656. //
  2657. // RETURNS : Returns the orginal angle of the player.
  2658. //------------------------------------------------------------------------
  2659. short FaceDoor(short x, short y)
  2660. {
  2661. short p_x,p_y,angle,old_angle;
  2662. old_angle = player->angle;
  2663. p_x = player->x>>16l;
  2664. p_y = player->y>>16l;
  2665. if (p_x != x)
  2666. {
  2667. if (p_x > x)
  2668. angle = 180; // Face Left
  2669. else
  2670. angle = 1; // Face Right
  2671. }
  2672. if (p_y != y)
  2673. {
  2674. if (p_y > y)
  2675. angle = 90; // Face Up
  2676. else
  2677. angle = 270; // Face Down
  2678. }
  2679. FaceAngle(angle);
  2680. return(old_angle);
  2681. }
  2682. #endif
  2683. /*==========================================================================
  2684. EXPLOSION SPAWNING ROUTINES
  2685. ===========================================================================*/
  2686. statetype s_explode = {0,1,T_ExpThink,&s_explode};
  2687. //-------------------------------------------------------------------------
  2688. // SpawnExplosion()
  2689. //------------------------------------------------------------------------
  2690. void SpawnExplosion(fixed x, fixed y, short Delay)
  2691. {
  2692. DSpawnNewObjFrac(x,y,&s_explode,PIXRADIUS*7);
  2693. new->obclass = expobj;
  2694. new->active = always;
  2695. new->temp1 = Delay;
  2696. }
  2697. //---------------------------------------------------------------------------
  2698. // T_ExpThink()
  2699. //---------------------------------------------------------------------------
  2700. void T_ExpThink(objtype *obj)
  2701. {
  2702. if (obj->temp1)
  2703. {
  2704. if ((obj->temp1-=realtics) <= 0)
  2705. obj->temp1 = 0;
  2706. }
  2707. else
  2708. {
  2709. obj->state = &s_pshot_exp1;
  2710. obj->ticcount = obj->state->tictime;
  2711. SD_PlaySound(BOOMSND);
  2712. }
  2713. }
  2714. //-------------------------------------------------------------------------
  2715. // SpawnBigExplosion()
  2716. //------------------------------------------------------------------------
  2717. void SpawnBigExplosion(fixed x, fixed y, short Delay, fixed Range)
  2718. {
  2719. SpawnExplosion(x-random(Range),y+random(Range),random(Delay));
  2720. SpawnExplosion(x+random(Range),y-random(Range),random(Delay));
  2721. SpawnExplosion(x-random(Range),y-random(Range),random(Delay));
  2722. SpawnExplosion(x+random(Range),y+random(Range),random(Delay));
  2723. }