+#include "nmm.qh"
+REGISTER_MINIGAME(nmm, "Nine Men's Morris");
+
const int NMM_TURN_PLACE = 0x0100; // player has to place a piece on the board
const int NMM_TURN_MOVE = 0x0200; // player has to move a piece by one tile
const int NMM_TURN_FLY = 0x0400; // player has to move a piece anywhere
// Create an new tile
// \param id Tile index (eg: a1)
-// \param minig Owner minigame instance
+// \param minig Owner minigame instance
// \param distance Distance from adjacent tiles
void nmm_spawn_tile(string id, entity minig, int distance)
{
// TODO global variable + list_next for simpler tile loops
- entity e = spawn();
+ entity e = new(minigame_nmm_tile);
e.origin = minigame_tile_pos(id,7,7);
- e.classname = "minigame_nmm_tile";
e.netname = id;
e.owner = minig;
e.team = 0;
}
// Create a tile square and recursively create inner squares
-// \param minig Owner minigame instance
+// \param minig Owner minigame instance
// \param offset Index offset (eg: 1 to start the square at b2, 0 at a1 etc.)
// \param skip Number of indices to skip between tiles (eg 1: a1, a3)
void nmm_spawn_tile_square( entity minig, int offset, int skip )
}
letter += skip+1;
}
-
+
if ( skip > 0 )
nmm_spawn_tile_square(minig,offset+1,skip-1);
}
// Remove tiles of a NMM minigame
void nmm_kill_tiles(entity minig)
{
- entity e = world;
+ entity e = NULL;
while ( ( e = findentity(e,owner,minig) ) )
if ( e.classname == "minigame_nmm_tile" )
{
strunzone(e.netname);
strunzone(e.nmm_tile_hmill);
strunzone(e.nmm_tile_vmill);
- remove(e);
+ delete(e);
}
}
// Find a tile by its id
entity nmm_find_tile(entity minig, string id)
{
- entity e = world;
+ entity e = NULL;
while ( ( e = findentity(e,owner,minig) ) )
if ( e.classname == "minigame_nmm_tile" && e.netname == id )
return e;
- return world;
+ return NULL;
}
// Check whether two tiles are adjacent
bool nmm_tile_adjacent(entity tile1, entity tile2)
{
-
+
int dnumber = fabs ( minigame_tile_number(tile1.netname) - minigame_tile_number(tile2.netname) );
int dletter = fabs ( minigame_tile_letter(tile1.netname) - minigame_tile_letter(tile2.netname) );
-
+
return ( dnumber == 0 && ( dletter == 1 || dletter == tile1.nmm_tile_distance ) ) ||
( dletter == 0 && ( dnumber == 1 || dnumber == tile1.nmm_tile_distance ) );
}
// Returns 1 if there is at least 1 free adjacent tile
bool nmm_tile_canmove(entity tile)
{
- entity e = world;
+ entity e = NULL;
while ( ( e = findentity(e,owner,tile.owner) ) )
- if ( e.classname == "minigame_nmm_tile" && !e.nmm_tile_piece
+ if ( e.classname == "minigame_nmm_tile" && !e.nmm_tile_piece
&& nmm_tile_adjacent(e,tile) )
{
return true;
// Check if a tile is in a mill
bool nmm_in_mill(entity tile)
{
- return tile.nmm_tile_piece && (
+ return tile.nmm_tile_piece && (
nmm_in_mill_string(tile,tile.nmm_tile_hmill) ||
nmm_in_mill_string(tile,tile.nmm_tile_vmill) );
}
{
entity e = start;
while ( ( e = findentity(e,owner,minigame) ) )
- if ( e.classname == "minigame_board_piece" &&
+ if ( e.classname == "minigame_board_piece" &&
(e.minigame_flags & pieceflags) && e.team == teamn )
return e;
- return world;
+ return NULL;
}
// Count NMM pieces matching flags and team number
int nmm_count_pieces(entity minigame, int teamn, int pieceflags)
{
int n = 0;
- entity e = world;
+ entity e = NULL;
while (( e = nmm_find_piece(e,minigame, teamn, pieceflags) ))
n++;
return n;
e.team = 2;
e.minigame_flags = NMM_PIECE_HOME;
}
-
+
return 1;
}
else if ( event == "end" )
{
entity e = ...(0,entity);
int argc = ...(1,int);
- entity tile = world;
- entity piece = world;
+ entity tile = NULL;
+ entity piece = NULL;
bool move_ok = false;
-
- if ( e && argc >= 2 && argv(0) == "move" &&
+
+ if ( e && argc >= 2 && argv(0) == "move" &&
( minigame.minigame_flags & NMM_TURN_TEAM ) == e.team )
{
tile = nmm_find_tile(minigame,argv(1));
}
else if ( minigame.minigame_flags & NMM_TURN_PLACE )
{
- piece = nmm_find_piece(world,minigame,e.team,NMM_PIECE_HOME);
+ piece = nmm_find_piece(NULL,minigame,e.team,NMM_PIECE_HOME);
if ( !tile.nmm_tile_piece && piece )
{
tile.nmm_tile_piece = piece;
entity tile2 = nmm_find_tile(minigame,argv(2));
if ( tile2 && nmm_tile_adjacent(tile,tile2) && !tile2.nmm_tile_piece )
{
- tile.nmm_tile_piece = world;
+ tile.nmm_tile_piece = NULL;
tile2.nmm_tile_piece = piece;
piece.origin = tile2.origin;
piece.SendFlags |= MINIG_SF_UPDATE;
move_ok = true;
}
}
-
+
}
else if ( minigame.minigame_flags & NMM_TURN_FLY )
{
entity tile2 = nmm_find_tile(minigame,argv(2));
if ( tile2 && !tile2.nmm_tile_piece )
{
- tile.nmm_tile_piece = world;
+ tile.nmm_tile_piece = NULL;
tile2.nmm_tile_piece = piece;
piece.origin = tile2.origin;
piece.SendFlags |= MINIG_SF_UPDATE;
move_ok = true;
}
}
-
+
}
else if ( minigame.minigame_flags & NMM_TURN_TAKE )
{
piece = tile.nmm_tile_piece;
if ( piece && piece.nmm_tile_piece.team != e.team )
{
- tile.nmm_tile_piece = world;
+ tile.nmm_tile_piece = NULL;
piece.minigame_flags = NMM_PIECE_DEAD;
piece.SendFlags |= MINIG_SF_UPDATE;
move_ok = true;
}
}
-
+
int nextteam = e.team % 2 + 1;
int npieces = nmm_count_pieces(minigame,nextteam,NMM_PIECE_HOME|NMM_PIECE_BOARD);
-
+
if ( npieces < 3 )
{
minigame.minigame_flags = NMM_TURN_WIN | e.team;
{
minigame.minigame_flags = NMM_TURN_TAKE|e.team;
int takemill = NMM_TURN_TAKEANY;
- entity f = world;
+ entity f = NULL;
while ( ( f = findentity(f,owner,minigame) ) )
if ( f.classname == "minigame_nmm_tile" && f.nmm_tile_piece &&
f.nmm_tile_piece.team == nextteam && !nmm_in_mill(f) )
}
else
{
- if ( nmm_find_piece(world,minigame,nextteam,NMM_PIECE_HOME) )
+ if ( nmm_find_piece(NULL,minigame,nextteam,NMM_PIECE_HOME) )
minigame.minigame_flags = NMM_TURN_PLACE|nextteam;
else if ( npieces == 3 )
minigame.minigame_flags = NMM_TURN_FLY|nextteam;
else
{
minigame.minigame_flags = NMM_TURN_WIN|e.team;
- entity f = world;
+ entity f = NULL;
while ( ( f = findentity(f,owner,minigame) ) )
if ( f.classname == "minigame_nmm_tile" && f.nmm_tile_piece &&
f.nmm_tile_piece.team == nextteam && nmm_tile_canmove(f) )
minigame.SendFlags |= MINIG_SF_UPDATE;
}
else
- dprint("Invalid move: ",...(2,string),"\n");
+ LOG_TRACE("Invalid move: ", ...(2, string));
return 1;
}
}
nmm_boardpos = pos;
nmm_boardsize = mySize;
minigame_hud_simpleboard(pos,mySize,minigame_texture("nmm/board"));
-
+
vector tile_size = minigame_hud_denormalize_size('1 1 0'/7,pos,mySize);
vector tile_pos;
entity e;
if ( e.classname == "minigame_nmm_tile" )
{
tile_pos = minigame_hud_denormalize(e.origin,pos,mySize);
-
+
if ( e == nmm_fromtile )
{
minigame_drawpic_centered( tile_pos, minigame_texture("nmm/tile_active"),
minigame_drawpic_centered( tile_pos, minigame_texture("nmm/tile_available"),
tile_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
}
-
+
if ( e == nmm_currtile )
{
minigame_drawpic_centered( tile_pos, minigame_texture("nmm/tile_selected"),
tile_size, '1 1 1', panel_fg_alpha, DRAWFLAG_ADDITIVE );
}
-
+
if ( e.nmm_tile_piece )
{
- minigame_drawpic_centered( tile_pos,
+ minigame_drawpic_centered( tile_pos,
minigame_texture(strcat("nmm/piece",ftos(e.nmm_tile_piece.team))),
tile_size*0.8, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
}
-
+
//drawstring(tile_pos, e.netname, hud_fontsize, '1 0 0', 1, DRAWFLAG_NORMAL);
}
}
-
+
if ( active_minigame.minigame_flags & NMM_TURN_WIN )
{
vector winfs = hud_fontsize*2;
string playername = "";
FOREACH_MINIGAME_ENTITY(e)
- if ( e.classname == "minigame_player" &&
+ if ( e.classname == "minigame_player" &&
e.team == (active_minigame.minigame_flags & NMM_TURN_TEAM) )
- playername = GetPlayerName(e.minigame_playerslot-1);
-
+ playername = entcs_GetName(e.minigame_playerslot-1);
+
vector win_pos = pos+eY*(mySize_y-winfs_y)/2;
vector win_sz;
win_sz = minigame_drawcolorcodedstring_wrapped(mySize_x,win_pos,
- sprintf("%s^7 won the game!",playername),
+ sprintf("%s^7 won the game!",playername),
winfs, 0, DRAWFLAG_NORMAL, 0.5);
-
+
drawfill(win_pos-eY*hud_fontsize_y,win_sz+2*eY*hud_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
-
+
minigame_drawcolorcodedstring_wrapped(mySize_x,win_pos,
- sprintf("%s^7 won the game!",playername),
+ sprintf("%s^7 won the game!",playername),
winfs, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5);
}
}
// Required function, draw the game status panel
void nmm_hud_status(vector pos, vector mySize)
{
- HUD_Panel_DrawBg(1);
+ HUD_Panel_DrawBg();
vector ts;
-
ts = minigame_drawstring_wrapped(mySize_x,pos,active_minigame.descriptor.message,
hud_fontsize * 2, '0.25 0.47 0.72', panel_fg_alpha, DRAWFLAG_NORMAL,0.5);
pos_y += ts_y;
mySize_y -= ts_y;
-
+
vector player_fontsize = hud_fontsize * 1.75;
ts_y = ( mySize_y - 2*player_fontsize_y ) / 2;
ts_x = mySize_x;
-
+
float player1x = 0;
float player2x = 0;
vector piece_sz = '48 48 0';
float piece_space = piece_sz_x + ( ts_x - 7 * piece_sz_x ) / 6;
vector mypos;
float piece_light = 1;
- entity e = world;
-
+ entity e = NULL;
+
mypos = pos;
if ( (active_minigame.minigame_flags&NMM_TURN_TEAM) == 2 )
mypos_y += player_fontsize_y + ts_y;
drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
mypos_y += player_fontsize_y;
drawfill(mypos,eX*mySize_x+eY*piece_sz_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
-
+
FOREACH_MINIGAME_ENTITY(e)
{
if ( e.classname == "minigame_player" )
if ( e.team == 2 )
mypos_y += player_fontsize_y + ts_y;
minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
- GetPlayerName(e.minigame_playerslot-1),
+ entcs_GetName(e.minigame_playerslot-1),
player_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
}
else if ( e.classname == "minigame_board_piece" )
piece_light = 1;
else
piece_light = 0.15;
-
+
drawpic(mypos, minigame_texture(strcat("nmm/piece",ftos(e.team))), piece_sz,
'1 1 1'*piece_light, panel_fg_alpha, DRAWFLAG_NORMAL );
}
if ( minigame.minigame_flags & (NMM_TURN_PLACE|NMM_TURN_TAKE) )
{
minigame_cmd("move ",nmm_currtile.netname);
- nmm_fromtile = world;
+ nmm_fromtile = NULL;
}
else if ( (minigame.minigame_flags & (NMM_TURN_MOVE|NMM_TURN_FLY)) )
{
if ( nmm_fromtile == nmm_currtile )
{
- nmm_fromtile = world;
+ nmm_fromtile = NULL;
}
else if ( nmm_currtile.nmm_tile_piece && nmm_currtile.nmm_tile_piece.team == minigame_self.team )
{
else if ( nmm_fromtile )
{
minigame_cmd("move ",nmm_fromtile.netname," ",nmm_currtile.netname);
- nmm_fromtile = world;
+ nmm_fromtile = NULL;
}
}
}
else
- nmm_fromtile = world;
+ nmm_fromtile = NULL;
}
string nmm_turn_to_string(int turnflags)
return _("You lost the game!");
return _("You win!");
}
-
+
if ( (turnflags&NMM_TURN_TEAM) != minigame_self.team )
return _("Wait for your opponent to make their move");
if ( turnflags & NMM_TURN_PLACE )
return _("You can select one of your pieces to move it anywhere on the board");
if ( turnflags & NMM_TURN_TAKE )
return _("You can take one of the opponent's pieces");
-
+
return "";
}
{
if ( event == "activate" )
{
- nmm_fromtile = world;
+ nmm_fromtile = NULL;
nmm_init_tiles(minigame);
minigame.message = nmm_turn_to_string(minigame.minigame_flags);
}
else if ( event == "deactivate" )
{
- nmm_fromtile = world;
+ nmm_fromtile = NULL;
nmm_kill_tiles(minigame);
}
else if ( event == "key_pressed" && (minigame.minigame_flags&NMM_TURN_TEAM) == minigame_self.team )
else
{
string tileid = nmm_currtile.netname;
- nmm_currtile = world;
+ nmm_currtile = NULL;
while ( !nmm_currtile )
{
tileid = minigame_relative_tile(tileid,1,0,7,7);
else
{
string tileid = nmm_currtile.netname;
- nmm_currtile = world;
+ nmm_currtile = NULL;
while ( !nmm_currtile )
{
tileid = minigame_relative_tile(tileid,-1,0,7,7);
else
{
string tileid = nmm_currtile.netname;
- nmm_currtile = world;
+ nmm_currtile = NULL;
while ( !nmm_currtile )
{
tileid = minigame_relative_tile(tileid,0,1,7,7);
else
{
string tileid = nmm_currtile.netname;
- nmm_currtile = world;
+ nmm_currtile = NULL;
while ( !nmm_currtile )
{
tileid = minigame_relative_tile(tileid,0,-1,7,7);
}
else if ( event == "mouse_moved" )
{
- nmm_currtile = world;
+ nmm_currtile = NULL;
vector tile_pos;
vector tile_size = minigame_hud_denormalize_size('1 1 0'/7,nmm_boardpos,nmm_boardsize);
entity e;
}
else if ( event == "network_receive" )
{
- if ( self.classname == "minigame_board_piece" && ( ...(1,int) & MINIG_SF_UPDATE ) )
+ entity sent = ...(0,entity);
+
+ if ( sent.classname == "minigame_board_piece" && ( ...(1,int) & MINIG_SF_UPDATE ) )
{
entity e;
string tileid = "";
- if ( self.minigame_flags & NMM_PIECE_BOARD )
- tileid = minigame_tile_name(self.origin,7,7);
+ if ( sent.minigame_flags & NMM_PIECE_BOARD )
+ tileid = minigame_tile_name(sent.origin,7,7);
FOREACH_MINIGAME_ENTITY(e)
{
if ( e.classname == "minigame_nmm_tile" )
{
- if ( e.nmm_tile_piece == self )
- e.nmm_tile_piece = world;
+ if ( e.nmm_tile_piece == sent )
+ e.nmm_tile_piece = NULL;
if ( e.netname == tileid )
- e.nmm_tile_piece = self;
+ e.nmm_tile_piece = sent;
}
}
}
- else if ( self.classname == "minigame" && ( ...(1,int) & MINIG_SF_UPDATE ) )
+ else if ( sent.classname == "minigame" && ( ...(1,int) & MINIG_SF_UPDATE ) )
{
- self.message = nmm_turn_to_string(self.minigame_flags);
- if ( self.minigame_flags & minigame_self.team )
+ sent.message = nmm_turn_to_string(sent.minigame_flags);
+ if ( sent.minigame_flags & minigame_self.team )
minigame_prompt();
}
}
-
+
return 0;
}
-#endif
+#endif