runrobo2.cpp 150 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585
  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. //Part two of RUNROBOT.CPP
  22. #include "profile.h"
  23. #include "error.h"
  24. #include "ezboard.h"
  25. #include "saveload.h"
  26. #include <stdio.h>
  27. #include "palette.h"
  28. #include "egacode.h"
  29. #include "intake.h"
  30. #include "edit.h"
  31. #include "random.h"
  32. #include "beep.h"
  33. #include "getkey.h"
  34. #include "graphics.h"
  35. #include "arrowkey.h"
  36. #include "scrdisp.h"
  37. #include "window.h"
  38. #include "sfx.h"
  39. extern int topindex,backindex;
  40. #include "mod.h"
  41. #include "idarray.h"
  42. #include "runrobot.h"
  43. #include "struct.h"
  44. #include "const.h"
  45. #include "data.h"
  46. #include "string.h"
  47. #include "counter.h"
  48. #include "game.h"
  49. #include "game2.h"
  50. #include "roballoc.h"
  51. #include <stdlib.h>
  52. #define parsedir(a,b,c,d) parsedir(a,b,c,d,_bl[0],_bl[1],_bl[2],_bl[3])
  53. #pragma warn -sig
  54. // side-effects: mangles the input string
  55. // bleah; this is so unreadable; just a very quick dirty hack
  56. static void magic_load_mod(char far *filename) {
  57. int magic;
  58. magic = str_len(filename);
  59. if ( ( magic > 1 ) && ( filename[magic-1] == '*' ) ) {
  60. filename[magic-1] = '\000';
  61. load_mod(filename);
  62. load_mod("*");
  63. } else {
  64. load_mod(filename);
  65. }
  66. }
  67. //Run a single robot through a single cycle.
  68. //If id is negative, only run it if .status is 2
  69. void run_robot(int id,int x,int y) {
  70. enter_func("run_robot");
  71. if(id<0) if(robots[-id].status!=2) return;
  72. int t1,t2,t3,t4,t5,t6,t7,t8,t9,t0,t10,t11,fad=is_faded();//Temps
  73. int cmd;//Command to run
  74. int lines_run=0,last_label=-1;//For preventing infinite loops
  75. char gotoed;//Set to 1 if we shouldn't advance cmd since we went to a lbl
  76. int old_pos;//Old position to verify gotos DID something
  77. int _bl[4]={ 0,0,0,0 };//Whether blocked in a given direction (2=OUR bullet)
  78. unsigned char far *robot;
  79. unsigned char far *cmd_ptr;//Points to current command
  80. char done=0;//Set to 1 on a finishing command
  81. char update_blocked=0;//Set to 1 to update the _bl[4] array
  82. unsigned char temp[81];
  83. char first_cmd=1;//It is the first cmd.
  84. FILE *fp;
  85. //Reset global prefixes
  86. first_prefix=mid_prefix=last_prefix=0;
  87. if(id<0) {
  88. id=-id;
  89. robots[id].xpos=x;
  90. robots[id].ypos=y;
  91. robots[id].cycle_count=0;
  92. goto redone;
  93. }
  94. //Reset x/y
  95. robots[id].xpos=x;
  96. robots[id].ypos=y;
  97. //Update cycle count
  98. if((++robots[id].cycle_count)<(robots[id].robot_cycle)) {
  99. robots[id].status=1;
  100. exit_func();
  101. return;
  102. }
  103. robots[id].cycle_count=0;
  104. //Does program exist?
  105. if(robots[id].program_length<3) {
  106. exit_func();
  107. return;//(nope)
  108. }
  109. //Walk?
  110. if((robots[id].walk_dir>0)&&(robots[id].walk_dir<5)) {
  111. t2=_move(x,y,robots[id].walk_dir-1,1|2|8|16+4*robots[id].can_lavawalk);
  112. if(t2==3) {//Send to edge, if no response, then to thud.
  113. if(send_robot_id(id,"edge",1))
  114. send_robot_id(id,"thud",1);
  115. }
  116. else if(t2>0) send_robot_id(id,"thud",1);
  117. else {
  118. //Update x/y
  119. switch(robots[id].walk_dir) {
  120. case 1: y--; break;
  121. case 2: y++; break;
  122. case 3: x++; break;
  123. case 4: x--; break;
  124. }
  125. }
  126. }
  127. if(robots[id].cur_prog_line==0) {
  128. robots[id].status=1;
  129. goto breaker;//Inactive
  130. }
  131. redone:
  132. //Get program location
  133. prepare_robot_mem(id==NUM_ROBOTS);
  134. robot=&robot_mem[robots[id].program_location];
  135. //NOW quit if inactive (had to do walk first)
  136. if(robot[robots[id].cur_prog_line]==0) {
  137. robots[id].status=1;
  138. goto end_prog;
  139. }
  140. //Figure blocked vars (accurate until robot program ends OR a put
  141. //or change command is issued)
  142. if(id<NUM_ROBOTS) {
  143. for(t1=0;t1<4;t1++) {
  144. t4=x; t5=y;
  145. if(!move_dir(t4,t5,t1)) {
  146. //Not edge... blocked?
  147. if((flags[level_id[t4+t5*max_bxsiz]]&A_UNDER)!=A_UNDER) _bl[t1]=1;
  148. }
  149. else _bl[t1]=1;//Edge is considered blocked
  150. }
  151. }
  152. if(level_id[player_x+player_y*max_bxsiz]!=127) find_player();
  153. //Main robot loop
  154. do {
  155. gotoed=0;
  156. old_pos=robots[id].cur_prog_line;
  157. //Get ptr to command
  158. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  159. //Get command number
  160. cmd=cmd_ptr[0];
  161. //Act according to command
  162. t10 = 0;
  163. switch(cmd) {
  164. case 0://End
  165. if(first_cmd) robots[id].status=1;
  166. goto end_prog;
  167. case 1://Die
  168. case 80://Die item
  169. die:
  170. clear_robot(id);
  171. if(id<NUM_ROBOTS) {
  172. id_remove_top(x,y);
  173. if(cmd==80) {
  174. id_remove_top(player_x,player_y);
  175. player_x=x;
  176. player_y=y;
  177. id_place(x,y,127,0,0);
  178. }
  179. }
  180. exit_func();
  181. return;
  182. case 2://Wait
  183. t1=(unsigned char)parse_param(&cmd_ptr[1],id);
  184. if(t1==robots[id].pos_within_line) break;
  185. robots[id].pos_within_line++;
  186. if(first_cmd) robots[id].status=1;
  187. goto breaker;
  188. case 3://Cycle
  189. robots[id].robot_cycle=(unsigned char)parse_param(&cmd_ptr[1],id);
  190. done=1;
  191. break;
  192. case 4://Go dir num
  193. //get num
  194. t1=(unsigned char)parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  195. //Inc. pos. or break
  196. if(t1==robots[id].pos_within_line) break;
  197. robots[id].pos_within_line++;
  198. case 68://Go dir label
  199. if(id==NUM_ROBOTS) break;
  200. //Parse dir
  201. t1=parsedir(cmd_ptr[2],x,y,robots[id].walk_dir);
  202. t1--;
  203. if((t1<0)||(t1>3)) break;
  204. t2=_move(x,y,t1,1|2|8|16|4*robots[id].can_lavawalk);
  205. if((t2>0)&&(cmd==68)) {
  206. //blocked- send to label
  207. send_robot_id(id,tr_msg(&cmd_ptr[next_param(cmd_ptr,1)+1],id),1);
  208. gotoed=1;
  209. break;
  210. }
  211. move_dir(x,y,t1);
  212. if(cmd==68) {
  213. //not blocked- make sure only moves once!
  214. done=1;
  215. break;
  216. }
  217. goto breaker;
  218. case 5://Walk dir
  219. if(id==NUM_ROBOTS) break;
  220. t1=parsedir(cmd_ptr[2],x,y,robots[id].walk_dir);
  221. if((t1<1)||(t1>4)) {
  222. robots[id].walk_dir=0;
  223. break;
  224. }
  225. robots[id].walk_dir=t1;
  226. break;
  227. case 6://Become color thing param
  228. if(id==NUM_ROBOTS) goto die;
  229. t1=x+y*max_bxsiz;
  230. //Color-
  231. t2=level_color[t1];
  232. t3=fix_color(parse_param(&cmd_ptr[1],id),t2);
  233. level_color[t1]=t3;
  234. //Point to thing...
  235. t4=next_param(cmd_ptr,1);
  236. //Thing-
  237. level_id[t1]=t6=parse_param(&cmd_ptr[t4],id);
  238. //Param- Only change if not becoming a robot
  239. if((t6!=123)&&(t6!=124)) {
  240. level_param[t1]=(unsigned char)parse_param(&cmd_ptr[t4+3],id);
  241. clear_robot(id);
  242. //If became a scroll, sensor, or sign...
  243. if((t6==122)||(t6==125)||(t6==126)||(t6==127))
  244. id_remove_top(x,y);
  245. //Delete "under"? (if became another type of "under")
  246. if(flags[t6]&A_UNDER) {
  247. //Became an under, so delete under.
  248. level_under_param[t1]=level_under_id[t1]=0;
  249. level_under_color[t1]=7;
  250. }
  251. exit_func();
  252. return;
  253. }
  254. //Became a robot. Whoopi.
  255. break;
  256. case 7://Char
  257. robots[id].robot_char=(unsigned char)parse_param(&cmd_ptr[1],id);
  258. break;
  259. case 8://Color
  260. if(id==NUM_ROBOTS) break;
  261. level_color[x+y*max_bxsiz]=fix_color(parse_param(&cmd_ptr[1],id),
  262. level_color[x+y*max_bxsiz]);
  263. break;
  264. case 9://Gotoxy
  265. if(id==NUM_ROBOTS) break;
  266. done=1;
  267. t1=parse_param(&cmd_ptr[1],id);
  268. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  269. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  270. if((t1==x)&&(t2==y)) break;
  271. //delete at x y
  272. t3=level_id[t1+t2*max_bxsiz];
  273. t4=level_param[t1+t2*max_bxsiz];
  274. if(t3==122) clear_sensor(t4);
  275. if((t3==126)||(t3==125)) clear_scroll(t4);
  276. if((t3==123)||(t3==124)) {
  277. clear_robot(t4);
  278. robot=&robot_mem[robots[id].program_location];
  279. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  280. }
  281. if(t3==127) break;//Abort jump if player there
  282. //move
  283. id_place(t1,t2,level_id[x+y*max_bxsiz],level_color[x+y*max_bxsiz],id);
  284. //remove
  285. id_remove_top(x,y);
  286. break;
  287. case 10://set c #
  288. case 11://inc c #
  289. case 12://dec c #
  290. tr_msg(&cmd_ptr[2],id);
  291. if(str_len(ibuff)>=COUNTER_NAME_SIZE)
  292. ibuff[COUNTER_NAME_SIZE-1]=0;
  293. t1=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  294. if(cmd==10) set_counter(ibuff,t1,id);
  295. else if(cmd==11) inc_counter(ibuff,t1,id);
  296. else dec_counter(ibuff,t1,id);
  297. last_label=-1;//Allows looping "infinitely"
  298. break;
  299. case 16://if c?n l
  300. //Get first number
  301. t1=parse_param(&cmd_ptr[1],id);
  302. //Get second number
  303. t2=parse_param(&cmd_ptr[3+next_param(cmd_ptr,1)],id);
  304. //Comparison
  305. t4=0;//Not true
  306. switch(parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id)) {
  307. case 0:
  308. if(t1==t2) t4=1;
  309. break;
  310. case 1:
  311. if(t1<t2) t4=1;
  312. break;
  313. case 2:
  314. if(t1>t2) t4=1;
  315. break;
  316. case 3:
  317. if(t1>=t2) t4=1;
  318. break;
  319. case 4:
  320. if(t1<=t2) t4=1;
  321. break;
  322. case 5:
  323. if(t1!=t2) t4=1;
  324. break;
  325. }
  326. if(t4) {
  327. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,
  328. 3+next_param(cmd_ptr,1))],id),1);
  329. gotoed=1;
  330. }
  331. break;
  332. case 18://if condition label
  333. case 19://if not cond. label
  334. t1=parse_param(&cmd_ptr[1],id);
  335. t2=((unsigned int)t1)>>8;
  336. t1=((unsigned int)t1)&255;
  337. t2=parsedir(t2,x,y,robots[id].walk_dir);
  338. //t1=condition, t2=direction if any (already parsed)
  339. t3=0;//Set to 1 for true
  340. switch(t1) {
  341. case 0://Walking dir
  342. if(t2<5) {
  343. if(robots[id].walk_dir==t2) t3=1;
  344. break;
  345. }
  346. if(t2==14) {
  347. if(robots[id].walk_dir==0) t3=1;
  348. break;
  349. }
  350. //assumed anydir
  351. if(robots[id].walk_dir!=0) t3=1;
  352. break;
  353. case 1://swimming
  354. if(id==NUM_ROBOTS) break;
  355. t2=level_under_id[x+y*max_bxsiz];
  356. if((t2>19)&&(t2<25)) t3=1;
  357. break;
  358. case 2://firewalking
  359. if(id==NUM_ROBOTS) break;
  360. t2=level_under_id[x+y*max_bxsiz];
  361. if((t2==26)||(t2==63)) t3=1;
  362. break;
  363. case 3://touching dir
  364. if(id==NUM_ROBOTS) break;
  365. if((t2<5)&&(t2>0)) {
  366. //Is player in dir t2?
  367. t4=x; t5=y;
  368. if(move_dir(t4,t5,t2-1)) break;
  369. if((player_x==t4)&&(player_y==t5)) t3=1;
  370. break;
  371. }
  372. //either anydir or nodir
  373. //is player touching at all?
  374. for(t6=0;t6<4;t6++) {//try all dirs
  375. t4=x; t5=y;
  376. if(move_dir(t4,t5,t6)) continue;
  377. if((player_x==t4)&&(player_y==t5)) t3=1;
  378. }
  379. //t3=1 for anydir
  380. if((t2==14)||(t2==0)) //We want NODIR though, so
  381. t3^=1; //reverse t3.
  382. break;
  383. case 4://Blocked dir
  384. //If REL PLAYER or REL COUNTERS, use special code
  385. if(mid_prefix==2) {
  386. //Rel player
  387. for(t1=0;t1<4;t1++) {
  388. _bl[t1]=0;
  389. t4=player_x; t5=player_y;
  390. if(!move_dir(t4,t5,t1)) {
  391. //Not edge... blocked?
  392. if((flags[level_id[t4+t5*max_bxsiz]]&A_UNDER)!=A_UNDER) _bl[t1]=1;
  393. }
  394. else _bl[t1]=1;//Edge is considered blocked
  395. }
  396. if((t2<5)&&(t2>0)) {
  397. t3=_bl[t2-1];
  398. }
  399. else {
  400. //either anydir or nodir
  401. //is blocked any dir at all?
  402. t3=_bl[0]|_bl[1]|_bl[2]|_bl[3];
  403. //t3=1 for anydir
  404. if((t2==14)||(t2==0)) //We want NODIR though, so
  405. t3^=1; //reverse t3.
  406. }
  407. //Fix blocked arrays
  408. if(id<NUM_ROBOTS) {
  409. for(t1=0;t1<4;t1++) {
  410. _bl[t1]=0;
  411. t4=x; t5=y;
  412. if(!move_dir(t4,t5,t1)) {
  413. //Not edge... blocked?
  414. if((flags[level_id[t4+t5*max_bxsiz]]&A_UNDER)!=A_UNDER) _bl[t1]=1;
  415. }
  416. else _bl[t1]=1;//Edge is considered blocked
  417. }
  418. }
  419. }
  420. else if(mid_prefix==3) {
  421. //Rel counters
  422. t2=get_counter("THISX");
  423. t3=get_counter("THISY");
  424. for(t1=0;t1<4;t1++) {
  425. _bl[t1]=0;
  426. t4=t2; t5=t3;
  427. if(!move_dir(t4,t5,t1)) {
  428. //Not edge... blocked?
  429. if((flags[level_id[t4+t5*max_bxsiz]]&A_UNDER)!=A_UNDER) _bl[t1]=1;
  430. }
  431. else _bl[t1]=1;//Edge is considered blocked
  432. }
  433. if((t2<5)&&(t2>0)) {
  434. t3=_bl[t2-1];
  435. }
  436. else {
  437. //either anydir or nodir
  438. //is blocked any dir at all?
  439. t3=_bl[0]|_bl[1]|_bl[2]|_bl[3];
  440. //t3=1 for anydir
  441. if((t2==14)||(t2==0)) //We want NODIR though, so
  442. t3^=1; //reverse t3.
  443. }
  444. if(id<NUM_ROBOTS) {
  445. for(t1=0;t1<4;t1++) {
  446. _bl[t1]=0;
  447. t4=x; t5=y;
  448. if(!move_dir(t4,t5,t1)) {
  449. //Not edge... blocked?
  450. if((flags[level_id[t4+t5*max_bxsiz]]&A_UNDER)!=A_UNDER) _bl[t1]=1;
  451. }
  452. else _bl[t1]=1;//Edge is considered blocked
  453. }
  454. }
  455. }
  456. else {
  457. if(id==NUM_ROBOTS) break;
  458. //Same as player except with anything
  459. if((t2<5)&&(t2>0)) {
  460. t3=_bl[t2-1];
  461. break;
  462. }
  463. //either anydir or nodir
  464. //is blocked any dir at all?
  465. t3=_bl[0]|_bl[1]|_bl[2]|_bl[3];
  466. //t3=1 for anydir
  467. if((t2==14)||(t2==0)) //We want NODIR though, so
  468. t3^=1; //reverse t3.
  469. }
  470. break;
  471. case 5://Aligned
  472. if(id==NUM_ROBOTS) break;
  473. if((player_x==x)||(player_y==y)) t3=1;
  474. break;
  475. case 6://AlignedNS
  476. if(id==NUM_ROBOTS) break;
  477. if(player_x==x) t3=1;
  478. break;
  479. case 7://AlignedEW
  480. if(id==NUM_ROBOTS) break;
  481. if(player_y==y) t3=1;
  482. break;
  483. case 8://LASTSHOT dir (only 1-4 accepted)
  484. if(id==NUM_ROBOTS) break;
  485. if((t2<1)||(t2>4)) break;
  486. if(t2==robots[id].last_shot_dir) t3=1;
  487. break;
  488. case 9://LASTTOUCH dir (only 1-4 accepted)
  489. if(id==NUM_ROBOTS) break;
  490. t2=parsedir(t2,x,y,robots[id].walk_dir);
  491. if((t2<1)||(t2>4)) break;
  492. if(t2==robots[id].last_touch_dir) t3=1;
  493. break;
  494. case 10://RTpressed
  495. if(rt_pressed) t3=1;
  496. break;
  497. case 11://LTpressed
  498. if(lf_pressed) t3=1;
  499. break;
  500. case 12://UPpressed
  501. if(up_pressed) t3=1;
  502. break;
  503. case 13://dnpressed
  504. if(dn_pressed) t3=1;
  505. break;
  506. case 14://sppressed
  507. if(sp_pressed) t3=1;
  508. break;
  509. case 15://delpressed
  510. if(del_pressed) t3=1;
  511. break;
  512. case 16://musicon
  513. if(music_on) t3=1;
  514. break;
  515. case 17://soundon
  516. if(sfx_on) t3=1;
  517. break;
  518. }
  519. if(cmd==19) t3^=1;//Reverse truth if NOT is present
  520. if(t3) {//jump
  521. send_robot_id(id,tr_msg(&cmd_ptr[5],id),1);
  522. gotoed=1;
  523. }
  524. break;
  525. case 20://if any thing label
  526. case 21://if no thing label
  527. //Get foreg/backg allowed in t1/t2
  528. t1=parse_param(&cmd_ptr[1],id);//Color
  529. t3=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);//Thing
  530. t4=parse_param(&cmd_ptr[next_param(cmd_ptr,next_param(cmd_ptr,1))],id);//Param
  531. if(t1&256) {
  532. t1^=256;
  533. if(t1==32) t1=t2=16;
  534. else if(t1<16) t2=16;
  535. else {
  536. t2=t1-16;
  537. t1=16;
  538. }
  539. }
  540. else {
  541. t2=t1>>4;
  542. t1=t1&15;
  543. }
  544. t5=cmd-20;
  545. for(t7=0;t7<10000;t7++) {
  546. t6=level_id[t7];
  547. if(t6!=t3) continue;
  548. t6=level_color[t7];
  549. if(t1<16) {
  550. if((t6&15)!=t1) continue;
  551. }
  552. if(t2<16) {
  553. if((t6>>4)!=t2) continue;
  554. }
  555. if(t4<256) {
  556. t6=level_param[t7];
  557. if(t6!=t4) continue;
  558. }
  559. t5=21-cmd;
  560. break;
  561. }
  562. if(t5) {
  563. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,
  564. next_param(cmd_ptr,next_param(cmd_ptr,1)))],id),1);
  565. gotoed=1;
  566. }
  567. break;
  568. case 22://if thing dir
  569. case 23://if NOT thing dir
  570. t1=x; t2=y;
  571. t4=1;
  572. t3=next_param(cmd_ptr,next_param(cmd_ptr,next_param(cmd_ptr,t4)));
  573. t9=1+next_param(cmd_ptr,t3);
  574. t3=parse_param(&cmd_ptr[t3],id);
  575. goto if_thing_dir;
  576. case 24://if thing x y
  577. t4=1;
  578. t3=next_param(cmd_ptr,next_param(cmd_ptr,next_param(cmd_ptr,t4)));
  579. t9=1+next_param(cmd_ptr,next_param(cmd_ptr,t3));
  580. t1=parse_param(&cmd_ptr[t3],id);
  581. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,t3)],id);
  582. prefix_xy(t8,t8,t1,t2,t8,t8,x,y);
  583. t10 = 0;
  584. goto if_thing_at_xy;
  585. case 25://if at x y label
  586. if(id==NUM_ROBOTS) break;
  587. t1=parse_param(&cmd_ptr[1],id);
  588. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  589. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  590. if((t1!=x)||(t2!=y)) break;
  591. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,
  592. next_param(cmd_ptr,1))],id),1);
  593. gotoed=1;
  594. break;
  595. case 26://if dir of player is thing, "label"
  596. t1=player_x; t2=player_y;// X/Y
  597. t3=parse_param(&cmd_ptr[1],id);// Direction
  598. t4=next_param(cmd_ptr,1);// Location of thing
  599. // Byte of label string
  600. t9=1+next_param(cmd_ptr,next_param(cmd_ptr,next_param(cmd_ptr,t4)));
  601. if_thing_dir:
  602. t10 = 0;
  603. t3=parsedir(t3,x,y,robots[id].walk_dir);
  604. // if((t3==11)&&(cmd==26)) {
  605. if(t3==11) {
  606. t10=999; //set t10, used to set cmd
  607. goto if_thing_at_xy;
  608. }
  609. if((t3<1)||(t3>4)) goto if_thing_no;
  610. if(move_dir(t1,t2,t3-1)) goto if_thing_no;
  611. t10 = 0;
  612. if_thing_at_xy:
  613. //t3/t4 <- color (fg/bk)
  614. //t5 <- thing
  615. //t6 <- param
  616. t3=parse_param(&cmd_ptr[t4],id);
  617. t5=parse_param(&cmd_ptr[next_param(cmd_ptr,t4)],id);
  618. t6=parse_param(&cmd_ptr[next_param(cmd_ptr,
  619. next_param(cmd_ptr,t4))],id);
  620. if(t3&256) {
  621. t3^=256;
  622. if(t3<16) t4=16;
  623. else if(t3==32) t3=t4=16;
  624. else {
  625. t4=t3-16;
  626. t3=16;
  627. }
  628. }
  629. else {
  630. t4=t3>>4;
  631. t3=t3&15;
  632. }
  633. if(t10==999) goto under_player; //checks t10, used to check cmd
  634. t7=level_id[t1+t2*max_bxsiz];
  635. if(t7!=t5) goto if_thing_no;
  636. t7=level_color[t1+t2*max_bxsiz];
  637. if(t3<16)
  638. if((t7&15)!=t3) goto if_thing_no;
  639. if(t4<16)
  640. if((t7>>4)!=t4) goto if_thing_no;
  641. if(t6<256) {
  642. t7=level_param[t1+t2*max_bxsiz];
  643. if(t7!=t6) goto if_thing_no;
  644. }
  645. //Jump to label if not cmd 23
  646. if(cmd==23) break;
  647. send_robot_id(id,tr_msg(&cmd_ptr[t9],id),1);
  648. gotoed=1;
  649. break;
  650. if_thing_no:
  651. //Jump to label if cmd 23
  652. if(cmd==23) {
  653. send_robot_id(id,tr_msg(&cmd_ptr[t9],id),1);
  654. gotoed=1;
  655. }
  656. break;
  657. under_player:
  658. //If UNDER/BENEATH PLAYER thing ( and if thing under)
  659. t7=level_under_id[t1+t2*max_bxsiz];
  660. if(t7!=t5) goto if_thing_no; //for next few statements, did not used to go to if_thing_no
  661. t7=level_under_color[t1+t2*max_bxsiz];
  662. if(t3<16)
  663. if((t7&15)!=t3) goto if_thing_no;
  664. if(t4<16)
  665. if((t7>>4)!=t4) goto if_thing_no;
  666. if(t6<256) {
  667. t7=level_under_param[t1+t2*max_bxsiz];
  668. if(t7!=t6) goto if_thing_no;
  669. }
  670. //POSSIBLE FIX FOR UNDER BUGGY!
  671. if(cmd==23) break;
  672. send_robot_id(id,tr_msg(&cmd_ptr[t9],id),1);
  673. gotoed=1;
  674. break;
  675. case 27://double c
  676. tr_msg(&cmd_ptr[2],id);
  677. if(!str_cmp(ibuff,"SCORE")) score<<=1;
  678. else {
  679. t1=get_counter(ibuff,id);
  680. t1<<=1;
  681. set_counter(ibuff,t1,id);
  682. }
  683. last_label=-1;//Allows looping "infinitely"
  684. break;
  685. case 28://half c
  686. tr_msg(&cmd_ptr[2],id);
  687. if(!str_cmp(ibuff,"SCORE")) score>>=1;
  688. else {
  689. t1=get_counter(ibuff,id);
  690. t1>>=1;
  691. set_counter(ibuff,t1,id);
  692. }
  693. last_label=-1;//Allows looping "infinitely"
  694. break;
  695. case 29://Goto
  696. send_robot_id(id,tr_msg(&cmd_ptr[2],id),1);
  697. gotoed=1;
  698. break;
  699. case 30://Send robot label
  700. send_robot(tr_msg(&cmd_ptr[2],id,ibuff2),tr_msg(
  701. &cmd_ptr[next_param(cmd_ptr,1)+1],id));
  702. break;
  703. case 31://Explode
  704. if(id==NUM_ROBOTS) goto die;
  705. level_param[x+y*max_bxsiz]=((unsigned char)parse_param(&cmd_ptr[1],id)-1)*16;
  706. level_id[x+y*max_bxsiz]=38;
  707. clear_robot(id);
  708. exit_func();
  709. return;
  710. case 32://put thing dir
  711. if(id==NUM_ROBOTS) break;
  712. //t1=color (w/?) t2=thing t3=param
  713. t0=1;
  714. t1=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  715. t2=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  716. t3=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  717. //t4 x t5 y t6 dir
  718. lay_bomb_entry:
  719. t4=x; t5=y;
  720. t6=parsedir(parse_param(&cmd_ptr[t0],id),x,y,robots[id].walk_dir);
  721. put_to_dir:
  722. if((t6<1)||(t6>4)) break;
  723. if(move_dir(t4,t5,t6-1)) break;
  724. put_at_XY:
  725. if((t2>121)&&(t2<128)) break;
  726. duplicate_entry:
  727. t7=level_id[t4+t5*max_bxsiz];
  728. t8=level_param[t4+t5*max_bxsiz];
  729. if(t7==127) break;
  730. if((t7==123)||(t7==124)) {
  731. clear_robot(t8);
  732. robot=&robot_mem[robots[id].program_location];
  733. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  734. }
  735. if((t7==125)||(t7==126))
  736. clear_scroll(t8);
  737. if(t8==122)
  738. clear_sensor(t8);
  739. t1=fix_color(t1,level_color[t4+t5*max_bxsiz]);
  740. //Put thing
  741. id_place(t4,t5,t2,t1,t3);
  742. //Are we still "alive"?
  743. if(id!=GLOBAL_ROBOT) {
  744. t1=level_id[x+y*max_bxsiz];
  745. if((t1!=123)&&(t1!=124)) {
  746. exit_func();
  747. return;//Nope.
  748. }
  749. t1=level_param[x+y*max_bxsiz];
  750. if(t1!=id) {
  751. exit_func();
  752. return;//Nope.
  753. }
  754. }
  755. //Figure blocked vars
  756. update_blocked=1;
  757. break;
  758. case 33://Give # item
  759. t1=parse_param(&cmd_ptr[1],id);
  760. t2=cmd_ptr[next_param(cmd_ptr,1)+1];
  761. inc_counter(item_to_counter[t2],t1);
  762. last_label=-1;//Allows looping "infinitely"
  763. break;
  764. case 34://Take # item
  765. case 35://Take # item "label"
  766. t1=parse_param(&cmd_ptr[1],id);
  767. t2=cmd_ptr[next_param(cmd_ptr,1)+1];
  768. t4=0;
  769. if(t2!=3) {
  770. t3=get_counter(item_to_counter[t2]);
  771. if(t3<t1) t4=1;
  772. else dec_counter(item_to_counter[t2],t1);
  773. }
  774. else {
  775. if(score<t1) t4=1;
  776. else score-=t1;
  777. }
  778. if((t4)&(cmd==35)) {
  779. send_robot_id(id,tr_msg(&cmd_ptr[next_param(cmd_ptr,1)+4],
  780. id),1);
  781. gotoed=1;
  782. }
  783. last_label=-1;//Allows looping "infinitely"
  784. break;
  785. case 36://Endgame
  786. set_counter("LIVES",0);
  787. case 37://Endlife
  788. set_counter("HEALTH",0);
  789. break;
  790. case 38://Mod
  791. magic_load_mod(tr_msg(&cmd_ptr[2],id));
  792. volume_mod(volume);
  793. break;
  794. case 39://sam
  795. t1=parse_param(&cmd_ptr[1],id);//Freq
  796. t2=next_param(cmd_ptr,1)+1;//Loc of string
  797. play_sample(t1,tr_msg(&cmd_ptr[t2],id));
  798. break;
  799. case 40://Volume
  800. volume=volume_target=t1=(unsigned char)parse_param(&cmd_ptr[1],id);
  801. volume_mod(t1);
  802. break;
  803. case 41://End mod
  804. end_mod();
  805. break;
  806. case 42://End sam
  807. end_sample();
  808. break;
  809. case 43://Play notes
  810. play_str(&cmd_ptr[2]);
  811. break;
  812. case 44://End play
  813. clear_sfx_queue();
  814. break;
  815. case 45://wait play "str"
  816. case 46://wait play
  817. t1=topindex-backindex;
  818. if(t1<0) t1=topindex+(NOISEMAX-backindex);
  819. if(t1>10) goto breaker;
  820. if(cmd==45) play_str(&cmd_ptr[2]);
  821. break;
  822. //case 47:Blank line
  823. case 48://sfx num
  824. play_sfx(parse_param(&cmd_ptr[1],id));
  825. break;
  826. case 49://play sfx notes
  827. if(!is_playing()) play_str(&cmd_ptr[2]);
  828. break;
  829. case 50://open
  830. if(id==NUM_ROBOTS) break;
  831. t1=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  832. if((t1<1)||(t1>4)) break;
  833. t2=x; t3=y;
  834. if(move_dir(t2,t3,t1-1)) break;
  835. t4=level_id[t2+t3*max_bxsiz];
  836. if((t4!=41)&&(t4!=47)) break;
  837. //Become pushable for a split second
  838. t6=level_id[x+y*max_bxsiz];
  839. level_id[x+y*max_bxsiz]=123;
  840. grab_item(t2,t3,0);
  841. //Re-find robot
  842. if(level_id[x+y*max_bxsiz]!=123); {
  843. for(t1=0;t1<4;t1++) {
  844. t4=x; t5=y;
  845. if(!move_dir(t4,t5,t1)) {
  846. //Not edge... robot?
  847. if(level_id[t4+t5*max_bxsiz]==123) {
  848. if(level_param[t4+t5*max_bxsiz]==id) {
  849. x=t4;
  850. y=t5;
  851. break;
  852. }
  853. }
  854. }
  855. }
  856. }
  857. //Become old pushable status
  858. level_id[x+y*max_bxsiz]=t6;
  859. //Figure blocked vars
  860. update_blocked=1;
  861. break;
  862. case 51://Lockself
  863. case 52://Unlockself
  864. robots[id].is_locked=52-cmd;
  865. break;
  866. case 53://Send DIR "label"
  867. if(id==NUM_ROBOTS) break;
  868. t1=x; t2=y;
  869. t3=parse_param(&cmd_ptr[1],id);
  870. t4=1+next_param(cmd_ptr,1);
  871. send_dir:
  872. //t1/t2=x/y
  873. //t3=dir
  874. //t4=loc of label
  875. t3=parsedir(t3,x,y,robots[id].walk_dir);
  876. if((t3<1)||(t3>4)) break;
  877. if(move_dir(t1,t2,t3-1)) break;
  878. send_at_XY:
  879. t3=level_id[t1+t2*max_bxsiz];
  880. if((t3!=123)&&(t3!=124)) break;
  881. t3=level_param[t1+t2*max_bxsiz];
  882. send_robot_id(t3,tr_msg(&cmd_ptr[t4],id));
  883. //Use t4 instead of 2 'cuase send
  884. //x y "label" uses 3.
  885. break;
  886. case 54://Zap label num
  887. case 55://Restore label num
  888. tr_msg(&cmd_ptr[2],id);
  889. t1=(unsigned char)parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  890. for(t2=0;t2<t1;t2++) {
  891. if(cmd==54) {
  892. if(zap_label(robot,ibuff)==0) break;
  893. }
  894. else {
  895. if(restore_label(robot,ibuff)==0) break;
  896. }
  897. }
  898. break;
  899. case 56://Lockplayer
  900. player_ns_locked=player_ew_locked=player_attack_locked=1;
  901. break;
  902. case 57://unlockplayer
  903. player_ns_locked=player_ew_locked=player_attack_locked=0;
  904. break;
  905. case 58://lockplayer ns
  906. player_ns_locked=1;
  907. break;
  908. case 59://lockplayer ew
  909. player_ew_locked=1;
  910. break;
  911. case 60://lockplayer attack
  912. player_attack_locked=1;
  913. break;
  914. case 61://move player dir
  915. case 62://move pl dir "label"
  916. t1=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  917. if((t1<1)||(t1>4)) break;
  918. t2=player_x; t3=player_y; t4=curr_board;
  919. //Have to fix vars and move to next command NOW, in case player
  920. //is send to another screen!
  921. first_prefix=mid_prefix=last_prefix=0;
  922. robots[id].pos_within_line=0;
  923. robots[id].cur_prog_line+=robot[robots[id].cur_prog_line]+2;
  924. if(!robot[robots[id].cur_prog_line])
  925. robots[id].cur_prog_line=0;
  926. robots[id].cycle_count=0;
  927. robots[id].xpos=x;
  928. robots[id].ypos=y;
  929. //Move player
  930. t0=target_where;
  931. move_player(t1-1);
  932. if((player_x==t2)&&(player_y==t3)&&(curr_board==t4)&&(cmd==62)&&
  933. (target_where==t0)) {
  934. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  935. id),1);
  936. gotoed=1;
  937. goto breaker;
  938. }
  939. exit_func();
  940. return;
  941. case 63://Put player x y
  942. t1=parse_param(&cmd_ptr[1],id);
  943. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  944. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  945. put_player_XY:
  946. //Put at t1,t2
  947. done=1;
  948. if((player_x==t1)&&(player_y==t2)) break;
  949. id_remove_top(player_x,player_y);
  950. t3=level_id[t1+t2*max_bxsiz];
  951. t4=level_param[t1+t2*max_bxsiz];
  952. if((t3==123)||(t3==124)) {
  953. clear_robot(t4);
  954. robot=&robot_mem[robots[id].program_location];
  955. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  956. }
  957. if((t3==125)||(t3==126))
  958. clear_scroll(t4);
  959. if(t3==122) step_sensor(t4);
  960. id_place(t1,t2,127,0,0);
  961. player_x=t1;
  962. player_y=t2;
  963. //still alive?
  964. if((player_x==x)&&(player_y==y)) {
  965. exit_func();
  966. return;
  967. }
  968. break;
  969. case 66://if player x y
  970. t1=parse_param(&cmd_ptr[1],id);
  971. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  972. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  973. if((t1!=player_x)||(t2!=player_y)) break;
  974. send_robot_id(id,tr_msg(&cmd_ptr[next_param(cmd_ptr,
  975. next_param(cmd_ptr,1))+1],id),1);
  976. gotoed=1;
  977. break;
  978. case 67://put player dir
  979. if(id==NUM_ROBOTS) break;
  980. t1=x; t2=y;
  981. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  982. if((t3<1)||(t3>4)) break;
  983. if(move_dir(t1,t2,t3-1)) break;
  984. goto put_player_XY;
  985. case 69://rotate cw
  986. case 70://rotate ccw
  987. if(id==NUM_ROBOTS) break;
  988. rotate(x,y,cmd-69);
  989. //Figure blocked vars
  990. update_blocked=1;
  991. break;
  992. case 71://switch dir dir
  993. if(id==NUM_ROBOTS) break;
  994. t1=t4=x; t2=t5=y;
  995. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  996. if((t3<1)||(t3>4)) break;
  997. if(move_dir(t1,t2,t3-1)) break;
  998. t6=parsedir(parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id)
  999. ,x,y,robots[id].walk_dir);
  1000. if((t6<1)||(t6>4)) break;
  1001. if(move_dir(t4,t5,t6-1)) break;
  1002. //Switch t1,t2 with t4,t5
  1003. if((t1==t4)&&(t2==t5)) break;
  1004. t3=level_id[t1+t2*max_bxsiz];
  1005. t6=level_param[t1+t2*max_bxsiz];
  1006. t7=level_color[t1+t2*max_bxsiz];
  1007. level_id[t1+t2*max_bxsiz]=level_id[t4+t5*max_bxsiz];
  1008. level_param[t1+t2*max_bxsiz]=level_param[t4+t5*max_bxsiz];
  1009. level_color[t1+t2*max_bxsiz]=level_color[t4+t5*max_bxsiz];
  1010. level_id[t4+t5*max_bxsiz]=t3;
  1011. level_param[t4+t5*max_bxsiz]=t6;
  1012. level_color[t4+t5*max_bxsiz]=t7;
  1013. //Figure blocked vars
  1014. update_blocked=1;
  1015. break;
  1016. case 72://Shoot
  1017. if(id==NUM_ROBOTS) break;
  1018. t3=parsedir(cmd_ptr[2],x,y,robots[id].walk_dir);
  1019. if((t3<1)||(t3>4)) break;
  1020. if(_bl[--t3]&2) break;//No shooty a shot
  1021. _shoot_c(x,y,t3,robots[id].bullet_type);
  1022. //Figure blocked vars
  1023. if(!_bl[t3]) _bl[t3]=3;
  1024. break;
  1025. case 73://laybomb
  1026. t1=0;
  1027. goto lay_bomb;
  1028. case 74://laybomb high
  1029. t1=128;
  1030. lay_bomb:
  1031. if(id==NUM_ROBOTS) break;
  1032. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1033. if(t3==11) {
  1034. //underneath
  1035. level_under_id[x+y*max_bxsiz]=37;
  1036. level_under_param[x+y*max_bxsiz]=t1;
  1037. level_under_color[x+y*max_bxsiz]=8;
  1038. break;
  1039. }
  1040. if((t3<1)||(t3>4)) break;
  1041. //Simulate a put
  1042. t3=t1; t1=8; t2=37; t0=1;
  1043. goto lay_bomb_entry;
  1044. case 75://shoot missile
  1045. if(id==NUM_ROBOTS) break;
  1046. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1047. if((t3<1)||(t3>4)) break;
  1048. _shoot_missile_c(x,y,t3-1);
  1049. //Figure blocked vars
  1050. update_blocked=1;
  1051. break;
  1052. case 76://shoot seeker
  1053. if(id==NUM_ROBOTS) break;
  1054. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1055. if((t3<1)||(t3>4)) break;
  1056. _shoot_seeker_c(x,y,t3-1);
  1057. //Figure blocked vars
  1058. update_blocked=1;
  1059. break;
  1060. case 77://spit fire
  1061. if(id==NUM_ROBOTS) break;
  1062. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1063. if((t3<1)||(t3>4)) break;
  1064. _shoot_fire_c(x,y,t3-1);
  1065. //Figure blocked vars
  1066. update_blocked=1;
  1067. break;
  1068. case 78://lazer wall
  1069. if(id==NUM_ROBOTS) break;
  1070. t1=(unsigned char)parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1071. t3=parsedir(cmd_ptr[2],x,y,robots[id].walk_dir);
  1072. if((t3<1)||(t3>4)) break;
  1073. _shoot_lazer_c(x,y,t3-1,t1,level_color[x+y*max_bxsiz]);
  1074. //Figure blocked vars
  1075. update_blocked=1;
  1076. break;
  1077. case 79://put thing at x y
  1078. t0=1;
  1079. t1=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1080. t2=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1081. t3=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1082. t4=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1083. t5=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1084. prefix_xy(t9,t9,t4,t5,t9,t9,x,y);
  1085. goto put_at_XY;
  1086. case 81://Send x y "label"
  1087. t1=parse_param(&cmd_ptr[1],id);
  1088. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1089. t4=1+next_param(cmd_ptr,next_param(cmd_ptr,1));
  1090. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  1091. goto send_at_XY;
  1092. case 82://copyrobot ""
  1093. tr_msg(&cmd_ptr[2],id);
  1094. for(t1=0;t1<=NUM_ROBOTS;t1++)
  1095. if(str_cmp(robots[t1].robot_name,ibuff)==0) break;
  1096. if(t1>NUM_ROBOTS) break;
  1097. copy_robot_num:
  1098. if(t1==id) break;
  1099. //Finally- Copy!
  1100. copy_robot(id,t1);
  1101. if(robots[id].cur_prog_line>0)
  1102. robots[id].cur_prog_line=1;
  1103. robots[id].pos_within_line=0;
  1104. robot=&robot_mem[robots[id].program_location];
  1105. goto breaker;
  1106. case 83://copyrobot x y
  1107. t1=parse_param(&cmd_ptr[1],id);
  1108. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1109. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  1110. copy_robot_at_XY:
  1111. t3=level_id[t1+t2*max_bxsiz];
  1112. if((t3!=123)&&(t3!=124)) break;
  1113. t1=level_param[t1+t2*max_bxsiz];
  1114. goto copy_robot_num;
  1115. case 84://copyrobot dir
  1116. if(id==NUM_ROBOTS) break;
  1117. t1=x; t2=y;
  1118. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1119. if((t3<1)||(t3>4)) break;
  1120. if(move_dir(t1,t2,t3-1)) break;
  1121. goto copy_robot_at_XY;
  1122. case 85://dupe self dir
  1123. if(id==NUM_ROBOTS) break;
  1124. t4=x; t5=y;
  1125. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1126. if((t3<1)||(t3>4)) break;
  1127. if(move_dir(t4,t5,t3-1)) break;
  1128. goto dupe_at_XY;
  1129. case 86://dupe self xy
  1130. t4=parse_param(&cmd_ptr[1],id);
  1131. t5=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1132. prefix_xy(t3,t3,t4,t5,t3,t3,x,y);
  1133. dupe_at_XY:
  1134. //Make copy
  1135. t3=find_robot();
  1136. if(!t3) break;
  1137. if(copy_robot(t3,id)) {
  1138. robots[t3].used=0;
  1139. break;
  1140. }
  1141. robot=&robot_mem[robots[id].program_location];
  1142. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  1143. robots[t3].cur_prog_line=1;
  1144. robots[t3].pos_within_line=0;
  1145. if(id!=GLOBAL_ROBOT) {
  1146. t1=level_color[x+y*max_bxsiz];
  1147. t2=level_id[x+y*max_bxsiz];
  1148. }
  1149. else {
  1150. t1=7;
  1151. t2=124;
  1152. }
  1153. goto duplicate_entry;
  1154. case 87://bulletn
  1155. case 88://s
  1156. case 89://e
  1157. case 90://w
  1158. t1=cmd-87;
  1159. bullet_char[t1]=bullet_char[t1+4]=bullet_char[t1+8]=
  1160. parse_param(&cmd_ptr[1],id);
  1161. break;
  1162. case 91://givekey col
  1163. case 92://givekey col "l"
  1164. t1=15&parse_param(&cmd_ptr[1],id);//Color
  1165. if(give_key(t1))
  1166. if(cmd==92) {
  1167. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  1168. id),1);
  1169. gotoed=1;
  1170. }
  1171. break;
  1172. case 93://takekey col
  1173. case 94://takekey col "l"
  1174. t1=15&parse_param(&cmd_ptr[1],id);//Color
  1175. if(take_key(t1))
  1176. if(cmd==94) {
  1177. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  1178. id),1);
  1179. gotoed=1;
  1180. }
  1181. break;
  1182. case 95://inc c r
  1183. case 96://dec c r
  1184. case 97://set c r
  1185. tr_msg(&cmd_ptr[2],id);
  1186. if(str_len(ibuff)>=COUNTER_NAME_SIZE)
  1187. ibuff[COUNTER_NAME_SIZE-1]=0;
  1188. t1=next_param(cmd_ptr,1);
  1189. //t1 points to low range to set to
  1190. t2=parse_param(&cmd_ptr[t1],id);
  1191. t1=next_param(cmd_ptr,t1);
  1192. t3=parse_param(&cmd_ptr[t1],id);
  1193. //Get random number from t2 to t3
  1194. if(t2==t3) t4=t2;
  1195. else {
  1196. if(t3<t2) {
  1197. t4=t2;
  1198. t2=t3;
  1199. t3=t4;
  1200. }
  1201. t4=((random_num())%(t3-t2+1))+t2;
  1202. //t4 <- random num
  1203. }
  1204. if(cmd==97) set_counter(ibuff,t4,id);
  1205. else if(cmd==95) inc_counter(ibuff,t4,id);
  1206. else dec_counter(ibuff,t4,id);
  1207. last_label=-1;//Allows looping "infinitely"
  1208. break;
  1209. case 98://Trade givenum givetype takenum taketype poorlabel
  1210. t1=1;
  1211. t2=parse_param(&cmd_ptr[t1],id); t1=next_param(cmd_ptr,t1);
  1212. t3=parse_param(&cmd_ptr[t1],id); t1=next_param(cmd_ptr,t1);
  1213. t4=parse_param(&cmd_ptr[t1],id); t1=next_param(cmd_ptr,t1);
  1214. t5=parse_param(&cmd_ptr[t1],id); t1=next_param(cmd_ptr,t1);
  1215. t9=0;
  1216. if(t5!=3) {
  1217. t6=get_counter(item_to_counter[t5]);
  1218. if(t6<t4) t9=1;
  1219. else set_counter(item_to_counter[t5],t6-t4);
  1220. }
  1221. else {
  1222. if(score<t6) t9=1;
  1223. else score-=t4;
  1224. }
  1225. if(t9) {
  1226. send_robot_id(id,tr_msg(&cmd_ptr[1+t1],id),1);
  1227. gotoed=1;
  1228. }
  1229. else {
  1230. if(t3!=3) inc_counter(item_to_counter[t3],t2);
  1231. else score+=t2;
  1232. }
  1233. last_label=-1;//Allows looping "infinitely"
  1234. break;
  1235. case 99://Send DIR of player "label"
  1236. t1=player_x; t2=player_y;
  1237. t3=parse_param(&cmd_ptr[1],id);
  1238. t4=1+next_param(cmd_ptr,1);
  1239. goto send_dir;
  1240. case 100://put thing dir of player
  1241. t0=1;
  1242. t1=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1243. t2=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1244. t3=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  1245. t6=parsedir(parse_param(&cmd_ptr[t0],id),x,y,robots[id].walk_dir);
  1246. t4=player_x; t5=player_y;
  1247. if(t6==11) {
  1248. //Put BENEATH player
  1249. if((t2>121)&&(t2<128)) break;
  1250. t1=fix_color(t1,level_under_color[t4+t5*max_bxsiz]);
  1251. t7=level_under_id[t4+t5*max_bxsiz];
  1252. t8=level_under_param[t4+t5*max_bxsiz];
  1253. if(t7==122)
  1254. clear_sensor(t8);
  1255. //Put it now.
  1256. level_under_id[t4+t5*max_bxsiz]=t2;
  1257. level_under_color[t4+t5*max_bxsiz]=t1;
  1258. level_under_param[t4+t5*max_bxsiz]=t3;
  1259. break;
  1260. }
  1261. goto put_to_dir;
  1262. case 101:// /"dirs"
  1263. case 232://Persistent go [str]
  1264. if(id==NUM_ROBOTS) break;
  1265. //get next dir char, if none, next cmd
  1266. t1=cmd_ptr[++robots[id].pos_within_line+1];
  1267. //t1='n' 's' 'w' 'e' or 'i'
  1268. if(t1=='n') t1=0;
  1269. else if(t1=='N') t1=0;
  1270. else if(t1=='s') t1=1;
  1271. else if(t1=='S') t1=1;
  1272. else if(t1=='e') t1=2;
  1273. else if(t1=='E') t1=2;
  1274. else if(t1=='w') t1=3;
  1275. else if(t1=='W') t1=3;
  1276. else if(t1=='i') goto breaker;
  1277. else if(t1=='I') goto breaker;
  1278. else goto next_cmd;//invalid char means next cmd (including null)
  1279. //move in dir
  1280. if((_move(x,y,t1,1|2|8|16|4*robots[id].can_lavawalk))&&//4 lava
  1281. (cmd==232)) robots[id].pos_within_line--;//persistent...
  1282. move_dir(x,y,t1);
  1283. goto breaker;
  1284. case 102://Mesg
  1285. set_mesg(tr_msg(&cmd_ptr[2],id));
  1286. break;
  1287. case 103:
  1288. case 104:
  1289. case 105:
  1290. case 116:
  1291. case 117:
  1292. //Box messages!
  1293. robot_box_display(&cmd_ptr[-1],id,temp);
  1294. //Move to end of all box mesg cmds.
  1295. do {
  1296. robots[id].cur_prog_line+=robot[robots[id].cur_prog_line]+2;
  1297. reek:
  1298. //At next line- check type
  1299. if(!robot[robots[id].cur_prog_line]) goto end_prog;
  1300. t1=robot[robots[id].cur_prog_line+1];
  1301. if((t1!=47)&&(t1!=103)&&(t1!=104)&&(t1!=105)&&(t1!=106)&&(t1!=116)&&(t1!=117)) break;
  1302. } while(1);
  1303. //Labels
  1304. if(!temp[0]) goto breaker;
  1305. send_robot_id(id,temp,1);
  1306. gotoed=1;
  1307. goto breaker;
  1308. case 106://label
  1309. if(last_label==robots[id].cur_prog_line) //Passed here already?
  1310. goto breaker;//Yep.
  1311. last_label=robots[id].cur_prog_line;
  1312. break;
  1313. case 107://comment-do nothing!
  1314. //(unless first char is a @)
  1315. if(cmd_ptr[2]!='@') break;
  1316. //Rename robot
  1317. if(cmd_ptr[1]<3) {
  1318. robots[id].robot_name[0]=0;
  1319. break;
  1320. }
  1321. tr_msg(&cmd_ptr[3],id);
  1322. if(str_len(ibuff)>14) ibuff[14]=0;
  1323. str_cpy(robots[id].robot_name,ibuff);
  1324. break;
  1325. //case 108://zapped label-do nothing!
  1326. case 109://teleport
  1327. tr_msg(&cmd_ptr[2],id);
  1328. for(t1=0;t1<NUM_BOARDS;t1++) {
  1329. if(board_where[t1]==W_NOWHERE) continue;
  1330. if(str_cmp(&board_list[t1*25],ibuff)==0) break;
  1331. }
  1332. if(t1==NUM_BOARDS) break;
  1333. t3=t1;
  1334. t4=next_param(cmd_ptr,1);
  1335. t1=parse_param(&cmd_ptr[t4],id);
  1336. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,t4)],id);
  1337. //x/y=t1/t2 brd=t3
  1338. //Prefix the XY pair
  1339. t5=board_xsiz;
  1340. t6=board_ysiz;
  1341. board_xsiz=board_ysiz=400;
  1342. prefix_xy(t4,t4,t1,t2,t4,t4,x,y);
  1343. board_xsiz=t5;
  1344. board_ysiz=t6;
  1345. //Set vars
  1346. target_board=t3;
  1347. target_x=t1;
  1348. target_y=t2;
  1349. target_where=-1;
  1350. done=1;
  1351. break;
  1352. case 110://scrollview dir num
  1353. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1354. if((t3<1)||(t3>4)) break;
  1355. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1356. switch(t3) {
  1357. case 1:
  1358. scroll_y-=t2;
  1359. break;
  1360. case 2:
  1361. scroll_y+=t2;
  1362. break;
  1363. case 3:
  1364. scroll_x+=t2;
  1365. break;
  1366. case 4:
  1367. scroll_x-=t2;
  1368. break;
  1369. }
  1370. break;
  1371. case 111://input string
  1372. m_hide();
  1373. save_screen(current_pg_seg);
  1374. if(fad) {
  1375. clear_screen(1824,current_pg_seg);
  1376. insta_fadein();
  1377. }
  1378. draw_window_box(3,11,77,14,current_pg_seg,EC_DEBUG_BOX,
  1379. EC_DEBUG_BOX_DARK,EC_DEBUG_BOX_CORNER);
  1380. write_string(tr_msg(&cmd_ptr[2],id),5,12,EC_DEBUG_LABEL,
  1381. current_pg_seg);
  1382. m_show();
  1383. input_string[0]=0;
  1384. t1=curr_table;
  1385. switch_keyb_table(1);
  1386. intake(input_string,70,5,13,current_pg_seg,15,1,0);
  1387. if(fad) insta_fadeout();
  1388. switch_keyb_table(t1);
  1389. restore_screen(current_pg_seg);
  1390. input_size=str_len(input_string);
  1391. num_input=atoi(input_string);
  1392. break;
  1393. case 112://If string "" "l"
  1394. if(!str_cmp(tr_msg(&cmd_ptr[2],id),input_string)) {
  1395. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  1396. id),1);
  1397. gotoed=1;
  1398. }
  1399. break;
  1400. case 113://If string not "" "l"
  1401. if(str_cmp(tr_msg(&cmd_ptr[2],id),input_string)) {
  1402. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  1403. id),1);
  1404. gotoed=1;
  1405. }
  1406. break;
  1407. case 114://If string matches "" "l"
  1408. //compare
  1409. tr_msg(&cmd_ptr[2],id);
  1410. for(t1=0;t1<str_len(ibuff);t1++) {
  1411. t2=ibuff[t1];
  1412. if((t2>='a')&&(t2<='z')) t2-=32;
  1413. t3=input_string[t1];
  1414. if((t3>='a')&&(t3<='z')) t3-=32;
  1415. if(t2=='?') continue;
  1416. if(t2=='#') {
  1417. if((t3<'0')||(t3>'9')) break;
  1418. continue;
  1419. }
  1420. if(t2=='_') {
  1421. if((t3<'A')||(t3>'Z')) break;
  1422. continue;
  1423. }
  1424. if(t2=='*') {
  1425. t1=32767;
  1426. break;
  1427. }
  1428. if(t2!=t3) break;
  1429. }
  1430. if(t1<str_len(ibuff)) break;
  1431. //Matches
  1432. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],id),1);
  1433. gotoed=1;
  1434. break;
  1435. case 115://Player char
  1436. t2=(unsigned char)parse_param(&cmd_ptr[1],id);
  1437. for(t1=0;t1<4;t1++)
  1438. player_char[t1]=t2;
  1439. break;
  1440. case 118://move all thing dir
  1441. done=1;
  1442. t1=parse_param(&cmd_ptr[1],id);//Color
  1443. t3=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);//Thing
  1444. t4=parse_param(&cmd_ptr[next_param(cmd_ptr,next_param(cmd_ptr,1))],id);//Param
  1445. if(t1&256) {
  1446. t1^=256;
  1447. if(t1==32) t1=t2=16;
  1448. else if(t1<16) t2=16;
  1449. else {
  1450. t2=t1-16;
  1451. t1=16;
  1452. }
  1453. }
  1454. else {
  1455. t2=t1>>4;
  1456. t1=t1&15;
  1457. }
  1458. //t1/t2=fg/bk t3=thing t4=param t5=dir
  1459. t5=parsedir(parse_param(&cmd_ptr[next_param(cmd_ptr,
  1460. next_param(cmd_ptr,next_param(cmd_ptr,1)))],id),x,y,robots[id].walk_dir);
  1461. if((t5<1)||(t5>4)) break;
  1462. //if dir is 1 or 4, search top to bottom.
  1463. //if dir is 2 or 3, search bottom to top.
  1464. //t6 set to start, t7 is dest., t8 is inc.
  1465. if((t5==1)||(t5==4)) {
  1466. t6=0; t7=max_bxsiz*max_bysiz; t8=1;
  1467. }
  1468. else {
  1469. t6=max_bxsiz*max_bysiz-1; t7=-1; t8=-1;
  1470. }
  1471. for(;t6!=t7;t6+=t8) {
  1472. if(level_id[t6]!=t3) continue;
  1473. t9=level_color[t6];
  1474. if(t1<16)
  1475. if((t9&15)!=t1) continue;
  1476. if(t2<16)
  1477. if((t9>>4)!=t2) continue;
  1478. if(t4<256)
  1479. if(level_param[t6]!=t4) continue;
  1480. //Correct thing- now move it! :>
  1481. _move(t6%max_bxsiz,t6/max_bxsiz,t5-1,1+2+4+8+16);
  1482. }
  1483. break;
  1484. case 119://copy x y x y
  1485. //t1,t2 to t3,t4
  1486. t9=1;
  1487. t1=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1488. t2=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1489. t3=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1490. t4=parse_param(&cmd_ptr[t9],id);
  1491. prefix_xy(t1,t2,t9,t9,t3,t4,x,y);
  1492. goto copy_XY;
  1493. case 120://set edge color
  1494. edge_color=parse_param(&cmd_ptr[1],id);
  1495. break;
  1496. case 121://board dir is ""
  1497. case 122://board dir is none
  1498. t3=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1499. if((t3<1)||(t3>4)) break;
  1500. if(cmd==122) board_dir[t3-1]=NO_BOARD;
  1501. else {
  1502. t2=next_param(cmd_ptr,1)+1;
  1503. //Find board by given name
  1504. tr_msg(&cmd_ptr[t2],id);
  1505. for(t1=0;t1<NUM_BOARDS;t1++) {
  1506. if(board_where[t1]==W_NOWHERE) continue;
  1507. if(!str_cmp(&board_list[t1*25],ibuff)) break;
  1508. }
  1509. if(t1<NUM_BOARDS) board_dir[t3-1]=t1;
  1510. }
  1511. break;
  1512. case 123://char edit
  1513. t2=next_param(cmd_ptr,1);
  1514. for(t1=0;t1<14;t1++) {
  1515. temp[t1]=parse_param(&cmd_ptr[t2],id);
  1516. t2=next_param(cmd_ptr,t2);
  1517. }
  1518. ec_change_char_nou((unsigned char)(parse_param(&cmd_ptr[1],id)),temp);
  1519. break;
  1520. case 124://Become push
  1521. case 125://Become nonpush
  1522. if(id==NUM_ROBOTS) break;
  1523. level_id[x+y*max_bxsiz]=cmd-1;
  1524. break;
  1525. case 126://blind
  1526. blind_dur=parse_param(&cmd_ptr[1],id);
  1527. break;
  1528. case 127://firewalker
  1529. firewalker_dur=parse_param(&cmd_ptr[1],id);
  1530. break;
  1531. case 128://freezetime
  1532. freeze_time_dur=parse_param(&cmd_ptr[1],id);
  1533. break;
  1534. case 129://slow time
  1535. slow_time_dur=parse_param(&cmd_ptr[1],id);
  1536. break;
  1537. case 130://wind
  1538. wind_dur=parse_param(&cmd_ptr[1],id);
  1539. break;
  1540. case 131://avalanche
  1541. for(t1=0;t1<10000;t1++) {
  1542. if((t2=flags[level_id[t1]])&A_UNDER) {
  1543. if(t2&A_ENTRANCE) continue;
  1544. if(random_num()%18==0) {
  1545. t2=t1%max_bxsiz;
  1546. t3=t1/max_bxsiz;
  1547. if(t2>=board_xsiz) continue;
  1548. if(t3>=board_ysiz) continue;
  1549. id_place(t2,t3,8,7,0);
  1550. }
  1551. }
  1552. }
  1553. break;
  1554. case 132://copy dir dir
  1555. if(id==NUM_ROBOTS) break;
  1556. //t1,t2 to t3,t4
  1557. t1=t3=x; t2=t4=y;
  1558. t5=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1559. if((t5<1)||(t5>4)) break;
  1560. if(move_dir(t1,t2,t5-1)) break;
  1561. t5=parsedir(parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id),
  1562. x,y,robots[id].walk_dir);
  1563. if((t5<1)||(t5>4)) break;
  1564. if(move_dir(t3,t4,t5-1)) break;
  1565. copy_XY:
  1566. t5=level_id[t1+t2*max_bxsiz];
  1567. t6=level_param[t1+t2*max_bxsiz];
  1568. t7=level_id[t3+t4*max_bxsiz];
  1569. if(t7==127) break;//No copy over player
  1570. if(t5==127) break;//No copying player
  1571. if(t5==122) {
  1572. /* Replicate a sensor */
  1573. t8=find_sensor();
  1574. if(!t8) break;// Out of sensors
  1575. copy_sensor(t8,t6);// Copy sensor
  1576. t6=t8;// Set param to newest copy
  1577. }
  1578. if((t5==123)||(t5==124)) {
  1579. /* Replicate a robot */
  1580. t8=find_robot();
  1581. if(!t8) break;// Out of robots
  1582. copy_robot(t8,t6);// Copy robot
  1583. robot=&robot_mem[robots[id].program_location];
  1584. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  1585. t6=t8;// Set param to newest copy
  1586. }
  1587. if((t5==125)||(t5==126)) {
  1588. /* Replicate a scroll */
  1589. t8=find_scroll();
  1590. if(!t8) break;// Out of scrolls
  1591. copy_scroll(t8,t6);// Copy scroll
  1592. t6=t8;// Set param to newest copy
  1593. }
  1594. //Remove at location
  1595. if((t7==123)||(t7==124)) {
  1596. //delete robot
  1597. clear_robot(level_param[t3+t4*max_bxsiz]);
  1598. robot=&robot_mem[robots[id].program_location];
  1599. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  1600. }
  1601. if((t7==125)||(t7==126))
  1602. //delete scroll
  1603. clear_scroll(level_param[t3+t4*max_bxsiz]);
  1604. if(t7==122)
  1605. //delete sensor
  1606. clear_sensor(level_param[t3+t4*max_bxsiz]);
  1607. level_id[t3+t4*max_bxsiz]=t5;
  1608. level_param[t3+t4*max_bxsiz]=t6;
  1609. level_color[t3+t4*max_bxsiz]=level_color[t1+t2*max_bxsiz];
  1610. if((t3==x)&&(t4==y)) {
  1611. exit_func();
  1612. return;
  1613. }
  1614. //Figure blocked vars
  1615. update_blocked=1;
  1616. break;
  1617. case 133://become lavawalker
  1618. case 134://become non lavawalker
  1619. robots[id].can_lavawalk=134-cmd;
  1620. break;
  1621. case 135://change color thing param color thing param
  1622. t9=1;
  1623. t1=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1624. t3=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1625. t4=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1626. t5=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1627. t7=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1628. t8=parse_param(&cmd_ptr[t9],id);
  1629. //t1/t3/t4 to t5/t7/t8
  1630. //Change fgbk code to seperate fg/bk codes
  1631. if(t1&256) {
  1632. t1^=256;
  1633. if(t1==32) t1=t2=16;
  1634. else if(t1<16) t2=16;
  1635. else {
  1636. t2=t1-16;
  1637. t1=16;
  1638. }
  1639. }
  1640. else {
  1641. t2=t1>>4;
  1642. t1=t1&15;
  1643. }
  1644. if(t5&256) {
  1645. t5^=256;
  1646. if(t5==32) t5=t6=16;
  1647. else if(t5<16) t6=16;
  1648. else {
  1649. t6=t5-16;
  1650. t5=16;
  1651. }
  1652. }
  1653. else {
  1654. t6=t5>>4;
  1655. t5=t5&15;
  1656. }
  1657. //t1/t2 = fg/bk orig
  1658. //t3 = thing orig
  1659. //t4 = param orig
  1660. //t5/t6 = fg/bk new
  1661. //t7 = thing new
  1662. //t8 = param new
  1663. //Check for changing between incompatible objects
  1664. if((t7==122)&&(t3!=122)) break;
  1665. if(((t7==123)||(t7==124))&&(t3!=123)&&(t3!=124)) break;
  1666. if(((t7==125)||(t7==126))&&(t3!=125)&&(t3!=126)) break;
  1667. if((t3==127)||(t7==127)) break;
  1668. //Changing to Lava or Fire or Ice or Energizer or CW/CCW
  1669. //or Life
  1670. if((t7==25)||(t7==26)||(t7==33)||(t7==45)||
  1671. (t7==46)||(t7==63)||(t7==66)) t8=0;
  1672. //Changing to explosion
  1673. if(t7==38) t8&=0xF3;//Ignore stages above 3
  1674. //Search for id t3 of color fg=t1 bg=t2. Param==t4
  1675. for(t9=0;t9<10000;t9++) {
  1676. if(t3==41)//Door finds open door
  1677. if(level_id[t9]==42) goto cid_okay;
  1678. if(t3==67)//Whirlpool finds any of them
  1679. if((level_id[t9]>66)&&(level_id[t9]<71)) goto cid_okay;
  1680. if(level_id[t9]!=t3) continue;
  1681. cid_okay:
  1682. t0=level_color[t9];
  1683. if(t1<16)
  1684. if((t0&15)!=t1) continue;
  1685. if(t2<16)
  1686. if((t0>>4)!=t2) continue;
  1687. if(t4<256)
  1688. if(level_param[t9]!=t4) continue;
  1689. if(t5<16) t0=(t0&240)|t5;
  1690. if(t6<16) t0=(t0&15)|(t6<<4);
  1691. level_color[t9]=t0;
  1692. level_id[t9]=t7;
  1693. if(t7==t3) goto skip_del;
  1694. if((t7==124)&&(t3==123)) goto skip_del;
  1695. if((t7==123)&&(t3==124)) goto skip_del;
  1696. if((t7==126)&&(t3==125)) goto skip_del;
  1697. if((t7==125)&&(t3==126)) goto skip_del;
  1698. if((t3==123)||(t3==124)) {
  1699. //delete robot
  1700. clear_robot(level_param[t9]);
  1701. robot=&robot_mem[robots[id].program_location];
  1702. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  1703. }
  1704. if((t3==125)||(t3==126))
  1705. //delete scroll
  1706. clear_scroll(level_param[t9]);
  1707. if(t3==122)
  1708. //delete sensor
  1709. clear_sensor(level_param[t9]);
  1710. skip_del:
  1711. if(t7==0) {
  1712. offs_remove_id(t9,0);
  1713. //If this LEAVES a space, use given color
  1714. if(level_id[t9]==0) level_color[t9]=t0;
  1715. }
  1716. else {
  1717. if(t8<256)
  1718. if(t7<122)
  1719. level_param[t9]=t8;
  1720. }
  1721. }
  1722. //Are we still "alive"?
  1723. if(id!=GLOBAL_ROBOT) {
  1724. t1=level_id[x+y*max_bxsiz];
  1725. if((t1!=123)&&(t1!=124)) {
  1726. exit_func();
  1727. return;//Nope.
  1728. }
  1729. }
  1730. //Figure blocked vars
  1731. update_blocked=1;
  1732. break;
  1733. case 136:// player color
  1734. t1=parse_param(&cmd_ptr[1],id);
  1735. if(get_counter("INVINCO",0))
  1736. saved_pl_color=fix_color(t1,saved_pl_color);
  1737. else player_color=fix_color(t1,player_color);
  1738. break;
  1739. case 137:// bullet color
  1740. for(t1=0;t1<3;t1++)
  1741. bullet_color[t1]=fix_color(parse_param(&cmd_ptr[1],id),
  1742. bullet_color[t1]);
  1743. break;
  1744. case 138:// missile color
  1745. missile_color=fix_color(parse_param(&cmd_ptr[1],id),missile_color);
  1746. break;
  1747. case 139://message row
  1748. b_mesg_row=parse_param(&cmd_ptr[1],id);
  1749. if(b_mesg_row>24) b_mesg_row=24;
  1750. break;
  1751. case 140://REL SELF
  1752. if(id==NUM_ROBOTS) break;
  1753. case 141://REL PLAYER
  1754. case 142://REL COUNTERS
  1755. first_prefix=mid_prefix=last_prefix=cmd-139;
  1756. lines_run--;
  1757. goto next_cmd_prefix;
  1758. case 143://set id char # to 'c'
  1759. t1=parse_param(&cmd_ptr[1],id);
  1760. if((t1>=0)&&(t1<=454))
  1761. id_chars[t1]=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1762. break;
  1763. case 144://jump mod order #
  1764. jump_mod(parse_param(&cmd_ptr[1],id));
  1765. break;
  1766. case 145://ask yes/no
  1767. if(fad) {
  1768. clear_screen(1824,current_pg_seg);
  1769. insta_fadein();
  1770. }
  1771. if(!ask_yes_no(tr_msg(&cmd_ptr[2],id))) send_robot_id(id,"YES",1);
  1772. else send_robot_id(id,"NO",1);
  1773. gotoed=1;
  1774. if(fad) insta_fadeout();
  1775. break;
  1776. case 146://fill health
  1777. set_counter("HEALTH",health_limit);
  1778. break;
  1779. case 147://thick arrow dir char
  1780. t1=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1781. if((t1<1)||(t1>4)) break;
  1782. id_chars[249+t1]=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1783. break;
  1784. case 148://thin arrow dir char
  1785. t1=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  1786. if((t1<1)||(t1>4)) break;
  1787. id_chars[253+t1]=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1788. break;
  1789. case 149://set max health
  1790. health_limit=parse_param(&cmd_ptr[1],id);
  1791. set_counter("HEALTH",get_counter("HEALTH"));
  1792. break;
  1793. case 150://save pos
  1794. t0=0;
  1795. save_pos:
  1796. pl_saved_x[t0]=player_x;
  1797. pl_saved_y[t0]=player_y;
  1798. pl_saved_board[t0]=curr_board;
  1799. break;
  1800. case 151://restore
  1801. t0=0;
  1802. restore_pos:
  1803. t1=pl_saved_x[t0];
  1804. t2=pl_saved_y[t0];
  1805. t3=pl_saved_board[t0];
  1806. exch_pos_entry:
  1807. //Teleport
  1808. target_board=t3;
  1809. target_x=t1;
  1810. target_y=t2;
  1811. target_where=0;
  1812. done=1;
  1813. break;
  1814. case 152://exchange
  1815. t0=0;
  1816. exchange_pos:
  1817. t1=pl_saved_x[t0];
  1818. t2=pl_saved_y[t0];
  1819. t3=pl_saved_board[t0];
  1820. pl_saved_x[t0]=player_x;
  1821. pl_saved_y[t0]=player_y;
  1822. pl_saved_board[t0]=curr_board;
  1823. goto exch_pos_entry;
  1824. case 153://mesg col
  1825. b_mesg_col=parse_param(&cmd_ptr[1],id);
  1826. if(b_mesg_col>79) b_mesg_col=79;
  1827. break;
  1828. case 154://center mesg
  1829. b_mesg_col=255;
  1830. break;
  1831. case 155://clear mesg
  1832. b_mesg_timer=0;
  1833. break;
  1834. case 156://resetview
  1835. scroll_x=scroll_y=0;
  1836. break;
  1837. case 157://modsam freq num
  1838. t1=parse_param(&cmd_ptr[1],id);
  1839. if(music_on) spot_sample(t1,
  1840. parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id));
  1841. break;
  1842. case 159://scrollbase
  1843. scroll_base_color=parse_param(&cmd_ptr[1],id);
  1844. break;
  1845. case 160://scrollcorner
  1846. scroll_corner_color=parse_param(&cmd_ptr[1],id);
  1847. break;
  1848. case 161://scrolltitle
  1849. scroll_title_color=parse_param(&cmd_ptr[1],id);
  1850. break;
  1851. case 162://scrollpointer
  1852. scroll_pointer_color=parse_param(&cmd_ptr[1],id);
  1853. break;
  1854. case 163://scrollarrow
  1855. scroll_arrow_color=parse_param(&cmd_ptr[1],id);
  1856. break;
  1857. case 164://viewport x y
  1858. viewport_x=parse_param(&cmd_ptr[1],id);
  1859. viewport_y=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1860. if((viewport_x+viewport_xsiz)>80) viewport_x=80-viewport_xsiz;
  1861. if((viewport_y+viewport_ysiz)>25) viewport_y=25-viewport_ysiz;
  1862. break;
  1863. case 165://viewport xsiz ysiz
  1864. viewport_xsiz=parse_param(&cmd_ptr[1],id);
  1865. viewport_ysiz=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  1866. if(viewport_xsiz<1) viewport_xsiz=1;
  1867. if(viewport_ysiz<1) viewport_ysiz=1;
  1868. if(viewport_xsiz>80) viewport_xsiz=80;
  1869. if(viewport_ysiz>25) viewport_ysiz=25;
  1870. if((viewport_x+viewport_xsiz)>80) viewport_x=80-viewport_xsiz;
  1871. if((viewport_y+viewport_ysiz)>25) viewport_y=25-viewport_ysiz;
  1872. break;
  1873. case 168://save pos #
  1874. t0=parse_param(&cmd_ptr[1],id)-1;
  1875. if((t0<0)||(t0>7)) t0=0;
  1876. goto save_pos;
  1877. case 169://restore pos #
  1878. t0=parse_param(&cmd_ptr[1],id)-1;
  1879. if((t0<0)||(t0>7)) t0=0;
  1880. goto restore_pos;
  1881. case 170://exchange pos #
  1882. t0=parse_param(&cmd_ptr[1],id)-1;
  1883. if((t0<0)||(t0>7)) t0=0;
  1884. goto exchange_pos;
  1885. case 171://restore pos # duplicate self
  1886. t0=parse_param(&cmd_ptr[1],id)-1;
  1887. if((t0<0)||(t0>7)) t0=0;
  1888. t1=pl_saved_x[t0];
  1889. t2=pl_saved_y[t0];
  1890. t3=pl_saved_board[t0];
  1891. exch_pos_entry2:
  1892. //Teleport
  1893. target_board=t3;
  1894. target_x=t1;
  1895. target_y=t2;
  1896. target_where=0;
  1897. t3=find_robot();
  1898. if(t3) {
  1899. copy_robot(t3,id);
  1900. if(robots[t3].cur_prog_line>0)
  1901. robots[t3].cur_prog_line=1;
  1902. robots[t3].pos_within_line=0;
  1903. if(id!=GLOBAL_ROBOT) {
  1904. target_d_id=level_id[x+y*max_bxsiz];
  1905. target_d_color=level_color[x+y*max_bxsiz];
  1906. }
  1907. else {
  1908. target_d_id=124;
  1909. target_d_color=7;
  1910. }
  1911. find_player();
  1912. id_place(player_x,player_y,target_d_id,
  1913. target_d_color,t3);
  1914. //Find a space location for the player
  1915. for(player_y=0;player_y<board_xsiz;player_y++) {
  1916. for(player_x=0;player_x<board_xsiz;player_x++) {
  1917. if(A_UNDER&flags[level_id[player_x+player_y*max_bxsiz]])
  1918. goto sailormoon;
  1919. }
  1920. }
  1921. sailormoon:
  1922. if((player_x<board_xsiz)&&(player_y<board_ysiz))
  1923. id_place(player_x,player_y,127,0,0);
  1924. else player_x=player_y=0;
  1925. }
  1926. done=1;
  1927. break;
  1928. case 172://exchange pos # duplicate self
  1929. t0=parse_param(&cmd_ptr[1],id)-1;
  1930. if((t0<0)||(t0>7)) t0=0;
  1931. t1=pl_saved_x[t0];
  1932. t2=pl_saved_y[t0];
  1933. t3=pl_saved_board[t0];
  1934. pl_saved_x[t0]=player_x;
  1935. pl_saved_y[t0]=player_y;
  1936. pl_saved_board[t0]=curr_board;
  1937. goto exch_pos_entry2;
  1938. case 173://Pl bulletn
  1939. case 174://Pl bullets
  1940. case 175://Pl bullete
  1941. case 176://Pl bulletw
  1942. case 177://Nu bulletn
  1943. case 178://Nu bullets
  1944. case 179://Nu bullete
  1945. case 180://Nu bulletw
  1946. case 181://En bulletn
  1947. case 182://En bullets
  1948. case 183://En bullete
  1949. case 184://En bulletw
  1950. bullet_char[cmd-173]=parse_param(&cmd_ptr[1],id);
  1951. break;
  1952. case 185://Pl bcolor
  1953. case 186://Nu bcolor
  1954. case 187://En bcolor
  1955. bullet_color[cmd-185]=parse_param(&cmd_ptr[1],id);
  1956. break;
  1957. case 193://Rel self first
  1958. if(id==NUM_ROBOTS) break;
  1959. case 195://Rel player first
  1960. case 197://Rel counters first
  1961. first_prefix=((cmd-193)>>1)+5;
  1962. lines_run--;
  1963. goto next_cmd_prefix;
  1964. case 194://Rel self last
  1965. if(id==NUM_ROBOTS) break;
  1966. case 196://Rel player last
  1967. case 198://Rel counters last
  1968. last_prefix=((cmd-194)>>1)+5;
  1969. lines_run--;
  1970. goto next_cmd_prefix;
  1971. case 199://Mod fade out
  1972. volume_inc=-8;
  1973. volume_target=0;
  1974. break;
  1975. case 200://Mod fade in
  1976. volume_inc=8;
  1977. volume_target=255;
  1978. magic_load_mod(tr_msg(&cmd_ptr[2],id));
  1979. volume_mod(volume=0);
  1980. break;
  1981. case 201://Copy block sx sy xsiz ysiz dx dy
  1982. case 243://Copy overlay block sx sy xs ys dx dy
  1983. t9=1;
  1984. t1=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1985. t2=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1986. t3=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1987. t4=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1988. t5=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  1989. t6=parse_param(&cmd_ptr[t9],id);
  1990. //Prefixes.
  1991. prefix_xy(t1,t2,t0,t0,t5,t6,x,y);
  1992. //Clip and verify parameters.
  1993. if(t1<0) t1=0;
  1994. if(t2<0) t2=0;
  1995. if(t5<0) t5=0;
  1996. if(t6<0) t6=0;
  1997. if(t1>=board_xsiz) t1=board_xsiz-1;
  1998. if(t2>=board_ysiz) t2=board_ysiz-1;
  1999. if(t5>=board_xsiz) t5=board_xsiz-1;
  2000. if(t6>=board_ysiz) t6=board_ysiz-1;
  2001. if(t3<1) t3=1;
  2002. if(t4<1) t4=1;
  2003. if((t1+t3)>board_xsiz) t3=board_xsiz-t1;
  2004. if((t5+t3)>board_xsiz) t3=board_xsiz-t5;
  2005. if((t2+t4)>board_ysiz) t4=board_ysiz-t2;
  2006. if((t6+t4)>board_ysiz) t4=board_ysiz-t6;
  2007. //Copy.
  2008. if((t1==t5)&&(t2==t6)) break;//None to do!
  2009. if((t5<t1)||((t5==t1)&&(t6<t2))) {
  2010. //Copy starting at UL, going by columns.
  2011. for(t7=t1;t7<(t1+t3);t7++) {
  2012. for(t8=t2;t8<(t2+t4);t8++) {
  2013. t9=t7+t8*max_bxsiz;
  2014. t0=((t7-t1)+t5)+((t8-t2)+t6)*max_bxsiz;
  2015. //Copy from t9 to t0
  2016. if(cmd==243) {
  2017. overlay[t0]=overlay[t9];
  2018. overlay_color[t0]=overlay_color[t9];
  2019. continue;
  2020. }
  2021. //Clear anything there...
  2022. cmd=level_id[t0];
  2023. if(cmd==127) continue;//No copy over player
  2024. if(cmd==122)
  2025. clear_sensor(level_param[t0]);
  2026. else if((cmd==123)||(cmd==124)) {
  2027. clear_robot(level_param[t0]);
  2028. robot=&robot_mem[robots[id].program_location];
  2029. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  2030. }
  2031. else if((cmd==125)||(cmd==126))
  2032. clear_scroll(level_param[t0]);
  2033. //Copy any robot/scroll at t9
  2034. cmd=level_id[t9];
  2035. t10=level_param[t9];
  2036. if(cmd==122) {//(sensor)
  2037. //...make a copy...
  2038. if(!(t11=find_sensor())) continue;
  2039. copy_sensor(t11,t10);
  2040. t10=t11;
  2041. }
  2042. if((cmd==123)||(cmd==124)) {//(robot)
  2043. //...make a copy...
  2044. if(!(t11=find_robot())) continue;
  2045. if(copy_robot(t11,t10)) {
  2046. robots[t11].used=0;
  2047. continue;
  2048. }
  2049. robot=&robot_mem[robots[id].program_location];
  2050. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  2051. //...and deallocate original if it was number 0.
  2052. t10=t11;
  2053. }
  2054. if((cmd==125)||(cmd==126)) {//(scroll)
  2055. //...make a copy...
  2056. if(!(t11=find_scroll())) continue;
  2057. if(copy_scroll(t11,t10)) {
  2058. robots[t11].used=0;
  2059. continue;
  2060. }
  2061. t10=t11;
  2062. }
  2063. //Player?
  2064. if(cmd==127) {
  2065. level_id[t0]=level_param[t0]=
  2066. level_under_id[t0]=level_under_param[t0]=0;
  2067. level_color[t0]=level_under_color[t0]=7;
  2068. }
  2069. else {
  2070. //Place
  2071. level_id[t0]=cmd;
  2072. level_param[t0]=t10;
  2073. level_color[t0]=level_color[t9];
  2074. level_under_id[t0]=level_under_id[t9];
  2075. level_under_color[t0]=level_under_color[t9];
  2076. level_under_param[t0]=level_under_param[t9];
  2077. }
  2078. //Loop. (whew!)
  2079. }
  2080. }
  2081. //Done (UL -> LR)
  2082. }
  2083. else {
  2084. //Copy starting at LR, going left by columns.
  2085. for(t7=(t1+t3-1);t7>=t1;t7--) {
  2086. for(t8=(t2+t4-1);t8>=t2;t8--) {
  2087. t9=t7+t8*max_bxsiz;
  2088. t0=((t7-t1)+t5)+((t8-t2)+t6)*max_bxsiz;
  2089. //Copy from t9 to t0
  2090. if(cmd==243) {
  2091. overlay[t0]=overlay[t9];
  2092. overlay_color[t0]=overlay_color[t9];
  2093. continue;
  2094. }
  2095. //Clear anything there...
  2096. cmd=level_id[t0];
  2097. if(cmd==127) continue;//No copy over player
  2098. if(cmd==122)
  2099. clear_sensor(level_param[t0]);
  2100. else if((cmd==123)||(cmd==124)) {
  2101. clear_robot(level_param[t0]);
  2102. robot=&robot_mem[robots[id].program_location];
  2103. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  2104. }
  2105. else if((cmd==125)||(cmd==126))
  2106. clear_scroll(level_param[t0]);
  2107. //Copy any robot/scroll at t9
  2108. cmd=level_id[t9];
  2109. t10=level_param[t9];
  2110. if(cmd==122) {//(sensor)
  2111. //...make a copy...
  2112. if(!(t11=find_sensor())) continue;
  2113. copy_sensor(t11,t10);
  2114. t10=t11;
  2115. }
  2116. if((cmd==123)||(cmd==124)) {//(robot)
  2117. //...make a copy...
  2118. if(!(t11=find_robot())) continue;
  2119. if(copy_robot(t11,t10)) {
  2120. robots[t11].used=0;
  2121. continue;
  2122. }
  2123. robot=&robot_mem[robots[id].program_location];
  2124. cmd_ptr=&robot[robots[id].cur_prog_line+1];
  2125. //...and deallocate original if it was number 0.
  2126. t10=t11;
  2127. }
  2128. if((cmd==125)||(cmd==126)) {//(scroll)
  2129. //...make a copy...
  2130. if(!(t11=find_scroll())) continue;
  2131. if(copy_scroll(t11,t10)) {
  2132. robots[t11].used=0;
  2133. continue;
  2134. }
  2135. t10=t11;
  2136. }
  2137. //Player?
  2138. if(cmd==127) {
  2139. level_id[t0]=level_param[t0]=
  2140. level_under_id[t0]=level_under_param[t0]=0;
  2141. level_color[t0]=level_under_color[t0]=7;
  2142. }
  2143. else {
  2144. //Place
  2145. level_id[t0]=cmd;
  2146. level_param[t0]=t10;
  2147. level_color[t0]=level_color[t9];
  2148. level_under_id[t0]=level_under_id[t9];
  2149. level_under_color[t0]=level_under_color[t9];
  2150. level_under_param[t0]=level_under_param[t9];
  2151. }
  2152. //Loop. (whew!)
  2153. }
  2154. }
  2155. //Done (UL -> LR)
  2156. }
  2157. update_blocked=(cmd==201);
  2158. break;
  2159. case 202://Clip input
  2160. //Chop up to and through first section of whitespace.
  2161. //First, until non space or end
  2162. if(!input_size) break;
  2163. t1=0;
  2164. do {
  2165. if(input_string[t1]==32) break;
  2166. } while((++t1)<input_size);
  2167. if(input_string[t1]==32) {
  2168. do {
  2169. if(input_string[t1]!=32) break;
  2170. } while((++t1)<input_size);
  2171. }
  2172. //Chop UNTIL t1. (t1 points to first No-Chop)
  2173. str_cpy(input_string,&input_string[t1]);
  2174. input_size=str_len(input_string);
  2175. num_input=atoi(input_string);
  2176. break;
  2177. case 203://Push dir
  2178. if(id==NUM_ROBOTS) break;
  2179. t1=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  2180. if((t1<1)||(t1>4)) break;
  2181. t2=x; t3=y;
  2182. if(move_dir(t2,t3,t1-1)) break;
  2183. t4=flags[t5=level_id[t2+t3*max_bxsiz]];
  2184. if((t5!=123)&&(t5!=127)) {
  2185. if((t3<3)&&(!(t4&A_PUSHNS))) break;
  2186. else if((t3>2)&&(!(t4&A_PUSHEW))) break;
  2187. }
  2188. _push(x,y,t1-1,0);
  2189. update_blocked=1;
  2190. break;
  2191. case 204://Scroll char dir
  2192. t9=(unsigned char)parse_param(&cmd_ptr[1],id);
  2193. t2=parsedir(parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id),
  2194. x,y,robots[id].walk_dir);
  2195. if((t2<1)||(t2>4)) break;
  2196. ec_read_char(t9,temp);
  2197. switch(t2) {
  2198. case 1:
  2199. t1=temp[0];
  2200. for(t2=0;t2<13;t2++) temp[t2]=temp[t2+1];
  2201. temp[13]=t1;
  2202. break;
  2203. case 2:
  2204. t1=temp[13];
  2205. for(t2=14;t2>0;t2--) temp[t2]=temp[t2-1];
  2206. temp[0]=t1;
  2207. break;
  2208. case 3:
  2209. for(t1=0;t1<14;t1++) {
  2210. t2=temp[t1]&1;
  2211. temp[t1]>>=1;
  2212. if(t2) temp[t1]|=128;
  2213. }
  2214. break;
  2215. case 4:
  2216. for(t1=0;t1<14;t1++) {
  2217. t2=temp[t1]&128;
  2218. temp[t1]<<=1;
  2219. if(t2) temp[t1]|=1;
  2220. }
  2221. }
  2222. ec_change_char_nou(t9,temp);
  2223. break;
  2224. case 205://Flip char dir
  2225. t9=(unsigned char)parse_param(&cmd_ptr[1],id);
  2226. t2=parsedir(parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id),
  2227. x,y,robots[id].walk_dir);
  2228. if((t2<1)||(t2>4)) break;
  2229. ec_read_char(t9,temp);
  2230. switch(t2) {
  2231. case 1:
  2232. case 2:
  2233. for(t1=0;t1<7;t1++) {
  2234. t2=temp[t1];
  2235. temp[t1]=temp[13-t1];
  2236. temp[13-t1]=t2;
  2237. }
  2238. break;
  2239. case 3:
  2240. case 4:
  2241. for(t1=0;t1<14;t1++) {
  2242. t3=128;
  2243. t4=1;
  2244. for(t2=0;t2<4;t2++) {
  2245. if((temp[t1]&t3)&&(temp[t1]&t4)) ;/* Both on */
  2246. else if((temp[t1]&t3)||(temp[t1]&t4)) temp[t1]^=t3+t4;
  2247. t3>>=1;
  2248. t4<<=1;
  2249. }
  2250. }
  2251. }
  2252. ec_change_char_nou(t9,temp);
  2253. break;
  2254. case 206://copy char char
  2255. t1=(unsigned char)parse_param(&cmd_ptr[1],id);
  2256. t2=(unsigned char)parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  2257. ec_read_char(t1,temp);
  2258. ec_change_char_nou(t2,temp);
  2259. break;
  2260. case 210://change sfx
  2261. t1=next_param(cmd_ptr,1)+1;
  2262. if(str_len(&cmd_ptr[t1])>68) cmd_ptr[t1+68]=0;
  2263. str_cpy(&custom_sfx[parse_param(&cmd_ptr[1],id)*69],&cmd_ptr[t1]);
  2264. break;
  2265. case 211://color intensity #%
  2266. set_palette_intensity(parse_param(&cmd_ptr[1],id));
  2267. pal_update=1;
  2268. break;
  2269. case 212://color intensity # #%
  2270. set_color_intensity(parse_param(&cmd_ptr[1],id)%16,
  2271. parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id));
  2272. pal_update=1;
  2273. break;
  2274. case 213://color fade out
  2275. vquick_fadeout();
  2276. break;
  2277. case 214://color fade in
  2278. vquick_fadein();
  2279. break;
  2280. case 215://set color # r g b
  2281. t9=1;
  2282. t1=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  2283. t2=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  2284. t3=parse_param(&cmd_ptr[t9],id); t9=next_param(cmd_ptr,t9);
  2285. t4=parse_param(&cmd_ptr[t9],id);
  2286. t1%=16;
  2287. set_rgb(t1,t2,t3,t4);
  2288. pal_update=1;
  2289. break;
  2290. case 216://Load char set ""
  2291. ec_load_set_nou(tr_msg(&cmd_ptr[2],id));
  2292. break;
  2293. case 217://multiply str #
  2294. case 218://divide str #
  2295. case 219://modulo str #
  2296. tr_msg(&cmd_ptr[2],id);
  2297. if(str_len(ibuff)>=COUNTER_NAME_SIZE)
  2298. ibuff[COUNTER_NAME_SIZE-1]=0;
  2299. t1=next_param(cmd_ptr,1);
  2300. //t1 points to number to use
  2301. t2=parse_param(&cmd_ptr[1],id);
  2302. t1=parse_param(&cmd_ptr[t1],id);
  2303. if(t1==0) t2=0;
  2304. else if(cmd==217) t2=t2*t1;
  2305. else if(cmd==218) t2=t2/t1;
  2306. else t2=t2%t1;
  2307. set_counter(ibuff,t2,id);
  2308. last_label=-1;//Allows looping "infinitely"
  2309. break;
  2310. case 220://Player char dir 'c'
  2311. t1=parsedir(parse_param(&cmd_ptr[1],id),x,y,robots[id].walk_dir);
  2312. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  2313. if((t1<1)||(t1>4)) break;
  2314. player_char[t1-1]=t2;
  2315. break;
  2316. case 222://Load palette
  2317. fp=fopen(tr_msg(&cmd_ptr[2],id),"rb");
  2318. if(fp==NULL) break;
  2319. for(t1=0;t1<16;t1++) {
  2320. t2=fgetc(fp);
  2321. t3=fgetc(fp);
  2322. t4=fgetc(fp);
  2323. set_rgb(t1,t2,t3,t4);
  2324. }
  2325. pal_update=1;
  2326. //Done.
  2327. fclose(fp);
  2328. break;
  2329. case 224://Mod fade #t #s
  2330. volume_inc=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  2331. volume_target=parse_param(&cmd_ptr[1],id);
  2332. if(volume_target==volume) {
  2333. volume_inc=volume_target=0;
  2334. break;
  2335. }
  2336. if(volume_inc==0) volume_inc=1;
  2337. if((volume<volume_target)&&(volume_inc<0)) volume_inc=-volume_inc;
  2338. if((volume>volume_target)&&(volume_inc>0)) volume_inc=-volume_inc;
  2339. break;
  2340. case 225://Scrollview x y
  2341. t1=parse_param(&cmd_ptr[1],id);
  2342. t2=parse_param(&cmd_ptr[next_param(cmd_ptr,1)],id);
  2343. prefix_xy(t3,t3,t1,t2,t3,t3,x,y);
  2344. //t1/t2 target to put in upper left corner
  2345. //offset off of player position
  2346. scroll_x=scroll_y=0;
  2347. calculate_xytop(t4,t5);
  2348. scroll_x=t1-t4;
  2349. scroll_y=t2-t5;
  2350. break;
  2351. case 226://Swap world str
  2352. str_cpy(temp,tr_msg(&cmd_ptr[2],id));
  2353. //Clear world and reload
  2354. clear_world();
  2355. update_done[0]|=254;
  2356. //(DON'T clear game params)
  2357. redo:
  2358. if(load_world(temp,-1)) {
  2359. t1=error("Error swapping to next world",1,23,current_pg_seg,0x2C01);
  2360. if(t1==2) goto redo;
  2361. }
  2362. str_cpy(curr_file,temp);
  2363. select_current(first_board);
  2364. send_robot_def(0,10);
  2365. target_where=-2;
  2366. target_board=first_board;
  2367. target_x=player_x;
  2368. target_y=player_y;
  2369. exit_func();
  2370. return;
  2371. case 227://If allignedrobot str str
  2372. if(id==NUM_ROBOTS) break;
  2373. tr_msg(&cmd_ptr[2],id);
  2374. for(t1=0;t1<NUM_ROBOTS;t1++) {
  2375. if(!str_cmp(robots[t1].robot_name,ibuff)) {
  2376. if(x==robots[t1].xpos) break;
  2377. if(y==robots[t1].ypos) break;
  2378. }
  2379. }
  2380. if(t1<NUM_ROBOTS) {
  2381. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  2382. id),1);
  2383. gotoed=1;
  2384. }
  2385. break;
  2386. case 229://Lockscroll
  2387. //The scrolling is locked at the current position.
  2388. //Further scrollview cmds can change it.
  2389. t1=scroll_x;
  2390. t2=scroll_y;
  2391. scroll_x=scroll_y=0;
  2392. calculate_xytop(t3,t4);
  2393. locked_x=t3;
  2394. locked_y=t4;
  2395. scroll_x=t1;
  2396. scroll_y=t2;
  2397. break;
  2398. case 230://Unlockscroll
  2399. locked_x=locked_y=65535;
  2400. break;
  2401. case 231://If first string str str
  2402. t1=-1;
  2403. if(!input_size) break;
  2404. t1=0;
  2405. do {
  2406. if(input_string[t1]==32) break;
  2407. } while((++t1)<input_size);
  2408. if(input_string[t1]==32) input_string[t1]=0;
  2409. else t1=-1;
  2410. //Compare
  2411. if(!str_cmp(input_string,tr_msg(&cmd_ptr[2],id))) {
  2412. send_robot_id(id,tr_msg(&cmd_ptr[1+next_param(cmd_ptr,1)],
  2413. id),1);
  2414. gotoed=1;
  2415. }
  2416. if(t1>=0) input_string[t1]=32;
  2417. break;
  2418. case 233://Wait mod fade
  2419. if(volume!=volume_target) goto breaker;
  2420. break;
  2421. case 235://Enable saving
  2422. case 236://Disable saving
  2423. case 237://Enable sensoronly saving
  2424. save_mode=cmd-235;
  2425. break;
  2426. case 238://Status counter ## str
  2427. t1=parse_param(&cmd_ptr[1],id);
  2428. t2=1+next_param(cmd_ptr,1);
  2429. if((t1<1)||(t1>6)) break;
  2430. tr_msg(&cmd_ptr[t2],id);
  2431. if(str_len(ibuff)>=COUNTER_NAME_SIZE)
  2432. ibuff[COUNTER_NAME_SIZE-1]=0;
  2433. str_cpy(&status_shown_counters[COUNTER_NAME_SIZE*(t1-1)],ibuff);
  2434. break;
  2435. case 239://Overlay on
  2436. case 240://Overlay static
  2437. case 241://Overlay transparent
  2438. overlay_mode=cmd-238;
  2439. break;
  2440. case 242://put col ch overlay x y
  2441. if(!overlay_mode) overlay_mode=3;
  2442. t0=1;
  2443. t1=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  2444. t2=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  2445. t3=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  2446. t4=parse_param(&cmd_ptr[t0],id);
  2447. prefix_xy(t9,t9,t3,t4,t9,t9,x,y);
  2448. //t1=color t2=char t3/t4=pos
  2449. t1=fix_color(t1,overlay_color[t3+t4*max_bxsiz]);
  2450. overlay[t3+t4*max_bxsiz]=t2;
  2451. overlay_color[t3+t4*max_bxsiz]=t1;
  2452. break;
  2453. case 245://Change overlay col ch col ch
  2454. case 246://Change overlay col col
  2455. if(!overlay_mode) overlay_mode=3;
  2456. t0=1;
  2457. t1=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  2458. if(cmd==245) {
  2459. t3=parse_param(&cmd_ptr[t0],id);
  2460. t0=next_param(cmd_ptr,t0);
  2461. }
  2462. t5=parse_param(&cmd_ptr[t0],id);
  2463. if(cmd==245) {
  2464. t0=next_param(cmd_ptr,t0);
  2465. t7=parse_param(&cmd_ptr[t0],id);
  2466. }
  2467. //Change fgbk code to seperate fg/bk codes
  2468. if(t1&256) {
  2469. t1^=256;
  2470. if(t1==32) t1=t2=16;
  2471. else if(t1<16) t2=16;
  2472. else {
  2473. t2=t1-16;
  2474. t1=16;
  2475. }
  2476. }
  2477. else {
  2478. t2=t1>>4;
  2479. t1=t1&15;
  2480. }
  2481. //col t1/t2 ch t3 to col t5 ch t7
  2482. for(t9=0;t9<10000;t9++) {
  2483. if(cmd==245)
  2484. if(overlay[t9]!=t3) continue;
  2485. t0=overlay_color[t9];
  2486. if(t1<16)
  2487. if((t0&15)!=t1) continue;
  2488. if(t2<16)
  2489. if((t0>>4)!=t2) continue;
  2490. t0=fix_color(t5,t0);
  2491. overlay_color[t9]=t0;
  2492. if(cmd==245) overlay[t9]=t7;
  2493. }
  2494. break;
  2495. case 247://Write overlay col str # #
  2496. if(!overlay_mode) overlay_mode=3;
  2497. t0=1;
  2498. t1=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  2499. t2=t0+1; t0=next_param(cmd_ptr,t0);
  2500. t3=parse_param(&cmd_ptr[t0],id); t0=next_param(cmd_ptr,t0);
  2501. t4=parse_param(&cmd_ptr[t0],id);
  2502. prefix_xy(t9,t9,t3,t4,t9,t9,x,y);
  2503. //Write str cmd_ptr[t2] at t3/t4 in color t1
  2504. t5=str_len(tr_msg(&cmd_ptr[t2],id));
  2505. for(t6=0;t6<t5;t6++) {
  2506. t7=t3+t4*max_bxsiz;
  2507. overlay_color[t7]=t1;
  2508. overlay[t7]=ibuff[t6];
  2509. if((++t3)>=board_xsiz) break;
  2510. }
  2511. break;
  2512. case 251://Loop start
  2513. robots[id].loop_count=0;
  2514. break;
  2515. case 252://Loop #
  2516. t1=parse_param(&cmd_ptr[1],id);
  2517. if((robots[id].loop_count++)>=t1) break;
  2518. //Search backwards for a cmd 251 or start of program
  2519. t2=robots[id].cur_prog_line;
  2520. do {
  2521. if(robot[t2-1]==0xFF) break;
  2522. t2-=robot[t2-1]+2;
  2523. } while(robot[t2+1]!=251);
  2524. robots[id].cur_prog_line=t2;
  2525. last_label=-1;//Allows looping "infinitely" even w/label inside
  2526. break;
  2527. case 253://Abort loop
  2528. //Search forwards for a cmd 252 or start of program
  2529. t2=robots[id].cur_prog_line;
  2530. do {
  2531. if(robot[t2]==0) break;
  2532. t2+=robot[t2]+2;
  2533. } while(robot[t2+1]!=252);
  2534. robots[id].cur_prog_line=t2;
  2535. if(!robot[t2]) goto end_prog;
  2536. break;
  2537. case 254://Disable mesg edge
  2538. case 255://Enable mesg edge
  2539. mesg_edges=cmd-254;
  2540. break;
  2541. }
  2542. //Go to next command! First erase prefixes...
  2543. next_cmd:
  2544. first_prefix=mid_prefix=last_prefix=0;
  2545. next_cmd_prefix:
  2546. //Next line
  2547. robots[id].pos_within_line=first_cmd=0;
  2548. if(old_pos==robots[id].cur_prog_line) gotoed=0;//No move=didn't goto
  2549. if(!gotoed) robots[id].cur_prog_line+=robot[robots[id].cur_prog_line]+2;
  2550. if(!robot[robots[id].cur_prog_line]) {
  2551. //End of program
  2552. end_prog:
  2553. robots[id].cur_prog_line=0;
  2554. break;
  2555. }
  2556. if((update_blocked)&&(id<NUM_ROBOTS)) {
  2557. update_blocked=0;
  2558. for(t1=0;t1<4;t1++) {
  2559. _bl[t1]=0;
  2560. t4=x; t5=y;
  2561. if(!move_dir(t4,t5,t1)) {
  2562. //Not edge... blocked?
  2563. if((flags[level_id[t4+t5*max_bxsiz]]&A_UNDER)!=A_UNDER) _bl[t1]=1;
  2564. }
  2565. else _bl[t1]=1;//Edge is considered blocked
  2566. }
  2567. //Update player position too
  2568. if(level_id[player_x+player_y*max_bxsiz]!=127) find_player();
  2569. }
  2570. } while(((++lines_run)<40)&&(!done));
  2571. breaker:
  2572. robots[id].cycle_count=0;//In case a label changed it
  2573. //Reset x/y (from movements)
  2574. robots[id].xpos=x;
  2575. robots[id].ypos=y;
  2576. exit_func();
  2577. }