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.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
@@ -0,0 +1,609 @@
#include "MW4Headers.hpp"
#include <Adept\DamageObject.hpp>
#include "AI_FindObject.hpp"
#include "Sensor.hpp"
#include "MWDamageObject.hpp"
#include "rail_move.hpp"
#include "CombatAI.hpp"
#include "MWPlayer.hpp"
#include "MWMission.hpp"
#include "VehicleInterface.hpp"
#include "MFB.hpp"
const Stuff::Scalar min_distance = 10.0f;
const Stuff::Scalar max_distance = 1000.0f;
const Stuff::Scalar min_tonnage = 40.0f;
const Stuff::Scalar max_tonnage = 105.0f;
const Stuff::Scalar find_object_shot_by_time = 2.0f;
const Stuff::Scalar building_data_refresh_rate = 4.0f;
const Stuff::Scalar find_object_cache_delay = 3.0f;
extern __int64 tCombatAITime_FindObject;
using namespace MW4AI;
using namespace MW4AI::FindObject;
using namespace MechWarrior4;
typedef SensorData sensor_data;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Scoring functions
//
inline Stuff::Scalar ScoreDistance(Adept::Entity& src, Adept::Entity& dest)
{
Vector3D delta;
delta.Subtract((Point3D)src.GetLocalToWorld(),(Point3D)dest.GetLocalToWorld());
delta.y = 0;
return (NormalizedValue(delta.GetLengthSquared(),
min_distance * min_distance,
max_distance * max_distance,
true));
}
inline Stuff::Scalar ScoreTonnage(Adept::Entity& entity)
{
if (entity.IsDerivedFrom(MWObject::DefaultData) == false)
{
return (0);
}
MWObject* object = Cast_Object(MWObject*,&entity);
return (NormalizedValue(object->GetTonage(),min_tonnage,max_tonnage));
}
inline Stuff::Scalar ScoreDamage(Adept::Entity& object)
{
if (object.IsDerivedFrom(MWObject::DefaultData) == false)
{
return (0);
}
MWObject* v = Cast_Object(MWObject*,&object);
Stuff::SortedChainIteratorOf<MWInternalDamageObject*,int> i(&(v->internalDamageObjects));
MWInternalDamageObject* o;
Stuff::Scalar total_damage = 0;
Stuff::Scalar max_damage = 0;
while ((o = i.ReadAndNext()) != 0)
{
total_damage += o->currentInternalDamage;
max_damage += o->baseInternalDamage;
}
if (Small_Enough(max_damage))
{
return (0);
}
return (NormalizedValue(total_damage,max_damage * 0.66f,max_damage,true)); // we crank up the minimum so 33% damage is considered 100% score
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ScoreByCriteria()
// Scores the given object (with a normalized score) using the given find criteria
Stuff::Scalar ScoreByCriteria(MWObject& src,
MWObject& target,
int criteria)
{
Verify((MW4AI::FindObject::Criteria)criteria >= MW4AI::FindObject::FC_FIRST);
Verify((MW4AI::FindObject::Criteria)criteria <= MW4AI::FindObject::FC_LAST);
switch ((MW4AI::FindObject::Criteria)criteria)
{
case MW4AI::FindObject::FC_BEST_TARGET:
{
return (0.45f * ScoreDistance(src,target) +
0.35f * ScoreDamage(target) +
0.2f * ScoreTonnage(target));
}
case MW4AI::FindObject::FC_GREATEST_THREAT:
{
return (0.6f * ScoreDistance(src,target) +
0.4f * ScoreTonnage(target));
}
case MW4AI::FindObject::FC_LEAST_THREAT:
{
return (1.0f - (0.6f * ScoreDistance(src,target) +
0.4f * ScoreTonnage(target)));
}
case MW4AI::FindObject::FC_MOST_DAMAGED:
{
return (ScoreDamage(target));
}
case MW4AI::FindObject::FC_NEAREST:
{
return (ScoreDistance(src,target));
}
}
Verify(!"Should never get here.");
return (ScoreDistance(src,target));
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// QualifiesByAlignment
// Indicates whether a given sensor data object qualifies by testing its alignment
// against the given alignment-specification value.
bool QualifiesByAlignment(MWObject& src,
MWObject& target,
int fa_alignment)
{
Verify(fa_alignment != 0); // value of 0 makes no sense
Verify(fa_alignment <= MW4AI::FindObject::FA_ANY);
if (&src == &target)
{
return (false);
}
switch (src.GetRelativeAlignment(target.GetAlignment()))
{
case Adept::Entity::Enemy:
{
return ((fa_alignment & MW4AI::FindObject::FA_ENEMY) != 0);
}
case Adept::Entity::Player:
{
return ((fa_alignment & MW4AI::FindObject::FA_FRIENDLY) != 0);
}
case Adept::Entity::DefaultAlignment:
{
return ((fa_alignment & MW4AI::FindObject::FA_NEUTRAL) != 0);
}
}
return (false);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// QualifiesByType
// Indicates whether a given sensor data object qualifies by testing its
// object type against the given alignment-specification value.
bool QualifiesByType(MWObject& src,
MWObject& target,
int ft_type)
{
Verify(ft_type != 0); // 0 is invalid: you must specify a type
if (target.GetTargetDesirability() == MWObject::desirability_never)
{
return (false);
}
if (ft_type & FT_BUILDING)
{
if (target.IsDerivedFrom(Building::DefaultData) == true)
{
return (true);
}
}
if (ft_type & FT_MFB)
{
if (target.IsDerivedFrom(MFB::DefaultData) == true)
{
return (true);
}
}
if ((target.GetTargetDesirability() == MWObject::desirability_invalid) &&
(target.IsPlayerVehicle() == false))
{
if (target.GetAI() == 0)
{
return (false);
}
if ((target.weaponChain.IsEmpty() == true) &&
(target.IsDerivedFrom(Mech::DefaultData) == false) &&
(!(ft_type & FT_UNARMED)))
{
return (false);
}
}
if (ft_type & FT_MECH)
{
if (target.IsDerivedFrom(Mech::DefaultData) == true)
{
return (true);
}
}
if (ft_type & FT_AIRPLANE)
{
if (target.IsDerivedFrom(Airplane::DefaultData) == true)
{
return (true);
}
}
if (ft_type & FT_VEHICLE)
{
if ((target.IsDerivedFrom(Vehicle::DefaultData) == true) &&
(target.IsDerivedFrom(MFB::DefaultData) == false) &&
(target.IsDerivedFrom(Mech::DefaultData) == false) &&
(target.IsDerivedFrom(Airplane::DefaultData) == false))
{
return (true);
}
}
if (ft_type & FT_BOAT)
{
if (target.IsDerivedFrom(Boat::DefaultData) == true)
{
return (true);
}
}
if (ft_type & FT_TURRET)
{
if (target.IsDerivedFrom(Building::DefaultData) == true)
{
return (true);
}
}
return (false);
}
bool Qualifies(MWObject& src,
MWObject& target,
int fa_alignment,
int ft_type)
{
if (QualifiesByAlignment(src,target,fa_alignment) == false)
{
return (false);
}
return (QualifiesByType(src,target,ft_type));
}
void FillNameTableData(MWObject& src,
std::vector<MWObject*>& objects_to_search)
{
Adept::NameTable* table = Adept::NameTable::GetInstance();
{
int size(table->nameTableArray[NameTable::VehicleArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data = &table->nameTableArray [NameTable::VehicleArray][i];
Adept::Entity* ent = data->dataPointer->GetCurrent();
if ((ent != 0) &&
(ent->IsDestroyed() == false) &&
(ent != &src) &&
(ent->IsDerivedFrom(MWObject::DefaultData) == true))
{
objects_to_search.push_back(Cast_Object(MWObject*,ent));
}
}}
}
{
int size(table->nameTableArray[NameTable::PlayerArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data = &table->nameTableArray [NameTable::PlayerArray][i];
Adept::Entity* ent = data->dataPointer->GetCurrent ();
if ((ent != 0) &&
(ent->IsDerivedFrom(Adept::Player::DefaultData) == true))
{
Adept::Player* player = Cast_Object(Adept::Player*,ent);
if ((player->vehicle != 0) &&
(player->vehicle->IsDestroyed() == false) &&
(player->vehicle != &src) &&
(player->vehicle->IsDerivedFrom(MWObject::DefaultData) == true))
{
objects_to_search.push_back(Cast_Object(MWObject*,player->vehicle));
}
}
}}
}
}
void FillSensorData(MWObject& src,
const Sensor::sensorDataArray& sensed_data,
int number_of_contacts,
std::vector<MWObject*>& sensor_data_list)
{
if ((src.GetAI() != 0) &&
(src.GetAI()->GetExtendedSensorData(sensor_data_list) == true))
{
return;
}
if (number_of_contacts == 0)
{
return;
}
sensor_data_list.reserve(number_of_contacts);
{for (int i = 0;
i < number_of_contacts;
++i)
{
if ((sensed_data[i] != 0) &&
(sensed_data[i]->object.GetCurrent() != 0) &&
(sensed_data[i]->object.GetCurrent() != &src))
{
sensor_data_list.push_back(sensed_data[i]->object.GetCurrent());
}
}}
}
// FindObject(): finds an object given the given sensor (sensor) and qualifier (object_type)
long MW4AI::FindObject::Find(MWObject& src,
int fa_alignment,
int ft_type,
int fc_criteria,
int ff_flags,
Stuff::Scalar distance_limit,
const Adept::ObjectID* except_object)
{
AI_LOGIC("Find Object");
TIME_FUNCTION(tCombatAITime_FindObject);
Verify(ff_flags <= FF_WHO_SHOT + FF_SEEPLAYER + FF_LOOK_EVERYWHERE + FF_TARGETLOS);
if (distance_limit == 0)
{
distance_limit = MW4AI::FindObject::DISTANCE_LIMIT;
}
if (src.m_FindObjectList == 0)
{
src.m_FindObjectList = new MW4AI::FindObjectList;
}
std::vector<MWObject*>& objects_to_search = src.m_FindObjectList->objects;
objects_to_search.clear();
if ((ff_flags & MW4AI::FindObject::FF_SEEPLAYER) &&
(MWMission::GetInstance()->GetGameModel() != 0) &&
(Adept::Player::GetInstance() != 0))
{
MWPlayer* p = Cast_Object(MWPlayer*,Adept::Player::GetInstance());
if ((p != 0) &&
(p->GetInterface() != 0) &&
(p->GetInterface()->vehicle != 0))
{
Vehicle* vehicle = p->GetInterface()->vehicle;
if ((QualifiesByAlignment(src,*vehicle,fa_alignment) == true) &&
(vehicle->IsDestroyed() == false) &&
(vehicle->objectID != src.objectID))
{
const Adept::Mission::GameModel* game_model = MWMission::GetInstance()->GetGameModel();
Stuff::Scalar fog_distance = game_model->m_generalFogEnd;
if (fog_distance > 1200)
{
fog_distance = 1200;
}
if (fog_distance > distance_limit)
{
fog_distance = distance_limit;
}
Stuff::Point3D player_vehicle_pos(vehicle->GetLineOfSight());
Stuff::Point3D my_pos(src.GetLineOfSight());
Stuff::LinearMatrix4D src_los;
src.GetLineOfSight(src_los);
if ((GetLengthSquared(player_vehicle_pos,my_pos) < fog_distance * fog_distance) &&
(MatrixFacesPoint(src_los,player_vehicle_pos,Stuff::Pi_Over_4) == true))
{
if ((src.m_FindObjectCache != 0) &&
(src.m_FindObjectCache->m_RayCastTime + find_object_cache_delay < gos_GetElapsedTime()))
{
delete src.m_FindObjectCache;
src.m_FindObjectCache = 0;
}
MW4AI::FireData::HIT_RESULT hit_result;
if (src.m_FindObjectCache != 0)
{
hit_result = src.m_FindObjectCache->m_HitResult;
}
else
{
FireData fire_data(src,my_pos,player_vehicle_pos);
fire_data.Project();
hit_result = fire_data.GetHitResult(vehicle);
src.m_FindObjectCache = new MW4AI::FindObjectCache((Stuff::Scalar)gos_GetElapsedTime(),hit_result);
}
if (hit_result == FireData::HIT_TARGET)
{
if (src.GetSensor() == 0)
{
return (vehicle->objectID);
}
else
{
objects_to_search.push_back(vehicle);
}
}
}
}
}
}
if ((src.GetSensor() == 0) &&
(objects_to_search.size() == 0))
{
return (-2);
}
if ((ff_flags & MW4AI::FindObject::FF_WHO_SHOT) &&
(src.GetAI() != 0))
{
Adept::Entity* e = src.GetAI()->ShotBy(gos_GetElapsedTime() - find_object_shot_by_time);
if ((e != 0) &&
(e != &src) &&
(e->IsDerivedFrom(MWObject::DefaultData) == true) &&
(e->IsDestroyed() == false))
{
MWObject* v = Cast_Object(MWObject*,e);
Check_Object(v);
if (QualifiesByAlignment(src,*v,fa_alignment) == true)
{
return (v->objectID);
}
}
}
if (ff_flags & MW4AI::FindObject::FF_LOOK_EVERYWHERE)
{
FillNameTableData(src,objects_to_search);
}
else
{
FillSensorData(src,
src.GetSensor()->RefreshAndGetSensorData(),
src.GetSensor()->numberOfContacts,
objects_to_search);
if (ft_type & FT_BUILDING)
{
if (src.GetSensor()->GetLastTimeUpdatedBuildingData() < gos_GetElapsedTime() + building_data_refresh_rate + Stuff::Random::GetFraction())
{
src.GetSensor()->UpdateBuildingData();
}
FillSensorData(src,
src.GetSensor()->GetBuildingData(),
src.GetSensor()->numberOfBuildingContacts,
objects_to_search);
}
}
if (objects_to_search.size() == 0)
{
return (-2);
}
const Stuff::Scalar distance_limit_squared = distance_limit * distance_limit;
Stuff::Scalar best_score = 0;
std::vector<MWObject*>::const_iterator best_found = objects_to_search.end();
Stuff::Point3D my_pos(src.GetLocalToWorld());
{for (std::vector<MWObject*>::const_iterator i = objects_to_search.begin();
i != objects_to_search.end();
++i)
{
if ((except_object != 0) &&
((*i)->objectID == *except_object))
{
continue;
}
if (ff_flags & MW4AI::FindObject::FF_TARGETLOS)
{
// Test line of sight
Stuff::Point3D target_pos((*i)->GetLineOfSight());
Stuff::Point3D my_pos(src.GetLineOfSight());
FireData fire_data(src,my_pos,target_pos);
fire_data.Project();
if (fire_data.GetHitResult((*i)) != FireData::HIT_TARGET)
{
continue;
}
}
if (Qualifies(src,**i,fa_alignment,ft_type) == true)
{
Point3D pos((*i)->GetLocalToWorld());
Scalar distance(0);
if (src.GetAI() != 0)
{
distance = src.GetAI()->GetLeastSquaredSensorDistance(pos);
}
if (distance == 0)
{
Vector3D delta;
delta.Subtract(my_pos,pos);
delta.y = 0;
distance = delta.GetLengthSquared();
}
if (distance < distance_limit_squared)
{
Stuff::Scalar s;
if ((*i)->GetTargetDesirability() == MWObject::desirability_invalid)
{
s = ScoreByCriteria(src,**i,fc_criteria);
}
else
{
Verify((*i)->GetTargetDesirability() != MWObject::desirability_never);
s = (*i)->GetTargetDesirability();
}
Verify(s >= 0);
Verify(s <= 1);
if (s >= best_score)
{
if (s == 1)
{
return ((*i)->objectID);
}
best_score = s;
best_found = i;
}
}
}
}}
if (best_found == objects_to_search.end())
{
return (-2); // -2 = ABL constant for nothing found
}
return ((*best_found)->objectID);
}