You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
291 lines
9.7 KiB
291 lines
9.7 KiB
/*==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 <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
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" // Resource Dependencies |
|
|
|
#include "MaxMain/plPhysicalProps.h" |
|
|
|
#include "plComponent.h" //Component Dependencies |
|
#include "plComponentReg.h" // Ibid |
|
#include "MaxMain/plMaxNode.h" // Ibid |
|
#include "pnKeyedObject/plKey.h" // Ibid |
|
#include "plComponentProcBase.h" |
|
|
|
#include "plNavigableComponents.h" |
|
#include "plActivatorBaseComponent.h" |
|
#include "plPhysicalComponents.h" |
|
|
|
#include "MaxConvert/hsConverterUtils.h" //Conversion Dependencies |
|
#include "MaxConvert/hsControlConverter.h" // Ibid |
|
|
|
#include "plAvatar/plAvLadderModifier.h" //Modifier Dependencies |
|
#include "plPhysical/plSimDefs.h" |
|
|
|
#include "plgDispatch.h" //Message Dependencies |
|
#include "pnMessage/plObjRefMsg.h" // Ibid |
|
#include "pnMessage/plIntRefMsg.h" // Ibid |
|
#include "pnMessage/plNodeRefMsg.h" // Ibid |
|
#include "MaxMain/plPlasmaRefMsgs.h" // Ibid |
|
|
|
void DummyCodeIncludeFuncNavigablesRegion() {} |
|
|
|
|
|
CLASS_DESC(plAvLadderComponent, gAvLadderComponentDesc, "(ex)Ladder Component", "(ex)LadderComp", COMP_TYPE_PHYS_TERRAINS, NAV_LADDER_CID) |
|
|
|
enum kAvLadderFields |
|
{ |
|
kTypeCombo, |
|
kLoopsInt, |
|
kTriggerNode, |
|
kDirectionBool, |
|
kBoundsType_DEAD, |
|
kEnabled, |
|
kLadderNode, |
|
}; |
|
|
|
class plAvLadderComponentProc : public ParamMap2UserDlgProc |
|
{ |
|
public: |
|
enum kLadderTypesEnums |
|
{ |
|
kReallyBig, |
|
kFourFeet, |
|
kTwoFeet, |
|
}; |
|
|
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
{ |
|
HWND hLadder = GetDlgItem(hWnd,IDC_COMP_NAV_LADDER_COMBO); |
|
|
|
ComboBox_AddString(hLadder, "Big"); |
|
ComboBox_AddString(hLadder, "4 feet"); |
|
ComboBox_AddString(hLadder, "2 feet"); |
|
|
|
int type = map->GetParamBlock()->GetInt(kTypeCombo); |
|
ComboBox_SetCurSel(hLadder, type); |
|
} |
|
return TRUE; |
|
|
|
case WM_COMMAND: |
|
if (LOWORD(wParam) == IDC_COMP_NAV_LADDER_COMBO && HIWORD(wParam) == CBN_SELCHANGE) |
|
{ |
|
//Util fcn found in plEventGroupRefs files in MaxMain |
|
HWND hLadder = GetDlgItem(hWnd,IDC_COMP_NAV_LADDER_COMBO); |
|
int idx = ComboBox_GetCurSel(hLadder); |
|
map->GetParamBlock()->SetValue(kTypeCombo, 0, idx); |
|
/* |
|
if (idx == kReallyBig) |
|
{ |
|
map->Enable(kLoopsInt, TRUE); |
|
// map->Invalidate(kLoopsInt); |
|
} |
|
else |
|
{ |
|
map->Enable(kLoopsInt, TRUE); |
|
// map->Invalidate(kLoopsInt); |
|
} |
|
*/ |
|
return TRUE; |
|
} |
|
break; |
|
} |
|
return FALSE; |
|
} |
|
|
|
void DeleteThis() {} |
|
}; |
|
static plAvLadderComponentProc gAvLadderComponentProc; |
|
|
|
ParamBlockDesc2 gAvLadderComponentBlock |
|
( |
|
plComponent::kBlkComp, _T("(ex)Ladder Component"), 0, &gAvLadderComponentDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, |
|
|
|
IDD_COMP_NAV_LADDER, IDS_COMP_NAV_LADDERS, 0, 0, &gAvLadderComponentProc, |
|
|
|
kTypeCombo, _T("Ladder Type"), TYPE_INT, 0,0, |
|
end, |
|
|
|
kDirectionBool, _T("Climbing Direction"), TYPE_INT, 0, 0, |
|
p_ui, TYPE_RADIO, 2, IDC_RADIO_UP, IDC_RADIO_DOWN, |
|
p_vals, true, false, |
|
end, |
|
|
|
kLoopsInt, _T("BigLadderNumLoop"), TYPE_INT, 0, 0, |
|
p_default, 0, |
|
p_range, 0, 500, |
|
p_ui, TYPE_SPINNER, EDITTYPE_INT, |
|
IDC_COMP_NAV_LADDER_LOOPS_EDIT, IDC_COMP_NAV_LADDER_LOOPS_SPIN, 0.4, |
|
end, |
|
|
|
kTriggerNode, _T("Trigger Node"), TYPE_INODE, 0, 0, |
|
p_ui, TYPE_PICKNODEBUTTON, IDC_COMP_NAV_TRIGGER, |
|
//p_sclassID, GEOMOBJECT_CLASS_ID, |
|
p_prompt, IDS_COMP_PHYS_CHOSEN_BASE, |
|
//p_accessor, &gPhysCoreAccessor, |
|
end, |
|
|
|
kLadderNode, _T("ladder"), TYPE_INODE, 0, 0, |
|
p_ui, TYPE_PICKNODEBUTTON, IDC_COMP_NAV_LADDER, |
|
end, |
|
|
|
kEnabled, _T("enabled"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_ENABLED, |
|
p_default, TRUE, |
|
end, |
|
|
|
end |
|
); |
|
|
|
plAvLadderComponent::plAvLadderComponent() |
|
{ |
|
fClassDesc = &gAvLadderComponentDesc; |
|
fClassDesc->MakeAutoParamBlocks(this); |
|
} |
|
|
|
void plAvLadderComponent::CollectNonDrawables(INodeTab& nonDrawables) |
|
{ |
|
INode* ladderNode = fCompPB->GetINode(kLadderNode); |
|
if( ladderNode ) |
|
nonDrawables.Append(1, &ladderNode); |
|
|
|
INode* triggerNode = fCompPB->GetINode(kTriggerNode); |
|
if( triggerNode ) |
|
nonDrawables.Append(1, &triggerNode); |
|
|
|
AddTargetsToList(nonDrawables); |
|
} |
|
|
|
hsBool plAvLadderComponent::SetupProperties(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
fKeys.Reset(); |
|
|
|
// |
|
// Create an invisible blocker for the ladder shape, so the avatar won't fall over the side |
|
// |
|
plMaxNode *ladderNode = (plMaxNode*)fCompPB->GetINode(kLadderNode); |
|
if (ladderNode) |
|
{ |
|
plPhysicalProps* ladderPhys = ladderNode->GetPhysicalProps(); |
|
// ladderPhys->SetMass(0, ladderNode, pErrMsg); |
|
ladderPhys->SetBoundsType(plSimDefs::kHullBounds, ladderNode, pErrMsg); |
|
ladderPhys->SetGroup(plSimDefs::kGroupStatic, ladderNode, pErrMsg); |
|
/// ladderPhys->SetAllowLOS(true, ladderNode, pErrMsg); |
|
|
|
ladderNode->SetDrawable(false); |
|
ladderNode->SetForceLocal(true); // Get a coord interface for facing calculations |
|
} |
|
else |
|
{ |
|
pErrMsg->Set(true, |
|
"Ladder Warning", |
|
"Ladder component %s doesn't have the ladder node set", |
|
GetINode()->GetName()).Show(); |
|
pErrMsg->Set(false); |
|
return false; |
|
} |
|
|
|
// |
|
// Create a detector region for the node we're attached to |
|
// |
|
plPhysicalProps *physProps = node->GetPhysicalProps(); |
|
|
|
plMaxNode *triggerNode = (plMaxNode*)fCompPB->GetINode(kTriggerNode); |
|
if (triggerNode) |
|
physProps->SetProxyNode(triggerNode, node, pErrMsg); |
|
|
|
physProps->SetGroup(plSimDefs::kGroupDetector, node, pErrMsg); // this is a detector |
|
physProps->SetReportGroup(1<<plSimDefs::kGroupAvatar, node, pErrMsg); // only fires on local avatars |
|
physProps->SetPinned(true, node, pErrMsg); |
|
// only if movable will it have mass (then it will keep track of movements in PhysX) |
|
if ( node->IsMovable() || node->IsTMAnimated() ) |
|
physProps->SetMass(1.0f, node, pErrMsg); // detectors don't move |
|
physProps->SetBoundsType(plSimDefs::kHullBounds, node, pErrMsg); |
|
|
|
node->SetForceLocal(true); // force our seek point to be local |
|
node->SetDrawable(false); |
|
|
|
return true; |
|
} |
|
|
|
hsBool plAvLadderComponent::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
plMaxNode *ladderNode = (plMaxNode*)fCompPB->GetINode(kLadderNode); |
|
if (!ladderNode) |
|
return false; |
|
|
|
plMaxNode *triggerNode = (plMaxNode*)fCompPB->GetINode(kTriggerNode); |
|
if (!triggerNode) |
|
triggerNode = node; |
|
|
|
// Get a vector pointing from the ladder to the detector, for facing calculations |
|
Point3 ladderViewMax = ladderNode->GetNodeTM(0).GetTrans() - triggerNode->GetNodeTM(0).GetTrans(); |
|
hsVector3 ladderView(ladderViewMax.x, ladderViewMax.y, ladderViewMax.z); |
|
ladderView.fZ = 0; |
|
ladderView.Normalize(); |
|
|
|
bool goingUp = (fCompPB->GetInt(kDirectionBool) != 0); |
|
int loops = fCompPB->GetInt(kLoopsInt); |
|
int ladderType = fCompPB->GetInt(kTypeCombo); |
|
bool enabled = (fCompPB->GetInt(kEnabled) != 0); |
|
|
|
plAvLadderMod* ladMod = new plAvLadderMod(goingUp, ladderType, loops, enabled, ladderView); |
|
plKey modKey = node->AddModifier(ladMod, IGetUniqueName(node)); |
|
fKeys.Append(modKey); |
|
|
|
return true; |
|
} |
|
|
|
hsBool plAvLadderComponent::Convert(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
return true; |
|
} |
|
|
|
hsBool plAvLadderComponent::DeInit(plMaxNode *node, plErrorMsg *pErrMsg) |
|
{ |
|
fKeys.Reset(); |
|
return true; |
|
}
|
|
|