1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// GridStructGen.h
// Declares the cGridStructGen class representing a common base class for structure generators that place structures in a semi-random grid
#pragma once
#include "ComposableGenerator.h"
/** Generates structures in a semi-random grid.
Defines a grid in the XZ space with predefined cell size in each direction. Each cell then receives exactly
one structure (provided by the descendant class). The structure is placed within the cell, but doesn't need
to be bounded by the cell, it can be well outside the cell; the generator uses the MaxStructureSize parameter
to determine how far away from the cell the structure can be at most.
This class provides a cache for the structures generated for successive chunks and manages that cache. It
also provides the cFinishGen override that uses the cache to actually generate the structure into chunk data.
After generating each chunk the cache is checked for size, each item in the cache has a cost associated with
it and the cache is trimmed (from its least-recently-used end) so that the sum of the cost in the cache is
less than m_MaxCacheSize
To use this class, declare a descendant class that implements the overridable methods, then create an
instance of that class. The descendant must provide the CreateStructure() function that is called to generate
a structure at the specific grid cell.
The descendant must use a specific cStructure descendant to provide the actual structure that gets generated.
The structure must provide the DrawIntoChunk() function that generates the structure into the chunk data, and
can override the GetCacheCost() function that returns the cost of that structure in the cache.
*/
class cGridStructGen :
public cFinishGen
{
public:
/** Represents a single structure that occupies the grid point. Knows how to draw itself into a chunk. */
class cStructure
{
public:
/** The origin (the coords of the gridpoint for which the structure is generated) */
int m_OriginX, m_OriginZ;
/** Creates a structure that has its originset at the specified coords. */
cStructure (int a_OriginX, int a_OriginZ) :
m_OriginX(a_OriginX),
m_OriginZ(a_OriginZ)
{
}
// Force a virtual destructor in descendants:
virtual ~cStructure() {}
/** Draws self into the specified chunk */
virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) = 0;
/** Returns the cost of keeping this structure in the cache */
virtual size_t GetCacheCost(void) const { return 1; }
} ;
typedef SharedPtr<cStructure> cStructurePtr;
typedef std::list<cStructurePtr> cStructurePtrs;
cGridStructGen(
int a_Seed,
int a_GridSizeX, int a_GridSizeZ,
int a_MaxStructureSizeX, int a_MaxStructureSizeZ,
size_t a_MaxCacheSize
);
protected:
/** Seed for generating the semi-random grid. */
int m_Seed;
/** The size of each grid's cell in the X axis */
int m_GridSizeX;
/** The size of each grid's cell in the Z axis */
int m_GridSizeZ;
/** Maximum theoretical size of the structure in the X axis.
This limits the structures considered for a single chunk, so the lesser the number, the better performance.
Structures large than this may get cropped. */
int m_MaxStructureSizeX;
/** Maximum theoretical size of the structure in the Z axis.
This limits the structures considered for a single chunk, so the lesser the number, the better performance.
Structures large than this may get cropped. */
int m_MaxStructureSizeZ;
/** Maximum allowed sum of costs for items in the cache. Items that are over this cost are removed from the
cache, oldest-first */
size_t m_MaxCacheSize;
/** Cache for the most recently generated structures, ordered by the recentness. */
cStructurePtrs m_Cache;
/** Clears everything from the cache */
void ClearCache(void);
/** Returns all structures that may intersect the given chunk.
The structures are considered as intersecting iff their bounding box (defined by m_MaxStructureSize)
around their gridpoint intersects the chunk. */
void GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructurePtrs & a_Structures);
// cFinishGen overrides:
virtual void GenFinish(cChunkDesc & a_ChunkDesc) override;
// Functions for the descendants to override:
/** Create a new structure at the specified gridpoint */
virtual cStructurePtr CreateStructure(int a_OriginX, int a_OriginZ) = 0;
} ;
|