/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "HeadSpin.h"
#include "max.h"
#include "resource.h"
#include "plComponent.h"
#include "plComponentReg.h"
#include "../MaxMain/plPlasmaRefMsgs.h"
#include "plPickNode.h"
#include "../MaxMain/plMaxNode.h"
#include "../MaxExport/plExportProgressBar.h"
#include "../MaxConvert/hsMaterialConverter.h"
#include "hsTypes.h"
#include "plTweak.h"
#include "hsResMgr.h"
#include "../pnMessage/plNodeRefMsg.h"
#include "../pnMessage/plObjRefMsg.h"
#include "../plDrawable/plDynaFootMgr.h"
#include "../plDrawable/plDynaRippleMgr.h"
#include "../plDrawable/plDynaRippleVSMgr.h"
#include "../plDrawable/plDynaBulletMgr.h"
#include "../plDrawable/plDynaPuddleMgr.h"
#include "../plDrawable/plDynaTorpedoMgr.h"
#include "../plDrawable/plDynaTorpedoVSMgr.h"
#include "../plDrawable/plDynaWakeMgr.h"
#include "../plDrawable/plCutter.h"
#include "../plModifier/plDecalEnableMod.h"
#include "../plDrawable/plPrintShape.h"
#include "../plDrawable/plActivePrintShape.h"
#include "../plSurface/hsGMaterial.h"
#include "../plSurface/plLayer.h"
#include "plWaterComponent.h"
#include "../plDrawable/plWaveSetBase.h"
#include "plParticleComponents.h"
void DummyCodeIncludeFuncFootPrint()
{
}
const Class_ID FOOTPRINT_COMP_CID(0x5d553f57, 0x42344c5e);
const Class_ID RIPPLE_COMP_CID(0x750e1b2a, 0x4ad10f15);
const Class_ID PUDDLE_COMP_CID(0x2f800331, 0x640f4914);
const Class_ID WAKE_COMP_CID(0x714b6b6b, 0xa937ff4);
const Class_ID BULLET_COMP_CID(0x208c05d7, 0x41540df2);
const Class_ID TORPEDO_COMP_CID(0x72b85c86, 0xe2b0b40);
const Class_ID DIRTY_COMP_CID(0x500f1fd3, 0x508c4486);
class plFootPrintComponent : public plComponent
{
protected:
plDynaDecalMgr* fDecalMgr;
bool fValid;
bool fNotifiesSetup;
hsBool ISetupNotifies(plMaxNode* node, plErrorMsg* pErrMsg);
hsBool ISetupDecalMgr(plMaxNode* node, plErrorMsg* pErrMsg, plDynaDecalMgr* decalMgr);
hsBool ICreateDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg);
hsBool ISetupColorDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg);
hsBool ISetupParticles(plMaxNode* node, plErrorMsg* pErrMsg);
static plParticleComponent* IGetParticleComp(INode* node);
virtual void IFakeParams();
public:
enum
{
kWidth,
kLength,
kFadeIn,
kFadeOut,
kLifeSpan,
kLayer,
kBlend,
kDirtyTime,
kNotifies,
kIntensity,
kParticles,
kPartyTime
};
enum
{
kAlpha,
kMADD,
kAdd,
kMult
};
plFootPrintComponent();
virtual ~plFootPrintComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool DeInit(plMaxNode *node, plErrorMsg *pErrMsg);
static plDynaDecalMgr* GetDecalMgr(INode* node);
};
CLASS_DESC(plFootPrintComponent, gFootPrintCompDesc, "Foot Print", "FootPrint", COMP_TYPE_FOOTPRINT, FOOTPRINT_COMP_CID)
class plWetProc : public ParamMap2UserDlgProc
{
public:
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
}
return true;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_NOTIFY)
{
std::vector cids;
cids.push_back(FOOTPRINT_COMP_CID);
cids.push_back(RIPPLE_COMP_CID);
cids.push_back(PUDDLE_COMP_CID);
cids.push_back(WAKE_COMP_CID);
IParamBlock2 *pb = map->GetParamBlock();
plPick::Node(pb, plFootPrintComponent::kNotifies, &cids, false, false);
map->Invalidate(plFootPrintComponent::kNotifies);
return TRUE;
}
else
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_PARTICLE)
{
std::vector cids;
cids.push_back(PARTICLE_SYSTEM_COMPONENT_CLASS_ID);
IParamBlock2 *pb = map->GetParamBlock();
plPick::Node(pb, plFootPrintComponent::kParticles, &cids, false, false);
map->Invalidate(plFootPrintComponent::kParticles);
return TRUE;
}
break;
}
return false;
}
void DeleteThis() {}
};
static plWetProc gWetProc;
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gFootPrintBk
(
plComponent::kBlkComp, _T("FootPrint"), 0, &gFootPrintCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_FOOTPRINT, IDS_COMP_FOOTPRINT, 0, 0, &gWetProc,
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 400.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0,
end,
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 400.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 1.0,
end,
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0,
// p_default, 10.0,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1,
end,
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0,
p_default, 30.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1,
end,
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0,
// p_default, 0.1,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1,
end,
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0,
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP,
end,
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0,
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT,
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult,
p_default, plFootPrintComponent::kAlpha,
end,
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
p_default, 10.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 0.0, 100.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0,
end,
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2,
end,
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0,
p_default, 0.25,
p_range, 0.1, 5.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1,
end,
end
);
hsBool plFootPrintComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
// If we don't have a valid layer, we're screwed. Throw up a warning
// and shutdown.
if( !fCompPB->GetTexmap(kLayer) )
{
pErrMsg->Set(true, GetINode()->GetName(), "No layer setup. Ignoring Footprint generator").CheckAndAsk();
pErrMsg->Set(false);
fValid = false;
return true;
}
fDecalMgr = nil;
fValid = true;
fNotifiesSetup = false;
return true;
}
hsBool plFootPrintComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
// If we haven't already, create our DynaDecalMgr and stash it away.
if( !fDecalMgr )
{
ISetupDecalMgr(node, pErrMsg, TRACKED_NEW plDynaFootMgr);
}
return true;
}
hsBool plFootPrintComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
if( !fNotifiesSetup )
ISetupNotifies(node, pErrMsg);
// Add this node's object to our DynaDecalMgr.
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef);
return true;
}
hsBool plFootPrintComponent::DeInit(plMaxNode *node, plErrorMsg *pErrMsg)
{
fDecalMgr = nil;
return true;
}
plFootPrintComponent::plFootPrintComponent()
: fDecalMgr(nil)
{
fClassDesc = &gFootPrintCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plFootPrintComponent::~plFootPrintComponent()
{
}
void plFootPrintComponent::IFakeParams()
{
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.1f);
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.25f);
}
hsBool plFootPrintComponent::ISetupDecalMgr(plMaxNode* node, plErrorMsg* pErrMsg, plDynaDecalMgr* decalMgr)
{
IFakeParams();
fDecalMgr = decalMgr;
plKey mgrKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), fDecalMgr, node->GetLocation());
float width = fCompPB->GetFloat(kWidth) * 1.e-2f;
float length = fCompPB->GetFloat(kLength) * 1.e-2f;
float wetTime = fCompPB->GetFloat(kDirtyTime);
float fadeIn = fCompPB->GetFloat(kFadeIn);
float fadeOut = fCompPB->GetFloat(kFadeOut);
float lifeSpan = fCompPB->GetFloat(kLifeSpan);
float intensity = fCompPB->GetFloat(kIntensity) * 1.e-2f;
float partyTime = fCompPB->GetFloat(kPartyTime);
const hsScalar kHeightHack = 1.f;
fDecalMgr->SetScale(hsVector3(width, length, kHeightHack));
const float kMinFadeOut = 1.e-2f;
if( fadeOut > lifeSpan - kMinFadeOut)
fadeOut = lifeSpan - kMinFadeOut;
if( fadeIn > lifeSpan - fadeOut )
fadeIn = lifeSpan - fadeOut;
fDecalMgr->SetWetLength(wetTime);
fDecalMgr->SetRampEnd(fadeIn);
fDecalMgr->SetDecayStart(lifeSpan - fadeOut);
fDecalMgr->SetLifeSpan(lifeSpan);
fDecalMgr->SetIntensity(intensity);
fDecalMgr->SetPartyTime(partyTime);
if( !ICreateDecalMaterials(node, pErrMsg) )
{
delete fDecalMgr;
fDecalMgr = nil;
return fValid = false;
}
hsgResMgr::ResMgr()->AddViaNotify(mgrKey, TRACKED_NEW plNodeRefMsg(node->GetRoomKey(), plRefMsg::kOnCreate, -1, plNodeRefMsg::kGeneric), plRefFlags::kActiveRef);
ISetupParticles(node, pErrMsg);
return true;
}
hsBool plFootPrintComponent::ISetupNotifies(plMaxNode* node, plErrorMsg* pErrMsg)
{
int num = fCompPB->Count(kNotifies);
int i;
for( i = 0; i < num; i++ )
{
plDynaDecalMgr* slave = GetDecalMgr(fCompPB->GetINode(kNotifies, TimeValue(0), i));
if( slave )
{
slave->SetWaitOnEnable(true);
fDecalMgr->AddNotify(slave->GetKey());
}
}
fNotifiesSetup = true;
return true;
}
hsBool plFootPrintComponent::ISetupParticles(plMaxNode* node, plErrorMsg* pErrMsg)
{
int num = fCompPB->Count(kParticles);
if( !num )
return true;
int i;
for( i = 0; i < num; i++ )
{
plParticleComponent* partyComp = IGetParticleComp(fCompPB->GetINode(kParticles, TimeValue(0), i));
if( partyComp && partyComp->NumTargets() )
{
plMaxNodeBase* partyNode = nil;
const int numTarg = partyComp->NumTargets();
int j;
for( j = 0; j < numTarg; j++ )
{
partyNode = partyComp->GetTarget(j);
if( partyNode )
break;
}
if( partyNode )
{
plSceneObject* obj = partyNode->GetSceneObject();
if( obj )
{
hsgResMgr::ResMgr()->AddViaNotify(obj->GetKey(),
new plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefPartyObject), plRefFlags::kPassiveRef);
}
}
plConst(int) kNumEmitters(3);
partyComp->SetEmitterReserve(kNumEmitters);
}
}
return true;
}
hsBool plFootPrintComponent::ICreateDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( fCompPB->GetInt(kBlend) != kAlpha )
return ISetupColorDecalMaterials(node, pErrMsg);
hsGMaterial* matRTShade = hsMaterialConverter::Instance().NonAlphaHackPrint(node, fCompPB->GetTexmap(kLayer), hsGMatState::kBlendAlpha);
if( !matRTShade )
return fValid = false;
hsgResMgr::ResMgr()->AddViaNotify(matRTShade->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefMatRTShade), plRefFlags::kActiveRef);
hsGMaterial* matPreShade = hsMaterialConverter::Instance().AlphaHackPrint(node, fCompPB->GetTexmap(kLayer), hsGMatState::kBlendAlpha);
hsgResMgr::ResMgr()->AddViaNotify(matPreShade->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefMatPreShade), plRefFlags::kActiveRef);
return true;
}
hsBool plFootPrintComponent::ISetupColorDecalMaterials(plMaxNode* node, plErrorMsg* pErrMsg)
{
UInt32 blendFlags = 0;
switch( fCompPB->GetInt(kBlend) )
{
case kMADD:
blendFlags = hsGMatState::kBlendMADD;
break;
case kAdd:
blendFlags = hsGMatState::kBlendAdd;
break;
case kMult:
blendFlags = hsGMatState::kBlendMult;
break;
default:
hsAssert(false, "Unknown blend mode");
blendFlags = hsGMatState::kBlendMADD; // cuz it's my fave.
break;
}
hsGMaterial* matRTShade = hsMaterialConverter::Instance().NonAlphaHackPrint(node, fCompPB->GetTexmap(kLayer), blendFlags);
if( blendFlags & hsGMatState::kBlendMult )
{
plLayer* layer = plLayer::ConvertNoRef(matRTShade->GetLayer(0)->BottomOfStack());
if( !layer )
return fValid = false;
layer->SetBlendFlags(layer->GetBlendFlags() | hsGMatState::kBlendInvertFinalColor);
}
hsgResMgr::ResMgr()->AddViaNotify(matRTShade->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefMatRTShade), plRefFlags::kActiveRef);
return true;
}
plParticleComponent* plFootPrintComponent::IGetParticleComp(INode* node)
{
if( !node )
return nil;
plComponentBase *comp = ((plMaxNodeBase*)node)->ConvertToComponent();
if( comp == nil )
return nil;
if( comp->ClassID() == PARTICLE_SYSTEM_COMPONENT_CLASS_ID )
{
plParticleComponent* party = (plParticleComponent*)comp;
return party;
}
return nil;
}
plDynaDecalMgr* plFootPrintComponent::GetDecalMgr(INode* node)
{
if( !node )
return nil;
plComponentBase *comp = ((plMaxNodeBase*)node)->ConvertToComponent();
if( comp == nil )
return nil;
if( (comp->ClassID() == FOOTPRINT_COMP_CID)
|| (comp->ClassID() == RIPPLE_COMP_CID)
|| (comp->ClassID() == PUDDLE_COMP_CID)
|| (comp->ClassID() == WAKE_COMP_CID)
)
{
plFootPrintComponent* foot = (plFootPrintComponent*)comp;
return foot->fDecalMgr;
}
return nil;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class plRippleComponent : public plFootPrintComponent
{
protected:
virtual void IFakeParams();
public:
plRippleComponent();
virtual ~plRippleComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plRippleComponent, gRippleCompDesc, "Ripple", "Ripple", COMP_TYPE_FOOTPRINT, RIPPLE_COMP_CID)
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gRippleBk
(
plComponent::kBlkComp, _T("Ripple"), 0, &gRippleCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_RIPPLE, IDS_COMP_RIPPLE, 0, 0, &gWetProc,
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 1000.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0,
end,
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
// p_default, 1.0,
// p_range, 0.25, 10.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1,
end,
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0,
// p_default, 3.5,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1,
end,
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0,
// p_default, 5.0,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1,
end,
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0,
// p_default, 0.25,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1,
end,
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0,
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP,
end,
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0,
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT,
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult,
p_default, plFootPrintComponent::kAlpha,
end,
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
p_default, 10.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 0.0, 100.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0,
end,
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2,
end,
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0,
p_default, 0.25,
p_range, 0.1, 5.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1,
end,
end
);
void plRippleComponent::IFakeParams()
{
fCompPB->SetValue(kLength, TimeValue(0), fCompPB->GetFloat(kWidth));
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.25f);
fCompPB->SetValue(kLifeSpan, TimeValue(0), fCompPB->GetFloat(kWidth) * 1.e-2f * 0.5f);
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.80f);
}
hsBool plRippleComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
return plFootPrintComponent::SetupProperties(node, pErrMsg);
}
hsBool plRippleComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
// If we haven't already, create our DynaDecalMgr and stash it away.
if( !fDecalMgr )
{
plDynaRippleMgr* ripple = nil;
if( node->GetVS() || node->UserPropExists("XXXWaterColor") )
{
ripple = TRACKED_NEW plDynaRippleVSMgr;
}
else
{
ripple = TRACKED_NEW plDynaRippleMgr;
}
ISetupDecalMgr(node, pErrMsg, ripple);
if( fValid )
{
ripple->SetUVWAnim(hsVector3(3.f, 3.f, 3.f), hsVector3(1.f, 1.f, 1.f));
}
}
return true;
}
hsBool plRippleComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
if( !fNotifiesSetup )
{
plWaveSetBase* waveSet = plWaterComponent::GetWaveSetFromNode(node);
if( waveSet )
{
plGenRefMsg* refMsg = TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaRippleVSMgr::kRefWaveSetBase);
hsgResMgr::ResMgr()->AddViaNotify(waveSet->GetKey(), refMsg, plRefFlags::kPassiveRef);
}
ISetupNotifies(node, pErrMsg);
}
// Add this node's object to our DynaDecalMgr.
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef);
return true;
}
plRippleComponent::plRippleComponent()
{
fClassDesc = &gRippleCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plRippleComponent::~plRippleComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class plPuddleComponent : public plRippleComponent
{
protected:
public:
plPuddleComponent();
virtual ~plPuddleComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plPuddleComponent, gPuddleCompDesc, "Puddle", "Puddle", COMP_TYPE_FOOTPRINT, PUDDLE_COMP_CID)
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gPuddleBk
(
plComponent::kBlkComp, _T("Puddle"), 0, &gPuddleCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_PUDDLE, IDS_COMP_PUDDLE, 0, 0, &gWetProc,
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 1000.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0,
end,
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
// p_default, 1.0,
// p_range, 0.25, 10.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1,
end,
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0,
// p_default, 3.5,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1,
end,
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0,
// p_default, 5.0,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1,
end,
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0,
// p_default, 0.25,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1,
end,
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0,
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP,
end,
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0,
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT,
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult,
p_default, plFootPrintComponent::kAlpha,
end,
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
p_default, 10.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 0.0, 100.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0,
end,
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2,
end,
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0,
p_default, 0.25,
p_range, 0.1, 5.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1,
end,
end
);
hsBool plPuddleComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
return plRippleComponent::SetupProperties(node, pErrMsg);
}
hsBool plPuddleComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
// If we haven't already, create our DynaDecalMgr and stash it away.
if( !fDecalMgr )
{
plDynaRippleMgr* puddle = TRACKED_NEW plDynaPuddleMgr;
ISetupDecalMgr(node, pErrMsg, puddle);
if( fValid )
{
puddle->SetUVWAnim(hsVector3(5.f, 5.f, 5.f), hsVector3(1.f, 1.f, 1.f));
}
}
return true;
}
hsBool plPuddleComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
if( !fNotifiesSetup )
ISetupNotifies(node, pErrMsg);
// Add this node's object to our DynaDecalMgr.
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef);
return true;
}
plPuddleComponent::plPuddleComponent()
{
fClassDesc = &gPuddleCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plPuddleComponent::~plPuddleComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class plBulletComponent : public plFootPrintComponent
{
protected:
virtual void IFakeParams();
public:
plBulletComponent();
virtual ~plBulletComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plBulletComponent, gBulletCompDesc, "Bullet", "Bullet", COMP_TYPE_FOOTPRINT, BULLET_COMP_CID)
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gBulletBk
(
plComponent::kBlkComp, _T("Bullet"), 0, &gBulletCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_BULLET, IDS_COMP_FP_BULLET, 0, 0, &gWetProc,
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 400.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_SCALE, IDC_COMP_FP_SCALE_SPIN, 1.0,
end,
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
// p_default, 100.0,
// p_range, 25.0, 400.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 1.0,
end,
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0,
// p_default, 10.0,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1,
end,
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0,
p_default, 15.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1,
end,
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0,
// p_default, 0.1,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1,
end,
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0,
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP,
end,
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0,
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT,
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult,
p_default, plFootPrintComponent::kAlpha,
end,
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
// p_default, 10.0,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
// p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 0.0, 100.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0,
end,
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2,
end,
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0,
p_default, 0.25,
p_range, 0.1, 5.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1,
end,
end
);
void plBulletComponent::IFakeParams()
{
fCompPB->SetValue(kLength, TimeValue(0), fCompPB->GetFloat(kWidth));
plFootPrintComponent::IFakeParams();
}
hsBool plBulletComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
return plFootPrintComponent::SetupProperties(node, pErrMsg);
}
hsBool plBulletComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
// If we haven't already, create our DynaDecalMgr and stash it away.
if( !fDecalMgr )
{
plDynaBulletMgr* bullet = TRACKED_NEW plDynaBulletMgr;
ISetupDecalMgr(node, pErrMsg, bullet);
}
return true;
}
hsBool plBulletComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
if( !fNotifiesSetup )
ISetupNotifies(node, pErrMsg);
// Add this node's object to our DynaDecalMgr.
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef);
return true;
}
plBulletComponent::plBulletComponent()
{
fClassDesc = &gBulletCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plBulletComponent::~plBulletComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class plTorpedoComponent : public plRippleComponent
{
protected:
virtual void IFakeParams();
public:
plTorpedoComponent();
virtual ~plTorpedoComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plTorpedoComponent, gTorpedoCompDesc, "Water Bullet", "WetBullet", COMP_TYPE_FOOTPRINT, TORPEDO_COMP_CID)
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gTorpedoBk
(
plComponent::kBlkComp, _T("Torpedo"), 0, &gTorpedoCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_TORPEDO, IDS_COMP_FP_TORPEDO, 0, 0, &gWetProc,
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 1000.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0,
end,
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
// p_default, 1.0,
// p_range, 0.25, 10.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1,
end,
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0,
// p_default, 3.5,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1,
end,
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0,
p_default, 5.0,
p_range, 0.0, 10.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1,
end,
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0,
// p_default, 0.25,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1,
end,
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0,
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP,
end,
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0,
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT,
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult,
p_default, plFootPrintComponent::kAlpha,
end,
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
p_default, 10.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 0.0, 100.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0,
end,
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2,
end,
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0,
p_default, 0.25,
p_range, 0.1, 5.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1,
end,
end
);
void plTorpedoComponent::IFakeParams()
{
fCompPB->SetValue(kLength, TimeValue(0), fCompPB->GetFloat(kWidth));
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.25f);
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.80f);
}
hsBool plTorpedoComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
return plRippleComponent::SetupProperties(node, pErrMsg);
}
hsBool plTorpedoComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
// If we haven't already, create our DynaDecalMgr and stash it away.
if( !fDecalMgr )
{
plDynaRippleMgr* torpedo;
if( node->GetVS() )
torpedo = TRACKED_NEW plDynaTorpedoVSMgr;
else
torpedo = TRACKED_NEW plDynaTorpedoMgr;
ISetupDecalMgr(node, pErrMsg, torpedo);
if( fValid )
{
torpedo->SetUVWAnim(hsVector3(5.f, 5.f, 5.f), hsVector3(1.f, 1.f, 1.f));
}
}
return true;
}
hsBool plTorpedoComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
return plRippleComponent::Convert(node, pErrMsg);
}
plTorpedoComponent::plTorpedoComponent()
{
fClassDesc = &gTorpedoCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plTorpedoComponent::~plTorpedoComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class plWakeComponent : public plFootPrintComponent
{
protected:
virtual void IFakeParams();
public:
plWakeComponent();
virtual ~plWakeComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plWakeComponent, gWakeCompDesc, "Wake", "Wake", COMP_TYPE_FOOTPRINT, WAKE_COMP_CID)
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gWakeBk
(
plComponent::kBlkComp, _T("Wake"), 0, &gWakeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_WAKE, IDS_COMP_FP_WAKE, 0, 0, &gWetProc,
plFootPrintComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 1000.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_WIDTH, IDC_COMP_FP_WIDTH_SPIN, 1.0,
end,
plFootPrintComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 25.0, 1000.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_LENGTH, IDC_COMP_FP_LENGTH_SPIN, 0.1,
end,
plFootPrintComponent::kFadeOut, _T("FadeOut"), TYPE_FLOAT, 0, 0,
// p_default, 3.5,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_FADEOUT, IDC_COMP_FP_FADEOUT_SPIN, 0.1,
end,
plFootPrintComponent::kLifeSpan, _T("LifeSpan"), TYPE_FLOAT, 0, 0,
// p_default, 5.0,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_LIFESPAN2, IDC_COMP_FP_LIFESPAN_SPIN2, 0.1,
end,
plFootPrintComponent::kFadeIn, _T("FadeIn"), TYPE_FLOAT, 0, 0,
// p_default, 0.25,
// p_range, 0.0, 300.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_RAMPEND, IDC_COMP_FP_RAMPEND_SPIN, 0.1,
end,
plFootPrintComponent::kLayer, _T("Layer"), TYPE_TEXMAP, 0, 0,
p_ui, TYPE_TEXMAPBUTTON, IDC_COMP_FP_TEXMAP,
end,
plFootPrintComponent::kBlend, _T("Blend"), TYPE_INT, 0, 0,
p_ui, TYPE_RADIO, 4, IDC_RADIO_ALPHA, IDC_RADIO_MADD, IDC_RADIO_ADD, IDC_RADIO_MULT,
p_vals, plFootPrintComponent::kAlpha, plFootPrintComponent::kMADD, plFootPrintComponent::kAdd, plFootPrintComponent::kMult,
p_default, plFootPrintComponent::kAlpha,
end,
plFootPrintComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
p_default, 10.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
plFootPrintComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plFootPrintComponent::kIntensity, _T("Intensity"), TYPE_FLOAT, 0, 0,
p_default, 100.0,
p_range, 0.0, 100.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_INTENSITY, IDC_COMP_FP_INTENSITY_SPIN, 1.0,
end,
plFootPrintComponent::kParticles, _T("Particles"), TYPE_INODE_TAB, 0, 0, 0,
// p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS2, 0, 0, IDC_DEL_TARGS2,
end,
plFootPrintComponent::kPartyTime, _T("PartyTime"), TYPE_FLOAT, 0, 0,
// p_default, 0.25,
// p_range, 0.1, 5.0,
// p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
// IDC_COMP_FP_PARTYTIME, IDC_COMP_FP_PARTYTIME_SPIN, 0.1,
end,
end
);
void plWakeComponent::IFakeParams()
{
fCompPB->SetValue(kFadeIn, TimeValue(0), 0.25f);
fCompPB->SetValue(kLifeSpan, TimeValue(0), fCompPB->GetFloat(kWidth) * 1.e-2f * 0.5f);
fCompPB->SetValue(kFadeOut, TimeValue(0), fCompPB->GetFloat(kLifeSpan) * 0.80f);
}
hsBool plWakeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
return plFootPrintComponent::SetupProperties(node, pErrMsg);
}
hsBool plWakeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
// If we haven't already, create our DynaDecalMgr and stash it away.
if( !fDecalMgr )
{
plDynaWakeMgr* wake = TRACKED_NEW plDynaWakeMgr;
ISetupDecalMgr(node, pErrMsg, wake);
if( fValid )
{
wake->SetUVWAnim(hsVector3(5.f, 5.f, 5.f), hsVector3(1.f, 1.f, 1.f));
}
}
return true;
}
hsBool plWakeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
if( !fValid )
return true;
if( !fNotifiesSetup )
ISetupNotifies(node, pErrMsg);
// Add this node's object to our DynaDecalMgr.
hsgResMgr::ResMgr()->AddViaNotify(node->GetKey(), TRACKED_NEW plGenRefMsg(fDecalMgr->GetKey(), plRefMsg::kOnCreate, 0, plDynaDecalMgr::kRefTarget), plRefFlags::kActiveRef);
return true;
}
plWakeComponent::plWakeComponent()
{
fClassDesc = &gWakeCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plWakeComponent::~plWakeComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
class plDirtyComponent : public plComponent
{
public:
enum
{
kDecals,
kDirtyTime
};
protected:
public:
plDirtyComponent();
virtual ~plDirtyComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plDirtyComponent, gDirtyCompDesc, "Dirty/Wet Region", "Dirty/Wet", COMP_TYPE_FOOTPRINT, DIRTY_COMP_CID)
class plDirtyProc : public ParamMap2UserDlgProc
{
public:
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
}
return true;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_DECAL)
{
std::vector cids;
cids.push_back(FOOTPRINT_COMP_CID);
cids.push_back(RIPPLE_COMP_CID);
cids.push_back(PUDDLE_COMP_CID);
cids.push_back(WAKE_COMP_CID);
IParamBlock2 *pb = map->GetParamBlock();
plPick::Node(pb, plDirtyComponent::kDecals, &cids, false, false);
map->Invalidate(plDirtyComponent::kDecals);
return TRUE;
}
break;
}
return false;
}
void DeleteThis() {}
};
static plDirtyProc gDirtyProc;
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gDirtyBk
(
plComponent::kBlkComp, _T("Dirty"), 0, &gDirtyCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_DIRTY, IDS_COMP_FP_DIRTY, 0, 0, &gDirtyProc,
plDirtyComponent::kDecals, _T("Decals"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
plDirtyComponent::kDirtyTime, _T("DirtyTime"), TYPE_FLOAT, 0, 0,
p_default, 10.0,
p_range, 0.0, 300.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_FP_DIRTYTIME, IDC_COMP_FP_DIRTYTIME_SPIN, 0.1,
end,
end
);
hsBool plDirtyComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
return true;
}
hsBool plDirtyComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
return true;
}
hsBool plDirtyComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
// Check that this node has a physical interface, or all is for nought.
// Should throw up a warning if it doesn't have one, seems an easy thing
// to miss.
if( !node->IsPhysical() )
{
pErrMsg->Set(true, node->GetName(), "Has no physical component to notify %s Dirty/Wet component", GetINode()->GetName()).CheckAndAsk();
pErrMsg->Set(false);
return true;
}
plDecalEnableMod* enable = TRACKED_NEW plDecalEnableMod;
plKey modKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), enable, node->GetLocation());
int numDecals = fCompPB->Count(kDecals);
int i;
for( i = 0; i < numDecals; i++ )
{
INode* decalNode = fCompPB->GetINode(kDecals, TimeValue(0), i);
plDynaDecalMgr* decal = plFootPrintComponent::GetDecalMgr(decalNode);
if( decal )
{
decal->SetWaitOnEnable(true);
enable->AddDecalKey(decal->GetKey());
}
}
enable->SetWetLength(fCompPB->GetFloat(kDirtyTime));
hsgResMgr::ResMgr()->AddViaNotify(modKey, TRACKED_NEW plObjRefMsg(node->GetKey(), plRefMsg::kOnCreate, -1, plObjRefMsg::kModifier), plRefFlags::kActiveRef);
return true;
}
plDirtyComponent::plDirtyComponent()
{
fClassDesc = &gDirtyCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plDirtyComponent::~plDirtyComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
const Class_ID PRINTSHAPE_COMP_CID(0x208226a1, 0x2a6e67ba);
class plPrintShapeComponent : public plComponent
{
public:
enum
{
kWidth,
kLength,
kHeight
};
protected:
public:
plPrintShapeComponent();
virtual ~plPrintShapeComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plPrintShapeComponent, gPrintShapeCompDesc, "Print Shape", "PrintShape", COMP_TYPE_FOOTPRINT, PRINTSHAPE_COMP_CID)
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gPrintShapeBk
(
plComponent::kBlkComp, _T("PrintShape"), 0, &gPrintShapeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_PRINTSHAPE, IDS_COMP_FP_PRINTSHAPE, 0, 0, NULL,
plPrintShapeComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 0.45,
p_range, 0.1, 30.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_WIDTH, IDC_COMP_WIDTH_SPIN, 0.1,
end,
plPrintShapeComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
p_default, 0.9,
p_range, 0.1, 30.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_LENGTH, IDC_COMP_LENGTH_SPIN, 0.1,
end,
plPrintShapeComponent::kHeight, _T("Height"), TYPE_FLOAT, 0, 0,
p_default, 1.0,
p_range, 0.1, 30.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_HEIGHT, IDC_COMP_HEIGHT_SPIN, 0.1,
end,
end
);
hsBool plPrintShapeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
node->SetForceLocal(true);
return true;
}
hsBool plPrintShapeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
return true;
}
hsBool plPrintShapeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
plSceneObject* obj = node->GetSceneObject();
if( !obj )
return true;
plPrintShape* shape = TRACKED_NEW plPrintShape();
plKey shapeKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), shape, node->GetLocation());
shape->SetWidth(fCompPB->GetFloat(kWidth));
shape->SetLength(fCompPB->GetFloat(kLength));
shape->SetHeight(fCompPB->GetFloat(kHeight));
hsgResMgr::ResMgr()->AddViaNotify(shapeKey, TRACKED_NEW plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface), plRefFlags::kActiveRef);
return true;
}
plPrintShapeComponent::plPrintShapeComponent()
{
fClassDesc = &gPrintShapeCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plPrintShapeComponent::~plPrintShapeComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
const Class_ID ACTIVEPRINTSHAPE_COMP_CID(0x61b52046, 0x787734a5);
class plActivePrintShapeComponent : public plComponent
{
public:
enum
{
kWidth,
kLength,
kHeight,
kNotifies
};
protected:
public:
plActivePrintShapeComponent();
virtual ~plActivePrintShapeComponent();
void DeleteThis() { delete this; }
// SetupProperties - Internal setup and write-only set properties on the MaxNode. No reading
// of properties on the MaxNode, as it's still indeterminant.
virtual hsBool SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool PreConvert(plMaxNode *node, plErrorMsg *pErrMsg);
virtual hsBool Convert(plMaxNode *node, plErrorMsg *pErrMsg);
};
CLASS_DESC(plActivePrintShapeComponent, gActivePrintShapeCompDesc, "Active Shape", "ActiveShape", COMP_TYPE_FOOTPRINT, ACTIVEPRINTSHAPE_COMP_CID)
class plActiveProc : public ParamMap2UserDlgProc
{
public:
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
}
return true;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ADD_NOTIFY2)
{
std::vector cids;
cids.push_back(FOOTPRINT_COMP_CID);
cids.push_back(RIPPLE_COMP_CID);
cids.push_back(PUDDLE_COMP_CID);
cids.push_back(WAKE_COMP_CID);
IParamBlock2 *pb = map->GetParamBlock();
plPick::Node(pb, plActivePrintShapeComponent::kNotifies, &cids, false, false);
map->Invalidate(plActivePrintShapeComponent::kNotifies);
return TRUE;
}
break;
}
return false;
}
void DeleteThis() {}
};
static plActiveProc gActiveProc;
/////////////////////////////////////////////////////////////////////////////////////
ParamBlockDesc2 gActivePrintShapeBk
(
plComponent::kBlkComp, _T("ActivePrintShape"), 0, &gActivePrintShapeCompDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp,
IDD_COMP_FP_ACTIVEPRINTSHAPE, IDS_COMP_FP_ACTIVEPRINTSHAPE, 0, 0, &gActiveProc,
plActivePrintShapeComponent::kWidth, _T("Width"), TYPE_FLOAT, 0, 0,
p_default, 0.45,
p_range, 0.1, 30.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_WIDTH, IDC_COMP_WIDTH_SPIN, 0.1,
end,
plActivePrintShapeComponent::kLength, _T("Length"), TYPE_FLOAT, 0, 0,
p_default, 0.9,
p_range, 0.1, 30.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_LENGTH, IDC_COMP_LENGTH_SPIN, 0.1,
end,
plActivePrintShapeComponent::kHeight, _T("Height"), TYPE_FLOAT, 0, 0,
p_default, 1.0,
p_range, 0.1, 30.0,
p_ui, TYPE_SPINNER, EDITTYPE_POS_FLOAT,
IDC_COMP_HEIGHT, IDC_COMP_HEIGHT_SPIN, 0.1,
end,
plActivePrintShapeComponent::kNotifies, _T("Notifies"), TYPE_INODE_TAB, 0, 0, 0,
p_ui, TYPE_NODELISTBOX, IDC_LIST_TARGS, 0, 0, IDC_DEL_TARGS,
end,
end
);
hsBool plActivePrintShapeComponent::SetupProperties(plMaxNode* node, plErrorMsg* pErrMsg)
{
node->SetForceLocal(true);
return true;
}
hsBool plActivePrintShapeComponent::PreConvert(plMaxNode* node, plErrorMsg* pErrMsg)
{
return true;
}
hsBool plActivePrintShapeComponent::Convert(plMaxNode* node, plErrorMsg* pErrMsg)
{
plSceneObject* obj = node->GetSceneObject();
if( !obj )
return true;
plActivePrintShape* shape = TRACKED_NEW plActivePrintShape();
plKey shapeKey = hsgResMgr::ResMgr()->NewKey(IGetUniqueName(node), shape, node->GetLocation());
shape->SetWidth(fCompPB->GetFloat(kWidth));
shape->SetLength(fCompPB->GetFloat(kLength));
shape->SetHeight(fCompPB->GetFloat(kHeight));
int num = fCompPB->Count(kNotifies);
int i;
for( i = 0; i < num; i++ )
{
plDynaDecalMgr* notify = plFootPrintComponent::GetDecalMgr(fCompPB->GetINode(kNotifies, TimeValue(0), i));
if( notify )
{
shape->AddDecalKey(notify->GetKey());
}
}
hsgResMgr::ResMgr()->AddViaNotify(shapeKey, TRACKED_NEW plObjRefMsg(obj->GetKey(), plRefMsg::kOnCreate, 0, plObjRefMsg::kInterface), plRefFlags::kActiveRef);
return true;
}
plActivePrintShapeComponent::plActivePrintShapeComponent()
{
fClassDesc = &gActivePrintShapeCompDesc;
fClassDesc->MakeAutoParamBlocks(this);
}
plActivePrintShapeComponent::~plActivePrintShapeComponent()
{
}
//////////////////////////////////////////////////////////////////////////////////////////////////////