Skip to content

Commit

Permalink
More background engine changes to the campaign manager
Browse files Browse the repository at this point in the history
  • Loading branch information
crudelios committed Mar 20, 2024
1 parent 084adc8 commit 6678bf2
Show file tree
Hide file tree
Showing 26 changed files with 820 additions and 347 deletions.
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ set(BUILDING_FILES
${PROJECT_SOURCE_DIR}/src/building/variant.c
${PROJECT_SOURCE_DIR}/src/building/warehouse.c
)
set(CAMPAIGN_FILES
${PROJECT_SOURCE_DIR}/src/campaign/campaign.c
${PROJECT_SOURCE_DIR}/src/campaign/file.c
${PROJECT_SOURCE_DIR}/src/campaign/mission.c
${PROJECT_SOURCE_DIR}/src/campaign/xml.c
)
set(CITY_FILES
${PROJECT_SOURCE_DIR}/src/city/buildings.c
${PROJECT_SOURCE_DIR}/src/city/culture.c
Expand Down Expand Up @@ -392,7 +398,6 @@ set(FIGURETYPE_FILES
set(GAME_FILES
${PROJECT_SOURCE_DIR}/src/game/animation.c
${PROJECT_SOURCE_DIR}/src/game/cheats.c
${PROJECT_SOURCE_DIR}/src/game/custom_campaign.c
${PROJECT_SOURCE_DIR}/src/game/difficulty.c
${PROJECT_SOURCE_DIR}/src/game/file.c
${PROJECT_SOURCE_DIR}/src/game/file_editor.c
Expand Down Expand Up @@ -708,6 +713,7 @@ set(SOURCE_FILES
${PLATFORM_FILES}
${CORE_FILES}
${BUILDING_FILES}
${CAMPAIGN_FILES}
${CITY_FILES}
${EMPIRE_FILES}
${FIGURE_FILES}
Expand Down
131 changes: 131 additions & 0 deletions src/campaign/campaign.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "campaign.h"

#include "campaign/file.h"
#include "campaign/mission.h"
#include "campaign/xml.h"
#include "core/log.h"

#include <stdlib.h>

static struct {
int active;
campaign_info campaign;
struct {
campaign_mission_info info;
int current_option_id;
const campaign_mission *current;
} mission;
} data;

static void get_campaign_data(void)
{
if (!campaign_file_open_zip()) {
log_error("Error opening campaign file", 0, 0);
campaign_clear();
return;
}
log_info("Opening campaign settings file", 0, 0);

size_t xml_size;
char *xml_text = campaign_file_load("settings.xml", &xml_size);
if (!xml_text) {
log_error("Error loading campaign settings file", 0, 0);
campaign_clear();
return;
}
int result = campaign_xml_get_info(xml_text, xml_size, &data.campaign);
campaign_file_close_zip();

free(xml_text);

if (!result) {
campaign_clear();
}

data.active = result;
}

int campaign_load(const char *filename)
{
campaign_clear();
if (!filename || !*filename) {
return 0;
}
campaign_file_set_path(filename);
get_campaign_data();
return data.active;
}

const campaign_info *campaign_get_info(void)
{
return data.active ? &data.campaign : 0;
}

int campaign_has_file(const char *filename)
{
if (!data.active) {
return 0;
}
filename = campaign_file_remove_prefix(filename);
if (!filename) {
return 0;
}
return campaign_file_exists(filename);
}

uint8_t *campaign_load_file(const char *filename, size_t *length)
{
*length = 0;
if (!data.active) {
return 0;
}
filename = campaign_file_remove_prefix(filename);
if (!filename) {
return 0;
}
return campaign_file_load(filename, length);
}

static const campaign_mission_option *get_next_mission_option(void)
{
if (!data.active || !data.mission.current || data.mission.current_option_id > data.mission.current->last_option) {
return 0;
}
const campaign_mission_option *option = campaign_mission_get_option(data.mission.current_option_id);
data.mission.current_option_id++;
return option;
}

const campaign_mission_info *campaign_get_next_mission(int last_scenario_id)
{
if (!data.active) {
return 0;
}
const campaign_mission *current = campaign_mission_next(last_scenario_id);
if (!current) {
data.mission.current = 0;
data.mission.info.background_image = 0;
data.mission.current_option_id = 0;
return 0;
}
data.mission.current = current;
data.mission.info.background_image = current->background_image;
data.mission.current_option_id = current->first_option;
return &data.mission.info;
}

void campaign_clear(void)
{
campaign_file_set_path(0);
campaign_mission_clear();
free((uint8_t *) data.campaign.name);
free((uint8_t *) data.campaign.description);
data.campaign.name = 0;
data.campaign.description = 0;
data.campaign.number_of_missions = 0;
data.mission.info.background_image = 0;
data.mission.info.get_next_option = get_next_mission_option;
data.mission.current_option_id = 0;
data.mission.current = 0;
data.active = 0;
}
74 changes: 74 additions & 0 deletions src/campaign/campaign.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#ifndef CAMPAIGN_H
#define CAMPAIGN_H

#include <stdint.h>

#define CAMPAIGN_FIRST_MISSION -1

typedef struct {
const uint8_t *name;
const uint8_t *description;
int number_of_missions;
} campaign_info;

typedef struct {
int id;
int x;
int y;
const char *name;
const char *description;
const char *path;
struct {
int x;
int y;
const char *path;
} image;
} campaign_mission_option;

typedef struct {
const char *background_image;
const campaign_mission_option *(*get_next_option)(void);
} campaign_mission_info;

/**
* Loads a campaign from the filename.
* @param filename The filename to load. Can be a directory or a file with the .campaign extension.
* @return 1 if the campaign was loaded, 0 if there was a problem.
*/
int campaign_load(const char *filename);

/**
* Gets the basic info for the campaign.
* @return A campaign_info struct with the data if successful, 0 otherwise.
*/
const campaign_info *campaign_get_info(void);

/**
* Checks if a file exists in the current campaign.
* @param filename The filename to check.
* @return 1 if the file exists, 0 otherwise.
*/
int campaign_has_file(const char *filename);

/**
* Loads a file from the campaign.
* @param filename The filename to load.
* @param length The length of the file.
* @return A pointer to the file data if successful, 0 otherwise. The caller is responsible for freeing the memory.
*/
uint8_t *campaign_load_file(const char *filename, size_t *length);

/**
* Gets the next mission from the campaign.
* @param last_scenario_id The last played scenario.
* @return A pointer to the first mission whose first scenario is higher than last_scenario_id,
* or 0 if there's an error or if there are no new missions.
*/
const campaign_mission_info *campaign_get_next_mission(int last_scenario_id);

/**
* Clears the campaign data.
*/
void campaign_clear(void);

#endif // CAMPAIGN_H
Loading

0 comments on commit 6678bf2

Please sign in to comment.