;================================ ; do battle ;================================ do_battle: ; int i,ch; ; int saved_drawpage; ; int ax=34; ; int enemy_count=30; ; int old; jsr rotate_intro .if 0 battle_count=20; ; Setup Enemy */ ; enemy_type=X ; random, with weight toward proper terrain ; 50% completely random, 50% terrain based? enemy_type=random_8()%0x7; ; enemy_hp=enemies[enemy_type].hp_base+ ; (rand()&enemies[enemy_type].hp_mask); saved_drawpage=ram[DRAW_PAGE]; ram[DRAW_PAGE]=PAGE2; ;******************/ ; Draw background */ ; Draw sky */ color_equals(COLOR_MEDIUMBLUE); for(i=0;i<10;i++) { hlin_double(ram[DRAW_PAGE],0,39,i); } ; Draw ground */ color_equals(ground_color); for(i=10;i<40;i++) { hlin_double(ram[DRAW_PAGE],0,39,i); } ; Draw some background images for variety? */ ram[DRAW_PAGE]=saved_drawpage; draw_battle_bottom(enemy_type); while(1) { gr_copy_to_current(0xc00); if (hp==0) { grsim_put_sprite(tfv_defeat,ax-2,24); } else if (running) { ; if (battle_count%2) { grsim_put_sprite(tfv_stand_right,ax,20); } else { grsim_put_sprite(tfv_walk_right,ax,20); } } else { grsim_put_sprite(tfv_stand_left,ax,20); grsim_put_sprite(tfv_led_sword,ax-5,20); } ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); draw_battle_bottom(enemy_type); page_flip(); if (hp==0) { for(i=0;i<15;i++) usleep(100000); break; } usleep(100000); ch=grsim_input(); if (ch=='q') return 0; if (enemy_count==0) { ; attack and decrement HP enemy_attack(ax); ; update limit count if (limit<4) limit++; ; reset enemy time. FIXME: variable? enemy_count=50; } else { enemy_count--; } if (battle_count>=64) { ; TODO: randomly fail at running? */ if (running) { break; } if (menu_state==MENU_NONE) menu_state=MENU_MAIN; menu_keypress(ch); } else { battle_count++; } old=battle_bar; battle_bar=(battle_count/16); if (battle_bar!=old) draw_battle_bottom(enemy_type); if (enemy_hp==0) { victory_dance(); break; } } ram[DRAW_PAGE]=PAGE0; clear_bottom(); ram[DRAW_PAGE]=PAGE1; clear_bottom(); running=0; .endif rts .if 0 ; Do Battle */ ; Metrocat (summon?) */ ; Environment: grass, beach, forest, ice */ ; Enemies: HP ATTACK WEAKNESS RESIST */ ; Killer Crab RND-32 PINCH MALAISE FIRE ; Plain Fish BUBBLE FIRE ICE ; Evil Tree RND-16 LEAVE FIRE ICE ; Wood Elf SING MALAISE BOLT ; Giant Bee RND-64 BUZZSAW ICE NONE ; Procrastinon RND-32 PUTOFF NONE MALAISE ; Ice Fish RND-32 AUGER FIRE ICE ; EvilPenguin WADDLE FIRE ICE ; Battle. ; Forest? Grassland? Artic? Ocean? ; ATTACK REST ; MAGIC LIMIT ; SUMMON RUN ; ; SUMMONS -> METROCAT VORTEXCN ; MAGIC -> HEAL FIRE ; ICE MALAISE ; BOLT ; LIMIT -> SLICE ZAP ; DROP ; ; 1 2 3 ;0123456789012345678901234567890123456789| ;----------------------------------------| ; | HP LIMIT | -> FIGHT/LIMIT 21 ;KILLER CRAB | DEATER 128/255 128 | ZAP 22 ; | | REST 23 ; | | RUN AWAY 24 ; ;Sound effects? ; ;List hits ; ;****** ** **** **** ** ** ****** **** ****** ****** ****** ;** ** **** ** ** ** ** ** ** ** ** ** ** ** ;** ** ** **** **** ****** **** ****** ** ****** ****** ;** ** ** ** ** ** ** ** ** ** ** ** ** ;****** ****** ****** **** ** **** ****** ** ****** ** static int battle_bar=0; static int susie_out=0; ; Background depend on map location? */ ; Room for guinea pig in party? */ ; Attacks -> HIT, ZAP, HEAL, RUNAWAY */ #define MAGIC_NONE 0 #define MAGIC_FIRE 1 #define MAGIC_ICE 2 #define MAGIC_MALAISE 4 #define MAGIC_BOLT 8 #define MAGIC_HEAL 16 struct enemy_type { char *name; int hp_base,hp_mask; char *attack_name; int weakness,resist; unsigned char *sprite; }; ;static struct enemy_type enemies[9]={ ; [0]= { ; .name="Killer Crab", ; .hp_base=50, ; .hp_mask=0x1f, ; .attack_name="Pinch", ; .weakness=MAGIC_MALAISE, ; .resist=MAGIC_FIRE, ; .sprite=killer_crab, ; }, ; [1]= { ; .name="Plain Fish", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Bubble", ; .weakness=MAGIC_FIRE, ; .resist=MAGIC_ICE, ; .sprite=plain_fish, ; }, ; [2]= { ; .name="Evil Tree", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Leaves", ; .weakness=MAGIC_FIRE, ; .resist=MAGIC_ICE, ; .sprite=evil_tree, ; }, ; [3]= { ; .name="Wood Elf", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Song", ; .weakness=MAGIC_MALAISE, ; .resist=MAGIC_BOLT|MAGIC_HEAL, ; .sprite=wood_elf, ; }, ; [4]= { ; .name="Giant Bee", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Buzzsaw", ; .weakness=MAGIC_ICE, ; .resist=MAGIC_NONE, ; .sprite=giant_bee, ; }, ; [5]= { ; .name="Procrastinon", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Putoff", ; .weakness=MAGIC_NONE, ; .resist=MAGIC_MALAISE, ; .sprite=procrastinon, ; }, ; [6]= { ; .name="Ice Fish", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Auger", ; .weakness=MAGIC_FIRE, ; .resist=MAGIC_ICE, ; .sprite=ice_fish, ; }, ; [7]= { ; .name="Evil Penguin", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="Waddle", ; .weakness=MAGIC_FIRE, ; .resist=MAGIC_ICE, ; .sprite=evil_penguin, ; }, ; [8]= { ; .name="Act.Principl", ; .hp_base=10, ; .hp_mask=0x1f, ; .attack_name="BIRDIE", ; .weakness=MAGIC_NONE, ; .resist=MAGIC_ICE|MAGIC_FIRE, ; .sprite=roboknee1, ; }, ;}; static int gr_put_num(int xx,int yy,int number) { int xt=xx,digit,left,hundreds; digit=number/100; if ((digit) && (digit<10)) { grsim_put_sprite(numbers[digit],xt,yy); xt+=4; } hundreds=digit; left=number%100; digit=left/10; if ((digit) || (hundreds)) { grsim_put_sprite(numbers[digit],xt,yy); xt+=4; } left=number%10; digit=left; grsim_put_sprite(numbers[digit],xt,yy); return 0; } ; ; ATTACK SKIP ; MAGIC LIMIT ; SUMMON ESCAPE ; ; SUMMONS -> METROCAT VORTEXCN ; MAGIC -> HEAL FIRE ; ICE MALAISE ; BOLT ; LIMIT -> SLICE ZAP ; DROP ; ; State Machine ; ; time ; BOTTOM -------> MAIN_MENU ----->ATTACK ; ------->SKIP ; ------->MAGIC_MENU ; ------->LIMIT_MENU ; ------->SUMMON_MENU ; ------->ESCAPE ; ; #define MENU_NONE 0 #define MENU_MAIN 1 #define MENU_MAGIC 2 #define MENU_SUMMON 3 #define MENU_LIMIT 4 static int enemy_attacking=0; static int menu_state=MENU_NONE; static int menu_position=0; static int battle_count=0; static int draw_battle_bottom(int enemy_type) { int i; clear_bottom(); vtab(22); htab(1); move_cursor(); ; print(enemies[enemy_type].name); if (enemy_attacking) { vtab(24); htab(2); move_cursor(); ; print_inverse(enemies[enemy_type].attack_name); } vtab(22); htab(15); move_cursor(); ; should print "NAMEO" ; print("DEATER"); print(nameo); if (susie_out) { vtab(23); htab(15); move_cursor(); print("SUSIE"); } if (menu_state==MENU_NONE) { ; TFV Stats */ vtab(21); htab(25); move_cursor(); print("HP"); vtab(21); htab(28); move_cursor(); print("MP"); vtab(21); htab(31); move_cursor(); print("TIME"); vtab(21); htab(36); move_cursor(); if (limit<4) { print("LIMIT"); } else { ; Make if flash? set bit 0x40 */ print_flash("LIMIT"); } vtab(22); htab(24); move_cursor(); print_byte(hp); vtab(22); htab(27); move_cursor(); print_byte(mp); ; Draw Time bargraph */ ; printf("Battle_bar=%d Limit=%d\n",battle_bar,limit); ram[COLOR]=0xa0; hlin_double(ram[DRAW_PAGE],30,34,42); ram[COLOR]=0x20; if (battle_bar) { hlin_double(ram[DRAW_PAGE],30,30+(battle_bar-1),42); } ; Draw Limit break bargraph */ ram[COLOR]=0xa0; hlin_double(ram[DRAW_PAGE],35,39,42); ram[COLOR]=0x20; if (limit) hlin_double(ram[DRAW_PAGE],35,35+limit,42); ; Susie Stats */ if (susie_out) { vtab(23); htab(24); move_cursor(); print_byte(255); vtab(23); htab(27); move_cursor(); print_byte(0); #if 0 ; Draw Time bargraph */ ram[COLOR]=0xa0; hlin_double(ram[DRAW_PAGE],30,34,42); ram[COLOR]=0x20; if (battle_bar) { hlin_double(ram[DRAW_PAGE],30,30+(battle_bar-1),42); } ; Draw Limit break bargraph */ ram[COLOR]=0xa0; hlin_double(ram[DRAW_PAGE],35,39,42); ram[COLOR]=0x20; if (limit) hlin_double(ram[DRAW_PAGE],35,35+limit,42); #endif } } if (menu_state==MENU_MAIN) { if (limit>3) { if (menu_position>5) menu_position=5; } else { if (menu_position>4) menu_position=4; } vtab(21); htab(24); move_cursor(); if (menu_position==0) print_inverse("ATTACK"); else print("ATTACK"); vtab(22); htab(24); move_cursor(); if (menu_position==2) print_inverse("MAGIC"); else print("MAGIC"); vtab(23); htab(24); move_cursor(); if (menu_position==4) print_inverse("SUMMON"); else print("SUMMON"); vtab(21); htab(32); move_cursor(); if (menu_position==1) print_inverse("SKIP"); else print("SKIP"); vtab(22); htab(32); move_cursor(); if (menu_position==3) print_inverse("ESCAPE"); else print("ESCAPE"); if (limit>3) { vtab(23); htab(32); move_cursor(); if (menu_position==5) print_inverse("LIMIT"); else print("LIMIT"); } } if (menu_state==MENU_SUMMON) { if (menu_position>1) menu_position=1; vtab(21); htab(25); move_cursor(); print("SUMMONS:"); vtab(22); htab(25); move_cursor(); if (menu_position==0) print_inverse("METROCAT"); else print("METROCAT"); vtab(23); htab(25); move_cursor(); if (menu_position==1) print_inverse("VORTEXCN"); else print("VORTEXCN"); } if (menu_state==MENU_MAGIC) { if (menu_position>4) menu_position=4; vtab(21); htab(24); move_cursor(); print("MAGIC:"); vtab(22); htab(25); move_cursor(); if (menu_position==0) print_inverse("HEAL"); else print("HEAL"); vtab(23); htab(25); move_cursor(); if (menu_position==2) print_inverse("ICE"); else print("ICE"); vtab(24); htab(25); move_cursor(); if (menu_position==4) print_inverse("BOLT"); else print("BOLT"); vtab(22); htab(32); move_cursor(); if (menu_position==1) print_inverse("FIRE"); else print("FIRE"); vtab(23); htab(32); move_cursor(); if (menu_position==3) print_inverse("MALAISE"); else print("MALAISE"); } if (menu_state==MENU_LIMIT) { if (menu_position>2) menu_position=2; vtab(21); htab(24); move_cursor(); print("LIMIT BREAKS:"); vtab(22); htab(25); move_cursor(); if (menu_position==0) print_inverse("SLICE"); else print("SLICE"); vtab(23); htab(25); move_cursor(); if (menu_position==2) print_inverse("DROP"); else print("DROP"); vtab(22); htab(32); move_cursor(); if (menu_position==1) print_inverse("ZAP"); else print("ZAP"); } ; Draw inverse separator */ ram[COLOR]=0x20; for(i=40;i<50;i+=2) { hlin_double(ram[DRAW_PAGE],12,12,i); } ; ram[DRAW_PAGE]=saved_page; return 0; } static int enemy_hp=0,enemy_type=0,enemy_x=0; static int damage_enemy(int value) { if (enemy_hp>value) enemy_hp-=value; else enemy_hp=0; return 0; } static int heal_self(int value) { hp+=value; if (hp>max_hp) hp=max_hp; return 0; } static int damage_tfv(int value) { if (hp>value) hp-=value; else hp=0; return 0; } static int attack(void) { int ax=34; int damage=10; while(ax>10) { gr_copy_to_current(0xc00); if (ax&1) { grsim_put_sprite(tfv_stand_left,ax,20); } else { grsim_put_sprite(tfv_walk_left,ax,20); } grsim_put_sprite(tfv_led_sword,ax-5,20); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); draw_battle_bottom(enemy_type); page_flip(); ax-=1; usleep(20000); } damage_enemy(damage); gr_put_num(2,10,damage); page_flip(); usleep(250000); return 0; } static int enemy_attack(int tfv_x) { int ax=enemy_x; int damage=10; enemy_attacking=1; while(ax<30) { ; put attack name on ; occasionally attack with that enemy's power? ; occasionally heal self? gr_copy_to_current(0xc00); ; draw first so behind enemy grsim_put_sprite(tfv_stand_left,tfv_x,20); grsim_put_sprite(tfv_led_sword,tfv_x-5,20); if (ax&1) { ; grsim_put_sprite(enemies[enemy_type].sprite,ax,20); } else { ; grsim_put_sprite(enemies[enemy_type].sprite,ax,20); } draw_battle_bottom(enemy_type); page_flip(); ax+=1; usleep(20000); } enemy_attacking=0; damage_tfv(damage); gr_put_num(25,10,damage); draw_battle_bottom(enemy_type); page_flip(); usleep(250000); return damage; } static int victory_dance(void) { int ax=34; int i; int saved_drawpage; saved_drawpage=ram[DRAW_PAGE]; ram[DRAW_PAGE]=PAGE2; ; 0xc00 clear_bottom(); vtab(21); htab(10); move_cursor(); print("EXPERIENCE +2"); experience+=2; vtab(22); htab(10); move_cursor(); print("MONEY +1"); money+=1; ram[DRAW_PAGE]=saved_drawpage; for(i=0;i<25;i++) { gr_copy_to_current(0xc00); if (i&1) { grsim_put_sprite(tfv_stand_left,ax,20); grsim_put_sprite(tfv_led_sword,ax-5,20); } else { grsim_put_sprite(tfv_victory,ax,20); grsim_put_sprite(tfv_led_sword,ax-2,14); } page_flip(); usleep(200000); } return 0; } static int rotate_intro(void) { int xx,yy,color,x2,y2; double h,theta,dx,dy,theta2,thetadiff,nx,ny; int i; gr_copy(0x400,0xc00); ; gr_copy_to_current(0xc00); ; page_flip(); ; gr_copy_to_current(0xc00); ; page_flip(); thetadiff=0; for(i=0;i<8;i++) { grsim_update(); for(yy=0;yy<40;yy++) { for(xx=0;xx<40;xx++) { dx=(xx-20); dy=(yy-20); h=sqrt((dx*dx)+(dy*dy)); theta=atan2(dy,dx); theta2=theta+thetadiff; nx=h*cos(theta2); ny=h*sin(theta2); x2=nx+20; y2=ny+20; if ((x2<0) || (x2>39)) color=0; else if ((y2<0) || (y2>39)) color=0; else color=scrn_page(x2,y2,PAGE2); color_equals(color); plot(xx,yy); } } thetadiff+=(6.28/16.0); page_flip(); usleep(100000); } return 0; } #define MENU_MAGIC_HEAL 0 #define MENU_MAGIC_ICE 1 #define MENU_MAGIC_FIRE 2 #define MENU_MAGIC_MALAISE 3 #define MENU_MAGIC_BOLT 4 static void magic_attack(int which) { int ax=34,ay=20; int mx,my; int damage=20; int i; unsigned char *sprite; if (which==MENU_MAGIC_HEAL) { sprite=magic_health; mx=33; my=20; } if (which==MENU_MAGIC_FIRE) { sprite=magic_fire; mx=2; my=20; } if (which==MENU_MAGIC_ICE) { sprite=magic_ice; mx=2; my=20; } if (which==MENU_MAGIC_BOLT) { sprite=magic_bolt; mx=2; my=20; } if (which==MENU_MAGIC_MALAISE) { sprite=magic_malaise; mx=2; my=20; } ; FIXME: damage based on weakness of enemy ; FIXME: disallow if not enough MP ; cast the magic */ i=0; while(i<10) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_victory,34,20); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); draw_battle_bottom(enemy_type); page_flip(); i++; usleep(20000); } ax=34; ay=20; i=0; ; Actually put the magic */ while(i<=20) { gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,ax,ay); grsim_put_sprite(tfv_led_sword,ax-5,ay); grsim_put_sprite(sprite,mx+(i&1),my); draw_battle_bottom(enemy_type); page_flip(); i++; usleep(100000); } mp-=5; gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,ax,ay); grsim_put_sprite(tfv_led_sword,ax-5,ay); draw_battle_bottom(enemy_type); if (which!=MENU_MAGIC_HEAL) { damage_enemy(damage); gr_put_num(2,10,damage); } else { heal_self(damage); } draw_battle_bottom(enemy_type); page_flip(); for(i=0;i<20;i++) { usleep(100000); } } ; Limit Break "Drop" */ ; Jump into sky, drop down and slice enemy in half */ static void limit_break_drop(void) { int ax=34,ay=20; int damage=100; int i; while(ay>0) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,ax,ay); grsim_put_sprite(tfv_led_sword,ax-5,ay); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); draw_battle_bottom(enemy_type); page_flip(); ay-=1; usleep(20000); } ax=10; ay=0; ; Falling */ while(ay<=20) { gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,ax,ay); grsim_put_sprite(tfv_led_sword,ax-5,ay); draw_battle_bottom(enemy_type); color_equals(13); vlin(0,ay,ax-5); page_flip(); ay+=1; usleep(100000); } i=0; while(i<13) { gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,ax,ay); grsim_put_sprite(tfv_led_sword,ax-5,ay); draw_battle_bottom(enemy_type); color_equals(COLOR_LIGHTGREEN); vlin(ay,ay+i,ax-5); page_flip(); i++; usleep(100000); } ax=34; ay=20; gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,ax,ay); grsim_put_sprite(tfv_led_sword,ax-5,ay); draw_battle_bottom(enemy_type); color_equals(COLOR_LIGHTGREEN); vlin(20,33,5); damage_enemy(damage); gr_put_num(2,10,damage); page_flip(); for(i=0;i<20;i++) { usleep(100000); } } ; Limit Break "Slice" */ ; Run up and slap a bunch with sword */ ; TODO: cause damage value to bounce around more? */ static void limit_break_slice(void) { int tx=34,ty=20; int damage=5; int i; while(tx>10) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); draw_battle_bottom(enemy_type); page_flip(); tx-=1; usleep(20000); } ; Slicing */ for(i=0;i<20;i++) { gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); if (i&1) { grsim_put_sprite(tfv_stand_left,tx,20); grsim_put_sprite(tfv_led_sword,tx-5,20); } else { grsim_put_sprite(tfv_victory,tx,20); grsim_put_sprite(tfv_led_sword,tx-2,14); } damage_enemy(damage); ; gr_put_num(2+(i%2),10+((i%2)*2),damage); draw_battle_bottom(enemy_type); page_flip(); usleep(100000); } tx=34; ty=20; gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); draw_battle_bottom(enemy_type); page_flip(); for(i=0;i<20;i++) { usleep(100000); } } ; Limit Break "Zap" */ ; Zap with a laser out of the LED sword */ static void limit_break_zap(void) { int tx=34,ty=20; int damage=100; int i; gr_copy_to_current(0xc00); ; Draw background */ color_equals(COLOR_AQUA); vlin(12,24,34); hlin_double(ram[DRAW_PAGE],28,38,18); ; Sword in air */ grsim_put_sprite(tfv_victory,tx,20); grsim_put_sprite(tfv_led_sword,tx-2,14); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); draw_battle_bottom(enemy_type); page_flip(); usleep(500000); for(i=0;i<32;i++) { gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); color_equals(i%16); hlin_double(ram[DRAW_PAGE],5,30,22); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); draw_battle_bottom(enemy_type); page_flip(); usleep(100000); } gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); draw_battle_bottom(enemy_type); damage_enemy(damage); gr_put_num(2,10,damage); page_flip(); for(i=0;i<20;i++) { usleep(100000); } } #define MENU_LIMIT_SLICE 0 #define MENU_LIMIT_ZAP 1 #define MENU_LIMIT_DROP 2 static void limit_break(int which) { if (which==MENU_LIMIT_DROP) limit_break_drop(); else if (which==MENU_LIMIT_SLICE) limit_break_slice(); else if (which==MENU_LIMIT_ZAP) limit_break_zap(); ; reset limit counter */ limit=0; } static void summon_metrocat(void) { int tx=34,ty=20; int damage=100; int i; int ax=28,ay=2; i=0; while(i<30) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(metrocat,ax,ay); draw_battle_bottom(enemy_type); page_flip(); i++; usleep(20000); } while(ax>15) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(metrocat,ax,ay); draw_battle_bottom(enemy_type); page_flip(); ax-=1; usleep(20000); } while(ax>5) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(metrocat,ax,ay); draw_battle_bottom(enemy_type); page_flip(); ay+=1; ax-=1; usleep(20000); } i=0; while(i<30) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(metrocat,ax,ay); draw_battle_bottom(enemy_type); page_flip(); i++; usleep(20000); } gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); draw_battle_bottom(enemy_type); damage_enemy(damage); gr_put_num(2,10,damage); page_flip(); for(i=0;i<20;i++) { usleep(100000); } } static void summon_vortex_cannon(void) { int tx=34,ty=20; int damage=5; int i; int ax=20,ay=20; ; draw the cannon */ i=0; while(i<30) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(vortex_cannon,ax,ay); draw_battle_bottom(enemy_type); page_flip(); i++; usleep(20000); } ; Fire vortices */ ax=20; for(i=0;i<5;i++) { while(ax>5) { gr_copy_to_current(0xc00); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(vortex_cannon,20,20); grsim_put_sprite(vortex,ax,24); draw_battle_bottom(enemy_type); if (ax<10) { gr_put_num(2,10,damage); } page_flip(); ax-=1; usleep(50000); } damage_enemy(damage); ax=20; } gr_copy_to_current(0xc00); ; grsim_put_sprite(enemies[enemy_type].sprite,enemy_x,20); grsim_put_sprite(tfv_stand_left,tx,ty); grsim_put_sprite(tfv_led_sword,tx-5,ty); draw_battle_bottom(enemy_type); page_flip(); for(i=0;i<20;i++) { usleep(100000); } } static void summon(int which) { if (which==0) summon_metrocat(); else summon_vortex_cannon(); } static void done_attack(void) { ; reset battle time battle_count=0; menu_state=MENU_NONE; } #define MENU_MAIN_ATTACK 0 #define MENU_MAIN_SKIP 1 #define MENU_MAIN_MAGIC 2 #define MENU_MAIN_ESCAPE 3 #define MENU_MAIN_SUMMON 4 #define MENU_MAIN_LIMIT 5 static int running=0; void menu_keypress(int ch) { if ((ch==' ') || (ch==13)) { if (menu_state==MENU_MAIN) { switch(menu_position) { case MENU_MAIN_ATTACK: ; attack and decrement HP attack(); done_attack(); break; case MENU_MAIN_SKIP: done_attack(); break; case MENU_MAIN_MAGIC: menu_state=MENU_MAGIC; menu_position=0; break; case MENU_MAIN_LIMIT: menu_state=MENU_LIMIT; menu_position=0; break; case MENU_MAIN_SUMMON: menu_state=MENU_SUMMON; menu_position=0; break; case MENU_MAIN_ESCAPE: running=1; done_attack(); break; } } else if (menu_state==MENU_MAGIC) { magic_attack(menu_position); done_attack(); } else if (menu_state==MENU_LIMIT) { limit_break(menu_position); done_attack(); } else if (menu_state==MENU_SUMMON) { summon(menu_position); done_attack(); } } if (ch==27) { menu_state=MENU_MAIN; menu_position=0; } if (ch==APPLE_UP) { if (menu_position>=2) menu_position-=2; } if (ch==APPLE_DOWN) { menu_position+=2; } if (ch==APPLE_RIGHT) { menu_position++; } if (ch==APPLE_LEFT) { if (menu_position>0) menu_position--; } } int boss_battle(void) { int i,ch; int saved_drawpage; int ax=34; int enemy_count=30; int old; susie_out=1; rotate_intro(); battle_count=20; enemy_type=8; enemy_hp=255; saved_drawpage=ram[DRAW_PAGE]; ram[DRAW_PAGE]=PAGE2; ;******************/ ; Draw background */ ; Draw sky */ color_equals(COLOR_BLACK); for(i=0;i<20;i++) { hlin_double(ram[DRAW_PAGE],0,39,i); } color_equals(COLOR_ORANGE); for(i=20;i<39;i++) { hlin_double(ram[DRAW_PAGE],0,39,i); } ; Draw horizon */ ; color_equals(COLOR_GREY); ; hlin_double(ram[DRAW_PAGE],0,39,10); ram[DRAW_PAGE]=saved_drawpage; draw_battle_bottom(enemy_type); while(1) { gr_copy_to_current(0xc00); if (hp==0) { grsim_put_sprite(tfv_defeat,ax-2,24); } else if (running) { ; if (battle_count%2) { grsim_put_sprite(tfv_stand_right,ax,20); } else { grsim_put_sprite(tfv_walk_right,ax,20); } } else { grsim_put_sprite(tfv_stand_left,ax,20); grsim_put_sprite(tfv_led_sword,ax-5,20); } grsim_put_sprite(susie_left,28,30); if ((enemy_count&0xf)<4) { grsim_put_sprite(roboknee1,enemy_x,16); } else { grsim_put_sprite(roboknee2,enemy_x,16); } draw_battle_bottom(enemy_type); page_flip(); if (hp==0) { for(i=0;i<15;i++) usleep(100000); break; } usleep(100000); ch=grsim_input(); if (ch=='q') return 0; if (enemy_count==0) { ; attack and decrement HP enemy_attack(ax); ; update limit count if (limit<4) limit++; ; reset enemy time. FIXME: variable? enemy_count=50; } else { enemy_count--; } if (battle_count>=64) { ; TODO: randomly fail at running? */ if (running) { break; } if (menu_state==MENU_NONE) menu_state=MENU_MAIN; menu_keypress(ch); } else { battle_count++; } old=battle_bar; battle_bar=(battle_count/16); if (battle_bar!=old) draw_battle_bottom(enemy_type); if (enemy_hp==0) { ; FIXME? victory_dance(); break; } } ram[DRAW_PAGE]=PAGE0; clear_bottom(); ram[DRAW_PAGE]=PAGE1; clear_bottom(); running=0; return 0; } .endif