afxPhraseEffect.cpp
Engine/source/afx/ce/afxPhraseEffect.cpp
Public Defines
define
myOffset(field) (field, )
Public Variables
Public Functions
ConsoleDocClass(afxPhraseEffectData , "@brief A datablock that specifies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Phrase Effect, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> grouping of other <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n\n</a>" "A Phrase Effect is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> grouping or phrase of effects that do nothing until certain trigger events occur. It 's like having <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> whole " "Effectron organized as an individual effect." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Phrase effects can respond <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> number of different kinds of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggers:\n</a>" " -- <a href="/coding/class/classplayer/">Player</a> triggers such as footsteps, jumps , landings , and idle <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggers.\n</a>" " -- Arbitrary animation triggers on dts-based scene <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n</a>" " -- Arbitrary trigger bits assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> active choreographer objects." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
DefineEngineMethod(afxPhraseEffectData , pushEffect , void , (afxEffectBaseData *effectData) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child effect <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> phrase effect datablock. Argument can be an afxEffectWrappperData or an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffectGroupData.\n</a>" )
ImplementEnumType(afxPhraseEffect_MatchType , "Possible phrase effect match <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxPhraseEffect\n\n</a>" )
ImplementEnumType(afxPhraseEffect_PhraseType , "Possible phrase effect <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxPhraseEffect\n\n</a>" )
ImplementEnumType(afxPhraseEffect_StateType , "Possible phrase effect state <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxPhraseEffect\n\n</a>" )
Detailed Description
Public Defines
myOffset(field) (field, )
Public Variables
EndImplementEnumType
Public Functions
ConsoleDocClass(afxPhraseEffectData , "@brief A datablock that specifies <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> Phrase Effect, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> grouping of other <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n\n</a>" "A Phrase Effect is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> grouping or phrase of effects that do nothing until certain trigger events occur. It 's like having <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> whole " "Effectron organized as an individual effect." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "Phrase effects can respond <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> number of different kinds of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggers:\n</a>" " -- <a href="/coding/class/classplayer/">Player</a> triggers such as footsteps, jumps , landings , and idle <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">triggers.\n</a>" " -- Arbitrary animation triggers on dts-based scene <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n</a>" " -- Arbitrary trigger bits assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> active choreographer objects." "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffects\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
DefineEngineMethod(afxPhraseEffectData , pushEffect , void , (afxEffectBaseData *effectData) , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> child effect <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> phrase effect datablock. Argument can be an afxEffectWrappperData or an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxEffectGroupData.\n</a>" )
IMPLEMENT_CO_DATABLOCK_V1(afxPhraseEffectData )
ImplementEnumType(afxPhraseEffect_MatchType , "Possible phrase effect match <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxPhraseEffect\n\n</a>" )
ImplementEnumType(afxPhraseEffect_PhraseType , "Possible phrase effect <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxPhraseEffect\n\n</a>" )
ImplementEnumType(afxPhraseEffect_StateType , "Possible phrase effect state <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxPhraseEffect\n\n</a>" )
1 2 3//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 4// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 5// Copyright (C) 2015 Faust Logic, Inc. 6// 7// Permission is hereby granted, free of charge, to any person obtaining a copy 8// of this software and associated documentation files (the "Software"), to 9// deal in the Software without restriction, including without limitation the 10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11// sell copies of the Software, and to permit persons to whom the Software is 12// furnished to do so, subject to the following conditions: 13// 14// The above copyright notice and this permission notice shall be included in 15// all copies or substantial portions of the Software. 16// 17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23// IN THE SOFTWARE. 24// 25//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 26 27#include "afx/arcaneFX.h" 28 29#include "console/engineAPI.h" 30 31#include "afx/afxEffectWrapper.h" 32#include "afx/ce/afxPhraseEffect.h" 33 34//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 35// afxPhraseEffectData::ewValidator 36// 37// When an effect is added using "addEffect", this validator intercepts the value 38// and adds it to the dynamic effects list. 39// 40void afxPhraseEffectData::ewValidator::validateType(SimObject* object, void* typePtr) 41{ 42 afxPhraseEffectData* eff_data = dynamic_cast<afxPhraseEffectData*>(object); 43 afxEffectBaseData** ew = (afxEffectBaseData**)(typePtr); 44 45 if (eff_data && ew) 46 { 47 eff_data->fx_list.push_back(*ew); 48 *ew = 0; 49 } 50} 51 52//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 53// afxPhraseEffectData 54 55IMPLEMENT_CO_DATABLOCK_V1(afxPhraseEffectData); 56 57ConsoleDocClass( afxPhraseEffectData, 58 "@brief A datablock that specifies a Phrase Effect, a grouping of other effects.\n\n" 59 60 "A Phrase Effect is a grouping or phrase of effects that do nothing until certain trigger events occur. It's like having a whole " 61 "Effectron organized as an individual effect." 62 "\n\n" 63 64 "Phrase effects can respond to a number of different kinds of triggers:\n" 65 " -- Player triggers such as footsteps, jumps, landings, and idle triggers.\n" 66 " -- Arbitrary animation triggers on dts-based scene objects.\n" 67 " -- Arbitrary trigger bits assigned to active choreographer objects." 68 "\n\n" 69 70 "@ingroup afxEffects\n" 71 "@ingroup AFX\n" 72 "@ingroup Datablocks\n" 73); 74 75afxPhraseEffectData::afxPhraseEffectData() 76{ 77 duration = 0.0f; 78 n_loops = 1; 79 80 // dummy entry holds effect-wrapper pointer while a special validator 81 // grabs it and adds it to an appropriate effects list 82 dummy_fx_entry = NULL; 83 84 // marked true if datablock ids need to 85 // be converted into pointers 86 do_id_convert = false; 87 88 trigger_mask = 0; 89 match_type = MATCH_ANY; 90 match_state = STATE_ON; 91 phrase_type = PHRASE_TRIGGERED; 92 93 no_choreographer_trigs = false; 94 no_cons_trigs = false; 95 no_player_trigs = false; 96 97 on_trig_cmd = ST_NULLSTRING; 98} 99 100afxPhraseEffectData::afxPhraseEffectData(const afxPhraseEffectData& other, bool temp_clone) : GameBaseData(other, temp_clone) 101{ 102 duration = other.duration; 103 n_loops = other.n_loops; 104 dummy_fx_entry = other.dummy_fx_entry; 105 do_id_convert = other.do_id_convert; // -- 106 trigger_mask = other.trigger_mask; 107 match_type = other.match_type; 108 match_state = other.match_state; 109 phrase_type = other.phrase_type; 110 no_choreographer_trigs = other.no_choreographer_trigs; 111 no_cons_trigs = other.no_cons_trigs; 112 no_player_trigs = other.no_player_trigs; 113 on_trig_cmd = other.on_trig_cmd; 114 115 // fx_list; // -- ?? 116} 117 118void afxPhraseEffectData::reloadReset() 119{ 120 fx_list.clear(); 121} 122 123ImplementEnumType( afxPhraseEffect_MatchType, "Possible phrase effect match types.\n" "@ingroup afxPhraseEffect\n\n" ) 124 { afxPhraseEffectData::MATCH_ANY, "any", "..." }, 125 { afxPhraseEffectData::MATCH_ALL, "all", "..." }, 126EndImplementEnumType; 127 128ImplementEnumType( afxPhraseEffect_StateType, "Possible phrase effect state types.\n" "@ingroup afxPhraseEffect\n\n" ) 129 { afxPhraseEffectData::STATE_ON, "on", "..." }, 130 { afxPhraseEffectData::STATE_OFF, "off", "..." }, 131 { afxPhraseEffectData::STATE_ON_AND_OFF, "both", "..." }, 132EndImplementEnumType; 133 134ImplementEnumType( afxPhraseEffect_PhraseType, "Possible phrase effect types.\n" "@ingroup afxPhraseEffect\n\n" ) 135 { afxPhraseEffectData::PHRASE_TRIGGERED, "triggered", "..." }, 136 { afxPhraseEffectData::PHRASE_CONTINUOUS, "continuous", "..." }, 137EndImplementEnumType; 138 139#define myOffset(field) Offset(field, afxPhraseEffectData) 140 141void afxPhraseEffectData::initPersistFields() 142{ 143 addField("duration", TypeF32, myOffset(duration), 144 "Specifies a duration for the phrase-effect. If set to infinity, the phrase-effect " 145 "needs to have a phraseType of continuous. Set infinite duration using " 146 "$AFX::INFINITE_TIME."); 147 addField("numLoops", TypeS32, myOffset(n_loops), 148 "Specifies the number of times the phrase-effect should loop. If set to infinity, " 149 "the phrase-effect needs to have a phraseType of continuous. Set infinite looping " 150 "using $AFX::INFINITE_REPEATS."); 151 addField("triggerMask", TypeS32, myOffset(trigger_mask), 152 "Sets which bits to consider in the current trigger-state which consists of 32 " 153 "trigger-bits combined from (possibly overlapping) player trigger bits, constraint " 154 "trigger bits, and choreographer trigger bits."); 155 156 addField("matchType", TYPEID<afxPhraseEffectData::MatchType>(), myOffset(match_type), 157 "Selects what combination of bits in triggerMask lead to a trigger. When set to " 158 "'any', any bit in triggerMask matching the current trigger-state will cause a " 159 "trigger. If set to 'all', every bit in triggerMask must match the trigger-state. " 160 "Possible values: any or all."); 161 addField("matchState", TYPEID<afxPhraseEffectData::StateType>(), myOffset(match_state), 162 "Selects which bit-state(s) of bits in the triggerMask to consider when comparing to " 163 "the current trigger-state. Possible values: on, off, or both."); 164 addField("phraseType", TYPEID<afxPhraseEffectData::PhraseType>(), myOffset(phrase_type), 165 "Selects between triggered and continuous types of phrases. When set to 'triggered', " 166 "the phrase-effect is triggered when the relevant trigger-bits change state. When set " 167 "to 'continuous', the phrase-effect will stay active as long as the trigger-bits " 168 "remain in a matching state. Possible values: triggered or continuous."); 169 170 addField("ignoreChoreographerTriggers", TypeBool, myOffset(no_choreographer_trigs), 171 "When true, trigger-bits on the choreographer will be ignored."); 172 addField("ignoreConstraintTriggers", TypeBool, myOffset(no_cons_trigs), 173 "When true, animation triggers from dts-based constraint source objects will be " 174 "ignored."); 175 addField("ignorePlayerTriggers", TypeBool, myOffset(no_player_trigs), 176 "When true, Player-specific triggers from Player-derived constraint source objects " 177 "will be ignored."); 178 179 addField("onTriggerCommand", TypeString, myOffset(on_trig_cmd), 180 "Like a field substitution statement without the leading '$$' token, this eval " 181 "statement will be executed when a trigger occurs. Any '%%' and '##' tokens will be " 182 "substituted."); 183 184 // effect lists 185 // for each of these, dummy_fx_entry is set and then a validator adds it to the appropriate effects list 186 static ewValidator emptyValidator(0); 187 addFieldV("addEffect", TYPEID< afxEffectBaseData >(), myOffset(dummy_fx_entry), &emptyValidator, 188 "A field macro which adds an effect wrapper datablock to a list of effects associated " 189 "with the phrase-effect's single phrase. Unlike other fields, addEffect follows an " 190 "unusual syntax. Order is important since the effects will resolve in the order they " 191 "are added to each list."); 192 193 Parent::initPersistFields(); 194 195 // disallow some field substitutions 196 disableFieldSubstitutions("addEffect"); 197} 198 199bool afxPhraseEffectData::onAdd() 200{ 201 if (Parent::onAdd() == false) 202 return false; 203 204 return true; 205} 206 207void afxPhraseEffectData::pack_fx(BitStream* stream, const afxEffectList& fx, bool packed) 208{ 209 stream->writeInt(fx.size(), EFFECTS_PER_PHRASE_BITS); 210 for (int i = 0; i < fx.size(); i++) 211 writeDatablockID(stream, fx[i], packed); 212} 213 214void afxPhraseEffectData::unpack_fx(BitStream* stream, afxEffectList& fx) 215{ 216 fx.clear(); 217 S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS); 218 for (int i = 0; i < n_fx; i++) 219 fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream)); 220} 221 222void afxPhraseEffectData::packData(BitStream* stream) 223{ 224 Parent::packData(stream); 225 226 stream->write(duration); 227 stream->write(n_loops); 228 stream->write(trigger_mask); 229 stream->writeInt(match_type, 1); 230 stream->writeInt(match_state, 2); 231 stream->writeInt(phrase_type, 1); 232 233 stream->writeFlag(no_choreographer_trigs); 234 stream->writeFlag(no_cons_trigs); 235 stream->writeFlag(no_player_trigs); 236 237 stream->writeString(on_trig_cmd); 238 239 pack_fx(stream, fx_list, mPacked); 240} 241 242void afxPhraseEffectData::unpackData(BitStream* stream) 243{ 244 Parent::unpackData(stream); 245 246 stream->read(&duration); 247 stream->read(&n_loops); 248 stream->read(&trigger_mask); 249 match_type = stream->readInt(1); 250 match_state = stream->readInt(2); 251 phrase_type = stream->readInt(1); 252 253 no_choreographer_trigs = stream->readFlag(); 254 no_cons_trigs = stream->readFlag(); 255 no_player_trigs = stream->readFlag(); 256 257 on_trig_cmd = stream->readSTString(); 258 259 do_id_convert = true; 260 unpack_fx(stream, fx_list); 261} 262 263bool afxPhraseEffectData::preload(bool server, String &errorStr) 264{ 265 if (!Parent::preload(server, errorStr)) 266 return false; 267 268 // Resolve objects transmitted from server 269 if (!server) 270 { 271 if (do_id_convert) 272 { 273 for (S32 i = 0; i < fx_list.size(); i++) 274 { 275 SimObjectId db_id = SimObjectId((uintptr_t)fx_list[i]); 276 if (db_id != 0) 277 { 278 // try to convert id to pointer 279 if (!Sim::findObject(db_id, fx_list[i])) 280 { 281 Con::errorf(ConsoleLogEntry::General, 282 "afxPhraseEffectData::preload() -- bad datablockId: 0x%x", 283 db_id); 284 } 285 } 286 } 287 do_id_convert = false; 288 } 289 } 290 291 return true; 292} 293 294void afxPhraseEffectData::gather_cons_defs(Vector<afxConstraintDef>& defs) 295{ 296 afxConstraintDef::gather_cons_defs(defs, fx_list); 297} 298 299//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 300 301DefineEngineMethod( afxPhraseEffectData, pushEffect, void, ( afxEffectBaseData* effectData ),, 302 "Add a child effect to a phrase effect datablock. Argument can be an afxEffectWrappperData or an afxEffectGroupData.\n" ) 303{ 304 if (!effectData) 305 { 306 Con::errorf("afxPhraseEffectData::pushEffect() -- failed to resolve effect datablock."); 307 return; 308 } 309 310 object->fx_list.push_back(effectData); 311} 312 313//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 314