Improved replay consistency

This commit is contained in:
Andrei "Akari" Alexeyev 2017-02-15 19:34:47 +02:00
parent 61b2488b50
commit 0be20dab0d
9 changed files with 32 additions and 31 deletions

View file

@ -108,7 +108,6 @@ typedef struct {
RefArray refs;
int game_over;
int points;
FPSCounter fps;

View file

@ -93,10 +93,10 @@ void process_items(void) {
player_set_power(&global.plr, global.plr.power + POWER_VALUE);
break;
case Point:
global.points += 100;
global.plr.points += 100;
break;
case BPoint:
global.points += 1;
global.plr.points += 1;
break;
case Life:
global.plr.lifes++;

View file

@ -52,8 +52,6 @@ void start_replay(void *arg) {
mctx->pickedstage = 0;
}
init_player(&global.plr);
for(int i = mctx->pickedstage; i < global.replay.numstages; ++i) {
ReplayStage *rstg = global.replay_stage = global.replay.stages+i;
StageInfo *gstg = stage_get(rstg->stage);

View file

@ -23,8 +23,7 @@ void init_player(Player *plr) {
plr->deathtime = -1;
plr->continues = 0;
// maybe move this to player?
global.points = 0;
plr->points = 0;
}
void prepare_player_for_next_stage(Player *plr) {
@ -420,7 +419,7 @@ void player_input_workaround(Player *plr) {
}
void player_graze(Player *plr, complex pos, int pts) {
global.points += pts;
plr->points += pts;
plr->graze++;
play_sound("graze");

View file

@ -43,7 +43,9 @@ typedef struct {
short dir;
short power;
int graze;
int points;
int lifes;
int bombs;

View file

@ -97,7 +97,7 @@ int collision_projectile(Projectile *p) {
while(e != NULL) {
if(e->hp != ENEMY_IMMUNE && cabs(e->pos - p->pos) < 15) {
global.points += damage * 0.5;
global.plr.points += damage * 0.5;
e->hp -= damage;
return 2;
}
@ -106,7 +106,7 @@ int collision_projectile(Projectile *p) {
if(global.boss && cabs(global.boss->pos - p->pos) < 42
&& global.boss->current->type != AT_Move && global.boss->current->type != AT_SurvivalSpell && global.boss->current->starttime < global.frames) {
global.points += damage * 0.2;
global.plr.points += damage * 0.2;
global.boss->dmg += damage;
return 2;
}

View file

@ -60,6 +60,19 @@ ReplayStage* replay_create_stage(Replay *rpy, StageInfo *stage, uint64_t seed, D
return s;
}
void replay_stage_sync_player_state(ReplayStage *stg, Player *plr) {
plr->points = stg->points;
plr->shot = stg->plr_shot;
plr->cha = stg->plr_char;
plr->pos = stg->plr_pos_x + I * stg->plr_pos_y;
plr->focus = stg->plr_focus;
plr->fire = stg->plr_fire;
plr->lifes = stg->plr_lifes;
plr->bombs = stg->plr_bombs;
plr->power = stg->plr_power;
plr->moveflags = stg->plr_moveflags;
}
static void replay_destroy_stage(ReplayStage *stage) {
if(stage->events) {
free(stage->events);

View file

@ -140,6 +140,7 @@ void replay_destroy_events(Replay *rpy);
void replay_stage_event(ReplayStage *stg, uint32_t frame, uint8_t type, int16_t value);
void replay_stage_check_desync(ReplayStage *stg, int time, uint16_t check, ReplayMode mode);
void replay_stage_sync_player_state(ReplayStage *stg, Player *plr);
int replay_write(Replay *rpy, SDL_RWops *file);
int replay_read(Replay *rpy, SDL_RWops *file, ReplayReadMode mode);

View file

@ -219,7 +219,7 @@ void draw_hud(void) {
sprintf(buf, "%i", global.plr.graze);
draw_text(AL_Left, -5, 270, buf, _fonts.standard);
sprintf(buf, "%i", global.points);
sprintf(buf, "%i", global.plr.points);
draw_text(AL_Center, 13, 49, buf, _fonts.standard);
if(global.plr.iddqd) {
@ -490,17 +490,16 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
if(global.replaymode == REPLAY_RECORD) {
if(tconfig.intval[SAVE_RPY]) {
global.replay_stage = replay_create_stage(&global.replay, info, seed, global.diff, global.points, &global.plr);
global.replay_stage = replay_create_stage(&global.replay, info, seed, global.diff, global.plr.points, &global.plr);
// make sure our player state is consistent with what goes into the replay
init_player(&global.plr);
replay_stage_sync_player_state(global.replay_stage, &global.plr);
} else {
global.replay_stage = NULL;
}
printf("Random seed: %u\n", seed);
// match replay format
uint16_t px = floor(creal(global.plr.pos));
uint16_t py = floor(cimag(global.plr.pos));
global.plr.pos = px + I * py;
} else {
if(!global.replay_stage) {
errx(-1, "Attemped to replay a NULL stage");
@ -513,19 +512,9 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
tsrand_seed_p(&global.rand_game, stg->seed);
printf("Random seed: %u\n", stg->seed);
global.diff = stg->diff;
global.points = stg->points;
global.plr.shot = stg->plr_shot;
global.plr.cha = stg->plr_char;
global.plr.pos = stg->plr_pos_x + I * stg->plr_pos_y;
global.plr.focus = stg->plr_focus;
global.plr.fire = stg->plr_fire;
global.plr.lifes = stg->plr_lifes;
global.plr.bombs = stg->plr_bombs;
global.plr.power = stg->plr_power;
global.plr.moveflags = stg->plr_moveflags;
global.diff = stg->diff;
init_player(&global.plr);
replay_stage_sync_player_state(stg, &global.plr);
stg->playpos = 0;
}
@ -548,7 +537,7 @@ void stage_loop(StageInfo* info, StageRule start, StageRule end, StageRule draw,
event();
((global.replaymode == REPLAY_PLAY)? replay_input : stage_input)();
replay_stage_check_desync(global.replay_stage, global.frames, (tsrand() ^ global.points) & 0xFFFF, global.replaymode);
replay_stage_check_desync(global.replay_stage, global.frames, (tsrand() ^ global.plr.points) & 0xFFFF, global.replaymode);
stage_logic(endtime);