<commit_before>#include <stdlib.h>
#include <math.h>
#include <SDL2/SDL.h>
#include "controller/keyboard.h"
#include "controller/joystick.h"
#include "utils/log.h"
#include "utils/miscmath.h"
#include "game/utils/serial.h"
#include "resources/ids.h"
#include "resources/pilots.h"
#include "console/console.h"
#include "video/video.h"
#include "video/tcache.h"
#include "game/game_state.h"
#include "game/common_defines.h"
#include "game/utils/settings.h"
#include "game/utils/ticktimer.h"
#include "game/protos/scene.h"
#include "game/protos/object.h"
#include "game/protos/intersect.h"
#include "game/scenes/intro.h"
#include "game/scenes/mainmenu.h"
#include "game/scenes/credits.h"
#include "game/scenes/cutscene.h"
#include "game/scenes/arena.h"
#include "game/scenes/mechlab.h"
#include "game/scenes/newsroom.h"
#include "game/scenes/melee.h"
#include "game/scenes/vs.h"
#include "game/scenes/scoreboard.h"

#define MS_PER_OMF_TICK 10
#define MS_PER_OMF_TICK_SLOWEST 90

enum {
    TICK_DYNAMIC = 0,
    TICK_STATIC,
};

// How long the scene waits after order to move to another scene
// Used for crossfades
#define FRAME_WAIT_TICKS 30

typedef struct {
    int layer;
    object *obj;
} render_obj;

int game_state_create(game_state *gs, int net_mode) {
    gs->run = 1;
    gs->paused = 0;
    gs->tick = 0;
    gs->int_tick = 0;
    gs->role = ROLE_CLIENT;
    gs->next_requires_refresh = 0;
    gs->net_mode = net_mode;
    gs->speed = settings_get()->gameplay.speed + 5;
    vector_create(&gs->objects, sizeof(render_obj));

    // For screen shake
    gs->screen_shake_horizontal = 0;
    gs->screen_shake_vertical = 0;

    // For momentary game speed switches
    gs->speed_slowdown_previous = 0;
    gs->speed_slowdown_time = 0;

    // Used for crossfades
    gs->next_wait_ticks = 0;
    gs->this_wait_ticks = 0;

    // Set up players
    gs->sc = malloc(sizeof(scene));
    for(int i = 0; i < 2; i++) {
        gs->players[i] = malloc(sizeof(game_player));
        game_player_create(gs->players[i]);
    }

    reconfigure_controller(gs);

    // Select correct starting scene and load resources
    int nscene = (net_mode == NET_MODE_NONE ? SCENE_INTRO : SCENE_MENU);
    if(scene_create(gs->sc, gs, nscene)) {
        PERROR("Error while loading scene %d.", nscene);
        goto error_0;
    }
    if(net_mode == NET_MODE_NONE) {
        if(intro_create(gs->sc)) {
            PERROR("Error while creating intro scene.");
            goto error_1;
        }
    } else {
        // if connecting to the server or listening, jump straight to the menu
        if(mainmenu_create(gs->sc)) {
            PERROR("Error while creating menu scene.");
            goto error_1;
        }
    }

    // Initialize scene
    scene_init(gs->sc);

    // All done
    gs->this_id = nscene;
    gs->next_id = nscene;
    return 0;

error_1:
    scene_free(gs->sc);
error_0:
    free(gs->sc);
    vector_free(&gs->objects);
    return 1;
}

int game_state_add_object(game_state *gs, object *obj, int layer) {
    render_obj o;
    o.obj = obj;
    o.layer = layer;
    animation *new_ani = object_get_animation(obj);
    if(object_get_singleton(obj)) {
        iterator it;
        render_obj *robj;
        vector_iter_begin(&gs->objects, &it);
        while((robj = iter_next(&it)) != NULL) {
            animation *ani = object_get_animation(robj->obj);
            if(ani != NULL && ani->id == new_ani->id && robj->obj->singleton) {
                return 1;
            }
        }
    }
    vector_append(&gs->objects, &o);

#ifdef DEBUGMODE_STFU
    animation *ani = object_get_animation(obj);
    DEBUG("Added animation %i to game_state on layer %d.", ani->id, layer);
#endif
    return 0;
}

void game_state_slowdown(game_state *gs, int ticks, int rate) {
    gs->speed_slowdown_previous = gs->speed;
    gs->speed_slowdown_time = ticks;
    gs->speed = rate;
}

void game_state_set_speed(game_state *gs, int speed) {
    DEBUG("game speed set to %d", speed);
    gs->speed = (speed + 5);
}

unsigned int game_state_get_speed(game_state *gs) {
    return gs->speed - 5;
}

void game_state_del_animation(game_state *gs, int anim_id) {
    iterator it;
    render_obj *robj;
    vector_iter_begin(&gs->objects, &it);
    while((robj = iter_next(&it)) != NULL) {
        animation *ani = object_get_animation(robj->obj);
        if(ani != NULL && ani->id == anim_id) {
            object_free(robj->obj);
            free(robj->obj);
            vector_delete(&gs->objects, &it);
            DEBUG("Deleted animation %i from game_state.", anim_id);
            return;
        }
    }
    DEBUG("Attempted to delete animation %i from game_state, but no such animation was playing.", anim_id);<commit_msg>Fix the problem with game state rewinding itself.<commit_after>#include <stdlib.h>
#include <math.h>
#include <SDL2/SDL.h>
#include "controller/keyboard.h"
#include "controller/joystick.h"
#include "utils/log.h"
#include "utils/miscmath.h"
#include "game/utils/serial.h"
#include "resources/ids.h"
#include "resources/pilots.h"
#include "console/console.h"
#include "video/video.h"
#include "video/tcache.h"
#include "game/game_state.h"
#include "game/common_defines.h"
#include "game/utils/settings.h"
#include "game/utils/ticktimer.h"
#include "game/protos/scene.h"
#include "game/protos/object.h"
#include "game/protos/intersect.h"
#include "game/scenes/intro.h"
#include "game/scenes/mainmenu.h"
#include "game/scenes/credits.h"
#include "game/scenes/cutscene.h"
#include "game/scenes/arena.h"
#include "game/scenes/mechlab.h"
#include "game/scenes/newsroom.h"
#include "game/scenes/melee.h"
#include "game/scenes/vs.h"
#include "game/scenes/scoreboard.h"

#define MS_PER_OMF_TICK 10
#define MS_PER_OMF_TICK_SLOWEST 90

enum {
    TICK_DYNAMIC = 0,
    TICK_STATIC,
};

// How long the scene waits after order to move to another scene
// Used for crossfades
#define FRAME_WAIT_TICKS 30

typedef struct {
    int layer;
    object *obj;
} render_obj;

int game_state_create(game_state *gs, int net_mode) {
    gs->run = 1;
    gs->paused = 0;
    gs->tick = 0;
    gs->int_tick = 0;
    gs->role = ROLE_CLIENT;
    gs->next_requires_refresh = 0;
    gs->net_mode = net_mode;
    gs->speed = settings_get()->gameplay.speed + 5;
    vector_create(&gs->objects, sizeof(render_obj));

    // For screen shake
    gs->screen_shake_horizontal = 0;
    gs->screen_shake_vertical = 0;

    // For momentary game speed switches
    gs->speed_slowdown_previous = 0;
    gs->speed_slowdown_time = 0;

    // Used for crossfades
    gs->next_wait_ticks = 0;
    gs->this_wait_ticks = 0;

    // Set up players
    gs->sc = malloc(sizeof(scene));
    for(int i = 0; i < 2; i++) {
        gs->players[i] = malloc(sizeof(game_player));
        game_player_create(gs->players[i]);
    }

    reconfigure_controller(gs);

    // Select correct starting scene and load resources
    int nscene = (net_mode == NET_MODE_NONE ? SCENE_INTRO : SCENE_MENU);
    if(scene_create(gs->sc, gs, nscene)) {
        PERROR("Error while loading scene %d.", nscene);
        goto error_0;
    }
    if(net_mode == NET_MODE_NONE) {
        if(intro_create(gs->sc)) {
            PERROR("Error while creating intro scene.");
            goto error_1;
        }
    } else {
        // if connecting to the server or listening, jump straight to the menu
        if(mainmenu_create(gs->sc)) {
            PERROR("Error while creating menu scene.");
            goto error_1;
        }
    }

    // Initialize scene
    scene_init(gs->sc);

    // All done
    gs->this_id = nscene;
    gs->next_id = nscene;
    return 0;

error_1:
    scene_free(gs->sc);
error_0:
    free(gs->sc);
    vector_free(&gs->objects);
    return 1;
}

int game_state_add_object(game_state *gs, object *obj, int layer) {
    render_obj o;
    o.obj = obj;
    o.layer = layer;
    animation *new_ani = object_get_animation(obj);
    if(object_get_singleton(obj)) {
        iterator it;
        render_obj *robj;
        vector_iter_begin(&gs->objects, &it);
        while((robj = iter_next(&it)) != NULL) {
            animation *ani = object_get_animation(robj->obj);
            if(ani != NULL && ani->id == new_ani->id && robj->obj->singleton) {
                return 1;
            }
        }
    }
    vector_append(&gs->objects, &o);

#ifdef DEBUGMODE_STFU
    animation *ani = object_get_animation(obj);
    DEBUG("Added animation %i to game_state on layer %d.", ani->id, layer);
#endif
    return 0;
}

/*
 * Slows down the game for n ticks. Only allows slowdown if one isn't already ongoing.
 */
void game_state_slowdown(game_state *gs, int ticks, int rate) {
    if(gs->speed_slowdown_time < 0) { 
        gs->speed_slowdown_previous = gs->speed;
        gs->speed_slowdown_time = ticks;
        gs->speed = rate;
    }
}

void game_state_set_speed(game_state *gs, int speed) {
    DEBUG("game speed set to %d", speed);
    gs->speed = (speed + 5);
}

unsigned int game_state_get_speed(game_state *gs) {
    return gs->speed - 5;
}

void game_state_del_animation(game_state *gs, int anim_id) {
    iterator it;
    render_obj *robj;
    vector_iter_begin(&gs->objects, &it);
    while((robj = iter_next(&it)) != NULL) {
        animation *ani = object_get_animation(robj->obj);
        if(ani != NULL && ani->id == anim_id) {
            object_free(robj->obj);
            free(robj->obj);
            vector_delete(&gs->objects, &it);
            DEBUG("Deleted animation %i from game_state.", anim_id);
            return;
        }
    }
    DEBUG("Attempted to delete animation %i from game_state, but no such animation was playing.", anim_id);
{'fraction_non_alphanumeric': 0.13755844155844155, 'fraction_numerical': 0.006961038961038961, 'mean_word_length': 2.93218954248366, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 106, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3999381', 'n_tokens_mistral': 3542, 'n_tokens_neox': 3362, 'n_words': 755}