forked from 0ad/0ad
ScEd: Added unit deletion. Made zoom less frustrating. Let >2 players work.
Fixed random actor props. This was SVN commit r2109.
This commit is contained in:
parent
a948e4687b
commit
6a0b5fa0ab
@ -17,6 +17,7 @@
|
||||
#include "SkeletonAnimManager.h"
|
||||
#include "MeshManager.h"
|
||||
#include "lib/res/ogl_tex.h"
|
||||
#include "lib/res/h_mgr.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
#define LOG_CATEGORY "graphics"
|
||||
@ -366,6 +367,7 @@ CModel* CModel::Clone() const
|
||||
clone->m_ObjectBounds=m_ObjectBounds;
|
||||
clone->InitModel(m_pModelDef);
|
||||
clone->SetTexture(m_Texture);
|
||||
if (m_Texture.GetHandle()) h_add_ref(m_Texture.GetHandle());
|
||||
clone->SetMaterial(m_Material);
|
||||
clone->SetAnimation(m_Anim);
|
||||
clone->SetPlayerID(m_PlayerID);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "ObjectBase.h"
|
||||
|
||||
#include "ObjectManager.h"
|
||||
#include "Xeromyces.h"
|
||||
#include "CLogger.h"
|
||||
|
||||
@ -352,9 +353,41 @@ void CObjectBase::CalculateVariation(std::set<CStr>& strings, variation_key& cho
|
||||
}
|
||||
}
|
||||
|
||||
assert(randNum < 0); // which should always happen; otherwise it
|
||||
// wouldn't have chosen any of the variants.
|
||||
assert(randNum < 0);
|
||||
// This should always happen; otherwise it
|
||||
// wouldn't have chosen any of the variants.
|
||||
}
|
||||
|
||||
assert(choices.size() == m_Variants.size());
|
||||
|
||||
|
||||
// Also, make choices for all props:
|
||||
|
||||
// Work out which props have been chosen
|
||||
std::map<CStr, CStr> chosenProps;
|
||||
CObjectBase::variation_key::const_iterator choice_it = choices.begin();
|
||||
for (std::vector<std::vector<CObjectBase::Variant> >::iterator grp = m_Variants.begin();
|
||||
grp != m_Variants.end();
|
||||
++grp)
|
||||
{
|
||||
CObjectBase::Variant& var (grp->at(*(choice_it++)));
|
||||
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
|
||||
{
|
||||
chosenProps[it->m_PropPointName] = it->m_ModelName;
|
||||
}
|
||||
}
|
||||
|
||||
// Load each prop, and call CalculateVariation on them:
|
||||
for (std::map<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
|
||||
{
|
||||
CObjectBase* prop = g_ObjMan.FindObjectBase(it->second);
|
||||
if (prop)
|
||||
{
|
||||
variation_key propChoices;
|
||||
prop->CalculateVariation(strings, propChoices);
|
||||
choices.insert(choices.end(), propChoices.begin(), propChoices.end());
|
||||
}
|
||||
}
|
||||
|
||||
// (TODO: This seems rather fragile, e.g. if props fail to load)
|
||||
}
|
||||
|
@ -40,20 +40,68 @@ CObjectEntry::~CObjectEntry()
|
||||
delete m_Model;
|
||||
}
|
||||
|
||||
bool CObjectEntry::BuildModel()
|
||||
bool CObjectEntry::BuildRandomVariant(CObjectBase::variation_key& vars, CObjectBase::variation_key::iterator& vars_it)
|
||||
{
|
||||
// check we've enough data to consider building the object
|
||||
if (m_ModelName.Length()==0 || m_TextureName.Length()==0) {
|
||||
return false;
|
||||
CStr chosenTexture;
|
||||
CStr chosenModel;
|
||||
std::map<CStr, CObjectBase::Prop> chosenProps;
|
||||
std::map<CStr, CObjectBase::Anim> chosenAnims;
|
||||
|
||||
// For each group in m_Base->m_Variants, take whichever variant is specified
|
||||
// by 'vars', and then store its data into the 'chosen' variables. If data
|
||||
// is specified more than once, the last value overrides all previous ones.
|
||||
|
||||
for (std::vector<std::vector<CObjectBase::Variant> >::iterator grp = m_Base->m_Variants.begin();
|
||||
grp != m_Base->m_Variants.end();
|
||||
++grp)
|
||||
{
|
||||
if (vars_it == vars.end())
|
||||
{
|
||||
debug_warn("BuildRandomVariant is using too many vars");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the correct variant
|
||||
CObjectBase::Variant& var (grp->at(*(vars_it++)));
|
||||
|
||||
// Apply its data:
|
||||
|
||||
if (var.m_TextureFilename.Length())
|
||||
chosenTexture = var.m_TextureFilename;
|
||||
|
||||
if (var.m_ModelFilename.Length())
|
||||
chosenModel = var.m_ModelFilename;
|
||||
|
||||
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
|
||||
chosenProps[it->m_PropPointName] = *it;
|
||||
|
||||
for (std::vector<CObjectBase::Anim>::iterator it = var.m_Anims.begin(); it != var.m_Anims.end(); ++it)
|
||||
chosenAnims[it->m_AnimName] = *it;
|
||||
}
|
||||
|
||||
// Copy the chosen data onto this model:
|
||||
|
||||
m_TextureName = chosenTexture;
|
||||
m_ModelName = chosenModel;
|
||||
|
||||
for (std::map<CStr, CObjectBase::Prop>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
|
||||
m_Props.push_back(it->second);
|
||||
|
||||
for (std::map<CStr, CObjectBase::Anim>::iterator it = chosenAnims.begin(); it != chosenAnims.end(); ++it)
|
||||
m_Animations.push_back(it->second);
|
||||
|
||||
|
||||
|
||||
// Build the model:
|
||||
|
||||
|
||||
// get the root directory of this object
|
||||
CStr dirname=g_ObjMan.m_ObjectTypes[m_Type].m_Name;
|
||||
CStr dirname = g_ObjMan.m_ObjectTypes[m_Type].m_Name;
|
||||
|
||||
// remember the old model so we can replace any models using it later on
|
||||
CModelDefPtr oldmodeldef=m_Model ? m_Model->GetModelDef() : CModelDefPtr();
|
||||
CModelDefPtr oldmodeldef = m_Model ? m_Model->GetModelDef() : CModelDefPtr();
|
||||
|
||||
const char* modelfilename = m_ModelName.c_str();
|
||||
const char* modelfilename = m_ModelName;
|
||||
|
||||
// try and create a model
|
||||
CModelDefPtr modeldef (g_MeshManager.GetMesh(modelfilename));
|
||||
@ -65,7 +113,7 @@ bool CObjectEntry::BuildModel()
|
||||
|
||||
// delete old model, create new
|
||||
delete m_Model;
|
||||
m_Model=new CModel;
|
||||
m_Model = new CModel;
|
||||
m_Model->SetTexture((const char*) m_TextureName);
|
||||
m_Model->SetMaterial(g_MaterialManager.LoadMaterial(m_Base->m_Material));
|
||||
m_Model->InitModel(modeldef);
|
||||
@ -74,12 +122,12 @@ bool CObjectEntry::BuildModel()
|
||||
m_Model->CalcObjectBounds();
|
||||
|
||||
// load animations
|
||||
for (uint t = 0; t < m_Animations.size(); t++)
|
||||
for (size_t t = 0; t < m_Animations.size(); t++)
|
||||
{
|
||||
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);
|
||||
const char* animfilename = m_Animations[t].m_FileName;
|
||||
m_Animations[t].m_AnimData = m_Model->BuildAnimation(animfilename, m_Animations[t].m_Speed);
|
||||
|
||||
CStr AnimNameLC = m_Animations[t].m_AnimName.LowerCase();
|
||||
|
||||
@ -103,7 +151,7 @@ bool CObjectEntry::BuildModel()
|
||||
else
|
||||
{
|
||||
// FIXME, RC - don't store invalid animations (possible?)
|
||||
m_Animations[t].m_AnimData=0;
|
||||
m_Animations[t].m_AnimData = NULL;
|
||||
}
|
||||
}
|
||||
// start up idling
|
||||
@ -111,117 +159,92 @@ bool CObjectEntry::BuildModel()
|
||||
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++) {
|
||||
const CObjectBase::Prop& prop=m_Props[p];
|
||||
SPropPoint* proppoint=modeldef->FindPropPoint((const char*) prop.m_PropPointName);
|
||||
if (proppoint) {
|
||||
CObjectEntry* oe=g_ObjMan.FindObject(prop.m_ModelName);
|
||||
if (oe) {
|
||||
// try and build model if we haven't already got it
|
||||
if (!oe->m_Model) oe->BuildModel();
|
||||
if (oe->m_Model) {
|
||||
CModel* propmodel=oe->m_Model->Clone();
|
||||
m_Model->AddProp(proppoint,propmodel);
|
||||
if (oe->m_WalkAnim) propmodel->SetAnimation(oe->m_WalkAnim);
|
||||
} else {
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to build prop model \"%s\" on actor \"%s\"", (const char*)prop.m_ModelName, (const char*)m_Base->m_ShortName);
|
||||
}
|
||||
// TODO: Make sure random variations get handled correctly when a prop fails
|
||||
for (size_t p = 0; p < m_Props.size(); p++)
|
||||
{
|
||||
const CObjectBase::Prop& prop = m_Props[p];
|
||||
SPropPoint* proppoint = modeldef->FindPropPoint((const char*) prop.m_PropPointName);
|
||||
if (proppoint)
|
||||
{
|
||||
CObjectEntry* oe = g_ObjMan.FindObjectVariation(prop.m_ModelName, vars, vars_it);
|
||||
if (oe)
|
||||
{
|
||||
CModel* propmodel = oe->m_Model->Clone();
|
||||
m_Model->AddProp(proppoint, propmodel);
|
||||
if (oe->m_WalkAnim)
|
||||
propmodel->SetAnimation(oe->m_WalkAnim);
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to build prop model \"%s\" on actor \"%s\"", (const char*)prop.m_ModelName, (const char*)m_Base->m_ShortName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" on actor \"%s\"", (const char*)prop.m_PropPointName, modelfilename, (const char*)prop.m_ModelName);
|
||||
}
|
||||
}
|
||||
|
||||
// setup flags
|
||||
if (m_Base->m_Properties.m_CastShadows) {
|
||||
if (m_Base->m_Properties.m_CastShadows)
|
||||
{
|
||||
m_Model->SetFlags(m_Model->GetFlags()|MODELFLAG_CASTSHADOWS);
|
||||
}
|
||||
|
||||
// replace any units using old model to now use new model; also reprop models, if necessary
|
||||
// FIXME, RC - ugh, doesn't recurse correctly through props
|
||||
const std::vector<CUnit*>& units=g_UnitMan.GetUnits();
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
/*
|
||||
// (PT: Removed this, since I'm not entirely sure what it's useful for, and it
|
||||
// gets a bit confusing with randomised actors)
|
||||
|
||||
const std::vector<CUnit*>& units = g_UnitMan.GetUnits();
|
||||
for (size_t i = 0; i < units.size(); ++i)
|
||||
{
|
||||
CModel* unitmodel=units[i]->GetModel();
|
||||
if (unitmodel->GetModelDef()==oldmodeldef) {
|
||||
if (unitmodel->GetModelDef() == oldmodeldef)
|
||||
{
|
||||
unitmodel->InitModel(m_Model->GetModelDef());
|
||||
unitmodel->SetFlags(m_Model->GetFlags());
|
||||
|
||||
const std::vector<CModel::Prop>& newprops=m_Model->GetProps();
|
||||
for (uint j=0;j<newprops.size();j++) {
|
||||
unitmodel->AddProp(newprops[j].m_Point,newprops[j].m_Model->Clone());
|
||||
}
|
||||
const std::vector<CModel::Prop>& newprops = m_Model->GetProps();
|
||||
for (size_t j = 0; j < newprops.size(); j++)
|
||||
unitmodel->AddProp(newprops[j].m_Point, newprops[j].m_Model->Clone());
|
||||
}
|
||||
|
||||
std::vector<CModel::Prop>& mdlprops=unitmodel->GetProps();
|
||||
for (uint j=0;j<mdlprops.size();j++) {
|
||||
CModel::Prop& prop=mdlprops[j];
|
||||
if (prop.m_Model) {
|
||||
if (prop.m_Model->GetModelDef()==oldmodeldef) {
|
||||
std::vector<CModel::Prop>& mdlprops = unitmodel->GetProps();
|
||||
for (size_t j = 0; j < mdlprops.size(); j++)
|
||||
{
|
||||
CModel::Prop& prop = mdlprops[j];
|
||||
if (prop.m_Model)
|
||||
{
|
||||
if (prop.m_Model->GetModelDef() == oldmodeldef)
|
||||
{
|
||||
delete prop.m_Model;
|
||||
prop.m_Model=m_Model->Clone();
|
||||
prop.m_Model = m_Model->Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
void CObjectEntry::ApplyRandomVariant(CObjectBase::variation_key& vars)
|
||||
|
||||
CSkeletonAnim* CObjectEntry::GetNamedAnimation(CStr animationName)
|
||||
{
|
||||
CStr chosenTexture;
|
||||
CStr chosenModel;
|
||||
std::map<CStr, CObjectBase::Prop> chosenProps;
|
||||
std::map<CStr, CObjectBase::Anim> chosenAnims;
|
||||
for (size_t t = 0; t < m_Animations.size(); t++)
|
||||
if (m_Animations[t].m_AnimName == animationName)
|
||||
return m_Animations[t].m_AnimData;
|
||||
|
||||
CObjectBase::variation_key::const_iterator vars_it = vars.begin();
|
||||
|
||||
for (std::vector<std::vector<CObjectBase::Variant> >::iterator grp = m_Base->m_Variants.begin();
|
||||
grp != m_Base->m_Variants.end();
|
||||
++grp)
|
||||
{
|
||||
CObjectBase::Variant& var (grp->at(*(vars_it++)));
|
||||
|
||||
if (var.m_TextureFilename.Length())
|
||||
chosenTexture = var.m_TextureFilename;
|
||||
|
||||
if (var.m_ModelFilename.Length())
|
||||
chosenModel = var.m_ModelFilename;
|
||||
|
||||
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
|
||||
chosenProps[it->m_PropPointName] = *it;
|
||||
|
||||
for (std::vector<CObjectBase::Anim>::iterator it = var.m_Anims.begin(); it != var.m_Anims.end(); ++it)
|
||||
chosenAnims[it->m_AnimName] = *it;
|
||||
}
|
||||
|
||||
m_TextureName = chosenTexture;
|
||||
m_ModelName = chosenModel;
|
||||
|
||||
for (std::map<CStr, CObjectBase::Prop>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
|
||||
m_Props.push_back(it->second);
|
||||
|
||||
for (std::map<CStr, CObjectBase::Anim>::iterator it = chosenAnims.begin(); it != chosenAnims.end(); ++it)
|
||||
m_Animations.push_back(it->second);
|
||||
}
|
||||
|
||||
|
||||
CSkeletonAnim* CObjectEntry::GetNamedAnimation( CStr animationName )
|
||||
{
|
||||
for( uint t = 0; t < m_Animations.size(); t++ )
|
||||
{
|
||||
if( m_Animations[t].m_AnimName == animationName )
|
||||
return( m_Animations[t].m_AnimData );
|
||||
}
|
||||
return( NULL );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CObjectBase::Prop* CObjectEntry::FindProp(const char* proppointname)
|
||||
{
|
||||
for (size_t i=0;i<m_Props.size();i++) {
|
||||
if (strcmp(proppointname,m_Props[i].m_PropPointName)==0) return &m_Props[i];
|
||||
}
|
||||
for (size_t i = 0; i < m_Props.size(); i++)
|
||||
if (strcmp(proppointname, m_Props[i].m_PropPointName) == 0)
|
||||
return &m_Props[i];
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -14,11 +14,9 @@ public:
|
||||
CObjectEntry(int type, CObjectBase* base);
|
||||
~CObjectEntry();
|
||||
|
||||
bool BuildModel();
|
||||
bool BuildRandomVariant(CObjectBase::variation_key& vars, CObjectBase::variation_key::iterator& vars_it);
|
||||
|
||||
void ApplyRandomVariant(CObjectBase::variation_key& var);
|
||||
|
||||
// base actor. Contains all the things that don't change between
|
||||
// Base actor. Contains all the things that don't change between
|
||||
// different variations of the actor.
|
||||
CObjectBase* m_Base;
|
||||
|
||||
|
@ -49,6 +49,7 @@ CObjectManager::~CObjectManager()
|
||||
delete_pair_2nd<CStr, CObjectBase*>
|
||||
);
|
||||
}
|
||||
delete m_SelectedThing;
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +82,7 @@ CObjectBase* CObjectManager::FindObjectBase(const char* objectname)
|
||||
delete obj;
|
||||
}
|
||||
|
||||
LOG(ERROR, LOG_CATEGORY, "CObjectManager::FindObject(): Cannot find object '%s'", objectname);
|
||||
LOG(ERROR, LOG_CATEGORY, "CObjectManager::FindObjectBase(): Cannot find object '%s'", objectname);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -100,9 +101,24 @@ CObjectEntry* CObjectManager::FindObject(const char* objname)
|
||||
CObjectBase::variation_key var;
|
||||
base->CalculateVariation(choices, var);
|
||||
|
||||
return FindObjectVariation(base, var, var.begin());
|
||||
}
|
||||
|
||||
CObjectEntry* CObjectManager::FindObjectVariation(const char* objname, CObjectBase::variation_key vars, CObjectBase::variation_key::iterator& vars_it)
|
||||
{
|
||||
CObjectBase* base = FindObjectBase(objname);
|
||||
|
||||
if (! base)
|
||||
return NULL;
|
||||
|
||||
return FindObjectVariation(base, vars, vars_it);
|
||||
}
|
||||
|
||||
CObjectEntry* CObjectManager::FindObjectVariation(CObjectBase* base, CObjectBase::variation_key vars, CObjectBase::variation_key::iterator& vars_it)
|
||||
{
|
||||
// Look to see whether this particular variation has already been loaded
|
||||
|
||||
ObjectKey key (CStr(objname), var);
|
||||
ObjectKey key (base->m_Name, vars);
|
||||
|
||||
std::map<ObjectKey, CObjectEntry*>::iterator it = m_ObjectTypes[0].m_Objects.find(key);
|
||||
if (it != m_ObjectTypes[0].m_Objects.end())
|
||||
@ -110,11 +126,9 @@ CObjectEntry* CObjectManager::FindObject(const char* objname)
|
||||
|
||||
// If it hasn't been loaded, load it now
|
||||
|
||||
CObjectEntry* obj = new CObjectEntry(0, base); // TODO: type ???
|
||||
CObjectEntry* obj = new CObjectEntry(0, base); // TODO: type ?
|
||||
|
||||
obj->ApplyRandomVariant(var);
|
||||
|
||||
if (! obj->BuildModel())
|
||||
if (! obj->BuildRandomVariant(vars, vars_it))
|
||||
{
|
||||
DeleteObject(obj);
|
||||
return NULL;
|
||||
@ -161,6 +175,9 @@ void CObjectManager::LoadObjects()
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// For ScEd:
|
||||
|
||||
static void GetObjectThunk(const char* path, const vfsDirEnt* ent, void* context)
|
||||
{
|
||||
std::vector<CStr>* names = (std::vector<CStr>*)context;
|
||||
@ -172,13 +189,13 @@ void CObjectManager::GetAllObjectNames(std::vector<CStr>& names)
|
||||
VFSUtil::EnumDirEnts("art/actors/", "*.xml", true, GetObjectThunk, &names);
|
||||
}
|
||||
|
||||
|
||||
struct CObjectThing_Entity : public CObjectThing
|
||||
{
|
||||
CObjectThing_Entity(CBaseEntity* b) : base(b) {}
|
||||
CObjectThing_Entity(CBaseEntity* b) : base(b), obj(g_ObjMan.FindObject((CStr)b->m_actorName)), ent(NULL) {}
|
||||
~CObjectThing_Entity() {}
|
||||
CBaseEntity* base;
|
||||
CEntity* ent;
|
||||
CObjectEntry* obj;
|
||||
void Create(CMatrix3D& transform, int playerID)
|
||||
{
|
||||
CVector3D orient = transform.GetIn();
|
||||
@ -191,7 +208,7 @@ struct CObjectThing_Entity : public CObjectThing
|
||||
CVector3D orient = transform.GetIn();
|
||||
CVector3D position = transform.GetTranslation();
|
||||
|
||||
// This is quite yucky, but nothing else seems to actually work:
|
||||
// This looks quite yucky, but nothing else seems to actually work:
|
||||
ent->m_position =
|
||||
ent->m_position_previous =
|
||||
ent->m_graphics_position = position;
|
||||
@ -203,7 +220,7 @@ struct CObjectThing_Entity : public CObjectThing
|
||||
}
|
||||
CObjectEntry* GetObjectEntry()
|
||||
{
|
||||
return g_ObjMan.FindObject((CStr)base->m_actorName);
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
struct CObjectThing_Object : public CObjectThing
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "CStr.h"
|
||||
#include "ObjectBase.h"
|
||||
|
||||
class CObjectBase;
|
||||
class CObjectEntry;
|
||||
class CBaseEntity;
|
||||
class CMatrix3D;
|
||||
@ -68,6 +67,9 @@ public:
|
||||
|
||||
CObjectBase* FindObjectBase(const char* objname);
|
||||
|
||||
CObjectEntry* FindObjectVariation(const char* objname, CObjectBase::variation_key vars, CObjectBase::variation_key::iterator& vars_it);
|
||||
CObjectEntry* FindObjectVariation(CObjectBase* base, CObjectBase::variation_key vars, CObjectBase::variation_key::iterator& vars_it);
|
||||
|
||||
// Get all names, quite slowly. (Intended only for ScEd.)
|
||||
void GetAllObjectNames(std::vector<CStr>& names);
|
||||
|
||||
|
@ -13,10 +13,10 @@ class CUnit
|
||||
{
|
||||
public:
|
||||
// constructor - unit invalid without a model and object
|
||||
CUnit(CObjectEntry* object,CModel* model) : m_Object(object), m_Model(model), m_Entity( NULL ) {
|
||||
CUnit(CObjectEntry* object,CModel* model) : m_Object(object), m_Model(model), m_Entity(NULL) {
|
||||
assert(object && model);
|
||||
}
|
||||
CUnit(CObjectEntry* object,CModel* model, CEntity* entity) : m_Object(object), m_Model(model), m_Entity( entity ) {
|
||||
CUnit(CObjectEntry* object,CModel* model, CEntity* entity) : m_Object(object), m_Model(model), m_Entity(entity) {
|
||||
assert(object && model);
|
||||
}
|
||||
|
||||
|
@ -1236,6 +1236,12 @@ int debug_assert_failed(const char* file, int line, const char* expr)
|
||||
out(L"Assertion failed in %hs, line %d: \"%hs\"\r\n", file, line, expr);
|
||||
dump_stack(1); // skip this function's frame
|
||||
|
||||
#if defined(SCED) && !(defined(NDEBUG)||defined(TESTING))
|
||||
// ScEd keeps running while the dialog is showing, and tends to crash before
|
||||
// there's a chance to read the assert message. So, just break immediately.
|
||||
debug_break();
|
||||
#endif
|
||||
|
||||
return dialog(ASSERT);
|
||||
}
|
||||
|
||||
|
@ -1446,13 +1446,9 @@ int main(int argc, char* argv[])
|
||||
MICROLOG(L"Init");
|
||||
Init(argc, argv, true);
|
||||
|
||||
// Do some limited tests to ensure things aren't broken
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
extern void PerformTests();
|
||||
PerformTests();
|
||||
}
|
||||
#endif
|
||||
// Optionally, do some simple tests to ensure things aren't broken
|
||||
// extern void PerformTests();
|
||||
// PerformTests();
|
||||
|
||||
while(!quit)
|
||||
{
|
||||
@ -1472,6 +1468,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
void ScEd_Init()
|
||||
{
|
||||
new CProfileManager;
|
||||
|
||||
g_Quickstart = true;
|
||||
|
||||
Init(0, NULL, false);
|
||||
@ -1480,6 +1478,8 @@ void ScEd_Init()
|
||||
void ScEd_Shutdown()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
delete &g_Profiler;
|
||||
}
|
||||
|
||||
#endif // SCED
|
||||
|
@ -132,6 +132,11 @@ void CPlayerSlot::AssignToSessionID(int id)
|
||||
SetAssignment(SLOT_SESSION, NULL, id);
|
||||
}
|
||||
|
||||
void CPlayerSlot::AssignLocal()
|
||||
{
|
||||
AssignToSessionID(1);
|
||||
}
|
||||
|
||||
namespace PlayerSlotArray_JS
|
||||
{
|
||||
JSBool GetProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp )
|
||||
|
@ -95,7 +95,10 @@ public:
|
||||
|
||||
// Reset any assignment the slot might have before and mark the slot as free
|
||||
void AssignOpen();
|
||||
|
||||
|
||||
// Assign to the local player in SP or Server Player in MP
|
||||
void AssignLocal();
|
||||
|
||||
// TODO This will wait until there actually is AI to set up
|
||||
// void AssignAI();
|
||||
};
|
||||
|
@ -165,6 +165,9 @@ bool CEditorData::Init()
|
||||
// Set attributes for the game
|
||||
g_GameAttributes.m_MapFile = L""; // start without a map
|
||||
|
||||
for (int i=1; i<8; ++i)
|
||||
g_GameAttributes.GetSlot(i)->AssignLocal();
|
||||
|
||||
// Set up the actual game
|
||||
g_Game = new CGame();
|
||||
PSRETURN ret = g_Game->StartGame(&g_GameAttributes);
|
||||
@ -603,9 +606,9 @@ void CEditorData::UpdateWorld(float time)
|
||||
for (uint i=0;i<units.size();++i) {
|
||||
units[i]->GetModel()->Update(time);
|
||||
}
|
||||
if (m_Mode==TEST_MODE) {
|
||||
g_EntityManager.updateAll( time );
|
||||
}
|
||||
// if (m_Mode==TEST_MODE) {
|
||||
// g_EntityManager.updateAll( time );
|
||||
// }
|
||||
} else {
|
||||
// CObjectEntry* selobject=g_ObjMan.GetSelectedObject();
|
||||
// if (selobject && selobject->m_Model) {
|
||||
|
@ -22,18 +22,21 @@ void CNaviCam::OnMouseWheelScroll(u32 flags,int px,int py,float dir)
|
||||
float factor=dir*dir;
|
||||
if (dir<0) factor=-factor;
|
||||
|
||||
// check we're not going to zoom into the terrain, or too far out into space
|
||||
float h=m_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*m_CameraZoom;
|
||||
float minh=65536*HEIGHT_SCALE*1.05f;
|
||||
|
||||
if (h<minh || h>1500) {
|
||||
// yup, we will; don't move anywhere (do clamped move instead, at some point)
|
||||
} else {
|
||||
// do a full move
|
||||
m_CameraZoom-=(factor)*0.1f;
|
||||
if (m_CameraZoom<0.01f) m_CameraZoom=0.01f;
|
||||
m_Camera.m_Orientation.Translate(forward*(factor*m_CameraZoom));
|
||||
}
|
||||
// // check we're not going to zoom into the terrain, or too far out into space
|
||||
// float h=m_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*m_CameraZoom;
|
||||
// float minh=65536*HEIGHT_SCALE*1.05f;
|
||||
//
|
||||
// if (h<minh || h>1500) {
|
||||
// // yup, we will; don't move anywhere (do clamped move instead, at some point)
|
||||
// } else {
|
||||
// // do a full move
|
||||
// m_CameraZoom-=(factor)*0.1f;
|
||||
// if (m_CameraZoom<0.1f) m_CameraZoom=0.01f;
|
||||
// m_Camera.m_Orientation.Translate(forward*(factor*m_CameraZoom));
|
||||
// }
|
||||
|
||||
m_Camera.m_Orientation.Translate(forward*(factor*2.5f));
|
||||
|
||||
g_EditorData.OnCameraChanged();
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Renderer.h"
|
||||
#include "UnitManager.h"
|
||||
#include "SelectObjectTool.h"
|
||||
#include "Entity.h"
|
||||
#include <algorithm>
|
||||
|
||||
// default tool instance
|
||||
@ -106,6 +107,19 @@ void CSelectObjectTool::RenderUnitBounds(CUnit* unit)
|
||||
glEnd();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CSelectObjectTool::DeleteSelected()
|
||||
{
|
||||
for (std::vector<CUnit*>::iterator iter = m_SelectedUnits.begin(); iter != m_SelectedUnits.end(); ++iter)
|
||||
{
|
||||
if ((*iter)->GetEntity())
|
||||
(*iter)->GetEntity()->kill();
|
||||
else
|
||||
g_UnitMan.DeleteUnit(*iter);
|
||||
}
|
||||
m_SelectedUnits.clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GetFirstEntity: return the entity of the first selected object
|
||||
|
@ -26,6 +26,8 @@ public:
|
||||
// (TODO: less hackiness, for the whole player-selection system)
|
||||
CEntity* GetFirstEntity();
|
||||
|
||||
void DeleteSelected();
|
||||
|
||||
// get the default select object instance
|
||||
static CSelectObjectTool* GetTool() { return &m_SelectObjectTool; }
|
||||
|
||||
|
@ -21,6 +21,7 @@ void CSmoothElevationTool::SmoothSelection()
|
||||
double curtime=1000*get_time();
|
||||
double elapsed=(curtime-m_LastTriggerTime);
|
||||
|
||||
if (elapsed > 1000.0) elapsed = 1000.0;
|
||||
while (elapsed>=m_SmoothPower) {
|
||||
CSmoothElevationCommand* smoothCmd=new CSmoothElevationCommand(MAX_SMOOTH_POWER,m_BrushSize,m_SelectionCentre);
|
||||
g_CmdMan.Execute(smoothCmd);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "ogl.h"
|
||||
#undef _IGNORE_WGL_H_
|
||||
|
||||
#include "SelectObjectTool.h"
|
||||
#include "Game.h"
|
||||
|
||||
#include "res/vfs.h"
|
||||
@ -572,6 +573,9 @@ BOOL CScEdView::PreTranslateMessage(MSG* pMsg)
|
||||
if (GetAsyncKeyState(VK_CONTROL))
|
||||
mainfrm->OnEditRedo();
|
||||
break;
|
||||
case VK_DELETE:
|
||||
CSelectObjectTool::GetTool()->DeleteSelected();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user