Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
wars.cpp
- Committer:
- trelemar
- Date:
- 2017-12-11
- Revision:
- 8:976e983ce79a
- Parent:
- 7:91365e9ad8c6
- Child:
- 9:682f31473b25
File content as of revision 8:976e983ce79a:
#include "Pokitto.h"
#include "warsprites.h"
#include "hero_sprites.h"
#include "ui_sprites.h"
uint16_t dark_pal[16];
#include "warfont.cpp"
#include <vector>
#include <stdint.h>
Pokitto::Core game;
Pokitto::Display disp;
Pokitto::Buttons btn;
#define SW disp.width
#define SH disp.height
void splashScreen(const uint8_t * bitmap, char * name, uint16_t time) {
disp.bgcolor = 3;
disp.clear();
disp.drawBitmap(SW/2 -(*bitmap/2), SH/2 - (*bitmap/2), bitmap);
disp.setColor(15);
disp.print(SW/2- ((strlen(name)*6)/2),88-32,name);
//game.wait(time);
for (int i=0;i<16;i++) {disp.palette[i]=0;}
disp.update();
for (int i=0;i<80;i++) {
for (int c = 0;c<16;c++) {
disp.palette[c]=disp.interpolateColor(disp.palette[c],sprite_pal[c],80);
}
disp.update();
game.wait(10);
if (btn.pressed(BTN_A)) break;
}
disp.load565Palette(sprite_pal);
}
void init_dark_palette() {
for (uint8_t c=1;c<15;c++) {
dark_pal[c] = disp.interpolateColor(sprite_pal[c], sprite_pal[0], 100);
}
}
bool loading;
int solids[64] {
0,1,1,1,1,0,0,0,
0,0,1,0,1,0,0,0,
0,0,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
};
//Sprite sheet:2x1
const uint8_t cursor_sprites [][244] ={
//[0] cell:0x0
{
22,22,
204,0,12,204,204,204,204,204,192,0,204,
192,255,240,204,204,204,204,204,15,255,12,
15,160,12,204,204,204,204,204,192,10,240,
15,12,204,204,204,204,204,204,204,192,240,
15,12,204,204,204,204,204,204,204,192,240,
192,204,204,204,204,204,204,204,204,204,12,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
192,204,204,204,204,204,204,204,204,204,12,
15,12,204,204,204,204,204,204,204,192,240,
15,12,204,204,204,204,204,204,204,192,240,
15,160,12,204,204,204,204,204,192,10,240,
192,255,240,204,204,204,204,204,15,255,12,
204,0,12,204,204,204,204,204,192,0,204,
},
//[1] cell:1x0
{
22,22,
204,204,204,204,204,204,204,204,204,204,204,
204,192,0,204,204,204,204,204,0,12,204,
204,15,255,12,204,204,204,192,255,240,204,
192,250,0,204,204,204,204,204,0,175,12,
192,240,204,204,204,204,204,204,204,15,12,
192,240,204,204,204,204,204,204,204,15,12,
204,12,204,204,204,204,204,204,204,192,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,204,204,204,204,204,204,204,204,204,204,
204,12,204,204,204,204,204,204,204,192,204,
192,240,204,204,204,204,204,204,204,15,12,
192,240,204,204,204,204,204,204,204,15,12,
192,250,0,204,204,204,204,204,0,175,12,
204,15,255,12,204,204,204,192,255,240,204,
204,192,0,204,204,204,204,204,0,12,204,
204,204,204,204,204,204,204,204,204,204,204,
},
};
using namespace std;
int clamp(int low, int n, int high) {return min(max(low, n), high);}
float dist(int x1, int y1, int x2, int y2) {
int x = x1 - x2;
int y = y1 - y2;
float dist;
dist = pow((float)x,2)+pow((float)y,2);
dist = sqrt((float)dist);
return dist;
}
int lerp(int a, int b, float t) {
return (1-t)*a + t*b;
}
float lerp(float a, float b, float t) {
return (1-t)*a + t*b;
}
enum GameState {MAIN, PAUSE, MENU} State = MENU;
#define KEY_REPEAT 5
#define TASK_MOVE 0
#define TASK_ATTACK 1
#define TASK_ITEM 2
#define TASK_WAIT 3
#define TASK_NONE 4
#define TEAM_USER 0
#define TEAM_CPU 1
int current_team = TEAM_USER;
uint8_t selected_task = 0;
uint8_t current_task = TASK_NONE;
static char task_names[4][7] {
{"MOVE"},
{"ATTACK"},
{"TRAIT"},
{"WAIT"},
};
int task_colors[4] {
11,9,6,8
};
int map_x, map_y, cursor_x, cursor_y;
bool center_cursor = true;
void centerCursor() {
map_x = cursor_x - 3;
map_y = cursor_y - 2;
}
static void print(char text[], uint8_t color) {
disp.setColor(color);
disp.print(text);
}
static void printb(int x, int y, int text) {
disp.setColor(0);
disp.print(x,y-1,text);
disp.print(x,y+1,text);
disp.print(x+1,y,text);
disp.print(x-1,y,text);
disp.setColor(15);
disp.print(x,y,text);
}
static void printb(int x, int y, char text[]) {
disp.setColor(0);
disp.print(x,y-1,text);
disp.print(x,y+1,text);
disp.print(x+1,y,text);
disp.print(x-1,y,text);
disp.setColor(15);
disp.print(x,y,text);
}
struct Dialog {
char text[20];
int start_time;
int position;
Dialog(char _text[20]) {
strcpy(text, _text);
position = 0;
start_time = game.frameCount;
};
void update() {
position = min(position + 1, 19);
};
void draw(int x, int y) {
disp.setCursor(x, y);
for (int p=0;p<position;p++) {
disp.print(text[p]);
}
};
};
struct Transition {
int on_val, off_val, val;
bool enabled;
Transition() {};
Transition(int _onv, int _offv, bool _enabled) {
on_val = _onv;
off_val = _offv;
enabled = _enabled;
if (enabled) val=on_val;
else val = off_val;
};
void toggle() {enabled=!enabled;};
void update() {
if (enabled) val = lerp(val, on_val, 0.2);
else val = lerp(val, off_val, 0.2);
};
};
struct Vec2 {
int x, y;
Vec2(int _x, int _y) {x=_x; y=_y;};
};
struct Item {
int id, x, y;
Item(int _id, int _x, int _y) {
id = _id;
x = _x;
y = _y;
};
void Draw() {
int dx = (x-map_x)*16;
int dy = (y-map_y)*16;
//disp.setColor(1);
//disp.fillRectangle(dx+4,dy+12,8,3);
//disp.drawBitmap(dx, dy+(sin(game.frameCount/4))*2, sprites[id]);
};
};
#define ID_SOLDIER 0
#define ID_HEAVY 1
#define ID_SNIPER 2
#define ID_ORC 3
const int sprite_ids[16] {
0, //SOLDIER
2, //HEAVY
4, //SNIPER
9, //ORC
};
char id_names[][8] {
{"SOLDIER"},
{"HEAVY"},
{"SNIPER"},
{"ORC"},
};
char TRAITS[][8] {
{""},
{"FAST"},
{"HULKISH"},
};
struct Hero {
unsigned int index, team, id, x, y;
uint8_t atk, def, hp, max_hp;
float range;
int spr;
int hurt_time;
bool tasks[4], flip;
char * traits;
Hero(int _x, int _y, int _id, int _team) {
hurt_time = 0;
x = _x; y = _y; flip = false;
id = _id; team = _team;
if (_team == TEAM_USER) {
}
else {flip=true;}
spr = sprite_ids[id];
max_hp = 10;
atk = 5;
def = 2;
range = 2.1;
if (id == ID_HEAVY) {atk+=3; def++; range-=.5; max_hp+=2;}
if (id == ID_SNIPER) {def--; atk--; range+=1.5; max_hp-=2;}
hp = max_hp;
NewTurn();
};
void NewTurn() {
for (int i=0;i<4;i++) {tasks[i]=true;}
};
void update(int i) {
index = i;
};
void Draw() {
int ox = 0;
int oy = 0;
int dx = (x-map_x)*16;
int dy = (y-map_y)*16;
bool draw = true;
if (game.frameCount-hurt_time<10) {
ox = random(-2,2);
oy = random(-2,2);
if (game.frameCount%2==0) {draw=false;}
}
int spr_id = spr + (game.frameCount/10)%2;
disp.invisiblecolor = 13;
if (draw) disp.drawBitmap((dx)+ox,(dy)+oy,hero_sprites[spr_id], 0, flip);
disp.invisiblecolor = 12;
if (id==ID_SNIPER&&team==TEAM_USER) {
int lx = dx+ox+16;
int ly = dy+oy+5;
if (game.frameCount/10%2==1) ly++;
if (flip) lx-=18;
disp.setColor(0);
disp.drawLine(lx,ly,lx+1,ly);
}
};
bool inRange(Hero * enemy) {
return (dist(x, y, enemy->x, enemy->y)<=range);
};
bool inRange(int dx, int dy) {
return (dist(x, y, dx, dy)<=range);
};
void AIhandle(int &ai_index, vector<Hero> &heros) {
Hero * target=NULL;
for (int i=0; i<heros.size(); i++) {
if (inRange(&heros[i])&&tasks[TASK_ATTACK]) {
target = &heros[i];
break;
}
}
if (target!=NULL&&tasks[TASK_ATTACK]) {
target->hurt_time=game.frameCount;
target->hp-= (atk-target->def);
tasks[TASK_ATTACK] = 0;
}
};
};
struct Base {
int x, y, id, team;
int hp;
int spawn_points;
Base() {};
Base(int _x, int _y, int _id, int _team) {
x = _x;
y = _y;
id = _id;
team = _team;
spawn_points = 10;
};
void Draw() {
int dx = (x-map_x)*16;
int dy = (y-map_y)*16;
disp.drawBitmap(dx, dy, sprites[id]);
};
void Spawn(int x, int y, int id, vector<Hero> &heros) {
};
};
Hero * cursor_hero = NULL;
Hero * current_hero = NULL;
vector<Hero> * hptr;
Base bases[2];
Base * current_base = NULL;
void DrawCursorHeroUI (Hero * h, int x, int y) {
float bw = 24;
float hw = (bw/h->max_hp) * h->hp;
disp.setColor(0);
disp.drawRoundRect(x-1,y-1,bw+2,5,2); //HEALTH BAR
disp.fillRoundRect(x-1, y+26,bw+2,7,2); //TEXT BG BOX
disp.setColor(6);
disp.fillRect(x, y, bw, 2);
disp.setColor(11);
disp.fillRect(x, y, hw, 2);
disp.setColor(11);
disp.print(x,y+27,"^");
disp.setColor(15);
disp.print((int)h->atk);
disp.setColor(6);
disp.print("n");
disp.setColor(15);
disp.print((int)h->def);
}
void DrawSelectedBaseUI(Base * base, int y) {
disp.setColor(0);
disp.fillRoundRect(1,y,SW-2,88-67,3);
if (!base) return;
disp.setColor(15);
disp.print(4, y, (int)selected_task);
}
void DrawSelectedHeroUI(Hero * h, int y) {
disp.setColor(0);
//disp.fillRect(0,66,SW,88-66);
disp.fillRoundRect(1,y,SW-2,88-67,3);
//disp.setColor(15);
if (!h) return;
printb(3,y-3,id_names[h->id]);
disp.setColor(8);
disp.print(3,y+3,">");
disp.setColor(15);
disp.print((int)h->atk);
disp.print(" ATK");
disp.setColor(6);
disp.print(3,y+9,"n");
disp.setColor(15);
disp.print((int)h->def);
disp.print(" DEF");
disp.setColor(11);
disp.print(3,y+15,"^");
disp.setColor(15);
disp.print((int)h->range);
disp.print(" RNG");
printb(16,(-y)+68,task_names[selected_task]);
for (int i=0;i<4;i++) {
int spr = i+8;
if (!h->tasks[i]) spr-=8;
else if (selected_task==i) spr+=8;
disp.drawBitmap(44+(i*16), y+4, ui_sprites[spr]);
}
int bw = 62;
int hw = (bw/h->max_hp) * h->hp;
disp.setColor(0);
disp.drawRoundRect(44,y-4,bw+2,7,3);
disp.setColor(6);
disp.fillRoundRect(45,y-3,bw,5,2);
disp.setColor(11);
disp.fillRoundRect(45,y-3,hw+2,5,2);
disp.setColor(15);
printb(50+(bw/2)-10,y-3,(int)h->hp);
}
void DrawTraitList(Hero * h, int x) {
//disp.setColor(0);
//disp.fillRoundRect(32,y,SW-63,12,3);
//disp.setColor(15);
//for (int i = 0; i<4; i++) {
//disp.drawRoundRect(34+(i*11),y+1,10,10,2);
//}
int y = 17;
disp.setColor(0);
disp.fillRoundRect(x, y-1, 12, 45, 3);
disp.setColor(15);
for (int i=0; i<4; i++) {
disp.drawRoundRect(x+1,y+(i*11), 10, 10, 2);
}
disp.print(x+4,y+2, "f");
if (selected_task!=TASK_ITEM) return;
disp.setColor(0);
disp.fillRoundRect(x+13, y-1+6, 64, 6*3+1, 3);
disp.setColor(15);
//disp.print(x+28,y,"~WIMP~");
printb(x+14,y,"< ~HULKISH~");
disp.setColor(7);
disp.print(x+15, y+6, "MOVEMENT");
disp.setColor(6);
disp.print("nn");
disp.setColor(7);
disp.print(x+15, y+12, "MAX HP");
disp.setColor(11);
disp.print("^^");
disp.setColor(7);
disp.print(x+15, y+18, "^ATK ^DEF");
}
void DrawTurnCounter(vector<Hero> &_heros) {
disp.invisiblecolor = 13;
int spr = 32;
if (current_team==TEAM_CPU) spr = 33;
disp.drawBitmap(0, 0, ui_sprites[spr]);
disp.invisiblecolor = 12;
int count = 0;
for (int i=0; i<_heros.size();i++) {
if (_heros[i].team == current_team) count++;
}
printb(11,10,(int)count);
}
#define MAP_WIDTH 12
#define MAP_HEIGHT 12
int Map[MAP_HEIGHT][MAP_WIDTH] {
{0,8,0,5,10,8,8,1,8,8,0,8},
{1,0,0,21,15,14,8,0,8,0,1,0},
{0,8,0,8,10,5,8,8,0,9,8,8},
{0,1,8,0,10,5,1,8,8,8,0,8},
{8,0,9,0,18,7,3,3,3,4,8,1},
{0,8,8,0,0,5,0,0,0,12,8,13},
{0,0,1,8,8,5,8,1,8,11,0,5},
{8,0,8,0,8,5,8,0,0,10,0,5},
{8,8,0,8,1,21,6,30,6,15,6,22},
{8,0,0,8,8,0,0,5,8,12,0,0},
{0,1,8,9,0,8,1,5,8,18,3,3},
{0,0,8,8,8,8,0,5,8,0,8,0},
};
void loadTileMap(char * filename) {
disp.enableDirectPrinting(true);
disp.fillLCD(disp.palette[0]);
disp.directBitmap(110-16,176/2-16,ui_sprites[7],4,2);
disp.directbgcolor = disp.palette[0];
disp.fontSize = 2;
disp.directcolor = disp.palette[15];
disp.print(24,164,"LOADING CONTENT");
int inc = 220/144;
#ifdef POK_SIM
game.wait(20);
#endif
pokInitSD();
int success = fileOpen(filename,FILE_MODE_BINARY);
if (!isThisFileOpen(filename)) {
disp.directcolor = disp.palette[6];
disp.print(0,16,"SD LOADING ERROR");
while (!btn.aBtn()) {
game.wait(100);
}
}
for (int i = 0; i<144; i++) {
int x = i%MAP_WIDTH;
int y = (i-x)/MAP_WIDTH;
//fileSetPosition(i);
Map[y][x] = (int)filePeek(i);
#ifdef POK_SIM
game.wait(10);
#endif // POK_SIM
disp.directRectangle(inc*(i*2),0,inc,8,disp.palette[15]);
}
fileClose();
disp.enableDirectPrinting(false);
}
void saveTileMap() {
}
void DrawTileMap(int8_t x, int8_t y, Hero * hero) {
disp.setColor(15);
for (int map_x=0; map_x<7; map_x++) {
for (int map_y=0; map_y<6; map_y++) {
int spr;
if (map_x+x<0||x+map_x>MAP_WIDTH-1||y+map_y<0||y+map_y>MAP_HEIGHT-1) {
spr = 9;
}
else {
spr = Map[map_y+y][map_x+x];
}
float distance;
disp.drawBitmap((map_x*16), (map_y*16),sprites[spr]);
//RANGE BOXES
if (hero && (current_task == TASK_MOVE || current_task == TASK_ATTACK)) {
distance = dist(map_x+x, map_y+y, hero->x, hero->y);
if (distance<hero->range&&x+map_x<MAP_WIDTH&&y+map_y<MAP_HEIGHT) {
disp.setColor(8);
if (solids[Map[map_y+y][map_x+x]]) {disp.setColor(6);}
disp.drawRoundRect(map_x*16+2, map_y*16+2, 12, 12,3);
//disp.print(map_x*16,map_y*16,(float)distance);
}
}
}
}
}
void DrawCursor(int x, int y) {
//uint8_t spr = 52 + (game.frameCount/12)%2;
disp.drawBitmap(x*16-3, y*16-3,cursor_sprites[(game.frameCount/4)%2]);
}
Hero * getHeroAtCoords(int x, int y, vector<Hero> &herovect) {
Hero *h = NULL;
bool found = false;
for (int i=0;i<herovect.size();i++) {
if (herovect[i].x==x&&herovect[i].y==y) {
h = &herovect[i];
break;
}
}
return h;
}
void CursorInput() {
int last_x=cursor_x;
int last_y=cursor_y;
if (btn.repeat(BTN_UP,KEY_REPEAT)) {
if (cursor_y-map_y<=0) {
map_y=max(map_y-1,0);
}
cursor_y=max(cursor_y-1,0);
}
if (btn.repeat(BTN_DOWN,KEY_REPEAT)) {
if (cursor_y-map_y>=4) {
map_y=min(map_y+1,MAP_HEIGHT-6);
}
cursor_y=min(cursor_y+1,MAP_HEIGHT-1);
}
if (btn.repeat(BTN_LEFT,KEY_REPEAT)) {
if (cursor_x-map_x<=0) {
map_x=max(map_x-1,0);
}
cursor_x=max(cursor_x-1,0);
}
if (btn.repeat(BTN_RIGHT,KEY_REPEAT)) {
if (cursor_x-map_x>=6) {
map_x=min(map_x+1,MAP_WIDTH-7);
}
cursor_x=min(cursor_x+1,MAP_WIDTH-1);
}
if (center_cursor) {
centerCursor();
}
}
struct PauseMenu {
char items[3][12];
unsigned int selected_item;
Transition lb; //letterbox
PauseMenu() {
lb.off_val=0;
lb.on_val=16;
lb.enabled=true;
lb.val = lb.off_val;
selected_item = 0;
strcpy(items[0], "RESUME");
strcpy(items[1], "END TURN");
strcpy(items[2], "QUIT GAME");
};
void endTurn(vector<Hero> * _heros) {
for (int i=0; i<0+_heros->size(); i++) {
_heros->at(i).NewTurn();
}
};
void update() {
lb.update();
for (int i = 1; i<15; i++) {
disp.palette[i] = disp.interpolateColor(disp.palette[i],dark_pal[i], 80);
}
if (btn.pressed(BTN_DOWN)) {
selected_item++;
selected_item%=3;
}
else if (btn.pressed(BTN_UP)) {
selected_item--;
selected_item%=3;
}
if (btn.pressed(BTN_A)) {
lb.val = lb.off_val;
disp.load565Palette(sprite_pal);
switch (selected_item) {
case 0:
State = MAIN;
break;
case 1:
current_team=(current_team+1) % 2;
endTurn(hptr);
State = MAIN;
break;
case 2:
State = MENU;
break;
}
}
};
void draw() {
//disp.fillRoundRect()
DrawTileMap(map_x, map_y, current_hero);
disp.setColor(0);
disp.fillRect(0,0,SW,lb.val);
disp.fillRect(0,SH-lb.val,SW,lb.on_val);
disp.setColor(15);
disp.setCursor(0,lb.val+2);
disp.println("PAUSED");
disp.print("CURRENT TEAM ");
disp.println(current_team);
disp.println(selected_item);
for (int i=0;i<3; i++) {
int color = 3;
if (selected_item==i) {
color = 15;
}
disp.setColor(0);
disp.print(32, 33+ (i*6), items[i]);
disp.setColor(color);
disp.print(32, 32+ (i*6), items[i]);
}
};
};
struct LevelList {
int pos;
int files;
char * fname;
void init() {
pokInitSD();
pos = 0;
files = 0;
fname = getFirstFile("war");
files++;
while(fname!=NULL) {
fname = getNextFile("war");
files++;
}
fname = getFirstFile("war");
};
void update() {
if (btn.pressed(BTN_DOWN)) {
fname = getNextFile("war");
if (fname==NULL) {
fname = getFirstFile("war");
}
}
if (btn.pressed(BTN_A)&&fname!=NULL) {
loadTileMap(fname);
}
};
void draw() {
disp.setFont(font5x7);
disp.bgcolor=0;
disp.clear();
disp.setColor(15);
disp.setCursor(2,2);
disp.print((int)files);
disp.print(" MAPS FOUND");
disp.print(2,SH/2-3, fname);
disp.setFont(fontWAR);
disp.bgcolor = 12;
};
};
#define MENU_STATE_MAIN 0
#define MENU_STATE_LEVEL 1
struct MainMenu {
int state;
struct Transition trans;
char items[3][10];
int selected_item;
int box_x;
int box_target;
MainMenu() {
state = MENU_STATE_MAIN;
box_x = 0;
box_target = 0;
trans.off_val=SH+16;
trans.on_val = SH-12;
trans.val=trans.off_val;
trans.enabled=true;
strcpy(items[0], "CAMPAIGN");
strcpy(items[1], "SKIRMISH");
strcpy(items[2], "OPTIONS");
selected_item = 0;
};
void update(LevelList *l) {
switch (state) {
case MENU_STATE_MAIN:
box_x = lerp(box_x, box_target, 0.50);
trans.update();
if (btn.pressed(BTN_RIGHT)) {
selected_item = min(selected_item + 1, 2);
trans.val=trans.off_val;
}
if (btn.pressed(BTN_LEFT)) {
selected_item = max(selected_item - 1, 0);
trans.val=trans.off_val;
}
if (btn.pressed(BTN_A)) {
switch (selected_item){
case (0): //CAMPAIGN
break;
case (1): //SKIRMISH
disp.clear();
disp.print("LOADING");
pokInitSD();
loadTileMap("file_out.war");
State = MAIN;
break;
case (2): //OPTIONS
state = MENU_STATE_LEVEL;
break;
}
}
break;
case (MENU_STATE_LEVEL):
if (btn.pressed(BTN_B)) {
state = MENU_STATE_MAIN;
}
l->update();
break;
}//SWITCH
};
void draw(LevelList *l) {
switch (state) {
case (MENU_STATE_MAIN):
disp.bgcolor=0;
disp.clear();
disp.setColor(15);
disp.print(2,2,"POKIT WARS");
disp.setColor(15);
disp.print(SW/2-(strlen(items[selected_item])*6/2),trans.val, items[selected_item]);
disp.fillRoundRect(box_x, SH/2, 16, 16,2);
for (int i=0; i<3; i++) {
int x = (SW/4)*(i+1)-8;
int spr = 4+i;
if (i==selected_item) {
box_target = x;
if (box_x-2<x&&box_x+2>x) {
box_x = x;
}
}
disp.drawBitmap(x, SH/2, ui_sprites[spr]);
}
disp.bgcolor=12;
break;
case (MENU_STATE_LEVEL):
l->draw();
break;
}//SWITCH
};
};
int main() {
MainMenu main_menu;
PauseMenu pause_menu;
Transition tTrans(66,96,false);
Transition itemlist(1,-16,false);
game.begin();
game.initClock();
game.initRandom();
game.setFrameRate(30);
disp.invisiblecolor = 12;
disp.bgcolor=12;
disp.persistence = 1;
disp.directbgcolor = disp.palette[0];
disp.directcolor = disp.palette[15];
disp.load565Palette(sprite_pal);
disp.textWrap=false;
init_dark_palette();
disp.setFont(fontWAR);
map_x=0;
map_y=0;
cursor_x=4;
cursor_y=6;
vector<Hero> heros;
hptr = &heros;
pokInitSD();
char dir[3];
strcpy(dir, "War");
LevelList level_menu;
level_menu.init();
bases[0] = Base(2,2,24,TEAM_USER);
bases[1] = Base(10,10,25,TEAM_CPU);
heros.push_back(Hero(4,5,ID_SOLDIER, TEAM_USER));
heros.push_back(Hero(5,6,ID_SNIPER, TEAM_USER));
heros.push_back(Hero(3,8,ID_HEAVY, TEAM_USER));
heros.push_back(Hero(8,5,ID_ORC, TEAM_CPU));
heros.push_back(Hero(8,7,ID_ORC, TEAM_CPU));
heros.push_back(Hero(5,9,ID_ORC, TEAM_CPU));
//Hero * cursor_hero = NULL;
//Hero * current_hero = NULL;
splashScreen(sprites[0],"TRELEMAR", 1000);
while (game.isRunning()) {
if (game.update()) {
switch (State) {
case MENU:
main_menu.update(&level_menu);
main_menu.draw(&level_menu);
break;
case MAIN:
tTrans.update();
itemlist.update();
//If no current hero or current task is to move our current hero, accept cursor movement.
if (!current_hero||current_task==TASK_MOVE||current_task==TASK_ATTACK) {
CursorInput();
cursor_hero = getHeroAtCoords(cursor_x,cursor_y, heros);
}
//This will call when there is a current hero and not in a current task
else if (current_hero) {
//TASK SELECTOR
int dir = 0;
if (btn.pressed(BTN_RIGHT)) {
selected_task=min(selected_task+1,3);
}
if (btn.pressed(BTN_LEFT)) {
selected_task=max(selected_task-1,0);
}
if (selected_task==TASK_ITEM) {
itemlist.enabled = true;
}
else itemlist.enabled = false;
//selected_task=selected_task%4;
}
DrawTileMap(map_x, map_y, current_hero);
for (int i = 0; i<heros.size(); i++) {
heros[i].Draw();
heros[i].update(i);
}
for (int i=0; i<2; i++) {
bases[i].Draw();
}
DrawCursor(cursor_x-map_x,cursor_y-map_y);
disp.setColor(15);
if (btn.pressed(BTN_A)) {
if (current_hero&¤t_task!=TASK_NONE) {
//THIS IS WITHIN A TASK, EX: SELECTING A MOVE LOCATION OR ATTACK TARGET.
switch (current_task) {
case TASK_MOVE:
//MOVE HERO TO CURSOR, NO COLISSIONS YET.
//ONLY IF IN RANGE AND NOT SOLID
//FIX STACKABLE HEROS
if (current_hero->inRange(cursor_x, cursor_y)&&!getHeroAtCoords(cursor_x, cursor_y, heros)&&!solids[Map[cursor_y][cursor_x]]) {
if (cursor_x<current_hero->x) current_hero->flip=true;
else if (cursor_x>current_hero->x) current_hero->flip=false;
current_hero->x = cursor_x;
current_hero->y = cursor_y;
current_task = TASK_NONE;
current_hero->tasks[TASK_MOVE] = false;
}
break;
case TASK_ATTACK:
if (cursor_hero&¤t_hero->inRange(cursor_hero)) {
//FOUND TARGET AT CURSOR.
cursor_x = current_hero->x;
cursor_y = current_hero->y;
int8_t result = cursor_hero->hp - (current_hero->atk-cursor_hero->def);
cursor_hero->hp = result;
cursor_hero->hurt_time=game.frameCount;
if (result<=0) {
heros.erase(heros.begin()+cursor_hero->index);
cursor_hero = NULL;
}
current_task = TASK_NONE;
current_hero->tasks[TASK_ATTACK] = false;
}
else {
//NO TARGET FOUND, ERROR SOUND SHOULD PLAY.
}
break;
//DUMMY CODE, THESE ARE CALLED BELOW. NOT HERE.
case TASK_ITEM:
current_task = TASK_NONE;
current_hero->tasks[TASK_ITEM] = false;
break;
case TASK_WAIT:
current_task = TASK_NONE;
current_hero->tasks[TASK_WAIT] = false;
break;
}
}
else if (current_hero&¤t_hero->tasks[selected_task]==true) {
//TASK SWITCH HERE
//THIS HAPPENS DIRECTLY AFTER PRESSING BTN_A ON A NEW TASK.
current_task=selected_task;
switch (selected_task) {
case TASK_ITEM:
current_task = TASK_NONE;
current_hero->tasks[TASK_ITEM] = false;
break;
case TASK_WAIT:
current_task = TASK_NONE;
current_hero->tasks[TASK_WAIT] = false;
break;
}
}
else if (cursor_hero) {
//NO CURRENT HERO, SELECT A HERO ONLY IF IN CURSOR HERE.
if (cursor_hero->team == current_team) {
current_hero = cursor_hero;
selected_task = TASK_MOVE;
tTrans.enabled = true;
}
}
else if (bases[current_team].x==cursor_x&&bases[current_team].y==cursor_y) {
current_base = &bases[current_team];
tTrans.enabled = true;
}
}
if (btn.pressed(BTN_B)) {
if (current_task!=TASK_NONE) {
//BACK OUT OF CURRENT TASK.
current_task=TASK_NONE;
cursor_x = current_hero->x;
cursor_y = current_hero->y;
}
else if (current_hero&¤t_task==TASK_NONE) {
tTrans.enabled=false; current_hero = NULL; //UNSELECT HERO.
}
else if (current_base&¤t_task==TASK_NONE) {
tTrans.enabled=false; current_base = NULL; //UNSELECT BASE
}
}
if (btn.pressed(BTN_C)&& !current_hero) {
//heros.push_back(Hero(cursor_x,cursor_y,0,0));
//for (int i=0;i<heros.size();i++) heros[i].NewTurn();
State = PAUSE;
//disp.print("PAUSED");
//tTrans.toggle();
}
if (cursor_hero&&cursor_hero!=current_hero&¤t_task) {
DrawCursorHeroUI(cursor_hero, (cursor_hero->x-map_x)*16-4,(cursor_hero->y-map_y)*16-7);
}
if (tTrans.val==tTrans.on_val) {
DrawTraitList(current_hero, itemlist.val);
}
DrawSelectedHeroUI(current_hero, tTrans.val);
if (!current_hero) {
DrawSelectedBaseUI(current_base, tTrans.val);
}
disp.setCursor(0,0);
DrawTurnCounter(heros);
//disp.print(0,32,dtest.text);
//disp.print(1,SH-6,(int)game.battery.level);
//disp.print(" ");
break;
case PAUSE:
pause_menu.update();
pause_menu.draw();
break;
}//GAME STATE SWITCH
}//UPDATE
}//IS RUNNING
return 1;
}
