//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames // Copyright (C) 2015 Faust Logic, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// #include #include "afx/arcaneFX.h" #include "gui/core/guiControl.h" #include "gui/3d/guiTSControl.h" #include "T3D/gameBase/gameConnection.h" #include "gui/game/guiProgressCtrl.h" #include "afx/afxChoreographer.h" #include "afx/afxEffectDefs.h" #include "afx/afxEffectWrapper.h" #include "afx/ce/afxGuiController.h" #include "afx/ui/afxProgressBase.h" //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// // afxEA_GuiController class afxEA_GuiController : public afxEffectWrapper { typedef afxEffectWrapper Parent; afxGuiControllerData* controller_data; GuiControl* gui_control; GuiTSCtrl* ts_ctrl; afxProgressBase* progress_base; GuiProgressCtrl* progress_ctrl; void do_runtime_substitutions(); public: /*C*/ afxEA_GuiController(); virtual void ea_set_datablock(SimDataBlock*); virtual bool ea_start(); virtual bool ea_update(F32 dt); virtual void ea_finish(bool was_stopped); }; //~~~~~~~~~~~~~~~~~~~~// afxEA_GuiController::afxEA_GuiController() { controller_data = 0; gui_control = 0; ts_ctrl = 0; progress_base = 0; progress_ctrl = 0; } void afxEA_GuiController::ea_set_datablock(SimDataBlock* db) { controller_data = dynamic_cast(db); } bool afxEA_GuiController::ea_start() { if (!controller_data) { Con::errorf("afxEA_GuiController::ea_start() -- missing or incompatible datablock."); return false; } do_runtime_substitutions(); if (controller_data->ctrl_client_only) { afxConstraint* pos_cons = getPosConstraint(); if (!pos_cons) return false; // not an error condition GameBase* gamebase_obj = dynamic_cast(pos_cons->getSceneObject()); if (!gamebase_obj || !gamebase_obj->getControllingClient()) return false; // not an error condition } if (controller_data->control_name == ST_NULLSTRING || controller_data->control_name[0] == '\0') { Con::errorf("afxEA_GuiController::ea_start() -- empty control name."); return false; } gui_control = dynamic_cast(Sim::findObject(controller_data->control_name)); if (!gui_control) { Con::errorf("afxEA_GuiController::ea_start() -- failed to find control \"%s\".", controller_data->control_name); return false; } gui_control->setVisible(true); progress_base = dynamic_cast(gui_control); if (progress_base) { progress_base->setProgress(0.0f); progress_ctrl = 0; } else { progress_ctrl = (GuiProgressCtrl*)gui_control; if (progress_ctrl) { progress_ctrl->setScriptValue(0); progress_base = 0; } } ts_ctrl = 0; for (GuiControl* ctrl = gui_control->getParent(); ctrl != 0; ctrl->getParent()) { if (dynamic_cast(ctrl)) { ts_ctrl = (GuiTSCtrl*) ctrl; break; } } return true; } bool afxEA_GuiController::ea_update(F32 dt) { if (ts_ctrl && !controller_data->preserve_pos) { Point3F screen_pos; if (ts_ctrl->project(mUpdated_pos, &screen_pos)) { const Point2I ext = gui_control->getExtent(); Point2I newpos(screen_pos.x - ext.x/2, screen_pos.y - ext.y/2); gui_control->setPosition(newpos); } } if (progress_base) progress_base->setProgress((mEW_timing.lifetime > 0.0) ? mLife_elapsed / mEW_timing.lifetime : 0.0f); else if (progress_ctrl) progress_ctrl->setScriptValue((mEW_timing.lifetime > 0.0) ? avar("%g", mLife_elapsed / mEW_timing.lifetime) : 0); if (mDo_fades) gui_control->setFadeAmount(mFade_value); return true; } void afxEA_GuiController::ea_finish(bool was_stopped) { if (progress_base) progress_base->setProgress(1.0f); else if (progress_ctrl) progress_ctrl->setScriptValue("1"); gui_control->setVisible(false); } void afxEA_GuiController::do_runtime_substitutions() { // only clone the datablock if there are substitutions if (controller_data->getSubstitutionCount() > 0) { // clone the datablock and perform substitutions afxGuiControllerData* orig_db = controller_data; controller_data = new afxGuiControllerData(*orig_db, true); orig_db->performSubstitutions(controller_data, mChoreographer, mGroup_index); } } //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// class afxEA_GuiControllerDesc : public afxEffectAdapterDesc, public afxEffectDefs { static afxEA_GuiControllerDesc desc; public: virtual bool testEffectType(const SimDataBlock*) const; virtual bool requiresStop(const afxEffectWrapperData*, const afxEffectTimingData&) const; virtual bool runsOnServer(const afxEffectWrapperData*) const { return false; } virtual bool runsOnClient(const afxEffectWrapperData*) const { return true; } virtual afxEffectWrapper* create() const { return new afxEA_GuiController; } }; afxEA_GuiControllerDesc afxEA_GuiControllerDesc::desc; bool afxEA_GuiControllerDesc::testEffectType(const SimDataBlock* db) const { return (typeid(afxGuiControllerData) == typeid(*db)); } bool afxEA_GuiControllerDesc::requiresStop(const afxEffectWrapperData* ew, const afxEffectTimingData& timing) const { return (timing.lifetime < 0); } //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//