diff --git a/Client/App/App.vcproj b/Client/App/App.vcproj index 6176a9ea..504e43eb 100644 --- a/Client/App/App.vcproj +++ b/Client/App/App.vcproj @@ -337,6 +337,10 @@ RelativePath=".\include\util\Debug.h" > + + @@ -785,6 +789,10 @@ + + @@ -797,6 +805,14 @@ RelativePath=".\include\v8datamodel\Camera.h" > + + + + @@ -805,6 +821,10 @@ RelativePath=".\include\v8datamodel\Decal.h" > + + @@ -813,10 +833,26 @@ RelativePath=".\include\v8datamodel\Feature.h" > + + + + + + + + @@ -841,6 +877,10 @@ RelativePath=".\include\v8datamodel\JointInstance.h" > + + @@ -849,10 +889,22 @@ RelativePath=".\include\v8datamodel\LocalBackpack.h" > + + + + + + @@ -865,6 +917,22 @@ RelativePath=".\include\v8datamodel\RootInstance.h" > + + + + + + + + @@ -897,14 +965,30 @@ RelativePath=".\include\v8datamodel\TimerService.h" > + + + + + + + + @@ -1346,6 +1430,10 @@ + + @@ -1354,10 +1442,22 @@ RelativePath=".\v8datamodel\Camera.cpp" > + + + + + + @@ -1366,22 +1466,70 @@ RelativePath=".\v8datamodel\Feature.cpp" > + + + + + + + + + + + + + + + + + + + + + + + + @@ -1394,10 +1542,26 @@ RelativePath=".\v8datamodel\RootInstance.cpp" > + + + + + + + + @@ -1406,6 +1570,18 @@ RelativePath=".\v8datamodel\Teams.cpp" > + + + + + + namespace RBX { + // These classes are only used in ICharacterSubject (found in v8datamodel). + // Since the constructors of these classes are completely inlined in all builds of RBXGS, their implementation is guessed. + class floatERA { float weight; float avg; public: - floatERA(float); - floatERA(); + floatERA(float weight) + : weight(weight) + { + reset(); + } + + floatERA() + : weight(1.0f) + { + reset(); + } void reset(); float pushAndGetAverage(float value); @@ -22,8 +35,17 @@ namespace RBX float x, y, z; public: - Vector3ERA(float); - Vector3ERA(); + Vector3ERA(float weight) + : weight(weight) + { + reset(); + } + + Vector3ERA() + : weight(1.0f) + { + reset(); + } void reset(); G3D::Vector3 pushAndGetAverage(G3D::Vector3 value); diff --git a/Client/App/include/util/Extents.h b/Client/App/include/util/Extents.h index 4ea1c2ce..3339f465 100644 --- a/Client/App/include/util/Extents.h +++ b/Client/App/include/util/Extents.h @@ -22,6 +22,11 @@ namespace RBX public: bool operator==(const Extents&) const; bool operator!=(const Extents&) const; + Extents& operator=(const Extents& other) + { + this->low = other.low; + this->high = other.high; + } const G3D::Vector3& min() const {return this->low;} const G3D::Vector3& max() const {return this->high;} G3D::Vector3 getCorner(int i) const; diff --git a/Client/App/include/util/Http.h b/Client/App/include/util/Http.h index f3403d60..20541e7e 100644 --- a/Client/App/include/util/Http.h +++ b/Client/App/include/util/Http.h @@ -10,14 +10,18 @@ namespace RBX std::string additionalHeaders; public: - //Http(const Http&); - Http(const std::string&); - Http(const char*); + Http(const std::string& url) + : url(url) + { + } + + Http(const char* url) + : url(url) + { + } public: void post(std::istream&, bool, std::string&); void get(std::string&); - public: - ~Http(); public: static bool trustCheck(const char*); diff --git a/Client/App/include/util/IRenderable.h b/Client/App/include/util/IRenderable.h index 5fb59447..c1748c6f 100644 --- a/Client/App/include/util/IRenderable.h +++ b/Client/App/include/util/IRenderable.h @@ -2,7 +2,6 @@ #include "RbxGraphics/Adorn.h" #include "AppDraw/SelectState.h" #include "util/IndexArray.h" -#include "AppDraw/SelectState.h" namespace RBX { @@ -47,9 +46,20 @@ namespace RBX void shouldRenderSetDirty(); - virtual void render2d(Adorn* adorn); - virtual void render3dAdorn(Adorn* adorn); - virtual void render3dSelect(Adorn* adorn, SelectState selectState); + virtual void render2d(Adorn* adorn) + { + return; + } + + virtual void render3dAdorn(Adorn* adorn) + { + return; + } + + virtual void render3dSelect(Adorn* adorn, SelectState selectState) + { + return; + } }; diff --git a/Client/App/include/util/Name.h b/Client/App/include/util/Name.h index 57e9e063..0b809786 100644 --- a/Client/App/include/util/Name.h +++ b/Client/App/include/util/Name.h @@ -90,10 +90,28 @@ namespace RBX { public: virtual const Name& getName() const = 0; + }; + + template + class Named : public DerivedClass + { public: - //INamed(const INamed&); - INamed(); + typedef Named Base; + + Named() + : DerivedClass() + { + } + + template + Named(Arg0Type type) + : DerivedClass(type) + { + } + + virtual const Name& getName() const; + public: - //INamed& operator=(const INamed&); + static const Name& name(); }; } diff --git a/Client/App/include/util/RunStateOwner.h b/Client/App/include/util/RunStateOwner.h index 76969a79..cca05d9b 100644 --- a/Client/App/include/util/RunStateOwner.h +++ b/Client/App/include/util/RunStateOwner.h @@ -29,7 +29,7 @@ namespace RBX RunTransition(RunState oldState, RunState newState) : oldState(oldState), - newState(newState) + newState(newState) { } diff --git a/Client/App/include/util/StateStack.h b/Client/App/include/util/StateStack.h index 1e2665d3..bb6ebb02 100644 --- a/Client/App/include/util/StateStack.h +++ b/Client/App/include/util/StateStack.h @@ -20,8 +20,11 @@ namespace RBX int currentState; std::vector stack; public: - //StateStack(const StateStack&); - //StateStack(); + StateStack() + : currentState(-1) + { + } + ~StateStack(); void pushState(const Name&, T*, T*); @@ -36,7 +39,5 @@ namespace RBX virtual bool isStackTooBig() const; private: void clearStackAfter(int); - - //StateStack& operator=(const StateStack&); }; } diff --git a/Client/App/include/v8datamodel/Accoutrement.h b/Client/App/include/v8datamodel/Accoutrement.h new file mode 100644 index 00000000..d8ef0ded --- /dev/null +++ b/Client/App/include/v8datamodel/Accoutrement.h @@ -0,0 +1,94 @@ +#pragma once +#include "v8tree/Instance.h" +#include "v8datamodel/IEquipable.h" +#include "util/IRenderable.h" +#include "util/ICameraSubject.h" +#include "util/ISelectable3d.h" + +namespace RBX +{ + class IReferenceBinder; + class ModelInstance; + class PartInstance; + + extern const char* sAccoutrement; + + class Accoutrement : public DescribedCreatable, + public IEquipable, + public IRenderable, + public virtual ICameraSubject, + public virtual ISelectable3d + { + enum AccoutrementState + { + NOTHING, + HAS_HANDLE, + IN_WORKSPACE, + IN_CHARACTER, + EQUIPPED + }; + + protected: + AccoutrementState backendAccoutrementState; + G3D::CoordinateFrame attachmentPoint; + boost::signals::scoped_connection handleTouched; + boost::signals::scoped_connection characterChildAdded; + boost::signals::scoped_connection characterChildRemoved; + public: + static bool writeUnlocked; + + protected: + void onEvent_AddedBackend(boost::shared_ptr); + void onEvent_RemovedBackend(boost::shared_ptr); + void onEvent_HandleTouched(boost::shared_ptr); + AccoutrementState computeDesiredState(Instance*); + AccoutrementState computeDesiredState(); + void setDesiredState(AccoutrementState, const ServiceProvider*); + void setBackendAccoutrementStateNoReplicate(int); + void rebuildBackendState(); + void connectTouchEvent(); + void upTo_Equipped(); + void upTo_InCharacter(); + void upTo_InWorkspace(); + void upTo_HasHandle(); + void downFrom_Equipped(); + void downFrom_InCharacter(); + void downFrom_InWorkspace(); + void downFrom_HasHandle(); + void onChildAdded(); + void onChildRemoved(); + virtual void onAncestorChanged(const AncestorChanged&); + virtual bool askSetParent(const Instance*) const; + virtual bool askAddChild(const Instance*) const; + virtual void readProperty(const XmlElement*, IReferenceBinder&); + virtual const G3D::CoordinateFrame getLocation() const; + bool drawSelected() const; + virtual void render3dSelect(Adorn*, SelectState); + public: + Accoutrement(); + virtual ~Accoutrement(); + virtual XmlElement* write(); + PartInstance* getHandle(); + const PartInstance* getHandleConst() const; + void setBackendAccoutrementState(int); + int getBackendAccoutrementState() const; + const G3D::CoordinateFrame& getAttachmentPoint() const; + void setAttachmentPoint(const G3D::CoordinateFrame&); + virtual void onCameraNear(float); + const G3D::Vector3 getAttachmentPos() const; + const G3D::Vector3 getAttachmentForward() const; + const G3D::Vector3 getAttachmentUp() const; + const G3D::Vector3 getAttachmentRight() const; + void setAttachmentPos(const G3D::Vector3&); + void setAttachmentForward(const G3D::Vector3&); + void setAttachmentUp(const G3D::Vector3&); + void setAttachmentRight(const G3D::Vector3&); + + protected: + static AccoutrementState characterCanPickUpAccoutrement(Instance*); + static void UnequipThis(boost::shared_ptr); + public: + static void dropAll(ModelInstance*); + static void dropAllOthers(ModelInstance*, Accoutrement*); + }; +} diff --git a/Client/App/include/v8datamodel/Backpack.h b/Client/App/include/v8datamodel/Backpack.h index ba476fab..2b444d42 100644 --- a/Client/App/include/v8datamodel/Backpack.h +++ b/Client/App/include/v8datamodel/Backpack.h @@ -1,20 +1,16 @@ #pragma once -#include "v8datamodel/Hopper.h" #include "script/Script.h" +#include "v8datamodel/Hopper.h" namespace RBX { extern const char* sBackpack; class Backpack : public RBX::DescribedCreatable, - public IScriptOwner + public IScriptOwner { private: - virtual IScriptOwner* scriptShouldRun(Script*); + virtual IScriptOwner* scriptShouldRun(Script* script); public: - //Backpack(const Backpack&); Backpack(); - virtual ~Backpack(); - public: - //Backpack& operator=(const Backpack&); }; } diff --git a/Client/App/include/v8datamodel/DataModel.h b/Client/App/include/v8datamodel/DataModel.h new file mode 100644 index 00000000..40f2bc1c --- /dev/null +++ b/Client/App/include/v8datamodel/DataModel.h @@ -0,0 +1,144 @@ +#pragma once +#include "util/RunStateOwner.h" +#include "util/Evaluator.h" +#include "v8tree/Verb.h" +#include "gui/GuiEvent.h" + +namespace RBX +{ + class LocalBackpack; + class Workspace; + class StarterPackService; + class GuiRoot; + class TimeState; + class IMetric; + + extern const char* sDataModel; + + class DataModel : public DescribedNonCreatable, + public VerbContainer, + public IDataState, + public Evaluator, + public Listener + { + public: + class Lock + { + private: + boost::shared_ptr mutex; + boost::recursive_mutex::scoped_lock* lock; + + private: + void doLock(const DataModel* dataModel); + public: + Lock(const DataModel* dataModel); + Lock(boost::shared_ptr dataModel); + ~Lock(); + }; + + private: + boost::shared_ptr localBackpack; + boost::shared_ptr workspace; + boost::shared_ptr runService; + boost::shared_ptr starterPackService; + boost::shared_ptr guiRoot; + boost::shared_ptr guiHooks; + GuiTarget* guiTarget; + bool forceArrowCursor; + std::string uiMessage; + int drawId; + IMetric* tempMetric; + bool dirty; + boost::shared_ptr mutex; + boost::scoped_ptr timeState; + + private: + GuiResponse processAccelerators(const GuiEvent&); + void processEvent(const UIEvent&); + void initializeContents(); + public: + void clearContents(); + boost::shared_ptr getMutex() const; + DataModel(); + virtual ~DataModel(); + void loadContent(ContentId); + void save(ContentId); + std::string httpGet(std::string url, bool synchronous); + std::string httpPost(std::string url, std::string data, bool synchronous); + void close(); + boost::shared_ptr>> get(ContentId); + void raiseClose(); + int numChatOptions(); + void buildGui(Adorn*); + void processGui(const UIEvent&); + GuiRoot* getGuiRoot() const; + GuiRoot* getGuiHooks() const; + + virtual void setDirty(bool dirty) + { + this->dirty = dirty; + } + + virtual bool isDirty() const + { + return dirty; + } + + virtual bool isStackTooBig() const; + Workspace* getWorkspace() const; + float step(float); + float getSimTime() const; + TimeState* getTimeState(); + virtual std::string evaluate(const std::string&) const; + void renderPass2d(Adorn*, IMetric*); + void renderPass3dAdorn(Adorn*); + + void setUiMessage(std::string message) + { + uiMessage = message; + } + + void clearUiMessage() + { + uiMessage = ""; + } + + void setUiMessageBrickCount() + { + uiMessage = "[[[progress]]]"; + } + + bool canDelaySwapBuffer() const; + protected: + virtual bool askAddChild(const Instance* instance) const; + virtual void onChildAdded(Instance* child); + + virtual void onChildChanged(Instance* instance, const PropertyChanged& event) + { + Instance::onChildChanged(instance, event); + setDirty(true); + } + + virtual void onDescendentAdded(Instance* instance) + { + ServiceProvider::onDescendentAdded(instance); + setDirty(true); + } + + virtual void onDescendentRemoving(const boost::shared_ptr& instance) + { + ServiceProvider::onDescendentRemoving(instance); + setDirty(true); + } + + virtual void onEvent(const RunService* source, RunTransition event); + + public: + static boost::shared_ptr getMutex(Instance*); + static boost::shared_ptr createDataModel(); + static void closeDataModel(boost::shared_ptr, bool); + private: + static std::string doHttpGet(std::string url); + static std::string doHttpPost(std::string url, std::string data); + }; +} diff --git a/Client/App/include/v8datamodel/DebrisService.h b/Client/App/include/v8datamodel/DebrisService.h new file mode 100644 index 00000000..4f8d5fe3 --- /dev/null +++ b/Client/App/include/v8datamodel/DebrisService.h @@ -0,0 +1,32 @@ +#pragma once +#include +#include "v8tree/Instance.h" +#include "v8tree/Service.h" + +namespace RBX +{ + class TimerService; + + extern const char* sDebrisService; + + class DebrisService : public DescribedCreatable, public Service + { + private: + std::queue> queue; + int maxItems; + TimerService* timer; + + public: + DebrisService(); + void addItem(boost::shared_ptr item, double lifetime); + void setMaxItems(int value); + int getMaxItems() const + { + return maxItems; + } + protected: + virtual void onServiceProvider(const ServiceProvider* oldProvider, const ServiceProvider* newProvider); + private: + void cleanup(); + }; +} diff --git a/Client/App/include/v8datamodel/Explosion.h b/Client/App/include/v8datamodel/Explosion.h new file mode 100644 index 00000000..782e66cf --- /dev/null +++ b/Client/App/include/v8datamodel/Explosion.h @@ -0,0 +1,58 @@ +#pragma once +#include "util/RunStateOwner.h" +#include "util/IRenderable.h" + +namespace RBX +{ + class Primitive; + + extern const char* sExplosion; + + class Explosion : public DescribedCreatable, + public Listener, + public IRenderable + { + private: + float age; + G3D::Vector3 position; + float blastRadius; + float blastPressure; + public: + static Reflection::BoundProp propPosition; + static Reflection::BoundProp propBlastPressure; + + private: + float renderTime() const; + float visualRadius() const; + float killRadius() const; + float blastMaxObjectRadius() const; + float killMaxObjectRadius() const; + void doKill(); + void doBlast(const G3D::Array& primitives); + void signalBlast(const G3D::Array& primitives); + virtual void onEvent(const RunService*, Stepped); + virtual bool askSetParent(const Instance* instance) const; + virtual void onServiceProvider(const ServiceProvider* oldProvider, const ServiceProvider* newProvider); + + virtual bool shouldRender3dAdorn() const + { + return true; + } + + virtual void render3dAdorn(Adorn* adorn); + public: + Explosion(); + + virtual ~Explosion() + { + } + + void setVisualOnly(); + void setBlastRadius(float _blastRadius); + + float getBlastRadius() const + { + return blastRadius; + } + }; +} diff --git a/Client/App/include/v8datamodel/Flag.h b/Client/App/include/v8datamodel/Flag.h new file mode 100644 index 00000000..a2a6e7c9 --- /dev/null +++ b/Client/App/include/v8datamodel/Flag.h @@ -0,0 +1,52 @@ +#pragma once +#include "v8datamodel/Tool.h" +#include "v8datamodel/BrickColor.h" + +namespace RBX +{ + class TimerService; + + namespace Network + { + class Player; + } + + extern const char* sFlag; + + class Flag : public DescribedCreatable + { + enum FlagState + { + NOTHING, + LOOSE, + IN_STAND, + EQUIPPED + }; + + private: + boost::shared_ptr evilClone; + FlagState state; + boost::signals::scoped_connection flagTouched; + TimerService* timer; + public: + BrickColor teamColor; + + private: + void onEvent_flagTouched(boost::shared_ptr); + void doUglyPeriodicCloneHack(); + protected: + virtual bool canUnequip() + { + return false; + } + + virtual bool canBePickedUpByPlayer(Network::Player* p); + public: + BrickColor getTeamColor() const; + void setTeamColor(BrickColor color); + virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + Flag(); + virtual ~Flag(); + virtual void onChildAdded(Instance* instance); + }; +} diff --git a/Client/App/include/v8datamodel/FlagStand.h b/Client/App/include/v8datamodel/FlagStand.h new file mode 100644 index 00000000..8e56adf4 --- /dev/null +++ b/Client/App/include/v8datamodel/FlagStand.h @@ -0,0 +1,45 @@ +#pragma once +#include "v8datamodel/PartInstance.h" +#include "v8tree/Service.h" + +namespace RBX +{ + class Flag; + + extern const char* sFlagStand; + + class FlagStand : public DescribedCreatable + { + private: + boost::signals::scoped_connection standTouched; + public: + BrickColor teamColor; + + private: + void onEvent_standTouched(boost::shared_ptr); + public: + FlagStand(); + virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + void AffixFlag(Flag* flag); + bool HasFlag(); + Flag* GetFlag(); + BrickColor getTeamColor() const; + void setTeamColor(BrickColor color); + }; + + extern const char* sFlagStandService; + + class FlagStandService : public DescribedCreatable, public Service + { + private: + std::list flagStands; + + public: + FlagStandService(); + virtual ~FlagStandService(); + FlagStand* FindClosestEmptyStandForFlag(Flag*); + FlagStand* FindStandWithFlag(Flag* f); + void RegisterFlagStand(FlagStand*); + void UnregisterFlagStand(FlagStand*); + }; +} diff --git a/Client/App/include/v8datamodel/GameSettings.h b/Client/App/include/v8datamodel/GameSettings.h new file mode 100644 index 00000000..db156004 --- /dev/null +++ b/Client/App/include/v8datamodel/GameSettings.h @@ -0,0 +1,20 @@ +#pragma once +#include "v8datamodel/GlobalSettings.h" + +namespace RBX +{ + extern const char* sGameSettings; + + class GameSettings : public GlobalSettingsItem + { + public: + int chatHistory; + int chatScrollLength; + bool soundEnabled; + bool softwareSound; + bool animatedCharacter; + + public: + GameSettings(); + }; +} diff --git a/Client/App/include/v8datamodel/GlobalSettings.h b/Client/App/include/v8datamodel/GlobalSettings.h index f27cdb76..9d521a41 100644 --- a/Client/App/include/v8datamodel/GlobalSettings.h +++ b/Client/App/include/v8datamodel/GlobalSettings.h @@ -19,17 +19,11 @@ namespace RBX { return fastDynamicCast(instance) != NULL; } - public: - //Item(const Item&); - Item(); - ~Item(); - //Item& operator=(const Item&); }; public: static boost::recursive_mutex mutex; - //GlobalSettings(const GlobalSettings&); GlobalSettings() { setName("Global Settings"); diff --git a/Client/App/include/v8datamodel/Gyro.h b/Client/App/include/v8datamodel/Gyro.h new file mode 100644 index 00000000..41db0db1 --- /dev/null +++ b/Client/App/include/v8datamodel/Gyro.h @@ -0,0 +1,162 @@ +#pragma once +#include "util/RunStateOwner.h" +#include "v8kernel/Connector.h" + +namespace RBX +{ + class World; + class PartInstance; + + class BodyMover : public Instance, public Connector, public Listener + { + protected: + World* world; + PartInstance* part; + + protected: + BodyMover(const char*); + public: + virtual ~BodyMover(); + virtual bool askSetParent(const Instance*) const; + protected: + virtual bool preventBodySleep() const; + virtual void onAncestorChanged(const AncestorChanged&); + virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + virtual void onEvent(const RunService*, Stepped); + private: + void updateWorld(); + }; + + extern const char* sBodyGyro; + + class BodyGyro : public DescribedCreatable + { + private: + float kP; + float kD; + G3D::Vector3 maxTorque; + G3D::CoordinateFrame cframe; + public: + static Reflection::BoundProp prop_kP; + static Reflection::BoundProp prop_kD; + static Reflection::BoundProp prop_maxTorque; + static Reflection::BoundProp prop_cframe; + + private: + void computeBalance(Body*); + void computeOrientation(Body*); + public: + BodyGyro(); + virtual void computeForce(const float, bool); + }; + + extern const char* sBodyPosition; + + class BodyPosition : public DescribedCreatable + { + private: + float kP; + float kD; + G3D::Vector3 maxForce; + G3D::Vector3 position; + G3D::Vector3 lastForce; + public: + static Reflection::BoundProp prop_kP; + static Reflection::BoundProp prop_kD; + static Reflection::BoundProp prop_maxForce; + static Reflection::BoundProp prop_position; + + public: + BodyPosition(); + G3D::Vector3 getLastForce(); + virtual void computeForce(const float, bool); + }; + + extern const char* sBodyVelocity; + + class BodyVelocity : public DescribedCreatable + { + private: + float kP; + G3D::Vector3 maxForce; + G3D::Vector3 position; + G3D::Vector3 lastForce; + public: + static Reflection::BoundProp prop_kP; + static Reflection::BoundProp prop_maxForce; + static Reflection::BoundProp prop_position; + + protected: + virtual bool preventBodySleep() const; + public: + BodyVelocity(); + G3D::Vector3 getLastForce(); + virtual void computeForce(const float, bool); + }; + + extern const char* sBodyThrust; + + class BodyThrust : public DescribedCreatable + { + private: + G3D::Vector3 force; + G3D::Vector3 location; + public: + static Reflection::BoundProp prop_force; + static Reflection::BoundProp prop_location; + + protected: + virtual bool preventBodySleep() const; + public: + BodyThrust(); + virtual void computeForce(const float, bool); + }; + + extern const char* sRocket; + + class Rocket : public DescribedCreatable + { + private: + bool active; + boost::shared_ptr target; + G3D::Vector3 targetOffset; + float targetRadius; + bool firedEvent; + float maxThrust; + float kThrustP; + float kThrustD; + float maxSpeed; + float kTurnP; + float kTurnD; + G3D::Vector3 maxTorque; + float cartoonFactor; + public: + static Reflection::RefPropDescriptor prop_Target; + static Reflection::BoundProp prop_targetOffset; + static Reflection::BoundProp prop_targetRadius; + static Reflection::BoundProp prop_MaxThrust; + static Reflection::BoundProp prop_ThrustP; + static Reflection::BoundProp prop_ThrustD; + static Reflection::BoundProp prop_MaxSpeed; + static Reflection::BoundProp prop_MaxTorque; + static Reflection::BoundProp prop_TurnP; + static Reflection::BoundProp prop_TurnD; + static Reflection::BoundProp prop_CartoonFactor; + static Reflection::BoundFuncDesc func_Fire; + static Reflection::BoundFuncDesc func_Abort; + static Reflection::SignalDesc event_ReachedTarget; + + public: + Rocket(); + void fire(); + void abort(); + virtual void computeForce(const float, bool); + protected: + virtual void onEvent(const RunService*, Stepped); + private: + G3D::Vector3 turn(Body*, const G3D::Vector3&); + PartInstance* getTarget() const; + void setTarget(PartInstance*); + void onGoalChanged(const Reflection::PropertyDescriptor&); + }; +} diff --git a/Client/App/include/v8datamodel/Hopper.h b/Client/App/include/v8datamodel/Hopper.h index 52623be5..9c7971b9 100644 --- a/Client/App/include/v8datamodel/Hopper.h +++ b/Client/App/include/v8datamodel/Hopper.h @@ -1,20 +1,17 @@ #pragma once -#include "v8datamodel/LocalBackpack.h" #include "v8tree/Service.h" +#include "gui/Widget.h" +#include "gui/GuiDraw.h" namespace RBX { class Hopper : public RelativePanel { protected: - virtual bool askSetParent(const Instance*) const; - virtual bool askAddChild(const Instance*) const; + virtual bool askSetParent(const Instance* instance) const; + virtual bool askAddChild(const Instance* instance) const; public: - //Hopper(const Hopper&); Hopper(); - virtual ~Hopper(); - public: - //Hopper& operator=(const Hopper&); }; extern const char* sStarterPackService; @@ -22,14 +19,62 @@ namespace RBX public Service { public: - //StarterPackService(const StarterPackService&); StarterPackService(); - public: + virtual void render2d(Adorn* adorn); + }; +} + +namespace RBX +{ + extern const char* sBackpackItem; + class BackpackItem : public DescribedNonCreatable + { + private: + GuiDrawImage guiImageDraw; + TextureId textureId; + + private: + bool inBackpack(); + virtual bool askSetParent(const Instance* instance) const; + virtual bool askAddChild(const Instance* instance) const; + protected: + virtual G3D::Vector2 getSize() const; virtual void render2d(Adorn*); + /* + TODO: + + isEnabled is defined in the header, however defining it here causes problems, + as doing so would require including Backpack.h in this header. + + This is not easily possible without doing some very hacky workarounds, + as Hopper needs to be defined before Backpack is, and + Backpack needs to be defined before BackpackItem is. + */ + virtual bool isEnabled(); + int getBinId() const; public: - virtual ~StarterPackService(); - public: - //StarterPackService& operator=(const StarterPackService&); + void setTextureId(const TextureId& value); + const TextureId getTextureId() const; + + virtual bool drawEnabled() const + { + return true; + } + + virtual bool drawSelected() const + { + return false; + } + + virtual void onLocalClicked() + { + return; + } + + virtual void onLocalOtherClicked() + { + return; + } }; extern const char* sHopperBin; @@ -56,20 +101,22 @@ namespace RBX void onSelectScript(); void onSelectCommand(); int getCursor(); - virtual bool drawSelected() const; + virtual bool drawSelected() const + { + return active; + } public: - //HopperBin(const HopperBin&); HopperBin(); public: - BinType getBinType() const; - void setBinType(const BinType); + BinType getBinType() const + { + return binType; + } + + void setBinType(const BinType value); virtual void onLocalClicked(); virtual void onLocalOtherClicked(); - void setLegacyCommand(const std::string&); - void setLegacyTextureName(const std::string&); - public: - virtual ~HopperBin(); - public: - //HopperBin& operator=(const HopperBin&); + void setLegacyCommand(const std::string& text); + void setLegacyTextureName(const std::string& value); }; } diff --git a/Client/App/include/v8datamodel/ICameraOwner.h b/Client/App/include/v8datamodel/ICameraOwner.h index c3b5e366..caa15adc 100644 --- a/Client/App/include/v8datamodel/ICameraOwner.h +++ b/Client/App/include/v8datamodel/ICameraOwner.h @@ -26,12 +26,12 @@ namespace RBX virtual void cameraMoved() = 0; virtual Extents computeCameraOwnerExtents() = 0; public: - void setCameraIgnoreParts(const std::vector&); - void setCameraIgnoreParts(PartInstance*); + void setCameraIgnoreParts(const std::vector& _set); + void setCameraIgnoreParts(PartInstance* _set); void clearCameraIgnoreParts() { cameraIgnoreParts.clear(); } - void getCameraIgnorePrimitives(std::vector&); + void getCameraIgnorePrimitives(std::vector& primitives); }; } diff --git a/Client/App/include/v8datamodel/ICharacterSubject.h b/Client/App/include/v8datamodel/ICharacterSubject.h index 056b8d39..8cfd5dca 100644 --- a/Client/App/include/v8datamodel/ICharacterSubject.h +++ b/Client/App/include/v8datamodel/ICharacterSubject.h @@ -10,7 +10,7 @@ namespace RBX class Primitive; class ContactManager; - class ICharacterSubject : public ICameraSubject + class __declspec(novtable) ICharacterSubject : public ICameraSubject { private: Vector3ERA focusERA; @@ -24,13 +24,12 @@ namespace RBX G3D::Vector3 goalInFocus; private: - G3D::CoordinateFrame getFocusLookingAtGoal(const G3D::CoordinateFrame&, const G3D::CoordinateFrame&); + G3D::CoordinateFrame getFocusLookingAtGoal(const G3D::CoordinateFrame& cameraFocus, const G3D::CoordinateFrame& cameraGoal); bool testOcclusion(const G3D::CoordinateFrame&, const G3D::CoordinateFrame&, float&); - G3D::CoordinateFrame goalFromDistance(const G3D::CoordinateFrame&, const G3D::CoordinateFrame&, const float); - virtual bool zoom(const float, G3D::CoordinateFrame&, G3D::CoordinateFrame&); + G3D::CoordinateFrame goalFromDistance(const G3D::CoordinateFrame& cameraFocus, const G3D::CoordinateFrame& cameraGoal, const float distance); + virtual bool zoom(const float in, G3D::CoordinateFrame& cameraGoal, G3D::CoordinateFrame& cameraFocus); virtual void stepGoalAndFocus(G3D::CoordinateFrame&, G3D::CoordinateFrame&, bool); public: - //ICharacterSubject(const ICharacterSubject&); ICharacterSubject(); public: virtual ContactManager* getContactManager() = 0; @@ -43,9 +42,5 @@ namespace RBX void onHeartBeat(G3D::CoordinateFrame&, G3D::CoordinateFrame&); void setCursorCenterLocked(bool); bool getCursorCenterLocked() const; - public: - virtual ~ICharacterSubject(); - public: - //ICharacterSubject& operator=(const ICharacterSubject&); }; } diff --git a/Client/App/include/v8datamodel/IEquipable.h b/Client/App/include/v8datamodel/IEquipable.h index a2bcab97..4041e9d6 100644 --- a/Client/App/include/v8datamodel/IEquipable.h +++ b/Client/App/include/v8datamodel/IEquipable.h @@ -9,20 +9,16 @@ namespace RBX class PartInstance; class Workspace; - class IEquipable + class __declspec(novtable) IEquipable { protected: boost::shared_ptr weld; Workspace* workspace; protected: - void buildWeld(PartInstance*, PartInstance*, const G3D::CoordinateFrame&, const G3D::CoordinateFrame&, const std::string&); - public: - //IEquipable(const IEquipable&); + void buildWeld(PartInstance* humanoidPart, PartInstance* gadgetPart, const G3D::CoordinateFrame& humanoidCoord, const G3D::CoordinateFrame& gadgetCoord, const std::string& name); protected: IEquipable(); virtual ~IEquipable(); - public: - //IEquipable& operator=(const IEquipable&); }; } diff --git a/Client/App/include/v8datamodel/JointInstance.h b/Client/App/include/v8datamodel/JointInstance.h index 8a224cf3..cf940ae2 100644 --- a/Client/App/include/v8datamodel/JointInstance.h +++ b/Client/App/include/v8datamodel/JointInstance.h @@ -22,6 +22,7 @@ namespace RBX public: JointInstance(Joint* joint); ~JointInstance(); + Joint::JointType getJointType() const; }; extern const char* sAutoJoint; @@ -63,7 +64,6 @@ namespace RBX public: Snap(Joint* joint); Snap(); - virtual ~Snap(); }; extern const char* sWeld; @@ -72,7 +72,6 @@ namespace RBX public: Weld(Joint* joint); Weld(); - virtual ~Weld(); }; extern const char* sGlue; @@ -81,7 +80,6 @@ namespace RBX public: Glue(Joint* joint); Glue(); - virtual ~Glue(); }; extern const char* sRotate; @@ -90,7 +88,6 @@ namespace RBX public: Rotate(Joint* joint); Rotate(); - virtual ~Rotate(); }; extern const char* sRotateP; @@ -99,7 +96,6 @@ namespace RBX public: RotateP(Joint* joint); RotateP(); - virtual ~RotateP(); }; extern const char* sRotateV; @@ -108,7 +104,6 @@ namespace RBX public: RotateV(Joint* joint); RotateV(); - virtual ~RotateV(); }; extern const char* sMotor; @@ -131,7 +126,5 @@ namespace RBX float getCurrentAngle() const; void setCurrentAngle(float value); - - virtual ~Motor(); }; } diff --git a/Client/App/include/v8datamodel/JointsService.h b/Client/App/include/v8datamodel/JointsService.h new file mode 100644 index 00000000..5437cd41 --- /dev/null +++ b/Client/App/include/v8datamodel/JointsService.h @@ -0,0 +1,43 @@ +#pragma once +#include "v8datamodel/JointInstance.h" +#include "v8tree/Instance.h" +#include "v8tree/Service.h" +#include "v8world/World.h" +#include "util/IRenderable.h" + +namespace RBX +{ + class JointsService : public NonFactoryProduct, + public Service, + public IRenderableBucket, + public Listener, + public Listener + { + public: + World* world; + + private: + virtual void onDescendentAdded(Instance* instance); + virtual void onDescendentRemoving(const boost::shared_ptr&); + + virtual bool askAddChild(const Instance* instance) const + { + return fastDynamicCast(instance) != NULL; + } + + virtual XmlElement* write() + { + return NULL; + } + + virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + virtual void onEvent(const World* source, AutoDestroy event); + virtual void onEvent(const World* source, AutoJoin event); + public: + JointsService() + : world(NULL) + { + setName("JointsService"); + } + }; +} diff --git a/Client/App/include/v8datamodel/LocalBackpack.h b/Client/App/include/v8datamodel/LocalBackpack.h index a47eab2d..2a6d0b4d 100644 --- a/Client/App/include/v8datamodel/LocalBackpack.h +++ b/Client/App/include/v8datamodel/LocalBackpack.h @@ -1,37 +1,91 @@ #pragma once -#include "gui/Widget.h" -#include "gui/GuiDraw.h" +#include "v8datamodel/Hopper.h" +#include "Network/Player.h" namespace RBX { - extern const char* sBackpackItem; - class BackpackItem : public DescribedNonCreatable + extern const char* sLocalBackpackItem; + class LocalBackpackItem : public DescribedCreatable { private: + boost::shared_ptr myItem; GuiDrawImage guiImageDraw; - TextureId textureId; - + private: - bool inBackpack(); - virtual bool askSetParent(const Instance*) const; - virtual bool askAddChild(const Instance*) const; - protected: + virtual bool askSetParent(const Instance* instance) const + { + return true; + } + virtual G3D::Vector2 getSize() const; virtual void render2d(Adorn*); - virtual bool isEnabled(); + virtual void onClick(const GuiEvent& event); int getBinId() const; public: - void setTextureId(const TextureId&); - const TextureId getTextureId() const; - virtual bool drawEnabled() const; - virtual bool drawSelected() const; - virtual void onLocalClicked(); - virtual void onLocalOtherClicked(); - public: - //BackpackItem(const BackpackItem&); - BackpackItem(); - virtual ~BackpackItem(); + LocalBackpackItem(); + + void setItem(BackpackItem* item) + { + myItem = shared_from(item); + } + + BackpackItem* getItem() + { + return myItem.get(); + } + }; + + extern const char* sLocalBackpack; + class LocalBackpack : public DescribedCreatable, + public Service, + public Listener, + public Listener, + public Listener, + public Listener, + public Listener, + public Listener + { + private: + boost::shared_ptr players; + boost::shared_ptr localPlayer; + boost::shared_ptr localBackpack; + boost::shared_ptr localCharacter; + boost::shared_ptr pendingClick; + int lastRemovedIndex; + + private: + virtual bool askSetParent(const Instance* instance) const + { + return true; + } + virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + virtual void onEvent(const Network::Player* source, Network::CharacterRemoving event); + virtual void onEvent(const Network::Player* source, Network::CharacterAdded event); + virtual void onEvent(const Instance* source, DescendentRemoving event); + virtual void onEvent(const Instance* source, DescendentAdded event); + virtual void onEvent(const Instance* source, ChildRemoved event); + virtual void onEvent(const Instance* source, ChildAdded event); + void onLocalCharacterAdded(Instance*); + void onLocalPlayerAdded(Network::Player*); + void onLocalBackpackAdded(Backpack*); + void clearAll(); + void clearLocalCharacter(); + void clearLocalPlayer(); + void clearLocalBackpack(); + void insertBackpackItem(BackpackItem*); + void removeBackpackItem(BackpackItem*); public: - //BackpackItem& operator=(const BackpackItem&); + LocalBackpack(); + virtual ~LocalBackpack(); + void onHeartbeat(); + void onClick(LocalBackpackItem* clickedItem); + bool onKey(int); + void cycleUp(); + void cycleDown(); + + virtual XmlElement* write() + { + return NULL; + } }; } diff --git a/Client/App/include/v8datamodel/Message.h b/Client/App/include/v8datamodel/Message.h new file mode 100644 index 00000000..4ab37d42 --- /dev/null +++ b/Client/App/include/v8datamodel/Message.h @@ -0,0 +1,48 @@ +#pragma once +#include "v8tree/Instance.h" +#include "util/IRenderable.h" + +namespace RBX +{ + extern const char* sMessage; + + class Message : public DescribedCreatable, public IRenderable + { + protected: + std::string text; + + protected: + void renderFullScreen(Adorn* adorn); + void renderPersonalMsg(Adorn* adorn); + public: + Message(); + + virtual bool shouldRender2d() const + { + return true; + + } + + virtual void render2d(Adorn* adorn); + + virtual bool askSetParent(const Instance* instance) const + { + return true; + } + + const std::string& getText() const + { + return text; + } + + void setText(const std::string& value); + }; + + extern const char* sHint; + + class Hint : public DescribedCreatable + { + private: + virtual void render2d(Adorn* adorn); + }; +} diff --git a/Client/App/include/v8datamodel/Mouse.h b/Client/App/include/v8datamodel/Mouse.h new file mode 100644 index 00000000..888dbca8 --- /dev/null +++ b/Client/App/include/v8datamodel/Mouse.h @@ -0,0 +1,87 @@ +#pragma once +#include "v8tree/Instance.h" +#include "util/UIEvent.h" +#include "util/TextureId.h" +#include + +namespace RBX +{ + class MouseCommand; + class PartInstance; + + extern const char* sMouse; + + class Mouse : public DescribedNonCreatable + { + private: + UIEvent lastEvent; + TextureId icon; + MouseCommand* command; + + private: + void cacheUIEvent(const UIEvent& uiEvent) + { + lastEvent = uiEvent; + lastEvent.eventType = UIEvent::NO_EVENT; + } + + void checkActive() const + { + if (!command) + { + RBXASSERT(0); + throw std::runtime_error("This Mouse is no longer active"); + } + } + public: + Mouse() + : command(NULL) + { + } + + void update(const UIEvent&); + G3D::CoordinateFrame getHit() const; + G3D::CoordinateFrame getOrigin() const; + PartInstance* getTarget() const; + + void setCommand(MouseCommand* value) + { + command = value; + } + + TextureId getIcon() const + { + checkActive(); + return icon; + } + + void setIcon(const TextureId& value) + { + icon = value; + } + + int getX() const + { + checkActive(); + return lastEvent.mousePosition.x; + } + + int getY() const + { + checkActive(); + return lastEvent.mousePosition.y; + } + + int getViewSizeX() const + { + checkActive(); + return lastEvent.windowSize.x; + } + + int getViewSizeY() const + { + checkActive(); + return lastEvent.windowSize.y; + } + }; +} diff --git a/Client/App/include/v8datamodel/MouseCommand.h b/Client/App/include/v8datamodel/MouseCommand.h new file mode 100644 index 00000000..39051110 --- /dev/null +++ b/Client/App/include/v8datamodel/MouseCommand.h @@ -0,0 +1,121 @@ +#pragma once +#include "util/Name.h" +#include "util/UIEvent.h" +#include "util/TextureId.h" +#include "util/IRenderable.h" + +namespace RBX +{ + class PartInstance; + class Primitive; + class ContactManager; + class ICameraOwner; + class Surface; + class HitTestFilter; + class Workspace; + class XmlState; + + class MouseCommand : public INamed, public IRenderable + { + private: + bool capturedMouse; + protected: + Workspace* workspace; + std::auto_ptr undoState; + private: + static G3D::Vector3 ignoreVector3; + + public: + G3D::Ray getUnitMouseRay(const UIEvent& uiEvent) const; + G3D::Ray getSearchRay(const UIEvent& uiEvent) const; + PartInstance* getPart(const UIEvent& uiEvent, const HitTestFilter* filter, G3D::Vector3& hitWorld = ignoreVector3); + PartInstance* getUnlockedPart(const UIEvent&, G3D::Vector3&); + PartInstance* getPartByLocalCharacter(const UIEvent&, G3D::Vector3&); + PartInstance* getUnlockedPartByLocalCharacter(const UIEvent&, G3D::Vector3&); + Surface* getSurface(const UIEvent&, PartInstance*&, int&); + Surface* getSurface(const UIEvent&); + + virtual MouseCommand* onMouseDown(const UIEvent& uiEvent) + { + return this; + } + protected: + virtual void onMouseIdle(const UIEvent& uiEvent) + { + return; + } + + virtual void onMouseHover(const UIEvent& uiEvent) + { + return; + } + + virtual MouseCommand* onKeyDown(const UIEvent& uiEvent) + { + return this; + } + + virtual MouseCommand* onPeekKeyDown(const UIEvent& uiEvent) + { + return NULL; + } + + virtual void onMouseMove(const UIEvent& uiEvent) + { + return; + } + + virtual void onMouseDelta(const UIEvent& uiEvent) + { + return; + } + + virtual MouseCommand* onMouseUp(const UIEvent& uiEvent) + { + releaseCapture(); + return NULL; + } + + virtual void capture(); + + virtual void releaseCapture() + { + capturedMouse = false; + } + + virtual void cancel() + { + if (capturedMouse) + releaseCapture(); + } + + void snapshotSelectionPosition(XmlState*); + bool characterCanReach(const G3D::Vector3& hitPoint) const; + MouseCommand(Workspace* workspace); + public: + virtual ~MouseCommand(); + bool captured() const; + + virtual MouseCommand* isSticky() const + { + return false; + } + + virtual TextureId getCursorId() const; + private: + virtual const std::string getCursorName() const + { + return "ArrowCursor"; + } + + private: + static const float maxSearch(); + public: + static G3D::Ray getUnitMouseRay(const UIEvent& uiEvent, ICameraOwner* _workspace); + static inline G3D::Ray getSearchRay(const G3D::Ray& unitRay); + static G3D::Ray getSearchRay(const UIEvent& uiEvent, ICameraOwner* _workspace); + static Instance* getTopSelectable3d(PartInstance* part); + static PartInstance* getMousePart(const G3D::Ray& unitRay, const ContactManager& contactManager, const std::vector& ignore, const HitTestFilter* filter, G3D::Vector3& hitPoint, float maxSearchGrid); + static PartInstance* getMousePart(const G3D::Ray& unitRay, const ContactManager& contactManager, const Primitive* ignore, const HitTestFilter* filter, G3D::Vector3& hitPoint, float maxSearchGrid); + }; +} diff --git a/Client/App/include/v8datamodel/PartInstance.h b/Client/App/include/v8datamodel/PartInstance.h index bc9c9b6c..bbf5fcaa 100644 --- a/Client/App/include/v8datamodel/PartInstance.h +++ b/Client/App/include/v8datamodel/PartInstance.h @@ -34,6 +34,8 @@ namespace RBX public virtual ICameraSubject, public virtual ISelectable3d { + friend class Surface; + public: enum FormFactor { @@ -85,7 +87,6 @@ namespace RBX bool computeSurfacesNeedAdorn() const; void safeMove(); public: - //PartInstance(const PartInstance&); PartInstance(); virtual ~PartInstance(); public: @@ -231,8 +232,6 @@ namespace RBX void onSurfaceChanged(RBX::NormalId surfId); void writeSize(XmlState*); void raiseSurfacePropertyChanged(const RBX::Reflection::PropertyDescriptor&); - public: - //PartInstance& operator=(const PartInstance&); public: static float plateHeight(); diff --git a/Client/App/include/v8datamodel/SafeChat.h b/Client/App/include/v8datamodel/SafeChat.h new file mode 100644 index 00000000..88fc2c80 --- /dev/null +++ b/Client/App/include/v8datamodel/SafeChat.h @@ -0,0 +1,38 @@ +#pragma once +#include "v8xml/XmlElement.h" +#include +#include +#include + +namespace RBX +{ + class ChatOption + { + public: + std::vector children; + std::string text; + + public: + ChatOption(std::string); + ChatOption(); + ~ChatOption(); + }; + + class SafeChat + { + private: + boost::scoped_ptr chatRoot; + + public: + SafeChat(); + ChatOption* getChatRoot(); + std::string getMessage(std::vector); + private: + void loadChatTree(); + void saveChatTree(); + void loadChildren(ChatOption*, const XmlElement*); + + public: + static SafeChat& singleton(); + }; +} diff --git a/Client/App/include/v8datamodel/ScriptMouseCommand.h b/Client/App/include/v8datamodel/ScriptMouseCommand.h new file mode 100644 index 00000000..97772fea --- /dev/null +++ b/Client/App/include/v8datamodel/ScriptMouseCommand.h @@ -0,0 +1,30 @@ +#pragma once +#include "v8datamodel/MouseCommand.h" + +namespace RBX +{ + class Mouse; + + class ScriptMouseCommand : public MouseCommand + { + private: + boost::shared_ptr mouse; + + public: + ScriptMouseCommand(Workspace* workspace); + virtual ~ScriptMouseCommand(); + + boost::shared_ptr getMouse() + { + return mouse; + } + + virtual TextureId getCursorId() const; + virtual MouseCommand* onMouseDown(const UIEvent& uiEvent); + virtual void onMouseHover(const UIEvent& uiEvent); + virtual void onMouseIdle(const UIEvent& uiEvent); + virtual MouseCommand* onMouseUp(const UIEvent& uiEvent); + virtual MouseCommand* onPeekKeyDown(const UIEvent& uiEvent); + virtual const Name& getName() const; + }; +} diff --git a/Client/App/include/v8datamodel/Seat.h b/Client/App/include/v8datamodel/Seat.h new file mode 100644 index 00000000..86e06bb7 --- /dev/null +++ b/Client/App/include/v8datamodel/Seat.h @@ -0,0 +1,29 @@ +#pragma once +#include "v8datamodel/PartInstance.h" + +namespace RBX +{ + class Weld; + class Humanoid; + + extern const char* sSeat; + + class Seat : public DescribedCreatable + { + private: + boost::signals::scoped_connection seatTouched; + boost::signals::scoped_connection humanoidJumped; + boost::shared_ptr weld; + double sleepTime; + + private: + void onEvent_seatTouched(boost::shared_ptr); + void onEvent_humanoidJumped(bool); + void seatCharacter(Humanoid*); + void unseatCharacter(); + bool charSeated(); + public: + Seat(); + virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + }; +} diff --git a/Client/App/include/v8datamodel/Selection.h b/Client/App/include/v8datamodel/Selection.h new file mode 100644 index 00000000..f952af35 --- /dev/null +++ b/Client/App/include/v8datamodel/Selection.h @@ -0,0 +1,122 @@ +#pragma once +#include "v8tree/Instance.h" +#include "v8tree/Service.h" + +namespace RBX +{ + class SelectionChanged + { + public: + const boost::shared_ptr addedItem; + const boost::shared_ptr removedItem; + + private: + SelectionChanged(boost::shared_ptr, boost::shared_ptr); + }; + + class ISelectionBase + { + private: + virtual void onSelectionChanged(const SelectionChanged&) = 0; + }; + + extern const char* sSelection; + + class Selection : public DescribedCreatable, + public Notifier, + public Service, + public Listener + { + class AddIterator : public std::_Outit // base class has zero typedefs... + { + private: + Selection* selection; + + public: + AddIterator(Selection*); + AddIterator& operator*(); + AddIterator operator++(int); + AddIterator& operator++(); + }; + + class RemoveIterator : public std::_Outit + { + private: + Selection* selection; + + public: + RemoveIterator(Selection*); + RemoveIterator& operator*(); + RemoveIterator operator++(int); + RemoveIterator& operator++(); + }; + + class ToggleIterator : public std::_Outit + { + private: + Selection* selection; + + public: + ToggleIterator(Selection*); + ToggleIterator& operator*(); + ToggleIterator operator++(int); + ToggleIterator& operator++(); + }; + + private: + CopyOnWrite>> selection; + std::vector filteredSelections; + + public: + Selection(); + virtual ~Selection(); + size_t size() const; + boost::shared_ptr front() const; + boost::shared_ptr back() const; + std::vector>::const_iterator begin() const; + std::vector>::const_iterator end() const; + const CopyOnWrite>> getSelection() const; + void setSelection(boost::shared_ptr>>); + void setSelection(Instance*); + void clearSelection(); + boost::shared_ptr>> getSelection2(); + void addToSelection(const boost::shared_ptr&); + void addToSelection(Instance*); + void toggleSelection(Instance*); + void removeFromSelection(const Instance*); + bool isSelected(const Instance*) const; + virtual void onEvent(const Instance*, AncestorChanged); + void addFilteredSelection(ISelectionBase*); + void removeFilteredSelection(ISelectionBase*); + private: + void raiseAdded(boost::shared_ptr); + void raiseRemoved(boost::shared_ptr); + }; + + template + class FilteredSelection : public NonFactoryProduct, public Service, public ISelectionBase + { + private: + boost::shared_ptr rootSelection; + std::vector filteredSelection; + + public: + FilteredSelection(); + virtual ~FilteredSelection(); + Selection* getSelection() const; + const std::vector& items() const; + size_t size() const; + const Class* front() const; + Class* front(); + const Class* back() const; + Class* back(); + typename std::vector::const_iterator begin() const; + typename std::vector::const_iterator end() const; + void clearSelection(); + void addToSelection(Class*); + void setSelection(Class*); + protected: + virtual void onAncestorChanged(const AncestorChanged&); + virtual void onSelectionChanged(const SelectionChanged&); + }; +} diff --git a/Client/App/include/v8datamodel/Sky.h b/Client/App/include/v8datamodel/Sky.h index aa777e39..031cf96e 100644 --- a/Client/App/include/v8datamodel/Sky.h +++ b/Client/App/include/v8datamodel/Sky.h @@ -1,7 +1,7 @@ #pragma once +#include #include "v8tree/Instance.h" #include "util/TextureId.h" -#include namespace RBX { @@ -28,11 +28,7 @@ namespace RBX static Reflection::BoundProp prop_CelestialBodiesShown; public: - //Sky(const Sky&); Sky(); - virtual ~Sky(); - public: - //Sky& operator=(const Sky&); public: static G3D::ReferenceCountedPointer getG3DSky(Sky*); diff --git a/Client/App/include/v8datamodel/SpawnLocation.h b/Client/App/include/v8datamodel/SpawnLocation.h index 9f782011..8642ccb1 100644 --- a/Client/App/include/v8datamodel/SpawnLocation.h +++ b/Client/App/include/v8datamodel/SpawnLocation.h @@ -1,9 +1,13 @@ #pragma once #include "v8datamodel/PartInstance.h" +#include "v8tree/Service.h" namespace RBX { - class ServiceProvider; + namespace Network + { + class Player; + } extern const char* sSpawnLocation; class SpawnLocation : public DescribedCreatable @@ -22,15 +26,24 @@ namespace RBX private: void onEvent_spawnerTouched(boost::shared_ptr); public: - //SpawnLocation(const SpawnLocation&); SpawnLocation(); public: - virtual void onServiceProvider(const ServiceProvider*, const ServiceProvider*); + virtual void onServiceProvider(const ServiceProvider* oldProvider, const ServiceProvider* newProvider); BrickColor getTeamColor() const; - void setTeamColor(BrickColor); - public: - virtual ~SpawnLocation(); + void setTeamColor(BrickColor color); + }; + + extern const char* sSpawnerService; + class SpawnerService : public DescribedCreatable, public Service + { + private: + std::list spawners; + public: - //SpawnLocation& operator=(const SpawnLocation&); + SpawnerService(); + virtual ~SpawnerService(); + G3D::Vector3 FindSpawnPositionForPlayer(Network::Player* p); + void RegisterSpawner(SpawnLocation* spawner); + void UnregisterSpawner(SpawnLocation* spawner); }; } diff --git a/Client/App/include/v8datamodel/Surface.h b/Client/App/include/v8datamodel/Surface.h index ef6849be..1eeb6e7c 100644 --- a/Client/App/include/v8datamodel/Surface.h +++ b/Client/App/include/v8datamodel/Surface.h @@ -1,5 +1,4 @@ #pragma once -#include "reflection/property.h" #include "v8world/Controller.h" #include "v8xml/XmlElement.h" #include "util/SurfaceType.h" @@ -8,6 +7,7 @@ namespace RBX { class PartInstance; + class IReferenceBinder; class Surface { @@ -18,19 +18,19 @@ namespace RBX public: void flat(); public: - Surface(PartInstance*, NormalId); + Surface(PartInstance* partInstance, NormalId surfId); public: PartInstance* getPartInstance() const; NormalId getNormalId() const; bool isControllable() const; SurfaceType getSurfaceType() const; - void setSurfaceType(SurfaceType); + void setSurfaceType(SurfaceType type); Controller::InputType getInput() const; - void setSurfaceInput(Controller::InputType); + void setSurfaceInput(Controller::InputType value); float getParamA() const; float getParamB() const; - void setParamA(float); - void setParamB(float); + void setParamA(float value); + void setParamB(float value); void toggleSurfaceType(); void writeValue(XmlElement*) const; void readValue(const XmlElement*, IReferenceBinder&); diff --git a/Client/App/include/v8datamodel/TimeState.h b/Client/App/include/v8datamodel/TimeState.h new file mode 100644 index 00000000..3c6ad971 --- /dev/null +++ b/Client/App/include/v8datamodel/TimeState.h @@ -0,0 +1,17 @@ +#pragma once +#include + +namespace RBX +{ + class TimeState + { + public: + G3D::Stopwatch simulationStopwatch; + G3D::Stopwatch fpsStopwatch; + float totalVirtualTime; + + public: + TimeState(); + void clear(); + }; +} diff --git a/Client/App/include/v8datamodel/TimerService.h b/Client/App/include/v8datamodel/TimerService.h index 3c2689b4..4d2cc87b 100644 --- a/Client/App/include/v8datamodel/TimerService.h +++ b/Client/App/include/v8datamodel/TimerService.h @@ -1,4 +1,5 @@ #include "util/RunStateOwner.h" +#include namespace RBX { diff --git a/Client/App/include/v8datamodel/Tool.h b/Client/App/include/v8datamodel/Tool.h index f12f1a08..c3b13598 100644 --- a/Client/App/include/v8datamodel/Tool.h +++ b/Client/App/include/v8datamodel/Tool.h @@ -1,5 +1,5 @@ #pragma once -#include "v8datamodel/LocalBackpack.h" +#include "v8datamodel/Hopper.h" #include "v8datamodel/IEquipable.h" #include "util/IRenderable.h" #include "util/ILocation.h" diff --git a/Client/App/include/v8datamodel/ToolMouseCommand.h b/Client/App/include/v8datamodel/ToolMouseCommand.h new file mode 100644 index 00000000..3d2a6525 --- /dev/null +++ b/Client/App/include/v8datamodel/ToolMouseCommand.h @@ -0,0 +1,25 @@ +#pragma once +#include "v8datamodel/ScriptMouseCommand.h" + +namespace RBX +{ + class Tool; + + extern const char* sToolMouseCommand; + + class ToolMouseCommand : public Named + { + private: + boost::shared_ptr tool; + + private: + void updateTargetPoint(const UIEvent& uiEvent); + public: + ToolMouseCommand(Workspace* workspace, Tool* tool); + virtual ~ToolMouseCommand(); + virtual MouseCommand* onMouseDown(const UIEvent& uiEvent); + virtual void onMouseHover(const UIEvent& uiEvent); + virtual void onMouseIdle(const UIEvent& uiEvent); + virtual MouseCommand* onMouseUp(const UIEvent& uiEvent); + }; +} diff --git a/Client/App/include/v8datamodel/Value.h b/Client/App/include/v8datamodel/Value.h new file mode 100644 index 00000000..ab77b59a --- /dev/null +++ b/Client/App/include/v8datamodel/Value.h @@ -0,0 +1,66 @@ +#pragma once +#include "v8tree/Instance.h" +#include "v8datamodel/BrickColor.h" +#include + +namespace RBX +{ + extern const char* sIntValue; + extern const char* sBoolValue; + extern const char* sFloatValue; + extern const char* sColor3Value; + extern const char* sVector3Value; + extern const char* sBrickColorValue; + extern const char* sStringValue; + extern const char* sCFrameValue; + + template + class Value : public DescribedCreatable, Instance, ClassName> + { + private: + ValueType value; + private: + static const ValueType defaultValue; + public: + static Reflection::BoundProp desc_Value; + static Reflection::SignalDesc desc_ValueChanged; + + public: + Value(); + const Value& getValue() const; + void setValue(const Value&); + protected: + virtual bool askSetParent(const Instance*) const; + private: + void onValueChanged(const Reflection::PropertyDescriptor&); + }; + + typedef Value IntValue; + typedef Value BoolValue; + typedef Value FloatValue; + typedef Value Color3Value; + typedef Value Vector3Value; + typedef Value BrickColorValue; + typedef Value StringValue; + typedef Value CFrameValue; + + extern const char* sObjectValue; + + class ObjectValue : public DescribedCreatable + { + private: + boost::shared_ptr value; + public: + static Reflection::RefPropDescriptor desc_Value; + static Reflection::SignalDesc)> desc_ValueChanged; + + public: + ObjectValue(); + Instance* getValue() const; + void setValue(Instance*); + protected: + virtual bool askSetParent(const Instance*) const; + private: + void onValueChanged(const Reflection::PropertyDescriptor&); + }; +} diff --git a/Client/App/include/v8datamodel/Visit.h b/Client/App/include/v8datamodel/Visit.h new file mode 100644 index 00000000..9210801d --- /dev/null +++ b/Client/App/include/v8datamodel/Visit.h @@ -0,0 +1,38 @@ +#pragma once +#include "v8tree/Instance.h" +#include "v8tree/Service.h" + +namespace RBX +{ + extern const char* sVisit; + + class Visit : public DescribedCreatable, public Service + { + private: + std::string uploadUrl; + boost::scoped_ptr pingThread; + + public: + Visit(); + virtual ~Visit(); + void setPing(std::string url, int interval); + + void setUploadUrl(std::string value) + { + uploadUrl = value; + } + + std::string getUploadUrl() + { + return uploadUrl; + } + + virtual XmlElement* write() + { + return NULL; + } + + public: + static worker_thread::work_result ping(std::string url, int interval); + }; +} diff --git a/Client/App/include/v8datamodel/Workspace.h b/Client/App/include/v8datamodel/Workspace.h index 707d2015..3c1140e2 100644 --- a/Client/App/include/v8datamodel/Workspace.h +++ b/Client/App/include/v8datamodel/Workspace.h @@ -86,7 +86,10 @@ namespace RBX return world.get(); } IDataState& getDataState() const; - MouseCommand* getCurrentMouseCommand(); + MouseCommand* getCurrentMouseCommand() + { + return currentCommand.get(); + } void cancelMouseCommand(); void setMouseCommand(MouseCommand*); void setDefaultMouseCommand(); @@ -115,7 +118,10 @@ namespace RBX void insertContent(ContentId, std::vector>&, InsertMode, PromptMode); void makeJoints(boost::shared_ptr>>); void breakJoints(boost::shared_ptr>>); - void raiseDrawChanged() const; + void raiseDrawChanged() const + { + Notifier::raise(DrawChanged()); + } public: //Workspace& operator=(Workspace&); diff --git a/Client/App/include/v8tree/Instance.h b/Client/App/include/v8tree/Instance.h index e900e038..cc7b8985 100644 --- a/Client/App/include/v8tree/Instance.h +++ b/Client/App/include/v8tree/Instance.h @@ -30,15 +30,13 @@ namespace RBX const boost::shared_ptr child; public: - //ChildAdded(const ChildAdded&); + ChildAdded(const ChildAdded&); ChildAdded(Instance* child) : child(shared_from(child)) { } private: ChildAdded& operator=(const ChildAdded&); - public: - ~ChildAdded(); }; struct ChildRemoved @@ -47,12 +45,10 @@ namespace RBX const boost::shared_ptr child; public: - //ChildRemoved(const ChildRemoved&); + ChildRemoved(const ChildRemoved&); ChildRemoved(Instance*); private: ChildRemoved& operator=(const ChildRemoved&); - public: - ~ChildRemoved(); }; struct DescendentAdded @@ -64,8 +60,6 @@ namespace RBX const boost::shared_ptr instance; const boost::shared_ptr parent; - public: - //DescendentAdded(const DescendentAdded&); private: DescendentAdded(Instance* instance, Instance* parent) : instance(shared_from(instance)), @@ -73,8 +67,6 @@ namespace RBX { } DescendentAdded(boost::shared_ptr, boost::shared_ptr); - public: - ~DescendentAdded() {} }; struct DescendentRemoving @@ -84,14 +76,11 @@ namespace RBX const boost::shared_ptr parent; public: - //DescendentRemoving(const DescendentRemoving&); DescendentRemoving(const boost::shared_ptr& instance, const boost::shared_ptr& parent) : instance(instance), parent(parent) { } - public: - ~DescendentRemoving(); }; struct AncestorChanged @@ -223,7 +212,13 @@ namespace RBX bool isAncestorOf2(boost::shared_ptr descendent); bool isDescendentOf2(boost::shared_ptr); bool isDescendentOf(const Instance* ancestor) const; - size_t numChildren() const; + size_t numChildren() const + { + if (&(*children)) + return children->size(); + else + return 0; + } int findChildIndex(const Instance*) const; const Instance* getChild(size_t i) const { diff --git a/Client/App/include/v8tree/Verb.h b/Client/App/include/v8tree/Verb.h index e7c73bf9..baf165d7 100644 --- a/Client/App/include/v8tree/Verb.h +++ b/Client/App/include/v8tree/Verb.h @@ -11,7 +11,7 @@ namespace RBX { class VerbContainer; - class IDataState : public StateStack // NOTE: may not be intended for this file + class __declspec(novtable) IDataState : public StateStack // NOTE: may not be intended for this file { public: virtual void setDirty(bool) = 0; diff --git a/Client/App/include/v8world/ContactManager.h b/Client/App/include/v8world/ContactManager.h index beabe321..331ac1f8 100644 --- a/Client/App/include/v8world/ContactManager.h +++ b/Client/App/include/v8world/ContactManager.h @@ -36,8 +36,8 @@ namespace RBX return *spatialHash; } - Primitive* getHit(const G3D::Ray& worldRay, const std::vector* ignorePrim, const HitTestFilter* filter, G3D::Vector3& hitPoint, bool& inside) const; - Primitive* getHit(const G3D::Ray& worldRay, const G3D::Array* ignorePrim, const HitTestFilter* filter, G3D::Vector3& hitPoint, bool& inside) const; + Primitive* getHit(const G3D::Ray& worldRay, const std::vector* ignorePrim, const HitTestFilter* filter, G3D::Vector3& hitPoint, bool& inside = ignoreBool) const; + Primitive* getHit(const G3D::Ray& worldRay, const G3D::Array* ignorePrim, const HitTestFilter* filter, G3D::Vector3& hitPoint, bool& inside = ignoreBool) const; void getPrimitivesTouchingExtents(const Extents& extents, const Primitive* ignore, G3D::Array& found); bool intersectingOthers(Primitive* check, const std::set& checkSet, float overlapIgnored); bool intersectingOthers(const G3D::Array& check, float overlapIgnored); diff --git a/Client/App/include/v8xml/XmlSerializer.h b/Client/App/include/v8xml/XmlSerializer.h index b3ed19be..f5741275 100644 --- a/Client/App/include/v8xml/XmlSerializer.h +++ b/Client/App/include/v8xml/XmlSerializer.h @@ -13,25 +13,16 @@ class XmlParser : public boost::noncopyable std::streambuf* buffer; std::stack elements; -public: - //XmlParser(const XmlParser&); protected: XmlParser(std::streambuf* buffer); public: virtual std::auto_ptr parse() = 0; - -public: - ~XmlParser(); - -public: - //XmlParser& operator=(const XmlParser&); }; class TextXmlParser : public XmlParser { public: - //TextXmlParser(const TextXmlParser&); TextXmlParser(std::streambuf* buffer) : XmlParser(buffer) { @@ -49,28 +40,15 @@ class TextXmlParser : public XmlParser std::string findNextToken(const std::string&, int&); std::string findText(const std::string&); XmlElement* parseAttributes(const std::string&); - -public: - ~TextXmlParser(); - -public: - //TextXmlParser& operator=(const TextXmlParser&); }; class BinaryXmlParser : public XmlParser { public: - //BinaryXmlParser(const BinaryXmlParser&); BinaryXmlParser(std::streambuf*); public: virtual std::auto_ptr parse(); - -public: - ~BinaryXmlParser(); - -public: - //BinaryXmlParser& operator=(const BinaryXmlParser&); }; class XmlWriter : public boost::noncopyable @@ -78,27 +56,18 @@ class XmlWriter : public boost::noncopyable protected: std::map handles; std::ostream& stream; - -public: - ///XmlWriter(const XmlWriter&); + protected: XmlWriter(std::ostream&); public: virtual void serialize(const XmlElement*) = 0; int getHandleIndex(RBX::InstanceHandle); - -public: - ~XmlWriter(); - -public: - //XmlWriter& operator=(const XmlWriter&); }; class TextXmlWriter : public XmlWriter { public: - //TextXmlWriter(const TextXmlWriter&); TextXmlWriter(std::ostream&); protected: @@ -111,12 +80,6 @@ class TextXmlWriter : public XmlWriter void writeText(const std::string&, bool); void writeText(const char*, bool); virtual void serializeNode(const XmlElement*, int); - -public: - ~TextXmlWriter(); - -public: - //TextXmlWriter& operator=(const TextXmlWriter&); public: static void encodedWrite(std::ostream&, const std::string&); @@ -129,23 +92,15 @@ class TextXmlWriterWithEmbeddedContent : public TextXmlWriter std::set embeddedContent; public: - //TextXmlWriterWithEmbeddedContent(const TextXmlWriterWithEmbeddedContent&); TextXmlWriterWithEmbeddedContent(std::ostream&); protected: virtual void serializeNode(const XmlElement*, int); - -public: - ~TextXmlWriterWithEmbeddedContent(); - -public: - //TextXmlWriterWithEmbeddedContent& operator=(const TextXmlWriterWithEmbeddedContent&); }; class BinaryXmlWriter : public XmlWriter { public: - //BinaryXmlWriter(const BinaryXmlWriter&); BinaryXmlWriter(std::ostream&); private: @@ -164,10 +119,4 @@ class BinaryXmlWriter : public XmlWriter private: void serializeAttribute(const XmlAttribute*); void serializeNameValuePair(const XmlNameValuePair*); - -public: - ~BinaryXmlWriter(); - -public: - //BinaryXmlWriter& operator=(const BinaryXmlWriter&); }; diff --git a/Client/App/v8datamodel/Backpack.cpp b/Client/App/v8datamodel/Backpack.cpp new file mode 100644 index 00000000..ffe09a26 --- /dev/null +++ b/Client/App/v8datamodel/Backpack.cpp @@ -0,0 +1,9 @@ +#include "v8datamodel/Backpack.h" + +namespace RBX +{ + Backpack::Backpack() + { + setName("Backpack"); + } +} diff --git a/Client/App/v8datamodel/DataModel.cpp b/Client/App/v8datamodel/DataModel.cpp new file mode 100644 index 00000000..4c96c98e --- /dev/null +++ b/Client/App/v8datamodel/DataModel.cpp @@ -0,0 +1,167 @@ +#include "v8datamodel/DataModel.h" +#include "v8datamodel/TimeState.h" +#include "v8datamodel/Workspace.h" +#include "gui/GUI.h" +#include "util/standardout.h" +#include "util/Http.h" + +namespace RBX +{ + +#pragma warning (push) +#pragma warning (disable : 4355) // warning C4355: 'this' : used in base member initializer list + + //99% match + DataModel::DataModel() + : VerbContainer(NULL), + workspace(Creatable::create(this)), + guiRoot(Creatable::create()), + guiHooks(Creatable::create()), + timeState(new TimeState), + mutex(new boost::recursive_mutex), + guiTarget(NULL), + forceArrowCursor(true), + dirty(false), + drawId(0) + { + setName("Level"); + } + +#pragma warning (pop) + + DataModel::~DataModel() + { + if (runService) + runService->Notifier::removeListener(this); + + StandardOut::singleton()->print(MESSAGE_INFO, "~DataModel"); + } + + bool DataModel::askAddChild(const Instance* instance) const + { + return fastDynamicCast(instance) != NULL; + } + + boost::shared_ptr DataModel::createDataModel() + { + ContentProvider::singleton().clearContentCache(); + + boost::shared_ptr dataModel = Creatable::create(); + + { + Lock lock(dataModel); + dataModel->initializeContents(); + } + + return dataModel; + } + + void DataModel::onChildAdded(Instance* child) + { + ServiceProvider::onChildAdded(child); + + if (child->getClassName() == "NetworkClient") + { + Verb* lockPlayMode = getVerb("LockPlayMode"); + if (lockPlayMode) + lockPlayMode->doIt(NULL); + + workspace->setNullMouseCommand(); + } + } + + void DataModel::onEvent(const RunService* source, RunTransition event) + { + switch (event.newState) + { + case RS_NORMAL: + if (event.oldState == RS_RUNNING) + workspace->reset(); + + timeState->clear(); + break; + case RS_RUNNING: + workspace->start(); + break; + case RS_PAUSED: + workspace->stop(); + break; + } + } + + std::string DataModel::doHttpGet(std::string url) + { + std::string result; + Http(url.c_str()).get(result); + + return result; + } + + std::string DataModel::doHttpPost(std::string url, std::string data) + { + std::string result; + Http(url).post(std::istringstream(data), true, result); + + return result; + } + + void DataModel::close() + { + Verb* exitVerb = getVerb("Exit"); + if (!exitVerb) + throw std::runtime_error("Couldn\'t find Exit Verb"); + + exitVerb->doIt(NULL); + } + + std::string DataModel::httpGet(std::string url, bool synchronous) + { + if (synchronous) + { + return doHttpGet(url); + } + else + { + if (url.size() > 0) + { + boost::function0 f = boost::bind(&DataModel::doHttpGet, url); + boost::function0 g = boost::bind(&StandardOut::print_exception, f, MESSAGE_ERROR, false); + + boost::thread(background_function(g, "rbx_httpGet")); + } + + return ""; + } + } + + std::string DataModel::httpPost(std::string url, std::string data, bool synchronous) + { + if (synchronous) + { + return doHttpPost(url, data); + } + else + { + boost::function0 f = boost::bind(&DataModel::doHttpPost, url, data); + boost::function0 g = boost::bind(&StandardOut::print_exception, f, MESSAGE_ERROR, false); + + boost::thread(background_function(g, "rbx_httpPost")); + + return ""; + } + } + + void DataModel::Lock::doLock(const DataModel* dataModel) + { + if (dataModel) + { + mutex = dataModel->mutex; + lock = new boost::recursive_mutex::scoped_lock(*mutex); + } + } + + DataModel::Lock::~Lock() + { + delete lock; + } +} diff --git a/Client/App/v8datamodel/DebrisService.cpp b/Client/App/v8datamodel/DebrisService.cpp new file mode 100644 index 00000000..ac8e09eb --- /dev/null +++ b/Client/App/v8datamodel/DebrisService.cpp @@ -0,0 +1,74 @@ +#include "v8datamodel/DebrisService.h" +#include "v8datamodel/TimerService.h" +#include "util/standardout.h" + +RBX::Reflection::BoundFuncDesc, double), 2> func_AddItem(&RBX::DebrisService::addItem, "AddItem", "item", "lifetime", RBX::Reflection::FunctionDescriptor::AnyCaller); +RBX::Reflection::PropDescriptor prop_MaxItems("MaxItems", "Data", &RBX::DebrisService::getMaxItems, &RBX::DebrisService::setMaxItems, RBX::Reflection::PropertyDescriptor::STANDARD); + +static void cleanup(boost::weak_ptr item) +{ + try + { + boost::shared_ptr i = item.lock(); + if (i) + i->setParent(NULL); + } + catch (std::exception& e) + { + RBX::StandardOut::singleton()->print(RBX::MESSAGE_WARNING, e); + } +} + +namespace RBX +{ + DebrisService::DebrisService() + : Base("Debris"), + maxItems(300), + timer(NULL) + { + } + + void DebrisService::setMaxItems(int value) + { + if (value != maxItems) + { + if (value < 0) + throw std::runtime_error("DebrisService MaxItems must be greater than 0"); + + maxItems = value; + raisePropertyChanged(prop_MaxItems); + DebrisService::cleanup(); + } + } + + void DebrisService::addItem(boost::shared_ptr item, double lifetime) + { + if (timer) + timer->delay(boost::bind(&::cleanup, item), lifetime); + + queue.push(item); + DebrisService::cleanup(); + } + + void DebrisService::cleanup() + { + while ((int)queue.size() > maxItems) + { + ::cleanup(queue.front()); + queue.pop(); + } + } + + void DebrisService::onServiceProvider(const ServiceProvider* oldProvider, const ServiceProvider* newProvider) + { + while ((int)queue.size() > 0) + { + ::cleanup(queue.front()); + queue.pop(); + } + + Instance::onServiceProvider(oldProvider, newProvider); + + timer = newProvider ? newProvider->create() : NULL; + } +} diff --git a/Client/App/v8datamodel/Explosion.cpp b/Client/App/v8datamodel/Explosion.cpp new file mode 100644 index 00000000..02a7973e --- /dev/null +++ b/Client/App/v8datamodel/Explosion.cpp @@ -0,0 +1,129 @@ +#include "v8datamodel/Explosion.h" +#include "v8datamodel/Workspace.h" +#include "v8datamodel/PartInstance.h" +#include "v8world/ContactManager.h" +#include "v8world/World.h" + +namespace RBX +{ + Reflection::PropDescriptor propBlastRadius("BlastRadius", "Data", &Explosion::getBlastRadius, &Explosion::setBlastRadius, Reflection::PropertyDescriptor::STANDARD); + Reflection::BoundProp Explosion::propPosition("Position", "Data", &Explosion::position, Reflection::PropertyDescriptor::STANDARD); + Reflection::BoundProp Explosion::propBlastPressure("BlastPressure", "Data", &Explosion::blastPressure, Reflection::PropertyDescriptor::STANDARD); + + Reflection::SignalDesc, float)> signal_Hit("Hit", "part", "distance"); + + Explosion::Explosion() + : blastRadius(4.0f), + blastPressure(500000.0f), + age(0.0f) + { + setName("Explosion"); + } + + bool Explosion::askSetParent(const Instance* instance) const + { + return true; + } + + void Explosion::setBlastRadius(float _blastRadius) + { + float newRadius = G3D::clamp(_blastRadius, 0.0f, 100.0f); + if (blastRadius != newRadius) + { + blastRadius = newRadius; + raisePropertyChanged(propBlastRadius); + } + } + + void Explosion::signalBlast(const G3D::Array& primitives) + { + if (!signal_Hit.empty(this)) + { + for (int i = 0; i < primitives.size(); i++) + { + Primitive* current = primitives[i]; + + if (blastRadius * 2.0f > current->getRadius()) + { + if (Instance* part = PartInstance::fromPrimitive(current)) + { + float distance = (current->getCoordinateFrame().translation - position).magnitude(); + signal_Hit.fire(this, shared_from(part), distance); + } + } + } + } + } + + //99% match + void Explosion::doBlast(const G3D::Array& primitives) + { + if (blastPressure > 0.0f) + { + World* world = Workspace::getMyWorldFast(this); + RBXASSERT(world); + + for (int i = 0; i < primitives.size(); i++) + { + Primitive* current = primitives[i]; + + if (blastRadius * 2.0f > current->getRadius()) + { + PartInstance::fromPrimitive(current)->destroyJoints(); + } + } + + world->update(); + + for (int i = 0; i < primitives.size(); i++) + { + Primitive* current = primitives[i]; + + if (blastRadius * 2.0f > current->getRadius()) + { + G3D::Vector3 delta = current->getCoordinateFrame().translation - position; + G3D::Vector3 normal = delta == G3D::Vector3::zero() ? G3D::Vector3::unitY() : delta.direction(); + RBXASSERT(normal.magnitude() <= 1.001); + + float radius = current->getRadius(); + float squaredRadius = radius * radius; + + G3D::Vector3 impulse = normal * blastPressure * squaredRadius * (1.0f/4560.0f); + G3D::Vector3 force = impulse * Constants::kernelStepsPerSec(); + + world->ticklePrimitive(current); + + Body* body = current->getBody(); + + const G3D::Vector3& pos = body->getCoordinateFrame().translation; + body->accumulateForce(force, pos); + + current->getBody()->accumulateTorque(force * 0.5f * radius); + + world->addedBodyForce(); + } + } + } + } + + void Explosion::onServiceProvider(const ServiceProvider* oldProvider, const ServiceProvider* newProvider) + { + Listener* oldListener = this; + + if (oldProvider) + { + if (RunService* runService = oldProvider->find()) + runService->Notifier::removeListener(oldListener); + } + + Instance::onServiceProvider(oldProvider, newProvider); + + Listener* newListener = this; + + if (newProvider) + { + if (RunService* runService = newProvider->find()) + runService->Notifier::addListener(newListener); + } + } +} diff --git a/Client/App/v8datamodel/Flag.cpp b/Client/App/v8datamodel/Flag.cpp new file mode 100644 index 00000000..3cfbbabc --- /dev/null +++ b/Client/App/v8datamodel/Flag.cpp @@ -0,0 +1,52 @@ +#include "v8datamodel/Flag.h" +#include "v8datamodel/FlagStand.h" +#include "v8datamodel/PartInstance.h" +#include "v8datamodel/TimerService.h" +#include "humanoid/Humanoid.h" +#include "Network/Player.h" + +namespace RBX +{ + Reflection::PropDescriptor prop_Color("TeamColor", "Data", &Flag::getTeamColor, &Flag::setTeamColor, Reflection::PropertyDescriptor::STANDARD); + + Flag::Flag() + : timer(NULL) + { + setName("Flag"); + } + + Flag::~Flag() {} + + BrickColor Flag::getTeamColor() const + { + return teamColor; + } + + void Flag::setTeamColor(BrickColor color) + { + teamColor = color; + raisePropertyChanged(prop_Color); + } + + void Flag::onChildAdded(Instance* instance) + { + if (fastDynamicCast(instance)) + { + if (PartInstance* handle = getHandle()) + { + boost::slot)>> slot(boost::bind(&Flag::onEvent_flagTouched, this, _1)); + flagTouched = PartInstance::event_Touched.connect(handle, slot); + } + } + } + + void Flag::doUglyPeriodicCloneHack() + { + evilClone = clone(); + + if (timer && numChildren() == 0) + { + timer->delay(boost::bind(&Flag::doUglyPeriodicCloneHack, shared_from(this)), 2.0f); + } + } +} diff --git a/Client/App/v8datamodel/FlagStand.cpp b/Client/App/v8datamodel/FlagStand.cpp new file mode 100644 index 00000000..0f3a9633 --- /dev/null +++ b/Client/App/v8datamodel/FlagStand.cpp @@ -0,0 +1,78 @@ +#include "v8datamodel/FlagStand.h" +#include "v8datamodel/Flag.h" + +namespace RBX +{ + FlagStand::FlagStand() + { + setName("FlagStand"); + } + + BrickColor FlagStand::getTeamColor() const + { + return teamColor; + } + + void FlagStand::setTeamColor(BrickColor color) + { + teamColor = color; + raisePropertyChanged(PartInstance::prop_Color); + } + + void FlagStand::AffixFlag(Flag* flag) + { + if (!GetFlag()) + { + flag->setParent(getParent()); + + PartInstance* handle = flag->getHandle(); + + handle->setCoordinateFrame(G3D::CoordinateFrame()); + + G3D::Vector3 location = getLocation().translation; + location.y += 0.5f; + + handle->moveToPoint(location); + handle->join(); + } + } + + Flag* FlagStand::GetFlag() + { + Primitive* primitive = getPrimitive(); + + for (RigidJoint* current = primitive->getFirstRigid(); current != NULL; current = primitive->getNextRigid(current)) + { + for (int i = 0; i < 2; i++) + { + Flag* flag = fastDynamicCast(PartInstance::fromPrimitive(current->getPrimitive(i))->getParent()); + if (flag) + return flag; + } + } + + return NULL; + } + + FlagStandService::FlagStandService() + { + setName("FlagStandService"); + propArchivable.setValue(this, false); + } + + FlagStandService::~FlagStandService() {} + + FlagStand* FlagStandService::FindStandWithFlag(Flag* f) + { + if (flagStands.empty()) + return NULL; + + for (std::list::const_iterator iter = flagStands.begin(); iter != flagStands.end(); iter++) + { + if ((*iter)->GetFlag() == f) + return *iter; + } + + return NULL; + } +} diff --git a/Client/App/v8datamodel/GameSettings.cpp b/Client/App/v8datamodel/GameSettings.cpp new file mode 100644 index 00000000..5a0ce2ef --- /dev/null +++ b/Client/App/v8datamodel/GameSettings.cpp @@ -0,0 +1,14 @@ +#include "v8datamodel/GameSettings.h" + +namespace RBX +{ + GameSettings::GameSettings() + : chatHistory(50), + chatScrollLength(5), + soundEnabled(true), + softwareSound(false), + animatedCharacter(true) + { + setName("Game Options"); + } +} diff --git a/Client/App/v8datamodel/Hopper.cpp b/Client/App/v8datamodel/Hopper.cpp new file mode 100644 index 00000000..a141045c --- /dev/null +++ b/Client/App/v8datamodel/Hopper.cpp @@ -0,0 +1,181 @@ +#include "v8datamodel/Hopper.h" +#include "v8datamodel/Backpack.h" +#include "v8datamodel/Workspace.h" + +namespace RBX +{ + Reflection::PropDescriptor desc_TextureId("TextureId", "Data", &BackpackItem::getTextureId, &BackpackItem::setTextureId, Reflection::PropertyDescriptor::STANDARD); + + Reflection::PropDescriptor desc_legacyCommand("Command", "Data", NULL, &HopperBin::setLegacyCommand, Reflection::PropertyDescriptor::LEGACY); + Reflection::PropDescriptor desc_legacyTextureName("TextureName", "Data", NULL, &HopperBin::setLegacyTextureName, Reflection::PropertyDescriptor::LEGACY); + Reflection::EnumPropDescriptor desc_BinType("BinType", "Data", &HopperBin::getBinType, &HopperBin::setBinType, Reflection::PropertyDescriptor::STANDARD); + + Reflection::SignalDesc desc_Deselected("Deselected"); + Reflection::SignalDesc)> desc_Selected("Selected", "mouse"); + + Hopper::Hopper() + { + yLocation = Rect::BOTTOM; + } + + bool Hopper::askAddChild(const Instance* instance) const + { + return fastDynamicCast(instance) != NULL; + } + + bool Hopper::askSetParent(const Instance* instance) const + { + return true; + } + + bool BackpackItem::askSetParent(const Instance* instance) const + { + return true; + } + + bool BackpackItem::askAddChild(const Instance* instance) const + { + return true; + } + + const TextureId BackpackItem::getTextureId() const + { + return textureId; + } + + bool BackpackItem::isEnabled() + { + return getParent() && fastDynamicCast(getParent()) != NULL; + } + + void BackpackItem::setTextureId(const TextureId& value) + { + if (value != textureId) + { + textureId = value; + + std::string filename; + ContentProvider::singleton().requestContentFile(value, filename); + + Workspace* workspace = ServiceProvider::find(this); + if (workspace) + workspace->raiseDrawChanged(); + + raisePropertyChanged(desc_TextureId); + } + } + + G3D::Vector2 BackpackItem::getSize() const + { + float width = GuiRoot::toPixelSize(G3D::Vector2(10.0f, 10.0f)).x; + return G3D::Vector2(width, width); + } + + HopperBin::HopperBin() + : binType(SCRIPT_BIN), + active(false) + { + setName("HopperBin"); + } + + void HopperBin::setBinType(const HopperBin::BinType value) + { + if (value != binType) + { + binType = value; + raisePropertyChanged(desc_BinType); + + if (binType != SCRIPT_BIN) + { + std::string textureName = Reflection::EnumDesc::singleton().convertToString(binType); + setLegacyTextureName(textureName); + } + } + } + + void HopperBin::setLegacyTextureName(const std::string& value) + { + TextureId textureId = ContentId::fromAssets("Textures\\" + value + ".png"); + setTextureId(textureId); + } + + void HopperBin::setLegacyCommand(const std::string& text) + { + BinType newBinType; + + if (!Reflection::EnumDesc::singleton().convertToValue(text, newBinType)) + { + newBinType = SCRIPT_BIN; + } + + setBinType(newBinType); + } + + void HopperBin::onLocalClicked() + { + RBXASSERT(isEnabled()); + + if (!active) + { + active = true; + + if (binType == SCRIPT_BIN) + { + onSelectScript(); + } + else + { + onSelectCommand(); + } + } + else + { + onLocalOtherClicked(); + } + } + + void HopperBin::onLocalOtherClicked() + { + if (active) + { + if (binType == SCRIPT_BIN) + desc_Deselected.fire(this); + + active = false; + + Workspace* workspace = ServiceProvider::find(this); + if (workspace) + workspace->setDefaultMouseCommand(); + } + } + + StarterPackService::StarterPackService() + { + setName("StarterPack"); + } + + //97.87% match + //le EPIC TROLL + void StarterPackService::render2d(Adorn* adorn) + { + TopMenuBar::render2d(adorn); + + if (findFirstChildOfType()) + { + G3D::Rect2D viewPort = adorn->getViewport(); + int fontSize = GuiRoot::normalizedFontSize(12); + G3D::Vector2 pos2d = viewPort.x0y1() + G3D::Vector2(4.0f, -4.0f); + + adorn->drawFont2D( + "StarterPack - these items will be given to each new player", + pos2d, + fontSize, + G3D::Color3::white(), + G3D::Color4::clear(), + Adorn::XALIGN_LEFT, + Adorn::YALIGN_BOTTOM, + Adorn::PROPORTIONAL_SPACING + ); + } + } +} diff --git a/Client/App/v8datamodel/ICameraOwner.cpp b/Client/App/v8datamodel/ICameraOwner.cpp new file mode 100644 index 00000000..cd89a4ec --- /dev/null +++ b/Client/App/v8datamodel/ICameraOwner.cpp @@ -0,0 +1,40 @@ +#include "v8datamodel/ICameraOwner.h" +#include "v8datamodel/PartInstance.h" + +namespace RBX +{ + void ICameraOwner::getCameraIgnorePrimitives(std::vector& primitives) + { + for (size_t i = 0; i < cameraIgnoreParts.size(); i++) + { + if (!cameraIgnoreParts[i].expired()) + { + PartInstance* part = cameraIgnoreParts[i].lock().get(); + Primitive* prim = part->getPrimitive(); + + primitives.push_back(prim); + } + } + } + + void ICameraOwner::setCameraIgnoreParts(PartInstance* _set) + { + std::vector temp; + temp.push_back(_set); + + setCameraIgnoreParts(temp); + } + + void ICameraOwner::setCameraIgnoreParts(const std::vector& _set) + { + cameraIgnoreParts.clear(); + + for (size_t i = 0; i < _set.size(); i++) + { + PartInstance* part = _set[i]; + boost::weak_ptr ptr = shared_from(part); + + cameraIgnoreParts.push_back(ptr); + } + } +} diff --git a/Client/App/v8datamodel/ICharacterSubject.cpp b/Client/App/v8datamodel/ICharacterSubject.cpp new file mode 100644 index 00000000..0fcb8e6b --- /dev/null +++ b/Client/App/v8datamodel/ICharacterSubject.cpp @@ -0,0 +1,50 @@ +#include "v8datamodel/ICharacterSubject.h" +#include "v8datamodel/Camera.h" + +namespace RBX +{ + ICharacterSubject::ICharacterSubject() + : lastOffset(G3D::Vector3::ZERO), + cursorLocked(false), + wasOccluded(false), + hasGoalInFocus(false) + { + } + + G3D::CoordinateFrame ICharacterSubject::getFocusLookingAtGoal(const G3D::CoordinateFrame& cameraFocus, const G3D::CoordinateFrame& cameraGoal) + { + G3D::CoordinateFrame temp = cameraFocus; + temp.lookAt(cameraGoal.translation); + + return temp; + } + + G3D::CoordinateFrame ICharacterSubject::goalFromDistance(const G3D::CoordinateFrame& cameraFocus, const G3D::CoordinateFrame& cameraGoal, const float distance) + { + G3D::CoordinateFrame manLookCamera = getFocusLookingAtGoal(cameraFocus, cameraGoal); + G3D::Vector3 newCameraPt = manLookCamera.lookVector() * distance + manLookCamera.translation; + + return G3D::CoordinateFrame(G3D::Matrix3::identity(), newCameraPt); + } + + bool ICharacterSubject::zoom(const float in, G3D::CoordinateFrame& cameraGoal, G3D::CoordinateFrame& cameraFocus) + { + G3D::Vector3 focusToGoal = cameraGoal.translation - cameraFocus.translation; + + float currentDistance = focusToGoal.magnitude(); + float newDistance = Camera::getNewZoomDistance(currentDistance, in); + + newDistance = G3D::min(400.0f, newDistance); + + if (newDistance == currentDistance) + return false; + + focusToGoal.y = 0.0f; + focusToGoal.unitize(); + focusToGoal.y = newDistance * 0.03f; + + cameraGoal.translation = focusToGoal.direction() * newDistance + cameraFocus.translation; + + return true; + } +} diff --git a/Client/App/v8datamodel/IEquipable.cpp b/Client/App/v8datamodel/IEquipable.cpp new file mode 100644 index 00000000..59e5aa56 --- /dev/null +++ b/Client/App/v8datamodel/IEquipable.cpp @@ -0,0 +1,35 @@ +#include "v8datamodel/IEquipable.h" +#include "v8datamodel/JointInstance.h" + +namespace RBX +{ + IEquipable::IEquipable() + : workspace(NULL) + { + } + + IEquipable::~IEquipable() + { + RBXASSERT(!weld); + } + + //95.03% match + void IEquipable::buildWeld(PartInstance* humanoidPart, PartInstance* gadgetPart, const G3D::CoordinateFrame& humanoidCoord, const G3D::CoordinateFrame& gadgetCoord, const std::string& name) + { + G3D::CoordinateFrame attachmentCoordWorld = humanoidPart->getCoordinateFrame() * humanoidCoord; + G3D::CoordinateFrame gadgetCoordWorld = attachmentCoordWorld * gadgetCoord.inverse(); + + gadgetPart->setCoordinateFrame(gadgetCoordWorld); + + RBXASSERT(!weld); + + weld = Creatable::create(); + + weld->setName(name); + weld->setPart0(humanoidPart); + weld->setPart1(humanoidPart); + weld->setC0(humanoidCoord); + weld->setC1(humanoidCoord); + weld->setParent(humanoidPart); + } +} diff --git a/Client/App/v8datamodel/JointsService.cpp b/Client/App/v8datamodel/JointsService.cpp new file mode 100644 index 00000000..a2055ef8 --- /dev/null +++ b/Client/App/v8datamodel/JointsService.cpp @@ -0,0 +1,49 @@ +#include "v8datamodel/JointsService.h" + +namespace RBX +{ + void JointsService::onEvent(const World* source, AutoDestroy event) + { + RBXASSERT(event.joint != NULL); + + IJointOwner* jointOwner = event.joint->getJointOwner(); + RBXASSERT(jointOwner); + + if (jointOwner) + static_cast(jointOwner)->setParent(NULL); + } + + void JointsService::onEvent(const World* source, AutoJoin event) + { + RBXASSERT(event.joint != NULL); + RBXASSERT(event.joint->getJointOwner() == NULL); + + boost::shared_ptr ji; + + switch (event.joint->getJointType()) + { + case Joint::SNAP_JOINT: + ji = Creatable::create(event.joint); + break; + case Joint::WELD_JOINT: + ji = Creatable::create(event.joint); + break; + case Joint::GLUE_JOINT: + ji = Creatable::create(event.joint); + break; + case Joint::ROTATE_JOINT: + ji = Creatable::create(event.joint); + break; + case Joint::ROTATE_P_JOINT: + ji = Creatable::create(event.joint); + break; + case Joint::ROTATE_V_JOINT: + ji = Creatable::create(event.joint); + break; + default: + RBXASSERT(0); + } + + ji->setParent(this); + } +} diff --git a/Client/App/v8datamodel/LocakBackpack.cpp b/Client/App/v8datamodel/LocakBackpack.cpp new file mode 100644 index 00000000..c84c24f2 --- /dev/null +++ b/Client/App/v8datamodel/LocakBackpack.cpp @@ -0,0 +1,103 @@ +#include "v8datamodel/LocalBackpack.h" + +namespace RBX +{ + LocalBackpackItem::LocalBackpackItem() {} + + void LocalBackpackItem::onClick(const GuiEvent& event) + { + LocalBackpack* parent = static_cast(getParent()); + RBXASSERT(fastDynamicCast(getParent()) == parent); + + parent->onClick(this); + } + + G3D::Vector2 LocalBackpackItem::getSize() const + { + float width = GuiRoot::toPixelSize(G3D::Vector2(10.0f, 10.0f)).x; + return G3D::Vector2(width, width); + } + + LocalBackpack::LocalBackpack() + : lastRemovedIndex(-1) + { + yLocation = Rect::BOTTOM; + } + + LocalBackpack::~LocalBackpack() + { + clearAll(); + } + + void LocalBackpack::onEvent(const Instance* source, ChildAdded event) + { + Instance* child = event.child.get(); + + if (Network::Player* player = fastDynamicCast(child)) + { + if (player == Network::Players::findLocalPlayer(this)) + { + onLocalPlayerAdded(player); + } + } + else + { + if (Backpack* backpack = fastDynamicCast(child)) + { + onLocalBackpackAdded(backpack); + } + else if (BackpackItem* backpackItem = fastDynamicCast(child)) + { + insertBackpackItem(backpackItem); + } + } + } + + void LocalBackpack::onEvent(const Instance* source, ChildRemoved event) + { + Instance* child = event.child.get(); + + if (Network::Player* player = fastDynamicCast(child)) + { + if (player == localPlayer.get()) + { + clearLocalPlayer(); + } + } + else + { + if (Backpack* backpack = fastDynamicCast(child)) + { + RBXASSERT(localBackpack); + clearLocalBackpack(); + } + else if (BackpackItem* backpackItem = fastDynamicCast(child)) + { + removeBackpackItem(backpackItem); + } + } + } + + void LocalBackpack::onEvent(const Instance* source, DescendentAdded event) + { + RBXASSERT(source == localCharacter.get()); + + BackpackItem* backpackItem = fastDynamicCast(event.instance.get()); + if (backpackItem) + insertBackpackItem(backpackItem); + } + + void LocalBackpack::onEvent(const Instance* source, DescendentRemoving event) + { + RBXASSERT(source == localCharacter.get()); + + BackpackItem* backpackItem = fastDynamicCast(event.instance.get()); + if (backpackItem) + removeBackpackItem(backpackItem); + } + + void LocalBackpack::onClick(LocalBackpackItem* clickedItem) + { + pendingClick = shared_from(clickedItem->getItem()); + } +} diff --git a/Client/App/v8datamodel/Message.cpp b/Client/App/v8datamodel/Message.cpp new file mode 100644 index 00000000..c008dd1a --- /dev/null +++ b/Client/App/v8datamodel/Message.cpp @@ -0,0 +1,47 @@ +#include "v8datamodel/Message.h" +#include "util/Rect.h" +#include "Network/Player.h" + +namespace RBX +{ + Reflection::PropDescriptor desc_Text("Text", "Appearance", &Message::getText, &Message::setText, Reflection::PropertyDescriptor::STANDARD); + + Message::Message() + : Base("Message") + { + } + + void Message::setText(const std::string& value) + { + if (text != value) + { + text = value; + raisePropertyChanged(desc_Text); + } + } + + void Message::render2d(Adorn* adorn) + { + if (text.size() > 0) + { + if (!fastDynamicCast(getParent())) + { + renderFullScreen(adorn); + } + else + { + renderPersonalMsg(adorn); + } + } + } + + void Message::renderFullScreen(Adorn* adorn) + { + G3D::Rect2D rect = adorn->getViewport(); + Rect translucentArea = rect; + G3D::Vector2 textPos = rect.center(); + + adorn->rect2d(translucentArea.toRect2D(), G3D::Color4(0.5f, 0.5f, 0.5f, 0.5f)); + adorn->drawFont2D(text, textPos, 14.0, G3D::Color3::white(), G3D::Color3::black(), Adorn::XALIGN_CENTER, Adorn::YALIGN_CENTER, Adorn::PROPORTIONAL_SPACING); + } +} diff --git a/Client/App/v8datamodel/Mouse.cpp b/Client/App/v8datamodel/Mouse.cpp new file mode 100644 index 00000000..13d4f14c --- /dev/null +++ b/Client/App/v8datamodel/Mouse.cpp @@ -0,0 +1,44 @@ +#include "v8datamodel/Mouse.h" +#include "v8datamodel/MouseCommand.h" +#include "v8datamodel/PartInstance.h" +#include + +namespace RBX +{ + G3D::CoordinateFrame Mouse::getHit() const + { + checkActive(); + + G3D::CoordinateFrame origin = getOrigin(); + + if (command) + command->getPartByLocalCharacter(lastEvent, origin.translation); + + return origin; + } + + G3D::CoordinateFrame Mouse::getOrigin() const + { + checkActive(); + + G3D::Ray ray; + + if (command) + ray = command->getUnitMouseRay(lastEvent); + + G3D::CoordinateFrame origin(ray.origin); + origin.lookAt(ray.origin + ray.direction); + + return origin; + } + + PartInstance* Mouse::getTarget() const + { + checkActive(); + + if (command) + return command->getPart(lastEvent, NULL); + else + return NULL; + } +} diff --git a/Client/App/v8datamodel/MouseCommand.cpp b/Client/App/v8datamodel/MouseCommand.cpp new file mode 100644 index 00000000..cccd6b02 --- /dev/null +++ b/Client/App/v8datamodel/MouseCommand.cpp @@ -0,0 +1,108 @@ +#include "v8datamodel/MouseCommand.h" +#include "v8datamodel/PartInstance.h" +#include "v8datamodel/Workspace.h" +#include "v8world/ContactManager.h" +#include "v8world/Primitive.h" +#include "humanoid/Humanoid.h" + +namespace RBX +{ + MouseCommand::MouseCommand(Workspace* workspace) + : workspace(workspace), + capturedMouse(false) + { + } + + MouseCommand::~MouseCommand() + { + RBXASSERT(undoState.get() == NULL); + } + + bool MouseCommand::characterCanReach(const G3D::Vector3& hitPoint) const + { + PartInstance* head = Humanoid::getLocalHeadFromContext(workspace); + + if (head) + return (head->getCoordinateFrame().translation - hitPoint).magnitude() < 60.0; + else + return false; + } + + TextureId MouseCommand::getCursorId() const + { + return TextureId::fromAssets("Textures\\" + getCursorName() + ".png"); + } + + PartInstance* MouseCommand::getMousePart(const G3D::Ray& unitRay, const ContactManager& contactManager, const std::vector& ignore, const HitTestFilter* filter, G3D::Vector3& hitPoint, float maxSearchGrid) + { + RBXASSERT(G3D::fuzzyEq(unitRay.direction.squaredMagnitude(), 1.0f)); + + G3D::Ray searchRay = G3D::Ray::fromOriginAndDirection(unitRay.origin, unitRay.direction * 2048.0f); // MouseCommand::getSearchRay inline + Primitive* primitive = contactManager.getHit(searchRay, &ignore, filter, hitPoint); + + return primitive ? PartInstance::fromPrimitive(primitive) : NULL; + } + + PartInstance* MouseCommand::getMousePart(const G3D::Ray& unitRay, const ContactManager& contactManager, const Primitive* ignore, const HitTestFilter* filter, G3D::Vector3& hitPoint, float maxSearchGrid) + { + std::vector ignorePrims; + ignorePrims.push_back(ignore); + + return getMousePart(unitRay, contactManager, ignorePrims, filter, hitPoint, maxSearchGrid); + } + + G3D::Ray MouseCommand::getSearchRay(const G3D::Ray& unitRay) + { + RBXASSERT(G3D::fuzzyEq(unitRay.direction.squaredMagnitude(), 1.0f)); + return G3D::Ray::fromOriginAndDirection(unitRay.origin, unitRay.direction * 2048.0f); + } + + G3D::Ray MouseCommand::getSearchRay(const UIEvent& uiEvent, ICameraOwner* _workspace) + { + G3D::Ray unitRay = getUnitMouseRay(uiEvent, _workspace); + return getSearchRay(unitRay); + } + + G3D::Ray MouseCommand::getSearchRay(const UIEvent& uiEvent) const + { + return getSearchRay(uiEvent, workspace); + } + + G3D::Ray MouseCommand::getUnitMouseRay(const UIEvent& uiEvent, ICameraOwner* _workspace) + { + return _workspace->getGCamera().worldRay( + uiEvent.mousePosition.x, + uiEvent.mousePosition.y, + G3D::Rect2D::xyxy(0.0f, 0.0f, uiEvent.windowSize.x, uiEvent.windowSize.y) + ); + } + + G3D::Ray MouseCommand::getUnitMouseRay(const UIEvent& uiEvent) const + { + return getUnitMouseRay(uiEvent, workspace); + } + + PartInstance* MouseCommand::getPart(const UIEvent& uiEvent, const HitTestFilter* filter, G3D::Vector3& hitWorld) + { + G3D::Ray unitRay = getUnitMouseRay(uiEvent); + ContactManager& contactManager = workspace->getWorld()->getContactManager(); + + std::vector ignorePrims; + static_cast(workspace)->getCameraIgnorePrimitives(ignorePrims); + + if (Camera* camera = workspace->getCamera()) + { + if (ICharacterSubject* subject = dynamic_cast(camera->getCameraSubject())) + { + subject->getCameraIgnorePrimitives(ignorePrims); + } + } + + PartInstance* part = getMousePart(unitRay, contactManager, ignorePrims, filter, hitWorld, 2048.0f); + + if (!part) + hitWorld = unitRay.origin + unitRay.direction * 10000.0f; + + return part; + } +} diff --git a/Client/App/v8datamodel/ScriptMouseCommand.cpp b/Client/App/v8datamodel/ScriptMouseCommand.cpp new file mode 100644 index 00000000..350446d8 --- /dev/null +++ b/Client/App/v8datamodel/ScriptMouseCommand.cpp @@ -0,0 +1,51 @@ +#include "v8datamodel/ScriptMouseCommand.h" +#include "v8datamodel/Mouse.h" + +namespace RBX +{ + ScriptMouseCommand::ScriptMouseCommand(Workspace* workspace) + : MouseCommand(workspace) + { + mouse = Creatable::create(); + mouse->setCommand(this); + } + + ScriptMouseCommand::~ScriptMouseCommand() + { + mouse->setCommand(NULL); + mouse->disconnect_all_slots(); + } + + TextureId ScriptMouseCommand::getCursorId() const + { + return mouse->getIcon(); + } + + MouseCommand* ScriptMouseCommand::onMouseDown(const UIEvent& uiEvent) + { + mouse->update(uiEvent); + return this; + } + + MouseCommand* ScriptMouseCommand::onMouseUp(const UIEvent& uiEvent) + { + mouse->update(uiEvent); + return this; + } + + MouseCommand* ScriptMouseCommand::onPeekKeyDown(const UIEvent& uiEvent) + { + mouse->update(uiEvent); + return this; + } + + void ScriptMouseCommand::onMouseIdle(const UIEvent& uiEvent) + { + mouse->update(uiEvent); + } + + void ScriptMouseCommand::onMouseHover(const UIEvent& uiEvent) + { + mouse->update(uiEvent); + } +} diff --git a/Client/App/v8datamodel/Sky.cpp b/Client/App/v8datamodel/Sky.cpp new file mode 100644 index 00000000..8682ac20 --- /dev/null +++ b/Client/App/v8datamodel/Sky.cpp @@ -0,0 +1,18 @@ +#include "v8datamodel/Sky.h" + +namespace RBX +{ + Sky::Sky() + : drawCelestialBodies(true), + numStars(3000) + { + setName("Sky"); + + skyUp = ContentId::fromAssets("Sky\\null_plainsky512_up.jpg"); + skyLf = ContentId::fromAssets("Sky\\null_plainsky512_lf.jpg"); + skyRt = ContentId::fromAssets("Sky\\null_plainsky512_rt.jpg"); + skyBk = ContentId::fromAssets("Sky\\null_plainsky512_bk.jpg"); + skyFt = ContentId::fromAssets("Sky\\null_plainsky512_ft.jpg"); + skyDn = ContentId::fromAssets("Sky\\null_plainsky512_dn.jpg"); + } +} diff --git a/Client/App/v8datamodel/SpawnLocation.cpp b/Client/App/v8datamodel/SpawnLocation.cpp new file mode 100644 index 00000000..534acd41 --- /dev/null +++ b/Client/App/v8datamodel/SpawnLocation.cpp @@ -0,0 +1,102 @@ +#include "v8datamodel/SpawnLocation.h" +#include "Network/Players.h" + +namespace RBX +{ + Reflection::PropDescriptor prop_TeamColor("TeamColor", "Teams", &SpawnLocation::getTeamColor, &SpawnLocation::setTeamColor, Reflection::PropertyDescriptor::STANDARD); + + SpawnLocation::SpawnLocation() + : neutral(true), + allowTeamChangeOnTouch(false) + { + setName("SpawnLocation"); + } + + BrickColor SpawnLocation::getTeamColor() const + { + return teamColor; + } + + void SpawnLocation::setTeamColor(BrickColor color) + { + teamColor = color; + raisePropertyChanged(prop_TeamColor); + } + + //99.81% match + //somehow stack usage in the DLL is less optimized + void SpawnLocation::onServiceProvider(const ServiceProvider* oldProvider, const ServiceProvider* newProvider) + { + Instance::onServiceProvider(oldProvider, newProvider); + + if (!oldProvider) + { + boost::slot)>> slot(boost::bind(&SpawnLocation::onEvent_spawnerTouched, this, _1)); + spawnerTouched = PartInstance::event_Touched.connect(this, slot); + } + + if (!oldProvider) + { + SpawnerService* spawnerService = newProvider ? newProvider->create() : NULL; + RBXASSERT(spawnerService != NULL); + + spawnerService->RegisterSpawner(this); + } + + if (!newProvider) + { + spawnerTouched.disconnect(); + + SpawnerService* spawnerService = oldProvider ? oldProvider->create() : NULL; + RBXASSERT(spawnerService != NULL); + + spawnerService->UnregisterSpawner(this); + } + } + + SpawnerService::SpawnerService() + { + setName("SpawnerService"); + Instance::propArchivable.setValue(this, false); + } + + SpawnerService::~SpawnerService() {} + + void SpawnerService::RegisterSpawner(SpawnLocation* spawner) + { + spawners.push_back(spawner); + } + + void SpawnerService::UnregisterSpawner(SpawnLocation* spawner) + { + spawners.remove(spawner); + } + + G3D::Vector3 SpawnerService::FindSpawnPositionForPlayer(Network::Player* p) + { + if (spawners.empty()) + return G3D::Vector3(0.0f, 100.0f, 0.0f); + + std::vector possibleLocations; + + for (std::list::const_iterator iter = spawners.begin(); iter != spawners.end(); iter++) + { + if ((*iter)->neutral || (!p->getNeutral() && p->getTeamColor() == (*iter)->getTeamColor())) + { + possibleLocations.push_back(*iter); + } + } + + if (possibleLocations.empty()) + { + return G3D::Vector3(0.0f, 100.0f, 0.0f); + } + else + { + G3D::Vector3 spawnPos = possibleLocations[rand() % possibleLocations.size()]->getCoordinateFrame().translation; + spawnPos.y += 7.0f; + + return spawnPos; + } + } +} diff --git a/Client/App/v8datamodel/Surface.cpp b/Client/App/v8datamodel/Surface.cpp new file mode 100644 index 00000000..7e040d87 --- /dev/null +++ b/Client/App/v8datamodel/Surface.cpp @@ -0,0 +1,53 @@ +#include "v8datamodel/Surface.h" +#include "v8datamodel/PartInstance.h" + +namespace RBX +{ + Surface::Surface(PartInstance* partInstance, NormalId surfId) + : partInstance(partInstance), + surfId(surfId) + { + } + + bool Surface::isControllable() const + { + Controller::InputType inputType = getInput(); + return inputType != Controller::NO_INPUT && inputType != Controller::CONSTANT_INPUT && inputType != Controller::SIN_INPUT; + } + + SurfaceType Surface::getSurfaceType() const + { + RBXASSERT(partInstance->getPrimitive()); + return partInstance->getPrimitive()->getSurfaceType(surfId); + } + + void Surface::setSurfaceType(SurfaceType type) + { + if (type != getSurfaceType()) + { + partInstance->getPrimitive()->setSurfaceType(surfId, type); + partInstance->onSurfaceChanged(surfId); + partInstance->raisePropertyChanged(partInstance->getSurfaces().getSurfaceType(surfId)); + } + } + + // the functions below don't match 100% most likely due to Primitive::getSurfaceData + + Controller::InputType Surface::getInput() const + { + RBXASSERT(partInstance->getPrimitive()); + return partInstance->getPrimitive()->getSurfaceData(surfId).inputType; + } + + float Surface::getParamA() const + { + RBXASSERT(partInstance->getPrimitive()); + return partInstance->getPrimitive()->getSurfaceData(surfId).paramA; + } + + float Surface::getParamB() const + { + RBXASSERT(partInstance->getPrimitive()); + return partInstance->getPrimitive()->getSurfaceData(surfId).paramB; + } +} diff --git a/Client/App/v8datamodel/TimeState.cpp b/Client/App/v8datamodel/TimeState.cpp new file mode 100644 index 00000000..b1495228 --- /dev/null +++ b/Client/App/v8datamodel/TimeState.cpp @@ -0,0 +1,14 @@ +#include "v8datamodel/TimeState.h" + +namespace RBX +{ + TimeState::TimeState() + : totalVirtualTime(0.0f) + { + } + + void TimeState::clear() + { + totalVirtualTime = 0.0f; + } +} diff --git a/Client/App/v8datamodel/ToolMouseCommand.cpp b/Client/App/v8datamodel/ToolMouseCommand.cpp new file mode 100644 index 00000000..c12106c2 --- /dev/null +++ b/Client/App/v8datamodel/ToolMouseCommand.cpp @@ -0,0 +1,41 @@ +#include "v8datamodel/ToolMouseCommand.h" +#include "v8datamodel/PartInstance.h" +#include "v8datamodel/Tool.h" +#include "humanoid/Humanoid.h" + +namespace RBX +{ + ToolMouseCommand::ToolMouseCommand(Workspace* workspace, Tool* tool) + : Base(workspace), + tool(shared_from(tool)) + { + } + + ToolMouseCommand::~ToolMouseCommand() {} + + void ToolMouseCommand::onMouseHover(const UIEvent& uiEvent) + { + updateTargetPoint(uiEvent); + ScriptMouseCommand::onMouseHover(uiEvent); + } + + void ToolMouseCommand::onMouseIdle(const UIEvent& uiEvent) + { + updateTargetPoint(uiEvent); + ScriptMouseCommand::onMouseIdle(uiEvent); + } + + MouseCommand* ToolMouseCommand::onMouseDown(const UIEvent& uiEvent) + { + updateTargetPoint(uiEvent); + tool->activate(); + return ScriptMouseCommand::onMouseDown(uiEvent); + } + + MouseCommand* ToolMouseCommand::onMouseUp(const UIEvent& uiEvent) + { + updateTargetPoint(uiEvent); + tool->deactivate(); + return ScriptMouseCommand::onMouseUp(uiEvent); + } +} diff --git a/Client/App/v8datamodel/Visit.cpp b/Client/App/v8datamodel/Visit.cpp new file mode 100644 index 00000000..0dd9d52b --- /dev/null +++ b/Client/App/v8datamodel/Visit.cpp @@ -0,0 +1,50 @@ +#include "v8datamodel/Visit.h" +#include "util/Http.h" +#include "util/standardout.h" +#include +#include + +namespace RBX +{ + Visit::Visit() + : uploadUrl("NoVisit") + { + } + + Visit::~Visit() {} + + void Visit::setPing(std::string url, int interval) + { + if (url != "") + { + pingThread.reset(new worker_thread(boost::bind(&Visit::ping, url, interval), "rbx_visit")); + } + else + { + pingThread.reset(); + } + } + + worker_thread::work_result Visit::ping(std::string url, int interval) + { + try + { + std::string message; + Http(url).get(message); + } + catch (std::exception& exp) + { + std::string failMessage = G3D::format("ping %s failed: %s", url.c_str(), exp.what()); + StandardOut::singleton()->print(MESSAGE_WARNING, failMessage.c_str()); + } + + boost::xtime xt; + boost::xtime_get(&xt, boost::TIME_UTC); + + xt.sec += interval; + + boost::thread::sleep(xt); + + return worker_thread::more; + } +} diff --git a/Client/App/v8tree/Instance.cpp b/Client/App/v8tree/Instance.cpp index 8ebdb956..a2ec8703 100644 --- a/Client/App/v8tree/Instance.cpp +++ b/Client/App/v8tree/Instance.cpp @@ -86,14 +86,6 @@ namespace RBX return askAddChild(instance) || askSetParent(instance); } - size_t Instance::numChildren() const - { - if (&(*children)) - return children->size(); - else - return 0; - } - Instance* Instance::getRootAncestor() { Instance* ancestor = this;