mirror of
https://github.com/Valeh2012/PersonalVotingMachine
synced 2024-11-26 10:51:00 +02:00
259 lines
4.3 KiB
C
259 lines
4.3 KiB
C
/*
|
|
|
|
item.c
|
|
|
|
during level setup, the item pool is filled with items from the
|
|
onmap list.
|
|
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include "ugl_bc.h"
|
|
#include "item.h"
|
|
#include "map.h"
|
|
|
|
/* max number of items in the pool */
|
|
#define ITEM_MAX 32
|
|
|
|
/* current number of items in the pool */
|
|
uint8_t item_cnt;
|
|
|
|
/* current level */
|
|
uint8_t current_level;
|
|
|
|
/* the pool with all dynamic created items */
|
|
item_t item_pool[ITEM_MAX];
|
|
|
|
item_t *item_under_pos; /* set by getMapTile() */
|
|
|
|
bc_t bc;
|
|
|
|
|
|
/*===============================================*/
|
|
|
|
|
|
void execute(uint16_t pos)
|
|
{
|
|
bc_exec(&bc, map_code, pos);
|
|
}
|
|
|
|
/*===============================================*/
|
|
|
|
void posStep(pos_t *pos, uint8_t dir)
|
|
{
|
|
switch( dir )
|
|
{
|
|
case 0:
|
|
pos->x+=1;
|
|
break;
|
|
case 1:
|
|
pos->y+=1;
|
|
break;
|
|
case 2:
|
|
pos->x-=1;
|
|
break;
|
|
case 3:
|
|
pos->y-=1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*===============================================*/
|
|
|
|
|
|
void pool_Clear(void)
|
|
{
|
|
item_cnt = 0;
|
|
}
|
|
|
|
uint8_t pool_NewItem(void)
|
|
{
|
|
if ( item_cnt >= ITEM_MAX )
|
|
return ITEM_MAX;
|
|
item_pool[item_cnt].dir = 4; /* no move */
|
|
item_cnt++;
|
|
return item_cnt-1;
|
|
}
|
|
|
|
item_t *pool_GetItem(uint8_t idx)
|
|
{
|
|
return item_pool+idx;
|
|
}
|
|
|
|
/*
|
|
Based on the dir attribute, all items, including hero are moved
|
|
*/
|
|
void moveAllItems(void)
|
|
{
|
|
uint8_t i;
|
|
item_t *item;
|
|
i = item_cnt;
|
|
item = item_pool;
|
|
do
|
|
{
|
|
posStep(&(item->pos), item->dir);
|
|
item->dir = 4; /* no move */
|
|
item++;
|
|
i--;
|
|
} while( i != 0);
|
|
}
|
|
|
|
void callStepAllItems(void)
|
|
{
|
|
uint8_t i;
|
|
item_t *item;
|
|
i = item_cnt;
|
|
item = item_pool;
|
|
do
|
|
{
|
|
execute(item_template_list[item->template_index].step_proc);
|
|
|
|
item++;
|
|
i--;
|
|
} while( i != 0);
|
|
}
|
|
|
|
|
|
/*===============================================*/
|
|
|
|
|
|
|
|
/*
|
|
void item_SetDefaultTile(uint8_t idx)
|
|
{
|
|
item_t *item = pool_GetItem((idx);
|
|
|
|
item->tile = item_template_list[item->template_index].fg_tile;
|
|
}
|
|
*/
|
|
|
|
|
|
/*===============================================*/
|
|
|
|
void setupLevel(uint8_t level)
|
|
{
|
|
uint8_t i, cnt;
|
|
item_t *item;
|
|
item_onmap_t *onmap_ptr;
|
|
current_level = level;
|
|
|
|
cnt = map_list[level].onmap_cnt;
|
|
|
|
/* build the pool */
|
|
pool_Clear();
|
|
|
|
/* first item always is our hero (index 0) */
|
|
item = pool_GetItem(pool_NewItem());
|
|
item->pos.x = 0;
|
|
item->pos.y = 0;
|
|
item->tile = 0x04e;
|
|
item->template_index = 0; /* not used, but still template index should be reserverd then */
|
|
|
|
onmap_ptr = map_list[level].onmap_list;
|
|
for( i = 0; i < cnt; i++ )
|
|
{
|
|
/* no check of pool_NewItem() here, this should always succeed */
|
|
item = pool_GetItem(pool_NewItem());
|
|
item->pos.x = onmap_ptr->x;
|
|
item->pos.y = onmap_ptr->y;
|
|
item->template_index = onmap_ptr->template_index;
|
|
item->tile = item_template_list[item->template_index].fg_tile;
|
|
onmap_ptr++;
|
|
}
|
|
|
|
execute(map_list[level].init_proc);
|
|
|
|
}
|
|
|
|
/*
|
|
return a tile on the map.
|
|
as a side effect,
|
|
item_under_pos
|
|
is set if the tile is from an item. Otherwise item_under_pos is set to NULL
|
|
*/
|
|
uint8_t getMapTile(uint8_t x, uint8_t y)
|
|
{
|
|
item_t *item;
|
|
uint16_t offset;
|
|
uint8_t i, cnt;
|
|
|
|
cnt = item_cnt;
|
|
for( i = 0; i < cnt; i++ )
|
|
{
|
|
item = pool_GetItem(i);
|
|
if ( item->pos.x == x && item->pos.y == y )
|
|
{
|
|
return item->tile;
|
|
item_under_pos = item;
|
|
}
|
|
}
|
|
|
|
item_under_pos = NULL;
|
|
|
|
offset = y;
|
|
offset *= map_list[current_level].width;
|
|
offset += x;
|
|
|
|
return map_list[current_level].data[offset];
|
|
}
|
|
|
|
/*
|
|
sideeffect: will set item_under_pos
|
|
*/
|
|
uint8_t getMapTileByPos(pos_t *pos)
|
|
{
|
|
return getMapTile(pos->x, pos->y);
|
|
}
|
|
|
|
/*
|
|
Check whether a tile is solid by definition.
|
|
The case, when hitting a tile and it became wakable (because it disapears
|
|
or moves away) is not considered.
|
|
*/
|
|
uint8_t isSolidTile(uint8_t tile)
|
|
{
|
|
if ( tile >= 0x07d && tile <= 0x088 )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
sideeffect: will set item_under_pos
|
|
*/
|
|
uint8_t canWalkTo(pos_t *pos)
|
|
{
|
|
uint8_t tile;
|
|
tile = getMapTileByPos(pos);
|
|
/*
|
|
if ( item_under_pos != NULL )
|
|
...
|
|
*/
|
|
if ( isSolidTile(tile) != 0 )
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*
|
|
0: not moved
|
|
1: moved
|
|
sideeffect: will set item_under_pos
|
|
*/
|
|
uint8_t moveItem(uint8_t item_index, uint8_t dir)
|
|
{
|
|
item_t *item;
|
|
pos_t pos;
|
|
item = pool_GetItem(item_index);
|
|
pos = item->pos;
|
|
posStep(&pos, dir);
|
|
if ( canWalkTo(&pos) != 0 )
|
|
{
|
|
item->dir = dir;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|