Files
firestorm/Gameleap/code/mw4/Code/MW4/MechLab.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

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);
}
}