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.
634 lines
19 KiB
C++
634 lines
19 KiB
C++
//===========================================================================//
|
|
// File: Armor.cpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 12/19/01 MSL Added StandardArmor //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1998, Fasa Interactive //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "MW4Headers.hpp"
|
|
|
|
#include "Armor.hpp"
|
|
#include "Mech.hpp"
|
|
#include "MWDamageObject.hpp"
|
|
#include "SubsystemClassData.hpp"
|
|
|
|
#include <Adept\DamageObject.hpp>
|
|
|
|
//#############################################################################
|
|
//############################### Armor #################################
|
|
//#############################################################################
|
|
|
|
Armor::ClassData*
|
|
Armor::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Armor::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
ArmorClassID,
|
|
"MechWarrior4::Armor",
|
|
Subsystem::DefaultData,
|
|
0, NULL,
|
|
(Entity::Factory)Make,
|
|
(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
|
|
ExecutionStateEngine::DefaultData,
|
|
(Entity::GameModel::Factory)GameModel::ConstructGameModel,
|
|
NULL,
|
|
(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
|
|
(Entity::GameModel::ModelWrite)GameModel::WriteToText,
|
|
(Entity::GameModel::ModelSave)GameModel::SaveGameModel,
|
|
(Subsystem::StreamCreate) CreateStream
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
ArmDistributive,
|
|
m_armDistributive,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
LegDistributive,
|
|
m_legDistributive,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
SideFrontDistributive,
|
|
m_sideFrontDistributive,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
CenterFrontDistributive,
|
|
m_centerFrontDistributive,
|
|
Scalar
|
|
);
|
|
|
|
DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
CenterRearDistributive,
|
|
m_centerRearDistributive,
|
|
Scalar
|
|
);
|
|
// MSL 5.00 Armor
|
|
CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
PointsPerStandardTon,
|
|
m_pointsPerStandardTon,
|
|
int,
|
|
IntClassID
|
|
);
|
|
|
|
|
|
CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
PointsPerFerroTon,
|
|
m_pointsPerFerroTon,
|
|
int,
|
|
IntClassID
|
|
);
|
|
|
|
CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
PointsPerReflectiveTon,
|
|
m_pointsPerReflectiveTon,
|
|
int,
|
|
IntClassID
|
|
);
|
|
|
|
CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
PointsPerReactiveTon,
|
|
m_pointsPerReactiveTon,
|
|
int,
|
|
IntClassID
|
|
);
|
|
|
|
CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(
|
|
Armor__GameModel,
|
|
PointsPerSolarianTon,
|
|
m_pointsPerSolarianTon,
|
|
int,
|
|
IntClassID
|
|
);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Armor::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Armor*
|
|
Armor::Make(
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
)
|
|
{
|
|
Check_Object(message);
|
|
gos_PushCurrentHeap(Heap);
|
|
Armor *new_entity =
|
|
new Armor(DefaultData, message, base_id, NULL);
|
|
gos_PopCurrentHeap();
|
|
Check_Object(new_entity);
|
|
return new_entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Replicator::CreateMessage*
|
|
Armor::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
|
|
stream->AllocateBytes(sizeof(CreateMessage));
|
|
Subsystem::SaveMakeMessage(stream, res_file);
|
|
CreateMessage *message =
|
|
Cast_Pointer(CreateMessage*, stream->GetPointer());
|
|
message->messageLength = sizeof(*message);
|
|
|
|
message->m_leftLegArmor = m_armorZoneValues[DamageObject::LeftLegArmorZone];
|
|
message->m_rightLegArmor = m_armorZoneValues[DamageObject::RightLegArmorZone];
|
|
message->m_leftArmArmor = m_armorZoneValues[DamageObject::LeftArmArmorZone];
|
|
message->m_rightArmArmor = m_armorZoneValues[DamageObject::RightArmArmorZone];
|
|
message->m_leftFrontTorsoArmor = m_armorZoneValues[DamageObject::LeftTorsoArmorZone];
|
|
message->m_rightFrontTorsoArmor = m_armorZoneValues[DamageObject::RightTorsoArmorZone];
|
|
message->m_centerFrontTorsoArmor = m_armorZoneValues[DamageObject::CenterTorsoArmorZone];
|
|
message->m_centerRearTorsoArmor = m_armorZoneValues[DamageObject::CenterRearTorsoArmorZone];
|
|
message->m_headArmor = m_armorZoneValues[DamageObject::HeadArmorZone];
|
|
|
|
message->m_armorType = m_armorType;
|
|
message ->m_internalType = m_internalType;
|
|
|
|
return message;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Armor::Armor(
|
|
ClassData *class_data,
|
|
CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
):
|
|
Subsystem(class_data, message, base_id, element)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(message);
|
|
|
|
//Set up the armor Zone array
|
|
m_totalArmor = 0;
|
|
m_armorZoneValues[DamageObject::LeftLegArmorZone] = message->m_leftLegArmor;
|
|
m_totalArmor += message->m_leftLegArmor;
|
|
m_armorZoneValues[DamageObject::RightLegArmorZone] = message->m_rightLegArmor;
|
|
m_totalArmor += message->m_rightLegArmor;
|
|
m_armorZoneValues[DamageObject::LeftArmArmorZone] = message->m_leftArmArmor;
|
|
m_totalArmor += message->m_leftArmArmor;
|
|
m_armorZoneValues[DamageObject::RightArmArmorZone] = message->m_rightArmArmor;
|
|
m_totalArmor += message->m_rightArmArmor;
|
|
m_armorZoneValues[DamageObject::RightTorsoArmorZone] = message->m_rightFrontTorsoArmor;
|
|
m_totalArmor += message->m_rightFrontTorsoArmor;
|
|
m_armorZoneValues[DamageObject::LeftTorsoArmorZone] = message->m_leftFrontTorsoArmor;
|
|
m_totalArmor += message->m_leftFrontTorsoArmor;
|
|
m_armorZoneValues[DamageObject::CenterTorsoArmorZone] = message->m_centerFrontTorsoArmor;
|
|
m_totalArmor += message->m_centerFrontTorsoArmor;
|
|
m_armorZoneValues[DamageObject::CenterRearTorsoArmorZone] = message->m_centerRearTorsoArmor;
|
|
m_totalArmor += message->m_centerRearTorsoArmor;
|
|
m_armorZoneValues[DamageObject::HeadArmorZone] = message->m_headArmor;
|
|
m_totalArmor += message->m_headArmor;
|
|
|
|
m_armorType = message->m_armorType,
|
|
m_internalType = message->m_internalType;
|
|
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
m_armorMultiplier = 1;
|
|
switch(m_armorType)
|
|
{
|
|
// MSL 5.00 Armor
|
|
case StandardArmor:
|
|
m_armorMultiplier = model->m_pointsPerStandardTon;
|
|
break;
|
|
case FerroFiberusArmor:
|
|
m_armorMultiplier = model->m_pointsPerFerroTon;
|
|
break;
|
|
case ReactiveArmor:
|
|
m_armorMultiplier = model->m_pointsPerReactiveTon;
|
|
break;
|
|
case ReflectiveArmor:
|
|
m_armorMultiplier = model->m_pointsPerReflectiveTon;
|
|
break;
|
|
case SolarianArmor:
|
|
m_armorMultiplier = model->m_pointsPerSolarianTon;
|
|
break;
|
|
}
|
|
|
|
m_totalTonage =(m_totalArmor / m_armorMultiplier);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Armor::~Armor()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
Armor::ConnectSubsystem()
|
|
{
|
|
InitializeDamageObjectsWithArmor();
|
|
GetParentVehicle()->AddTonage(m_totalTonage);
|
|
|
|
//Must call the inherited virtual function!!!!
|
|
return Subsystem::ConnectSubsystem();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Armor::InitializeDamageObjectsWithArmor()
|
|
{
|
|
Check_Object(this);
|
|
|
|
MWObject *parent = GetParentVehicle();
|
|
Check_Object(parent);
|
|
|
|
DamageObject *damage_object;
|
|
MWInternalDamageObject *internal_object;
|
|
SortedChainIteratorOf<DamageObject *, int> damage_iterator(&parent->damageObjects);
|
|
SortedChainIteratorOf<MWInternalDamageObject *, int> internal_iterator(&parent->internalDamageObjects);
|
|
|
|
//
|
|
//---------------------------------------------------------------
|
|
//Setup the Damage Objects with Armor Type and their distribution
|
|
//---------------------------------------------------------------
|
|
//
|
|
for(int i=DamageObject::LeftLegArmorZone; i<=DamageObject::HeadArmorZone; i++)
|
|
{
|
|
damage_object = parent->damageObjects.Find(i);
|
|
if(damage_object)
|
|
{
|
|
damage_object->SetType(m_armorType);
|
|
damage_object->AppendArmor(m_armorZoneValues[i]);
|
|
}
|
|
#if defined(LAB_ONLY)
|
|
else
|
|
{
|
|
PAUSE(("This mech is missing a %s zone!", DamageObject::ArmorZoneAsciiToText(i)));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//
|
|
//------------------------------------
|
|
//Setup Internal Zones with their type
|
|
//------------------------------------
|
|
//
|
|
while((internal_object = internal_iterator.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(internal_object);
|
|
internal_object->SetType(m_internalType);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
Armor::ArmorTypeTextToAscii(const char *armor_type_string)
|
|
{
|
|
// MSL 5.00 Armor
|
|
if(!_stricmp(armor_type_string, "Standard"))
|
|
return StandardArmor;
|
|
if(!_stricmp(armor_type_string, "FerroFiberus"))
|
|
return FerroFiberusArmor;
|
|
if(!_stricmp(armor_type_string, "Reactive"))
|
|
return ReactiveArmor;
|
|
if(!_stricmp(armor_type_string, "Reflective"))
|
|
return ReflectiveArmor;
|
|
if(!_stricmp(armor_type_string, "Solarian"))
|
|
return SolarianArmor;
|
|
|
|
PAUSE(("That is a bad Armor String: %s", armor_type_string));
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
const char*
|
|
Armor::ArmorTypeAsciiToText(int armor_type)
|
|
{
|
|
switch(armor_type)
|
|
{
|
|
// MSL 5.00 Armor
|
|
case StandardArmor:
|
|
return "Standard";
|
|
case FerroFiberusArmor:
|
|
return "FerroFiberus";
|
|
case ReactiveArmor:
|
|
return "Reactive";
|
|
case ReflectiveArmor:
|
|
return "Reflective";
|
|
case SolarianArmor:
|
|
return "Solarian";
|
|
}
|
|
|
|
PAUSE(("That is a bad armor value"));
|
|
return "Bad";
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
Armor::InternalTypeTextToAscii(const char *internal_type_string)
|
|
{
|
|
if(!_stricmp(internal_type_string, "Standard"))
|
|
return StandardInternal;
|
|
if(!_stricmp(internal_type_string, "EndoSteel"))
|
|
return EndoSteelInternal;
|
|
|
|
PAUSE(("That is a bad Internal String: %s", internal_type_string));
|
|
return -1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
const char*
|
|
Armor::InternalTypeAsciiToText(int internal_type)
|
|
{
|
|
switch(internal_type)
|
|
{
|
|
case StandardInternal:
|
|
return "Statndard";
|
|
case EndoSteelInternal:
|
|
return "EndoSteel";
|
|
}
|
|
|
|
PAUSE(("That is a bad armor value"));
|
|
return "Bad";
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
Armor::ApplyDistributiveArmor()
|
|
{
|
|
Check_Object(this);
|
|
|
|
//Ok so the easiest way to do this is for us...to just clear all the armor and then
|
|
//run through them and distribute it all.
|
|
Scalar total_armor = 0.0f;
|
|
Scalar left_over_armor = 0.0f;
|
|
Scalar armor_used = 0.0f; //use for armoring purposes (code armor that is)
|
|
|
|
for(int i=DamageObject::LeftLegArmorZone; i<=DamageObject::HeadArmorZone; i++)
|
|
{
|
|
total_armor += m_armorZoneValues[i];
|
|
m_armorZoneValues[i] = 0.0f;
|
|
}
|
|
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
//We need to make the distribution array so we can easily run everything else through a loop
|
|
Scalar armor_dist[DamageObject::HeadArmorZone];
|
|
armor_dist[DamageObject::LeftLegArmorZone] = model->m_legDistributive;
|
|
armor_dist[DamageObject::RightLegArmorZone] = model->m_legDistributive;
|
|
armor_dist[DamageObject::LeftArmArmorZone] = model->m_armDistributive;
|
|
armor_dist[DamageObject::RightArmArmorZone] = model->m_armDistributive;
|
|
armor_dist[DamageObject::RightTorsoArmorZone] = model->m_sideFrontDistributive;
|
|
armor_dist[DamageObject::LeftTorsoArmorZone] = model->m_sideFrontDistributive;
|
|
armor_dist[DamageObject::CenterTorsoArmorZone] = model->m_centerFrontDistributive;
|
|
armor_dist[DamageObject::CenterRearTorsoArmorZone] = model->m_centerRearDistributive;
|
|
|
|
//first grab the head
|
|
//Ok now we run the loop and try to distribute the armor based upon our nice little array
|
|
//We should not have to worry at all about tonnage since the armor has already been added...we
|
|
//just need to redistribute the numbers!
|
|
MWObject *parent = GetParentVehicle();
|
|
Check_Object(parent);
|
|
|
|
//first grab the head and fill it
|
|
DamageObject *damage_object = parent->damageObjects.Find(DamageObject::HeadArmorZone);
|
|
Check_Object(damage_object);
|
|
m_armorZoneValues[DamageObject::HeadArmorZone] = damage_object->maxArmorValue;
|
|
total_armor -= damage_object->maxArmorValue;
|
|
|
|
for(i = DamageObject::LeftLegArmorZone; i<DamageObject::HeadArmorZone; i++)
|
|
{
|
|
Verify(armor_dist[i] >= 0.0f);
|
|
Scalar armor_amount = total_armor * armor_dist[i];
|
|
//Check the max on this one first...see if we have left_over
|
|
DamageObject *damage_object = parent->damageObjects.Find(i);
|
|
Check_Object(damage_object);
|
|
if(armor_amount > damage_object->maxArmorValue)
|
|
left_over_armor += armor_amount - damage_object->maxArmorValue;
|
|
Clamp(armor_amount, 0.0f, damage_object->maxArmorValue);
|
|
m_armorZoneValues[i] = armor_amount;
|
|
armor_used += armor_amount;
|
|
Verify(armor_used <= total_armor);
|
|
}
|
|
|
|
//now run through the left over and just place the shit!
|
|
for(i = DamageObject::HeadArmorZone - 1; i>=DamageObject::LeftLegArmorZone; i--)
|
|
{
|
|
DamageObject *damage_object = parent->damageObjects.Find(i);
|
|
Check_Object(damage_object);
|
|
Scalar armor_amount = left_over_armor;
|
|
|
|
//Try to add it all...just keep track of what we don't add.
|
|
if(left_over_armor > damage_object->maxArmorValue)
|
|
left_over_armor = left_over_armor - damage_object->maxArmorValue;
|
|
else
|
|
left_over_armor = 0.0f;
|
|
Clamp(armor_amount, 0.0f, damage_object->maxArmorValue);
|
|
m_armorZoneValues[i] += armor_amount;
|
|
armor_used += armor_amount;
|
|
Verify(armor_used <= total_armor);
|
|
}
|
|
|
|
Verify(armor_used = total_armor);
|
|
return true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
Armor::ApplyZoneBasedArmor(int armor_zone, Stuff::Scalar armor_amount)
|
|
{
|
|
Check_Object(this);
|
|
|
|
MWObject *parent = GetParentVehicle();
|
|
Check_Object(parent);
|
|
|
|
DamageObject *damage_object;
|
|
damage_object = parent->damageObjects.Find(armor_zone);
|
|
|
|
if(!damage_object)
|
|
return false;
|
|
|
|
//these checks are needed so we know when to add tonnage
|
|
if(((m_armorZoneValues[armor_zone] + armor_amount * m_armorMultiplier) - damage_object->maxArmorValue) > SMALL)
|
|
{
|
|
Max_Clamp(m_armorZoneValues[armor_zone], damage_object->maxArmorValue);
|
|
return false;
|
|
}
|
|
|
|
if((m_armorZoneValues[armor_zone] + (armor_amount * m_armorMultiplier)) < 0.0f)
|
|
{
|
|
Min_Clamp(m_armorZoneValues[armor_zone], 1.0f);
|
|
return false;
|
|
}
|
|
|
|
if(GetParentVehicle()->DoesHaveAvailableTonage(armor_amount))
|
|
{
|
|
m_armorZoneValues[armor_zone] += (armor_amount * m_armorMultiplier);
|
|
Clamp(m_armorZoneValues[armor_zone], 0.0f, damage_object->maxArmorValue);
|
|
m_totalTonage += armor_amount;
|
|
GetParentVehicle()->AddTonage(armor_amount);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
Armor::SetZoneBasedArmor(int armor_zone, Stuff::Scalar armor_amount)
|
|
{
|
|
Check_Object(this);
|
|
|
|
Scalar amount_to_add = armor_amount - (m_armorZoneValues[armor_zone] / m_armorMultiplier);
|
|
return ApplyZoneBasedArmor(armor_zone, amount_to_add);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
Armor::SetArmorType(int new_type)
|
|
{
|
|
Check_Object(this);
|
|
const GameModel *model = GetGameModel();
|
|
Check_Object(model);
|
|
|
|
//The first thing that we need to do is to get all the values in tonnages so
|
|
//we can manipulate all the values with the armor change.
|
|
|
|
Scalar ratio = (Scalar)m_armorMultiplier;
|
|
|
|
switch(new_type)
|
|
{
|
|
// MSL 5.00 Armor
|
|
case StandardArmor:
|
|
m_armorMultiplier = model->m_pointsPerStandardTon;
|
|
break;
|
|
case FerroFiberusArmor:
|
|
m_armorMultiplier = model->m_pointsPerFerroTon;
|
|
break;
|
|
case ReactiveArmor:
|
|
m_armorMultiplier = model->m_pointsPerReactiveTon;
|
|
break;
|
|
case ReflectiveArmor:
|
|
m_armorMultiplier = model->m_pointsPerReflectiveTon;
|
|
break;
|
|
case SolarianArmor:
|
|
m_armorMultiplier = model->m_pointsPerSolarianTon;
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
//i.e. if old was 20 per ton and new is 16 per ton....we want 16/20
|
|
ratio = m_armorMultiplier / ratio;
|
|
|
|
for(int i=DamageObject::LeftLegArmorZone; i<=DamageObject::HeadArmorZone; i++)
|
|
{
|
|
m_armorZoneValues[i] *= ratio;
|
|
}
|
|
|
|
if(ratio > 1.0f)
|
|
{
|
|
//This means that we may have over stepped our points bounds! We need to run through
|
|
//And check to make sure that this is not true
|
|
for(i=DamageObject::LeftLegArmorZone; i<=DamageObject::HeadArmorZone; i++)
|
|
{
|
|
DamageObject *damage_object;
|
|
damage_object = GetParentVehicle()->damageObjects.Find(i);
|
|
Check_Object(damage_object);
|
|
|
|
if(m_armorZoneValues[i] > damage_object->maxArmorValue)
|
|
{
|
|
//We have surpased our max and must clamp and release some tonnage!
|
|
Scalar overflow = m_armorZoneValues[i] - damage_object->maxArmorValue;
|
|
Scalar tonnage_overflow = overflow / m_armorMultiplier;
|
|
Max_Clamp(m_armorZoneValues[i], damage_object->maxArmorValue);
|
|
GetParentVehicle()->AddTonage(-tonnage_overflow);
|
|
}
|
|
}
|
|
}
|
|
|
|
m_armorType = new_type;
|
|
return 1;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Armor::CreateStream(ResourceID data_list, MemoryStream *stream)
|
|
{
|
|
Check_Pointer(stream);
|
|
|
|
stream->AllocateBytes(sizeof(Armor__CreateMessage));
|
|
Subsystem::CreateStream(data_list, stream);
|
|
|
|
Armor__CreateMessage *create_message = Cast_Pointer(
|
|
Armor__CreateMessage *, stream->GetPointer());
|
|
|
|
create_message->m_leftLegArmor = 0.0f;
|
|
create_message->m_rightLegArmor = 0.0f;
|
|
create_message->m_leftArmArmor = 0.0f;
|
|
create_message->m_rightArmArmor = 0.0f;
|
|
create_message->m_leftFrontTorsoArmor = 0.0f;
|
|
create_message->m_rightFrontTorsoArmor = 0.0f;
|
|
create_message->m_centerFrontTorsoArmor = 0.0f;
|
|
create_message->m_centerRearTorsoArmor = 0.0f;
|
|
create_message->m_headArmor = 0.0f;
|
|
|
|
// MSL 5.00 Armor
|
|
// create_message->m_armorType = FerroFiberusArmor;
|
|
create_message->m_armorType = StandardArmor;
|
|
create_message->m_internalType = StandardInternal;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Armor::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|