On-demand loading of actors (sort of)

This was SVN commit r2017.
This commit is contained in:
Ykkrosh 2005-03-19 11:55:27 +00:00
parent 219509f00f
commit 79da4bf050
14 changed files with 199 additions and 168 deletions

View File

@ -83,11 +83,7 @@ void CMapReader::UnpackObjects(CFileUnpacker& unpacker)
unpacker.UnpackRaw(&numObjTypes,sizeof(numObjTypes));
m_ObjectTypes.resize(numObjTypes);
for (uint i=0;i<numObjTypes;i++) {
CStr objname;
unpacker.UnpackString(objname);
CObjectEntry* object=g_ObjMan.FindObject((const char*) objname);
m_ObjectTypes[i]=object;
unpacker.UnpackString(m_ObjectTypes[i]);
}
// unpack object data
@ -168,15 +164,13 @@ TIMER(____CMapReader__ApplyData);
// add new objects
for (u32 i=0;i<m_Objects.size();i++) {
CObjectEntry* objentry=m_ObjectTypes[m_Objects[i].m_ObjectIndex];
if (objentry && objentry->m_Model) {
if (unpacker.GetVersion() < 3) {
// Hijack the standard actor instantiation for actors that correspond to entities.
// Not an ideal solution; we'll have to figure out a map format that can define entities separately or somesuch.
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(objentry);
CBaseEntity* templateObject = g_EntityTemplateCollection.getTemplateByActor(m_ObjectTypes.at(m_Objects[i].m_ObjectIndex));
if (templateObject)
{
@ -189,14 +183,13 @@ TIMER(____CMapReader__ApplyData);
}
}
CUnit* unit=new CUnit(objentry,objentry->m_Model->Clone());
CUnit* unit = g_UnitMan.CreateUnit(m_ObjectTypes.at(m_Objects[i].m_ObjectIndex), NULL);
if (unit)
{
CMatrix3D transform;
memcpy(&transform._11,m_Objects[i].m_Transform,sizeof(float)*16);
unit->GetModel()->SetTransform(transform);
// add this unit to list of units stored in unit manager
pUnitMan->AddUnit(unit);
}
}

View File

@ -45,7 +45,7 @@ private:
// tile descriptions for each tile
std::vector<STileDesc> m_Tiles;
// list of object types used by map
std::vector<CObjectEntry*> m_ObjectTypes;
std::vector<CStr> m_ObjectTypes;
// descriptions for each objects
std::vector<SObjectDesc> m_Objects;
// lightenv stored in file

View File

@ -194,6 +194,7 @@ CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName )
bool CObjectEntry::Load(const char* filename)
{
//static int x=0; debug_out("load %s %d\n", filename, ++x);
CXeromyces XeroFile;
if (XeroFile.Load(filename) != PSRETURN_OK)
@ -332,6 +333,8 @@ bool CObjectEntry::Load(const char* filename)
std::vector< std::vector<Variant> > actorVariants;
// (This code is rather worryingly verbose...)
XERO_ITER_EL(root, child)
{
int element_name = child.getNodeName();
@ -540,3 +543,47 @@ CObjectEntry::Prop* CObjectEntry::FindProp(const char* proppointname)
return 0;
}
// TODO: Remove this, once all the actors are renamed properly
bool CObjectEntry::LoadName(const CStr& filename, CStr& out)
{
CXeromyces XeroFile;
if (XeroFile.Load(filename) != PSRETURN_OK)
return false;
XMBElement root = XeroFile.getRoot();
if (root.getNodeName() == XeroFile.getElementID("object"))
{
//// Old-format actor file ////
#define EL(x) int el_##x = XeroFile.getElementID(#x)
EL(name);
#undef EL
XERO_ITER_EL(root, child)
{
if (child.getNodeName() == el_name)
{
out = child.getText();
return true;
}
}
LOG(ERROR, LOG_CATEGORY, "Invalid actor format (couldn't find 'name')");
return false;
}
else if (root.getNodeName() == XeroFile.getElementID("actor"))
{
//// New-format actor file ////
// Use the filename for the model's name
out = CStr(filename).AfterLast("/").BeforeLast(".xml");
return true;
}
else
{
LOG(ERROR, LOG_CATEGORY, "Invalid actor format (unrecognised root element '%s')", XeroFile.getElementString(root.getNodeName()));
return false;
}
}

View File

@ -40,6 +40,9 @@ public:
bool Load(const char* filename);
bool Save(const char* filename);
// TODO: Remove this, once all the actors are renamed properly
static bool LoadName(const CStr& filename, CStr& out);
Prop* FindProp(const char* proppointname);
// object name

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,9 @@ public:
// index in parent array
int m_Index;
// list of objects of this type (found from the objects directory)
std::vector<CObjectEntry*> m_Objects;
std::map<CStr, CObjectEntry*> m_Objects;
std::map<CStr, CStr> m_ObjectNameToFilename;
};
public:
@ -33,7 +35,6 @@ public:
void AddObjectType(const char* name);
CObjectEntry* FindObject(const char* objname);
CObjectEntry* FindObjectByFileName(const char* filename);
void AddObject(CObjectEntry* entry,int type);
void DeleteObject(CObjectEntry* entry);
@ -43,8 +44,7 @@ public:
std::vector<SObjectType> m_ObjectTypes;
private:
void BuildObjectTypes(const char* basedir);
void LoadObjects(int type);
void LoadObjectsIn(CStr& pathname);
CObjectEntry* m_SelectedObject;
};

View File

@ -13,6 +13,7 @@
#include "UnitManager.h"
#include "Unit.h"
#include "CConsole.h"
#include "ObjectManager.h"
extern CConsole* g_Console;
@ -105,3 +106,17 @@ CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) cons
}
return hit;
}
///////////////////////////////////////////////////////////////////////////////
// CreateUnit: create a new unit and add it to the world
CUnit* CUnitManager::CreateUnit(CStr& actorName, CEntity* entity)
{
CObjectEntry* obj = g_ObjMan.FindObject(actorName);
if (! obj)
return NULL;
CUnit* unit = new CUnit(obj, obj->m_Model->Clone(), entity);
AddUnit(unit);
return unit;
}

View File

@ -14,6 +14,8 @@
class CUnit;
class CVector3D;
class CEntity;
class CStr;
// access to sole CUnitManager object
#define g_UnitMan CUnitManager::GetSingleton()
@ -36,6 +38,9 @@ public:
// remove and delete all units
void DeleteAll();
// creates a new unit and adds it to the world
CUnit* CreateUnit(CStr& actorName, CEntity* entity);
// return the units
const std::vector<CUnit*>& GetUnits() const { return m_Units; }

View File

@ -50,24 +50,6 @@ template<> JSObject* ToScript<CBaseEntity*>( CBaseEntity** Native )
return( ToScript<CBaseEntity>( *Native ) );
}
// CObjectEntry
template<> bool ToPrimitive<CObjectEntry>( JSContext* cx, jsval v, CObjectEntry*& Storage )
{
CStrW ActorName;
if( !ToPrimitive<CStrW>( cx, v, ActorName ) )
return( false );
Storage = g_ObjMan.FindObject( (CStr)ActorName );
return( true );
}
template<> jsval ToJSVal<CObjectEntry>( CObjectEntry*& Native )
{
if( !Native )
return( ToJSVal<CStrW>( CStrW( L"[No actor]" ) ) );
return( ToJSVal<CStrW>( CStrW( Native->m_Name ) ) );
}
// CVector3D
template<> CVector3D* ToNative<CVector3D>( JSContext* cx, JSObject* obj )

View File

@ -17,7 +17,7 @@ CBaseEntity::CBaseEntity()
AddProperty( L"actions.move.turningradius", &m_turningRadius );
AddProperty( L"actions.attack.range", &m_meleeRange );
AddProperty( L"actions.attack.rangemin", &m_meleeRangeMin );
AddProperty( L"actor", &m_actorObject );
AddProperty( L"actor", &m_actorName );
AddProperty( L"traits.extant", &m_extant );
AddProperty( L"traits.corpse", &m_corpse );
@ -26,8 +26,6 @@ CBaseEntity::CBaseEntity()
m_base = NULL;
m_actorObject = NULL;
// Initialize, make life a little easier on the scriptors
m_speed = m_turningRadius = m_meleeRange = m_meleeRangeMin = 0.0f;
m_extant = true; m_corpse = CStrW();

View File

@ -46,7 +46,7 @@ public:
CStrW m_Base_Name; // <- We don't guarantee the order XML files will be loaded in, so we'll store the name of the
// parent entity referenced, then, after all files are loaded, attempt to match names to objects.
CObjectEntry* m_actorObject;
CStrW m_actorName;
CStrW m_Tag;

View File

@ -120,10 +120,10 @@ CBaseEntity* CBaseEntityCollection::getTemplate( CStrW name )
return( NULL );
}
CBaseEntity* CBaseEntityCollection::getTemplateByActor( CObjectEntry* actor )
CBaseEntity* CBaseEntityCollection::getTemplateByActor( CStrW actorName )
{
for( u16 t = 0; t < m_templates.size(); t++ )
if( m_templates[t]->m_actorObject == actor ) return( m_templates[t] );
if( m_templates[t]->m_actorName == actorName ) return( m_templates[t] );
return( NULL );
}

View File

@ -35,7 +35,7 @@ public:
void loadTemplates();
void LoadDirectory( Handle directory, CStr pathname );
void addTemplate( CBaseEntity* temp );
CBaseEntity* getTemplateByActor( CObjectEntry* actor );
CBaseEntity* getTemplateByActor( CStrW actorName );
};
#endif

View File

@ -95,13 +95,8 @@ void CEntity::loadBase()
m_bounds = NULL;
}
if( m_base->m_actorObject )
m_actor = new CUnit( m_base->m_actorObject, m_base->m_actorObject->m_Model->Clone(), this );
// Register the actor with the renderer.
if( m_actor )
g_UnitMan.AddUnit( m_actor );
CStr actorName ( m_base->m_actorName ); // convert CStrW->CStr8
m_actor = g_UnitMan.CreateUnit( actorName, this );
// Set up our instance data