made stuff for ctf. all editor stuff for it is done. the ctf logic has to be written.

This commit is contained in:
Magnus Auvinen 2007-08-30 07:15:26 +00:00
parent 0e7054a24a
commit c919da6640
8 changed files with 198 additions and 131 deletions

View file

@ -119,5 +119,4 @@ const array:int sound = sounds.*
const array:int image = images.*
const array:int sprite = sprites.*.*
const array:int anim = animations.*
const array:int gametype = playerstats.*
const array:int powerup = powerups.*
const array:int powerup = powerups.*

View file

@ -1,6 +1,5 @@
const array:int sound = sounds.*
const array:int weapon = weapons.*
const array:int gametype = playerstats.*
const array:int powerup = powerups.*
struct weapon {
@ -21,13 +20,7 @@ struct powerupinf {
int startspawntime = startspawntime@1
}
struct playerstats {
int maxhealth = maxhealth@1
int maxarmor = maxarmor@1
}
struct data_container {
array:weapon weapons = weapons.*
array:playerstats playerinfo = playerstats.*
array:powerupinf powerupinfo = powerups.*
}

View file

@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
extern "C" {
#include <engine/system.h>
@ -21,28 +22,31 @@ struct ent_type
{
const char *name;
int id;
int item_id;
int numfields;
int fields[8];
};
static ent_type ent_types[] = {
{"spawn", MAPRES_SPAWNPOINT, 0},
{"spawn_red", MAPRES_SPAWNPOINT_RED, 0},
{"spawn_blue", MAPRES_SPAWNPOINT_BLUE, 0},
{"---", 0, 0},
{"flagstand_red", MAPRES_SPAWNPOINT_RED, 0},
{"flagstand_blue", MAPRES_SPAWNPOINT_BLUE, 0},
{"---", 0, 0},
{"gun", MAPRES_ITEM, ITEM_WEAPON_GUN},
{"shotgun", MAPRES_ITEM, ITEM_WEAPON_SHOTGUN},
{"rocket", MAPRES_ITEM, ITEM_WEAPON_ROCKET},
{"sniper", MAPRES_ITEM, ITEM_WEAPON_SNIPER},
{"hammer", MAPRES_ITEM, ITEM_WEAPON_HAMMER},
{"---", 0, 0},
{"health", MAPRES_ITEM, ITEM_HEALTH},
{"armor", MAPRES_ITEM, ITEM_ARMOR},
{"---", 0, 0},
{"ninja", MAPRES_ITEM, ITEM_NINJA},
{0, 0}
{"null", 0, 0, {0}},
{"---", 0, 0, {0}},
{"spawn", MAPRES_SPAWNPOINT, 0, {0}},
{"spawn_red", MAPRES_SPAWNPOINT_RED, 0, {0}},
{"spawn_blue", MAPRES_SPAWNPOINT_BLUE, 0, {0}},
{"---", 0, 0, {0}},
{"flagstand_red", MAPRES_FLAGSTAND_RED, 0, {0}},
{"flagstand_blue", MAPRES_FLAGSTAND_BLUE, 0, {0}},
{"---", 0, 0, {0}},
{"gun", MAPRES_ITEM, 1, {ITEM_WEAPON_GUN,0}},
{"shotgun", MAPRES_ITEM, 1, {ITEM_WEAPON_SHOTGUN,0}},
{"rocket", MAPRES_ITEM, 1, {ITEM_WEAPON_ROCKET,0}},
{"sniper", MAPRES_ITEM, 1, {ITEM_WEAPON_SNIPER,0}},
{"hammer", MAPRES_ITEM, 1, {ITEM_WEAPON_HAMMER,0}},
{"---", 0, 0, {0}},
{"health", MAPRES_ITEM, 1, {ITEM_HEALTH,0}},
{"armor", MAPRES_ITEM, 1, {ITEM_ARMOR,0}},
{"---", 0, 0, {0}},
{"ninja", MAPRES_ITEM, 1, {ITEM_NINJA,0}},
{0, 0, 0, {0}}
};
@ -904,7 +908,11 @@ static void editor_render()
{
int x = (int)(world_offset_x+400*zoom/2)/32*32+16;
int y = (int)(world_offset_y+300*zoom/2)/32*32+16;
ents_new(0, x, y);
if(editor_selected_ent >= 0 && editor_selected_ent < ents_count())
ents_new(ents_get(editor_selected_ent)->type, x, y);
else
ents_new(0, x, y);
}
y += 8;
@ -955,46 +963,33 @@ int editor_load(const char *filename)
}
// load entities
for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
{
int type = -1;
for(int i = 0; ent_types[i].name; i++)
{
if(ent_types[i].id == MAPRES_SPAWNPOINT)
{
type = i;
break;
}
}
// fetch entities of this class
int start, num;
datafile_get_type(df, MAPRES_SPAWNPOINT, &start, &num);
for(int t = 0; t < num; t++)
datafile_get_type(df, t, &start, &num);
for(int i = 0; i < num; i++)
{
mapres_spawnpoint *sp = (mapres_spawnpoint *)datafile_get_item(df, start+t,0,0);
ents_new(type, sp->x, sp->y);
}
}
{
int start, num;
datafile_get_type(df, MAPRES_ITEM, &start, &num);
for(int t = 0; t < num; t++)
{
mapres_item *it = (mapres_item *)datafile_get_item(df, start+t,0,0);
mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0);
int type = -1;
for(int i = 0; ent_types[i].name; i++)
// map type
int type = 0;
for(int k = 0; ent_types[k].name; k++)
{
if(ent_types[i].id == MAPRES_ITEM && ent_types[i].item_id == it->type)
if(ent_types[k].id == t &&
memcmp(ent_types[k].fields, e->data, ent_types[k].numfields*sizeof(int)) == 0)
{
type = i;
type = k;
break;
}
}
ents_new(type, it->x, it->y);
//dbg_msg("editor", "ent type=%d pos=(%d,%d)", type, e->x, e->y);
ents_new(type, e->x, e->y);
}
}
}
return 1;
}
@ -1056,33 +1051,23 @@ int editor_save(const char *filename)
}
}
// add spawnpoints
for(int i = 0, id = 0; i < ents_count(); i++)
// add entities
for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
{
entity *ent = ents_get(i);
if(ent->type >= 0 && ent_types[ent->type].id == MAPRES_SPAWNPOINT)
int id = 0;
for(int i = 0; i < ents_count(); i++)
{
mapres_spawnpoint sp;
sp.x = ent->x;
sp.y = ent->y;
sp.type = 0;
datafile_add_item(df, MAPRES_SPAWNPOINT, id, sizeof(sp), &sp);
id++;
}
}
// add items
for(int i = 0, id = 0; i < ents_count(); i++)
{
entity *ent = ents_get(i);
if(ent->type >= 0 && ent_types[ent->type].id == MAPRES_ITEM)
{
mapres_item it;
it.x = ent->x;
it.y = ent->y;
it.type = ent_types[ent->type].item_id;
dbg_msg("editor", "i mapped=%d type=%x", ent->type, it.type);
datafile_add_item(df, MAPRES_ITEM, id, sizeof(it), &it);
entity *ent = ents_get(i);
if(ent_types[ent->type].id != t)
continue;
int savebuf[64];
mapres_entity *mapent = (mapres_entity *)savebuf;
mapent->x = ent->x;
mapent->y = ent->y;
dbg_msg("editor", "saving ent idx=%d pos=(%d,%d)", i, ent->x, ent->y);
memcpy(mapent->data, ent_types[ent->type].fields, ent_types[ent->type].numfields*sizeof(int));
datafile_add_item(df, t, id, (ent_types[ent->type].numfields+2)*sizeof(int), mapent);
id++;
}
}
@ -1099,7 +1084,7 @@ static int editor_loop()
int mouse_x = 0;
int mouse_y = 0;
//input::set_mouse_mode(input::mode_relative);
inp_mouse_mode_relative();
while(!(inp_key_pressed(KEY_LCTRL) && inp_key_pressed('Q')))
{
@ -1164,12 +1149,10 @@ static int editor_loop()
gfx_swap();
//
/*
if(inp_key_pressed(KEY_F1))
input::set_mouse_mode(input::mode_absolute);
inp_mouse_mode_absolute();
if(inp_key_pressed(KEY_F2))
input::set_mouse_mode(input::mode_relative);
*/
inp_mouse_mode_relative();
// mode switch
if(inp_key_down(KEY_TAB))

View file

@ -399,6 +399,13 @@ int datafile_add_item(DATAFILE_OUT *df, int type, int id, int size, void *data)
df->items[df->num_items].id = id;
df->items[df->num_items].size = size;
/*
dbg_msg("datafile", "added item type=%d id=%d size=%d", type, id, size);
int i;
for(i = 0; i < size/4; i++)
dbg_msg("datafile", "\t%d: %08x %d", i, ((int*)data)[i], ((int*)data)[i]);
*/
/* copy data */
df->items[df->num_items].data = mem_alloc(size, 1);
mem_copy(df->items[df->num_items].data, data, size);

View file

@ -789,7 +789,7 @@ static void render_flag(const obj_flag *prev, const obj_flag *current)
float size = 64.0f;
gfx_blend_normal();
gfx_texture_set(0);
gfx_texture_set(-1);
gfx_quads_begin();
gfx_quads_setrotation(angle);
@ -805,7 +805,7 @@ static void render_flag(const obj_flag *prev, const obj_flag *current)
0, // starty
1, // endx
1); // endy
gfx_quads_drawTL(pos.x,pos.y,size,size);
gfx_quads_draw(pos.x,pos.y,size,size);
gfx_quads_end();
}
@ -1075,7 +1075,7 @@ static void render_player(const obj_player *prev, const obj_player *player)
if(player->health < 0) // dont render dead players
return;
int skin = gametype == GAMETYPE_TDM ? skinseed + player->team : player->clientid;
int skin = gametype == GAMETYPE_DM ? player->clientid : skinseed + player->team;
vec2 direction = get_direction(player->angle);
float angle = player->angle/256.0f;

View file

@ -27,10 +27,15 @@ inline float get_angle(vec2 dir)
inline bool col_check_point(float x, float y) { return col_check_point((int)x, (int)y) != 0; }
inline bool col_check_point(vec2 p) { return col_check_point(p.x, p.y); }
struct mapres_entity
{
int x, y;
int data[];
};
struct mapres_spawnpoint
{
int x, y;
int type;
};
struct mapres_item
@ -39,14 +44,21 @@ struct mapres_item
int type;
};
struct mapres_flagstand
{
int x, y;
};
enum
{
MAPRES_ENTS_START=1,
MAPRES_SPAWNPOINT=1,
MAPRES_ITEM=2,
MAPRES_SPAWNPOINT_RED=2,
MAPRES_SPAWNPOINT_BLUE=3,
MAPRES_FLAGSTAND_RED=4,
MAPRES_FLAGSTAND_BLUE=5,
MAPRES_SPAWNPOINT_RED=3,
MAPRES_SPAWNPOINT_BLUE=4,
MAPRES_FLAGSTAND_RED=5,
MAPRES_FLAGSTAND_BLUE=6,
MAPRES_ENTS_END,
ITEM_NULL=0,
ITEM_WEAPON_GUN=0x00010001,

View file

@ -409,12 +409,26 @@ game_world world;
gameobject::gameobject()
: entity(OBJTYPE_GAME)
{
gametype = GAMETYPE_DM;
// select gametype
if(strcmp(config.gametype, "ctf") == 0)
{
gametype = GAMETYPE_CTF;
dbg_msg("game", "-- Capture The Flag --");
}
else if(strcmp(config.gametype, "tdm") == 0)
{
gametype = GAMETYPE_TDM;
dbg_msg("game", "-- Team Death Match --");
}
else
{
gametype = GAMETYPE_DM;
dbg_msg("game", "-- Death Match --");
}
//
//
game_over_tick = -1;
sudden_death = 0;
round_start_tick = server_tick();
@ -451,6 +465,10 @@ void gameobject::post_reset()
}
}
void gameobject::tick_ctf()
{
}
void gameobject::tick_dm()
{
if(game_over_tick == -1)
@ -533,6 +551,11 @@ void gameobject::tick()
{
switch(gametype)
{
case GAMETYPE_CTF:
{
tick_ctf();
break;
}
case GAMETYPE_TDM:
{
tick_tdm();
@ -794,19 +817,40 @@ void player::respawn()
spawning = true;
}
void player::try_respawn()
bool try_spawntype(int t, vec2 *pos)
{
// get spawn point
int start, num;
map_get_type(1, &start, &num);
map_get_type(t, &start, &num);
if(!num)
return false;
mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + (rand()%num), NULL, NULL);
*pos = vec2((float)sp->x, (float)sp->y);
return true;
}
void player::try_respawn()
{
vec2 spawnpos = vec2(100.0f, -60.0f);
if(num)
{
mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + (rand()%num), NULL, NULL);
spawnpos = vec2((float)sp->x, (float)sp->y);
}
// get spawn point
if(gameobj->gametype == GAMETYPE_CTF)
{
// try first try own team spawn, then normal spawn and then enemy
if(!try_spawntype(MAPRES_SPAWNPOINT_RED+(team&1), &spawnpos))
{
if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos))
try_spawntype(MAPRES_SPAWNPOINT_RED+((team+1)&1), &spawnpos);
}
}
else
{
if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos))
try_spawntype(MAPRES_SPAWNPOINT_RED+(rand()&1), &spawnpos);
}
// check if the position is occupado
entity *ents[2] = {0};
int types[] = {OBJTYPE_PLAYER};
@ -822,7 +866,7 @@ void player::try_respawn()
defered_pos = pos;
health = data->playerinfo[gameobj->gametype].maxhealth;
health = 10;
armor = 0;
jumped = 0;
dead = false;
@ -1642,18 +1686,18 @@ void powerup::tick()
switch (type)
{
case POWERUP_HEALTH:
if(pplayer->health < data->playerinfo[gameobj->gametype].maxhealth)
if(pplayer->health < 10)
{
create_sound(pos, SOUND_PICKUP_HEALTH, 0);
pplayer->health = min((int)data->playerinfo[gameobj->gametype].maxhealth, pplayer->health + data->powerupinfo[type].amount);
pplayer->health = min(10, pplayer->health + data->powerupinfo[type].amount);
respawntime = data->powerupinfo[type].respawntime;
}
break;
case POWERUP_ARMOR:
if(pplayer->armor < data->playerinfo[gameobj->gametype].maxarmor)
if(pplayer->armor < 10)
{
create_sound(pos, SOUND_PICKUP_ARMOR, 0);
pplayer->armor = min((int)data->playerinfo[gameobj->gametype].maxarmor, pplayer->armor + data->powerupinfo[type].amount);
pplayer->armor = min(10, pplayer->armor + data->powerupinfo[type].amount);
respawntime = data->powerupinfo[type].respawntime;
}
break;
@ -1753,6 +1797,8 @@ void flag::reset()
void flag::tick()
{
// THIS CODE NEEDS TO BE REWRITTEN. ITS NOT SAVE AT ALL
// wait for respawn
if(spawntick > 0)
{
@ -1763,17 +1809,34 @@ void flag::tick()
}
// Check if a player intersected us
vec2 meh;
player* pplayer = intersect_player(pos, pos + vel, meh, 0);
if (pplayer)
if(!carrying_player)
{
if (!carrying_player)
carrying_player = pplayer;
player *players[MAX_CLIENTS];
int types[] = {OBJTYPE_PLAYER};
int num = world.find_entities(pos, 32.0f, (entity**)players, MAX_CLIENTS, types, 1);
for(int i = 0; i < num; i++)
{
if(players[i]->team != team)
{
carrying_player = players[i];
break;
}
}
if(!carrying_player)
{
vel.y += 0.25f;
vec2 new_pos = pos + vel;
// TODO: something..?
col_intersect_line(pos, new_pos, &new_pos);
pos = new_pos;
if (is_grounded())
vel.x = vel.y = 0;
}
}
if (carrying_player)
else
{
if (carrying_player->dead)
carrying_player = 0x0;
@ -1783,19 +1846,6 @@ void flag::tick()
pos = carrying_player->pos;
}
}
if (!carrying_player)
{
vel.y += 0.25f;
vec2 new_pos = pos + vel;
col_intersect_line(pos, new_pos, &new_pos);
pos = new_pos;
if (is_grounded())
vel.x = vel.y = 0;
}
}
bool flag::is_grounded()
@ -1973,6 +2023,8 @@ void mods_tick()
{
mods_client_enter(MAX_CLIENTS-i-1);
strcpy(players[MAX_CLIENTS-i-1].name, "(bot)");
if(gameobj->gametype != GAMETYPE_DM)
players[MAX_CLIENTS-i-1].team = count&1;
}
count = -1;
}
@ -2189,6 +2241,23 @@ void mods_init()
}
}
if(gameobj->gametype == GAMETYPE_CTF)
{
// fetch flagstands
for(int i = 0; i < 2; i++)
{
mapres_flagstand *stand;
stand = (mapres_flagstand *)map_find_item(MAPRES_FLAGSTAND_RED+i, 0);
if(stand)
gameobj->flagsstands[i] = vec2(stand->x, stand->y);
flag *f = new flag(i);
f->pos = gameobj->flagsstands[i];
//world.insert_entity(f);
dbg_msg("game", "flag at %f,%f", f->pos.x, f->pos.y);
}
}
world.insert_entity(gameobj);
}

View file

@ -112,12 +112,16 @@ class gameobject : public entity
int sudden_death;
public:
class flag *flags[2];
vec2 flagsstands[2];
int gametype;
gameobject();
virtual void post_reset();
virtual void tick();
virtual void tick_dm();
virtual void tick_tdm();
virtual void tick_ctf();
virtual void snap(int snapping_client);
virtual int getteam(int notthisid);
};