diff --git a/Client/App/App.vcproj b/Client/App/App.vcproj
index 36ecce02..2868f030 100644
--- a/Client/App/App.vcproj
+++ b/Client/App/App.vcproj
@@ -797,6 +797,10 @@
RelativePath=".\include\v8datamodel\Camera.h"
>
+
+
@@ -1354,6 +1358,10 @@
RelativePath=".\v8datamodel\Camera.cpp"
>
+
+
diff --git a/Client/App/include/v8datamodel/CharacterAppearance.h b/Client/App/include/v8datamodel/CharacterAppearance.h
new file mode 100644
index 00000000..90a6b1cd
--- /dev/null
+++ b/Client/App/include/v8datamodel/CharacterAppearance.h
@@ -0,0 +1,129 @@
+#include "humanoid/Humanoid.h"
+#include "util/TextureId.h"
+#include "v8datamodel/BrickColor.h"
+#include "Network/Players.h"
+
+namespace RBX
+{
+ class CharacterAppearance : public Instance
+ {
+ private:
+ virtual void apply(Humanoid* humanoid) = 0;
+ public:
+ void apply();
+ protected:
+ virtual void onAncestorChanged(const AncestorChanged& event);
+ virtual bool askSetParent(const Instance* instance) const;
+ };
+
+ extern const char* sBodyColors;
+ class BodyColors : public DescribedCreatable
+ {
+ private:
+ BrickColor headColor;
+ BrickColor leftArmColor;
+ BrickColor rightArmColor;
+ BrickColor torsoColor;
+ BrickColor leftLegColor;
+ BrickColor rightLegColor;
+
+ public:
+ static Reflection::BoundProp prop_HeadColor;
+ static Reflection::BoundProp prop_LeftArmColor;
+ static Reflection::BoundProp prop_RightArmColor;
+ static Reflection::BoundProp prop_TorsoColor;
+ static Reflection::BoundProp prop_LeftLegColor;
+ static Reflection::BoundProp prop_RightLegColor;
+
+ public:
+ BodyColors();
+ private:
+ virtual void apply(Humanoid* humanoid);
+
+ void dataChanged(const Reflection::PropertyDescriptor& __formal)
+ {
+ if (Network::Players::backendProcessing(this, false))
+ {
+ Humanoid* humanoid = Humanoid::modelIsCharacter(getParent());
+ if (humanoid)
+ apply(humanoid);
+ }
+ }
+ };
+
+ extern const char* sShirtGraphic;
+ class ShirtGraphic : public DescribedCreatable
+ {
+ private:
+ TextureId graphic;
+ public:
+ static Reflection::BoundProp prop_Graphic;
+
+ public:
+ ShirtGraphic();
+ protected:
+ virtual void apply(Humanoid* humanoid);
+ private:
+ void dataChanged(const Reflection::PropertyDescriptor& __formal)
+ {
+ if (Network::Players::backendProcessing(this, false))
+ {
+ Humanoid* humanoid = Humanoid::modelIsCharacter(getParent());
+ if (humanoid)
+ apply(humanoid);
+ }
+ }
+ };
+
+ extern const char* sShirt;
+ class Shirt : public DescribedCreatable
+ {
+ private:
+ BrickColor leftSleeveColor;
+ BrickColor rightSleeveColor;
+ BrickColor torsoColor;
+ public:
+ static Reflection::BoundProp prop_leftSleeveColor;
+ static Reflection::BoundProp prop_rightSleeveColor;
+ static Reflection::BoundProp prop_torsoColor;
+
+ public:
+ Shirt();
+ private:
+ virtual void apply(Humanoid* humanoid);
+
+ void dataChanged(const Reflection::PropertyDescriptor& __formal)
+ {
+ if (Network::Players::backendProcessing(this, false))
+ {
+ Humanoid* humanoid = Humanoid::modelIsCharacter(getParent());
+ if (humanoid)
+ apply(humanoid);
+ }
+ }
+ };
+
+ extern const char* sSkin;
+ class Skin : public DescribedCreatable
+ {
+ private:
+ BrickColor skinColor;
+ public:
+ static Reflection::BoundProp prop_skinColor;
+
+ public:
+ Skin();
+ private:
+ virtual void apply(Humanoid* humanoid);
+
+ void dataChanged(const Reflection::PropertyDescriptor& __formal)
+ {
+ if (Network::Players::backendProcessing(this, false))
+ {
+ Humanoid* humanoid = Humanoid::modelIsCharacter(getParent());
+ if (humanoid)
+ apply(humanoid);
+ }
+ }
+ };
+}
diff --git a/Client/App/v8datamodel/CharacterAppearance.cpp b/Client/App/v8datamodel/CharacterAppearance.cpp
new file mode 100644
index 00000000..e02431a4
--- /dev/null
+++ b/Client/App/v8datamodel/CharacterAppearance.cpp
@@ -0,0 +1,148 @@
+#include "v8datamodel/CharacterAppearance.h"
+#include "v8datamodel/PartInstance.h"
+#include "v8datamodel/Decal.h"
+
+namespace RBX
+{
+ void CharacterAppearance::onAncestorChanged(const AncestorChanged& event)
+ {
+ if (event.child == this && Network::Players::backendProcessing(this, false))
+ {
+ Humanoid* humanoid = Humanoid::modelIsCharacter(getParent());
+ if (humanoid)
+ apply(humanoid);
+ }
+ }
+
+ bool CharacterAppearance::askSetParent(const Instance* instance) const
+ {
+ return fastDynamicCast(instance) != NULL;
+ }
+
+ ShirtGraphic::ShirtGraphic()
+ {
+ setName("Shirt Graphic");
+ }
+
+ void ShirtGraphic::apply(Humanoid* humanoid)
+ {
+ PartInstance* torso = humanoid->getTorso();
+ if (torso)
+ {
+ Decal* decal = torso->findFirstChildOfType();
+ if (decal)
+ decal->setTexture(graphic);
+ }
+ }
+
+ Shirt::Shirt()
+ : leftSleeveColor(BrickColor::lego_23),
+ rightSleeveColor(BrickColor::lego_23),
+ torsoColor(BrickColor::lego_1)
+ {
+ setName("Shirt");
+ }
+
+ void Shirt::apply(Humanoid* humanoid)
+ {
+ ShirtGraphic::apply(humanoid);
+
+ PartInstance* torso = humanoid->getTorso();
+ if (torso)
+ torso->setColor(torsoColor);
+
+ PartInstance* leftArm = humanoid->getLeftArm();
+ if (leftArm)
+ leftArm->setColor(leftSleeveColor);
+
+ PartInstance* rightArm = humanoid->getRightArm();
+ if (rightArm)
+ rightArm->setColor(rightSleeveColor);
+ }
+
+ Skin::Skin()
+ : skinColor(BrickColor::lego_226)
+ {
+ setName("Skin");
+ }
+
+ void Skin::apply(Humanoid* humanoid)
+ {
+ bool hasShirt = getParent()->findFirstChildOfType() != NULL;
+
+ PartInstance* head = humanoid->getHead();
+ if (head)
+ head->setColor(skinColor);
+
+ PartInstance* leftLeg = humanoid->getLeftLeg();
+ if (leftLeg)
+ leftLeg->setColor(skinColor);
+
+ PartInstance* rightLeg = humanoid->getRightLeg();
+ if (rightLeg)
+ rightLeg->setColor(skinColor);
+
+ if (!hasShirt)
+ {
+ PartInstance* torso = humanoid->getTorso();
+ if (torso)
+ torso->setColor(skinColor);
+
+ PartInstance* leftArm = humanoid->getLeftArm();
+ if (leftArm)
+ leftArm->setColor(skinColor);
+
+ PartInstance* rightArm = humanoid->getRightArm();
+ if (rightArm)
+ rightArm->setColor(skinColor);
+ }
+ }
+
+ BodyColors::BodyColors()
+ : headColor(BrickColor::lego_226),
+ leftArmColor(BrickColor::lego_226),
+ rightArmColor(BrickColor::lego_226),
+ torsoColor(BrickColor::lego_28),
+ leftLegColor(BrickColor::lego_23),
+ rightLegColor(BrickColor::lego_23)
+ {
+ setName("Body Colors");
+ }
+
+ void BodyColors::apply(Humanoid* humanoid)
+ {
+ Skin* skin = getParent()->findFirstChildOfType();
+
+ if (!skin)
+ {
+ bool hasShirt = getParent()->findFirstChildOfType() != NULL;
+
+ PartInstance* head = humanoid->getHead();
+ if (head)
+ head->setColor(headColor);
+
+ PartInstance* leftLeg = humanoid->getLeftLeg();
+ if (leftLeg)
+ leftLeg->setColor(leftLegColor);
+
+ PartInstance* rightLeg = humanoid->getRightLeg();
+ if (rightLeg)
+ rightLeg->setColor(rightLegColor);
+
+ if (!hasShirt)
+ {
+ PartInstance* torso = humanoid->getTorso();
+ if (torso)
+ torso->setColor(torsoColor);
+
+ PartInstance* leftArm = humanoid->getLeftArm();
+ if (leftArm)
+ leftArm->setColor(leftArmColor);
+
+ PartInstance* rightArm = humanoid->getRightArm();
+ if (rightArm)
+ rightArm->setColor(rightArmColor);
+ }
+ }
+ }
+}