diff --git doc/data_format.rst doc/data_format.rst
index 1595824..57d1faf 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
@@ -1471,9 +1471,18 @@ 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.
+============ ===== ======= ============================================
+Name Value Version Description
+============ ===== ======= ============================================
+Any 0 1- Any kind of person (persons are not shown).
+Pillar 8 1 Guests from the Pillar planet (testing).
+Guest 8 2- Guests.
+Earth 16 1 Earth-bound persons.
+Handyman 17 2- Handymen.
+Mechanic 18 2- Mechanics.
+Guard 19 2- Security guards.
+Entertainer 20 2- Entertainers.
+============ ===== ======= ============================================
The *any* kind is used as fall back.
@@ -1490,6 +1499,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..f798c08 100644
--- src/people.cpp
+++ src/people.cpp
@@ -86,16 +86,16 @@ Guests::~Guests()
void Guests::Initialize()
{
this->valid_ptypes = 0;
- for (PersonType pertype = PERSON_MIN_GUEST; pertype <= PERSON_MAX_GUEST; pertype++) {
- bool usable = true;
- for (AnimationType antype = ANIM_BEGIN; antype <= ANIM_LAST; antype++) {
- if (_sprite_manager.GetAnimation(antype, pertype) == nullptr) {
- usable = false;
- break;
- }
+ PersonType pertype = PERSON_GUEST;
+ bool usable = true;
+
+ for (AnimationType antype = ANIM_BEGIN; antype <= ANIM_LAST; antype++) {
+ if (_sprite_manager.GetAnimation(antype, pertype) == nullptr) {
+ usable = false;
+ 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) 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..0895d12 100644
--- src/people.h
+++ src/people.h
@@ -60,6 +60,7 @@ protected:
/**
* All our guests.
* @todo Allow to have several blocks of guests.
+ * @todo valid_ptypes should be removed.
*/
class Guests {
public:
@@ -113,7 +114,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..5d92f68 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 || rcd_file->version > 2 || length < 1) return false;
uint8 count = rcd_file->GetUInt8();
length--;
@@ -71,8 +71,12 @@ 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..47be967 100644
--- src/person_type.h
+++ src/person_type.h
@@ -19,15 +19,15 @@ 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_TYPE_COUNT, ///< Number of known types of persons.
+ PERSON_ANY, ///< No people displayed in the animation.
+ PERSON_GUEST, ///< %Guests.
+ PERSON_HANDYMAN, ///< %Staff handymen.
+ PERSON_MECHANIC, ///< %Staff mechanics.
+ PERSON_GUARD, ///< %Staff security guards.
+ PERSON_ENTERTAINER, ///< %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.
};
DECLARE_POSTFIX_INCREMENT(PersonType)
diff --git src/rcdgen/check_data.cpp src/rcdgen/check_data.cpp
index 260441c..72f59b8 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..92ebc45 100644
--- src/sprite_store.cpp
+++ src/sprite_store.cpp
@@ -605,8 +605,12 @@ 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;
}
}