Stopped ScEd crashing when loading maps. Avoided crashes from invalid animations. Moved game-specific code out of XMLWriter.
This was SVN commit r1920.
This commit is contained in:
parent
414015ca57
commit
03a6b6e804
@ -149,7 +149,10 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitMan
|
||||
}
|
||||
}
|
||||
|
||||
// empty out existing units
|
||||
// remove all existing entities (by recreating the entity manager)
|
||||
delete &g_EntityManager;
|
||||
new CEntityManager();
|
||||
// delete all remaining non-entity units
|
||||
pUnitMan->DeleteAll();
|
||||
|
||||
// add new objects
|
||||
|
@ -279,7 +279,7 @@ void CMapWriter::WriteXML(const char* filename, CUnitManager* pUnitMan)
|
||||
|
||||
XML_Setting("Template", entity->m_base->m_Tag);
|
||||
|
||||
XML_Setting("Player", entity->GetPlayer());
|
||||
XML_Setting("Player", entity->GetPlayer()->GetPlayerID());
|
||||
|
||||
{
|
||||
CVector3D position = entity->m_position;
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include "MeshManager.h"
|
||||
#include "lib/res/ogl_tex.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
#define LOG_CATEGORY "graphics"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
CModel::CModel()
|
||||
@ -249,6 +252,8 @@ void CModel::GenerateBoneMatrices()
|
||||
{
|
||||
if (!m_Anim || !m_BoneMatrices) return;
|
||||
|
||||
assert(m_pModelDef->GetNumBones() == m_Anim->m_AnimDef->GetNumKeys());
|
||||
|
||||
m_Anim->m_AnimDef->BuildBoneMatrices(m_AnimTime,m_BoneMatrices);
|
||||
|
||||
const CMatrix3D& transform=GetTransform();
|
||||
@ -282,8 +287,9 @@ void CModel::GenerateBoneMatrices()
|
||||
// return false on error, else true
|
||||
bool CModel::SetAnimation(CSkeletonAnim* anim, bool once)
|
||||
{
|
||||
m_Anim=anim;
|
||||
if (m_Anim) {
|
||||
m_Anim=NULL; // in case something fails
|
||||
|
||||
if (anim) {
|
||||
m_Flags &= ~MODELFLAG_NOLOOPANIMATION;
|
||||
if( once )
|
||||
m_Flags |= MODELFLAG_NOLOOPANIMATION;
|
||||
@ -293,8 +299,10 @@ bool CModel::SetAnimation(CSkeletonAnim* anim, bool once)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_Anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
|
||||
if (anim->m_AnimDef->GetNumKeys()!=m_pModelDef->GetNumBones()) {
|
||||
// mismatch between model's skeleton and animation's skeleton
|
||||
LOG(ERROR, LOG_CATEGORY, "Mismatch between model's skeleton and animation's skeleton (%d model bones != %d animation keys)",
|
||||
m_pModelDef->GetNumBones(), anim->m_AnimDef->GetNumKeys());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -306,6 +314,8 @@ bool CModel::SetAnimation(CSkeletonAnim* anim, bool once)
|
||||
m_AnimTime=0;
|
||||
}
|
||||
|
||||
m_Anim=anim;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ CModelDef* CModelDef::Load(const char* filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
} catch (CFileUnpacker::CFileEOFError) {
|
||||
delete mdef;
|
||||
throw CFileUnpacker::CFileEOFError();
|
||||
}
|
||||
|
@ -73,28 +73,28 @@ bool CObjectEntry::BuildModel()
|
||||
m_Model->CalcObjectBounds();
|
||||
|
||||
// load animations
|
||||
for( uint t = 0; t < m_Animations.size(); t++ )
|
||||
for (uint t = 0; t < m_Animations.size(); t++)
|
||||
{
|
||||
if( m_Animations[t].m_FileName.Length() > 0 )
|
||||
if (m_Animations[t].m_FileName.Length() > 0)
|
||||
{
|
||||
const char* animfilename = m_Animations[t].m_FileName.c_str();
|
||||
m_Animations[t].m_AnimData = m_Model->BuildAnimation(animfilename,m_Animations[t].m_Speed);
|
||||
|
||||
CStr AnimNameLC = m_Animations[t].m_AnimName.LowerCase();
|
||||
|
||||
if( AnimNameLC == "idle" )
|
||||
if (AnimNameLC == "idle")
|
||||
m_IdleAnim = m_Animations[t].m_AnimData;
|
||||
else
|
||||
if( AnimNameLC == "walk" )
|
||||
if (AnimNameLC == "walk")
|
||||
m_WalkAnim = m_Animations[t].m_AnimData;
|
||||
else
|
||||
if( AnimNameLC == "attack" )
|
||||
if (AnimNameLC == "attack")
|
||||
m_MeleeAnim = m_Animations[t].m_AnimData;
|
||||
else
|
||||
if( AnimNameLC == "death" )
|
||||
if (AnimNameLC == "death")
|
||||
m_DeathAnim = m_Animations[t].m_AnimData;
|
||||
else
|
||||
if( AnimNameLC == "decay" )
|
||||
if (AnimNameLC == "decay")
|
||||
m_CorpseAnim = m_Animations[t].m_AnimData;
|
||||
//else
|
||||
// debug_out("Invalid animation name '%s'\n", (const char*)AnimNameLC);
|
||||
@ -106,7 +106,8 @@ bool CObjectEntry::BuildModel()
|
||||
}
|
||||
}
|
||||
// start up idling
|
||||
m_Model->SetAnimation( m_IdleAnim );
|
||||
if (! m_Model->SetAnimation(m_IdleAnim))
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to set idle animation in model \"%s\"", modelfilename);
|
||||
|
||||
// build props - TODO, RC - need to fix up bounds here
|
||||
for (uint p=0;p<m_Props.size();p++) {
|
||||
|
@ -25,7 +25,7 @@ protected:
|
||||
|
||||
public:
|
||||
/*
|
||||
Note: This constructer takes over ownership of the passed pipe end. It
|
||||
Note: This constructor takes over ownership of the passed pipe end. It
|
||||
should not be freed by the caller, and should be heap-allocated.
|
||||
*/
|
||||
inline CNetSession(MessageHandler *pMsgHandler=NULL):
|
||||
|
@ -20,16 +20,20 @@ void CWorld::Initialize(CGameAttributes *pAttribs)
|
||||
{
|
||||
g_EntityTemplateCollection.loadTemplates();
|
||||
|
||||
CStr mapfilename("maps/scenarios/");
|
||||
// Load the map, if one was specified
|
||||
if (pAttribs->m_MapFile.Length())
|
||||
{
|
||||
CStr mapfilename("maps/scenarios/");
|
||||
|
||||
mapfilename += (CStr)pAttribs->m_MapFile;
|
||||
mapfilename += (CStr)pAttribs->m_MapFile;
|
||||
|
||||
try {
|
||||
CMapReader reader;
|
||||
reader.LoadMap(mapfilename, &m_Terrain, &m_UnitManager, &g_LightEnv);
|
||||
} catch (...) {
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to load map %s", mapfilename.c_str());
|
||||
throw PSERROR_Game_World_MapLoadFailed();
|
||||
try {
|
||||
CMapReader reader;
|
||||
reader.LoadMap(mapfilename, &m_Terrain, &m_UnitManager, &g_LightEnv);
|
||||
} catch (...) {
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to load map %s", mapfilename.c_str());
|
||||
throw PSERROR_Game_World_MapLoadFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,10 @@
|
||||
|
||||
#include "XMLWriter.h"
|
||||
|
||||
// TODO: (MT) Someone who knows what this is supposed to do, please take a look at CPlayer and make sure it's doing what it's supposed to.
|
||||
|
||||
#include "Player.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "lib/res/vfs.h"
|
||||
|
||||
// TODO: Write to the VFS handle all the time frequently, instead of buffering
|
||||
// TODO (maybe): Write to the VFS handle frequently, instead of buffering
|
||||
// the entire file, so that large files get written faster.
|
||||
|
||||
enum { EL_ATTR, EL_TEXT, EL_SUBEL };
|
||||
@ -145,7 +142,11 @@ template <> void XMLWriter_File::ElementAttribute<CStr>(const char* name, const
|
||||
}
|
||||
}
|
||||
|
||||
// Attribute/setting value-to-string template specialisations:
|
||||
// Attribute/setting value-to-string template specialisations.
|
||||
//
|
||||
// These only deal with basic types. Anything more complicated should
|
||||
// be converted into a basic type by whatever is making use of XMLWriter,
|
||||
// to keep game-related logic out of the not-directly-game-related code here.
|
||||
|
||||
// Use CStr's conversion for most types:
|
||||
#define TYPE2(ID_T, ARG_T) \
|
||||
@ -163,12 +164,10 @@ TYPE(double)
|
||||
// Weird - I know ;-)
|
||||
TYPE2(const char *, char const* const&)
|
||||
|
||||
// Encode Unicode strings as UTF-8 (though that will only be correct if
|
||||
// the encoding was set to "utf-8"; it'll look a little odd if you store
|
||||
// Unicode strings in an iso-8859-1 file, so please don't do that)
|
||||
template <> void XMLWriter_File::ElementAttribute<CStrW>(const char* name, const CStrW& value, bool newelement)
|
||||
{
|
||||
ElementAttribute(name, value.utf8(), newelement);
|
||||
}
|
||||
|
||||
template <> void XMLWriter_File::ElementAttribute<CPlayer*>(const char* name, CPlayer*const & value, bool newelement)
|
||||
{
|
||||
ElementAttribute(name, value->GetPlayerID(), newelement);
|
||||
}
|
||||
|
@ -161,6 +161,9 @@ static bool saveTGA(const char* filename,int width,int height,unsigned char* dat
|
||||
// Init: perform one time initialisation of the editor
|
||||
bool CEditorData::Init()
|
||||
{
|
||||
// Set attributes for the game
|
||||
g_GameAttributes.m_MapFile = L""; // start without a map
|
||||
|
||||
// Set up the actual game
|
||||
g_Game = new CGame();
|
||||
PSRETURN ret = g_Game->StartGame(&g_GameAttributes);
|
||||
|
@ -75,11 +75,7 @@ void CSelectObjectTool::SelectObject(unsigned int flags,int px,int py)
|
||||
// RenderUnitBounds: render a bounding box round given unit
|
||||
void CSelectObjectTool::RenderUnitBounds(CUnit* unit)
|
||||
{
|
||||
glPushMatrix();
|
||||
const CMatrix3D& transform=unit->GetModel()->GetTransform();
|
||||
glMultMatrixf(&transform._11);
|
||||
|
||||
const CBound& bounds=unit->GetModel()->GetObjectBounds();
|
||||
const CBound& bounds=unit->GetModel()->GetBounds();
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(bounds[0].X,bounds[0].Y,bounds[0].Z);
|
||||
@ -108,8 +104,6 @@ void CSelectObjectTool::RenderUnitBounds(CUnit* unit)
|
||||
glVertex3f(bounds[1].X,bounds[1].Y,bounds[1].Z);
|
||||
glVertex3f(bounds[1].X,bounds[1].Y,bounds[0].Z);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user