game2.asm 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956
  1. ; $Id$
  2. ; MegaZeux
  3. ;
  4. ; Copyright (C) 1996 Greg Janson
  5. ; Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. ;
  7. ; This program is free software; you can redistribute it and/or
  8. ; modify it under the terms of the GNU General Public License as
  9. ; published by the Free Software Foundation; either version 2 of
  10. ; the License, or (at your option) any later version.
  11. ;
  12. ; This program is distributed in the hope that it will be useful,
  13. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ; General Public License for more details.
  16. ;
  17. ; You should have received a copy of the GNU General Public License
  18. ; along with this program; if not, write to the Free Software
  19. ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ;
  21. ; GAME2.ASM- Main update function and support functions
  22. ;
  23. Ideal
  24. include "runrobot.inc"
  25. include "game.inc"
  26. include "sfx.inc"
  27. include "counter.inc"
  28. include "game2.inc"
  29. include "data.inc"
  30. include "random.inc"
  31. include "string.inc"
  32. include "const.inc"
  33. include "idarray.inc"
  34. include "trig.inc"
  35. p386
  36. JUMPS
  37. include "model.inc"
  38. Dataseg
  39. return_value dw ?
  40. multiplier dw 10000
  41. divider dw 10000
  42. c_divisions dw 360
  43. const_2pi dt 6.2831853071796
  44. slow_down db 0 ; Global slowdown for most objects
  45. gem_name db "GEMS",0 ; Misc. strings
  46. health_name db "HEALTH",0
  47. ouch db "Ouch!",0
  48. ;For missile turning (directions)
  49. cwturndir db 2,3,1,0
  50. ccwturndir db 3,2,0,1
  51. ; OPEN DOOR movement directions, use bits 1,2,4,8,16 to index it.
  52. ; 0ffh=no movement.
  53. label open_door_movement
  54. db 3,0,2,0,3,1,2,1 ; From "open 1/2" to "open"
  55. db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh ; From "open" to "wait"
  56. db 2,1,3,1,2,0,3,0 ; From "wait" to "close 1/2"
  57. db 1,2,1,3,0,2,0,3 ; From "close 1/2" to reg. door
  58. ; Bits for WAIT, in proper bit form, for opening doors. Use bits 1-16.
  59. label open_door_max_wait
  60. db 32,32,32,32,32,32,32,32
  61. db 224,224,224,224,224,224,224,224
  62. db 224,224,224,224,224,224,224,224
  63. db 32,32,32,32,32,32,32,32
  64. MACRO hurt_player_id _id
  65. push es
  66. pusha
  67. mov al,[ds:id_dmg+_id]
  68. xor ah,ah
  69. mov bx,OFFSET health_name
  70. call dec_counter,bx,ds,ax,0 ; Decrease health by ax
  71. call play_sfx,21 ; Hurt sound
  72. mov bx,OFFSET ouch ; Say OUCH
  73. call set_mesg,bx,ds
  74. popa
  75. pop es
  76. ENDM hurt_player_id
  77. MACRO dispmesg mesgname
  78. push ax bx cx dx
  79. mov dx,mesgname
  80. call set_mesg,dx,ds
  81. pop dx cx bx ax
  82. ENDM
  83. ; Find seek dir if "_x","_y" is the location to "seek" from.
  84. ; Loads into "_dest".
  85. ; All must be registers. _dest cannot be al or ah. (ax okay)
  86. MACRO find_seek _x,_y,_dest
  87. LOCAL @@horiz,@@vert,@@end,@@up,@@left
  88. ;; Only save ax if not the destination
  89. IFDIFI <_dest>,<ax>
  90. push ax
  91. ENDIF
  92. cmp _y,[player_y]
  93. je @@horiz
  94. cmp _x,[player_x]
  95. je @@vert
  96. ;; Diagonal movement req.
  97. call random_num ;; Get random number
  98. testflag ax,1 ;; Odd?
  99. jz @@horiz ;; Horiz 50%
  100. @@vert: ;; Vert 50%
  101. ;; Dir becomes up or down.
  102. cmp [player_y],_y
  103. jb @@up
  104. ;; down
  105. mov _dest,1
  106. jmp @@end
  107. @@up:
  108. mov _dest,0
  109. jmp @@end
  110. @@horiz:
  111. ;; Dir becomes left or right.
  112. cmp [player_x],_x
  113. jb @@left
  114. ;; right
  115. mov _dest,2
  116. jmp @@end
  117. @@left:
  118. mov _dest,3
  119. @@end:
  120. IFDIFI <_dest>,<ax>
  121. pop ax
  122. ENDIF
  123. ENDM find_seek
  124. ; Reverse dir in val (dir is 0-3 in the two LSB)
  125. MACRO flip_dir val
  126. flipflag val,1
  127. ENDM flip_dir
  128. MACRO sfxp num
  129. push ax bx cx dx es
  130. call play_sfx,num
  131. pop es dx cx bx ax
  132. ENDM
  133. ; AH contains param, ES:DI contains level_param, BX contains array offset
  134. ; Increases current parameter and stores
  135. MACRO inc_param max
  136. LOCAL @@end1,@@end2
  137. cmp ah,max ;; At end of anim
  138. je @@end1 ;; Yep.
  139. inc ah ;; Nope.
  140. mov [es:di+bx],ah ;; Increase anim
  141. jmp @@end2
  142. @@end1:
  143. mov [BYTE PTR es:di+bx],0 ;; Restart anim
  144. @@end2:
  145. ENDM inc_param
  146. MACRO inc_param_and_end max
  147. LOCAL @@end1
  148. cmp ah,max ;; At end of anim
  149. je @@end1 ;; Yep.
  150. inc ah ;; Nope.
  151. mov [es:di+bx],ah ;; Increase anim
  152. jmp @@inner_end
  153. @@end1:
  154. mov [BYTE PTR es:di+bx],0 ;; Restart anim
  155. jmp @@inner_end
  156. ENDM inc_param_and_end
  157. Codeseg
  158. ;
  159. ; MACRO to take x/y pos and return array offset
  160. ; X in CX, Y in dX. Does NOT affect any registers except AX (dest.)
  161. ;
  162. MACRO _xy2array2
  163. mov ax,[max_bxsiz] ;; Load maxsize and
  164. push dx
  165. mul dx ;; multiply by Y, storing in AX
  166. ;; (the new DX is irrevelant)
  167. pop dx
  168. add ax,cx ;; Add X.
  169. ENDM _xy2array2
  170. ;
  171. ; Internal procedure to take an x/y pos and a direction and return
  172. ; a new x/y pos. Returns 0FFFFh if offscreen in that direction.
  173. ;
  174. ; X in CX, Y in DX, direction in AL.
  175. ;
  176. proc _arraydir2 near
  177. cmp al,0 ; North?
  178. je @@n
  179. cmp al,1 ; South?
  180. je @@s
  181. cmp al,2 ; East?
  182. je @@e
  183. ; West
  184. dec cx ; Decrease. If < 0, auto 0FFFFh
  185. ret
  186. @@n:
  187. dec dx ; Decrease. If < 0, auto 0FFFFh
  188. @@done:
  189. ret
  190. @@s:
  191. inc dx ; Increase
  192. cmp dx,[board_ysiz]
  193. jne @@done ; Not too big.
  194. mov dx,0FFFFh ; Overflow.
  195. ret
  196. @@e:
  197. inc cx ; Increase
  198. cmp cx,[board_xsiz]
  199. jne @@done ; Not too big.
  200. mov cx,0FFFFh ; Overflow.
  201. ret
  202. endp _arraydir2
  203. ;
  204. ; Update ALL of the stuff on-screen
  205. ;
  206. proc update_screen far
  207. local @@ex_id:byte,@@ex_prm:byte
  208. pusha
  209. push ds es
  210. ; Flip slow_down to slow certain things down
  211. xor [ds:slow_down],1
  212. ; Clear all robots' status code
  213. les di,[robots]
  214. mov cx,NUM_ROBOTS
  215. add di,35
  216. xor ax,ax
  217. cld
  218. @@carscl:
  219. mov [es:di],al
  220. add di,41
  221. dec cx
  222. jnz @@carscl
  223. ; Clear update_done array
  224. les di,[update_done]
  225. mov cx,5000
  226. rep stosw
  227. xor dx,dx
  228. ; BX = array offset, CX = X, DX = Y
  229. ; X and Y already cleared from loop above
  230. xor bx,bx ; Clear offset
  231. push bx ; Save offset
  232. @@outer: ; Y loop
  233. xor cx,cx ; Clear X
  234. @@inner: ; X loop
  235. les di,[ds:level_id]
  236. mov al,[es:di+bx] ; Load id
  237. cmp al,25
  238. jb @@inner_end ; Space thru W Water don't
  239. ; get updated!
  240. les di,[ds:update_done]
  241. test [BYTE PTR es:di+bx],1 ; Is update already done?
  242. jnz @@inner_end ; Yep, done this square
  243. ; already
  244. xor ah,ah ; Fill AX with id
  245. push bx ; Save offset
  246. mov bx,ax ; Make the id the offset
  247. add bl,bl ; Double id
  248. mov si,[ds:flags+bx] ; Get flags byte
  249. pop bx ; Restore array offset
  250. testflag si,A_UPDATE ; Test flags for UPDATE
  251. jz @@inner_end ; No? Continue inner loop
  252. les di,[ds:level_param]
  253. mov ah,[es:di+bx] ; Load param
  254. ; BX=offset, CX=X, DX=Y, AL=id, AH=param, SI=flags, ES:DI=level_param
  255. ; Don't EVER change BX, CX, or DX within the loop!
  256. ; Check id, take appropriate action
  257. cmp al,123
  258. je @@robot
  259. cmp al,124
  260. je @@robot
  261. cmp al,25
  262. je @@ice
  263. cmp al,26
  264. je @@lava
  265. cmp al,63
  266. je @@fire
  267. cmp al,61
  268. je @@bullet
  269. cmp al,38
  270. je @@explosion
  271. cmp al,45
  272. je @@cw
  273. cmp al,46
  274. je @@ccw
  275. cmp al,49
  276. je @@transport
  277. cmp al,78
  278. je @@shootingfire
  279. cmp al,62
  280. je @@missile
  281. cmp al,79
  282. je @@seeker
  283. cmp al,59
  284. je @@lazer
  285. cmp al,56
  286. je @@pusher
  287. cmp al,80
  288. je @@snake
  289. cmp al,81
  290. je @@eye
  291. cmp al,82
  292. je @@thief
  293. cmp al,83
  294. je @@slime
  295. cmp al,84
  296. je @@runner
  297. cmp al,85
  298. je @@ghost
  299. cmp al,86
  300. je @@dragon
  301. cmp al,87
  302. je @@fish
  303. cmp al,88
  304. je @@shark
  305. cmp al,89
  306. je @@spider
  307. cmp al,90
  308. je @@goblin
  309. cmp al,91
  310. je @@tiger
  311. cmp al,92
  312. je @@bulletgun
  313. cmp al,93
  314. je @@spinning
  315. cmp al,94
  316. je @@bear
  317. cmp al,95
  318. je @@cub
  319. cmp al,33
  320. je @@energizer
  321. cmp al,37
  322. je @@litbomb
  323. cmp al,42
  324. je @@opendoor
  325. cmp al,48
  326. je @@opengate
  327. cmp al,51
  328. jb @@not_move_wall
  329. cmp al,54
  330. jbe @@movingwall
  331. @@not_move_wall:
  332. cmp al,60
  333. je @@lazgun
  334. cmp al,66
  335. je @@life
  336. cmp al,67
  337. jb @@not_wp
  338. cmp al,70
  339. jbe @@whirlpool
  340. @@not_wp:
  341. cmp al,74
  342. je @@mine
  343. cmp al,97
  344. je @@misslegun
  345. jmp @@inner_end
  346. ;
  347. ; HERE ON, must preserve BX, CX, and DX. See above for register values.
  348. ;
  349. @@lava:
  350. cmp [ds:slow_down],0
  351. jne @@inner_end
  352. mov si,ax
  353. call random_num ; Get random num
  354. cmp al,20 ; Below 20?
  355. jb @@inner_end ; Yep. DON'T animate
  356. mov ax,si
  357. cmp ah,2 ; At end of anim
  358. je @@endlava ; Yep.
  359. inc ah ; Nope.
  360. mov [es:di+bx],ah ; Increase anim
  361. jmp @@inner_end
  362. @@endlava:
  363. mov [BYTE PTR es:di+bx],0 ; Restart anim
  364. jmp @@inner_end
  365. @@energizer:
  366. inc_param_and_end 7 ; Increase to 7 max
  367. @@life:
  368. cmp [ds:slow_down],0
  369. jne @@inner_end
  370. inc_param_and_end 3 ; Increase to 3 max
  371. @@seeker:
  372. cmp [ds:slow_down],0
  373. jne @@inner_end
  374. or ah,ah ; At end of life?
  375. jz @@seeker_die ; yes
  376. dec ah ; No, decrease anim
  377. mov [es:di+bx],ah
  378. ; Move.
  379. find_seek cx,dx,si
  380. ; Seek dir in dl
  381. ; Call move- X/Y=CX, Dir=DX, Flags=Immed.
  382. call _move,cx,dx,si,1+4+8+16+128+1024
  383. cmp ax,2 ; Player?
  384. jne @@inner_end ; Nope
  385. ; Yeah- hurt 'n' die!
  386. ; COMMON LABEL for enemies, etc
  387. mov si,79
  388. @@hurt_n_die:
  389. ; SI must hold id of what's dmging
  390. hurt_player_id si
  391. call id_remove_top,cx,dx
  392. jmp @@inner_end
  393. @@seeker_die:
  394. call id_remove_top,cx,dx
  395. jmp @@inner_end
  396. @@cw:
  397. @@ccw:
  398. cmp [ds:slow_down],0
  399. jne @@inner_end
  400. inc_param 3 ; Increase to 3 max
  401. sub al,45
  402. xor ah,ah
  403. push dx bx cx
  404. call rotate,cx,dx,ax ; Rotate
  405. pop cx bx dx
  406. jmp @@inner_end
  407. @@litbomb:
  408. cmp [ds:slow_down],0 ; SLOW anim
  409. jne @@inner_end
  410. testflag ah,2 ; At end of anim (Both bits 2 AND 4 set)
  411. jz @@noblow
  412. testflag ah,4
  413. jnz @@blow ; Yep.
  414. @@noblow:
  415. inc ah
  416. mov [BYTE PTR es:di+bx],ah ; Increase anim
  417. jmp @@inner_end
  418. @@blow:
  419. testflag ah,128 ; High?
  420. jnz @@highblow ; Yep
  421. mov [BYTE PTR es:di+bx],0+2*16; Set low param
  422. @@blow2:
  423. les di,[ds:level_id]
  424. mov [BYTE PTR es:di+bx],38 ; Set id
  425. sfxp 36
  426. jmp @@inner_end
  427. @@highblow:
  428. mov [BYTE PTR es:di+bx],0+4*16; Set param
  429. jmp @@blow2
  430. @@explosion:
  431. testflag ah,15 ; Check stage
  432. jz @@outward ; Climb outward- Stage 0!
  433. @@exp2:
  434. mov al,ah
  435. maskflag al,15
  436. cmp al,3 ; Check for final stage
  437. je @@expremove ; Die!
  438. les di,[level_param]
  439. inc ah ; Nope.
  440. mov [es:di+bx],ah ; Increase anim
  441. jmp @@inner_end
  442. @@expremove:
  443. ; Get flags of below to check for entrance
  444. les di,[level_under_id]
  445. mov al,[es:di+bx]
  446. cmp al,34
  447. je @@e_spc ; Goop is spaced
  448. cmp al,20
  449. jb @@notespc
  450. cmp al,26
  451. jbe @@e_spc ; Water, lava, ice are spaced
  452. @@notespc:
  453. add al,al
  454. push bx
  455. mov bl,al
  456. xor bh,bh
  457. mov ax,[ds:flags+bx]
  458. pop bx
  459. testflag ax,A_ENTRANCE
  460. jnz @@e_spc ; Leaves space if entrance
  461. les di,[level_id]
  462. cmp [explosions_leave],EXPL_LEAVE_SPACE ; Leave space?
  463. je @@e_spc
  464. cmp [explosions_leave],EXPL_LEAVE_ASH ; Leave ash?
  465. je @@e_ash
  466. ; Leave fire.
  467. mov [BYTE PTR es:di+bx],63
  468. les di,[level_param]
  469. mov [BYTE PTR es:di+bx],0
  470. jmp @@inner_end
  471. @@e_spc:
  472. call id_remove_top,cx,dx
  473. jmp @@inner_end
  474. @@e_ash:
  475. mov [BYTE PTR es:di+bx],15
  476. les di,[level_color]
  477. mov [BYTE PTR es:di+bx],8
  478. jmp @@inner_end
  479. @@outward: ; Move explosion outward
  480. mov al,ah
  481. and al,240
  482. jz @@exp2 ; Not SUPPOSED to move outward!
  483. sub al,16 ; Decrease by 1 "outward"
  484. xor ah,ah
  485. mov si,ax
  486. ; SI holds param for outward expansion
  487. push ax bx
  488. mov ax,3
  489. @@outloop:
  490. push ax cx dx
  491. call _arraydir2 ; Move in dir
  492. cmp cx,0ffffh ; Out of bounds?
  493. je @@ol_end
  494. cmp dx,0ffffh
  495. je @@ol_end
  496. _xy2array2 ; Get offset
  497. mov bx,ax
  498. les di,[ds:level_param]
  499. mov al,[es:di+bx] ; Get param in that direction (for SPEC_BLOW)
  500. mov [@@ex_prm],al
  501. les di,[ds:level_id]
  502. mov bl,[es:di+bx] ; Get id in that direction
  503. mov [@@ex_id],bl
  504. add bl,bl
  505. xor bh,bh
  506. mov ax,[ds:flags+bx] ; Get flags
  507. testflag ax,A_BLOW_UP ; Blow up?
  508. jnz @@ex2
  509. testflag ax,A_EXPLODE ; Explode?
  510. jnz @@ex3
  511. testflag ax,A_UNDER ; Under?
  512. jnz @@ex1
  513. testflag ax,A_SPEC_BOMB ; SPEC_BOMB ?
  514. jz @@ol_end ; Can't move there
  515. ; Handle players, robots, etc.
  516. ; 34-goop, 74-mine, 83-slime, 85-ghost, 86-dragon, 127-player,
  517. ; 123/124-robot
  518. cmp [@@ex_id],34
  519. je @@ol_end
  520. cmp [@@ex_id],127
  521. je @@ex_player
  522. cmp [@@ex_id],74
  523. je @@ex_mine
  524. cmp [@@ex_id],83
  525. je @@ex_slime
  526. cmp [@@ex_id],85
  527. je @@ex_ghost
  528. cmp [@@ex_id],86
  529. je @@ex_dragon
  530. ; robot bombing
  531. ; send_robot_def,[@@ex_prm],[WORD] 1
  532. pusha
  533. mov al,[@@ex_prm]
  534. xor ah,ah
  535. call send_robot_def,ax,[WORD] 1
  536. popa
  537. jmp @@ol_end
  538. @@ex_slime:
  539. ; If bit 128 is set, don't die.
  540. testflag [@@ex_prm],128
  541. jnz @@ol_end
  542. jmp @@ex2
  543. @@ex_ghost:
  544. ; If bit 8 is set, don't die.
  545. testflag [@@ex_prm],8
  546. jnz @@ol_end
  547. jmp @@ex2
  548. @@ex_dragon:
  549. testflag [@@ex_prm],128+64+32
  550. jz @@ex2 ; If HP=0, die
  551. _xy2array2 ; Get offset
  552. mov bx,ax
  553. mov al,[@@ex_prm]
  554. sub al,32
  555. les di,[level_param]
  556. mov [es:di+bx],al
  557. jmp @@ol_end
  558. @@ex_mine:
  559. call id_remove_top,bx
  560. mov al,[@@ex_prm]
  561. and al,240 ; Use mine radius
  562. call id_place_asm,cx,dx,38,ax ; Place explosion!
  563. jmp @@ol_end
  564. @@ex_player:
  565. hurt_player_id 38
  566. jmp @@ol_end
  567. @@ex3:
  568. call id_remove_top,cx,dx
  569. call id_place_asm,cx,dx,38,64 ; Place NEW explosion!
  570. jmp @@ol_end
  571. @@ex2:
  572. call id_remove_top,cx,dx
  573. @@ex1:
  574. call id_place_asm,cx,dx,38,si ; Place our explosion!
  575. @@ol_end:
  576. pop dx cx ax
  577. dec al
  578. jns @@outloop
  579. pop bx ax
  580. jmp @@exp2
  581. @@transport:
  582. cmp [ds:slow_down],0
  583. jne @@inner_end
  584. testflag ah,8
  585. jz @@transanim
  586. testflag ah,16
  587. jz @@transanim
  588. ; At end of anim
  589. maskflag ah,231 ; Erase anim bits
  590. mov [es:di+bx],ah
  591. jmp @@inner_end
  592. @@transanim:
  593. add ah,8 ; Increase anim
  594. mov [es:di+bx],ah
  595. jmp @@inner_end
  596. @@lazer:
  597. sub ah,8 ; Decrease "time-till-die"
  598. cmp ah,8
  599. jb @@lazdie ; At 0- die! :)
  600. ; Only anim every OTHER cycle
  601. cmp [ds:slow_down],0
  602. jne @@inner_end
  603. testflag ah,2
  604. jz @@lazanim
  605. testflag ah,4
  606. jz @@lazanim
  607. ; At end of anim
  608. maskflag ah,249 ; Erase anim bits
  609. mov [es:di+bx],ah
  610. jmp @@inner_end
  611. @@lazanim:
  612. add ah,2 ; Increase anim
  613. mov [es:di+bx],ah
  614. jmp @@inner_end
  615. @@lazdie:
  616. call id_remove_top,cx,dx
  617. jmp @@inner_end
  618. @@lazgun:
  619. mov al,ah
  620. maskflag al,28
  621. shr al,2 ; AL=start time
  622. cmp [ds:lazwall_start],al ; Correct time?
  623. jne @@inner_end ; Nope.
  624. ; Yep.
  625. les di,[ds:level_color]
  626. mov si,bx
  627. mov bl,[es:di+bx] ; Get color,
  628. xor bh,bh ; fill bx.
  629. mov al,ah
  630. maskflag ah,224
  631. shr ah,5 ; AH=length
  632. inc ah
  633. maskflag al,3 ; AL=direction
  634. call _shoot_lazer,cx,dx,ax,bx
  635. mov bx,si
  636. jmp @@inner_end
  637. @@opengate:
  638. cmp ah,0 ; End of wait?
  639. je @@closegate ; Close.
  640. dec ah
  641. mov [es:di+bx],ah ; dec. wait
  642. jmp @@inner_end
  643. @@closegate:
  644. les di,[ds:level_id]
  645. mov [BYTE PTR es:di+bx],47 ; Close gate
  646. sfxp 25
  647. jmp @@inner_end
  648. @@mine:
  649. testflag ah,2
  650. jz @@mineinc
  651. testflag ah,4
  652. jz @@mineinc
  653. testflag ah,8
  654. jnz @@mineanim
  655. @@mineinc:
  656. add ah,2
  657. mov [es:di+bx],ah ; Increase count
  658. jmp @@inner_end
  659. @@mineanim:
  660. maskflag ah,241 ; Clear count
  661. flipflag ah,1 ; Flip anim bit
  662. mov [es:di+bx],ah ; Set new param
  663. jmp @@inner_end
  664. @@whirlpool:
  665. cmp [ds:slow_down],0 ; Slow down?
  666. jne @@inner_end
  667. les di,[level_id]
  668. cmp al,70 ; Last whirl?
  669. je @@lastwhirl
  670. inc al ; Next "frame" (id) ! :)
  671. mov [es:di+bx],al
  672. jmp @@inner_end
  673. @@lastwhirl:
  674. mov [BYTE PTR es:di+bx],67 ; First id frame
  675. jmp @@inner_end
  676. @@pusher:
  677. ; BX=offset, CX=X, DX=Y, AL=id, AH=param, SI=flags, ES:DI=level_param
  678. cmp [ds:slow_down],0
  679. jne @@inner_end
  680. mov al,ah
  681. xor ah,ah ; AX=dir
  682. ; CX/DX=_xy
  683. call _move,cx,dx,ax,1
  684. jmp @@inner_end
  685. @@movingwall:
  686. xor ah,ah
  687. sub al,51 ; AX=dir
  688. ; CX=_xy
  689. mov si,ax
  690. call _move,cx,dx,ax,1+2+4+8+16
  691. cmp ax,0 ; Move ok?
  692. mov ax,si
  693. je @@inner_end
  694. ; Reverse dir
  695. flip_dir al
  696. add al,51 ; Make into id
  697. les di,[ds:level_id] ; Change id
  698. mov [es:di+bx],al ; Save new id
  699. jmp @@inner_end
  700. @@bullet:
  701. ; Erase old-
  702. call id_remove_top,cx,dx
  703. ; Place new!
  704. mov al,ah
  705. xor ah,ah
  706. mov si,ax
  707. shr al,2 ; AX=typ of bullet (bits 4 & 8 of param)
  708. and si,1+2 ; DX=dir
  709. call _shoot,cx,dx,si,ax
  710. jmp @@inner_end
  711. @@opendoor:
  712. mov al,ah ; Copy param
  713. mov si,ax ; 2 copys
  714. and al,224 ; AL=curr wait
  715. and ah,31 ; AH=stage
  716. push bx
  717. mov bx,OFFSET open_door_max_wait
  718. add bl,ah
  719. adc bh,0 ; BX=offset to get max wait
  720. mov ah,[ds:bx]
  721. pop bx
  722. cmp ah,al ; Compare curr_wait and max_wait
  723. jne @@door_inc_wait ; INCREASE WAIT
  724. ; Move door, reset wait, and increase stage.
  725. mov ax,si ; Use copy of param
  726. and ah,24 ; Stage
  727. ; Reset wait & increase stage, unless stage 3.
  728. cmp ah,24 ; Stage 3?
  729. je @@door_3
  730. mov ax,si
  731. ; reset wait,inc stage
  732. and ah,31 ; Remove wait
  733. add ah,8 ; Next stage
  734. mov [es:di+bx],ah ; Put param
  735. mov ax,si
  736. jmp @@move_door
  737. @@door_3:
  738. mov ax,si
  739. and ah,7 ; Open/orient
  740. mov [es:di+bx],ah
  741. mov ax,si
  742. les di,[ds:level_id]
  743. mov [BYTE PTR es:di+bx],41 ; Reg. door
  744. @@move_door:
  745. mov si,bx
  746. mov di,ax ; Save param in case no movey
  747. mov bx,OFFSET open_door_movement
  748. mov al,ah
  749. and al,31 ; Stage,open,& orient
  750. xlat
  751. cmp al,0ffh ; No movement?
  752. je @@no_door_move ; Jump to fix bx, then haul off to end
  753. xor ah,ah ; Dir fills ax
  754. call _move,cx,dx,ax,1+4+8+16
  755. or ax,ax
  756. @@no_door_move:
  757. mov bx,si
  758. jz @@inner_end ; It moved, go to over
  759. ; No movey! Reset param and id
  760. mov ax,di
  761. les di,[ds:level_param]
  762. mov [es:di+bx],ah ; Reset param
  763. les di,[ds:level_id]
  764. mov [BYTE PTR es:di+bx],42 ; Reset id (for door_3)
  765. jmp @@inner_end
  766. @@door_inc_wait:
  767. ; Increase param's wait portion and store
  768. mov ax,si
  769. add al,32
  770. mov [es:di+bx],al
  771. jmp @@inner_end
  772. @@fire:
  773. mov si,ax
  774. call random_num ; Get random num
  775. cmp al,20 ; Below 20?
  776. jb @@fire2 ; Yep. DON'T animate
  777. mov ax,si
  778. cmp ah,5 ; At end of anim
  779. je @@endfr1 ; Yep.
  780. inc ah ; Nope.
  781. mov [es:di+bx],ah ; Increase anim
  782. jmp @@fire2
  783. @@endfr1:
  784. mov [BYTE PTR es:di+bx],0 ; Restart anim
  785. @@fire2:
  786. ; Check under for water, ice, or lava.
  787. ; Lava and water kills fire.
  788. ; Ice kills fire but melts into stillwater first.
  789. les di,[ds:level_under_id]
  790. mov al,[es:di+bx]
  791. cmp al,20
  792. jb @@fire3
  793. cmp al,26
  794. ja @@fire3
  795. cmp al,25
  796. jne @@fire_die
  797. mov [BYTE PTR es:di+bx],20
  798. les di,[ds:level_under_color]
  799. mov [BYTE PTR es:di+bx],25
  800. @@fire_die:
  801. call id_remove_top,cx,dx
  802. jmp @@inner_end
  803. @@fire3:
  804. ; Die? Spread?
  805. call random_num
  806. cmp al,8 ; > 8?
  807. ja @@inner_end ; No spread or die
  808. cmp al,1 ; = 2-8
  809. ja @@die_done ; No die
  810. cmp [ds:fire_burns],FIRE_BURNS_FOREVER
  811. je @@die_done ; No death here
  812. les di,[ds:level_id]
  813. mov [BYTE PTR es:di+bx],15 ; ASH
  814. les di,[ds:level_color]
  815. mov [BYTE PTR es:di+bx],8 ; (dk. grey)
  816. @@die_done:
  817. ; Spread?
  818. push bx
  819. mov al,3
  820. @@spreadloop:
  821. push ax cx dx
  822. call _arraydir2 ; Move in dir
  823. cmp cx,0ffffh ; Out of bounds?
  824. je @@sl_end
  825. cmp dx,0ffffh
  826. je @@sl_end
  827. _xy2array2 ; Get offset
  828. mov bx,ax
  829. les di,[ds:level_id]
  830. mov al,[es:di+bx] ; Get id in that direction
  831. les di,[ds:level_color]
  832. mov ah,[es:di+bx] ; Get color
  833. ; AL=id AH=color, check for- space, brown, fake/carpet/tiles/custom, trees
  834. cmp al,0
  835. je @@fire_space
  836. cmp al,13
  837. jb @@not_fake_fire
  838. cmp al,19
  839. jbe @@fire_fake
  840. @@not_fake_fire:
  841. cmp al,127
  842. je @@fire_player
  843. cmp ah,6
  844. je @@fire_brown
  845. cmp al,3
  846. je @@fire_tree
  847. jmp @@sl_end
  848. @@fire_player:
  849. cmp [ds:firewalker_dur],0
  850. jne @@sl_end
  851. hurt_player_id 63
  852. jmp @@sl_end
  853. @@fire_tree:
  854. cmp [ds:fire_burn_trees],1
  855. jne @@sl_end
  856. jmp @@fire_place
  857. @@fire_brown:
  858. cmp al,120
  859. ja @@sl_end ; Don't burn scrolls, signs, sensors,
  860. ; robots, or the player!
  861. cmp [ds:fire_burn_brown],1
  862. jne @@sl_end
  863. jmp @@fire_place
  864. @@fire_fake:
  865. cmp [ds:fire_burn_fakes],1
  866. jne @@sl_end
  867. jmp @@fire_place
  868. @@fire_space:
  869. cmp [ds:fire_burn_space],1
  870. jne @@sl_end
  871. @@fire_place:
  872. call id_place_asm,cx,dx,63,0
  873. @@sl_end:
  874. pop dx cx ax
  875. dec al
  876. jns @@spreadloop
  877. pop bx
  878. jmp @@inner_end
  879. @@snake:
  880. testflag ah,4
  881. jz @@sn_move ; Speed = 0
  882. ; Speed = 1
  883. flipflag ah,8 ; Flip count and
  884. mov [es:di+bx],ah ; store.
  885. testflag ah,8
  886. jz @@inner_end ; Count = 0
  887. ; Count = 1
  888. @@sn_move:
  889. mov di,bx
  890. mov bl,ah
  891. maskflag bl,3 ; dx=dir
  892. xor bh,bh
  893. mov si,ax
  894. call _move,cx,dx,bx,128 ; move
  895. xchg ax,si
  896. mov bx,di
  897. cmp si,2
  898. jne @@sn_n_hurt_n_die
  899. mov si,80 ; hurt 'n' die!
  900. jmp @@hurt_n_die
  901. @@sn_n_hurt_n_die:
  902. cmp si,0 ; moved?
  903. je @@inner_end ; done.
  904. ; Choose new dir
  905. maskflag ah,252 ; AH=param minus direction
  906. mov bl,ah
  907. maskflag bl,64+32+16 ; BL=intellegence
  908. shr bl,4
  909. mov bh,ah ; BH=param
  910. call random_num
  911. maskflag al,7 ; AL=0-7
  912. cmp al,bl
  913. jb @@sn_smart ; Rand < Int = Smart Move
  914. ; Dumb Move
  915. call random_num
  916. maskflag al,3 ; AL=new dir
  917. setflag bh,al ; Place into bh
  918. mov ah,bh
  919. mov bx,di
  920. les di,[level_param]
  921. mov [es:di+bx],ah ; store.
  922. jmp @@inner_end
  923. @@sn_smart:
  924. ; Smart move, load seek into bl
  925. find_seek cx,dx,bl
  926. setflag bh,bl ; Add dir into param
  927. mov ah,bh
  928. mov bx,di
  929. les di,[level_param]
  930. mov [es:di+bx],ah ; store.
  931. jmp @@inner_end
  932. @@eye:
  933. testflag ah,64
  934. jz @@i_move ; Speed = 0
  935. ; Speed = 1
  936. flipflag ah,128 ; Flip count and
  937. mov [es:di+bx],ah ; store.
  938. testflag ah,128
  939. jz @@inner_end ; Count = 0
  940. ; Count = 1
  941. @@i_move:
  942. mov di,bx
  943. mov bl,ah
  944. maskflag bl,7 ; dl=intel
  945. mov si,ax
  946. call random_num
  947. maskflag al,7 ; al=0-7
  948. cmp al,bl
  949. jb @@i_smart ; Smart move if rand < intel
  950. ; Dumb move
  951. call random_num
  952. mov bl,al
  953. maskflag al,3 ; dl=dir
  954. jmp @@i_dir
  955. @@i_smart:
  956. find_seek cx,dx,al
  957. @@i_dir:
  958. xor ah,ah ; ax=dir
  959. call _move,cx,dx,ax,4+8+16+128+1024
  960. cmp al,2 ; player?
  961. mov ax,si
  962. mov bx,di
  963. jne @@inner_end
  964. maskflag ah,8+16+32 ; ah=radius
  965. add ah,ah ; put in explosion radius pos.
  966. les di,[level_param]
  967. mov [BYTE PTR es:di+bx],ah
  968. les di,[level_id]
  969. mov [BYTE PTR es:di+bx],38 ; Become explosion!
  970. sfxp 36 ; Expl. sound
  971. jmp @@inner_end
  972. @@thief:
  973. mov si,bx
  974. mov bl,ah
  975. mov bh,ah
  976. and bl,8+16
  977. and bh,32+64
  978. shr bh,2
  979. ; BL=speed, BH=count
  980. cmp bl,bh
  981. mov bx,si
  982. je @@th_move
  983. add ah,32
  984. mov [es:di+bx],ah
  985. jmp @@inner_end
  986. @@th_move:
  987. and ah,255-64-32 ; Zero count
  988. mov [es:di+bx],ah
  989. ; Move now
  990. mov bl,ah
  991. and bl,7 ; bl=intel
  992. push ax
  993. call random_num
  994. and al,7 ; al=0-7
  995. cmp al,bl
  996. pop ax
  997. jb @@th_smart ; Smart move if rand < intel
  998. ; Dumb move
  999. push ax
  1000. call random_num
  1001. mov bl,al
  1002. pop ax
  1003. and bl,3 ; bl=dir
  1004. jmp @@th_dir
  1005. @@th_smart:
  1006. find_seek cx,dx,bl
  1007. @@th_dir:
  1008. flipflag bh,bh ; bx=dir
  1009. push ax
  1010. call _move,cx,dx,bx,128
  1011. cmp al,2 ; player?
  1012. pop ax
  1013. mov bx,si
  1014. jne @@inner_end
  1015. ; Take gems
  1016. mov al,ah
  1017. flipflag ah,ah
  1018. and al,128
  1019. shr al,7 ; dx=gems to take
  1020. inc al
  1021. mov di,OFFSET gem_name
  1022. push bx cx dx
  1023. call dec_counter,di,ds,ax,0
  1024. pop dx cx bx
  1025. sfxp 44
  1026. jmp @@inner_end
  1027. @@slime:
  1028. cmp [ds:slow_down],0
  1029. jne @@inner_end
  1030. mov si,bx
  1031. mov bl,ah
  1032. mov bh,ah
  1033. ; BL= SPEED BITS << 2 + SPEED BITS
  1034. and bl,1+2
  1035. mov al,bl
  1036. add bl,bl
  1037. setflag bl,al
  1038. ; BH= COUNT BITS >> 2
  1039. and bh,32+16+8+4
  1040. shr bh,2
  1041. ; BL=speed, BH=count
  1042. cmp bl,bh
  1043. mov bx,si
  1044. je @@slime_spread
  1045. add ah,4
  1046. mov [es:di+bx],ah
  1047. jmp @@inner_end
  1048. @@slime_spread:
  1049. ; SPREAD LOOP
  1050. push bx
  1051. ; Spread?
  1052. les di,[ds:level_color]
  1053. mov bh,[es:di+bx]
  1054. mov bl,83
  1055. mov si,bx
  1056. mov bl,ah
  1057. and bl,255-8-16-32
  1058. ; BL holds param for outward expansion,
  1059. ; and SI=id/color.
  1060. flipflag ax,ax
  1061. @@slimeloop:
  1062. push ax cx dx
  1063. call _arraydir2 ; Move in dir
  1064. cmp cx,0ffffh ; Out of bounds?
  1065. je @@ssl_end
  1066. cmp dx,0ffffh
  1067. je @@ssl_end
  1068. push bx
  1069. _xy2array2 ; Get offset
  1070. mov bx,ax
  1071. les di,[ds:level_id]
  1072. mov al,[es:di+bx] ; Get id in that direction
  1073. pop bx
  1074. ; AL=id
  1075. cmp al,0
  1076. je @@slime_fake
  1077. cmp al,13
  1078. je @@slime_fake
  1079. cmp al,14
  1080. je @@slime_fake
  1081. cmp al,15
  1082. je @@slime_fake
  1083. cmp al,16
  1084. je @@slime_fake
  1085. cmp al,17
  1086. je @@slime_fake
  1087. cmp al,18
  1088. je @@slime_fake
  1089. cmp al,19
  1090. je @@slime_fake
  1091. cmp al,127
  1092. je @@slime_player
  1093. jmp @@ssl_end
  1094. @@slime_player:
  1095. testflag bl,64
  1096. jz @@ssl_end ; No hurt.
  1097. hurt_player_id 83
  1098. jmp @@ssl_end
  1099. @@slime_fake:
  1100. ; BX=XY,BL=param SI=id/color
  1101. call id_place_asm,cx,dx,si,bx
  1102. @@ssl_end:
  1103. pop dx cx ax
  1104. inc al
  1105. cmp al,4
  1106. jb @@slimeloop
  1107. pop bx
  1108. maskflag si,65535-255 ; Clear id
  1109. setflag si,6
  1110. call id_place_asm,cx,dx,si,0
  1111. jmp @@inner_end
  1112. @@runner:
  1113. mov si,bx
  1114. mov bl,ah
  1115. mov bh,ah
  1116. and bl,4+8
  1117. and bh,32+16
  1118. shr bh,2
  1119. ; BL=speed, BH=count
  1120. cmp bl,bh
  1121. mov bx,si
  1122. je @@run_run
  1123. add ah,16
  1124. mov [es:di+bx],ah
  1125. jmp @@inner_end
  1126. @@run_run:
  1127. and ah,255-32-16
  1128. mov [es:di+bx],ah
  1129. mov bl,ah
  1130. xor bh,bh
  1131. and bl,3 ; BX=dir
  1132. push ax
  1133. call _move,cx,dx,bx,1+2+128
  1134. xchg ax,si
  1135. mov bx,ax
  1136. pop ax
  1137. cmp si,0 ; Move ok?
  1138. je @@inner_end
  1139. cmp si,2 ; Player?
  1140. jne @@run_n_hurt_n_die
  1141. mov si,84
  1142. jmp @@hurt_n_die
  1143. @@run_n_hurt_n_die:
  1144. ; Reverse dir
  1145. xor ah,1
  1146. mov [es:di+bx],ah ; Save new param
  1147. jmp @@inner_end
  1148. @@ghost:
  1149. mov si,bx
  1150. mov bl,ah
  1151. mov bh,ah
  1152. and bl,16+32
  1153. and bh,64+128
  1154. shr bh,2
  1155. ; BL=speed, BH=count
  1156. cmp bl,bh
  1157. mov bx,si
  1158. je @@gh_move
  1159. add ah,64
  1160. mov [es:di+bx],ah
  1161. jmp @@inner_end
  1162. @@gh_move:
  1163. and ah,255-64-128 ; Zero count
  1164. mov [es:di+bx],ah
  1165. ; Move now
  1166. mov bl,ah
  1167. and bl,7 ; dl=intel
  1168. push ax
  1169. call random_num
  1170. and al,7 ; al=0-7
  1171. cmp al,bl
  1172. pop ax
  1173. jb @@gh_smart ; Smart move if rand < intel
  1174. ; Dumb move
  1175. push ax
  1176. call random_num
  1177. mov bl,al
  1178. pop ax
  1179. and bl,3 ; dl=dir
  1180. jmp @@gh_dir
  1181. @@gh_smart:
  1182. find_seek cx,dx,bl
  1183. @@gh_dir:
  1184. flipflag bh,bh ; dx=dir
  1185. push ax
  1186. call _move,cx,dx,bx,4+8+16+128+1024
  1187. cmp al,2 ; player?
  1188. pop ax
  1189. mov bx,si
  1190. jne @@inner_end
  1191. ; Hit player
  1192. mov si,85
  1193. testflag ah,8
  1194. jz @@hurt_n_die ; Not invinco
  1195. hurt_player_id 85 ; Invinco
  1196. jmp @@inner_end
  1197. @@dragon:
  1198. testflag ah,4
  1199. jnz @@move_ok
  1200. push cx dx
  1201. jmp @@dr_try_fire ; No move, try fire
  1202. @@move_ok:
  1203. mov si,bx
  1204. mov bh,ah
  1205. and bh,16+8
  1206. ; BH=count
  1207. cmp bh,16+8
  1208. mov bx,si
  1209. je @@dr_move
  1210. add ah,8
  1211. mov [es:di+bx],ah
  1212. push cx dx
  1213. jmp @@dr_try_fire
  1214. @@dr_move:
  1215. and ah,255-16-8 ; Zero count
  1216. mov [es:di+bx],ah
  1217. ; Move now
  1218. push ax
  1219. call random_num
  1220. testflag al,7
  1221. jz @@dr_dumb_move ; 1 out of 8 moves is random
  1222. find_seek cx,dx,bl
  1223. flipflag bh,bh ; bx=dir
  1224. jmp @@dr_move2
  1225. @@dr_dumb_move:
  1226. call random_num ; Random dir
  1227. maskflag ax,3
  1228. mov bx,ax ; bx=dir
  1229. @@dr_move2:
  1230. call _move,cx,dx,bx,4+8+128
  1231. mov bh,al
  1232. pop ax
  1233. cmp bh,2 ; player?
  1234. je @@dr_player
  1235. cmp bh,0
  1236. xchg bx,si
  1237. jne @@inner_end ; Blocked.
  1238. ; get new dir and fire
  1239. xchg bx,si
  1240. push cx dx ax
  1241. mov ax,bx
  1242. call _arraydir2
  1243. pop ax
  1244. mov bx,si
  1245. @@dr_try_fire:
  1246. mov si,bx
  1247. mov bl,ah
  1248. and bl,3 ; bl=fire rate
  1249. push ax
  1250. call random_num
  1251. and al,15 ; al=0-15
  1252. cmp al,bl
  1253. pop ax
  1254. jb @@dr_fire2 ; Fire seek if rand < rate
  1255. pop dx cx
  1256. mov bx,si
  1257. jmp @@inner_end
  1258. @@dr_fire2:
  1259. find_seek cx,dx,bx
  1260. call _shoot_fire,cx,dx,bx
  1261. pop dx cx
  1262. mov bx,si
  1263. sfxp 46
  1264. jmp @@inner_end
  1265. @@dr_player:
  1266. ; Hit player
  1267. mov bx,si
  1268. hurt_player_id 86 ; Invinco
  1269. jmp @@inner_end
  1270. @@shootingfire:
  1271. xor ah,1 ; Flip anim
  1272. mov [es:di+bx],ah ; And store
  1273. ; Move in dir
  1274. mov al,ah
  1275. shr al,1
  1276. xor ah,ah ; ax=dir
  1277. call _move,cx,dx,ax,4+8+16+128+1024+2048
  1278. cmp al,2
  1279. jne @@sf_n_hurt_n_die ; Hit player
  1280. mov si,78
  1281. jmp @@hurt_n_die
  1282. @@sf_n_hurt_n_die:
  1283. or al,al
  1284. jz @@inner_end ; Done if moved ok.
  1285. ; Become fire
  1286. les di,[ds:level_under_id]
  1287. cmp [BYTE PTR es:di+bx],43
  1288. je @@_sf_die ; entrance
  1289. cmp [BYTE PTR es:di+bx],44
  1290. je @@_sf_die ; entrance
  1291. cmp [BYTE PTR es:di+bx],67
  1292. je @@_sf_die ; entrance
  1293. cmp [BYTE PTR es:di+bx],68
  1294. je @@_sf_die ; entrance
  1295. cmp [BYTE PTR es:di+bx],69
  1296. je @@_sf_die ; entrance
  1297. cmp [BYTE PTR es:di+bx],70
  1298. je @@_sf_die ; entrance
  1299. les di,[ds:level_id]
  1300. mov [BYTE PTR es:di+bx],63 ; id of fire
  1301. les di,[ds:level_param]
  1302. mov [BYTE PTR es:di+bx],0 ; param of fire
  1303. jmp @@inner_end
  1304. @@_sf_die:
  1305. call id_remove_top,cx,dx
  1306. jmp @@inner_end
  1307. @@missile:
  1308. ; Move in dir
  1309. mov al,ah
  1310. xor ah,ah ; ax=dir
  1311. push ax
  1312. call _move,cx,dx,ax,4+8+16+128+1024
  1313. mov si,ax
  1314. pop ax
  1315. cmp si,2
  1316. je @@miss_blow ; Hit player
  1317. cmp si,0
  1318. je @@inner_end ; Done if moved ok.
  1319. ; Try to turn- CW then CCW
  1320. mov ah,al ; Save dir
  1321. push bx
  1322. mov bx,OFFSET cwturndir
  1323. xlat
  1324. pop bx
  1325. mov [es:di+bx],al ; Store new param
  1326. ; Try the new dir
  1327. push ax
  1328. call _move,cx,dx,ax,4+8+16+128+1024
  1329. mov si,ax
  1330. pop ax
  1331. cmp si,2
  1332. je @@miss_blow ; Player
  1333. cmp si,0
  1334. je @@inner_end ; Moved
  1335. ; Now try CCW of orig. dir
  1336. mov al,dh
  1337. push bx ; Get CCW
  1338. mov bx,OFFSET ccwturndir
  1339. xlat
  1340. pop bx
  1341. mov [es:di+bx],al ; Store new param
  1342. ; Try the new dir
  1343. call _move,cx,dx,ax,4+8+16+128+1024
  1344. cmp al,0
  1345. je @@inner_end ; Okay.
  1346. ; Player or dead-end - blow up!
  1347. @@miss_blow:
  1348. mov [BYTE PTR es:di+bx],48 ; param of explosion
  1349. les di,[level_id]
  1350. mov [BYTE PTR es:di+bx],38 ; id of explosion
  1351. sfxp 36
  1352. jmp @@inner_end
  1353. @@fish:
  1354. testflag ah,8
  1355. jz @@f_move ; Speed = 0
  1356. ; Speed = 1
  1357. testflag ah,16
  1358. jnz @@f_move ; Count = 1
  1359. ; Count = 0
  1360. xor ah,16 ; Set count 1 and
  1361. mov [es:di+bx],ah ; store.
  1362. jmp @@inner_end
  1363. @@f_move:
  1364. and ah,255-16 ; Set count 0 and
  1365. mov [es:di+bx],ah ; store.
  1366. testflag ah,32 ; Affected by current?
  1367. jz @@f_move_ok ; Nope.
  1368. ; Yep, get under.
  1369. les di,[ds:level_under_id]
  1370. mov al,[es:di+bx]
  1371. sub al,21
  1372. ; DL=0-3 for dir, >3 for reg. move
  1373. cmp al,3
  1374. jbe @@f_move_dir
  1375. @@f_move_ok:
  1376. mov si,bx
  1377. mov bl,ah
  1378. and bl,7 ; dl=intel
  1379. push ax
  1380. call random_num
  1381. and al,7 ; al=0-7
  1382. cmp al,bl
  1383. pop ax
  1384. jb @@f_smart ; Smart move if rand < intel
  1385. ; Dumb move
  1386. push ax
  1387. call random_num
  1388. mov bl,al
  1389. pop ax
  1390. and bl,3 ; dl=dir
  1391. mov al,bl
  1392. mov bx,si
  1393. jmp @@f_move_dir
  1394. @@f_smart:
  1395. find_seek cx,dx,ax
  1396. mov bx,si
  1397. @@f_move_dir:
  1398. ; Move in dir al
  1399. push ax
  1400. xor ah,ah
  1401. call _move,cx,dx,ax,16+128+256
  1402. cmp al,2
  1403. pop ax
  1404. je @@f_player
  1405. jmp @@inner_end
  1406. @@f_player:
  1407. testflag ah,64
  1408. jz @@inner_end
  1409. ; Hurts.
  1410. mov si,87
  1411. jmp @@hurt_n_die
  1412. @@shark:
  1413. ; Move
  1414. cmp [ds:slow_down],0
  1415. jne @@inner_end
  1416. mov si,bx
  1417. mov bl,ah
  1418. and bl,7 ; dl=intel
  1419. push ax
  1420. call random_num
  1421. and al,7 ; al=0-7
  1422. cmp al,bl
  1423. pop ax
  1424. jb @@sk_smart ; Smart move if rand < intel
  1425. ; Dumb move
  1426. push ax
  1427. call random_num
  1428. mov bl,al
  1429. pop ax
  1430. and bl,3 ; dl=dir
  1431. jmp @@sk_move_dir
  1432. @@sk_smart:
  1433. find_seek cx,dx,bl
  1434. @@sk_move_dir:
  1435. flipflag bh,bh ; dx=dir
  1436. push ax
  1437. call _move,cx,dx,bx,512+128+4
  1438. mov bh,al
  1439. pop ax
  1440. cmp bh,2 ; player?
  1441. jne @@sk_n_hurt_n_die
  1442. mov bx,si
  1443. mov si,88
  1444. jmp @@hurt_n_die
  1445. @@sk_n_hurt_n_die:
  1446. cmp bh,0
  1447. mov bx,si
  1448. je @@sk_ok_to_fire ; not Blocked.
  1449. push cx dx
  1450. jmp @@sk_dir_gotten ; Fire even if blocked
  1451. @@sk_ok_to_fire:
  1452. ; get new dir and fire
  1453. push cx dx
  1454. call _arraydir2
  1455. @@sk_dir_gotten:
  1456. ; Attempt to fire
  1457. mov si,bx
  1458. mov bl,ah
  1459. and bl,32+64+128 ; bl=fire rate
  1460. shr bl,5
  1461. push ax
  1462. call random_num
  1463. and al,31 ; al=0-31
  1464. cmp al,bl
  1465. pop ax
  1466. jbe @@sk_fire2 ; Fire seek if rand <= rate
  1467. pop dx cx
  1468. mov bx,si
  1469. jmp @@inner_end
  1470. @@sk_fire2:
  1471. find_seek cx,dx,bl
  1472. mov bh,ah
  1473. and bh,16+8
  1474. @@fire_time:
  1475. ; General loc.-
  1476. ; Fires dir BL of AX (x/y) according to BH then ends.
  1477. ; BH=0 for bullets, 8 for seeker, 16 for fire, 24 for cancel
  1478. ; BX is stored in SI and CX DX is on stack
  1479. cmp bh,24
  1480. je @@fire_time_end
  1481. cmp bh,0
  1482. je @@ft_shoot
  1483. cmp bh,8
  1484. je @@ft_seeker
  1485. ; bh=16, @@ft_fire
  1486. xor bh,bh
  1487. call _shoot_fire,cx,dx,bx
  1488. sfxp 46
  1489. jmp @@fire_time_end
  1490. @@ft_shoot:
  1491. xor bh,bh
  1492. mov di,ENEMY_BULLET
  1493. call _shoot,cx,dx,bx,di
  1494. jmp @@fire_time_end
  1495. @@ft_seeker:
  1496. xor bh,bh
  1497. call _shoot_seeker,cx,dx,bx
  1498. @@fire_time_end:
  1499. mov bx,si
  1500. pop dx cx
  1501. jmp @@inner_end
  1502. @@spider:
  1503. testflag ah,32
  1504. jz @@spdr_move ; Speed = 0
  1505. ; Speed = 1
  1506. testflag ah,64
  1507. jnz @@spdr_move ; Count = 1
  1508. ; Count = 0
  1509. xor ah,64 ; Set count 1 and
  1510. mov [es:di+bx],ah ; store.
  1511. jmp @@inner_end
  1512. @@spdr_move:
  1513. and ah,255-64 ; Set count 0 and
  1514. mov [es:di+bx],ah ; store.
  1515. mov si,bx
  1516. mov bl,ah
  1517. and bl,7 ; dl=intel
  1518. push ax
  1519. call random_num
  1520. and al,7 ; al=0-7
  1521. cmp al,bl
  1522. pop ax
  1523. jb @@spdr_smart ; Smart move if rand < intel
  1524. ; Dumb move
  1525. push ax
  1526. call random_num
  1527. mov bl,al
  1528. pop ax
  1529. and bl,3 ; dl=dir
  1530. jmp @@spdr_move_dir
  1531. @@spdr_smart:
  1532. find_seek cx,dx,bl
  1533. @@spdr_move_dir:
  1534. xor bh,bh ; Move in dir dl
  1535. mov di,128 ; si=flags
  1536. ; Get "web" setting
  1537. mov al,ah
  1538. and al,16+8
  1539. shl al,2
  1540. add al,32
  1541. ; al=32 reg, 64 thck, 96 both, 128 anything
  1542. cmp al,128
  1543. je @@spdr_flags_done
  1544. flipflag ah,ah
  1545. add di,ax ; Add "web flags" to flags
  1546. @@spdr_flags_done:
  1547. call _move,cx,dx,bx,di
  1548. cmp al,2
  1549. mov bx,si
  1550. mov si,89
  1551. je @@hurt_n_die
  1552. jmp @@inner_end
  1553. @@tiger:
  1554. cmp [ds:slow_down],0
  1555. jne @@inner_end
  1556. ; Move
  1557. mov si,bx
  1558. mov bl,ah
  1559. and bl,7 ; dl=intel
  1560. push ax
  1561. call random_num
  1562. and al,7 ; al=0-7
  1563. cmp al,bl
  1564. pop ax
  1565. jb @@tg_smart ; Smart move if rand < intel
  1566. ; Dumb move
  1567. push ax
  1568. call random_num
  1569. mov bl,al
  1570. pop ax
  1571. and bl,3 ; dl=dir
  1572. jmp @@tg_move_dir
  1573. @@tg_smart:
  1574. find_seek cx,dx,bl
  1575. @@tg_move_dir:
  1576. flipflag bh,bh ; dx=dir
  1577. push ax
  1578. call _move,cx,dx,bx,16+128
  1579. mov bh,al
  1580. pop ax
  1581. cmp bh,2 ; player?
  1582. jne @@sk_n_hurt_n_die ; REST OF TIGER LOGIC IS SAME AS SHARK
  1583. mov bx,si
  1584. mov si,91
  1585. jmp @@hurt_n_die
  1586. @@goblin:
  1587. cmp [ds:slow_down],0
  1588. jne @@inner_end
  1589. mov si,bx
  1590. mov bl,ah
  1591. testflag bl,32
  1592. jz @@gb_move ; Move
  1593. ; Rest
  1594. mov bl,ah
  1595. mov bh,ah
  1596. and bl,2+1
  1597. add bl,bl
  1598. inc bl
  1599. and bh,16+8+4
  1600. shr bh,2
  1601. ; BL=rest length, BH=rest count
  1602. cmp bl,bh
  1603. mov bx,si
  1604. je @@gb_time_to_move
  1605. add ah,4
  1606. mov [es:di+bx],ah
  1607. jmp @@inner_end
  1608. @@gb_time_to_move:
  1609. ; Reset count and flip switch to moving
  1610. and ah,255-4-8-16-32
  1611. mov [es:di+bx],ah
  1612. jmp @@inner_end
  1613. @@gb_move:
  1614. ; Increase count, if 5 reset and flip
  1615. ; switch to resting
  1616. add ah,4
  1617. mov bl,ah
  1618. and bl,4+8+16
  1619. cmp bl,20
  1620. jne @@gb_move_now
  1621. ; Reset & flip
  1622. and ah,255-4-8-16
  1623. or ah,32
  1624. @@gb_move_now:
  1625. ; Store new parameter
  1626. xchg si,bx
  1627. mov [es:di+bx],ah
  1628. xchg si,bx
  1629. ; Move now
  1630. mov bl,ah
  1631. and bl,64+128 ; dl=intel
  1632. shr bl,6
  1633. push ax
  1634. call random_num
  1635. and al,3 ; al=0-3
  1636. cmp al,bl
  1637. pop ax
  1638. jb @@gb_smart ; Smart move if rand < intel
  1639. ; Dumb move
  1640. push ax
  1641. call random_num
  1642. mov bl,al
  1643. pop ax
  1644. and bl,3 ; dl=dir
  1645. jmp @@gb_dir
  1646. @@gb_smart:
  1647. find_seek cx,dx,bl
  1648. @@gb_dir:
  1649. flipflag bh,bh ; bx=dir
  1650. ; cx/dx=x/y
  1651. push ax
  1652. call _move,cx,dx,bx,16+128
  1653. cmp al,2 ; player?
  1654. pop ax
  1655. mov bx,si
  1656. jne @@inner_end
  1657. ; Hit player
  1658. mov si,90
  1659. jmp @@hurt_n_die
  1660. @@cub:
  1661. cmp [ds:slow_down],0
  1662. jne @@inner_end
  1663. ; Increase count
  1664. mov si,bx
  1665. mov bl,ah
  1666. mov bh,ah
  1667. and bl,8+4
  1668. shr bl,1
  1669. inc bl
  1670. and bh,16+32+64
  1671. shr bh,4
  1672. ; BL=length, BH=count
  1673. cmp bl,bh
  1674. je @@cub_switch_typ
  1675. add ah,16
  1676. jmp @@cub_time_to_move
  1677. @@cub_switch_typ:
  1678. ; Reset count and flip switch
  1679. and ah,255-16-32-64
  1680. xor ah,128
  1681. @@cub_time_to_move:
  1682. mov bx,si
  1683. mov [es:di+bx],ah
  1684. ; Move now
  1685. mov bl,ah
  1686. and bl,1+2 ; bl=intel
  1687. push ax
  1688. call random_num
  1689. and al,3 ; al=0-3
  1690. cmp al,bl
  1691. pop ax
  1692. jb @@cub_smart ; Smart move if rand < intel
  1693. ; Dumb move
  1694. push ax
  1695. call random_num
  1696. mov bl,al
  1697. pop ax
  1698. and bl,3 ; dl=dir
  1699. jmp @@cub_dir
  1700. @@cub_smart:
  1701. find_seek cx,dx,bl
  1702. @@cub_dir:
  1703. ; if "run" mode then reverse dir
  1704. testflag ah,128
  1705. jz @@cub_not_run
  1706. flip_dir bl
  1707. @@cub_not_run:
  1708. flipflag bh,bh ; bx=dir
  1709. ; cx=x/y
  1710. call _move,cx,dx,bx,16+128
  1711. cmp al,2 ; player?
  1712. mov bx,si
  1713. jne @@inner_end
  1714. ; Hit player
  1715. mov si,95
  1716. jmp @@hurt_n_die
  1717. @@bear:
  1718. mov si,bx
  1719. mov bl,ah
  1720. mov bh,ah
  1721. and bl,8+16
  1722. and bh,32+64
  1723. shr bh,2
  1724. ; BL=speed, BH=count
  1725. cmp bl,bh
  1726. mov bx,si
  1727. je @@bear_move
  1728. add ah,32
  1729. mov [es:di+bx],ah
  1730. jmp @@inner_end
  1731. @@bear_move:
  1732. and ah,255-64-32 ; Zero count
  1733. mov [es:di+bx],ah
  1734. ; Move now
  1735. push cx dx
  1736. sub cx,[player_x]
  1737. jns @@cx_positive
  1738. neg cx
  1739. @@cx_positive:
  1740. sub dx,[player_y]
  1741. jns @@dx_positive
  1742. neg dx
  1743. @@dx_positive:
  1744. ; CX=x offset of player, DX=y offset
  1745. ; of player
  1746. add cx,dx
  1747. ; CX=player distance
  1748. mov dl,ah
  1749. and dl,7
  1750. inc dl ; Increase (so sens. 0 is really 2)
  1751. add dl,dl ; Double sensitivity
  1752. ; DH=bear sensitivity
  1753. xor dh,dh
  1754. cmp cx,dx
  1755. pop dx cx
  1756. jbe @@bear_can_move
  1757. ; Not close enough
  1758. jmp @@inner_end
  1759. @@bear_can_move:
  1760. ; Distance is below or equal to sensitivity.
  1761. find_seek cx,dx,bl
  1762. flipflag bh,bh ; bx=dir
  1763. ; cx=x/y
  1764. call _move,cx,dx,bx,16+128
  1765. cmp al,2 ; player?
  1766. mov bx,si
  1767. jne @@inner_end
  1768. ; Hit player
  1769. mov si,94
  1770. jmp @@hurt_n_die
  1771. @@bulletgun:
  1772. cmp [ds:slow_down],0
  1773. jne @@inner_end
  1774. @@spingun_entry:
  1775. mov si,bx
  1776. mov bl,ah
  1777. mov bh,ah
  1778. and bl,7 ; Get rate
  1779. call random_num
  1780. and al,15
  1781. cmp al,bl
  1782. xchg si,bx
  1783. ja @@inner_end ; Fire if rand <= rate
  1784. xchg si,bx
  1785. mov bl,bh
  1786. and bl,64+32 ; Get intel.
  1787. call random_num
  1788. and al,64+32
  1789. flipflag di,di ; DI=0 for 1 FIRE (if aimed)
  1790. cmp al,bl
  1791. jbe @@bg_smart
  1792. xor di,1 ; NO FIRE (if aimed)
  1793. @@bg_smart:
  1794. find_seek cx,dx,bl ; Get seek
  1795. mov ah,bh
  1796. and ah,16+8
  1797. shr ah,3 ; Get dir.
  1798. cmp bl,ah ; Same?
  1799. je @@bg_same
  1800. xor di,1 ; If NOT same, then flip whether to fire
  1801. @@bg_same:
  1802. cmp di,0 ; Fire?
  1803. xchg bx,si
  1804. jne @@inner_end
  1805. xchg bx,si
  1806. ; Fire in dir ah
  1807. mov bl,ah
  1808. testflag bh,128 ; Fire or bullet?
  1809. jz @@bg_bullet
  1810. flipflag bh,bh
  1811. call _shoot_fire,cx,dx,bx
  1812. xchg si,bx
  1813. jmp @@inner_end
  1814. xchg si,bx
  1815. @@bg_bullet:
  1816. flipflag bh,bh
  1817. call _shoot,cx,dx,bx,ENEMY_BULLET
  1818. mov bx,si
  1819. jmp @@inner_end
  1820. @@spinning:
  1821. cmp [ds:slow_down],0
  1822. jne @@inner_end
  1823. testflag ah,8
  1824. jz @@sg_anim
  1825. testflag ah,16
  1826. jz @@sg_anim
  1827. and ah,255-16-8
  1828. jmp @@sg2
  1829. @@sg_anim:
  1830. add ah,8
  1831. @@sg2:
  1832. mov [es:di+bx],ah
  1833. jmp @@spingun_entry
  1834. @@misslegun:
  1835. cmp [ds:slow_down],0
  1836. jne @@inner_end
  1837. mov si,bx
  1838. mov bl,ah
  1839. mov bh,ah
  1840. and bl,7 ; Get rate
  1841. cmp bl,7
  1842. je @@mg_rate_ok ; ALWAYS fire if rate 7
  1843. call random_num
  1844. and al,31
  1845. cmp al,bl
  1846. mov al,bh
  1847. mov bx,si
  1848. ja @@inner_end ; Fire if rand <= rate
  1849. mov bh,al
  1850. @@mg_rate_ok:
  1851. find_seek cx,dx,bl
  1852. ; BL holds player dir
  1853. mov al,bh
  1854. shr al,3 ; AL=missile dir
  1855. and al,3
  1856. cmp al,bl
  1857. xchg bx,si
  1858. jne @@inner_end ; Wrong direction
  1859. xchg bx,si
  1860. ; Right dir- fire!
  1861. mov bl,al
  1862. mov al,bh
  1863. flipflag bh,bh ; BX=dir, CX/DX=source pos
  1864. call _shoot_missile,cx,dx,bx
  1865. testflag al,128
  1866. mov bx,si
  1867. jnz @@inner_end
  1868. ; Only one shot- kill self.
  1869. call id_remove_top,cx,dx
  1870. jmp @@inner_end
  1871. @@ice:
  1872. cmp ah,0
  1873. je @@ice_start ; Check random_num to start ice anim
  1874. cmp ah,3
  1875. je @@ice_end ; End ice anim
  1876. inc ah
  1877. mov [es:di+bx],ah ; Increase anim
  1878. jmp @@inner_end
  1879. @@ice_end:
  1880. mov [BYTE PTR es:di+bx],0 ; Clear anim
  1881. jmp @@inner_end
  1882. @@ice_start:
  1883. call random_num ; Get random num
  1884. cmp al,0 ; If zero,
  1885. jne @@inner_end ; then start anim-
  1886. inc al ; al=1
  1887. mov [es:di+bx],al ; First frame
  1888. jmp @@inner_end
  1889. @@robot:
  1890. push bx cx dx
  1891. ; ah=param=id of robot!
  1892. mov al,ah
  1893. xor ah,ah
  1894. ; x/y in cx/dx
  1895. ; call sub
  1896. call run_robot,ax,cx,dx
  1897. pop dx cx bx
  1898. les di,[update_done]
  1899. mov ax,[es:di]
  1900. and ax,254
  1901. cmp ax,254
  1902. je @@all_done ; Abort loop on Swap World
  1903. @@inner_end:
  1904. inc cx ; X+=1
  1905. inc bx ; offset+=1
  1906. cmp cx,[ds:board_xsiz] ; out of bounds?
  1907. jne @@inner ; Nope, loop
  1908. ; Yep-
  1909. pop bx ; Load old offset
  1910. add bx,[max_bxsiz] ; offset+=max_bxsiz (down one row)
  1911. push bx ; Save new offset
  1912. inc dx ; Y+=1
  1913. cmp dx,[ds:board_ysiz] ; out of bounds?
  1914. jne @@outer ; Nope, loop (X=0 auto)
  1915. @@all_done:
  1916. pop bx ; Done, pop offset
  1917. ; Do REVERSE robot loop
  1918. mov cx,[ds:board_xsiz]
  1919. dec cx
  1920. mov bx,[ds:board_ysiz]
  1921. dec bx
  1922. ; Calculate offset
  1923. mov ax,[max_bxsiz] ; Multiply 100 by
  1924. mul bx ; Y pos,
  1925. mov dx,bx
  1926. add ax,cx ; add X pos,
  1927. mov bx,ax
  1928. mov si,bx
  1929. les di,[ds:level_id]
  1930. @@rrl_loop:
  1931. mov al,[es:di+bx]
  1932. cmp al,123
  1933. jb @@rrl_not
  1934. cmp al,124
  1935. ja @@rrl_not
  1936. les di,[ds:level_param]
  1937. mov al,[es:di+bx]
  1938. xor ah,ah
  1939. neg ax
  1940. push si bx cx dx
  1941. call run_robot,ax,cx,dx
  1942. pop dx cx bx si
  1943. les di,[ds:level_id]
  1944. @@rrl_not:
  1945. dec bx
  1946. dec cx
  1947. jns @@rrl_loop
  1948. mov cx,[ds:board_xsiz]
  1949. dec cx
  1950. mov bx,si
  1951. sub bx,[ds:max_bxsiz]
  1952. mov si,bx
  1953. dec dx
  1954. jns @@rrl_loop
  1955. ; Done!
  1956. call find_player
  1957. pop es ds
  1958. popa
  1959. ret
  1960. endp update_screen
  1961. proc _shoot_lazer near
  1962. arg _cx_x:word,_cx_y:word,_ax_pd:word,color:word
  1963. ; _cx_x/_cx_y- x/y pos
  1964. ; _ax_pd- al=dir ah=length
  1965. pusha
  1966. push es
  1967. mov cx,[_cx_x]
  1968. mov dx,[_cx_y]
  1969. @@laz_loop:
  1970. mov ax,[_ax_pd] ; Load al with dir
  1971. call _arraydir2 ; Move x/y in direction
  1972. cmp cx,0ffffh ; Out of bounds? Quit loop.
  1973. je @@end_laz
  1974. cmp dx,0ffffh
  1975. je @@end_laz
  1976. ; Get offset
  1977. _xy2array2 ; Offset in AX
  1978. mov bx,ax ; Offset in BX & AX
  1979. les di,[ds:level_id] ; level ids
  1980. mov bl,[es:di+bx] ; Get id
  1981. ; Check for player
  1982. cmp bl,127
  1983. jne @@not_lplayer
  1984. ; Take health and try to move player in opposite of last dir
  1985. hurt_player_id 59
  1986. cmp [restart_if_zapped],1
  1987. je @@end_laz
  1988. mov al,[player_last_dir]
  1989. and al,15
  1990. dec al
  1991. js @@end_laz
  1992. xor ah,ah ; AX=last dir (must reverse)
  1993. flip_dir al
  1994. call _move,cx,dx,ax,1+2+16
  1995. jmp @@end_laz
  1996. @@not_lplayer:
  1997. cmp bl,123
  1998. je @@lrobot
  1999. cmp bl,124
  2000. jne @@not_lrobot
  2001. @@lrobot:
  2002. ; Send robot to lazer label
  2003. les di,[ds:level_param]
  2004. mov bx,ax
  2005. mov al,[es:di+bx]
  2006. xor ah,ah
  2007. call send_robot_def,ax,[WORD] 8
  2008. jmp @@end_laz
  2009. @@not_lrobot:
  2010. flipflag bh,bh
  2011. add bl,bl ; For flags offset
  2012. mov bx,[ds:flags+bx] ; Get flags
  2013. testflag bx,A_UNDER
  2014. jz @@end_laz ; If not BK, quit loop
  2015. ; Dirs=cx/dx
  2016. mov ax,[_ax_pd] ; Loads AH with length
  2017. flipflag al,al ; length in 8 4 2 1 of AH
  2018. xchg al,ah
  2019. shl al,3 ; length in 64 32 16 8 of AL
  2020. mov bx,[_ax_pd] ; Get dir
  2021. cmp bl,1 ; Check dir
  2022. ja @@direw ; horiz
  2023. setflag al,1 ; vert
  2024. @@direw:
  2025. mov bh,[BYTE color] ; Color in bh
  2026. mov bl,59 ; Load id
  2027. call id_place_asm,cx,dx,bx,ax
  2028. jmp @@laz_loop ; Loop and do it again!
  2029. @@end_laz:
  2030. ; All done!
  2031. pop es
  2032. popa
  2033. ret
  2034. endp _shoot_lazer
  2035. proc _shoot_lazer_c far
  2036. arg x:word,y:word,dir:word,len:word,color:word
  2037. mov cx,[dir]
  2038. mov dx,[len]
  2039. mov ch,dl
  2040. call _shoot_lazer,[x],[y],cx,[color]
  2041. ret
  2042. endp _shoot_lazer_c
  2043. ;
  2044. ; Try to transport in dir DIR of xy _XY. Places id ID/COLOR/PARAM. Only pushes
  2045. ; if CAN_PUSH > 0. Returns 1 for not possible, 0 for did/is possible. Does
  2046. ; not affect id at xy _XY-DIR. Note, _XY is the location of the TRANSPORTER.
  2047. ;
  2048. ; RECURSIZE
  2049. ;
  2050. proc _transport far ; ID=0 means just tell whether it is possible
  2051. arg _x:word,_y:word,dir:word,id:word,param:word,color:word,can_push:word
  2052. ; Check for deep recursion
  2053. cmp sp,1500 ; SP < 1500 ?
  2054. jae @@okey ; No
  2055. mov ax,1
  2056. ret ; Yep, return negative
  2057. @@okey:
  2058. push bx cx dx di si es
  2059. mov cx,[_x] ; Load xy
  2060. mov dx,[_y]
  2061. mov ax,[dir] ; Load dir,
  2062. xor ah,ah ; clear top,
  2063. mov si,A_PUSHNS ; set SI to flag for testing
  2064. cmp al,2 ; Check for NS or EW
  2065. jb @@NS
  2066. mov si,A_PUSHEW ; Load EW flag
  2067. @@NS:
  2068. mov bx,ax ; Dir into bl
  2069. _xy2array2 ; Create offset
  2070. xchg bx,ax ; Move into bx, dir into al
  2071. les di,[ds:level_param] ; Load location of params
  2072. mov ah,[es:di+bx] ; Get param of transport
  2073. ; Check for proper dir/all
  2074. maskflag ah,7 ; Use dir bits only
  2075. cmp ah,4 ; Any dir?
  2076. je @@dir_okey
  2077. cmp ah,al ; Same dir?
  2078. jne @@neg ; NOPE!
  2079. @@dir_okey:
  2080. xor ah,ah
  2081. call _arraydir2 ; Get loc after transporter (x/y)
  2082. cmp cx,0ffffh ; Out of bounds?
  2083. je @@neg
  2084. cmp dx,0ffffh
  2085. je @@neg
  2086. _xy2array2 ; Create offset
  2087. mov bx,ax ; Move into bx
  2088. les di,[ds:level_id] ; Load location of ids
  2089. mov al,[es:di+bx] ; Get id after transporter
  2090. cmp al,34 ; Goop- special case
  2091. je @@loop_part_1
  2092. ;
  2093. ; Finally, get flags of id after transporter
  2094. ;
  2095. mov bx,ax
  2096. add bl,bl ; Double id
  2097. flipflag bh,bh ; Clear upper of offset
  2098. mov di,OFFSET flags ; Load flags location
  2099. mov bx,[ds:di+bx] ; Get flags after transporter
  2100. ; DX is loc of x/y of dest. trans.
  2101. testflag bx,A_UNDER ; Under?
  2102. jnz @@checks_ok ; Yeppo.
  2103. testflag bx,si ; Pushable?
  2104. jnz @@check_push
  2105. cmp al,49 ; Transporter (so SPEC_PUSH doesn't get)
  2106. je @@loop_part_1b
  2107. testflag bx,A_SPEC_PUSH ; Special pushable?
  2108. jnz @@check_push
  2109. ; Continue searching
  2110. jmp @@loop_part_1 ; Loop to get next id
  2111. @@check_push:
  2112. ; sensor w/player?
  2113. cmp al,122
  2114. jne @@cpt2
  2115. cmp [id],127
  2116. je @@checks_ok
  2117. @@cpt2:
  2118. ; Are we ALLOWED to push?
  2119. cmp [can_push],0
  2120. je @@loop_part_1 ; Aren't allowed to push. (?)
  2121. ; Pushable- Check if truly.
  2122. ; Actually push so we don't have to later.
  2123. push cx dx
  2124. mov ax,[dir]
  2125. flip_dir ax
  2126. call _arraydir2
  2127. call _push,cx,dx,[dir],[id] ; Is it possible?
  2128. pop dx cx
  2129. cmp ax,0
  2130. je @@checks_ok ; Ok
  2131. jmp @@loop_part_1b ; Not Ok
  2132. @@loop_part_1:
  2133. ;
  2134. ; Loop, searching for a proper dest.
  2135. ;
  2136. ; Get next id in sequence (CX/DX hold curr pos)
  2137. mov ax,[dir]
  2138. call _arraydir2 ; Get next loc
  2139. cmp cx,0ffffh ; Out of bounds?
  2140. je @@neg
  2141. cmp dx,0ffffh
  2142. je @@neg
  2143. @@loop_part_1b:
  2144. _xy2array2 ; Create offset
  2145. mov bx,ax ; Move into bx
  2146. les di,[ds:level_id] ; Load location of ids
  2147. mov al,[es:di+bx] ; Get next ID
  2148. ; AL holds ID
  2149. cmp al,49 ; Transporter?
  2150. jne @@loop_part_1 ; Nope, continue!
  2151. ; Check dir- get param
  2152. les di,[ds:level_param] ; Load param loc
  2153. mov al,[es:di+bx] ; get param
  2154. maskflag al,7 ; Use dir bits only
  2155. cmp al,4 ; Any dir?
  2156. je @@found_tr_dir_ok
  2157. ; Load ah with OPPOSITE dir for cmp
  2158. mov bx,[dir]
  2159. flip_dir bl ; Flip the dir
  2160. cmp al,bl ; Opp dir?
  2161. jne @@loop_part_1 ; nope, cont.
  2162. @@found_tr_dir_ok:
  2163. ; Dir okay, check other side of it!
  2164. mov ax,[dir]
  2165. call _arraydir2 ; Get loc after transporter (x/y)
  2166. cmp cx,0ffffh ; Out of bounds?
  2167. je @@neg
  2168. cmp dx,0ffffh
  2169. je @@neg
  2170. _xy2array2 ; Create offset
  2171. mov bx,ax ; Move into bx
  2172. les di,[ds:level_id] ; Load location of ids
  2173. mov bl,[es:di+bx] ; Get id after transporter
  2174. cmp bl,34 ; Goop- special
  2175. je @@loop_part_1
  2176. ;
  2177. ; Finally, get flags of id after transporter
  2178. ;
  2179. push bx ; save id
  2180. add bl,bl ; Double id
  2181. flipflag bh,bh ; Clear upper of offset
  2182. mov di,OFFSET flags ; Load flags location
  2183. mov ax,[ds:di+bx] ; Get flags after transporter
  2184. pop bx ; restore id
  2185. ;
  2186. ; Check for UNDER or PUSHABLE.
  2187. ;
  2188. testflag ax,A_UNDER ; Under?
  2189. jnz @@checks_ok ; Yeppo. OK!
  2190. testflag ax,si ; Pushable?
  2191. jnz @@test_push ; Must test.
  2192. cmp bl,49
  2193. je @@loop_part_1b
  2194. testflag ax,A_SPEC_PUSH ; Pushable?
  2195. jnz @@test_push ; Must test.
  2196. jmp @@loop_part_1b ; loop
  2197. ;
  2198. ; Check if can push after transporter.
  2199. ;
  2200. @@test_push:
  2201. ; Sensor?
  2202. cmp bl,122
  2203. jne @@tpt2
  2204. cmp [id],127
  2205. je @@checks_ok
  2206. @@tpt2:
  2207. ; Are we ALLOWED to push?
  2208. cmp [can_push],0
  2209. je @@loop_part_1b ; Aren't allowed to push. (?)
  2210. ; Pushable- Check if truly.
  2211. push cx dx
  2212. mov ax,[dir]
  2213. flip_dir ax
  2214. call _arraydir2
  2215. call _push,cx,dx,[dir],[id] ; Is it possible?
  2216. pop dx cx
  2217. cmp ax,0
  2218. je @@checks_ok ; Ok
  2219. jmp @@loop_part_1 ; Not Ok, loop to 1st (THIS isn't a trans, so
  2220. ; even though this was never read within the
  2221. ; loop, we update the loc AGAIN to skip
  2222. ; checking this id for being a transporter.
  2223. ; whew! <g> )
  2224. @@checks_ok:
  2225. cmp [id],0 ; Just checking?
  2226. je @@pos ; Yeppo.
  2227. sfxp 27
  2228. ; CX/DX holds x y of dest., and any pushing has been done.
  2229. mov al,[BYTE id] ; Get id
  2230. mov si,[param] ; Get param
  2231. mov ah,[BYTE color] ; Get color
  2232. call id_place_asm,cx,dx,ax,si ; PLACE IT
  2233. ; Return.
  2234. @@pos:
  2235. pop es si di dx cx bx
  2236. xor ax,ax
  2237. ret
  2238. @@neg:
  2239. pop es si di dx cx bx
  2240. mov ax,1
  2241. ret
  2242. endp _transport
  2243. ;
  2244. ; Push DIR of _XY. Doesn't affect actaul id at _XY. Returns 1 for not
  2245. ; possible, 0 for did/is possible.
  2246. ;
  2247. ; RECURSIZE
  2248. ;
  2249. proc _push far ; checking=1 means just tell whether possible.
  2250. arg _x:word,_y:word,dir:word,checking:word
  2251. local @@moving_id:byte,@@moving_color:byte,@@moving_param:byte,@@offset:word,@@pushsensor:byte
  2252. ; Check for deep recursion
  2253. cmp sp,1500 ; SP < 1500 ?
  2254. jae @@okey ; No
  2255. mov ax,1
  2256. ret ; Yep, return negative
  2257. @@okey:
  2258. mov [@@pushsensor],0FFh
  2259. push bx cx dx di si es
  2260. mov cx,[_x] ; Load xy
  2261. mov dx,[_y]
  2262. mov ax,[dir] ; Load dir,
  2263. mov si,A_PUSHNS ; set SI to flag for testing
  2264. cmp al,2 ; Check for NS or EW
  2265. jb @@NS
  2266. mov si,A_PUSHEW ; Load EW flag
  2267. @@NS:
  2268. @@loop_1:
  2269. mov [@@moving_id],ah ; Keep track of ID for sensor check w/player
  2270. ;
  2271. ; Loop- Read IDs in dir, cont. for PUSH or SPEC_PUSH, end pos. for UNDER,
  2272. ; end neg. for EDGE or anything else.
  2273. ; CX/DX=dirs AL=dir SI=flag (pushns or pushew)
  2274. call _arraydir2 ; Get next location
  2275. cmp cx,0ffffh ; Check for edges
  2276. je @@neg
  2277. cmp dx,0ffffh
  2278. je @@neg
  2279. ;
  2280. ; Now get ID
  2281. ;
  2282. _xy2array2 ; Create offset
  2283. mov bx,ax ; Move into bx
  2284. les di,[ds:level_id] ; Load location of ids
  2285. mov ah,[es:di+bx] ; Get id
  2286. ;
  2287. ; Finally, get flags
  2288. ;
  2289. mov bl,ah ; Put into offset
  2290. add bl,bl ; Double id
  2291. xor bh,bh ; Clear upper of offset
  2292. mov di,OFFSET flags ; Load flags location
  2293. mov bx,[ds:di+bx] ; Get flag
  2294. mov al,[BYTE PTR dir]
  2295. ; BX=flag AH=id AL=dir SI=bit to test for push CX/DX=x/y
  2296. ; Test for UNDER
  2297. testflag bx,A_UNDER
  2298. jz @@not_under ; Not under
  2299. ; Under- Lava or water?
  2300. cmp ah,26 ; Lava?
  2301. je @@neg ; Yep!
  2302. cmp ah,34 ; Goop?
  2303. je @@neg ; Negative
  2304. cmp al,20 ; Below water?
  2305. jb @@pos ; Yep! POSITIVE
  2306. cmp ah,24 ; Above water?
  2307. ja @@pos ; Yep! POSITIVE
  2308. jmp @@neg ; NEGATIVE
  2309. @@not_under:
  2310. ; Test for pushable
  2311. testflag bx,si
  2312. jz @@not_push ; Jeez, not pushable either!
  2313. ; Pushable- continue loop
  2314. jmp @@loop_1
  2315. @@not_push:
  2316. ; Test for special-when-pushed
  2317. testflag bx,A_SPEC_PUSH
  2318. jz @@neg ; Well, guess we CAN'T push!
  2319. ; Is it a transport or a robot?
  2320. cmp ah,49 ; Transport?
  2321. je @@ptrans ; Yeah.
  2322. ; Robot or sensor- continue loop
  2323. cmp ah,122
  2324. je @@sensor
  2325. jmp @@loop_1
  2326. @@sensor:
  2327. ; Was LAST ID a player?
  2328. cmp [@@moving_id],127
  2329. je @@pos
  2330. jmp @@loop_1 ; If not, treat as a pushable
  2331. @@ptrans:
  2332. xor ah,ah
  2333. call _transport,cx,dx,ax,0,0,0,1 ; Call transport, on a test-w/push only
  2334. or ax,ax ; Negative?
  2335. jnz @@neg ; yep.
  2336. jmp @@pos ; Nope!
  2337. @@pos:
  2338. ; We CAN move- but are we "just checking" ?
  2339. cmp [checking],1 ; ???
  2340. je @@pos3 ; Yeah.
  2341. @@actual:
  2342. ;
  2343. ; Now actually PUSH the crap!
  2344. ;
  2345. mov cx,[_x] ; Load xy
  2346. mov dx,[_y]
  2347. mov ax,[dir] ; Load dir,
  2348. xor ah,ah ; clear top.
  2349. mov [@@moving_id],0FFh ; clear moving_id.
  2350. @@loop_2:
  2351. ;
  2352. ; Move in dir, swapping ids, etc.
  2353. ; CX/DX=x/y AL=dir or ?? SI=flag to test for push
  2354. ;
  2355. mov ax,[dir]
  2356. call _arraydir2 ; Get next location
  2357. _xy2array2 ; Create offset
  2358. mov bx,ax ; Move into bx
  2359. les di,[ds:level_id] ; Load location of ids
  2360. mov ax,[dir]
  2361. mov ah,[es:di+bx] ; Get id
  2362. mov [@@offset],bx ; Save offset
  2363. ;
  2364. ; Finally, get flags
  2365. ;
  2366. mov bl,ah ; Put into offset
  2367. add bl,bl ; Double id
  2368. xor bh,bh ; Clear upper of offset
  2369. mov di,OFFSET flags ; Load flags location
  2370. mov bx,[ds:di+bx] ; Get flag
  2371. ; BX=flag AH=id AL=dir CX/DX=x/y SI=flag
  2372. ; Test for UNDER
  2373. testflag bx,A_UNDER
  2374. jz @@not_under2 ; Not under
  2375. ; Prepare arguments to "place" moving id.
  2376. @@likeunder:
  2377. mov al,[@@moving_id]
  2378. mov ah,[@@moving_color] ; AX=id/color
  2379. mov bl,[@@moving_param]
  2380. xor bh,bh ; BX=param
  2381. call id_place_asm,cx,dx,ax,bx
  2382. cmp al,127 ; Player?
  2383. jne @@pos2
  2384. ; Yep. Sensor prev.?
  2385. mov ax,[dir]
  2386. flip_dir ax
  2387. call _arraydir2 ; Get OLD location
  2388. _xy2array2 ; Create offset
  2389. mov bx,ax ; Move into bx
  2390. les di,[ds:level_under_id] ; Load location of ids
  2391. cmp [BYTE PTR es:di+bx],122 ; Get id
  2392. jne @@pos2 ; Not a sensor back there
  2393. mov al,[under_player_id]
  2394. mov [BYTE PTR es:di+bx],al
  2395. les di,[ds:level_under_color]
  2396. mov al,[under_player_color]
  2397. xchg al,[es:di+bx]
  2398. les di,[ds:level_under_param]
  2399. mov ah,[under_player_param]
  2400. xchg ah,[es:di+bx]
  2401. mov [@@pushsensor],ah
  2402. mov [under_player_id],0
  2403. mov [under_player_color],7
  2404. mov [under_player_param],0
  2405. mov bx,[@@offset]
  2406. mov [es:di+bx],ah
  2407. les di,[ds:level_under_color]
  2408. mov [es:di+bx],al
  2409. les di,[ds:level_under_id]
  2410. mov [BYTE PTR es:di+bx],122 ; All moved!
  2411. jmp @@pos2
  2412. @@not_under2:
  2413. ; Test for pushable
  2414. testflag bx,si
  2415. jz @@not_push2 ; Jeez, not pushable either!
  2416. @@push_it:
  2417. mov bx,[@@offset] ; get array offset
  2418. cmp [@@moving_id],0ffh ; Already got a moving id?
  2419. je @@load_m_i ; Load moving id cause none currently
  2420. ; Swap w/moving id
  2421. ; AH=id AL=dir CX/DX=x/y SI=flag BX=offs
  2422. push cx
  2423. les di,[level_id]
  2424. mov al,[@@moving_id]
  2425. mov cl,al ; Save in case player is moving there
  2426. xchg [es:di+bx],al
  2427. mov [@@moving_id],al
  2428. les di,[level_color]
  2429. mov ah,[@@moving_color]
  2430. xchg [es:di+bx],ah
  2431. mov [@@moving_color],ah
  2432. les di,[level_param]
  2433. mov ah,[@@moving_param]
  2434. xchg [es:di+bx],ah
  2435. mov [@@moving_param],ah
  2436. ; Check (al=id, ah=param) for sending robot
  2437. ; to PUSHED label
  2438. cmp cl,127 ; Did we JUST move the player??
  2439. pop cx
  2440. je @@pl_m_sensor
  2441. cmp al,122
  2442. je @@pushed_a_sensor
  2443. cmp al,123
  2444. jne @@loop_2
  2445. ; push
  2446. pusha
  2447. mov al,ah
  2448. xor ah,ah
  2449. call send_robot_def,ax,[WORD] 3
  2450. popa
  2451. ; Done, loop
  2452. jmp @@loop_2
  2453. @@pushed_a_sensor:
  2454. pusha ; A sensor NOT near the player was pushed.
  2455. mov al,ah
  2456. xor ah,ah
  2457. call push_sensor,ax
  2458. popa
  2459. jmp @@loop_2
  2460. @@pl_m_sensor: ; Get sensor from prev. and move it,
  2461. ; if present
  2462. push ax cx dx
  2463. mov ax,[dir]
  2464. flip_dir ax
  2465. call _arraydir2 ; Get OLD location
  2466. _xy2array2 ; Create offset
  2467. mov bx,ax ; Move into bx
  2468. les di,[ds:level_under_id] ; Load location of ids
  2469. cmp [BYTE PTR es:di+bx],122 ; Get id
  2470. je @@plms2
  2471. pop dx cx ax
  2472. jmp @@loop_2 ; Not a sensor back there
  2473. @@plms2:
  2474. mov al,[under_player_id]
  2475. mov [es:di+bx],al
  2476. les di,[ds:level_under_color]
  2477. mov al,[under_player_color]
  2478. xchg al,[es:di+bx]
  2479. les di,[ds:level_under_param]
  2480. mov ah,[under_player_param]
  2481. xchg ah,[es:di+bx]
  2482. mov [@@pushsensor],ah
  2483. mov [under_player_id],0
  2484. mov [under_player_color],7
  2485. mov [under_player_param],0
  2486. mov bx,[@@offset]
  2487. mov [es:di+bx],ah
  2488. les di,[ds:level_under_color]
  2489. mov [es:di+bx],al
  2490. les di,[ds:level_under_id]
  2491. mov [BYTE PTR es:di+bx],122 ; All moved!
  2492. pop dx cx ax
  2493. jmp @@loop_2
  2494. @@load_m_i:
  2495. mov [@@moving_id],ah
  2496. les di,[level_param]
  2497. mov al,[es:di+bx]
  2498. mov [@@moving_param],al
  2499. les di,[level_color]
  2500. mov al,[es:di+bx]
  2501. mov [@@moving_color],al
  2502. cmp ah,127 ; DON'T remove top if player/sensor combo
  2503. jne @@lmi2
  2504. les di,[level_under_id]
  2505. cmp [BYTE PTR es:di+bx],122
  2506. je @@loop_2
  2507. @@lmi2:
  2508. call id_remove_top,cx,dx ; Remove the id
  2509. ; Done, loop
  2510. cmp ah,122
  2511. jne @@loop_2
  2512. ; Pushed a sensor...
  2513. mov ah,[@@moving_param]
  2514. jmp @@pushed_a_sensor
  2515. @@not_push2:
  2516. ; MUST be spec_push.
  2517. cmp ah,49 ; Transport?
  2518. je @@ptrans2 ; Yeah.
  2519. cmp ah,122 ; Sensor?
  2520. je @@psens2
  2521. ; Robot- like push
  2522. jmp @@push_it
  2523. @@psens2:
  2524. cmp [@@moving_id],127 ; Player?
  2525. jne @@push_it ; Push the sensor
  2526. ; Put player ON it
  2527. pusha
  2528. mov bx,[@@offset] ; get array offset
  2529. les di,[level_param]
  2530. mov al,[es:di+bx]
  2531. xor ah,ah
  2532. call step_sensor,ax ; Send sensor's robot to SENSORON
  2533. popa
  2534. jmp @@likeunder
  2535. @@ptrans2:
  2536. ; Prepare arguments to "transport" moving id.
  2537. xor ah,ah ; AX=dir
  2538. mov di,cx ; DI=x
  2539. mov si,dx ; SI=y
  2540. mov bl,[@@moving_id]
  2541. xor bh,bh ; BX=id
  2542. mov cl,[@@moving_color] ; CX=color
  2543. xor ch,ch
  2544. mov dl,[@@moving_param]
  2545. xor dh,dh ; DX=param
  2546. call _transport,di,si,ax,bx,dx,cx,1 ; Call transport!
  2547. @@pos2:
  2548. sfxp 26
  2549. ; Did we push a sensor?
  2550. cmp [@@pushsensor],0ffh
  2551. je @@pos3
  2552. mov al,[@@pushsensor]
  2553. xor ah,ah
  2554. call push_sensor,ax ; Yep! Notify it.
  2555. @@pos3:
  2556. xor ax,ax
  2557. jmp @@eeee
  2558. @@neg:
  2559. mov ax,1
  2560. @@eeee:
  2561. pop es si di dx cx bx
  2562. ret
  2563. endp _push
  2564. proc _shoot_c far
  2565. arg _x:word,_y:word,dir:word,typ:word
  2566. call _shoot,[_x],[_y],[dir],[typ]
  2567. ret
  2568. endp _shoot_c
  2569. ;
  2570. ; Shoot DIR of _X/_Y. Works w/ricochets, ricochet panels, robots, etc.
  2571. ; Type is SHOT_PLAYER, SHOT_NEUTRAL, or SHOT_ENEMY.
  2572. ;
  2573. ; RECURSIZE
  2574. ;
  2575. proc _shoot near
  2576. arg _x:word,_y:word,dir:word,typ:word
  2577. ; Check for deep recursion
  2578. cmp sp,1500 ; SP < 1500 ?
  2579. jae @@okey ; No
  2580. ret ; Yep, return
  2581. @@okey:
  2582. pusha
  2583. push es
  2584. ; If enemy_hurt_enemy and typ==enemy, typ==neutral.
  2585. cmp [typ],ENEMY_BULLET
  2586. jne @@typ_ok
  2587. cmp [ds:enemy_hurt_enemy],1
  2588. jne @@typ_ok
  2589. mov [typ],NEUTRAL_BULLET
  2590. @@typ_ok:
  2591. mov cx,[_x]
  2592. mov dx,[_y]
  2593. mov ax,[dir]
  2594. call _arraydir2 ; Get loc in dir
  2595. cmp cx,0ffffh ; Check for offscreen
  2596. je @@done
  2597. cmp dx,0ffffh
  2598. je @@done
  2599. _xy2array2
  2600. mov bx,ax ; Offset in bx
  2601. les di,[ds:level_id]
  2602. mov al,[es:di+bx] ; Load bl with id [dir] of [_xy]
  2603. ; First give 3 points for shooting anything from 80-95 except 83,85,92,93
  2604. cmp [typ],PLAYER_BULLET
  2605. jne @@no_pts
  2606. cmp al,80
  2607. jb @@no_pts
  2608. cmp al,95
  2609. ja @@no_pts
  2610. cmp al,83
  2611. je @@no_pts
  2612. cmp al,85
  2613. je @@no_pts
  2614. cmp al,92
  2615. je @@no_pts
  2616. cmp al,93
  2617. je @@no_pts
  2618. ; Give 3 points
  2619. add [WORD LOW score],3
  2620. adc [WORD HIGH score],0
  2621. jnc @@no_pts
  2622. ; Overflow
  2623. mov [WORD LOW score],255
  2624. mov [WORD HIGH score],255
  2625. @@no_pts:
  2626. mov si,bx ; Save offset
  2627. mov bl,al
  2628. xor bh,bh ; bx=id
  2629. add bl,bl ; bx=id*2
  2630. mov bx,[ds:flags+bx] ; ax=flags of id
  2631. testflag bx,A_UNDER ; Is it an under?
  2632. jnz @@move ; Yep.
  2633. testflag bx,A_SHOOTABLE ; Is it shootable?
  2634. jz @@notshootable ; Nope.
  2635. ; Yep. Remove THAT id then @@erase.
  2636. @@shootable:
  2637. ; Check for enemy bullet if not a "breakable"
  2638. cmp al,61
  2639. je @@ok_to_shoot
  2640. cmp al,28
  2641. je @@ok_to_shoot
  2642. cmp al,29
  2643. je @@ok_to_shoot
  2644. cmp al,6
  2645. je @@ok_to_shoot
  2646. cmp al,7
  2647. je @@ok_to_shoot
  2648. cmp [typ],ENEMY_BULLET
  2649. je @@done
  2650. @@ok_to_shoot:
  2651. call id_remove_top,cx,dx ; Remove that id
  2652. sfxp 29
  2653. jmp @@done
  2654. @@notshootable:
  2655. testflag bx,A_SPEC_SHOT ; Special when shot?
  2656. jz @@done ; No, die!
  2657. ; Yep- but what is it? (cl=id)
  2658. cmp al,72
  2659. je @@panel
  2660. cmp al,73
  2661. je @@ricochet
  2662. cmp al,74
  2663. je @@mine
  2664. cmp al,127
  2665. je @@player
  2666. cmp al,124
  2667. je @@robot
  2668. cmp al,123
  2669. je @@robot
  2670. cmp al,81
  2671. je @@eye
  2672. cmp al,83
  2673. je @@slime
  2674. cmp al,84
  2675. je @@runner
  2676. cmp al,85
  2677. je @@ghost
  2678. cmp al,86
  2679. je @@dragon
  2680. cmp al,87
  2681. je @@fish
  2682. cmp al,89
  2683. je @@fish ; Spider's HP works in the same way
  2684. cmp al,94
  2685. je @@fish ; Bear's HP works same
  2686. @@ricochet:
  2687. sfxp 31
  2688. mov cx,[_x]
  2689. mov dx,[_y]
  2690. mov ax,[dir]
  2691. call _arraydir2 ; Get loc in dir
  2692. flip_dir al
  2693. call _shoot,cx,dx,ax,NEUTRAL_BULLET
  2694. jmp @@done
  2695. @@panel:
  2696. sfxp 31
  2697. mov cx,[_x]
  2698. mov dx,[_y]
  2699. mov ax,[dir]
  2700. call _arraydir2 ; Get loc in dir
  2701. mov bx,si
  2702. les di,[ds:level_param]
  2703. mov bl,[es:di+bx] ; Get panel's orientation 1 is /
  2704. cmp bl,1
  2705. je @@p2 ; Other orient
  2706. ; \ so 0->3 1->2 2->1 3->0
  2707. xor ax,3
  2708. jmp @@pdone
  2709. @@p2:
  2710. ; / so 0->2 1->3 2->0 3->1
  2711. xor ax,2
  2712. @@pdone:
  2713. call _shoot,cx,dx,ax,NEUTRAL_BULLET
  2714. jmp @@done
  2715. @@eye:
  2716. cmp [typ],ENEMY_BULLET
  2717. je @@done ; Can't be shot by enemy bullets!
  2718. ; Get offset
  2719. mov bx,si ; in bx
  2720. les di,[ds:level_id]
  2721. mov [BYTE PTR es:di+bx],38 ; Expl. ID
  2722. les di,[ds:level_param]
  2723. maskflag [BYTE PTR es:di+bx],8+16+32
  2724. shl [BYTE PTR es:di+bx],1
  2725. sfxp 36
  2726. jmp @@done
  2727. @@mine:
  2728. ; Get offset
  2729. mov bx,si ; in bx
  2730. les di,[ds:level_id]
  2731. mov [BYTE PTR es:di+bx],38 ; Expl. ID
  2732. les di,[ds:level_param]
  2733. maskflag [BYTE PTR es:di+bx],240 ; Get rid of "count" and "anim"
  2734. sfxp 36
  2735. jmp @@done
  2736. @@player:
  2737. cmp [typ],PLAYER_BULLET
  2738. je @@done ; Can't be shot by player bullets!
  2739. hurt_player_id 61
  2740. call send_robot_def,ax,[WORD] 7
  2741. jmp @@done
  2742. @@slime:
  2743. cmp [typ],ENEMY_BULLET
  2744. je @@done ; Can't be shot by enemy bullets!
  2745. ; Get offset
  2746. mov bx,si ; in bx
  2747. les di,[ds:level_param]
  2748. mov al,[es:di+bx]
  2749. ; al = param
  2750. testflag al,128
  2751. jnz @@done ; Invinco
  2752. jmp @@shootable
  2753. @@runner:
  2754. cmp [typ],ENEMY_BULLET
  2755. je @@done ; Can't be shot by enemy bullets!
  2756. ; Get offset
  2757. mov bx,si ; in bx
  2758. les di,[ds:level_param]
  2759. mov al,[es:di+bx]
  2760. ; Cl = param
  2761. testflag al,64+128
  2762. jz @@shootable ; HP = 0, so die
  2763. sub al,64
  2764. mov [es:di+bx],al
  2765. sfxp 45
  2766. jmp @@done
  2767. @@ghost:
  2768. cmp [typ],ENEMY_BULLET
  2769. je @@done ; Can't be shot by enemy bullets!
  2770. ; Get offset
  2771. mov bx,si ; in bx
  2772. les di,[ds:level_param]
  2773. mov al,[es:di+bx]
  2774. ; Cl = param
  2775. testflag al,8
  2776. jnz @@done ; Invinco
  2777. jmp @@shootable
  2778. @@dragon:
  2779. cmp [typ],ENEMY_BULLET
  2780. je @@done ; Can't be shot by enemy bullets!
  2781. ; Get offset
  2782. mov bx,si ; in bx
  2783. les di,[ds:level_param]
  2784. mov al,[es:di+bx]
  2785. ; Cl = param
  2786. testflag al,128+64+32
  2787. jz @@shootable ; HP gone
  2788. sub al,32 ; HP dec
  2789. mov [es:di+bx],al
  2790. sfxp 45
  2791. jmp @@done
  2792. @@fish:
  2793. cmp [typ],ENEMY_BULLET
  2794. je @@done ; Can't be shot by enemy bullets!
  2795. ; Get offset
  2796. mov bx,si ; in bx
  2797. les di,[ds:level_param]
  2798. mov al,[es:di+bx]
  2799. ; Cl = param
  2800. testflag al,128
  2801. jz @@shootable ; HP gone
  2802. xor al,128 ; HP dec
  2803. mov [es:di+bx],al
  2804. sfxp 45
  2805. jmp @@done
  2806. @@robot:
  2807. mov bx,si
  2808. les di,[ds:level_param]
  2809. mov bl,[es:di+bx] ; Get robot's id
  2810. ; Send typ of message, then done
  2811. mov cx,[typ]
  2812. add cl,4
  2813. xor bh,bh
  2814. push bx
  2815. call send_robot_def,bx,cx
  2816. pop bx
  2817. ; Now set robot's last_shot_dir variable
  2818. les di,[ds:robots]
  2819. mov ax,ROBOT_SIZE
  2820. mul bx
  2821. mov bx,ax
  2822. add bx,30 ; Reference last_shot_dir variable
  2823. mov ax,[dir]
  2824. flip_dir ax ; We need which side of ROBOT was shot
  2825. inc ax
  2826. mov [es:di+bx],al
  2827. jmp @@done
  2828. @@move:
  2829. mov ax,[typ]
  2830. mov si,ax ; si=bullet type
  2831. mov cx,[_x]
  2832. mov dx,[_y]
  2833. mov ax,[dir]
  2834. call _arraydir2 ; Get loc in dir
  2835. ; BX=X/Y
  2836. mov ax,[typ] ; AX=typ, shifted
  2837. sal al,2 ; left twice.
  2838. add ax,[dir] ; AX+=dir (AX:=param)
  2839. mov bh,[ds:bullet_color+si] ; dh=color
  2840. mov bl,61 ; dl=id
  2841. call id_place_asm,cx,dx,bx,ax
  2842. @@done:
  2843. pop es
  2844. popa
  2845. ret
  2846. endp _shoot
  2847. ;
  2848. ; Shoot FIRE DIR of _X/_Y.
  2849. ;
  2850. proc _shoot_fire near
  2851. arg _x:word,_y:word,dir:word
  2852. push es
  2853. pusha
  2854. mov cx,[_x]
  2855. mov dx,[_y]
  2856. mov ax,[dir]
  2857. call _arraydir2 ; Get loc in dir
  2858. cmp cx,0ffffh ; Check for offscreen
  2859. je @@done
  2860. cmp dx,0ffffh
  2861. je @@done
  2862. _xy2array2
  2863. mov bx,ax ; Offset in bx
  2864. les di,[ds:level_id]
  2865. mov si,bx ; Save offset
  2866. mov bl,[es:di+bx] ; Load bl with id [dir] of [_x/_y]
  2867. xor bh,bh ; bx=id
  2868. add bl,bl ; bx=id*2
  2869. mov ax,[ds:flags+bx] ; ax=flags of id
  2870. shr bl,1
  2871. testflag ax,A_UNDER ; Is it an under?
  2872. jnz @@move ; Yep.
  2873. cmp bl,127
  2874. je @@player
  2875. cmp bl,123
  2876. je @@robot
  2877. cmp bl,124
  2878. jne @@done
  2879. @@robot:
  2880. ; Robot!
  2881. mov bx,si
  2882. les di,[ds:level_param]
  2883. mov bl,[es:di+bx]
  2884. xor bh,bh
  2885. call send_robot_def,bx,[WORD] 9
  2886. jmp @@done
  2887. @@player:
  2888. ; Player!
  2889. hurt_player_id 78
  2890. jmp @@done
  2891. @@move:
  2892. mov cx,[_x]
  2893. mov dx,[_y]
  2894. mov ax,[dir]
  2895. call _arraydir2 ; Get loc in dir
  2896. ; cx/dx=x/Y
  2897. add al,al ; put dir in bits 2,4 (AX:=Param)
  2898. call id_place_asm,cx,dx,78,ax
  2899. @@done:
  2900. popa
  2901. pop es
  2902. ret
  2903. endp _shoot_fire
  2904. proc _shoot_fire_c far
  2905. arg x:word,y:word,dir:word
  2906. call _shoot_fire,[x],[y],[dir]
  2907. ret
  2908. endp _shoot_fire_c
  2909. ;
  2910. ; Shoot SEEKER DIR of _XY.
  2911. ;
  2912. proc _shoot_seeker near
  2913. arg _x:word,_y:word,dir:word
  2914. push es
  2915. pusha
  2916. mov cx,[_x]
  2917. mov dx,[_y]
  2918. mov ax,[dir]
  2919. call _arraydir2 ; Get loc in dir
  2920. cmp cx,0ffffh ; Check for offscreen
  2921. je @@done
  2922. cmp dx,0ffffh
  2923. je @@done
  2924. _xy2array2
  2925. mov bx,ax ; Offset in bx
  2926. les di,[ds:level_id]
  2927. mov si,bx ; Save offset
  2928. mov bl,[es:di+bx] ; Load cl with id [dir] of [_xy]
  2929. xor bh,bh ; bx=id
  2930. add bl,bl ; bx=id*2
  2931. mov ax,[ds:flags+bx] ; ax=flags of id
  2932. add bl,bl
  2933. testflag ax,A_UNDER ; Is it an under?
  2934. jnz @@move ; Yep.
  2935. cmp bl,127
  2936. jne @@done
  2937. ; Player!
  2938. hurt_player_id 79
  2939. jmp @@done
  2940. @@move:
  2941. mov cx,[_x]
  2942. mov dx,[_y]
  2943. mov ax,[dir]
  2944. call _arraydir2 ; Get loc in dir
  2945. ; BX=X/Y
  2946. call id_place_asm,cx,dx,79,127
  2947. @@done:
  2948. popa
  2949. pop es
  2950. ret
  2951. endp _shoot_seeker
  2952. proc _shoot_seeker_c far
  2953. arg x:word,y:word,dir:word
  2954. call _shoot_seeker,[x],[y],[dir]
  2955. ret
  2956. endp _shoot_seeker_c
  2957. ;
  2958. ; Shoot MISSILE DIR of _X/_Y.
  2959. ;
  2960. proc _shoot_missile near
  2961. arg _x:word,_y:word,dir:word
  2962. push es
  2963. pusha
  2964. mov cx,[_x]
  2965. mov dx,[_y]
  2966. mov ax,[dir]
  2967. call _arraydir2 ; Get loc in dir
  2968. cmp cx,0ffffh ; Check for offscreen
  2969. je @@done
  2970. cmp dx,0ffffh
  2971. je @@done
  2972. _xy2array2
  2973. mov bx,ax ; Offset in bx
  2974. les di,[ds:level_id]
  2975. mov si,bx ; Save offset
  2976. mov bl,[es:di+bx] ; Load cl with id [dir] of [_xy]
  2977. xor bh,bh ; bx=id
  2978. sal bl,1 ; bx=id*2
  2979. mov ax,[ds:flags+bx] ; ax=flags of id
  2980. shr bl,1
  2981. testflag ax,A_UNDER ; Is it an under?
  2982. jnz @@move ; Yep.
  2983. cmp bl,127
  2984. jne @@done
  2985. ; Player!
  2986. hurt_player_id 62
  2987. jmp @@done
  2988. @@move:
  2989. mov cx,[_x]
  2990. mov dx,[_y]
  2991. mov ax,[dir]
  2992. call _arraydir2 ; Get loc in dir
  2993. ; cx/dx=X/Y
  2994. mov ax,[dir] ; AX==dir (param)
  2995. ;mov [ds:323],0
  2996. ;mov bh,[ds:323] ; BX=color used to be missile_color
  2997. mov bh, [missile_color]
  2998. mov bl,62 ; id
  2999. call id_place_asm,cx,dx,bx,ax
  3000. @@done:
  3001. popa
  3002. pop es
  3003. ret
  3004. endp _shoot_missile
  3005. proc _shoot_missile_c far
  3006. arg x:word,y:word,dir:word
  3007. call _shoot_missile,[x],[y],[dir]
  3008. ret
  3009. endp _shoot_missile_c
  3010. ;
  3011. ; General move sub- move ID at _X/_Y in DIR according to FLAGS. Erase original.
  3012. ; Assumes DS=Near Seg
  3013. ;
  3014. proc _move far
  3015. arg _x:word,_y:word,dir:word,movflags:word
  3016. local @@temp:word
  3017. ; Flags:
  3018. ; 1-Can push
  3019. ; 2-Can transport
  3020. ; 4-Can lava walk
  3021. ; 8-Can fire walk
  3022. ; 16-Can water walk
  3023. ; 32-Must web ¿Together is:
  3024. ; 64-Must thick web Ù Must any web
  3025. ; 128-React to player BEFORE push
  3026. ; 256-Must water
  3027. ; 512-Must lava OR goop
  3028. ;1024-Can goop walk
  3029. ;2048-Shooting fire (IE send robot to label and return 1)
  3030. ; Returns:
  3031. ; 0-Moved
  3032. ; 1-Blocked
  3033. ; 2-Player (and didn't move)
  3034. ; 3-Edge
  3035. push es
  3036. push di si dx cx bx
  3037. mov cx,[_x]
  3038. mov dx,[_y]
  3039. mov ax,[dir] ; Load x/y & dir
  3040. call _arraydir2 ; Get new x/y
  3041. cmp cx,0ffffh ; Check for edge
  3042. je @@edge
  3043. cmp dx,0ffffh
  3044. je @@edge
  3045. _xy2array2 ; Get offset
  3046. mov bx,ax ; Load offset
  3047. mov si,bx ; "store" offset
  3048. les di,[ds:level_id] ; Get level id
  3049. mov bl,[es:di+bx]
  3050. add bl,bl ; Make an offset
  3051. xor bh,bh
  3052. mov ax,[ds:flags+bx] ; Get flags
  3053. ; AX=FLAGS BL=ID
  3054. shr bl,1
  3055. testflag [movflags],128
  3056. jz @@dont_test_player_yet
  3057. ; Test for player BEFORE push
  3058. cmp bl,127 ; Player
  3059. je @@player
  3060. @@dont_test_player_yet:
  3061. testflag ax,A_UNDER ; Under?
  3062. jz @@notunder ; no
  3063. testflag [movflags],96 ; Check web status
  3064. jz @@notmustweb ; Web not neccesary
  3065. ; Web neccesary
  3066. testflag [movflags],32
  3067. jnz @@regweb
  3068. jmp @@thickweb
  3069. ; Any web
  3070. @@anyweb:
  3071. cmp bl,18 ; Thin web
  3072. je @@move
  3073. @@thickweb:
  3074. cmp bl,19
  3075. je @@move
  3076. jmp @@dont
  3077. @@regweb:
  3078. testflag [movflags],64
  3079. jnz @@anyweb
  3080. cmp bl,18
  3081. je @@move
  3082. jmp @@dont
  3083. @@notmustweb:
  3084. ; Must HýO?
  3085. testflag [movflags],256
  3086. jz @@notmustwater
  3087. ; Must be 20-24
  3088. cmp bl,20
  3089. jb @@dont
  3090. cmp bl,24
  3091. ja @@dont
  3092. jmp @@move
  3093. @@notmustwater:
  3094. ; Must lava/goop?
  3095. testflag [movflags],512
  3096. jz @@notmustlava
  3097. cmp bl,26
  3098. jne @@notlavaisitgoop
  3099. jmp @@move
  3100. @@notlavaisitgoop:
  3101. cmp bl,34
  3102. jne @@dont
  3103. jmp @@move
  3104. @@notmustlava:
  3105. ; Under
  3106. cmp bl,26 ; Lava
  3107. jne @@notlava
  3108. testflag [movflags],4 ; Can we lavawalk?
  3109. jz @@dont
  3110. jmp @@move
  3111. @@notlava:
  3112. cmp bl,63 ; Fire
  3113. jne @@notfire
  3114. testflag [movflags],8 ; Can we firewalk?
  3115. jz @@dont
  3116. jmp @@move
  3117. @@notfire:
  3118. cmp bl,34 ; Goop
  3119. jne @@notgoop
  3120. testflag [movflags],1024 ; Can we goopwalk?
  3121. jz @@dont
  3122. jmp @@move
  3123. @@notgoop:
  3124. cmp bl,20
  3125. jb @@move
  3126. cmp bl,24
  3127. ja @@move
  3128. ; Water
  3129. testflag [movflags],16 ; Can we waterwalk?
  3130. jz @@dont
  3131. jmp @@move
  3132. @@notunder:
  3133. ; Spit fire code
  3134. testflag [movflags],2048
  3135. jz @@notspitty
  3136. cmp bl,123
  3137. je @@sprob
  3138. cmp bl,124
  3139. jne @@notspitty
  3140. @@sprob:
  3141. ; Spit fire has hit a robot
  3142. mov bx,si
  3143. les di,[ds:level_param] ; Get robot id
  3144. mov al,[es:di+bx]
  3145. xor ah,ah
  3146. call send_robot_def,ax,[WORD] 9 ; Send to SPITFIRE
  3147. jmp @@dont ; and don't move any more
  3148. @@notspitty:
  3149. ; Check for PUSH/TRANS
  3150. ; BX=FLAGS AL=ID
  3151. cmp bl,49 ; Transporter
  3152. je @@trytrans
  3153. testflag ax,A_PUSHNS
  3154. jnz @@trypush
  3155. testflag ax,A_PUSHEW
  3156. jnz @@trypush
  3157. testflag ax,A_SPEC_PUSH
  3158. jnz @@trypush
  3159. @@dont:
  3160. mov ax,1
  3161. jmp @@ret
  3162. @@player:
  3163. mov ax,2
  3164. jmp @@ret
  3165. @@edge:
  3166. mov ax,3
  3167. jmp @@ret
  3168. @@trytrans:
  3169. testflag [movflags],2 ; CAN we trans?
  3170. jz @@dont
  3171. ; Prepare arguments
  3172. mov cx,[_x]
  3173. mov dx,[_y]
  3174. _xy2array2
  3175. mov bx,ax ; BX=offset
  3176. les di,[ds:level_id]
  3177. mov al,[es:di+bx]
  3178. xor ah,ah ; AX=id
  3179. les di,[ds:level_color]
  3180. mov cl,[es:di+bx]
  3181. xor ch,ch ; CX=color
  3182. les di,[ds:level_param]
  3183. mov dl,[es:di+bx]
  3184. xor dh,dh ; DX=param
  3185. mov si,ax ; SI=id
  3186. mov di,cx ; DI=color
  3187. xor bx,bx ; BX=can_push
  3188. mov [@@temp],dx ; temp=param
  3189. testflag [movflags],1 ; Can we push?
  3190. jz @@trans_no_push
  3191. flipflag bx,1 ; can push
  3192. @@trans_no_push:
  3193. ; SI=id DI=color DX=param CX=can_push
  3194. mov cx,[_x]
  3195. mov dx,[_y]
  3196. mov ax,[dir]
  3197. call _arraydir2 ; CX/DX=_xy AX=dir
  3198. call _transport,cx,dx,ax,si,[@@temp],di,bx
  3199. or ax,ax ; Make it?
  3200. jz @@erase ; Yeah.
  3201. jmp @@dont ; Nope.
  3202. @@trypush:
  3203. testflag [movflags],1 ; Can we push?
  3204. jz @@dont
  3205. mov cx,[_x] ; Prepare arguments
  3206. mov dx,[_y]
  3207. mov ax,[dir] ; Not just checking
  3208. call _push,cx,dx,ax,0
  3209. or ax,ax ; Made it?
  3210. jnz @@dont ; No dont move
  3211. ; Okay, move
  3212. @@move:
  3213. mov cx,[_x]
  3214. mov dx,[_y]
  3215. _xy2array2
  3216. mov bx,ax
  3217. les di,[ds:level_id]
  3218. mov al,[es:di+bx]
  3219. les di,[ds:level_color]
  3220. mov ah,[es:di+bx]
  3221. mov si,ax
  3222. les di,[ds:level_param]
  3223. mov al,[es:di+bx]
  3224. xor ah,ah
  3225. mov di,ax
  3226. ; cX=param
  3227. mov cx,[_x]
  3228. mov dx,[_y]
  3229. call id_remove_top,cx,dx
  3230. mov cx,[_x]
  3231. mov dx,[_y]
  3232. mov ax,[dir]
  3233. call _arraydir2 ; Get dest. loc
  3234. call id_place_asm,cx,dx,si,di
  3235. jmp @@era2
  3236. @@erase:
  3237. mov cx,[_x]
  3238. mov dx,[_y]
  3239. call id_remove_top,cx,dx
  3240. @@era2:
  3241. xor ax,ax
  3242. @@ret:
  3243. pop bx cx dx si di
  3244. pop es
  3245. ret
  3246. endp _move
  3247. proc parsedir far
  3248. arg old_dir:word,x:word,y:word,flow_dir:word,bln:word,bls:word,ble:word,blw:word
  3249. mov bx,[old_dir]
  3250. and bx,15 ; base dir
  3251. mov cx,[x]
  3252. mov dx,[y]
  3253. ; ax for dest
  3254. cmp bx,0
  3255. je @@use_bx
  3256. cmp bx,11
  3257. je @@use_bx
  3258. cmp bx,12
  3259. je @@use_bx
  3260. cmp bx,13
  3261. je @@flow
  3262. cmp bx,14
  3263. je @@use_bx
  3264. ja @@randb
  3265. cmp bx,5
  3266. jb @@bx_base
  3267. je @@randns
  3268. cmp bx,7
  3269. jb @@randew
  3270. je @@randne
  3271. cmp bx,9
  3272. je @@seek
  3273. jb @@randnb
  3274. ; randany
  3275. call random_num
  3276. mov bx,ax
  3277. and bx,3
  3278. inc bx
  3279. jmp @@bx_base
  3280. @@randb:
  3281. @@randnb:
  3282. ; RANDNB- XOR bln thru blw with 1
  3283. cmp bx,15
  3284. je @@mustberandb
  3285. xor [bln],1
  3286. xor [bls],1
  3287. xor [ble],1
  3288. xor [blw],1
  3289. @@mustberandb:
  3290. ; First, figure # allowed (number dirs blocked)
  3291. mov ax,[bln]
  3292. add ax,[bls]
  3293. add ax,[ble]
  3294. add ax,[blw]
  3295. ; If 0, return NO_DIR
  3296. cmp ax,0
  3297. ja @@notnodir
  3298. mov bx,14
  3299. jmp @@use_bx
  3300. @@notnodir:
  3301. ; Random...
  3302. mov bx,ax
  3303. call random_num
  3304. ; Make rand. num 0-255
  3305. xor ah,ah
  3306. ; Get modulo
  3307. div bl
  3308. ; Remainder in ah
  3309. mov bl,ah
  3310. xor bh,bh
  3311. ; Increase if bln=0
  3312. ; Increase if bls=0 and > 0
  3313. ; Increase if ble=0 and > 1
  3314. cmp [bln],0
  3315. jne @@nott_n
  3316. inc bx
  3317. @@nott_n:
  3318. cmp [bls],0
  3319. jne @@nott_s
  3320. cmp bx,0
  3321. je @@nott_s
  3322. inc bx
  3323. @@nott_s:
  3324. cmp [ble],0
  3325. jne @@nott_e
  3326. cmp bx,1
  3327. jbe @@nott_e
  3328. inc bx
  3329. @@nott_e:
  3330. ; Finally, increase bx to range 1-4
  3331. inc bx
  3332. jmp @@bx_base
  3333. @@flow:
  3334. mov bx,[flow_dir]
  3335. jmp @@bx_base
  3336. @@randns:
  3337. call random_num
  3338. mov bx,ax
  3339. and bx,1
  3340. inc bx
  3341. jmp @@bx_base
  3342. @@randew:
  3343. call random_num
  3344. mov bx,ax
  3345. and bx,1
  3346. add bx,3
  3347. jmp @@bx_base
  3348. @@randne:
  3349. call random_num
  3350. mov bx,ax
  3351. and bx,2
  3352. inc bx
  3353. jmp @@bx_base
  3354. @@seek:
  3355. find_seek cx,dx,bx
  3356. inc bx
  3357. jmp @@bx_base
  3358. @@bx_base:
  3359. ; bx holds base dir (1-4)
  3360. mov ax,bx
  3361. mov bx,[old_dir]
  3362. ; check for modifiers
  3363. test bx,32
  3364. jz @@nocw
  3365. dec ax
  3366. ; turn cw
  3367. ; 0 > 2
  3368. ; 1 > 3
  3369. ; 2 > 1
  3370. ; 3 > 0
  3371. ; 0/1/2/3, flip 2
  3372. ; 2/3, flip 1
  3373. cmp al,2
  3374. jb @@cw3
  3375. xor al,1
  3376. @@cw3:
  3377. xor al,2
  3378. xor ah,ah
  3379. inc ax
  3380. @@nocw:
  3381. test bx,64
  3382. je @@noopp
  3383. dec ax
  3384. xor ax,1
  3385. inc ax
  3386. @@noopp:
  3387. test bx,16
  3388. je @@norandp
  3389. dec al
  3390. ; flip ns / ew
  3391. xor al,2
  3392. ; take random number whether to flip ne / sw
  3393. mov bx,ax
  3394. call random_num
  3395. test ax,1
  3396. je @@randp2
  3397. xor bx,1
  3398. @@randp2:
  3399. mov ax,bx
  3400. inc ax
  3401. jmp @@done
  3402. @@norandp:
  3403. test bx,128
  3404. je @@done
  3405. ; RandNot
  3406. mov bx,ax
  3407. call random_num ; Get # 0-2
  3408. xor ah,ah
  3409. mov cl,3
  3410. div cl ; AL % 3 -> AH (0-2)
  3411. inc ah ; (1-3)
  3412. cmp ah,bl ; If AH != BL, use, else use 4
  3413. jne @@use_ah
  3414. mov ax,4
  3415. jmp @@done
  3416. @@use_ah:
  3417. mov al,ah
  3418. xor ah,ah
  3419. jmp @@done
  3420. @@use_bx:
  3421. mov ax,bx
  3422. @@done:
  3423. ret
  3424. endp parsedir
  3425. proc sin far
  3426. arg theta:word
  3427. shl [theta], 1
  3428. fild [theta]
  3429. fldpi
  3430. fmulp st(1), st(0)
  3431. fidiv [c_divisions]
  3432. fsin
  3433. fimul [multiplier]
  3434. fistp [return_value]
  3435. mov ax, [return_value]
  3436. ret
  3437. endp sin
  3438. proc cos far
  3439. arg theta:word
  3440. shl [theta], 1
  3441. fild [theta]
  3442. fldpi
  3443. fmulp st(1), st(0)
  3444. fidiv [c_divisions]
  3445. fcos
  3446. fimul [multiplier]
  3447. fistp [return_value]
  3448. mov ax, [return_value]
  3449. ret
  3450. endp cos
  3451. proc tan far
  3452. arg theta:word
  3453. shl theta, 1
  3454. fild [theta]
  3455. fldpi
  3456. fmulp st(1), st(0)
  3457. fidiv [c_divisions]
  3458. fptan
  3459. fstp st(0)
  3460. fimul [multiplier]
  3461. fistp [return_value]
  3462. mov ax, [return_value]
  3463. ret
  3464. endp tan
  3465. proc atan far
  3466. arg val:word
  3467. fild [val]
  3468. fidiv [divider]
  3469. fld1
  3470. fpatan
  3471. fimul [c_divisions]
  3472. fld const_2pi
  3473. fdivp
  3474. fistp [return_value]
  3475. mov ax, [return_value]
  3476. ret
  3477. endp atan
  3478. proc asin far
  3479. arg val:word
  3480. fild [val]
  3481. fidiv [divider]
  3482. fld st(0) ; put a in st(1)
  3483. fmul st(0), st(0) ; square a
  3484. fld1 ; load 1
  3485. fsubrp ; 1 - a^2
  3486. fsqrt ; take sqrt
  3487. fpatan
  3488. fimul [c_divisions]
  3489. fld const_2pi
  3490. fdivp
  3491. fistp [return_value]
  3492. mov ax, [return_value]
  3493. ret
  3494. endp asin
  3495. proc acos far
  3496. arg val:word
  3497. fild [val]
  3498. fidiv [divider]
  3499. fld st(0) ; put a in st(1)
  3500. fmul st(0), st(0) ; squar a
  3501. fld1 ; load 1
  3502. fsubrp ; 1 - a^2
  3503. fsqrt ; take sqrt
  3504. fxch ; swap st(0) and st(1)
  3505. fpatan
  3506. fimul [c_divisions]
  3507. fld [const_2pi]
  3508. fdivp
  3509. fistp [return_value]
  3510. mov ax, [return_value]
  3511. ret
  3512. endp acos
  3513. ends
  3514. end