Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
3405 lines
90 KiB
C++
3405 lines
90 KiB
C++
//===========================================================================//
|
|
// File: MechLab.cpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 12/19/01 MSL Added StandardArmor //
|
|
// 01/06/02 MSL Changed weapon groups from 6 to 3 //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1998, Fasa Interactive //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "MW4Headers.hpp"
|
|
#pragma warning(disable:4100) // unreferenced formal parameter
|
|
|
|
#include "MechLab.hpp"
|
|
#include <gosScript\gosScriptHeaders.hpp>
|
|
|
|
#include "Mech.hpp"
|
|
#include "MWDamageObject.hpp"
|
|
#include "Subsystem.hpp"
|
|
#include "Weapon.hpp"
|
|
#include "MWMover.hpp"
|
|
#include "Armor.hpp"
|
|
#include "SubsystemClassData.hpp"
|
|
#include "MWTable.hpp"
|
|
#include "MWApplication.hpp"
|
|
#include "Torso.hpp"
|
|
#include "Engine.hpp"
|
|
#include "HeatSink.hpp"
|
|
#include "AMS.hpp"
|
|
// MSL 5.02 SubSystems
|
|
//#include "EnhancedOptics.hpp"
|
|
#include "IFF_Jammer.hpp"
|
|
#include "AdvancedGyro.hpp"
|
|
// for campaign skin - jcem
|
|
#include "mw4shell.hpp"
|
|
// for campaign skin - jcem
|
|
|
|
|
|
#include <Adept\Entity.hpp>
|
|
#include <Adept\VideoRenderer.hpp>
|
|
#include <Adept\Site.hpp>
|
|
#include <Adept\ResourceImagePool.hpp>
|
|
|
|
#include <MissionLang\Resource.h>
|
|
|
|
#include <ElementRenderer\CameraElement.hpp>
|
|
#include <ElementRenderer\StateChange.hpp>
|
|
#include <ElementRenderer\GroupElement.hpp>
|
|
|
|
#include <MLR\MLRTexturePool.hpp>
|
|
#include <MLR\MLRClipper.hpp>
|
|
|
|
#include "..\buildnum\buildnum.h"
|
|
|
|
#include <GameOS\ToolOS.hpp>
|
|
#include <GameOS\Network.hpp>
|
|
|
|
#define VARIANTS_PATH "Resource\\Variants\\"
|
|
|
|
// jcem begin
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <WinBase.h>
|
|
#include <stdio.h>
|
|
#include <io.h>
|
|
|
|
#include <ddraw.h>
|
|
#include <d3d.h>
|
|
|
|
#include <GameOS\render.hpp>
|
|
|
|
#include "ctcls.h"
|
|
#include "ctcl.h"
|
|
|
|
extern bool g_bCOOP;
|
|
// MSL 5.03 MechView
|
|
extern void (__stdcall *g_pfnCTCL_AfterBeginScene)();
|
|
extern void __stdcall CTCL_AfterBeginScene();
|
|
|
|
#if 1 // jcem for MechView, CampaignMechLab.cpp too
|
|
#define CONN4ML (Connection::Hermit)
|
|
#else
|
|
#define CONN4ML (Connection::Local)
|
|
#endif
|
|
|
|
extern Stuff::SafeChainOf<Replicator*>* g_pTempReplicators;
|
|
// jcem end
|
|
|
|
MechLab
|
|
*MechLab::Instance = NULL;
|
|
ElementRenderer::CameraElement
|
|
*MechLab::s_MechCamera = NULL;
|
|
|
|
void MechView_Before()
|
|
{
|
|
MechLab::s_MechCamera->ClearBackBufferBeforeDraw(true);
|
|
}
|
|
|
|
void MechView_After()
|
|
{
|
|
MechLab::s_MechCamera->ClearBackBufferBeforeDraw(false);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MechLab::MechLab() :
|
|
m_subsystemsAvailable(NULL, true),
|
|
m_mechResourceFile(NULL)
|
|
{
|
|
// StartUp();
|
|
m_isCampaign = 0;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MechLab::~MechLab()
|
|
{
|
|
ShutDown();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::StartUp()
|
|
{
|
|
Stuff::SafeChainOf<Replicator*>* pOld = g_pTempReplicators;
|
|
g_pTempReplicators = &m_TempReplicators;
|
|
|
|
m_mechIDs = NULL;
|
|
m_chassisIDs = NULL;
|
|
m_workingMech = NULL;
|
|
m_workingEntity = NULL;
|
|
|
|
m_workingMechName = NULL;
|
|
|
|
m_mechResourceFile.Remove();
|
|
|
|
m_mode = ChassisTabMode;
|
|
|
|
m_mechLabCount = GetMechCount();
|
|
m_chassisCount = GetChassisCount();
|
|
|
|
InitializeSubsystemsAvailable();
|
|
|
|
gosScript_RegisterCallback("ML_CallbackHandler",&ML_CallbackHandler,GOSVAR_INT,0,NULL);
|
|
|
|
gosScript_RegisterVariable("m_mechLabCount", &m_mechLabCount, GOSVAR_INT, 0, NULL);
|
|
gosScript_RegisterVariable("m_chassisCount", &m_chassisCount, GOSVAR_INT, 0, NULL);
|
|
gosScript_RegisterVariable("m_isCampaign", &m_isCampaign, GOSVAR_INT, 0, NULL);
|
|
|
|
if(s_MechCamera)
|
|
{
|
|
delete s_MechCamera;
|
|
s_MechCamera = NULL;
|
|
}
|
|
|
|
//
|
|
//---------------
|
|
// Build a camera
|
|
//---------------
|
|
//
|
|
ElementRenderer::StateChange *Camera_State =
|
|
new ElementRenderer::StateChange();
|
|
Check_Object(Camera_State);
|
|
Camera_State->EnableBackfaceCulling();
|
|
Camera_State->EnableDithering();
|
|
Camera_State->EnablePerspectiveCorrection();
|
|
Camera_State->EnableZBufferWrite();
|
|
Camera_State->EnableZBufferCompare();
|
|
|
|
s_MechCamera = new ElementRenderer::CameraElement(Camera_State);
|
|
Check_Object(s_MechCamera);
|
|
s_MechCamera->SetPerspective(1.0f, 1100.0f, Stuff::Pi_Over_3);
|
|
s_MechCamera->SetViewport(0.0f, 0.0f, 1.0f, 1.0f);
|
|
// s_MechCamera->SetSecondaryCamera();
|
|
s_MechCamera->ClearZBeforeDraw(false);
|
|
s_MechCamera->ClearBackBufferBeforeDraw(false);
|
|
|
|
m_sceneRoot = new ElementRenderer::GroupElement;
|
|
m_sceneRoot->SetRootMode();
|
|
m_sceneRoot->AttachChild(s_MechCamera);
|
|
m_sceneRoot->SetRootMode();
|
|
// s_MechCamera->SetRootMode();
|
|
// Camera->SetScene(Scene);
|
|
|
|
g_pTempReplicators = pOld;
|
|
}
|
|
|
|
void MechLab::FreeReplicators()
|
|
{
|
|
SafeChainIteratorOf<Replicator*> replicators(&m_TempReplicators);
|
|
Replicator *replicator;
|
|
while ((replicator = replicators.GetCurrent()) != NULL)
|
|
{
|
|
Check_Object(replicator);
|
|
Unregister_Object(replicator);
|
|
Connection::DeleteReplicator(replicator);
|
|
replicators.First();
|
|
}
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::ShutDown()
|
|
{
|
|
gosScript_UnregisterCallback("ML_CallbackHandler");
|
|
|
|
gosScript_UnregisterVariable("m_mechLabCount");
|
|
gosScript_UnregisterVariable("m_chassisCount");
|
|
gosScript_UnregisterVariable("m_isCampaign");
|
|
|
|
m_subsystemsAvailable.DeletePlugs();
|
|
if(m_mechResourceFile.GetCurrent())
|
|
{
|
|
m_mechResourceFile.GetCurrent()->Save();
|
|
delete m_mechResourceFile.GetCurrent();
|
|
m_mechResourceFile.Remove();
|
|
}
|
|
|
|
if (MidLevelRenderer::MLRTexturePool::Instance) {
|
|
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
delete MidLevelRenderer::MLRTexturePool::Instance;
|
|
ResourceImagePool *pool = new ResourceImagePool;
|
|
Check_Object(pool);
|
|
MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
if(m_mechIDs)
|
|
{
|
|
gos_Free(m_mechIDs);
|
|
}
|
|
if(m_chassisIDs)
|
|
{
|
|
gos_Free(m_chassisIDs);
|
|
}
|
|
if(s_MechCamera)
|
|
{
|
|
delete s_MechCamera;
|
|
s_MechCamera = NULL;
|
|
}
|
|
if(m_sceneRoot)
|
|
{
|
|
delete m_sceneRoot;
|
|
m_sceneRoot = NULL;
|
|
}
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Uninit();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::Execute()
|
|
{
|
|
Check_Pointer(this);
|
|
if(m_mode == ChassisTabMode)
|
|
{
|
|
if(GetWorkingEntity())
|
|
{
|
|
Stuff::SafeChainOf<Replicator*>* pOld = g_pTempReplicators;
|
|
g_pTempReplicators = &MechLab::Instance->m_TempReplicators;
|
|
|
|
Check_Object(GetWorkingEntity());
|
|
ElementRenderer::Element *element = GetWorkingEntity()->GetElement();
|
|
Check_Object(element);
|
|
LinearMatrix4D new_local = element->GetLocalToWorld();
|
|
YawPitchRoll current_rotation;
|
|
current_rotation = element->GetLocalToWorld();
|
|
// MSL 5.03 Mechview
|
|
// begin of MechView - jcem
|
|
if (g_pfnCTCL_AfterBeginScene == CTCL_AfterBeginScene)
|
|
{
|
|
int nXCount = radar_device.m_ptMechViewDim.x / radar_device.m_ptMechViewSize.x;
|
|
int nYCount = radar_device.m_ptMechViewDim.y / radar_device.m_ptMechViewSize.y;
|
|
int nCount = nXCount * nYCount;
|
|
current_rotation.yaw = (2 * Stuff::Pi * radar_device.m_nMechViewMax) / nCount;
|
|
}
|
|
else
|
|
{
|
|
// end of MechView
|
|
current_rotation.yaw += 0.02f;
|
|
}
|
|
current_rotation.Normalize();
|
|
new_local.BuildRotation(current_rotation);
|
|
element->SetLocalToParent(new_local);
|
|
element->Sync();
|
|
|
|
g_pTempReplicators = pOld;
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int _stdcall MechLab::ML_CallbackHandler(void* instance, int count, void* data[])
|
|
{
|
|
Check_Pointer(MechLab::Instance);
|
|
|
|
Stuff::SafeChainOf<Replicator*>* pOld = g_pTempReplicators;
|
|
g_pTempReplicators = &MechLab::Instance->m_TempReplicators;
|
|
|
|
int nRet = ML_CallbackHandlerReal(instance, count, data);
|
|
|
|
g_pTempReplicators = pOld;
|
|
|
|
return nRet;
|
|
}
|
|
|
|
int _stdcall MechLab::ML_CallbackHandlerReal(void* instance, int count, void* data[])
|
|
{
|
|
Check_Pointer(MechLab::Instance);
|
|
|
|
switch(CALLBACKID)
|
|
{
|
|
case MLGetDummyData:
|
|
return MechLab::Instance->GetDummyData(data, count);
|
|
case MLDataSetupLeftArm:
|
|
return MechLab::Instance->GetLeftArmWeapons(data, count);
|
|
case MLDataSetupRightArm:
|
|
return MechLab::Instance->GetRightArmWeapons(data, count);
|
|
case MLDataSetupLeftLeg:
|
|
return MechLab::Instance->GetLeftLegWeapons(data, count);
|
|
case MLDataSetupRightLeg:
|
|
return MechLab::Instance->GetRightLegWeapons(data, count);
|
|
case MLDataSetupLeftTorso:
|
|
return MechLab::Instance->GetLeftTorsoWeapons(data, count);
|
|
case MLDataSetupRightTorso:
|
|
return MechLab::Instance->GetRightTorsoWeapons(data, count);
|
|
case MLDataSetupCenterTorso:
|
|
return MechLab::Instance->GetCenterTorsoWeapons(data, count);
|
|
case MLDataSetupHead:
|
|
return MechLab::Instance->GetHeadWeapons(data, count);
|
|
case MLDataSetupSpecial1:
|
|
return MechLab::Instance->GetSpecial1Weapons(data, count);
|
|
case MLDataSetupSpecial2:
|
|
return MechLab::Instance->GetSpecial2Weapons(data, count);
|
|
case MLDataSetupMechSelection:
|
|
return MechLab::Instance->GetMechs(data, count);
|
|
case MLDataSetupChassisSelection:
|
|
return MechLab::Instance->GetChassis(data, count);
|
|
case MLCreateNewMech:
|
|
return MechLab::Instance->CreateNewMech(data, count, VARIANTS_PATH);
|
|
case MLSelectNewMech:
|
|
return MechLab::Instance->SelectMech(data, count, VARIANTS_PATH);
|
|
case MLInitChassisTab:
|
|
return MechLab::Instance->InitChassisTab(data, count);
|
|
case MLInitWeaponsTab:
|
|
return MechLab::Instance->InitWeaponsTab(data, count);
|
|
case MLInitArmorTab:
|
|
return MechLab::Instance->InitArmorTab(data, count);
|
|
case MLDataSetupAllWeapons:
|
|
return MechLab::Instance->GetAllWeapons(data, count);
|
|
case MLDataSetupBeamWeapons:
|
|
return MechLab::Instance->GetBeamWeapons(data, count);
|
|
case MLDataSetupProjectileWeapons:
|
|
return MechLab::Instance->GetProjectileWeapons(data, count);
|
|
case MLDataSetupMissileWeapons:
|
|
return MechLab::Instance->GetMissileWeapons(data, count);
|
|
case MLDataSetupGetMechData:
|
|
return MechLab::Instance->GetCurrentMechData(data, count);
|
|
case MLDataSetupGetMechArmor:
|
|
return MechLab::Instance->GetCurrentMechArmorData(data, count);
|
|
case MLAddSubsystem:
|
|
return MechLab::Instance->AddSubsystem(data, count);
|
|
case MLRemoveSubsystem:
|
|
return MechLab::Instance->RemoveSubsystem(data, count);
|
|
case MLRemoveAllSubsystems:
|
|
return MechLab::Instance->RemoveAllSubsystems();
|
|
case MLAutoAddSubsystem:
|
|
return MechLab::Instance->AutoAddSubsystem(data, count);
|
|
case MLDataGetWeaponGroups:
|
|
return MechLab::Instance->GetWeaponGroups(data, count);
|
|
case MLSetWeaponGroup:
|
|
return MechLab::Instance->SetWeaponGroup(data, count);
|
|
case MLClearWeaponGroup:
|
|
return MechLab::Instance->ClearWeaponGroup(data, count);
|
|
case MLSetAllWeaponGroups:
|
|
return MechLab::Instance->SetAllWeaponGroups(data, count);
|
|
case MLSave:
|
|
return MechLab::Instance->SaveMech();
|
|
case MLExit:
|
|
return MechLab::Instance->Exit();
|
|
case MLDeleteMech:
|
|
return MechLab::Instance->DeleteMech();
|
|
case MLRestore:
|
|
return MechLab::Instance->Restore();
|
|
case MLDataSetupGetMechNoEditData:
|
|
return MechLab::Instance->GetCurrentMechNoEditData(data, count);
|
|
case MLDataSetupGetEngineSpeed:
|
|
return MechLab::Instance->GetEngineSpeed(data, count);
|
|
case MLSetEngineUpgrade:
|
|
return MechLab::Instance->UpgradeEngine();
|
|
case MLSetEngineDegrade:
|
|
return MechLab::Instance->DegradeEngine();
|
|
case MLDataSetupGetHeatSinks:
|
|
return MechLab::Instance->GetHeatSinkCount(data, count);
|
|
case MLAddHeatSink:
|
|
return MechLab::Instance->AddHeatSink();
|
|
case MLRemoveHeatSink:
|
|
return MechLab::Instance->RemoveHeatSink();
|
|
case MLGetJumpJets:
|
|
return MechLab::Instance->GetJumpJets(data, count);
|
|
case MLSetJumpJets:
|
|
return MechLab::Instance->SetJumpJets(data, count);
|
|
case MLGetECM:
|
|
return MechLab::Instance->GetECM(data, count);
|
|
case MLSetECM:
|
|
return MechLab::Instance->SetECM(data, count);
|
|
case MLGetBeagle:
|
|
return MechLab::Instance->GetBeagle(data, count);
|
|
case MLSetBeagle:
|
|
return MechLab::Instance->SetBeagle(data, count);
|
|
case MLSetArmorType:
|
|
return MechLab::Instance->SetArmorType(data, count);
|
|
case MLAddArmorToZone:
|
|
return MechLab::Instance->AddArmorZoneValue(data, count);
|
|
case MLRemoveArmorFromZone:
|
|
return MechLab::Instance->RemoveArmorZoneValue(data, count);
|
|
case MLRename:
|
|
return MechLab::Instance->Rename(data, count, VARIANTS_PATH);
|
|
case MLDataGetWeaponAmmo:
|
|
return MechLab::Instance->GetWeaponAmmo(data, count);
|
|
case MLAddWeaponAmmo:
|
|
return MechLab::Instance->AddWeaponAmmo(data, count);
|
|
case MLRemoveWeaponAmmo:
|
|
return MechLab::Instance->RemoveWeaponAmmo(data, count);
|
|
case MLGetSkinListCount:
|
|
return MechLab::Instance->GetSkinListCount(data, count);
|
|
case MLDataGetSkinList:
|
|
return MechLab::Instance->GetSkinList(data, count);
|
|
case MLSetMechSkin:
|
|
return MechLab::Instance->SetMechSkin(data, count);
|
|
case MLGetLightAmp:
|
|
return MechLab::Instance->GetLightAmp(data, count);
|
|
case MLSetLightAmp:
|
|
return MechLab::Instance->SetLightAmp();
|
|
case MLSetArmorZoneValue:
|
|
return MechLab::Instance->SetArmorValue(data, count);
|
|
case MLDistributeArmor:
|
|
return MechLab::Instance->DistributeAllArmor();
|
|
case MLGetAMS:
|
|
return MechLab::Instance->GetAMS(data, count);
|
|
case MLSetAMS:
|
|
return MechLab::Instance->SetAMS();
|
|
case MLGetLAMS:
|
|
return MechLab::Instance->GetLAMS(data, count);
|
|
case MLSetLAMS:
|
|
return MechLab::Instance->SetLAMS();
|
|
case MLGetBaseMechName:
|
|
return MechLab::Instance->GetBaseMechName(data, count);
|
|
// MSL 5.02 SubSystems
|
|
// case MLGetEnhancedOptics:
|
|
// return MechLab::Instance->GetEnhancedOptics(data, count);
|
|
// case MLSetEnhancedOptics:
|
|
// return MechLab::Instance->SetEnhancedOptics();
|
|
case MLGetIFF_Jammer:
|
|
return MechLab::Instance->GetIFF_Jammer(data, count);
|
|
case MLSetIFF_Jammer:
|
|
return MechLab::Instance->SetIFF_Jammer();
|
|
case MLGetAdvancedGyro:
|
|
return MechLab::Instance->GetAdvancedGyro(data, count);
|
|
case MLSetAdvancedGyro:
|
|
return MechLab::Instance->SetAdvancedGyro();
|
|
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetLeftArmWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::LeftArmZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetRightArmWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::RightArmZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetLeftLegWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::LeftLegZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetRightLegWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::RightLegZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetLeftTorsoWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::LeftTorsoZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetRightTorsoWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::RightTorsoZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetCenterTorsoWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::CenterTorsoZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetHeadWeapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::HeadZone, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetSpecial1Weapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::SpecialZone1, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetSpecial2Weapons(void* data[], int count)
|
|
{
|
|
return FillPartWeaponData(InternalDamageObject::SpecialZone2, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::FillPartWeaponData(int part_id, void *data[])
|
|
{
|
|
if(GetWorkingMech() == NULL)
|
|
return -1;
|
|
|
|
//char **name_array
|
|
int *id_array = INTARRAYPARAM(1);
|
|
int *weapon_id_array = INTARRAYPARAM(2);
|
|
int *slot_array = INTARRAYPARAM(3);
|
|
int *slot_size_array = INTARRAYPARAM(4);
|
|
Scalar *tonage_array = SCALARARRAYPARAM(5);
|
|
Scalar *damage_array = SCALARARRAYPARAM(6);
|
|
Scalar *range_array = SCALARARRAYPARAM(7);
|
|
Scalar *heat_array = SCALARARRAYPARAM(8);
|
|
Scalar *recycle_array = SCALARARRAYPARAM(9);
|
|
int *num_weapons = INTARRAYPARAM(10);
|
|
#if defined(_ARMOR)
|
|
int array_size = VALUEPARM(11);
|
|
#endif
|
|
|
|
MWInternalDamageObject *part =
|
|
m_workingMech->internalDamageObjects.Find(part_id);
|
|
|
|
if(!part)
|
|
{
|
|
*num_weapons = 0;
|
|
return -1;
|
|
}
|
|
|
|
Check_Object(part);
|
|
|
|
ChainIteratorOf<Subsystem *> iterator(&part->subsystemChain);
|
|
Subsystem *subsystem;
|
|
int weapon_count = 0;
|
|
int valid_weapon_id = 0;
|
|
|
|
for(int i=MWInternalDamageObject::MissileSlotType; i<=MWInternalDamageObject::OmniSlotType; i++)
|
|
{
|
|
valid_weapon_id = 0;
|
|
iterator.First();
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
Weapon *weapon;
|
|
Verify(weapon_count < array_size);
|
|
weapon = Cast_Object(Weapon *, subsystem);
|
|
if(weapon->containedInSlotType == i)
|
|
{
|
|
const Weapon::GameModel *weapon_model = weapon->GetGameModel();
|
|
id_array[weapon_count] = weapon_model->itemID;
|
|
slot_array[weapon_count] = weapon_model->slotType;
|
|
slot_size_array[weapon_count] = weapon_model->totalSlotsTaken;
|
|
tonage_array[weapon_count] = weapon_model->tonage;
|
|
damage_array[weapon_count] = weapon_model->damageAmount * weapon_model->numFire;
|
|
if(weapon_model->itemID == W_ArtilleryStrike)
|
|
damage_array[weapon_count] = 40.0f;
|
|
range_array[weapon_count] = weapon_model->maxDistance;
|
|
heat_array[weapon_count] = weapon_model->heat * 2.0f;
|
|
weapon_id_array[weapon_count] = valid_weapon_id;
|
|
recycle_array[weapon_count] = weapon_model->reloadTime;
|
|
weapon_count++;
|
|
}
|
|
valid_weapon_id++;
|
|
}
|
|
}
|
|
|
|
//Now we need to check to see if we have anything empty in that slot type
|
|
int slots_available = 0;
|
|
switch(i)
|
|
{
|
|
case MWInternalDamageObject::MissileSlotType:
|
|
slots_available = part->GetMissileSlotsAvailable();
|
|
break;
|
|
case MWInternalDamageObject::ProjectileSlotType:
|
|
slots_available = part->GetProjectileSlotsAvailable();
|
|
break;
|
|
case MWInternalDamageObject::BeamSlotType:
|
|
slots_available = part->GetBeamSlotsAvailable();
|
|
break;
|
|
case MWInternalDamageObject::OmniSlotType:
|
|
slots_available = part->GetOmniSlotsAvailable();
|
|
break;
|
|
}
|
|
|
|
if(slots_available > 0)
|
|
{
|
|
id_array[weapon_count] = EmptyWeaponID;
|
|
slot_array[weapon_count] = i;
|
|
slot_size_array[weapon_count] = slots_available;
|
|
tonage_array[weapon_count] = -1;
|
|
damage_array[weapon_count] = -1;
|
|
range_array[weapon_count] = -1;
|
|
heat_array[weapon_count] = -1;
|
|
weapon_count++;
|
|
}
|
|
}
|
|
*num_weapons = weapon_count;
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetAllWeapons(void *data[], int count)
|
|
{
|
|
return FillWeaponListData(AllWeapons, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetBeamWeapons(void *data[], int count)
|
|
{
|
|
return FillWeaponListData(BeamWeapons, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetProjectileWeapons(void *data[], int count)
|
|
{
|
|
return FillWeaponListData(ProjectileWeapons, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetMissileWeapons(void *data[], int count)
|
|
{
|
|
return FillWeaponListData(MissileWeapons, data);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::FillWeaponListData(int weapon_list, void *data[])
|
|
{
|
|
//char **name_array
|
|
int *id_array = INTARRAYPARAM(1);
|
|
int *slot_array = INTARRAYPARAM(2);
|
|
int *slot_size_array = INTARRAYPARAM(3);
|
|
Scalar *tonage_array = SCALARARRAYPARAM(4);
|
|
Scalar *damage_array = SCALARARRAYPARAM(5);
|
|
Scalar *range_array = SCALARARRAYPARAM(6);
|
|
Scalar *heat_array = SCALARARRAYPARAM(7);
|
|
Scalar *recycle_array = SCALARARRAYPARAM(8);
|
|
int *inventory_array = INTARRAYPARAM(9);
|
|
int *num_weapons = INTARRAYPARAM(10);
|
|
#if defined(_ARMOR)
|
|
int array_size = VALUEPARM(11);
|
|
#endif
|
|
|
|
int weapon_count = 0;
|
|
|
|
SubsystemResource *sub_resource;
|
|
SortedChainIteratorOf<SubsystemResource *, int> iterator(&m_subsystemsAvailable);
|
|
|
|
int low_range = FirstWeaponID;
|
|
int high_range = LastWeaponID;
|
|
|
|
switch (weapon_list)
|
|
{
|
|
case MissileWeapons:
|
|
low_range = FirstMissileID;
|
|
high_range = LastMissileID;
|
|
break;
|
|
case ProjectileWeapons:
|
|
low_range = FirstProjectileID;
|
|
high_range = LastProjectileID;
|
|
break;
|
|
case BeamWeapons:
|
|
low_range = FirstBeamID;
|
|
high_range = LastBeamID;
|
|
break;
|
|
}
|
|
|
|
while((sub_resource = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(sub_resource);
|
|
if((sub_resource->GetSubsystemType() >= low_range) &&
|
|
(sub_resource->GetSubsystemType() <= high_range) &&
|
|
(sub_resource->GetNumberAvailable() != 0))
|
|
{
|
|
Resource model_resource(sub_resource->GetGameModelID());
|
|
Verify(model_resource.DoesResourceExist());
|
|
|
|
Weapon::GameModel *weapon_model =
|
|
Cast_Pointer(Weapon::GameModel *, model_resource.GetPointer());
|
|
|
|
Verify(weapon_count < array_size);
|
|
id_array[weapon_count] = weapon_model->itemID;
|
|
slot_array[weapon_count] = weapon_model->slotType;
|
|
slot_size_array[weapon_count] = weapon_model->totalSlotsTaken;
|
|
tonage_array[weapon_count] = weapon_model->tonage;
|
|
damage_array[weapon_count] = weapon_model->damageAmount * weapon_model->numFire;
|
|
if(weapon_model->itemID == W_ArtilleryStrike)
|
|
damage_array[weapon_count] = 40.0f;
|
|
range_array[weapon_count] = weapon_model->maxDistance;
|
|
heat_array[weapon_count] = weapon_model->heat * 2.0f;
|
|
recycle_array[weapon_count] = weapon_model->reloadTime;
|
|
inventory_array[weapon_count] = sub_resource->GetNumberAvailable();
|
|
weapon_count++;
|
|
}
|
|
}
|
|
|
|
*num_weapons = weapon_count;
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetCurrentMechData(void *data[], int count)
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
int *id = INTARRAYPARAM(1);
|
|
Scalar *ton = SCALARARRAYPARAM(2);
|
|
Scalar *max_ton = SCALARARRAYPARAM(3);
|
|
int *battle_value = INTARRAYPARAM(4);
|
|
int *heat_effic = INTARRAYPARAM(5);
|
|
int *speed_bar = INTARRAYPARAM(6);
|
|
int *armor_bar = INTARRAYPARAM(7);
|
|
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*id = mech_model->mechID;
|
|
*ton = m_workingMech->GetTonage();
|
|
*max_ton = mech_model->maxVehicleTonnage;
|
|
|
|
// MSL 5.04 Modified Firepower bar
|
|
// *battle_value = (int)(m_workingMech->GetBattleValue());
|
|
// *battle_value = (int)(m_workingMech->GetBattleValue() / 4);
|
|
*battle_value = (int)(((m_workingMech->GetBattleValue()) / 80.0) * 100.0);
|
|
Clamp(*battle_value, 0, 100);
|
|
|
|
// MSL 5.04 Modified Speed bar
|
|
Engine *engine = m_workingMech->GetEngine();
|
|
Check_Object(engine);
|
|
Verify(mech_model->maxSpeed > mech_model->minMaxSpeed);
|
|
// Scalar speed_ratio = (engine->GetMaxSpeed()- mech_model->minMaxSpeed) / (mech_model->maxSpeed - mech_model->minMaxSpeed);
|
|
Scalar speed_ratio = (engine->GetMaxSpeed() / mech_model->maxSpeed);
|
|
*speed_bar = (int)(speed_ratio * 100);
|
|
Clamp(*speed_bar, 0, 100);
|
|
|
|
// MSL 5.04 Modified Armor bar
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
// *armor_bar = (int)armor->GetTotalTonage() * 5;
|
|
// Clamp(*armor_bar, 0, 100);
|
|
// *armor_bar = (int)((armor->GetTotalArmor() / 307.0) * 100.0);
|
|
// MSL 5.05 Mofified Armor bar
|
|
*armor_bar = (int)((armor->GetTotalArmor() / 535.0) * 100.0);
|
|
Clamp(*armor_bar, 0, 100);
|
|
|
|
*heat_effic = m_workingMech->GetHeatEffic();
|
|
#if 0
|
|
int num_weapons = m_workingMech->weaponChain.GetSize();
|
|
int num_heat_sinks = m_workingMech->m_numHeatSinks + engine_model->m_numHeatSinks;
|
|
|
|
if(num_weapons > 0)
|
|
*heat_effic = (int)(num_heat_sinks / (num_weapons * 2.5f));
|
|
else
|
|
*heat_effic = 0;
|
|
#endif
|
|
Clamp(*heat_effic, 0, 100);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetCurrentMechNoEditData(void *data[], int count)
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
Scalar *accel = SCALARARRAYPARAM(1);
|
|
Scalar *deaccel = SCALARARRAYPARAM(2);
|
|
Scalar *turn_rate = SCALARARRAYPARAM(3);
|
|
Scalar *twist = SCALARARRAYPARAM(4);
|
|
Scalar *twist_speed = SCALARARRAYPARAM(5);
|
|
int *tech_type = INTARRAYPARAM(6);
|
|
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*accel = mech_model->acceleration;
|
|
*deaccel = mech_model->decceleration;
|
|
*turn_rate = mech_model->topSpeedTurnRate;
|
|
const Torso::GameModel *torso_model = m_workingMech->GetTorso()->GetGameModel();
|
|
*twist = torso_model->twistRadius * Degrees_Per_Radian;
|
|
*twist_speed = torso_model->twistSpeed * Degrees_Per_Radian;
|
|
*tech_type = mech_model->techType;
|
|
|
|
}
|
|
return 1;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetCurrentMechArmorData(void *data[], int count)
|
|
{
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
Scalar *armor_array = SCALARARRAYPARAM(1);
|
|
int *armor_max_array = INTARRAYPARAM(2);
|
|
Scalar *tonnage_array = SCALARARRAYPARAM(3);
|
|
int *armor_type = INTARRAYPARAM(4);
|
|
int *internal_type = INTARRAYPARAM(5);
|
|
int *points_per = INTARRAYPARAM(6);
|
|
Scalar *tons = SCALARARRAYPARAM(7);
|
|
int *total_armor = INTARRAYPARAM(8);
|
|
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
|
|
const Armor::GameModel *armor_model = armor->GetGameModel();
|
|
switch(armor->GetArmorType())
|
|
{
|
|
// MSL 5.00 Armor
|
|
case Armor::StandardArmor:
|
|
{
|
|
*points_per = armor_model->m_pointsPerStandardTon;
|
|
break;
|
|
}
|
|
case Armor::FerroFiberusArmor:
|
|
{
|
|
*points_per = armor_model->m_pointsPerFerroTon;
|
|
break;
|
|
}
|
|
case Armor::ReactiveArmor:
|
|
{
|
|
*points_per = armor_model->m_pointsPerReactiveTon;
|
|
break;
|
|
}
|
|
case Armor::ReflectiveArmor:
|
|
{
|
|
*points_per = armor_model->m_pointsPerReflectiveTon;
|
|
break;
|
|
}
|
|
case Armor::SolarianArmor:
|
|
{
|
|
*points_per = armor_model->m_pointsPerSolarianTon;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for(int i=0; i<=A_Head; i++)
|
|
{
|
|
armor_array[i] = armor->GetArmorValue(i);
|
|
tonnage_array[i] = armor_array[i] / *points_per;
|
|
}
|
|
for(i=0; i<= A_Head; i++)
|
|
{
|
|
DamageObject *armor_zone = m_workingMech->damageObjects.Find(i);
|
|
Check_Object(armor_zone);
|
|
armor_max_array[i] = (int)armor_zone->maxArmorValue;
|
|
}
|
|
|
|
*armor_type = armor->GetArmorType();
|
|
*internal_type = armor->GetInternalType();
|
|
|
|
|
|
*tons = armor->GetTotalTonage();
|
|
*total_armor = armor->GetTotalArmor();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetArmorType(void *data[], int count)
|
|
{
|
|
int *new_type = INTARRAYPARAM(1);
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
|
|
armor->SetArmorType(*new_type);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::AddArmorZoneValue(void *data[], int count)
|
|
{
|
|
int *new_type = INTARRAYPARAM(1);
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
|
|
armor->ApplyZoneBasedArmor(*new_type, 0.1f);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::RemoveArmorZoneValue(void *data[], int count)
|
|
{
|
|
int *new_type = INTARRAYPARAM(1);
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
|
|
armor->ApplyZoneBasedArmor(*new_type, -0.1f);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetArmorValue(void *data[], int count)
|
|
{
|
|
int *zone = INTARRAYPARAM(1);
|
|
Scalar *new_amount = SCALARARRAYPARAM(2);
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
|
|
armor->SetZoneBasedArmor(*zone, *new_amount);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::DistributeAllArmor()
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
Armor *armor = m_workingMech->GetArmor();
|
|
Check_Object(armor);
|
|
|
|
return armor->ApplyDistributiveArmor();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetMechs(void* data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
char **name_array = STRARRAYPARAM(1);
|
|
int *selected_mech = INTARRAYPARAM(2);
|
|
|
|
*selected_mech = 0;
|
|
|
|
if(m_mechLabCount == 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if(m_mechIDs)
|
|
{
|
|
gos_Free(m_mechIDs);
|
|
m_mechIDs = NULL;
|
|
}
|
|
m_mechIDs = (ResourceID *)gos_Malloc(m_mechLabCount * sizeof(ResourceID));
|
|
|
|
SortedChainOf<PlugOf<MString>*, MString> alpha_mech_names(NULL, true);
|
|
MString* alpha_mech_names_with_mc = new MString[m_mechLabCount];
|
|
|
|
Stuff::MString mechs_path = VARIANTS_PATH"*.mw4";
|
|
Stuff::Directory *resource_directory;
|
|
resource_directory = new Stuff::Directory(mechs_path, true);
|
|
Check_Object(resource_directory);
|
|
const char *file_name;
|
|
while((file_name = resource_directory->GetCurrentFileName()) != NULL)
|
|
{
|
|
MString mech_name;
|
|
mech_name = file_name;
|
|
mech_name.StripDirectory().StripExtension();
|
|
|
|
PlugOf<MString> *name_plug = new PlugOf<MString>(mech_name);
|
|
alpha_mech_names.AddValue(name_plug, mech_name);
|
|
|
|
resource_directory->AdvanceCurrentFile();
|
|
}
|
|
|
|
// Sort Mad Cat correctly
|
|
SortedChainIteratorOf<PlugOf<MString> *, MString> mech_name_iterator(&alpha_mech_names);
|
|
PlugOf<MString> *mstring_plug;
|
|
int mech_index = 0;
|
|
while((mstring_plug = mech_name_iterator.ReadAndNext()) != NULL)
|
|
{
|
|
if (mech_index == m_mechLabCount)
|
|
break; // Boundary Check
|
|
|
|
alpha_mech_names_with_mc[mech_index] = mstring_plug->GetItem();
|
|
mech_index ++;
|
|
}
|
|
int mc2_start = 0;
|
|
while (_strnicmp(alpha_mech_names_with_mc[mc2_start], "Mad Cat MKII", 12) != 0)
|
|
{
|
|
mc2_start++;
|
|
|
|
if (mc2_start == m_mechLabCount)
|
|
break; // Boundary Check
|
|
}
|
|
int mc2_end = mc2_start;
|
|
if (mc2_start < m_mechLabCount)
|
|
{
|
|
while (_strnicmp(alpha_mech_names_with_mc[mc2_end], "Mad Cat MKII", 12) == 0)
|
|
{
|
|
mc2_end++;
|
|
|
|
if (mc2_end == m_mechLabCount)
|
|
break; // Boundary Check
|
|
}
|
|
}
|
|
int mc_end = mc2_end;
|
|
if (mc_end < m_mechLabCount)
|
|
{
|
|
while (_strnicmp(alpha_mech_names_with_mc[mc_end], "Mad Cat", 7) == 0)
|
|
{
|
|
mc_end++;
|
|
|
|
if (mc_end == m_mechLabCount)
|
|
break; // Boundary Check
|
|
}
|
|
}
|
|
int mc2_i = mc2_end - mc2_start;
|
|
int mc_i = mc_end - mc2_end;
|
|
if ((mc2_i > 0) && (mc_i > 0))
|
|
{
|
|
MString* mc2_string = new MString[mc2_i];
|
|
for (int i = 0; i < mc2_i; i++)
|
|
mc2_string[i] = alpha_mech_names_with_mc[mc2_start + i];
|
|
for (i = 0; i < mc_i; i++)
|
|
alpha_mech_names_with_mc[mc2_start + i] = alpha_mech_names_with_mc[mc2_end + i];
|
|
for (i = 0; i < mc2_i; i++)
|
|
alpha_mech_names_with_mc[mc2_start + mc_i + i] = mc2_string[i];
|
|
delete [] mc2_string;
|
|
}
|
|
|
|
// now return the sorted strings
|
|
mech_index = 0;
|
|
while (mech_index < m_mechLabCount)
|
|
{
|
|
MString mech_name = alpha_mech_names_with_mc[mech_index];
|
|
FREEANDNULL(name_array[mech_index]);
|
|
name_array[mech_index] = (char *)gos_Malloc(128);
|
|
Str_Copy(
|
|
name_array[mech_index],
|
|
(const char *)mech_name,
|
|
mech_name.GetLength() + 1
|
|
);
|
|
if(m_workingMechName)
|
|
{
|
|
MString compare_name = m_workingMechName;
|
|
compare_name.StripDirectory();
|
|
if(compare_name == mech_name)
|
|
*selected_mech = mech_index;
|
|
}
|
|
|
|
m_mechIDs[mech_index] = ResourceID::Null;
|
|
mech_index++;
|
|
}
|
|
|
|
alpha_mech_names.DeletePlugs();
|
|
delete [] alpha_mech_names_with_mc;
|
|
delete resource_directory;
|
|
return 1;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetChassis(void* data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
char **name_array = STRARRAYPARAM(1);
|
|
|
|
if(m_chassisIDs)
|
|
{
|
|
gos_Free(m_chassisIDs);
|
|
m_chassisIDs = NULL;
|
|
}
|
|
m_chassisIDs = (ResourceID *)gos_Malloc(m_chassisCount * sizeof(ResourceID));
|
|
|
|
int i = 0;
|
|
|
|
MWTable::TableIterator *mech_iterator;
|
|
Check_Object(MWApplication::GetInstance()->m_mechTable);
|
|
|
|
mech_iterator = MWApplication::GetInstance()->m_mechTable->MakeTableIterator();
|
|
MWTableEntry *mech_entry;
|
|
while((mech_entry = mech_iterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(mech_entry);
|
|
|
|
FREEANDNULL(name_array[i]);
|
|
name_array[i] = (char *)gos_Malloc(128);
|
|
Str_Copy(
|
|
name_array[i],
|
|
(const char *)mech_entry->GetEntryName(),
|
|
mech_entry->GetEntryName().GetLength() + 1
|
|
);
|
|
m_chassisIDs[i] = mech_entry->GetEntryResourceID();
|
|
i++;
|
|
}
|
|
|
|
delete mech_iterator;
|
|
return 1;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetMechCount()
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
int i = 0;
|
|
Stuff::MString mechs_path = VARIANTS_PATH"*.mw4";
|
|
Stuff::Directory *resource_directory;
|
|
resource_directory = new Stuff::Directory(mechs_path, true);
|
|
Check_Object(resource_directory);
|
|
i += resource_directory->fileWalker->GetSize();
|
|
delete resource_directory;
|
|
|
|
return i;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetChassisCount()
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
int i = 0;
|
|
|
|
Check_Object(MWApplication::GetInstance()->m_mechTable);
|
|
i += MWApplication::GetInstance()->m_mechTable->GetTableSize();
|
|
|
|
return i;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetMech(int mech_id, const char *mech_name, const char *path)
|
|
{
|
|
//For right now we are going to just create a known mech
|
|
ResourceID mech_resource_id = m_mechIDs[mech_id];
|
|
|
|
return SetMech(mech_resource_id, mech_name, path);
|
|
}
|
|
|
|
int MechLab::SetMech(ResourceID mech_resource_id, const char *mech_name, const char *path)
|
|
{
|
|
Entity *entity;
|
|
|
|
Stuff::SafeChainOf<Replicator*>* pOld = g_pTempReplicators;
|
|
g_pTempReplicators = &MechLab::Instance->m_TempReplicators;
|
|
|
|
DestroyWorkingEntity();
|
|
|
|
if(mech_resource_id == ResourceID::Null)
|
|
{
|
|
|
|
//
|
|
//-----------------------------------------------------------------
|
|
//This means that we have a user made mech in its own resource file
|
|
//-----------------------------------------------------------------
|
|
//
|
|
MString path_name = path;
|
|
path_name += mech_name;
|
|
MString res_name = path_name;
|
|
m_workingMechName = res_name;
|
|
res_name += ".mw4";
|
|
Check_Object(ResourceManager::Instance);
|
|
if(m_mechResourceFile.GetCurrent())
|
|
{
|
|
m_mechResourceFile.GetCurrent()->Save();
|
|
delete m_mechResourceFile.GetCurrent();
|
|
m_mechResourceFile.Remove();
|
|
}
|
|
ResourceFile *res_file;
|
|
res_file = ResourceManager::Instance->OpenResourceFile(
|
|
res_name,
|
|
NULL,
|
|
MechResourceFileID,
|
|
VER_CONTENTVERSION,
|
|
false,
|
|
false
|
|
);
|
|
Check_Object(res_file);
|
|
m_mechResourceFile.Add(res_file);
|
|
|
|
ResourceID mech_id(MechResourceFileID, 1);
|
|
Resource mech_resource(mech_id);
|
|
Verify(mech_resource.DoesResourceExist());
|
|
|
|
|
|
// MSL 5.03 MechView
|
|
ReplicatorID base_id(CONN4ML->GetNextReplicatorID());
|
|
entity = Entity::CreateEntity(&mech_resource, &base_id);
|
|
}
|
|
else
|
|
{
|
|
Resource mech_resource(mech_resource_id);
|
|
Verify(mech_resource.DoesResourceExist());
|
|
// MSL 5.03 MechView
|
|
ReplicatorID base_id(CONN4ML->GetNextReplicatorID());
|
|
entity = Entity::CreateEntity(&mech_resource, &base_id);
|
|
}
|
|
Check_Object(entity);
|
|
SetUpWorkingMech(entity);
|
|
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
|
|
if(!m_isCampaign)
|
|
{
|
|
app->m_lastMechID = -1;
|
|
app->m_lastMechName = mech_name;
|
|
}
|
|
|
|
g_pTempReplicators = pOld;
|
|
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::CreateNewMech(void *data[], int count, const char *path)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
const char *chassis_name = STRPARM(1);
|
|
int chassis_index = INTPARM(2);
|
|
const char *mech_name = STRPARM(3);
|
|
int overwrite = INTPARM(4);
|
|
|
|
if(!MWApplication::ValidateName((char*)mech_name, true))
|
|
return -1;
|
|
|
|
Verify(chassis_index >= 0);
|
|
Verify(chassis_index < m_chassisCount);
|
|
ResourceID chassis_resource_id = m_chassisIDs[chassis_index];
|
|
Resource chassis_resource(chassis_resource_id);
|
|
Verify(chassis_resource.DoesResourceExist());
|
|
MString path_name = path;
|
|
path_name += chassis_name;
|
|
path_name += " ";
|
|
path_name += mech_name;
|
|
MString res_name = path_name;
|
|
m_workingMechName = res_name;
|
|
res_name += ".mw4";
|
|
if (!gos_DoesFileExist(VARIANTS_PATH))
|
|
gos_CreateDirectory(VARIANTS_PATH);
|
|
|
|
if(gos_DoesFileExist(res_name) && !overwrite)
|
|
return E_MechAlreadyExists;
|
|
|
|
//Parameter [1] is the new mech name
|
|
//Parameter [2] is the new mech chassis ID
|
|
if(m_mechResourceFile.GetCurrent())
|
|
{
|
|
m_mechResourceFile.GetCurrent()->Save();
|
|
delete m_mechResourceFile.GetCurrent();
|
|
m_mechResourceFile.Remove();
|
|
}
|
|
|
|
if(!MWApplication::ValidatePath(res_name, true))
|
|
return -1;
|
|
|
|
Check_Object(ResourceManager::Instance);
|
|
ResourceFile *res_file;
|
|
res_file = ResourceManager::Instance->OpenResourceFile(
|
|
res_name,
|
|
NULL,
|
|
MechResourceFileID,
|
|
VER_CONTENTVERSION,
|
|
false,
|
|
true
|
|
);
|
|
Check_Object(res_file);
|
|
m_mechResourceFile.Add(res_file);
|
|
// MSL 5.03 MechView
|
|
ReplicatorID base_id(CONN4ML->GetNextReplicatorID());
|
|
|
|
DestroyWorkingEntity();
|
|
|
|
Entity *template_entity = Entity::CreateEntity(&chassis_resource, &base_id);
|
|
Check_Object(template_entity);
|
|
|
|
|
|
//We need to write in a dep resource and a texture hint file resource
|
|
//The we can write this resource in....
|
|
Resource dep_resource(m_workingMechName, m_mechResourceFile.GetCurrent());
|
|
DynamicMemoryStream dep_stream;
|
|
MString dep = "";
|
|
dep_stream << dep;
|
|
dep_resource.Save(&dep_stream, NULL);
|
|
|
|
Resource mech_resource("{Mech}", m_mechResourceFile.GetCurrent());
|
|
mech_resource.Save(NULL, NULL);
|
|
|
|
DynamicMemoryStream game_stream;
|
|
Check_Object(template_entity);
|
|
|
|
template_entity->SaveMakeMessage(&game_stream, m_mechResourceFile.GetCurrent());
|
|
|
|
game_stream.Rewind();
|
|
Stuff::FileDependencies dependancies;
|
|
dependancies.AddDependency("");
|
|
mech_resource.Save(&game_stream, &dependancies);
|
|
|
|
template_entity->Destroy();
|
|
|
|
// MSL 5.03 MechView
|
|
base_id = CONN4ML->GetNextReplicatorID();
|
|
|
|
Entity *entity = Entity::CreateEntity(&mech_resource, &base_id);
|
|
Check_Object(entity);
|
|
SetUpWorkingMech(entity);
|
|
|
|
|
|
|
|
// mark the mech to detect hex editing
|
|
{
|
|
|
|
Resource crc_resource("icuedbdii", m_mechResourceFile.GetCurrent());
|
|
crc_resource.Save(NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
ResourceID crc_id(MechResourceFileID, 3);
|
|
Resource crc_resource(crc_id);
|
|
|
|
MD5_CTX resource_context;
|
|
GUID resource_hash;
|
|
unsigned char * buff=(unsigned char *) &resource_hash;
|
|
|
|
MD5Init(&resource_context);
|
|
int key = 0xa1252388;
|
|
mech_resource.Rewind();
|
|
MD5Update(&resource_context, (unsigned char *) &key, 4);
|
|
MD5Update(&resource_context, (unsigned char *) mech_resource.GetPointer(), mech_resource.GetBytesRemaining());
|
|
|
|
MD5Final(buff, &resource_context);
|
|
|
|
DynamicMemoryStream hash_stream;
|
|
hash_stream.WriteBytes(&resource_hash,16);
|
|
hash_stream.Rewind();
|
|
|
|
crc_resource.Save(&hash_stream, &dependancies);
|
|
|
|
|
|
|
|
m_mechResourceFile.GetCurrent()->Save();
|
|
m_mechLabCount = GetMechCount();
|
|
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
|
|
if(!m_isCampaign)
|
|
{
|
|
app->m_lastMechID = -1;
|
|
app->m_lastMechName = MString(chassis_name)+" "+mech_name;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::SetUpWorkingMech(Entity *entity)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(entity);
|
|
Check_Object(s_MechCamera);
|
|
//Verify(entity->IsDerivedFrom(Mech::DefaultData));//jcem camera-ship could be setted for loading time
|
|
|
|
s_MechCamera->SetScene(NULL);
|
|
DestroyWorkingEntity();
|
|
if (entity->IsDerivedFrom(Mech::DefaultData))
|
|
{
|
|
m_workingMech = Cast_Object(Mech *, entity);
|
|
extern char g_SkinSet;
|
|
g_SkinSet = m_workingMech->GetSkinPrefix();
|
|
extern int g_PilotDecal;
|
|
g_PilotDecal = m_workingMech->GetPilotDecal();
|
|
extern int g_TeamDecal;
|
|
g_TeamDecal = m_workingMech->GetTeamDecal();
|
|
}
|
|
m_workingEntity = entity;
|
|
ElementRenderer::Element *mech_element = m_workingEntity/*m_workingMech*/->GetElement();
|
|
Check_Object(mech_element);
|
|
Check_Object(m_sceneRoot);
|
|
m_sceneRoot->AttachChild(mech_element);
|
|
Check_Object(VideoRenderer::Instance);
|
|
ChainIteratorOf<Entity*> children(&m_workingEntity/*m_workingMech*/->childEntityChain);
|
|
Entity *child_entity;
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
if(child_entity->IsDerivedFrom(MWMover::DefaultData))
|
|
{
|
|
MWMover *mover = Cast_Object(MWMover *, child_entity);
|
|
MakeMoverInteresting(mover);
|
|
}
|
|
}
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
|
|
s_MechCamera->SetScene(mech_element);
|
|
Stuff::LinearMatrix4D origin = LinearMatrix4D::Identity;
|
|
origin.BuildRotation(Stuff::YawPitchRoll(-Pi + 0.1f, 0.0, Pi));
|
|
|
|
MWApplication* app = MWApplication::GetInstance ();
|
|
// MSL 5.03 Mechview
|
|
if (g_pfnCTCL_AfterBeginScene == CTCL_AfterBeginScene)
|
|
{
|
|
origin.BuildTranslation(Stuff::Point3D(0.0f, 6.0f, 45.0f)); // MechView Param - relative look position
|
|
}
|
|
else
|
|
{
|
|
if (app->GetApplicationState() == ApplicationStateEngine::LoadingGameState)
|
|
{
|
|
// jcem - if single campaign, centering mech...
|
|
// origin.BuildTranslation(Stuff::Point3D(0.0f, 6.0f, 23.0f));
|
|
origin.BuildTranslation(Stuff::Point3D(0.0f, 6.0f, 30.0f)); // This affects Secondary View Size
|
|
}
|
|
else
|
|
{
|
|
origin.BuildTranslation(Stuff::Point3D(0.0f, 6.0f, 23.0f));
|
|
}
|
|
}
|
|
mech_element->SetLocalToParent(origin);
|
|
mech_element->Sync();
|
|
s_MechCamera->Sync();
|
|
m_sceneRoot->SetRootMode();
|
|
m_sceneRoot->Sync();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::MakeMoverInteresting(MWMover *mover)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(mover);
|
|
|
|
ChainIteratorOf<Entity*> children(&mover->childEntityChain);
|
|
Entity *child_entity;
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
MakeInteresting(child_entity);
|
|
}
|
|
|
|
VideoRenderer::Instance->EntityIsInteresting(mover, true);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::MakeInteresting(Entity *entity)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(entity);
|
|
|
|
ChainIteratorOf<Entity*> children(&entity->childEntityChain);
|
|
Entity *child_entity;
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
MakeInteresting(child_entity);
|
|
}
|
|
|
|
VideoRenderer::Instance->EntityIsInteresting(entity, true);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::MakeMoverUnInteresting(MWMover *mover)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(mover);
|
|
|
|
ChainIteratorOf<Entity*> children(&mover->childEntityChain);
|
|
Entity *child_entity;
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
MakeUnInteresting(child_entity);
|
|
}
|
|
|
|
//This is a hack to force a re-load of the web
|
|
RendererComponentWeb *web = mover->GetComponentWeb(RendererManager::VideoRendererType);
|
|
if(web)
|
|
mover->SetComponentWeb(RendererManager::VideoRendererType, NULL);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void MechLab::MakeUnInteresting(Entity *entity)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(entity);
|
|
|
|
ChainIteratorOf<Entity*> children(&entity->childEntityChain);
|
|
Entity *child_entity;
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
MakeUnInteresting(child_entity);
|
|
}
|
|
|
|
RendererComponentWeb *web = entity->GetComponentWeb(RendererManager::VideoRendererType);
|
|
if(web)
|
|
entity->SetComponentWeb(RendererManager::VideoRendererType, NULL);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::SelectMech(void *data[], int count, const char *path)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
//Parameter 1 is the mech's id in the mech array
|
|
int mech_index = INTPARM(1);
|
|
const char *mech_name = STRPARM(2);
|
|
Verify(mech_index >= 0);
|
|
Verify(mech_index < m_mechLabCount);
|
|
|
|
return SetMech(mech_index, mech_name, path);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::UpdateDisplay()
|
|
{
|
|
|
|
if(s_MechCamera)
|
|
{
|
|
s_MechCamera->DrawScene(true);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::InitChassisTab(void *data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
m_mode = ChassisTabMode;
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::InitWeaponsTab(void *data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
m_mode = WeaponsTabMode;
|
|
if(GetWorkingMech())
|
|
{
|
|
ElementRenderer::Element *mech_element = m_workingMech->GetElement();
|
|
Stuff::LinearMatrix4D origin = LinearMatrix4D::Identity;
|
|
origin.BuildRotation(Stuff::YawPitchRoll(-Pi + 0.1f, 0.0, Pi));
|
|
origin.BuildTranslation(Stuff::Point3D(5.5f, 6.0f, 23.0f));
|
|
mech_element->SetLocalToParent(origin);
|
|
mech_element->Sync();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::InitArmorTab(void *data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
m_mode = ArmorTabMode;
|
|
if(GetWorkingMech())
|
|
{
|
|
ElementRenderer::Element *mech_element = m_workingMech->GetElement();
|
|
Stuff::LinearMatrix4D origin = LinearMatrix4D::Identity;
|
|
origin.BuildRotation(Stuff::YawPitchRoll(-Pi + 0.1f, 0.0, Pi));
|
|
origin.BuildTranslation(Stuff::Point3D(5.5f, 6.0f, 23.0f));
|
|
mech_element->SetLocalToParent(origin);
|
|
mech_element->Sync();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::InitializeSubsystemsAvailable()
|
|
{
|
|
|
|
MWTable::TableIterator *weapon_iterator;
|
|
Check_Object(MWApplication::GetInstance()->m_weaponsTable);
|
|
|
|
weapon_iterator = MWApplication::GetInstance()->m_weaponsTable->MakeTableIterator();
|
|
MWTableEntry *weapon_entry;
|
|
while((weapon_entry = weapon_iterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(weapon_entry);
|
|
Resource model_resource;
|
|
Entity::GetGameModelResourceFromDataListID(&model_resource, weapon_entry->GetEntryResourceID());
|
|
Verify(model_resource.DoesResourceExist());
|
|
Weapon::GameModel *weapon_model =
|
|
Cast_Pointer(Weapon::GameModel *, model_resource.GetPointer());
|
|
SubsystemResource *sub_resource;
|
|
sub_resource = AddAvailableSubsystem(
|
|
weapon_entry->GetEntryResourceID(),
|
|
model_resource.GetResourceID(),
|
|
weapon_model->itemID
|
|
);
|
|
Check_Object(sub_resource);
|
|
sub_resource->SetUnlimited();
|
|
}
|
|
MWTable::TableIterator *sub_iterator;
|
|
Check_Object(MWApplication::GetInstance()->m_subsystemTable);
|
|
|
|
sub_iterator = MWApplication::GetInstance()->m_subsystemTable->MakeTableIterator();
|
|
MWTableEntry *sub_entry;
|
|
while((sub_entry = sub_iterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(sub_entry);
|
|
Resource model_resource;
|
|
Entity::GetGameModelResourceFromDataListID(&model_resource, sub_entry->GetEntryResourceID());
|
|
Verify(model_resource.DoesResourceExist());
|
|
Subsystem::GameModel *sub_model =
|
|
Cast_Pointer(Subsystem::GameModel *, model_resource.GetPointer());
|
|
SubsystemResource *sub_resource;
|
|
sub_resource = AddAvailableSubsystem(
|
|
sub_entry->GetEntryResourceID(),
|
|
model_resource.GetResourceID(),
|
|
sub_model->itemID
|
|
);
|
|
Check_Object(sub_resource);
|
|
sub_resource->SetUnlimited();
|
|
}
|
|
|
|
delete weapon_iterator;
|
|
delete sub_iterator;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SubsystemResource*
|
|
MechLab::AddAvailableSubsystem(const Adept::ResourceID& data_list, const Adept::ResourceID& model_id, int type)
|
|
{
|
|
SubsystemResource *sub_resource = m_subsystemsAvailable.Find(type);
|
|
if(sub_resource) //Just add another available
|
|
{
|
|
if(sub_resource->GetNumberAvailable() != -1) //if not unlimmited
|
|
sub_resource->AddNumberAvailable();
|
|
}
|
|
else
|
|
{
|
|
sub_resource = new SubsystemResource(data_list, model_id, type);
|
|
Check_Object(sub_resource);
|
|
m_subsystemsAvailable.AddValue(sub_resource, type);
|
|
}
|
|
|
|
return sub_resource;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SubsystemResource*
|
|
MechLab::AddAvailableSubsystem(Subsystem *subsystem)
|
|
{
|
|
ResourceID data_list;
|
|
ResourceID model_id;
|
|
int type;
|
|
|
|
data_list = subsystem->GetDataListResourceID();
|
|
model_id = subsystem->GetGameModelResourceID();
|
|
const Subsystem::GameModel *model = subsystem->GetGameModel();
|
|
Check_Object(model);
|
|
type = model->itemID;
|
|
|
|
return AddAvailableSubsystem(data_list, model_id, type);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::RemoveAvailableSubsystem(int type)
|
|
{
|
|
SubsystemResource *sub_resource = m_subsystemsAvailable.Find(type);
|
|
if(sub_resource)
|
|
{
|
|
if(sub_resource->GetNumberAvailable() >= 1)
|
|
{
|
|
sub_resource->RemoveNumberAvailable();
|
|
}
|
|
else if(sub_resource->GetNumberAvailable() != -1) //Check to see if we are unlimited
|
|
{
|
|
delete sub_resource;
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MechLab::DoesHaveAvailableSubsystem(int type)
|
|
{
|
|
if(m_subsystemsAvailable.Find(type))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::AddSubsystem(void *data[], int count)
|
|
{
|
|
int *sub_type = INTARRAYPARAM(1);
|
|
int *zone = INTARRAYPARAM(2);
|
|
int *error = INTARRAYPARAM(3);
|
|
|
|
AddSubsystemToMech(sub_type, zone, error);
|
|
|
|
return *error;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::AddSubsystemToMech(int *sub_type, int *zone, int *error)
|
|
{
|
|
*error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
SubsystemResource *sub_resource = m_subsystemsAvailable.Find(*sub_type);
|
|
if(sub_resource)
|
|
{
|
|
Check_Object(sub_resource);
|
|
RegisteredClass::ClassID class_id = Entity::GetClassIDFromDataListID(sub_resource->GetDataListID());
|
|
Subsystem::ClassData *class_data =
|
|
Cast_Pointer(Subsystem::ClassData*, RegisteredClass::FindClassData(class_id));
|
|
Check_Object(class_data);
|
|
DynamicMemoryStream stream;
|
|
(*class_data->streamCreate)(sub_resource->GetDataListID(), &stream);
|
|
// MSL 5.03 MechView
|
|
ReplicatorID base_id(CONN4ML->GetNextReplicatorID());
|
|
|
|
Subsystem__CreateMessage *create_message =
|
|
Cast_Pointer(Subsystem__CreateMessage *, stream.GetPointer());
|
|
create_message->locationID = (char)*zone;
|
|
|
|
Subsystem *subsystem =
|
|
Cast_Object(Subsystem *, Entity::CreateEntity(&stream, &base_id));
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
Weapon *weapon = Cast_Object(Weapon *, subsystem);
|
|
MWInternalDamageObject *zone_object = m_workingMech->internalDamageObjects.Find(*zone);
|
|
Check_Object(zone_object);
|
|
Site *site = zone_object->GetNextWeaponSite();
|
|
if(!site)
|
|
{
|
|
*error = 0;
|
|
#if defined(LAB_ONLY)
|
|
PAUSE(("This location does not have a child site!"));
|
|
#endif
|
|
subsystem->Destroy();
|
|
return;
|
|
}
|
|
Site *eject_site = zone_object->GetNextEjectSite();
|
|
if(eject_site)
|
|
{
|
|
weapon->ejectSiteName = eject_site->GetName();
|
|
}
|
|
weapon->siteName = site->GetName();
|
|
}
|
|
|
|
m_workingMech->AddChild(subsystem);
|
|
m_workingMech->SyncMatrices(true);
|
|
|
|
if(subsystem->ConnectSubsystem())
|
|
{
|
|
m_workingMech->AddSubsystem(subsystem);
|
|
RemoveAvailableSubsystem(*sub_type);
|
|
}
|
|
else
|
|
{
|
|
subsystem->Destroy();
|
|
*error = 0;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*error = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::RemoveSubsystem(void *data[], int count)
|
|
{
|
|
int *sub_id = INTARRAYPARAM(1);
|
|
int *zone = INTARRAYPARAM(2);
|
|
|
|
RemoveWeaponFromMech(sub_id, zone);
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::RemoveWeaponFromMech(int *sub_id, int *zone)
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
MWInternalDamageObject *part =
|
|
m_workingMech->internalDamageObjects.Find(*zone);
|
|
if(!part)
|
|
{
|
|
return;
|
|
}
|
|
Check_Object(part);
|
|
|
|
ChainIteratorOf<Subsystem *> iterator(&part->subsystemChain);
|
|
Subsystem *subsystem;
|
|
int weapon_count = 0;
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(weapon_count == *sub_id)
|
|
{
|
|
//we found it!
|
|
subsystem->DisconnectSubsystem();
|
|
m_workingMech->RemoveSubsystem(subsystem);
|
|
AddAvailableSubsystem(subsystem);
|
|
subsystem->Destroy();
|
|
}
|
|
weapon_count ++;
|
|
}
|
|
}
|
|
}
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MechLab::RemoveSubsystemFromMech(int *sub_type, int *zone)
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
MWInternalDamageObject *internal_zone;
|
|
|
|
internal_zone = m_workingMech->internalDamageObjects.Find(*zone);
|
|
Check_Object(internal_zone);
|
|
|
|
Subsystem *subsystem = internal_zone->GetSubsystem(*sub_type);
|
|
if(subsystem)
|
|
{
|
|
//Disconnect, add to our reserves, and delete
|
|
subsystem->DisconnectSubsystem();
|
|
m_workingMech->RemoveSubsystem(subsystem);
|
|
AddAvailableSubsystem(subsystem);
|
|
subsystem->Destroy();
|
|
}
|
|
}
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::SaveMech()
|
|
{
|
|
if(GetWorkingMech() && (m_mechResourceFile.GetCurrent())) //Can't save something in the core!
|
|
{
|
|
Check_Object(m_workingMech);
|
|
Check_Object(m_mechResourceFile.GetCurrent());
|
|
|
|
DynamicMemoryStream stream;
|
|
m_workingMech->SaveMakeMessage(&stream, m_mechResourceFile.GetCurrent());
|
|
|
|
stream.Rewind();
|
|
Stuff::FileDependencies dependancies;
|
|
dependancies.AddDependency("");
|
|
ResourceID mech_id(MechResourceFileID, 1);
|
|
Resource mech_resource(mech_id);
|
|
mech_resource.Save(&stream, &dependancies);
|
|
|
|
|
|
|
|
// mark the mech to detect hex editing
|
|
{
|
|
|
|
Resource crc_resource("icuedbdii", m_mechResourceFile.GetCurrent());
|
|
crc_resource.Save(NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
ResourceID crc_id(MechResourceFileID, 3);
|
|
Resource crc_resource(crc_id);
|
|
|
|
MD5_CTX resource_context;
|
|
GUID resource_hash;
|
|
unsigned char * buff=(unsigned char *) &resource_hash;
|
|
|
|
MD5Init(&resource_context);
|
|
int key = 0xa1252388;
|
|
stream.Rewind();
|
|
MD5Update(&resource_context, (unsigned char *) &key, 4);
|
|
MD5Update(&resource_context, (unsigned char *) stream.GetPointer(), stream.GetBytesRemaining());
|
|
|
|
MD5Final(buff, &resource_context);
|
|
|
|
DynamicMemoryStream hash_stream;
|
|
hash_stream.WriteBytes(&resource_hash,16);
|
|
hash_stream.Rewind();
|
|
|
|
crc_resource.Save(&hash_stream, &dependancies);
|
|
|
|
|
|
// save the mech
|
|
|
|
m_mechResourceFile.GetCurrent()->Save();
|
|
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::AutoAddSubsystem(void *data[], int count)
|
|
{
|
|
int *sub_type = INTARRAYPARAM(1);
|
|
int *error = INTARRAYPARAM(2);
|
|
|
|
*error = 1;
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
SubsystemResource *sub_resource = m_subsystemsAvailable.Find(*sub_type);
|
|
if(sub_resource)
|
|
{
|
|
Check_Object(sub_resource);
|
|
RegisteredClass::ClassID class_id = Entity::GetClassIDFromDataListID(sub_resource->GetDataListID());
|
|
Subsystem::ClassData *class_data =
|
|
Cast_Pointer(Subsystem::ClassData*, RegisteredClass::FindClassData(class_id));
|
|
Check_Object(class_data);
|
|
DynamicMemoryStream stream;
|
|
(*class_data->streamCreate)(sub_resource->GetDataListID(), &stream);
|
|
// MSL 5.03 MechView
|
|
ReplicatorID base_id(CONN4ML->GetNextReplicatorID());
|
|
|
|
Subsystem__CreateMessage *create_message =
|
|
Cast_Pointer(Subsystem__CreateMessage *, stream.GetPointer());
|
|
|
|
|
|
//Ok now we have the subsystem stream...before we create we need to know where
|
|
//we want to put the thing.
|
|
|
|
Resource sub_model_resource(sub_resource->GetGameModelID());
|
|
Verify(sub_model_resource.DoesResourceExist());
|
|
|
|
Subsystem::GameModel *sub_model = Cast_Pointer(
|
|
Subsystem::GameModel *, sub_model_resource.GetPointer());
|
|
|
|
int slots_needed = sub_model->totalSlotsTaken;
|
|
int slot_type = sub_model->slotType;
|
|
|
|
//First check for a slot with the correct type, starting with the arms
|
|
int location = FindInternalLocation(slot_type, slots_needed);
|
|
//Next check for an omni slot starting with the arms
|
|
if(location == -1)
|
|
location = FindInternalLocation(MWInternalDamageObject::OmniSlotType, slots_needed);
|
|
|
|
if(location == -1)
|
|
{
|
|
*error = 0;
|
|
return 0;
|
|
}
|
|
//if no zone then exit!
|
|
create_message->locationID = (char)location;
|
|
|
|
Subsystem *subsystem =
|
|
Cast_Object(Subsystem *, Entity::CreateEntity(&stream, &base_id));
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
Weapon *weapon = Cast_Object(Weapon *, subsystem);
|
|
MWInternalDamageObject *zone_object = m_workingMech->internalDamageObjects.Find(location);
|
|
Check_Object(zone_object);
|
|
Site *site = zone_object->GetNextWeaponSite();
|
|
if(!site)
|
|
{
|
|
*error = 0;
|
|
subsystem->Destroy();
|
|
return 0;
|
|
}
|
|
weapon->siteName = site->GetName();
|
|
}
|
|
|
|
m_workingMech->AddChild(subsystem);
|
|
m_workingMech->SyncMatrices(true);
|
|
if(subsystem->ConnectSubsystem())
|
|
{
|
|
m_workingMech->AddSubsystem(subsystem);
|
|
RemoveAvailableSubsystem(*sub_type);
|
|
}
|
|
else
|
|
{
|
|
subsystem->Destroy();
|
|
*error = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*error = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::RemoveAllSubsystems()
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
ChainIteratorOf<Subsystem *> iterator(&m_workingMech->subsystemsInVehicle);
|
|
Subsystem *subsystem;
|
|
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
//Disconnect, add to our reserves, and delete
|
|
subsystem->DisconnectSubsystem();
|
|
m_workingMech->RemoveSubsystem(subsystem);
|
|
AddAvailableSubsystem(subsystem);
|
|
subsystem->Destroy();
|
|
}
|
|
}
|
|
|
|
//SaveMech();
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::FindInternalLocation(int slot_type, int slots_needed)
|
|
{
|
|
Check_Object(m_workingMech);
|
|
|
|
SortedChainIteratorOf<MWInternalDamageObject *, int> iterator(&m_workingMech->internalDamageObjects);
|
|
MWInternalDamageObject *zone;
|
|
|
|
while((zone = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(zone);
|
|
if(zone->DoesHaveAvailableSlots(slot_type, slots_needed, false, false) > -2)
|
|
{
|
|
return zone->damageZone;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::GetWeaponGroups(void *data[], int count)
|
|
{
|
|
int *type_array = INTARRAYPARAM(1);
|
|
int *id_array = INTARRAYPARAM(2);
|
|
int *loc_array = INTARRAYPARAM(3);
|
|
int *group1_array = INTARRAYPARAM(4);
|
|
int *group2_array = INTARRAYPARAM(5);
|
|
int *group3_array = INTARRAYPARAM(6);
|
|
int *group4_array = INTARRAYPARAM(7);
|
|
int *group5_array = INTARRAYPARAM(8);
|
|
int *group6_array = INTARRAYPARAM(9);
|
|
// MSL 5.06
|
|
int *facing1 = INTARRAYPARAM(10);
|
|
int *facing2 = INTARRAYPARAM(11);
|
|
int *facing3 = INTARRAYPARAM(12);
|
|
int *num_weapons = INTARRAYPARAM(13);
|
|
|
|
#if defined(_ARMOR)
|
|
int array_size = VALUEPARM(14);
|
|
#endif
|
|
|
|
int num = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
ChainIteratorOf<Subsystem *> iterator(&m_workingMech->subsystemsInVehicle);
|
|
Subsystem *subsystem;
|
|
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
Weapon *weapon = Cast_Object(Weapon *, subsystem);
|
|
const Weapon::GameModel *weapon_model = weapon->GetGameModel();
|
|
Verify(num < array_size);
|
|
type_array[num] = weapon_model->itemID;
|
|
id_array[num] = num;
|
|
loc_array[num] = subsystem->internalLocation;
|
|
group1_array[num] = weapon->IsInWeaponGroup1();
|
|
group2_array[num] = weapon->IsInWeaponGroup2();
|
|
group3_array[num] = weapon->IsInWeaponGroup3();
|
|
group4_array[num] = weapon->IsInWeaponGroup4();
|
|
group5_array[num] = weapon->IsInWeaponGroup5();
|
|
group6_array[num] = weapon->IsInWeaponGroup6();
|
|
if (weapon->GetWeaponFacing() == 0)
|
|
{
|
|
facing1[num] = 1;
|
|
facing2[num] = 0;
|
|
facing3[num] = 0;
|
|
}
|
|
if (weapon->GetWeaponFacing() == 1)
|
|
{
|
|
facing1[num] = 0;
|
|
facing2[num] = 1;
|
|
facing3[num] = 0;
|
|
}
|
|
if (weapon->GetWeaponFacing() == 2)
|
|
{
|
|
facing1[num] = 0;
|
|
facing2[num] = 0;
|
|
facing3[num] = 1;
|
|
}
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
*num_weapons = num;
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::SetWeaponGroup(void *data[], int count)
|
|
{
|
|
int *id = INTARRAYPARAM(1);
|
|
int *group = INTARRAYPARAM(2);
|
|
int *facing = INTARRAYPARAM(3);
|
|
|
|
int num = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
ChainIteratorOf<Subsystem *> iterator(&m_workingMech->subsystemsInVehicle);
|
|
Subsystem *subsystem;
|
|
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(num == *id)
|
|
{
|
|
//we found the weapon!
|
|
Weapon *weapon = Cast_Object(Weapon *, subsystem);
|
|
weapon->SetWeaponGroup(*group);
|
|
weapon->SetWeaponFacing(*facing);
|
|
return 1;
|
|
}
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::SetAllWeaponGroups(void *data[], int count)
|
|
{
|
|
|
|
int *group1_array = INTARRAYPARAM(1); //in group 1?
|
|
int *group2_array = INTARRAYPARAM(2);
|
|
int *group3_array = INTARRAYPARAM(3);
|
|
int *group4_array = INTARRAYPARAM(4);
|
|
int *group5_array = INTARRAYPARAM(5);
|
|
int *group6_array = INTARRAYPARAM(6);
|
|
int *facing1 = INTARRAYPARAM(7);
|
|
int *facing2 = INTARRAYPARAM(8);
|
|
int *facing3 = INTARRAYPARAM(9);
|
|
int *array_size = INTARRAYPARAM(10);
|
|
|
|
for(int i=0; i<*array_size; i++)
|
|
{
|
|
Weapon *weapon = FindWeapon(i);
|
|
if(weapon)
|
|
{
|
|
if(group1_array[i] > 0)
|
|
weapon->SetGroup1();
|
|
else
|
|
weapon->ClearGroup1();
|
|
if(group2_array[i] > 0)
|
|
weapon->SetGroup2();
|
|
else
|
|
weapon->ClearGroup2();
|
|
if(group3_array[i] > 0)
|
|
weapon->SetGroup3();
|
|
else
|
|
weapon->ClearGroup3();
|
|
if(group4_array[i] > 0)
|
|
weapon->SetGroup4();
|
|
else
|
|
weapon->ClearGroup4();
|
|
if(group5_array[i] > 0)
|
|
weapon->SetGroup5();
|
|
else
|
|
weapon->ClearGroup5();
|
|
if(group6_array[i] > 0)
|
|
weapon->SetGroup6();
|
|
else
|
|
weapon->ClearGroup6();
|
|
if(facing1[i] == 1)
|
|
{
|
|
weapon->SetWeaponFacing(0);
|
|
}
|
|
else
|
|
if(facing2[i] == 1)
|
|
{
|
|
weapon->SetWeaponFacing(1);
|
|
}
|
|
else
|
|
if(facing3[i] == 1)
|
|
{
|
|
weapon->SetWeaponFacing(2);
|
|
}
|
|
}
|
|
}
|
|
// SaveMech();
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Weapon*
|
|
MechLab::FindWeapon(int id)
|
|
{
|
|
int num = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
ChainIteratorOf<Subsystem *> iterator(&m_workingMech->subsystemsInVehicle);
|
|
Subsystem *subsystem;
|
|
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(num == id)
|
|
{
|
|
return Cast_Object(Weapon *, subsystem);
|
|
}
|
|
num ++;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::ClearWeaponGroup(void *data[], int count)
|
|
{
|
|
int *id = INTARRAYPARAM(1);
|
|
int *group = INTARRAYPARAM(2);
|
|
|
|
int num = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
Check_Object(m_workingMech);
|
|
ChainIteratorOf<Subsystem *> iterator(&m_workingMech->subsystemsInVehicle);
|
|
Subsystem *subsystem;
|
|
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(num == *id)
|
|
{
|
|
//we found the weapon!
|
|
Weapon *weapon = Cast_Object(Weapon *, subsystem);
|
|
weapon->ClearWeaponGroup(*group);
|
|
return 1;
|
|
}
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetDummyData(void *data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
char **name_array = STRARRAYPARAM(1);
|
|
int array_size = VALUEPARM(2);
|
|
|
|
for(int i=0; i<array_size; i++)
|
|
{
|
|
FREEANDNULL(name_array[i]);
|
|
name_array[i] = (char *)gos_Malloc(128);
|
|
MString mech_name = "I Love Mech 4";
|
|
Str_Copy(
|
|
name_array[i],
|
|
(const char *)mech_name,
|
|
mech_name.GetLength() + 1
|
|
);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::Exit()
|
|
{
|
|
s_MechCamera->SetScene(NULL);
|
|
DestroyWorkingEntity();
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::Restore()
|
|
{
|
|
if(GetWorkingMech() && (m_mechResourceFile.GetCurrent()))
|
|
{
|
|
//Ok so we need to just redo a select and such.
|
|
m_workingMech->Destroy();
|
|
m_workingMech = NULL;
|
|
|
|
ResourceID mech_id(MechResourceFileID, 1);
|
|
Resource mech_resource(mech_id);
|
|
Verify(mech_resource.DoesResourceExist());
|
|
|
|
// MSL 5.03 MechView
|
|
ReplicatorID base_id(CONN4ML->GetNextReplicatorID());
|
|
|
|
Entity *entity;
|
|
entity = Entity::CreateEntity(&mech_resource, &base_id);
|
|
|
|
Check_Object(entity);
|
|
SetUpWorkingMech(entity);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::DeleteMech()
|
|
{
|
|
if(GetWorkingMech() && (m_mechResourceFile.GetCurrent()))
|
|
{
|
|
s_MechCamera->SetScene(NULL);
|
|
DestroyWorkingEntity();
|
|
|
|
MString resource_file_name = m_mechResourceFile.GetCurrent()->GetFileName();
|
|
|
|
delete m_mechResourceFile.GetCurrent();
|
|
|
|
Verify(gos_DoesFileExist(resource_file_name));
|
|
gos_DeleteFile(resource_file_name);
|
|
|
|
m_mechLabCount = GetMechCount();
|
|
if(m_mechLabCount == 0)
|
|
{
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
if(!m_isCampaign)
|
|
{
|
|
app->m_lastMechID = 0;
|
|
app->m_lastMechName = "";
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetEngineSpeed(void *data[], int count)
|
|
{
|
|
Scalar *speed = SCALARARRAYPARAM(1);
|
|
Scalar *tonnage = SCALARARRAYPARAM(2);
|
|
*speed = 0.0f;
|
|
if(GetWorkingMech())
|
|
{
|
|
Engine *engine = m_workingMech->GetEngine();
|
|
*speed = engine->GetMaxSpeedForDisplay();
|
|
const Engine::GameModel *engine_model = engine->GetGameModel();
|
|
*tonnage = (engine->GetUpgrades() + 1) * engine_model->m_tonsPerUpgrade;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::UpgradeEngine()
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
m_workingMech->GetEngine()->Upgrade();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::DegradeEngine()
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
m_workingMech->GetEngine()->Degrade();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetHeatSinkCount(void *data[], int count)
|
|
{
|
|
int *num_sinks = INTARRAYPARAM(1);
|
|
*num_sinks = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
*num_sinks = m_workingMech->m_numHeatSinks;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::AddHeatSink()
|
|
{
|
|
int sub_id = Sub_HeatSink;
|
|
int zone = MLCenterTorsoZone;
|
|
int error = 1;
|
|
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
return error;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::RemoveHeatSink()
|
|
{
|
|
int sub_id = Sub_HeatSink;
|
|
int zone = MLCenterTorsoZone;
|
|
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetJumpJets(void *data[], int count)
|
|
{
|
|
int *has_jump = INTARRAYPARAM(1);
|
|
int *can_have_jump = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_jump = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_jump = mech_model->m_canLoadJumpJets;
|
|
*tons = mech_model->m_jumpJetTonnage;
|
|
|
|
if(m_workingMech->GetJumpJet())
|
|
{
|
|
*has_jump = 1;
|
|
}
|
|
else
|
|
{
|
|
*has_jump = 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetJumpJets(void *data[], int count)
|
|
{
|
|
int sub_id = Sub_JumpJet;
|
|
int zone = MLCenterTorsoZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->GetJumpJet())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetECM(void *data[], int count)
|
|
{
|
|
int *has_ecm = INTARRAYPARAM(1);
|
|
int *can_have_ecm = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_ecm = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_ecm = mech_model->m_canLoadECM;
|
|
*tons = 1.0f;
|
|
*has_ecm = m_workingMech->DoesHaveECM();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetECM(void *data[], int count)
|
|
{
|
|
int sub_id = Sub_ECM;
|
|
int zone = MLHeadZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->DoesHaveECM())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetBeagle(void *data[], int count)
|
|
{
|
|
int *has_beagle = INTARRAYPARAM(1);
|
|
int *can_have_beagle = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_beagle = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_beagle = mech_model->m_canLoadBeagle;
|
|
*tons = 1.0f;
|
|
*has_beagle = m_workingMech->DoesHaveBeagle();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetBeagle(void *data[], int count)
|
|
{
|
|
int sub_id = Sub_Beagle;
|
|
int zone = MLHeadZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->DoesHaveBeagle())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetAMS(void *data[], int count)
|
|
{
|
|
int *has_ams = INTARRAYPARAM(1);
|
|
int *can_have_ams = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_ams = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_ams = mech_model->m_canLoadAMS;
|
|
*tons = 1.5f;
|
|
*has_ams = 0;
|
|
//Here we need to do a check on the ams that we have
|
|
if(m_workingMech->GetAMS())
|
|
{
|
|
const AMS::GameModel *ams_model = m_workingMech->GetAMS()->GetGameModel();
|
|
Check_Object(ams_model);
|
|
|
|
*tons = 1.5;
|
|
|
|
if(ams_model->itemID == Sub_AMS)
|
|
*has_ams = 1;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetAMS()
|
|
{
|
|
int sub_id = Sub_AMS;
|
|
int zone = MLCenterTorsoZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->GetAMS())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetLAMS(void *data[], int count)
|
|
{
|
|
int *has_ams = INTARRAYPARAM(1);
|
|
int *can_have_ams = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_ams = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_ams = mech_model->m_canLoadLAMS;
|
|
*tons = 1.5f;
|
|
*has_ams = 0;
|
|
//Here we need to do a check on the ams that we have
|
|
if(m_workingMech->GetAMS())
|
|
{
|
|
const AMS::GameModel *ams_model = m_workingMech->GetAMS()->GetGameModel();
|
|
Check_Object(ams_model);
|
|
|
|
*tons = 1.5f;
|
|
|
|
if(ams_model->itemID == Sub_LAMS)
|
|
*has_ams = 1;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetLAMS()
|
|
{
|
|
int sub_id = Sub_LAMS;
|
|
int zone = MLCenterTorsoZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->GetAMS())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
// MSL 5.02 SubSystems
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetIFF_Jammer(void *data[], int count)
|
|
{
|
|
int *has_IFF_Jammer = INTARRAYPARAM(1);
|
|
int *can_have_IFF_Jammer = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_IFF_Jammer = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_IFF_Jammer = mech_model->m_canLoadIFF_Jammer;
|
|
*has_IFF_Jammer = 0;
|
|
*tons = 1.0f;
|
|
|
|
if(m_workingMech->GetIFF_Jammer())
|
|
{
|
|
const IFF_Jammer::GameModel *iff_jammer_model = m_workingMech->GetIFF_Jammer()->GetGameModel();
|
|
Check_Object(iff_jammer_model);
|
|
|
|
if(iff_jammer_model->itemID == Sub_IFF_Jammer)
|
|
*has_IFF_Jammer = 1;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetIFF_Jammer()
|
|
{
|
|
int sub_id = Sub_IFF_Jammer;
|
|
int zone = MLHeadZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->GetIFF_Jammer())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
|
|
// MSL 5.02 SubSystems
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetAdvancedGyro(void *data[], int count)
|
|
{
|
|
int *has_AdvancedGyro = INTARRAYPARAM(1);
|
|
int *can_have_AdvancedGyro = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_AdvancedGyro = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_AdvancedGyro = mech_model->m_canLoadAdvancedGyro;
|
|
*has_AdvancedGyro = 0;
|
|
*tons = mech_model->m_advancedGyroTonnage;
|
|
|
|
if(m_workingMech->GetAdvancedGyro())
|
|
{
|
|
const AdvancedGyro::GameModel *advanced_gyro_model = m_workingMech->GetAdvancedGyro()->GetGameModel();
|
|
Check_Object(advanced_gyro_model);
|
|
|
|
if(advanced_gyro_model->itemID == Sub_AdvancedGyro)
|
|
*has_AdvancedGyro = 1;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetAdvancedGyro()
|
|
{
|
|
int sub_id = Sub_AdvancedGyro;
|
|
int zone = MLHeadZone;
|
|
int error = 1;
|
|
|
|
if(GetWorkingMech())
|
|
{
|
|
if(m_workingMech->GetAdvancedGyro())
|
|
{
|
|
RemoveSubsystemFromMech(&sub_id, &zone);
|
|
}
|
|
else
|
|
{
|
|
AddSubsystemToMech(&sub_id, &zone, &error);
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetLightAmp(void *data[], int count)
|
|
{
|
|
int *has_light = INTARRAYPARAM(1);
|
|
int *can_have_light = INTARRAYPARAM(2);
|
|
Scalar *tons = SCALARARRAYPARAM(3);
|
|
|
|
*has_light = 0;
|
|
if(GetWorkingMech())
|
|
{
|
|
const Mech::GameModel *mech_model = m_workingMech->GetGameModel();
|
|
Check_Object(mech_model);
|
|
|
|
*can_have_light = mech_model->m_canLoadLightAmp;
|
|
*tons = 1.0f;
|
|
*has_light = m_workingMech->DoesHaveLightAmp();
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetLightAmp()
|
|
{
|
|
if(GetWorkingMech())
|
|
{
|
|
m_workingMech->ToggleLightAmpLoad();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetWeaponAmmo(void *data[], int count)
|
|
{
|
|
int *zone_id = INTARRAYPARAM(1);
|
|
int *id = INTARRAYPARAM(2);
|
|
int *num_packs = INTARRAYPARAM(3);
|
|
int *num_per_pack = INTARRAYPARAM(4);
|
|
|
|
MWInternalDamageObject *part =
|
|
m_workingMech->internalDamageObjects.Find(*zone_id);
|
|
|
|
if(!part)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
Check_Object(part);
|
|
|
|
ChainIteratorOf<Subsystem *> iterator(&part->subsystemChain);
|
|
Subsystem *subsystem;
|
|
int weapon_count = 0;
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(weapon_count == *id)
|
|
{
|
|
//we found it!
|
|
Weapon *weapon;
|
|
weapon = Cast_Object(Weapon *, subsystem);
|
|
*num_packs = weapon->GetAmmoPacks();
|
|
*num_per_pack = weapon->GetAmmoPerPack();
|
|
|
|
return 1;
|
|
}
|
|
weapon_count ++;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::AddWeaponAmmo(void *data[], int count)
|
|
{
|
|
int *zone_id = INTARRAYPARAM(1);
|
|
int *id = INTARRAYPARAM(2);
|
|
|
|
MWInternalDamageObject *part =
|
|
m_workingMech->internalDamageObjects.Find(*zone_id);
|
|
|
|
if(!part)
|
|
{
|
|
return -1;
|
|
}
|
|
Check_Object(part);
|
|
|
|
ChainIteratorOf<Subsystem *> iterator(&part->subsystemChain);
|
|
Subsystem *subsystem;
|
|
int weapon_count = 0;
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(weapon_count == *id)
|
|
{
|
|
//we found it!
|
|
Weapon *weapon;
|
|
weapon = Cast_Object(Weapon *, subsystem);
|
|
if(weapon->AddAmmoPack())
|
|
return 1;
|
|
return -1;
|
|
}
|
|
weapon_count ++;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::RemoveWeaponAmmo(void *data[], int count)
|
|
{
|
|
int *zone_id = INTARRAYPARAM(1);
|
|
int *id = INTARRAYPARAM(2);
|
|
|
|
MWInternalDamageObject *part =
|
|
m_workingMech->internalDamageObjects.Find(*zone_id);
|
|
|
|
if(!part)
|
|
{
|
|
return -1;
|
|
}
|
|
Check_Object(part);
|
|
|
|
ChainIteratorOf<Subsystem *> iterator(&part->subsystemChain);
|
|
Subsystem *subsystem;
|
|
int weapon_count = 0;
|
|
while((subsystem = iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(subsystem);
|
|
|
|
if(subsystem->IsDerivedFrom(Weapon::DefaultData))
|
|
{
|
|
if(weapon_count == *id)
|
|
{
|
|
//we found it!
|
|
Weapon *weapon;
|
|
weapon = Cast_Object(Weapon *, subsystem);
|
|
if(weapon->RemoveAmmoPack())
|
|
return 1;
|
|
|
|
return -1;
|
|
}
|
|
weapon_count ++;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetSkinListCount(void *data[], int count)
|
|
{
|
|
int *skin_count = INTARRAYPARAM(1);
|
|
|
|
Check_Object(MWApplication::GetInstance()->m_skinsTable);
|
|
*skin_count = MWApplication::GetInstance()->m_skinsTable->GetTableSize();
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetSkinList(void *data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
char **name_array = STRARRAYPARAM(1);
|
|
int *current_skin = INTARRAYPARAM(2);
|
|
|
|
int i = 0;
|
|
|
|
MWTable::TableIterator *skin_iterator;
|
|
MWTable *skin_table = MWApplication::GetInstance()->m_skinsTable;
|
|
Check_Object(skin_table);
|
|
|
|
skin_iterator = skin_table->MakeTableIterator();
|
|
MWTableEntry *skin_entry;
|
|
|
|
//This is hardcoded for the .dll in missionlang
|
|
int skin_count = IDS_FIRSTSKIN + 1;
|
|
while((skin_entry = skin_iterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(skin_entry);
|
|
|
|
FREEANDNULL(name_array[i]);
|
|
name_array[i] = (char *)gos_Malloc(128);
|
|
MString skin_name = MWApplication::GetInstance()->GetLocString(skin_count);
|
|
Str_Copy(
|
|
name_array[i],
|
|
(const char *)skin_name,
|
|
skin_name.GetLength() + 1
|
|
);
|
|
skin_count ++;
|
|
i++;
|
|
}
|
|
|
|
*current_skin = 0;
|
|
if(m_workingMech)
|
|
{
|
|
char skin_string[2];
|
|
*skin_string = m_workingMech->GetSkinPrefix();
|
|
skin_string[1] = 0;
|
|
*current_skin = skin_table->FindIndexFromDataString(skin_string);
|
|
}
|
|
|
|
Verify(*current_skin >= 0);
|
|
Min_Clamp(*current_skin, 0);
|
|
|
|
delete skin_iterator;
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::SetMechSkin(void *data[], int count)
|
|
{
|
|
int *skin_name = INTARRAYPARAM(1);
|
|
Check_Object(MWApplication::GetInstance()->m_skinsTable);
|
|
|
|
char skin_prefix;
|
|
|
|
if(m_workingMech)
|
|
{
|
|
if (skin_name) {
|
|
MWTableEntry *skin_plug = MWApplication::GetInstance()->m_skinsTable->GetNthItem(*skin_name);
|
|
Check_Object(skin_plug);
|
|
skin_prefix = *skin_plug->GetData();
|
|
} else {
|
|
gosASSERT(count == 3);
|
|
skin_prefix = *(int*)data[2];
|
|
}
|
|
// for campaign skin - jcem
|
|
if (g_bCOOP && m_isCampaign) {
|
|
MW4Shell::Instance->m_skinPrefix = skin_prefix;
|
|
//MWApplication::GetInstance()->servedConnectionData[CONN4ML->GetID()].pilotSkins = skin_prefix;
|
|
}
|
|
// for campaign skin - jcem
|
|
|
|
m_workingMech->SetSkinPrefix(skin_prefix);
|
|
s_MechCamera->SetScene(NULL);
|
|
|
|
Check_Object(VideoRenderer::Instance);
|
|
ChainIteratorOf<Entity*> children(&m_workingMech->childEntityChain);
|
|
Entity *child_entity;
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
if(child_entity->IsDerivedFrom(MWMover::DefaultData))
|
|
{
|
|
MWMover *mover = Cast_Object(MWMover *, child_entity);
|
|
MakeMoverUnInteresting(mover);
|
|
}
|
|
}
|
|
|
|
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
delete MidLevelRenderer::MLRTexturePool::Instance;
|
|
|
|
ResourceImagePool *pool = new ResourceImagePool;
|
|
Check_Object(pool);
|
|
MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
gos_PopCurrentHeap();
|
|
|
|
s_MechCamera->GetClipper()->SetTexturePoolInSorter(MidLevelRenderer::MLRTexturePool::Instance);
|
|
|
|
extern char g_SkinSet;
|
|
g_SkinSet = m_workingMech->GetSkinPrefix();
|
|
extern int g_PilotDecal;
|
|
g_PilotDecal = m_workingMech->GetPilotDecal();
|
|
extern int g_TeamDecal;
|
|
g_TeamDecal = m_workingMech->GetTeamDecal();
|
|
|
|
Check_Object(VideoRenderer::Instance);
|
|
children.First();
|
|
while ((child_entity = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child_entity);
|
|
if(child_entity->IsDerivedFrom(MWMover::DefaultData))
|
|
{
|
|
MWMover *mover = Cast_Object(MWMover *, child_entity);
|
|
MakeMoverInteresting(mover);
|
|
}
|
|
}
|
|
ElementRenderer::Element *mech_element = m_workingMech->GetElement();
|
|
s_MechCamera->SetScene(mech_element);
|
|
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int MechLab::GetBaseMechName(void* data[], int count)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
const char *full_name = STRPARM(1);
|
|
char **base_name = (char **)STRARRAYPARAM(2);
|
|
char tmp_base_name[128] = "";
|
|
|
|
if (full_name == NULL)
|
|
return -1;
|
|
|
|
MWTable::TableIterator *mech_iterator;
|
|
Check_Object(MWApplication::GetInstance()->m_mechTable);
|
|
|
|
mech_iterator = MWApplication::GetInstance()->m_mechTable->MakeTableIterator();
|
|
MWTableEntry *mech_entry;
|
|
while((mech_entry = mech_iterator->ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(mech_entry);
|
|
|
|
if (strnicmp(full_name, (const char *)mech_entry->GetEntryName(),
|
|
mech_entry->GetEntryName().GetLength()) == 0 &&
|
|
mech_entry->GetEntryName().GetLength()>strlen(tmp_base_name)) {
|
|
Str_Copy(
|
|
tmp_base_name,
|
|
(const char *)mech_entry->GetEntryName(),
|
|
mech_entry->GetEntryName().GetLength() + 1);
|
|
|
|
}
|
|
}
|
|
|
|
delete mech_iterator;
|
|
|
|
if (strlen(tmp_base_name)>0) {
|
|
FREEANDNULL(*base_name);
|
|
*base_name = (char *)gos_Malloc(128);
|
|
Str_Copy(
|
|
*base_name,
|
|
tmp_base_name,
|
|
strlen(tmp_base_name) + 1);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
MechLab::Rename(void* data[], int count, const char *path)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
const char *chassis_name = STRPARM(1);
|
|
const char *mech_name = STRPARM(2);
|
|
int overwrite = INTPARM(3);
|
|
|
|
if(!MWApplication::ValidateName((char*)mech_name, true))
|
|
return -1;
|
|
|
|
if(GetWorkingMech() && (m_mechResourceFile.GetCurrent()))
|
|
{
|
|
|
|
MString path_name = path;
|
|
path_name += chassis_name;
|
|
path_name += " ";
|
|
path_name += mech_name;
|
|
MString res_name = path_name;
|
|
m_workingMechName = res_name;
|
|
res_name += ".mw4";
|
|
|
|
MString resource_file_name = m_mechResourceFile.GetCurrent()->GetFileName();
|
|
|
|
// Don't do anything if new name is the same as old name
|
|
if (res_name == resource_file_name)
|
|
return 1;
|
|
|
|
// Check if new name is already being used
|
|
if (stricmp(res_name, resource_file_name) && gos_DoesFileExist(res_name) && !overwrite)
|
|
return E_MechAlreadyExists;
|
|
|
|
m_mechResourceFile.GetCurrent()->Save();
|
|
delete m_mechResourceFile.GetCurrent();
|
|
m_mechResourceFile.Remove();
|
|
|
|
if(!MWApplication::ValidatePath(res_name, true))
|
|
return -1;
|
|
|
|
Verify(gos_DoesFileExist(resource_file_name));
|
|
|
|
// If they are the same file name except for cases
|
|
if (stricmp(res_name, resource_file_name) == 0) {
|
|
|
|
DWORD size;
|
|
BYTE * bitmap;
|
|
gos_GetFile(resource_file_name, &bitmap, &size);
|
|
gos_DeleteFile(resource_file_name);
|
|
HGOSFILE fHandle;
|
|
gos_OpenFile(&fHandle, res_name, READWRITE);
|
|
if (fHandle) {
|
|
gos_WriteFile(fHandle, bitmap, size);
|
|
gos_CloseFile(fHandle);
|
|
}
|
|
else {
|
|
}
|
|
gos_Free(bitmap);
|
|
}
|
|
|
|
else {
|
|
if(gos_DoesFileExist(res_name))
|
|
gos_DeleteFile(res_name);
|
|
|
|
gos_RenameFile(resource_file_name, res_name);
|
|
}
|
|
|
|
Check_Object(ResourceManager::Instance);
|
|
ResourceFile *res_file;
|
|
res_file = ResourceManager::Instance->OpenResourceFile(
|
|
res_name,
|
|
NULL,
|
|
MechResourceFileID,
|
|
VER_CONTENTVERSION,
|
|
false,
|
|
false
|
|
);
|
|
Check_Object(res_file);
|
|
m_mechResourceFile.Add(res_file);
|
|
|
|
m_mechLabCount = GetMechCount();
|
|
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
app->memoryDiffKiller.Init();
|
|
|
|
if(!m_isCampaign)
|
|
{
|
|
app->m_lastMechID = -1;
|
|
app->m_lastMechName = MString(chassis_name)+" "+mech_name;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
Mech* MechLab::GetWorkingMech() const
|
|
{
|
|
return m_workingMech;
|
|
}
|
|
|
|
Entity* MechLab::GetWorkingEntity() const
|
|
{
|
|
return m_workingEntity;
|
|
}
|
|
|
|
void MechLab::DestroyWorkingEntity()
|
|
{
|
|
if (m_workingEntity) {
|
|
gosASSERT(!m_workingMech || (m_workingEntity == m_workingMech));
|
|
|
|
m_workingEntity->Destroy();
|
|
|
|
m_workingMech = NULL;
|
|
m_workingEntity = NULL;
|
|
} else {
|
|
gosASSERT(!m_workingMech);
|
|
}
|
|
}
|
|
|