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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 | /********************************************************************
*
* File: gfCParkGuestViewComponent.h
*
* Purpose: Presentation for the day sim's guests: an animated
* character per guest, moved between gate, slot and out.
* The sim is spatial-free, so all positioning lives here
* (anchors from the TMX, walks interpolated here).
*
* The sim erases a guest the tick it enters LEAVING_*, so
* a view whose guest has vanished is walked out to the gate
* here before being destroyed.
*
*********************************************************************/
#ifndef gfCParkGuestViewComponenthdr
#define gfCParkGuestViewComponenthdr
#include <utility>
#include <vector>
#include <fsCore/src/fsCUniqueId.h>
#include <fsCore/fsStr.h>
#include <fsCore/fsVec2d.h>
#include <fsAppCore/src/components/fsIComponent.h>
class fsCEntity;
class gfCParkDaySim;
class gfCParkLevelComponent;
namespace fsNTileMap
{
class fsCView;
}
class gfCParkGuestViewComponent : public fsIComponent
{
friend class fsCComponentFactory;
public:
static const fsCUniqueId mTypeId;
// Guests live under this one child of the view, so a single
// bringToFrontOfSiblings() keeps them above buildings bought mid-day.
static const fsStr mGuestLayerName;
// Clears every guest sprite immediately. Called when a new day starts so the
// park doesn't begin with the previous day's guests frozen on screen (they'd
// otherwise all walk out at once as the new empty sim reconciles).
void reset();
virtual ~gfCParkGuestViewComponent();
protected:
void updateDo(fsS32 pDeltaMs) override;
static fsIComponent* const create(fsCEntity* const pParent);
gfCParkGuestViewComponent(fsCEntity* const pParent);
private:
struct SGuestView
{
fsStr mName;
fsCEntity* mEntity;<--- Member variable 'SGuestView::mEntity' has no initializer. [+]Member variable 'SGuestView::mEntity' has no initializer. Member variables of native types, pointers, or references are left uninitialized when the class is instantiated. That may cause bugs or undefined behavior.
// The lead entity plus catalogue-sized visual companions. One sim agent
// still owns the party's needs, queue place, spending and outcome.
std::vector<fsCEntity*> mMemberEntities;
fsVec2d mPos;
fsStr mAnimation;
fsS32 mWanderSeed;
fsS32 mWanderStep;
fsS32 mWanderPauseRemainingMs;
fsBool mSeen;
fsBool mDeparting;
// On arrival: false until the guest has walked in through the gate, then
// true for the rest of its life (it heads to its slot/park only after).
fsBool mEnteredGate;
// While departing: false = still heading to the gate, true = past the
// gate and heading out to the spawn point.
fsBool mReachedGate;
// Set once per walk, when this view has told the sim the distance-based
// travel time for its current slot (so the walk is a constant speed).
fsBool mTravelPaced;
// Remaining view-local waypoints for the current routed walk (front = next).
// Empty means "walk straight". mPathTarget* is the grid cell the current
// route heads to, so it is only recomputed when the destination changes.
std::vector<fsVec2d> mPath;
fsS32 mPathTargetCol;
fsS32 mPathTargetRow;
};
// Where a guest with no slot yet mills about (park centre, not the gate).
fsVec2d parkCentreGet(fsNTileMap::fsCView* const pView) const;
fsNTileMap::fsCView* viewGet() const;
// Find-or-create the guest layer (at the view origin).
fsCEntity* guestLayerGet(fsNTileMap::fsCView* const pView) const;
// Centre of a named TMX object in view-local space. False if not found.
fsBool mapPointGet(fsNTileMap::fsCView* const pView, const fsStr& pObjectName, fsVec2d& pOut) const;
SGuestView* viewFind(const fsStr& pGuestName);
SGuestView& viewCreate(fsNTileMap::fsCView* const pView, const fsStr& pGuestName,
const fsStr& pGuestType, fsS32 pPartySize, const fsVec2d& pAt);
// The Spriter character folder authored for a guest type in catalogue/
// guests.yml ("character" param). Empty if the type has none - viewCreate
// then falls back to cycling the guestNN placeholders. Loaded once, lazily.
const fsStr& characterForType(const fsStr& pGuestType);
void characterTableEnsureLoaded();
// Re-issues animationPlay only on change (else the clip restarts each frame).
void animationSet(SGuestView& pView, const fsStr& pAnimation);
// Steps toward pTarget; true while travelling. pArriveInMs is the sim's
// remaining travel time (paces the walk to it); 0 = default speed.
fsBool moveToward(SGuestView& pView, const fsVec2d& pTarget, fsS32 pDeltaMs,
fsS32 pArriveInMs = 0) const;
// As moveToward, but routes around uncleared forest: follows a BFS cell path
// from the guest's current cell to pTarget (recomputed only when the target
// cell changes). Falls back to a straight line when no path exists (open map,
// off-grid spawn), so behaviour on a fully-cleared park is unchanged.
fsBool moveTowardRouted(SGuestView& pView, fsNTileMap::fsCView* const pTileView,
const gfCParkLevelComponent* const pLevel,
const fsVec2d& pTarget, fsS32 pDeltaMs, fsS32 pArriveInMs) const;
void pathEnsure(SGuestView& pView, fsNTileMap::fsCView* const pTileView,
const gfCParkLevelComponent* const pLevel, const fsVec2d& pTarget) const;
fsF32 pathRemainingLength(const SGuestView& pView) const;
fsBool advanceAlongPath(SGuestView& pView, fsF32 pStep) const;
// Pins a tick/cross above a just-departed guest, from the sim's one-tick
// departure list.
void departureFeedbackAttach(SGuestView& pView, const gfCParkDaySim* const pSim) const;
std::vector<SGuestView> mViews;
fsS32 mNextCharacterIndex;
// Guest-type name -> Spriter character folder, from catalogue/guests.yml.
std::vector<std::pair<fsStr, fsStr>> mCharacterByType;
fsBool mCharacterTableLoaded;
};
#endif
|