cake
/
pixeltd
Archived
1
0
Fork 0

RDP version

This commit is contained in:
Thomas Touhey 2020-12-27 00:37:55 +01:00
parent c192ae6e1f
commit cc3c155b64
3 changed files with 209 additions and 29 deletions

BIN
assets-fx/img/menu_bar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
assets-fx/img/numbers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -2,6 +2,7 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/timer.h>
#include <gint/std/stdio.h>
#include <gint/std/stdlib.h>
/* State definition, as used throughout the main game.
@ -17,6 +18,8 @@
* of the path where is at, `substep` is the substep from 0 to 7, looping
* when 8 (augmenting step, except when at the castle).
* - nfwait: number of frames to be waited.
* - lfbase, lf: life base (e.g. lfbase = 10 and lf = 5 for 5/10 as life).
* - bonus: bonus when killed by a turret.
* - pdr: the enemy that spawned previously or is the next further on the
* path. Simple chain list that could evolve later if some enemies are
* slowed down or have various speeds, allowing some enemies to overtake
@ -28,6 +31,8 @@ struct enemy {
int alive;
int nstepf;
int lfbase, lf;
int bonus;
int x, y;
int step, substep;
@ -38,14 +43,24 @@ struct enemy {
/* For each turret, the data is:
*
* - x, y: the coordinates of the turret. */
* - type, amongst:
* 0x01: basic turret.
* 0x02: boom turret.
* - x, y: the coordinates of the turret.
* - rlbase, rl: reload base and current.
* - radius: radius of action, in blocks.
* - dmg: damage done to enemies either targetted or nearby. */
#define NTURRETS 256
struct turret {
int exists;
int type;
int x, y;
int rlbase, rl;
int radius;
int dmg;
};
/* And the main state definition. */
@ -68,11 +83,12 @@ struct state {
* - tbsp: time between enemy spawns.
* - tnsp: time to next spawn (as a number of ticks).
* - nae: number of currently alive enemies.
* - nvc: number of victims.
* - first_enemy: pointer to the last enemy to have spawned,
* to draw first */
int tbsp, tnsp;
int nae;
int nae, nvc;
struct enemy *first_enemy;
struct enemy *enemies;
@ -84,6 +100,14 @@ struct state {
int net;
struct turret *turrets;
/* Player information.
*
* - lf: number of lifes left.
* - money: the money left. */
int lf;
int money;
/* Camera, cursor and display information:
*
* - cur_x, cur_y: map coordinate for the cursor.
@ -131,6 +155,7 @@ static void init(uint8_t const *raw)
state.tbsp = 99;
state.tnsp = state.tbsp;
state.nae = 0;
state.nvc = 0;
state.first_enemy = NULL;
state.enemies = malloc(NENEMIES * sizeof (struct enemy));
@ -147,6 +172,11 @@ static void init(uint8_t const *raw)
for (i = 0; i < NTURRETS; i++)
state.turrets[i].exists = 0;
/* Initialize player information */
state.lf = 10;
state.money = 100;
/* Initialize display information */
state.cur_x = raw[4];
@ -161,7 +191,7 @@ static void deinit()
/* place_turret(): place a turret at the cursor position. */
static void place_turret()
static void place_turret(int type)
{
int i;
struct turret *tp, *ntp = NULL;
@ -186,13 +216,56 @@ static void place_turret()
return ;
}
/* The slot is free, let's go */
if (!ntp)
return ;
/* The slot is free, check that we have the money, deduce
* it and let's go */
{
int price;
if (type == 1)
price = 100;
else
price = 200;
if (state.money < price)
return ;
state.money -= price;
}
ntp->exists = 1;
ntp->type = type;
ntp->x = state.cur_x;
ntp->y = state.cur_y;
ntp->rlbase = type == 1 ? 50 : 90;
ntp->rl = ntp->rlbase;
ntp->radius = 2;
ntp->dmg = type == 1 ? 5 : 3;
}
/* kill(enemy): kill an enemy. */
static void kill(struct enemy *ep, int bonus)
{
ep->alive = 0;
if (ep->ndrp)
(*ep->ndrp) = ep->pdr;
state.nae--;
state.nvc++;
if (bonus)
state.money += ep->bonus;
}
/* damage_on(enemy, amount): make damage on enemies. */
static void damage_on(struct enemy *ep, int amount)
{
ep->lf -= amount;
if (ep->lf <= 0)
kill(ep, 1);
}
/* tick(): tick the game engine. */
@ -227,13 +300,9 @@ static void tick()
ep->substep = 0;
if (ep->step == state.nep) {
ep->alive = 0;
if (ep->ndrp)
(*ep->ndrp) = ep->pdr;
state.nae--;
/* TODO: remove one life to the castle */
kill(ep, 0);
if (state.lf >= 0)
state.lf--;
}
}
}
@ -264,9 +333,86 @@ static void tick()
ep->nstepf = 5;
ep->nfwait = ep->nstepf;
ep->lfbase = 10;
ep->lf = ep->lfbase;
ep->bonus = 5;
state.nae++;
}
}
/* Check the turrets. */
for (i = 0; i < NTURRETS; i++) {
struct turret *tp = &state.turrets[i];
if (!tp->exists)
continue ;
if (tp->rl > 0) {
tp->rl--;
continue ;
}
/* Now: we check if there's an enemy in the radius,
* starting from the earliest spawned.
* If that's the case:
* - if turret type is 1, we damage the targetted enemy.
* - if turret type is 2, we damage every enemy within the
* radius.
*
* The distance is calculated using the centers. */
if (tp->type == 1) {
struct enemy *target = NULL;
int tx = (tp->x << 3) + 4, ty = (tp->y << 3) + 4;
int trs = (tp->radius << 3) * (tp->radius << 3);
for (struct enemy *ep = state.first_enemy; ep; ep = ep->pdr) {
int cx = ep->x + 4, cy = ep->y + 4;
int dxs = cx - tx, dys = cy - ty;
dxs *= dxs;
dys *= dys;
if (dxs + dys <= trs)
target = ep;
}
if (target) {
damage_on(target, tp->dmg);
tp->rl = tp->rlbase;
}
} else if (tp->type == 2) {
int tx = (tp->x << 3) + 4, ty = (tp->y << 3) + 4;
int trs = (tp->radius << 3) * (tp->radius << 3);
for (struct enemy *ep = state.first_enemy; ep; ep = ep->pdr) {
int cx = ep->x + 4, cy = ep->y + 4;
int dxs = cx - tx, dys = cy - ty;
dxs *= dxs;
dys *= dys;
if (dxs + dys <= trs) {
damage_on(ep, tp->dmg);
tp->rl = tp->rlbase;
}
}
}
}
}
/* dnumber(): draw a number on three digits at given position. */
static void dnumber(int x, int y, int number)
{
extern bopti_image_t img_numbers;
char buf[4];
snprintf(buf, 4, "%03d", number < 0 ? 0 : number > 999 ? 999 : number);
drect(x, y, x + 11, y + 3, C_WHITE);
for (int i = 0; i < 3; i++)
dsubimage(x + i * 4, y, &img_numbers, (buf[i] - '0') * 4, 0, 3, 4, 0);
}
/* draw(): basically the drawing function for everything. */
@ -291,7 +437,7 @@ static void draw()
/* Draw the grid. */
for (y = 0; y < 8; y++) {
for (y = 0; y < 6; y++) {
for (x = 0; x < 16; x++) {
int ox = x << 3, oy = y << 3;
int tile = tile_cam(x, y);
@ -327,28 +473,47 @@ static void draw()
}
}
/* Draw the turrets. */
{
struct turret *tp;
extern bopti_image_t img_basic_turret;
extern bopti_image_t img_zone_turret;
int i;
for (i = 0; i < NTURRETS; i++) {
bopti_image_t *tip;
tp = &state.turrets[i];
if (tp->type == 1)
tip = &img_basic_turret;
else
tip = &img_zone_turret;
if (tp->exists)
dimage(x_cam(tp->x << 3), y_cam(tp->y << 3), tip);
}
}
/* Draw the enemies. */
{
struct enemy *ep;
extern bopti_image_t img_enemy;
for (ep = state.first_enemy; ep; ep = ep->pdr)
dimage(x_cam(ep->x), y_cam(ep->y), &img_enemy);
}
for (ep = state.first_enemy; ep; ep = ep->pdr) {
int ox = x_cam(ep->x), oy = y_cam(ep->y);
/* Draw the turrets. */
dimage(ox, oy, &img_enemy);
if (ep->lf < ep->lfbase) {
int lfwidth, spacing = 7;
{
struct turret *tp;
extern bopti_image_t img_basic_turret;
int i;
for (i = 0; i < NTURRETS; i++) {
tp = &state.turrets[i];
if (tp->exists)
dimage(x_cam(tp->x << 3), y_cam(tp->y << 3), &img_basic_turret);
drect_border(ox, oy + spacing, ox + 8, oy + spacing + 2,
C_WHITE, 1, C_BLACK);
lfwidth = ep->lf * 6 / ep->lfbase;
drect(ox + 1, oy + spacing + 1, ox + 1 + lfwidth,
oy + spacing + 1, C_BLACK);
}
}
}
@ -369,6 +534,19 @@ static void draw()
dline(ox + 7, oy + d + 4, ox + 7, oy + d + 5, C_BLACK);
}
/* Draw the menu */
{
extern bopti_image_t img_menu_bar;
dimage(0, 48, &img_menu_bar);
dnumber(94, 50, state.lf);
dnumber(94, 55, state.money);
dnumber(94, 60, 1); /* TODO: round number */
dnumber(113, 50, state.net);
dnumber(113, 55, state.nvc);
}
/* okay we can update now */
dupdate();
@ -456,9 +634,11 @@ menu_t *game(menu_t *last_menu)
if (state.cur_x < state.w - 1)
state.cur_x++;
break;
case KEY_XOT:
place_turret();
case KEY_F1:
place_turret(1);
break;
case KEY_F2:
place_turret(2);
}
break;
}