Skip to content

Commit

Permalink
Show face in high scores #151
Browse files Browse the repository at this point in the history
  • Loading branch information
cxong committed Feb 18, 2025
1 parent 46b293e commit 6f4a180
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 180 deletions.
193 changes: 112 additions & 81 deletions src/cdogs/character.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@

#define CHARACTER_VERSION 14

#define YAJL_CHECK(func) \
if (func != yajl_gen_status_ok) \
{ \
LOG(LM_MAIN, LL_ERROR, "JSON generator error for character\n"); \
res = false; \
goto bail; \
}

static void CharacterInit(Character *c)
{
memset(c, 0, sizeof *c);
Expand Down Expand Up @@ -82,22 +90,7 @@ void CharacterStoreCopy(
CharacterStoreInit(dst);
CArrayCopy(&dst->OtherChars, &src->OtherChars);
CA_FOREACH(Character, c, dst->OtherChars)
const CharBot *cb = c->bot;
CMALLOC(c->bot, sizeof *c->bot);
memcpy(c->bot, cb, sizeof *cb);
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
{
if (c->HeadParts[hp] != NULL)
{
char *hpCopy = NULL;
CSTRDUP(hpCopy, c->HeadParts[hp]);
c->HeadParts[hp] = hpCopy;
}
}
if (c->PlayerTemplateName != NULL)
{
PlayerTemplateAddCharacter(playerTemplates, c);
}
CharacterCopy(c, CArrayGet(&src->OtherChars, _ca_index), playerTemplates);
CA_FOREACH_END()
CArrayCopy(&dst->prisonerIds, &src->prisonerIds);
CArrayCopy(&dst->baddieIds, &src->baddieIds);
Expand Down Expand Up @@ -249,7 +242,7 @@ void CharacterLoadJSON(
}
}

bool CharacterSave(CharacterStore *s, const char *path)
bool CharacterStoreSave(CharacterStore *s, const char *path)
{
bool res = true;
yajl_gen g = yajl_gen_alloc(NULL);
Expand All @@ -261,77 +254,18 @@ bool CharacterSave(CharacterStore *s, const char *path)
goto bail;
}

#define YAJL_CHECK(func) \
if (func != yajl_gen_status_ok) \
{ \
LOG(LM_MAIN, LL_ERROR, "JSON generator error for character\n"); \
res = false; \
goto bail; \
}

YAJL_CHECK(yajl_gen_map_open(g));
YAJL_CHECK(YAJLAddIntPair(g, "Version", CHARACTER_VERSION));

YAJL_CHECK(yajl_gen_string(g, (const unsigned char *)"Characters", strlen("Characters")));
YAJL_CHECK(yajl_gen_string(
g, (const unsigned char *)"Characters", strlen("Characters")));
YAJL_CHECK(yajl_gen_array_open(g));
CA_FOREACH(Character, c, s->OtherChars)
YAJL_CHECK(yajl_gen_map_open(g));
YAJL_CHECK(YAJLAddStringPair(g, "Class", c->Class->Name));
if (c->PlayerTemplateName)
{
YAJL_CHECK(
YAJLAddStringPair(g, "PlayerTemplateName", c->PlayerTemplateName));
}
if (c->HeadParts[HEAD_PART_HAIR])
{
YAJL_CHECK(
YAJLAddStringPair(g, "HairType", c->HeadParts[HEAD_PART_HAIR]));
}
if (c->HeadParts[HEAD_PART_FACEHAIR])
if (!CharacterSave(g, c))
{
YAJL_CHECK(YAJLAddStringPair(
g, "FacehairType", c->HeadParts[HEAD_PART_FACEHAIR]));
}
if (c->HeadParts[HEAD_PART_HAT])
{
YAJL_CHECK(
YAJLAddStringPair(g, "HatType", c->HeadParts[HEAD_PART_HAT]));
}
if (c->HeadParts[HEAD_PART_GLASSES])
{
YAJL_CHECK(YAJLAddStringPair(
g, "GlassesType", c->HeadParts[HEAD_PART_GLASSES]));
}
YAJL_CHECK(YAJLAddColorPair(g, "Skin", c->Colors.Skin));
YAJL_CHECK(YAJLAddColorPair(g, "Arms", c->Colors.Arms));
YAJL_CHECK(YAJLAddColorPair(g, "Body", c->Colors.Body));
YAJL_CHECK(YAJLAddColorPair(g, "Legs", c->Colors.Legs));
YAJL_CHECK(YAJLAddColorPair(g, "Hair", c->Colors.Hair));
YAJL_CHECK(YAJLAddColorPair(g, "Feet", c->Colors.Feet));
YAJL_CHECK(YAJLAddColorPair(g, "Facehair", c->Colors.Facehair));
YAJL_CHECK(YAJLAddColorPair(g, "Hat", c->Colors.Hat));
YAJL_CHECK(YAJLAddColorPair(g, "Glasses", c->Colors.Glasses));
YAJL_CHECK(YAJLAddIntPair(g, "speed", (int)(c->speed * 256)));
YAJL_CHECK(YAJLAddStringPair(g, "Gun", c->Gun->name));
if (c->Melee != NULL)
{
YAJL_CHECK(YAJLAddStringPair(g, "Melee", c->Melee->name));
}
YAJL_CHECK(YAJLAddIntPair(g, "maxHealth", c->maxHealth));
YAJL_CHECK(YAJLAddIntPair(g, "excessHealth", c->excessHealth));
YAJL_CHECK(YAJLAddIntPair(g, "flags", c->flags));
if (c->Drop != NULL)
{
YAJL_CHECK(YAJLAddStringPair(g, "Drop", c->Drop->Name));
res = false;
goto bail;
}
YAJL_CHECK(
YAJLAddIntPair(g, "probabilityToMove", c->bot->probabilityToMove));
YAJL_CHECK(
YAJLAddIntPair(g, "probabilityToTrack", c->bot->probabilityToTrack));
YAJL_CHECK(
YAJLAddIntPair(g, "probabilityToShoot", c->bot->probabilityToShoot));
YAJL_CHECK(YAJLAddIntPair(g, "actionDelay", c->bot->actionDelay));
YAJL_CHECK(yajl_gen_map_close(g));
CA_FOREACH_END()
YAJL_CHECK(yajl_gen_array_close(g));

Expand Down Expand Up @@ -411,6 +345,103 @@ int CharacterStoreGetRandomSpecialId(const CharacterStore *store)
return *(int *)CArrayGet(&store->specialIds, idx);
}

void CharacterCopy(
Character *dst, const Character *src, CArray *playerTemplates)
{
memcpy(dst, src, sizeof *dst);
const CharBot *cb = dst->bot;
if (cb)
{
CMALLOC(dst->bot, sizeof *dst->bot);
memcpy(dst->bot, cb, sizeof *cb);
}
for (HeadPart hp = HEAD_PART_HAIR; hp < HEAD_PART_COUNT; hp++)
{
if (dst->HeadParts[hp] != NULL)
{
char *hpCopy = NULL;
CSTRDUP(hpCopy, dst->HeadParts[hp]);
dst->HeadParts[hp] = hpCopy;
}
}
if (dst->PlayerTemplateName != NULL && playerTemplates)
{
PlayerTemplateAddCharacter(playerTemplates, dst);
}
}

bool CharacterSave(yajl_gen g, const Character *c)
{
bool res = true;

YAJL_CHECK(yajl_gen_map_open(g));
YAJL_CHECK(YAJLAddStringPair(g, "Class", c->Class->Name));
if (c->PlayerTemplateName)
{
YAJL_CHECK(
YAJLAddStringPair(g, "PlayerTemplateName", c->PlayerTemplateName));
}
if (c->HeadParts[HEAD_PART_HAIR])
{
YAJL_CHECK(
YAJLAddStringPair(g, "HairType", c->HeadParts[HEAD_PART_HAIR]));
}
if (c->HeadParts[HEAD_PART_FACEHAIR])
{
YAJL_CHECK(YAJLAddStringPair(
g, "FacehairType", c->HeadParts[HEAD_PART_FACEHAIR]));
}
if (c->HeadParts[HEAD_PART_HAT])
{
YAJL_CHECK(
YAJLAddStringPair(g, "HatType", c->HeadParts[HEAD_PART_HAT]));
}
if (c->HeadParts[HEAD_PART_GLASSES])
{
YAJL_CHECK(YAJLAddStringPair(
g, "GlassesType", c->HeadParts[HEAD_PART_GLASSES]));
}
YAJL_CHECK(YAJLAddColorPair(g, "Skin", c->Colors.Skin));
YAJL_CHECK(YAJLAddColorPair(g, "Arms", c->Colors.Arms));
YAJL_CHECK(YAJLAddColorPair(g, "Body", c->Colors.Body));
YAJL_CHECK(YAJLAddColorPair(g, "Legs", c->Colors.Legs));
YAJL_CHECK(YAJLAddColorPair(g, "Hair", c->Colors.Hair));
YAJL_CHECK(YAJLAddColorPair(g, "Feet", c->Colors.Feet));
YAJL_CHECK(YAJLAddColorPair(g, "Facehair", c->Colors.Facehair));
YAJL_CHECK(YAJLAddColorPair(g, "Hat", c->Colors.Hat));
YAJL_CHECK(YAJLAddColorPair(g, "Glasses", c->Colors.Glasses));
YAJL_CHECK(YAJLAddIntPair(g, "speed", (int)(c->speed * 256)));
if (c->Gun)
{
YAJL_CHECK(YAJLAddStringPair(g, "Gun", c->Gun->name));
}
if (c->Melee != NULL)
{
YAJL_CHECK(YAJLAddStringPair(g, "Melee", c->Melee->name));
}
YAJL_CHECK(YAJLAddIntPair(g, "maxHealth", c->maxHealth));
YAJL_CHECK(YAJLAddIntPair(g, "excessHealth", c->excessHealth));
YAJL_CHECK(YAJLAddIntPair(g, "flags", c->flags));
if (c->Drop != NULL)
{
YAJL_CHECK(YAJLAddStringPair(g, "Drop", c->Drop->Name));
}
if (c->bot)
{
YAJL_CHECK(
YAJLAddIntPair(g, "probabilityToMove", c->bot->probabilityToMove));
YAJL_CHECK(YAJLAddIntPair(
g, "probabilityToTrack", c->bot->probabilityToTrack));
YAJL_CHECK(YAJLAddIntPair(
g, "probabilityToShoot", c->bot->probabilityToShoot));
YAJL_CHECK(YAJLAddIntPair(g, "actionDelay", c->bot->actionDelay));
}
YAJL_CHECK(yajl_gen_map_close(g));

bail:
return res;
}

bool CharacterIsPrisoner(const CharacterStore *store, const Character *c)
{
for (int i = 0; i < (int)store->prisonerIds.size; i++)
Expand Down
9 changes: 7 additions & 2 deletions src/cdogs/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
C-Dogs SDL
A port of the legendary (and fun) action/arcade cdogs.
Copyright (c) 2013-2014, 2016, 2019-2021, 2023 Cong Xu
Copyright (c) 2013-2014, 2016, 2019-2021, 2023, 2025 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -33,6 +33,7 @@
#include "character_class.h"
#include "pickup_class.h"
#include "weapon.h"
#include "yajl/api/yajl_gen.h"

typedef struct
{
Expand Down Expand Up @@ -76,7 +77,7 @@ void CharacterStoreCopy(
void CharacterStoreResetOthers(CharacterStore *store);
void CharacterLoadJSON(
CharacterStore *c, CArray *playerTemplates, json_t *root, int version);
bool CharacterSave(CharacterStore *s, const char *path);
bool CharacterStoreSave(CharacterStore *s, const char *path);
Character *CharacterStoreAddOther(CharacterStore *store);
Character *CharacterStoreInsertOther(CharacterStore *store, const size_t idx);
void CharacterStoreDeleteOther(CharacterStore *store, int idx);
Expand All @@ -90,6 +91,10 @@ int CharacterStoreGetSpecialId(const CharacterStore *store, const int i);
int CharacterStoreGetRandomBaddieId(const CharacterStore *store);
int CharacterStoreGetRandomSpecialId(const CharacterStore *store);

void CharacterCopy(
Character *dst, const Character *src, CArray *playerTemplates);
bool CharacterSave(yajl_gen g, const Character *c);

bool CharacterIsPrisoner(const CharacterStore *store, const Character *c);

void CharacterSetHeadPart(Character *c, const HeadPart hp, const char *name);
Expand Down
8 changes: 4 additions & 4 deletions src/cdogs/map_archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ static void LoadArchivePics(PicManager *pm, map_t cc, const char *archive)
{
char path[CDOGS_PATH_MAX];
sprintf(path, "%s/graphics", archive);
PicManagerLoadDir(pm, path, NULL, pm->customPics, pm->customSprites, false);
PicManagerLoadDir(
pm, path, NULL, pm->customPics, pm->customSprites, false);
sprintf(path, "%s/graphics_hd", archive);
PicManagerLoadDir(pm, path, NULL, pm->customPics, pm->customSprites, true);
CharSpriteClassesLoadDir(cc, archive);
Expand Down Expand Up @@ -286,7 +287,7 @@ int MapArchiveSave(const char *filename, CampaignSetting *c)
goto bail;
}

if (!CharacterSave(&c->characters, buf))
if (!CharacterStoreSave(&c->characters, buf))
{
res = 0;
goto bail;
Expand Down Expand Up @@ -337,8 +338,7 @@ static json_t *SaveMissions(CArray *a)
json_t *pcsNode = json_new_array();
for (int j = 0; j < (int)mission->PickupCounts.size; j++)
{
const PickupCount *pc =
CArrayGet(&mission->PickupCounts, j);
const PickupCount *pc = CArrayGet(&mission->PickupCounts, j);
json_t *pcNode = json_new_object();
AddStringPair(pcNode, "Pickup", pc->P->Name);
AddIntPair(pcNode, "Count", pc->Count);
Expand Down
Loading

0 comments on commit 6f4a180

Please sign in to comment.