diff --git doc/data_format.rst doc/data_format.rst
index 1595824..c949b15 100644
--- doc/data_format.rst
+++ doc/data_format.rst
@@ -1442,7 +1442,7 @@ Persons
=======
Persons are an important concept in the game. Their properties are defined in
the game blocks below.
-FreeRCT can read blocks with version 1.
+FreeRCT can read blocks with version 1 or 2.
====== ====== ==========================================================
Offset Length Description
@@ -1472,8 +1472,11 @@ Offset Length Description
A person type defines the kind of persons:
- *Any* (0) Any kind of person (eg persons are not shown).
-- *Pillar* (8) Guests from the Pillar Planet (test graphics).
-- *Earth* (16) Earth-bound persons.
+- *Guest* (8) Guests.
+- *Handyman* (17) Handymen.
+- *Mechanic* (18) Mechanics.
+- *Guard* (19) Security guards.
+- *Entertainer* (20) Entertainers.
The *any* kind is used as fall back.
@@ -1490,6 +1493,8 @@ Version history
...............
- 1 (20120708) Initial version.
+- 2 (20141230) Renamed type 'Pillar' to 'Guest', removed type 'Earth', and
+ added staff types (Handyman, Mechanic, Guard, Entertainer).
Animation
diff --git graphics/rcd/freerct.txt graphics/rcd/freerct.txt
index 10ff505..36f424d 100644
--- graphics/rcd/freerct.txt
+++ graphics/rcd/freerct.txt
@@ -651,7 +651,7 @@ file("freerct.rcd") {
// Person type graphics.
PRSG {
person_graphics {
- person_type: pillar;
+ person_type: guest;
recolour {
original: grey;
replace: bitset(yellow, green, blue, orange, pink);
@@ -661,14 +661,14 @@ file("freerct.rcd") {
// NE walking.
ANIM {
- person_type: pillar;
+ person_type: guest;
anim_type: walk_ne;
frame_data { duration: 40; change_x: -4; change_y: 0; }
}
ANSP {
tile_width: 64;
- person_type: pillar;
+ person_type: guest;
anim_type: walk_ne;
sprite {
@@ -679,14 +679,14 @@ file("freerct.rcd") {
// SE walking.
ANIM {
- person_type: pillar;
+ person_type: guest;
anim_type: walk_se;
frame_data { duration: 40; change_x: 0; change_y: 4; }
}
ANSP {
tile_width: 64;
- person_type: pillar;
+ person_type: guest;
anim_type: walk_se;
sprite {
@@ -697,14 +697,14 @@ file("freerct.rcd") {
// SW walking.
ANIM {
- person_type: pillar;
+ person_type: guest;
anim_type: walk_sw;
frame_data { duration: 40; change_x: 4; change_y: 0; }
}
ANSP {
tile_width: 64;
- person_type: pillar;
+ person_type: guest;
anim_type: walk_sw;
sprite {
@@ -715,14 +715,346 @@ file("freerct.rcd") {
// NW walking.
ANIM {
- person_type: pillar;
+ person_type: guest;
anim_type: walk_nw;
frame_data { duration: 40; change_x: 0; change_y: -4; }
}
ANSP {
tile_width: 64;
- person_type: pillar;
+ person_type: guest;
+ anim_type: walk_nw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // Handyman - person type graphics.
+ PRSG {
+ person_graphics {
+ person_type: handyman;
+ recolour {
+ original: grey;
+ replace: bitset(grey);
+ }
+ }
+ }
+
+ // NE walking.
+ ANIM {
+ person_type: handyman;
+ anim_type: walk_ne;
+
+ frame_data { duration: 40; change_x: -4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: handyman;
+ anim_type: walk_ne;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SE walking.
+ ANIM {
+ person_type: handyman;
+ anim_type: walk_se;
+
+ frame_data { duration: 40; change_x: 0; change_y: 4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: handyman;
+ anim_type: walk_se;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SW walking.
+ ANIM {
+ person_type: handyman;
+ anim_type: walk_sw;
+
+ frame_data { duration: 40; change_x: 4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: handyman;
+ anim_type: walk_sw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // NW walking.
+ ANIM {
+ person_type: handyman;
+ anim_type: walk_nw;
+
+ frame_data { duration: 40; change_x: 0; change_y: -4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: handyman;
+ anim_type: walk_nw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // Mechanic - person type graphics.
+ PRSG {
+ person_graphics {
+ person_type: mechanic;
+ recolour {
+ original: grey;
+ replace: bitset(grey);
+ }
+ }
+ }
+
+ // NE walking.
+ ANIM {
+ person_type: mechanic;
+ anim_type: walk_ne;
+
+ frame_data { duration: 40; change_x: -4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: mechanic;
+ anim_type: walk_ne;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SE walking.
+ ANIM {
+ person_type: mechanic;
+ anim_type: walk_se;
+
+ frame_data { duration: 40; change_x: 0; change_y: 4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: mechanic;
+ anim_type: walk_se;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SW walking.
+ ANIM {
+ person_type: mechanic;
+ anim_type: walk_sw;
+
+ frame_data { duration: 40; change_x: 4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: mechanic;
+ anim_type: walk_sw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // NW walking.
+ ANIM {
+ person_type: mechanic;
+ anim_type: walk_nw;
+
+ frame_data { duration: 40; change_x: 0; change_y: -4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: mechanic;
+ anim_type: walk_nw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // Security guard - person type graphics.
+ PRSG {
+ person_graphics {
+ person_type: guard;
+ recolour {
+ original: grey;
+ replace: bitset(grey);
+ }
+ }
+ }
+
+ // NE walking.
+ ANIM {
+ person_type: guard;
+ anim_type: walk_ne;
+
+ frame_data { duration: 40; change_x: -4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: guard;
+ anim_type: walk_ne;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SE walking.
+ ANIM {
+ person_type: guard;
+ anim_type: walk_se;
+
+ frame_data { duration: 40; change_x: 0; change_y: 4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: guard;
+ anim_type: walk_se;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SW walking.
+ ANIM {
+ person_type: guard;
+ anim_type: walk_sw;
+
+ frame_data { duration: 40; change_x: 4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: guard;
+ anim_type: walk_sw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // NW walking.
+ ANIM {
+ person_type: guard;
+ anim_type: walk_nw;
+
+ frame_data { duration: 40; change_x: 0; change_y: -4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: guard;
+ anim_type: walk_nw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // Entertainer - person type graphics.
+ PRSG {
+ person_graphics {
+ person_type: entertainer;
+ recolour {
+ original: grey;
+ replace: bitset(grey);
+ }
+ }
+ }
+
+ // NE walking.
+ ANIM {
+ person_type: entertainer;
+ anim_type: walk_ne;
+
+ frame_data { duration: 40; change_x: -4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: entertainer;
+ anim_type: walk_ne;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SE walking.
+ ANIM {
+ person_type: entertainer;
+ anim_type: walk_se;
+
+ frame_data { duration: 40; change_x: 0; change_y: 4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: entertainer;
+ anim_type: walk_se;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // SW walking.
+ ANIM {
+ person_type: entertainer;
+ anim_type: walk_sw;
+
+ frame_data { duration: 40; change_x: 4; change_y: 0; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: entertainer;
+ anim_type: walk_sw;
+
+ sprite {
+ x_base: 0; y_base: 0; width: 10; height: 27;
+ x_offset: -5; y_offset: -27; file: "../sprites/gui/pillar.png";
+ }
+ }
+
+ // NW walking.
+ ANIM {
+ person_type: entertainer;
+ anim_type: walk_nw;
+
+ frame_data { duration: 40; change_x: 0; change_y: -4; }
+ }
+ ANSP {
+ tile_width: 64;
+ person_type: entertainer;
anim_type: walk_nw;
sprite {
diff --git src/people.cpp src/people.cpp
index 7696121..3c47535 100644
--- src/people.cpp
+++ src/people.cpp
@@ -86,7 +86,7 @@ Guests::~Guests()
void Guests::Initialize()
{
this->valid_ptypes = 0;
- for (PersonType pertype = PERSON_MIN_GUEST; pertype <= PERSON_MAX_GUEST; pertype++) {
+ for (PersonType pertype = PERSON_GUEST; pertype <= PERSON_GUEST; pertype++) {
bool usable = true;
for (AnimationType antype = ANIM_BEGIN; antype <= ANIM_LAST; antype++) {
if (_sprite_manager.GetAnimation(antype, pertype) == nullptr) {
@@ -94,7 +94,7 @@ void Guests::Initialize()
break;
}
}
- if (usable) this->valid_ptypes |= 1u << (pertype - PERSON_MIN_GUEST);
+ if (usable) this->valid_ptypes |= 1u << (pertype - PERSON_ANY);
}
}
@@ -105,8 +105,8 @@ void Guests::Initialize()
*/
bool Guests::CanUsePersonType(PersonType ptype)
{
- if (ptype < PERSON_MIN_GUEST || ptype > PERSON_MAX_GUEST) return false;
- return (this->valid_ptypes & (1 << (ptype - PERSON_MIN_GUEST))) != 0;
+ if (ptype < PERSON_GUEST || ptype > PERSON_GUEST) return false;
+ return (this->valid_ptypes & (1 << (ptype - PERSON_ANY))) != 0;
}
/**
@@ -196,7 +196,7 @@ void Guests::DoTick()
*/
void Guests::OnNewDay()
{
- PersonType ptype = PERSON_PILLAR;
+ PersonType ptype = PERSON_GUEST;
if (!this->CanUsePersonType(ptype)) return;
if (this->CountActiveGuests() >= _scenario.max_guests) return;
if (!this->rnd.Success1024(_scenario.GetSpawnProbability(512))) return;
diff --git src/people.h src/people.h
index de3fa27..a9c1ced 100644
--- src/people.h
+++ src/people.h
@@ -113,7 +113,7 @@ private:
void AddFree(Guest *g);
Guest *GetFree();
};
-assert_compile(PERSON_MAX_GUEST - PERSON_MIN_GUEST + 1 <= 16); ///< Verify that all person types fit in #Guests::valid_ptypes
+assert_compile(PERSON_GUEST + 1 <= 16); ///< Verify that all person types fit in #Guests::valid_ptypes
extern Guests _guests;
diff --git src/person.cpp src/person.cpp
index d19d514..89d6548 100644
--- src/person.cpp
+++ src/person.cpp
@@ -58,7 +58,7 @@ PersonTypeData &ModifyPersonTypeData(PersonType pt)
bool LoadPRSG(RcdFileReader *rcd_file)
{
uint32 length = rcd_file->size;
- if (rcd_file->version != 1 || length < 1) return false;
+ if (rcd_file->version < 1 || length < 1) return false;
uint8 count = rcd_file->GetUInt8();
length--;
@@ -71,8 +71,14 @@ bool LoadPRSG(RcdFileReader *rcd_file)
PersonType pt;
switch (ps) {
- case 8: pt = PERSON_PILLAR; break;
- case 16: pt = PERSON_EARTH; break;
+ case 8:
+ case 16:
+ pt = PERSON_GUEST;
+ break;
+ case 17: pt = PERSON_HANDYMAN; break;
+ case 18: pt = PERSON_MECHANIC; break;
+ case 19: pt = PERSON_GUARD; break;
+ case 20: pt = PERSON_ENTERTAINER; break;
default: pt = PERSON_INVALID; break;
}
diff --git src/person.h src/person.h
index 4485913..b7a9058 100644
--- src/person.h
+++ src/person.h
@@ -121,7 +121,7 @@ public:
*/
bool IsGuest() const
{
- return this->type >= PERSON_MIN_GUEST && this->type <= PERSON_MAX_GUEST;
+ return this->type == PERSON_GUEST;
}
void SetName(const char *name);
diff --git src/person_type.h src/person_type.h
index 20d25d2..51496b7 100644
--- src/person_type.h
+++ src/person_type.h
@@ -19,15 +19,18 @@ class RcdFileReader;
/** Types of persons. */
enum PersonType {
- PERSON_ANY = 0, ///< No people displayed in the animation.
- PERSON_PILLAR = 1, ///< %Guests from the planet of Pillars (test graphics).
- PERSON_EARTH = 2, ///< Earth-bound guests.
+ PERSON_ANY = 0, ///< No people displayed in the animation.
+ PERSON_GUEST = 1, ///< %Guests.
+ PERSON_HANDYMAN = 2, ///< %Staff handymen.
+ PERSON_MECHANIC = 3, ///< %Staff mechanics.
+ PERSON_GUARD = 4, ///< %Staff security guards.
+ PERSON_ENTERTAINER = 5, ///< %Staff entertainers.
PERSON_TYPE_COUNT, ///< Number of known types of persons.
PERSON_INVALID = 0xFF, ///< Invalid person type.
- PERSON_MIN_GUEST = PERSON_ANY, ///< First value of a guest.
- PERSON_MAX_GUEST = PERSON_EARTH, ///< Last value of a guest.
+ PERSON_MIN_STAFF = PERSON_HANDYMAN, ///< First value of an employee.
+ PERSON_MAX_STAFF = PERSON_ENTERTAINER, ///< Last value of an employee.
};
DECLARE_POSTFIX_INCREMENT(PersonType)
diff --git src/rcdgen/check_data.cpp src/rcdgen/check_data.cpp
index 260441c..e2a5e86 100644
--- src/rcdgen/check_data.cpp
+++ src/rcdgen/check_data.cpp
@@ -1071,12 +1071,15 @@ static std::shared_ptr<PRSGBlock> ConvertPRSGNode(std::shared_ptr<NodeGroup> ng)
/** Symbols for an ANIM and ANSP blocks. */
static const Symbol _anim_symbols[] = {
- {"pillar", 8},
- {"earth", 16},
- {"walk_ne", 1}, // Walk in north-east direction.
- {"walk_se", 2}, // Walk in south-east direction.
- {"walk_sw", 3}, // Walk in south-west direction.
- {"walk_nw", 4}, // Walk in north-west direction.
+ {"guest", 8},
+ {"handyman", 17},
+ {"mechanic", 18},
+ {"guard", 19},
+ {"entertainer", 20},
+ {"walk_ne", 1}, // Walk in north-east direction.
+ {"walk_se", 2}, // Walk in south-east direction.
+ {"walk_sw", 3}, // Walk in south-west direction.
+ {"walk_nw", 4}, // Walk in north-west direction.
{nullptr, 0}
};
@@ -1501,8 +1504,11 @@ static std::shared_ptr<BitMask> ConvertBitMaskNode(std::shared_ptr<NodeGroup> ng
/** Names of person types and colour ranges. */
static const Symbol _person_graphics_symbols[] = {
- {"pillar", 8},
- {"earth", 16},
+ {"guest", 8},
+ {"handyman", 17},
+ {"mechanic", 18},
+ {"guard", 19},
+ {"entertainer", 20},
{"grey", COL_GREY},
{"green_brown", COL_GREEN_BROWN},
{"orange_brown", COL_ORANGE_BROWN},
diff --git src/rcdgen/nodes.cpp src/rcdgen/nodes.cpp
index 4295917..fb00cb6 100644
--- src/rcdgen/nodes.cpp
+++ src/rcdgen/nodes.cpp
@@ -493,7 +493,7 @@ bool PersonGraphics::AddRecolour(uint8 orig, uint32 replace)
return false;
}
-PRSGBlock::PRSGBlock() : GameBlock("PRSG", 1)
+PRSGBlock::PRSGBlock() : GameBlock("PRSG", 2)
{
}
diff --git src/sprite_store.cpp src/sprite_store.cpp
index cea7fd4..893e47f 100644
--- src/sprite_store.cpp
+++ src/sprite_store.cpp
@@ -605,8 +605,13 @@ static PersonType DecodePersonType(uint8 pt)
{
switch (pt) {
case 0: return PERSON_ANY;
- case 8: return PERSON_PILLAR;
- case 16: return PERSON_EARTH;
+ case 8:
+ case 16:
+ return PERSON_GUEST;
+ case 17: return PERSON_HANDYMAN;
+ case 18: return PERSON_MECHANIC;
+ case 19: return PERSON_GUARD;
+ case 20: return PERSON_ENTERTAINER;
default: return PERSON_INVALID;
}
}
@@ -1139,6 +1144,8 @@ void SpriteStorage::RemoveAnimations(AnimationType anim_type, PersonType pers_ty
++iter2;
this->animations.erase(iter);
iter = iter2;
+ } else {
+ ++iter;
}
}
}