Skip to content

Commit

Permalink
Refactor map builder to use tile class (#475)
Browse files Browse the repository at this point in the history
  • Loading branch information
cxong committed Jan 14, 2019
1 parent 67307e1 commit 516da55
Show file tree
Hide file tree
Showing 23 changed files with 762 additions and 789 deletions.
106 changes: 39 additions & 67 deletions src/cdogs/door.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2015, 2018 Cong Xu
Copyright (c) 2013-2015, 2018-2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -64,14 +64,12 @@ static Trigger *CreateOpenDoorTrigger(
const bool isHorizontal, const int doorGroupCount, const int keyFlags);
void MapAddDoorGroup(MapBuilder *mb, const struct vec2i v, const int keyFlags)
{
const unsigned short tileLeftType =
IMapGet(mb, svec2i(v.x - 1, v.y)) & MAP_MASKACCESS;
const unsigned short tileRightType =
IMapGet(mb, svec2i(v.x + 1, v.y)) & MAP_MASKACCESS;
const TileClass *tileLeftType = MapBuilderGetTile(mb, svec2i(v.x - 1, v.y));
const TileClass *tileRightType =
MapBuilderGetTile(mb, svec2i(v.x + 1, v.y));
const bool isHorizontal =
tileLeftType == MAP_WALL || tileRightType == MAP_WALL ||
tileLeftType == MAP_DOOR || tileRightType == MAP_DOOR ||
tileLeftType == MAP_NOTHING || tileRightType == MAP_NOTHING;
!tileLeftType->canWalk || !tileRightType->canWalk ||
tileLeftType->IsDoor || tileRightType->IsDoor;
const int doorGroupCount = GetDoorCountInGroup(mb, v, isHorizontal);
const struct vec2i dv = svec2i(isHorizontal ? 1 : 0, isHorizontal ? 0 : 1);
const struct vec2i dAside = svec2i(dv.y, dv.x);
Expand All @@ -86,11 +84,9 @@ void MapAddDoorGroup(MapBuilder *mb, const struct vec2i v, const int keyFlags)
default: doorKey = "normal"; break;
}
const TileClass *doorClass = DoorGetClass(
&gTileClasses, &gPicManager, mb->mission->DoorStyle, doorKey,
isHorizontal);
mb->mission->DoorStyle, doorKey, isHorizontal);
const TileClass *doorClassOpen = DoorGetClass(
&gTileClasses, &gPicManager, mb->mission->DoorStyle, "open",
isHorizontal);
mb->mission->DoorStyle, "open", isHorizontal);

// set up the door pics
for (int i = 0; i < doorGroupCount; i++)
Expand All @@ -111,10 +107,8 @@ void MapAddDoorGroup(MapBuilder *mb, const struct vec2i v, const int keyFlags)
CASSERT(TileCanWalk(tileB),
"map gen error: entrance should be clear");
// Change the tile below to shadow, cast by this door
const bool isFloor = IMapGet(mb, vB) == MAP_FLOOR;
const bool isFloor = !MapBuilderGetIsRoom(mb, vB);
tileB->Class = TileClassesGetMaskedTile(
&gTileClasses,
&gPicManager,
&gTileFloor,
isFloor ? mb->mission->FloorStyle : mb->mission->RoomStyle,
"shadow",
Expand Down Expand Up @@ -148,6 +142,8 @@ void MapAddDoorGroup(MapBuilder *mb, const struct vec2i v, const int keyFlags)
}
}

static void DoorGetClassName(
char *buf, const char *style, const char *key, const bool isHorizontal);
// Count the number of doors that are in the same group as this door
// Only check to the right/below
static int GetDoorCountInGroup(
Expand All @@ -156,7 +152,7 @@ static int GetDoorCountInGroup(
const struct vec2i dv = svec2i(isHorizontal ? 1 : 0, isHorizontal ? 0 : 1);
int count = 0;
for (struct vec2i vi = v;
(IMapGet(mb, vi) & MAP_MASKACCESS) == MAP_DOOR;
MapBuilderGetTile(mb, vi)->IsDoor;
vi = svec2i_add(vi, dv))
{
count++;
Expand Down Expand Up @@ -211,13 +207,9 @@ static TWatch *CreateCloseDoorWatch(
a->Type = ACTION_EVENT;
a->a.Event = GameEventNew(GAME_EVENT_TILE_SET);
a->a.Event.u.TileSet.Pos = Vec2i2Net(vI);
strcpy(
a->a.Event.u.TileSet.ClassName,
DoorGetClass(
&gTileClasses, &gPicManager, mb->mission->DoorStyle, "open",
isHorizontal
)->Name
);
DoorGetClassName(
a->a.Event.u.TileSet.ClassName, mb->mission->DoorStyle, "open",
isHorizontal);
strcpy(a->a.Event.u.TileSet.ClassAltName, classAlt->Name);
}

Expand All @@ -233,12 +225,10 @@ static TWatch *CreateCloseDoorWatch(
a->a.Event = GameEventNew(GAME_EVENT_TILE_SET);
const struct vec2i vI2 = svec2i(vI.x + dAside.x, vI.y + dAside.y);
a->a.Event.u.TileSet.Pos = Vec2i2Net(vI2);
const bool isFloor = IMapGet(mb, vI2) == MAP_FLOOR;
const bool isFloor = !MapBuilderGetIsRoom(mb, vI2);
strcpy(
a->a.Event.u.TileSet.ClassName,
TileClassesGetMaskedTile(
&gTileClasses,
&gPicManager,
&gTileFloor,
isFloor ? mb->mission->FloorStyle : mb->mission->RoomStyle,
"shadow",
Expand Down Expand Up @@ -276,23 +266,15 @@ static Trigger *CreateOpenDoorTrigger(
a->Type = ACTION_EVENT;
a->a.Event = GameEventNew(GAME_EVENT_TILE_SET);
a->a.Event.u.TileSet.Pos = Vec2i2Net(vI);
strcpy(
a->a.Event.u.TileSet.ClassName,
DoorGetClass(
&gTileClasses, &gPicManager, mb->mission->DoorStyle, "open",
isHorizontal
)->Name
);
DoorGetClassName(
a->a.Event.u.TileSet.ClassName, mb->mission->DoorStyle, "open",
isHorizontal);
if (!isHorizontal && i == 0)
{
// special door cavity picture
strcpy(
DoorGetClassName(
a->a.Event.u.TileSet.ClassAltName,
DoorGetClass(
&gTileClasses, &gPicManager, mb->mission->DoorStyle, "wall",
false
)->Name
);
mb->mission->DoorStyle, "wall", false);
}
}

Expand All @@ -307,13 +289,11 @@ static Trigger *CreateOpenDoorTrigger(
// Remove shadows below doors
a->Type = ACTION_EVENT;
a->a.Event = GameEventNew(GAME_EVENT_TILE_SET);
const bool isFloor = IMapGet(mb, vIAside) == MAP_FLOOR;
const bool isFloor = !MapBuilderGetIsRoom(mb, vIAside);
a->a.Event.u.TileSet.Pos = Vec2i2Net(vIAside);
strcpy(
a->a.Event.u.TileSet.ClassName,
TileClassesGetMaskedTile(
&gTileClasses,
&gPicManager,
&gTileFloor,
isFloor? mb->mission->FloorStyle : mb->mission->RoomStyle,
"normal",
Expand Down Expand Up @@ -367,38 +347,15 @@ typedef struct
int Wall;
} DoorPics;

static void DoorGetClassName(
char *buf, const char *style, const char *key, const bool isHorizontal);
// Get the tile class of a door; if it doesn't exist create it
// style: office/dungeon/blast/alien, or custom
// key: normal/yellow/green/blue/red/wall/open
const TileClass *DoorGetClass(
TileClasses *c, const PicManager *pm,
const char *style, const char *key,
const bool isHorizontal)
const char *style, const char *key, const bool isHorizontal)
{
char buf[CDOGS_FILENAME_MAX];
DoorGetClassName(buf, style, key, isHorizontal);
const TileClass *tc = StrTileClass(buf);
if (tc != &gTileNothing)
{
return tc;
}

// tile class not found; create it
TileClass *t = TileClassAdd(c->customClasses, pm, NULL, buf);
if (t == NULL)
{
return NULL;
}
t->IsDoor = true;
const bool isOpenOrWallCavity =
strcmp(key, "open") == 0 || strcmp(key, "wall") == 0;
t->isOpaque = !isOpenOrWallCavity;
t->canWalk = isOpenOrWallCavity;
t->shootable = !isOpenOrWallCavity;

return t;
return StrTileClass(buf);
}
static void DoorGetClassName(
char *buf, const char *style, const char *key, const bool isHorizontal)
Expand All @@ -408,6 +365,21 @@ static void DoorGetClassName(
buf, "door/%s/%s%s", style, key,
strcmp(key, "wall") == 0 ? "" : (isHorizontal ? "_h" : "_v"));
}
void DoorAddClass(
TileClasses *c, const PicManager *pm,
const char *style, const char *key, const bool isHorizontal)
{
char buf[CDOGS_FILENAME_MAX];
DoorGetClassName(buf, style, key, isHorizontal);
TileClass *t = TileClassAdd(c->customClasses, pm, NULL, buf);
CASSERT(t != NULL, "cannot add door class");
t->IsDoor = true;
const bool isOpenOrWallCavity =
strcmp(key, "open") == 0 || strcmp(key, "wall") == 0;
t->isOpaque = !isOpenOrWallCavity;
t->canWalk = isOpenOrWallCavity;
t->shootable = !isOpenOrWallCavity;
}

#define DOORSTYLE_COUNT 4
const char *IntDoorStyle(const int i)
Expand Down
7 changes: 4 additions & 3 deletions src/cdogs/door.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2016, 2018 Cong Xu
Copyright (c) 2013-2016, 2018-2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -54,9 +54,10 @@
void MapAddDoorGroup(MapBuilder *mb, const struct vec2i v, const int keyFlags);

const TileClass *DoorGetClass(
const char *style, const char *key, const bool isHorizontal);
void DoorAddClass(
TileClasses *c, const PicManager *pm,
const char *style, const char *key,
const bool isHorizontal);
const char *style, const char *key, const bool isHorizontal);

// Legacy door style int to str
const char *IntDoorStyle(const int i);
7 changes: 6 additions & 1 deletion src/cdogs/log.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2015-2017 Cong Xu
Copyright (c) 2015-2017, 2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -245,3 +245,8 @@ void LogLine(
fflush(stream);
}
}

void LogFlush(FILE *stream)
{
fflush(stream);
}
10 changes: 9 additions & 1 deletion src/cdogs/log.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2015-2016, Cong Xu
Copyright (c) 2015-2016, 2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -86,6 +86,14 @@ void LogTerminate(void);
}\
} while ((void)0, 0)

#define LOG_FLUSH()\
do\
{\
LogFlush(stderr);\
LogFlush(gLogFile);\
} while ((void)0, 0)

void LogLine(
FILE *stream, const LogModule m, const LogLevel l, const char *filename,
const int line, const char *function, const char *fmt, ...);
void LogFlush(FILE *stream);
26 changes: 8 additions & 18 deletions src/cdogs/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2018 Cong Xu
Copyright (c) 2013-2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -103,7 +103,7 @@ IMapType StrIMapType(const char *s)
}


unsigned short GetAccessMask(int k)
uint16_t GetAccessMask(const int k)
{
if (k == -1)
{
Expand All @@ -114,7 +114,7 @@ unsigned short GetAccessMask(int k)

Tile *MapGetTile(const Map *map, const struct vec2i pos)
{
if (pos.x < 0 || pos.x >= map->Size.x || pos.y < 0 || pos.y >= map->Size.y)
if (!MapIsTileIn(map, pos))
{
return NULL;
}
Expand All @@ -130,7 +130,7 @@ bool MapIsTileIn(const Map *map, const struct vec2i pos)
static bool MapIsPosIn(const Map *map, const struct vec2 pos)
{
// Check that the pos is within the interior of the map
return MapIsTileIn(map, Vec2ToTile(pos));
return pos.x >= 0 && pos.y >= 0 && MapIsTileIn(map, Vec2ToTile(pos));
}

bool MapIsTileInExit(const Map *map, const Thing *ti)
Expand Down Expand Up @@ -293,9 +293,9 @@ bool MapHasLockedRooms(const Map *map)
return map->keyAccessCount > 1;
}

unsigned short MapGetAccessLevel(const Map *map, const struct vec2i pos)
uint16_t MapGetAccessLevel(const Map *map, const struct vec2i pos)
{
const unsigned short t = *(unsigned short *)CArrayGet(
const uint16_t t = *(uint16_t *)CArrayGet(
&map->access, pos.y * map->Size.x + pos.x);
return AccessCodeToFlags(t);
}
Expand Down Expand Up @@ -407,18 +407,8 @@ bool MapPlaceRandomPos(
return false;
}


void MapSetAccess(Map *map, const CArray *access)
{
CASSERT(access->size == map->access.size, "Unequal access sizes");
CA_FOREACH(const unsigned short, t, *access)
const unsigned short tAccess = *t & MAP_ACCESSBITS;
CArraySet(&map->access, _ca_index, &tAccess);
CA_FOREACH_END()
}

// TODO: use enum instead of flag for map access
unsigned short AccessCodeToFlags(const unsigned short code)
uint16_t AccessCodeToFlags(const uint16_t code)
{
if (code & MAP_ACCESS_RED)
return FLAGS_KEYCARD_RED;
Expand Down Expand Up @@ -477,7 +467,7 @@ void MapInit(Map *map, const struct vec2i size)
CArrayInit(&map->Tiles, sizeof(Tile));
map->Size = size;
LOSInit(map);
CArrayInit(&map->access, sizeof(unsigned short));
CArrayInit(&map->access, sizeof(uint16_t));
CArrayResize(&map->access, size.x * size.y, NULL);
CArrayFillZero(&map->access);
CArrayInit(&map->triggers, sizeof(Trigger *));
Expand Down
11 changes: 5 additions & 6 deletions src/cdogs/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
This file incorporates work covered by the following copyright and
permission notice:
Copyright (c) 2013-2018 Cong Xu
Copyright (c) 2013-2019 Cong Xu
All rights reserved.
Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -95,7 +95,7 @@ typedef struct
struct vec2i Size;

LineOfSight LOS;
CArray access; // of unsigned short
CArray access; // of uint16_t

CArray triggers; // of Trigger *; owner
int triggerId;
Expand All @@ -111,16 +111,15 @@ typedef struct

extern Map gMap;

unsigned short GetAccessMask(int k);
uint16_t GetAccessMask(const int k);

Tile *MapGetTile(const Map *map, const struct vec2i pos);
bool MapIsTileIn(const Map *map, const struct vec2i pos);
bool MapIsTileInExit(const Map *map, const Thing *ti);

void MapSetAccess(Map *map, const CArray *access);
// TODO: remove this function
unsigned short MapGetAccessLevel(const Map *map, const struct vec2i pos);
unsigned short AccessCodeToFlags(const unsigned short code);
uint16_t MapGetAccessLevel(const Map *map, const struct vec2i pos);
uint16_t AccessCodeToFlags(const uint16_t code);
bool MapHasLockedRooms(const Map *map);
bool MapPosIsInLockedRoom(const Map *map, const struct vec2 pos);
int MapGetDoorKeycardFlag(Map *map, struct vec2i pos);
Expand Down
2 changes: 1 addition & 1 deletion src/cdogs/map_archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ static json_t *SaveStaticTiles(Mission *m)
for (int i = 0; i < size; i++)
{
char buf[32];
sprintf(buf, "%d", *(unsigned short *)CArrayGet(
sprintf(buf, "%d", *(uint16_t *)CArrayGet(
&m->u.Static.Tiles, i));
strcpy(pBuf, buf);
pBuf += strlen(buf);
Expand Down
Loading

0 comments on commit 516da55

Please sign in to comment.