Files
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

1413 lines
35 KiB
C++

// EdGameObject.cpp: implementation of the EdGameObject class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MW4GameEd2.h"
#include "EdGameObject.h"
#include "GameInterface.h"
#include "GameObjPropPanal.h"
#include "ObjPanelDlg.h"
#include "ObjProps.h"
#include "ObjManListCtrl.h"
#include "NameManager.h"
#include "drawInfo.h"
//#include <Adept\Adept.hpp>
#include <Adept\Entity.hpp>
#include <Adept\Zone.hpp>
#include <Adept\Map.hpp>
#include <MW4\MW4.hpp>
#include <MW4\Vehicle.hpp>
#include <MW4\Building.hpp>
#include <MW4\NonCom.hpp>
#include <MW4\Turret.hpp>
#include <MW4\Airplane.hpp>
#include <MW4\Flag.hpp>
#include <MW4\Team.hpp>
#include <MW4\Navpoint.hpp>
#include <MW4\Cultural.hpp>
#include <Adept\Dropzone.hpp>
#include <Adept\CollisionVolume.hpp>
#include <MW4\MWTool.hpp>
#include <MW4\Mech_AI.hpp>
#include <MW4\PlaneAI.hpp>
#include <MW4\ShooterAI.hpp>
#include <MW4\NonComAI.hpp>
#include <MW4\Mech.hpp>
#include <MW4\WaterCultural.hpp>
#include <MW4\MFB.hpp>
#include <Adept\EntityManager.hpp>
#include <MW4\aiutils.hpp>
using namespace MW4AI;
using namespace Adept;
using namespace MechWarrior4;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
EdGameObject::EdGameObject():EdGUIObject()
{
MyEntity = NULL;
InMap=false;
SnapToGround=false;
Alignment=Entity::DefaultAlignment;
Skin='_';
AIType="<NONE>";
m_ScriptName="";
for(int i=0;i<DEFAULT_MEMORYCELL_VALUES;i++) MemoryCell[i]=0.0f;
DrawFromOBB=false;
UseGameCollsion=true;
Changeable=true;
}
void EdGameObject::AssociateTo(Adept::Entity *entity)
{
InMap=false;
// Alterted for performance
// EdGUIObject::SetMat(entity->GetLocalToParent());
LinearMatrix4D mat=entity->GetLocalToParent();
SetMatNoUpdate(mat);
Point3D pnt;
pnt=mat;
HoverElevation=pnt.y-ComputeTerrainElevation(pnt.x,pnt.z,entity);
SnapToGround=true;
if(entity->GetParentEntity()==Map::GetInstance())
{
InMap=true;
}
MyEntity=entity;
ResourcePath=MyEntity->GetGameModelResourceName();
ResourcePath=ResourcePath.Left(ResourcePath.Find(".data"));
ResourcePath+=".Instance";
// SetName(CString((char *)entity->instanceName));
// For Performance Assume the name is unique
Name=CString((char *)entity->instanceName);
if(Name=="")
{
CString base_name=ResourcePath;
base_name=base_name.Left(base_name.ReverseFind('.'));
base_name=base_name.Mid(base_name.ReverseFind('\\')+1);
SetName(base_name);
}
else
NameManager::Instance->AddString(Name);
Alignment=MyEntity->GetAlignment();
Skin=GetEntitySkin(MyEntity);
//Sync AI
if (MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
Check_Object(mwobject);
MechWarrior4::AI* ai = mwobject->GetAI();
if (ai == 0)
AIType="<NONE>";
else
{
if(ai->IsDerivedFrom(MechWarrior4::PlaneAI::DefaultData)) AIType="PlaneAI";
else if(ai->IsDerivedFrom(MechWarrior4::MechAI::DefaultData)) AIType="MechAI";
else if(ai->IsDerivedFrom(MechWarrior4::ShooterAI::DefaultData)) AIType="ShooterAI";
else if(ai->IsDerivedFrom(MechWarrior4::NonComAI::DefaultData)) AIType="NonComAI";
else if(ai->IsDerivedFrom(MechWarrior4::CombatAI::DefaultData)) AIType="CombatAI";
else if(ai->IsDerivedFrom(MechWarrior4::MoverAI::DefaultData)) AIType="MoverAI";
else if(ai->IsDerivedFrom(MechWarrior4::AI::DefaultData)) AIType="AI";
}
}
else
AIType="<NONE>";
//Sync up Cells
if ((MyEntity->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
if (mwobject->GetAI() != 0)
{
for(int i=0;i<DEFAULT_MEMORYCELL_VALUES;i++) MemoryCell[i]=mwobject->GetAI()->RealMemory(i);
}
}
m_ScriptName=GetEntityScriptName(MyEntity);
Check_Object(MyEntity);
if(InMap)
{
BuildDisplayInfoFromData();
}
else
{
AddToMap();
BuildDisplayInfoFromData();
RemoveFromMap();
}
SetAlignment(Alignment);
PickPen();
}
bool EdGameObject::InRadius( Point3D &pnt)
{
return EdGUIObject::InRadius(pnt);
/*
// The following is for Object percise selection which was deemed troublesome do to underselction problems.
if(EdGUIObject::InRadius(pnt))
{
if(UseGameCollsion && MyEntity && (MyEntity->CanBeShot() || MyEntity->CanBeWalkedOn()) && Visual)
{
float height;
Entity* top_entity = GetTopEntity(pnt.x,pnt.z,height);
if(MyEntity == top_entity)
{
return true;
}
else
{
if (top_entity == Adept::Map::GetInstance())
{
Stuff::Point3D my_height(MyEntity->GetLocalToWorld());
if (my_height.y < (height - 2.0f))
{
return (true);
}
}
}
}
else
{
return true;
}
}
return false;
*/
}
void EdGameObject::ChangeTo(CString &path)
{
AIType="<None>";
m_ScriptName="";
BuildFrom(path,GetName());
}
void EdGameObject::BuildFrom(CString &res_name,CString &name)
{
if(MyEntity) Clear();
ResourcePath=res_name;
EdGUIObject::SetName(name);
Adept::Resource res((LPCSTR)ResourcePath);
res.LoadData();
Check_Object(Connection::Local);
ReplicatorID base_id = Connection::Local->GetNextReplicatorID();
MyEntity = Entity::CreateEntity(&res,&base_id);
Check_Object(MyEntity);
Check_Object(EntityManager::GetInstance());
//TOM CHECK THIS
// if(MyEntity->instanceName && EntityManager::GetInstance()->GetMover(MyEntity->instanceName))
//if(MyEntity->instanceName)
// {
// Verify(MyEntity->IsDerivedFrom(Mover::DefaultData));
// Mover *mover = Cast_Object(Mover *, MyEntity);
// EntityManager::GetInstance()->RemoveMover(mover);
// MyEntity->instanceName=(char *)(LPCSTR)GetName();
// EntityManager::GetInstance()->AddMover(mover);
// }
// else
// {
MyEntity->instanceName=(char *)(LPCSTR)GetName();
// }
MyEntity->SetPropType(Entity::MissionPropType);
SetAlignment(Alignment);
SetSkin(Skin);
SetAIType(AIType);
SetScriptName(m_ScriptName);
for(int i=0;i<DEFAULT_MEMORYCELL_VALUES;i++) SetMemoryCell(i,MemoryCell[i]);
PickPen();
AddToMap();
BuildDisplayInfoFromData();
}
bool EdGameObject::IsMultiZone()
{
if(MyEntity!=NULL && MyEntity->IsMultiZone() ) return true;
return false;
}
bool EdGameObject::IsMultiTile()
{
if(MyEntity!=NULL && MyEntity->IsMultiTile() ) return true;
return false;
}
void EdGameObject::SelectMultiZone()
{
if(MyEntity!=NULL && MyEntity->IsMultiZone() )
Select();
}
void EdGameObject::SelectMultiTile()
{
if(MyEntity!=NULL && MyEntity->IsMultiTile() )
Select();
}
void EdGameObject::PickPen()
{
Check_Object(MyEntity);
if(MyEntity->IsDerivedFrom(Mech::DefaultData))
DrawPen=DrawInfo::MechPen;
else
if(MyEntity->IsDerivedFrom(Vehicle::DefaultData))
DrawPen=DrawInfo::VehiclePen;
else
if(MyEntity->IsDerivedFrom(Building::DefaultData) )
DrawPen=DrawInfo::BuildingPen;
else
if(MyEntity->IsDerivedFrom(Cultural::DefaultData) )
DrawPen=DrawInfo::CulturalPen;
else
if(MyEntity->IsDerivedFrom(NonCom::DefaultData) )
DrawPen=DrawInfo::NonComPen;
else
DrawPen=DrawInfo::HelperPen;
}
void EdGameObject::BuildDisplayInfoFromData()
{
Check_Object(MyEntity);
if ( MyEntity->IsDerivedFrom(MechWarrior4::NonCom::DefaultData) ) UseGameCollsion=false;
if(!IsVisual()) return;
DrawFromOBB=false;
if(MyEntity->GetSolidVolume()!=NULL)
{
if(LineCount!=0)
{
Verify(LineCount>0);
if(LineList) delete LineList;
LineList=NULL;
LineCount=0;
}
DrawFromOBB=true;
}
else
{
Scalar rad=MyEntity->GetElement()->m_localOBB.sphereRadius;
if(LineCount!=12)
{
LineCount=12;
if(LineList) delete LineList;
LineList=new GUILine[LineCount];
}
LineList[0].SetLine(Point3D(-rad,-rad,-rad),
Point3D(rad,-rad,-rad));
LineList[1].SetLine(Point3D(rad,-rad,-rad),
Point3D(rad,-rad,rad));
LineList[2].SetLine(Point3D(rad,-rad,rad),
Point3D(-rad,-rad,rad));
LineList[3].SetLine(Point3D(-rad,-rad,rad),
Point3D(-rad,-rad,-rad));
LineList[4].SetLine(Point3D(-rad,rad,-rad),
Point3D(rad,rad,-rad));
LineList[5].SetLine(Point3D(rad,rad,-rad),
Point3D(rad,rad,rad));
LineList[6].SetLine(Point3D(rad,rad,rad),
Point3D(-rad,rad,rad));
LineList[7].SetLine(Point3D(-rad,rad,rad),
Point3D(-rad,rad,-rad));
LineList[8].SetLine(Point3D(-rad,-rad,-rad),
Point3D(-rad,rad,-rad));
LineList[9].SetLine(Point3D(rad,-rad,rad),
Point3D(rad,rad,rad));
LineList[10].SetLine(Point3D(-rad,-rad,rad),
Point3D(-rad,rad,rad));
LineList[11].SetLine(Point3D(rad,-rad,-rad),
Point3D(rad,rad,-rad));
}
if(MyEntity->IsDerivedFrom(WaterCultural::DefaultData))
{
ScreenDiv=75;
RadiusSqu=0;
Visual=false;
}
else
BuildRadius();
}
void EdGameObject::BuildRadius()
{
if(DrawFromOBB)
{
Verify(MyEntity && InMap && MyEntity->GetSolidVolume());
const OBB &obbTmp=MyEntity->GetSolidVolume()->m_localSpaceBounds;
RadiusSqu=obbTmp.sphereRadius*obbTmp.sphereRadius;
}
else
{
EdGUIObject::BuildRadius();
}
}
void EdGameObject::SetName( CString &name)
{
EdGUIObject::SetName(name);
if(InMap)
SetEntityName(MyEntity,GetName());
}
void EdGameObject::RemoveFromMap()
{
if(MyEntity && InMap)
{
RemoveEntityFromMap(MyEntity);
InMap=false;
}
// EdGUIObject::RemoveFromMap();
}
void EdGameObject::AddToMap()
{
if(MyEntity && !InMap)
{
AddEntityToMap(MyEntity,GetMat());
InMap=true;
}
// EdGUIObject::AddToMap();
}
void EdGameObject::UpdateMat()
{
RemoveFromMap();
EdGUIObject::UpdateMat();
AddToMap();
}
void EdGameObject::Clear()
{
if(MyEntity!=NULL)
{
Check_Object(MyEntity);
if(InMap)
{
RemoveFromMap();
}
delete Cast_Object(Stuff::Plug *,MyEntity);
}
}
EdGameObject::~EdGameObject()
{
Clear();
}
void EdGameObject::SetAlignment(int align)
{
Alignment=align;
if(MyEntity!=NULL)
{
Verify(align<Entity::LastAlignment);
MyEntity->SetAlignment(Alignment);
if(MyEntity->IsDerivedFrom(Vehicle::DefaultData) && !MyEntity->IsDerivedFrom(Mech::DefaultData))
if(Alignment==Entity::Enemy) SetSkin('_'); else SetSkin('0');
}
}
int EdGameObject::GetAlignment()
{
return Alignment;
}
CString EdGameObject::GetAIType()
{
return AIType;
}
void EdGameObject::FillValidAITypes(CComboBox *con)
{
if ((MyEntity == 0) ||
(MyEntity->IsDerivedFrom(MWObject::DefaultData) == false))
{
return;
}
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
Check_Object(mwobject);
if (mwobject->IsDerivedFrom(MWObject::DefaultData)) con->AddString("AI");
if (mwobject->IsDerivedFrom(Vehicle::DefaultData)) con->AddString("MoverAI");
if (mwobject->IsDerivedFrom(Vehicle::DefaultData)) con->AddString("CombatAI");
if (mwobject->IsDerivedFrom(MWObject::DefaultData)) con->AddString("ShooterAI");
if (mwobject->IsDerivedFrom(NonCom::DefaultData)) con->AddString("NonComAI");
if (mwobject->IsDerivedFrom(Mech::DefaultData)) con->AddString("MechAI");
if (mwobject->IsDerivedFrom(Airplane::DefaultData)) con->AddString("PlaneAI");
}
CString EdGameObject::GetBestAIType() const
{
if ((MyEntity == 0) ||
(MyEntity->IsDerivedFrom(MWObject::DefaultData) == false))
{
return ("<NONE>");
}
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
Check_Object(mwobject);
if (mwobject->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) == false)
{
if (mwobject->IsDerivedFrom(MechWarrior4::NonCom::DefaultData) == true)
{
return ("NonComAI");
}
if (mwobject->weaponChain.GetSize() == 0)
{
return ("AI");
}
return ("ShooterAI");
}
if (mwobject->IsDerivedFrom(Mech::DefaultData) == true)
{
return ("MechAI");
}
if (mwobject->IsDerivedFrom(Airplane::DefaultData) == true)
{
return ("PlaneAI");
}
if (mwobject->weaponChain.GetSize() == 0)
{
return ("MoverAI");
}
return ("CombatAI");
}
void EdGameObject::SetDefaultAI()
{
SetAIType(GetBestAIType());
}
template <class create_message_type>
void CreateAndAttachAI(MechWarrior4::MWObject& mwobject, const CString& type_name, Adept::Entity::ClassData* class_data)
{
UnBindEntity(&mwobject);
CString resource_name("Content\\AIPlayers\\");
resource_name += type_name;
resource_name += "\\";
resource_name += type_name;
resource_name += ".data";
Adept::Resource r(resource_name);
r.LoadData();
Stuff::Scalar blank_cells[DEFAULT_MEMORYCELL_VALUES];
for (int i=0;i<DEFAULT_MEMORYCELL_VALUES;++i) blank_cells[i]=0;
create_message_type create_message(sizeof(create_message_type),
DefaultEventPriority,
create_message_type::DefaultFlags,
class_data->GetClassID(),
create_message_type::DefaultFlags,
r.GetResourceID(),
mwobject.GetLocalToWorld(),
0.0f,
Entity__ExecutionStateEngine::AlwaysExecuteState,
NameTable::NullObjectID,
mwobject.GetAlignment(),
DropZone::Null,
// NameTable::NullObjectID,
mwobject.objectID,
"", // script name, should be scripts\<filename>.abl
blank_cells, // memory cell data
-1, // pilotSkill
-1, // gunnerySkill
-1, // eliteSkill
-1, // minHeatSkill
-1, // maxHeatSkill
-1, // sensor
-1, // blind
-1, // longrange
-1, // shortrange
0,
0,
0);
MemoryStream stream(&create_message,create_message.messageLength);
ReplicatorID ai_id = Connection::Local->GetNextReplicatorID();
Adept::Entity* ai_entity = Entity::CreateEntity(&stream,&ai_id,false);
Check_Object(ai_entity);
Verify(ai_entity->IsDerivedFrom(class_data));
ai_entity->instanceName = type_name;
ai_entity->instanceName += "_";
ai_entity->instanceName += mwobject.instanceName;
ai_entity->instanceName += "_";
ai_entity->instanceName += IntToString(rand() % 1000).c_str();
AI* ai = Cast_Object(AI*,ai_entity);
ai->ConnectEntity(&mwobject);
mwobject.AttachAI(ai);
}
void EdGameObject::SetAIType(const CString& type)
{
AIType=type;
if ((MyEntity == 0) ||
(MyEntity->IsDerivedFrom(MWObject::DefaultData) == false))
{
return;
}
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
Check_Object(mwobject);
if (AIType == "<NONE>")
{
mwobject->AttachAI(0);
return;
}
#define CREATE_AND_ATTACH(type_name) \
if (AIType == #type_name) \
{ \
RemoveEntityAI(MyEntity); \
CreateAndAttachAI<##type_name::CreateMessage>(*mwobject,#type_name,##type_name::DefaultData); \
AddEntityAI(MyEntity); \
return; \
}
CREATE_AND_ATTACH(MechAI);
CREATE_AND_ATTACH(PlaneAI);
CREATE_AND_ATTACH(NonComAI);
CREATE_AND_ATTACH(ShooterAI);
CREATE_AND_ATTACH(CombatAI);
CREATE_AND_ATTACH(MoverAI);
CREATE_AND_ATTACH(AI);
#undef CREATE_AND_ATTACH
}
void EdGameObject::MakeVisible(DWORD *visflag)
{
if (MyEntity == 0) return;
if (MyEntity->IsDerivedFrom(WaterCultural::DefaultData) ) {*visflag|=SHOW_WATER; return; }
if ( MyEntity->IsDerivedFrom(MechWarrior4::Mech::DefaultData) ) {*visflag|=SHOW_MECHS; return;}
if ( MyEntity->IsDerivedFrom(MechWarrior4::Airplane::DefaultData)) {*visflag|=SHOW_AIRPLANES; return;}
if ( MyEntity->IsDerivedFrom(MechWarrior4::NonCom::DefaultData) ) {*visflag|=SHOW_NONCOMS; return;}
if ( MyEntity->IsDerivedFrom(MechWarrior4::Building::DefaultData) ) {*visflag|=SHOW_BUILDINGS; return;}
if ( MyEntity->IsDerivedFrom(Cultural::DefaultData)) {*visflag|=SHOW_CULTURALS; return;}
if ( MyEntity->IsDerivedFrom(MechWarrior4::NavPoint::DefaultData)) {*visflag|=SHOW_NAVPOINTS; return;}
if ( MyEntity->IsDerivedFrom(Flag::DefaultData)) {*visflag|=SHOW_FLAGS; return;}
if ( MyEntity->IsDerivedFrom(Team::DefaultData)) {*visflag|=SHOW_TEAMS; return;}
if ( MyEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData)) {*visflag|=SHOW_VEHICLES; return;}
}
void EdGameObject::UpdateVisibility(DWORD visflags)
{
if (MyEntity == 0)
{
SetHide(false);
return;
}
if ((visflags&SHOW_FRIENDLY && MyEntity->GetAlignment()==Entity::Player ) ||
(visflags&SHOW_NEUTRAL && MyEntity->GetAlignment()==Entity::DefaultAlignment ) ||
(visflags&SHOW_ENEMY && MyEntity->GetAlignment()==Entity::Enemy ))
{
SetHide(false);
return;
}
if (visflags&SHOW_WATER && MyEntity->IsDerivedFrom(WaterCultural::DefaultData) )
{
SetHide(false);
return;
}
if ((visflags&SHOW_MECHS && MyEntity->IsDerivedFrom(MechWarrior4::Mech::DefaultData) ) ||
(visflags&SHOW_AIRPLANES && MyEntity->IsDerivedFrom(MechWarrior4::Airplane::DefaultData)) ||
(visflags&SHOW_NONCOMS && MyEntity->IsDerivedFrom(MechWarrior4::NonCom::DefaultData) ) ||
(visflags&SHOW_BUILDINGS && MyEntity->IsDerivedFrom(MechWarrior4::Building::DefaultData) ) ||
(visflags&SHOW_CULTURALS && MyEntity->IsDerivedFrom(Cultural::DefaultData) && !MyEntity->IsDerivedFrom(WaterCultural::DefaultData) ) ||
(visflags&SHOW_NAVPOINTS && MyEntity->IsDerivedFrom(MechWarrior4::NavPoint::DefaultData) ) ||
(visflags&SHOW_FLAGS && MyEntity->IsDerivedFrom(Flag::DefaultData) ) ||
(visflags&SHOW_TEAMS && MyEntity->IsDerivedFrom(Team::DefaultData) )
)
{
SetHide(false);
return;
}
if (visflags&SHOW_VEHICLES)
{
if ((MyEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) || MyEntity->IsDerivedFrom(MechWarrior4::MFB::DefaultData)) &&
(MyEntity->IsDerivedFrom(MechWarrior4::Mech::DefaultData) == false) &&
(MyEntity->IsDerivedFrom(MechWarrior4::Airplane::DefaultData) == false)
)
{
SetHide(false);
return;
}
}
CString ai_type(GetAIType());
if ((visflags&SHOW_AI_NONE && !ai_type.CompareNoCase("<NONE>") ) ||
(visflags&SHOW_AI && !ai_type.CompareNoCase("AI") ) ||
(visflags&SHOW_MOVERAI && !ai_type.CompareNoCase("MoverAI") ) ||
(visflags&SHOW_COMBATAI && !ai_type.CompareNoCase("CombatAI") ) ||
(visflags&SHOW_NONCOMAI && !ai_type.CompareNoCase("NonComAI") ) ||
(visflags&SHOW_SHOOTERAI && !ai_type.CompareNoCase("ShooterAI") ) ||
(visflags&SHOW_MECHAI && !ai_type.CompareNoCase("MechAI") ) ||
(visflags&SHOW_PLANEAI && !ai_type.CompareNoCase("PlaneAI") ))
{
SetHide(false);
return;
}
if (!(MyEntity->IsDerivedFrom(MechWarrior4::Mech::DefaultData) ||
MyEntity->IsDerivedFrom(MechWarrior4::Airplane::DefaultData) ||
MyEntity->IsDerivedFrom(MechWarrior4::NonCom::DefaultData) ||
MyEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) ||
MyEntity->IsDerivedFrom(MechWarrior4::Building::DefaultData) ||
MyEntity->IsDerivedFrom(MechWarrior4::Cultural::DefaultData) ||
MyEntity->IsDerivedFrom(MechWarrior4::NavPoint::DefaultData) ||
MyEntity->IsDerivedFrom(Flag::DefaultData) ||
MyEntity->IsDerivedFrom(Team::DefaultData) )
)
{
SetHide(false);
return;
}
SetHide(true);
}
void EdGameObject::AddPanel(CObjPanelDlg *pnl,UndoCommand **cmd)
{
EdGUIObject::AddPanel(pnl,cmd);
pnl->AddPanel((CPanelDlg *)new CGameObjPropPanal(this,cmd,pnl));
}
CString EdGameObject::GetTag(unsigned long tag_flags)
{
CString ftag(EdGUIObject::GetTag(tag_flags));
if (MyEntity != 0)
{
if (tag_flags&TAG_TYPE)
{
ftag+=GetTypeName() + ": " + GetResourceName()+"\n";
}
if (tag_flags&TAG_ALIGNMENT)
{
ftag+=(char *)Entity::AlignmentAsciiToText(GetAlignment());
ftag+="\n";
}
if (MyEntity->IsDerivedFrom(MWObject::DefaultData) == true)
{
MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
if ((tag_flags & TAG_AINAME) > 0)
{
if (mwobject->GetAI() != 0)
{
ftag += "AI: ";
ftag += mwobject->GetAI()->instanceName;
ftag += "\n";
}
else
{
ftag += "No AI\n";
}
}
if ((tag_flags & TAG_AITYPE) > 0)
{
ftag += "AI Type: ";
ftag += GetAIType();
ftag += "\n";
}
if ((tag_flags & TAG_SCRIPT) > 0)
{
if ((mwobject->GetAI() != 0) &&
(mwobject->GetAI()->GetScriptName() != 0))
{
CString scriptname;
scriptname=mwobject->GetAI()->GetScriptName();
int pos=scriptname.ReverseFind('\\');
if(pos>=0) scriptname=scriptname.Mid(pos+1);
ftag += "Script: ";
ftag += scriptname;
ftag += "\n";
}
else
{
ftag += "No Script\n";
}
}
}
if ((tag_flags & TAG_SKINTYPE) > 0)
{
ftag += "Skin: ";
ftag += GetSkinText();
ftag += "\n";
}
}
return ftag;
}
void EdGameObject::SetSkin(char id)
{
Skin=id;
if(MyEntity && HasSkin(MyEntity))
SetEntitySkin(MyEntity,Skin);
}
CString EdGameObject::GetScriptName()
{
return m_ScriptName;
}
void EdGameObject::SetScriptName(CString script_name)
{
m_ScriptName=script_name;
if(MyEntity)
SetEntityScriptName(MyEntity,(char *)(LPCSTR)script_name);
}
bool EdGameObject::HasAI() const
{
if ((MyEntity != 0) &&
(MyEntity->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
return (mwobject->GetAI() != 0);
}
return (false);
}
void EdGameObject::SetMemoryCell(int cell, Scalar value)
{
Verify(cell<DEFAULT_MEMORYCELL_VALUES);
MemoryCell[cell]=value;
if ((MyEntity != 0) &&
(MyEntity->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
if (mwobject->GetAI() != 0)
{
mwobject->GetAI()->RealMemory(cell,value);
}
}
}
Scalar EdGameObject::GetMemoryCell(int cell) const
{
Verify(cell<DEFAULT_MEMORYCELL_VALUES);
return MemoryCell[cell];
}
void EdGameObject::Copy(EdGameObject &obj)
{
EdGUIObject::Copy(obj);
Clear();
BuildFrom(obj.ResourcePath,GetName());
SetAIType(obj.GetAIType());
SetScriptName(obj.GetScriptName());
SetAlignment(obj.GetAlignment());
SetSkin(obj.GetSkin());
for(int i=0;i<DEFAULT_MEMORYCELL_VALUES;i++)
SetMemoryCell(i,obj.GetMemoryCell(i));
RemoveFromMap();
}
EdGUIObject *EdGameObject::Clone()
{
EdGameObject *obj=new EdGameObject;
obj->Copy(*this);
return obj;
}
CString EdGameObject::GetResourceName()
{
CString type_name=ResourcePath;
type_name=type_name.Left(type_name.ReverseFind('.'));
type_name=type_name.Mid(type_name.ReverseFind('\\')+1);
return type_name;
}
int EdGameObject::GetUnSelIcon()
{
if(MyEntity==NULL) return ICON_NONE;
if (MyEntity->IsDerivedFrom(WaterCultural::DefaultData) == true)
return ICON_WATER;
else if (MyEntity->IsDerivedFrom(Mech::DefaultData) == true)
return ICON_MECH;
else if (MyEntity->IsDerivedFrom(Airplane::DefaultData) == true)
return ICON_AIRPLANE;
else if ((MyEntity->IsDerivedFrom(Building::DefaultData) == true) || (MyEntity->IsDerivedFrom(MFB::DefaultData) == true))
return ICON_BUILDING;
else if (MyEntity->IsDerivedFrom(Vehicle::DefaultData) == true)
return ICON_VEHICLE;
else if (MyEntity->IsDerivedFrom(NonCom::DefaultData) == true)
return ICON_NONCOM;
else if (MyEntity->IsDerivedFrom(NavPoint::DefaultData) == true)
return ICON_NAVPOINT;
else if (MyEntity->IsDerivedFrom(Cultural::DefaultData) == true)
return ICON_CULTURAL;
return ICON_NONE;
}
CString EdGameObject::GetTypeName()
{
if (MyEntity != 0)
{
if (MyEntity->IsDerivedFrom(MechWarrior4::Mech::DefaultData) == true)
return "Mech";
else if (MyEntity->IsDerivedFrom(MechWarrior4::Airplane::DefaultData) == true)
return "Airplane";
else if (MyEntity->IsDerivedFrom(MechWarrior4::NonCom::DefaultData) == true)
return "NonCom";
else if (MyEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) == true)
return "Vehicle";
else if (MyEntity->IsDerivedFrom(MechWarrior4::Building::DefaultData) == true)
return "Building";
else if (MyEntity->IsDerivedFrom(MechWarrior4::Flag::DefaultData) == true)
return "Flag";
else if (MyEntity->IsDerivedFrom(MechWarrior4::NavPoint::DefaultData) == true)
return "NavPoint";
else if (MyEntity->IsDerivedFrom(MechWarrior4::MWObject::DefaultData) == true)
return "Cultural";
}
return "Game Object";
}
int EdGameObject::AddToList(CObjManListCtrl *list,unsigned long tagflag)
{
if(IsHidden()) return -1;
LVITEM lvitm;
int idx=EdGUIObject::AddToList(list,tagflag);
ZeroMemory(&lvitm,sizeof(lvitm));
lvitm.mask=LVIF_TEXT;
lvitm.iItem=idx;
CString str;
if(tagflag&TAG_ALIGNMENT)
{
lvitm.iSubItem=list->GetColWithID(TAGI_ALIGNMENT);
lvitm.pszText=(char *)Entity::AlignmentAsciiToText(GetAlignment());
list->SetItem(&lvitm);
}
if(tagflag&TAG_AINAME)
{
lvitm.iSubItem=list->GetColWithID(TAGI_AINAME);
str="None";
if (MyEntity != 0 && MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
if(mwobject->GetAI())
{
str=mwobject->GetAI()->instanceName;
}
}
lvitm.pszText=str.GetBuffer(0);
list->SetItem(&lvitm);
}
if(tagflag&TAG_AITYPE)
{
lvitm.iSubItem=list->GetColWithID(TAGI_AITYPE);
str=GetAIType();
lvitm.pszText=str.GetBuffer(0);
list->SetItem(&lvitm);
}
if(tagflag&TAG_SKINTYPE)
{
lvitm.iSubItem=list->GetColWithID(TAGI_SKINTYPE);
str=GetSkinText();
lvitm.pszText=str.GetBuffer(0);
list->SetItem(&lvitm);
}
if(tagflag&TAG_SCRIPT)
{
lvitm.iSubItem=list->GetColWithID(TAGI_SCRIPT);
str="None";
if (MyEntity != 0 && MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
if ((mwobject->GetAI() != 0) &&
(mwobject->GetAI()->GetScriptName() != 0))
{
int pos;
str=mwobject->GetAI()->GetScriptName();
pos=str.ReverseFind('\\');
if(pos>0) str=str.Mid(pos+1);
}
}
lvitm.pszText=str.GetBuffer(0);
list->SetItem(&lvitm);
}
return idx;
}
void EdGameObject::DrawTileViolation(DrawInfo &dinf)
{
if(!IsMultiTile()) return;
dinf.SetPen(DrawInfo::WarningPen);
Point3D start,end;
CPoint p1,p2;
if(MyEntity->GetMinTileRow() != MyEntity->GetMaxTileRow())
{
start.y=end.y=0.0f;
start.z=end.z=MyEntity->GetMaxTileRow()*Adept::c_TileSize-dinf.vinf.GetMapSize().x*0.5f;
start.x=MyEntity->GetMaxTileCol()*Adept::c_TileSize-dinf.vinf.GetMapSize().z*0.5f;
end.x=start.x+c_TileSize;
p1=dinf.vinf.DataToScreen(start);
p2=dinf.vinf.DataToScreen(end);
dinf.GetDC()->MoveTo(p1);
dinf.GetDC()->LineTo(p2);
}
if(MyEntity->GetMinTileCol() != MyEntity->GetMaxTileCol())
{
start.y=end.y=0.0f;
start.x=end.x=MyEntity->GetMaxTileCol()*c_TileSize-dinf.vinf.GetMapSize().z*0.5f;
start.z=MyEntity->GetMaxTileRow()*c_TileSize-dinf.vinf.GetMapSize().x*0.5f;
end.z=start.z+c_TileSize;
p1=dinf.vinf.DataToScreen(start);
p2=dinf.vinf.DataToScreen(end);
dinf.GetDC()->MoveTo(p1);
dinf.GetDC()->LineTo(p2);
}
}
void EdGameObject::Draw(DrawInfo &dinf)
{
if(IsHidden() || !InDisplayRegion(dinf)) return;
SetPen(dinf);
if(DrawFromOBB)
{
Verify(MyEntity && InMap);
Verify(MyEntity->GetSolidVolume()!=NULL);
Point3D center=GetPos();
const OBB &obbTmp=MyEntity->GetSolidVolume()->m_localSpaceBounds;
Verify(obbTmp.axisExtents.x!=0.0f && obbTmp.axisExtents.z!=0.0f);
LinearMatrix4D mat,mat1,mat2;
mat1=MyEntity->GetLocalToWorld();
mat2=obbTmp.localToParent;
mat.Multiply(mat2,mat1);
mat.Normalize();
YawPitchRoll ypr;
ypr=mat;
if(Small_Enough(ypr.pitch) && Small_Enough(ypr.roll))
{ // This is not really a box just a square from this view
if(Close_Enough(ypr.yaw,0.0f) || Close_Enough(ypr.yaw,Pi)) //Special ops for regular squares
{
Point3D tl,br;
CPoint p1,p2;
tl.x=center.x-obbTmp.axisExtents.x;
tl.z=center.z-obbTmp.axisExtents.z;
br.x=center.x+obbTmp.axisExtents.x;
br.z=center.z+obbTmp.axisExtents.z;
p1=dinf.vinf.DataToScreen(tl);
p2=dinf.vinf.DataToScreen(br);
dinf.GetDC()->Rectangle(p1.x,p1.y,p2.x,p2.y);
}
else if(Close_Enough(ypr.yaw,Pi_Over_2) || Close_Enough(ypr.yaw,Two_Pi/3.0f))
{
Point3D tl,br;
CPoint p1,p2;
tl.z=center.z-obbTmp.axisExtents.x;
tl.x=center.x-obbTmp.axisExtents.z;
br.z=center.z+obbTmp.axisExtents.x;
br.x=center.x+obbTmp.axisExtents.z;
p1=dinf.vinf.DataToScreen(tl);
p2=dinf.vinf.DataToScreen(br);
dinf.GetDC()->Rectangle(p1.x,p1.y,p2.x,p2.y);
}
else
{
UnitVector3D uvect;
Vector3D vect1,vect3;
Point3D tpnt1,tpnt2;
mat.GetLocalLeftInWorld(&uvect);
vect1.Multiply(uvect,obbTmp.axisExtents.x);
mat.GetLocalForwardInWorld(&uvect);
vect3.Multiply(uvect,obbTmp.axisExtents.z);
CPoint start;
tpnt1.Add(center,vect1);
tpnt2.Add(tpnt1,vect3);
start=dinf.vinf.DataToScreen(tpnt2);
dinf.GetDC()->MoveTo(start);
tpnt2.Subtract(tpnt1,vect3);
dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(tpnt2));
tpnt1.Subtract(center,vect1);
tpnt2.Subtract(tpnt1,vect3);
dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(tpnt2));
tpnt2.Add(tpnt1,vect3);
dinf.GetDC()->LineTo(dinf.vinf.DataToScreen(tpnt2));
dinf.GetDC()->LineTo(start);
}
}
else
{
UnitVector3D uvect;
Vector3D vect1,vect2,vect3;
Point3D tpnt,tpnt2,tpnt3;
mat.GetLocalLeftInWorld(&uvect);
vect1.Multiply(uvect,obbTmp.axisExtents.x);
mat.GetLocalUpInWorld(&uvect);
vect2.Multiply(uvect,obbTmp.axisExtents.y);
mat.GetLocalForwardInWorld(&uvect);
vect3.Multiply(uvect,obbTmp.axisExtents.z);
CPoint pnts[8];
tpnt.Add(center,vect1);
tpnt2.Add(tpnt,vect2);
tpnt3.Add(tpnt2,vect3);
pnts[0]=dinf.vinf.DataToScreen(tpnt3);
tpnt3.Subtract(tpnt2,vect3);
pnts[1]=dinf.vinf.DataToScreen(tpnt3);
tpnt2.Subtract(tpnt,vect2);
tpnt3.Add(tpnt2,vect3);
pnts[2]=dinf.vinf.DataToScreen(tpnt3);
tpnt3.Subtract(tpnt2,vect3);
pnts[3]=dinf.vinf.DataToScreen(tpnt3);
tpnt.Subtract(center,vect1);
tpnt2.Add(tpnt,vect2);
tpnt3.Add(tpnt2,vect3);
pnts[4]=dinf.vinf.DataToScreen(tpnt3);
tpnt3.Subtract(tpnt2,vect3);
pnts[5]=dinf.vinf.DataToScreen(tpnt3);
tpnt2.Subtract(tpnt,vect2);
tpnt3.Add(tpnt2,vect3);
pnts[6]=dinf.vinf.DataToScreen(tpnt3);
tpnt3.Subtract(tpnt2,vect3);
pnts[7]=dinf.vinf.DataToScreen(tpnt3);
dinf.GetDC()->MoveTo(pnts[0]);
dinf.GetDC()->LineTo(pnts[1]);
dinf.GetDC()->LineTo(pnts[3]);
dinf.GetDC()->LineTo(pnts[2]);
dinf.GetDC()->LineTo(pnts[0]);
dinf.GetDC()->LineTo(pnts[4]);
dinf.GetDC()->LineTo(pnts[5]);
dinf.GetDC()->LineTo(pnts[7]);
dinf.GetDC()->LineTo(pnts[6]);
dinf.GetDC()->LineTo(pnts[4]);
dinf.GetDC()->MoveTo(pnts[1]);
dinf.GetDC()->LineTo(pnts[5]);
dinf.GetDC()->MoveTo(pnts[3]);
dinf.GetDC()->LineTo(pnts[7]);
dinf.GetDC()->MoveTo(pnts[2]);
dinf.GetDC()->LineTo(pnts[6]);
}
}
else
{
EdGUIObject::Draw(dinf);
if(MyEntity->IsDerivedFrom(WaterCultural::DefaultData))
{
int rad=GetScreenRadius(dinf.vinf);
CPoint spnt,pnt=dinf.vinf.DataToScreen(GetPos());
CDC *pDC=dinf.GetDC();
CRect rct;
CPoint pstart;
CPoint pend;
int clines=3;
for(int lnum=0;lnum<clines;lnum++)
{
rct.left=pnt.x-rad;
rct.right=pnt.x;
rct.top=(pnt.y-rad)+(lnum*rad*2)/clines;
rct.bottom=(pnt.y-rad)+((lnum+1)*rad*2)/clines;
pstart.x=rct.left;
pstart.y=rct.CenterPoint().y;
pend.x=rct.right;
pend.y=rct.CenterPoint().y;
pDC->SetArcDirection(AD_CLOCKWISE);
pDC->Arc(&rct,pstart,pend);
rct.left=pnt.x;
rct.right=pnt.x+rad;
rct.top=(pnt.y-rad)+(lnum*rad*2)/clines;
rct.bottom=(pnt.y-rad)+((lnum+1)*rad*2)/clines;
pstart.x=rct.left;
pstart.y=rct.CenterPoint().y;
pend.x=rct.right;
pend.y=rct.CenterPoint().y;
pDC->SetArcDirection(AD_COUNTERCLOCKWISE);
pDC->Arc(&rct,pstart,pend);
}
}
}
}
void EdGameObject::GetMultiProps(CObjProps *props)
{
props->SetModTagFrom(this);
}
void EdGameObject::SetMultiProps(CObjProps *props,UndoCommand **cmd)
{
props->SetData(this,cmd);
}
bool EdGameObject::HasLocalizedName()
{
if(!MyEntity) return false;
Check_Object(MyEntity);
if (MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
return mwobject->m_doesHaveInstanceName;
}
else
{
return false;
}
}
void EdGameObject::UseLocalizedName(bool flag)
{
if (MyEntity && MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
Check_Object(MyEntity);
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
mwobject->m_doesHaveInstanceName=flag;
}
}
void EdGameObject::FillSkinList(CComboBox *ctrl)
{
ctrl->ResetContent();
int i,itm;
if(MyEntity && MyEntity->IsDerivedFrom(Mech::DefaultData))
{
for(i=0;i<GetSkinCount();i++)
{
itm=ctrl->AddString(GetNthSkinName(i));
ctrl->SetItemData(itm,GetNthSkin(i));
}
}
/*
else if(MyEntity && MyEntity->IsDerivedFrom(Vehicle::DefaultData))
{
for(i=0;i<2;i++) ctrl->AddString(SkinToText(i));
}
*/
}
CString EdGameObject::SkinToText(char skin)
{
return GetSkinName(skin);
/*
if(MyEntity && MyEntity->IsDerivedFrom(Mech::DefaultData))
{
switch(skin)
{
case DefaultSkin: return ("Default Skin"); break;
case LunarFriend: return ("Lunar Friend"); break;
case LunarEnemy: return ("Lunar Enemy"); break;
case ArticFriend: return ("Artic Friend"); break;
case ArticEnemy: return ("Artic Enemy"); break;
case AlpineFriend:return ("Alpine Friend"); break;
case AlpineEnemy: return ("Alpine Enemy"); break;
case DesertFriend:return ("Desert Friend"); break;
case DesertEnemy: return ("Desert Enemy"); break;
case SwampFriend: return ("Swamp Friend"); break;
case SwampEnemy: return ("Swamp Enemy"); break;
}
}
*/
/*
else
if(MyEntity && MyEntity->IsDerivedFrom(Vehicle::DefaultData))
{
switch(skin)
{
case VehicleEnemySkin: return ("Vehicle Enemy"); break;
case VehicleFriendlySkin: return ("Vehicle Friendly"); break;
}
}
*/
return ("UnSkinable");
}
bool EdGameObject::IsInvulnerable()
{
if (MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
Check_Object(mwobject);
return mwobject->invulnerable;
}
return false;
}
void EdGameObject::SetInvulnerable(bool inv)
{
if (MyEntity->IsDerivedFrom(MWObject::DefaultData))
{
MechWarrior4::MWObject* mwobject = Cast_Object(MWObject*,MyEntity);
Check_Object(mwobject);
mwobject->invulnerable=inv;
// If object is vulnerable and has no damage object
// rebuild from content and get the damage resource id
if (!mwobject->invulnerable && mwobject->damageStreamResourceID == ResourceID::Null)
{
EdGameObject* obj = new EdGameObject();
obj->BuildFrom(ResourcePath, CString("@#test213"));
ASSERT(obj->MyEntity->IsDerivedFrom(MWObject::DefaultData));
MechWarrior4::MWObject* newmwobject = Cast_Object(MWObject*,obj->MyEntity);
mwobject->damageStreamResourceID = newmwobject->damageStreamResourceID;
delete obj;
}
}
}
void EdGameObject::SaveTextInfo(NotationFile *not_file)
{
EdGUIObject::SaveTextInfo(not_file);
if(IsInvulnerable())
{
Page *page=not_file->SetPage((char *)(LPCSTR)GetName());
page->SetEntry("Invulnerable",true);
}
}
void EdGameObject::SetInfo(Page *page)
{
EdGUIObject::SetInfo(page);
bool inv;
if(page->GetEntry("Invulnerable",&inv)) SetInvulnerable(inv);
}