Undead: you can now mark clues as done

This commit is contained in:
Kevin Lyles
2015-05-25 19:46:24 -05:00
committed by Simon Tatham
parent c3285318e6
commit f0750894ff
3 changed files with 73 additions and 1 deletions

View File

@ -17,3 +17,6 @@ press Backspace.
Right-click in a square and then type a letter to add or remove the
monster as a pencil mark, indicating monsters that you think
<em>might</em> go in that square.
<p>
Left-click on a clue to mark it as done (grey it out). To unmark a
clue as done, left-click on it again.

View File

@ -3054,6 +3054,9 @@ If you prefer plain letters of the alphabet to cute monster pictures,
you can press \q{A} to toggle between showing the monsters as monsters or
showing them as letters.
Left-clicking a clue will mark it as done (grey it out), or unmark it
if it is already marked.
(All the actions described in \k{common-actions} are also available.)
\H{undead-parameters} \I{parameters, for Undead}Undead parameters

View File

@ -49,6 +49,7 @@ enum {
COL_GHOST,
COL_ZOMBIE,
COL_VAMPIRE,
COL_DONE,
NCOLOURS
};
@ -237,6 +238,7 @@ struct game_state {
unsigned char *pencils;
unsigned char *cell_errors;
unsigned char *hint_errors;
unsigned char *hints_done;
unsigned char count_errors[3];
int solved;
int cheated;
@ -289,6 +291,9 @@ static game_state *new_state(const game_params *params) {
state->hint_errors = snewn(2*state->common->num_paths, unsigned char);
for (i=0;i<2*state->common->num_paths;i++)
state->hint_errors[i] = FALSE;
state->hints_done = snewn(2 * state->common->num_paths, unsigned char);
memset(state->hints_done, 0,
2 * state->common->num_paths * sizeof(unsigned char));
for (i=0;i<3;i++)
state->count_errors[i] = FALSE;
@ -332,6 +337,13 @@ static game_state *dup_game(const game_state *state)
}
else ret->hint_errors = NULL;
if (state->hints_done != NULL) {
ret->hints_done = snewn(2 * state->common->num_paths, unsigned char);
memcpy(ret->hints_done, state->hints_done,
2 * state->common->num_paths * sizeof(unsigned char));
}
else ret->hints_done = NULL;
ret->count_errors[0] = state->count_errors[0];
ret->count_errors[1] = state->count_errors[1];
ret->count_errors[2] = state->count_errors[2];
@ -358,6 +370,7 @@ static void free_game(game_state *state) {
if (state->common->fixed != NULL) sfree(state->common->fixed);
sfree(state->common);
}
if (state->hints_done != NULL) sfree(state->hints_done);
if (state->hint_errors != NULL) sfree(state->hint_errors);
if (state->cell_errors != NULL) sfree(state->cell_errors);
if (state->pencils != NULL) sfree(state->pencils);
@ -1662,12 +1675,40 @@ struct game_drawstate {
unsigned char count_errors[3];
unsigned char *cell_errors;
unsigned char *hint_errors;
unsigned char *hints_done;
int hx, hy, hshow, hpencil; /* as for game_ui. */
int hflash;
int ascii;
};
static int is_clue(const game_state *state, int x, int y)
{
int h = state->common->params.h, w = state->common->params.w;
if (((x == 0 || x == w + 1) && y > 0 && y <= h) ||
((y == 0 || y == h + 1) && x > 0 && x <= w))
return TRUE;
return FALSE;
}
static int clue_index(const game_state *state, int x, int y)
{
int h = state->common->params.h, w = state->common->params.w;
if (y == 0)
return x - 1;
else if (x == w + 1)
return w + y - 1;
else if (y == h + 1)
return 2 * w + h - x;
else if (x == 0)
return 2 * (w + h) - y;
return -1;
}
#define TILESIZE (ds->tilesize)
#define BORDER (TILESIZE/4)
@ -1818,6 +1859,11 @@ static char *interpret_move(const game_state *state, game_ui *ui,
}
}
}
} else if (button == LEFT_BUTTON) {
if (is_clue(state, gx, gy)) {
sprintf(buf, "D%d,%d", gx, gy);
return dupstr(buf);
}
}
return NULL;
@ -1942,7 +1988,7 @@ int check_path_solution(game_state *state, int p) {
static game_state *execute_move(const game_state *state, const char *move)
{
int x,n,p,i;
int x,y,n,p,i;
char c;
int correct;
int solver;
@ -1969,6 +2015,11 @@ static game_state *execute_move(const game_state *state, const char *move)
if (c == 'z') ret->pencils[x] ^= 4;
move += n;
}
if (c == 'D' && sscanf(move + 1, "%d,%d%n", &x, &y, &n) == 2 &&
is_clue(ret, x, y)) {
ret->hints_done[clue_index(ret, x, y)] ^= 1;
move += n + 1;
}
if (*move == ';') move++;
}
@ -2058,6 +2109,10 @@ static float *game_colours(frontend *fe, int *ncolours)
ret[COL_VAMPIRE * 3 + 1] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
ret[COL_VAMPIRE * 3 + 2] = ret[COL_BACKGROUND * 3 + 0] * 0.9F;
ret[COL_DONE * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] / 1.5F;
ret[COL_DONE * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] / 1.5F;
ret[COL_DONE * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] / 1.5F;
*ncolours = NCOLOURS;
return ret;
}
@ -2090,6 +2145,9 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
ds->hint_errors = snewn(2*state->common->num_paths,unsigned char);
for (i=0;i<2*state->common->num_paths;i++)
ds->hint_errors[i] = FALSE;
ds->hints_done = snewn(2 * state->common->num_paths, unsigned char);
memset(ds->hints_done, 0,
2 * state->common->num_paths * sizeof(unsigned char));
ds->hshow = ds->hpencil = ds->hflash = 0;
ds->hx = ds->hy = 0;
@ -2097,6 +2155,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, const game_state *state)
}
static void game_free_drawstate(drawing *dr, game_drawstate *ds) {
sfree(ds->hints_done);
sfree(ds->hint_errors);
sfree(ds->cell_errors);
sfree(ds->pencils);
@ -2325,6 +2384,8 @@ static void draw_path_hint(drawing *dr, game_drawstate *ds,
color = COL_ERROR;
else if (hflash)
color = COL_FLASH;
else if (ds->hints_done[hint_index])
color = COL_DONE;
else
color = COL_TEXT;
@ -2453,6 +2514,11 @@ static int is_hint_stale(const game_drawstate *ds, int hflash,
return TRUE;
}
if (ds->hints_done[index] != state->hints_done[index]) {
ds->hints_done[index] = state->hints_done[index];
return TRUE;
}
return FALSE;
}