game2.asm 79 KB

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