# Use the correct projectile models.

Fixes #470.
Make CUnit::GetObject return a reference so it's clear it can never be
NULL.

This was SVN commit r7463.
This commit is contained in:
Ykkrosh
2010-04-17 11:34:40 +00:00
parent fb72b3c63b
commit 6a9de50692
14 changed files with 72 additions and 26 deletions
+1 -1
View File
@@ -376,7 +376,7 @@ void CMapWriter::WriteXML(const VfsPath& filename,
XML_Element("Nonentity");
XML_Setting("Actor", (*unit)->GetObject()->m_Base->m_Name);
XML_Setting("Actor", (*unit)->GetObject().m_Base->m_Name);
{
CVector3D position = (*unit)->GetModel()->GetTransform().GetTranslation();
+11 -9
View File
@@ -41,7 +41,7 @@
CObjectEntry::CObjectEntry(CObjectBase* base)
: m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f),
m_ProjectileModel(NULL), m_AmmunitionModel(NULL), m_AmmunitionPoint(NULL), m_Model(NULL)
m_AmmunitionModel(NULL), m_AmmunitionPoint(NULL), m_Model(NULL)
{
}
@@ -153,7 +153,14 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
for (size_t p = 0; p < props.size(); p++)
{
const CObjectBase::Prop& prop = props[p];
// Pluck out the special attachpoint 'projectile'
if (prop.m_PropPointName == "projectile")
{
m_ProjectileModelName = prop.m_ModelName.string();
continue;
}
CObjectEntry* oe = objectManager.FindObjectVariation(prop.m_ModelName.string().c_str(), selections);
if (!oe)
{
@@ -161,13 +168,8 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
continue;
}
// Pluck out the special attachpoint 'projectile'
if (prop.m_PropPointName == "projectile")
{
m_ProjectileModel = oe->m_Model;
}
// Also the other special attachpoint 'loaded-<proppoint>'
else if (prop.m_PropPointName.length() > 7 && prop.m_PropPointName.Left(7) == "loaded-")
// Also pluck out the other special attachpoint 'loaded-<proppoint>'
if (prop.m_PropPointName.length() > 7 && prop.m_PropPointName.Left(7) == "loaded-")
{
CStr ppn = prop.m_PropPointName.substr(7);
m_AmmunitionModel = oe->m_Model;
+2 -1
View File
@@ -55,7 +55,8 @@ public:
// so we can have lots of colour variations without wasting memory on
// lots of objectEntries)
CModel* m_ProjectileModel;
CStrW m_ProjectileModelName;
CModel* m_AmmunitionModel;
SPropPoint* m_AmmunitionPoint;
+1 -1
View File
@@ -216,7 +216,7 @@ void CUnit::ReloadObject()
// If these selections give a different object, change this unit to use it
CObjectEntry* newObject = m_ObjectManager.FindObjectVariation(m_Object->m_Base, selections);
if (newObject != m_Object)
if (newObject && newObject != m_Object)
{
// Clone the new object's base (non-instance) model
CModel* newModel = newObject->m_Model->Clone();
+2 -2
View File
@@ -57,8 +57,8 @@ public:
// destructor
~CUnit();
// get unit's template object; never NULL
CObjectEntry* GetObject() const { return m_Object; }
// get unit's template object
const CObjectEntry& GetObject() const { return *m_Object; }
// get unit's model data; never NULL
CModel* GetModel() const { return m_Model; }
// get actor's entity; can be NULL
+4
View File
@@ -66,6 +66,10 @@ void CUnitAnimation::SetAnimationState(const CStr& name, bool once, float speed,
void CUnitAnimation::SetAnimationSync(float actionTime, float repeatTime)
{
CModel* model = m_Unit.GetModel();
if (!model || !model->m_Anim || !model->m_Anim->m_AnimDef)
return;
float duration = model->m_Anim->m_AnimDef->GetDuration();
// Set the speed so it loops once in repeatTime
+1 -1
View File
@@ -136,7 +136,7 @@ CUnit* CUnitManager::PickUnit(const CVector3D& origin, const CVector3D& dir, boo
///////////////////////////////////////////////////////////////////////////////
// CreateUnit: create a new unit and add it to the world
CUnit* CUnitManager::CreateUnit(const CStr& actorName, CEntity* entity, const std::set<CStr>& selections)
CUnit* CUnitManager::CreateUnit(const CStrW& actorName, CEntity* entity, const std::set<CStr>& selections)
{
if (! m_ObjectManager)
return NULL;
+2 -1
View File
@@ -30,6 +30,7 @@ class CVector3D;
class CEntity;
class CObjectManager;
class CStr8;
class CStrW;
///////////////////////////////////////////////////////////////////////////////
// CUnitManager: simple container class holding all units within the world
@@ -50,7 +51,7 @@ public:
void DeleteAll();
// creates a new unit and adds it to the world
CUnit* CreateUnit(const CStr8& actorName, CEntity* entity, const std::set<CStr8>& selections);
CUnit* CreateUnit(const CStrW& actorName, CEntity* entity, const std::set<CStr8>& selections);
// return the units
const std::vector<CUnit*>& GetUnits() const { return m_Units; }
+1 -1
View File
@@ -158,7 +158,7 @@ JSBool CProjectile::Construct( JSContext* cx, JSObject* UNUSED(obj), uintN argc,
Temp = ToNative<CEntity>( argv[0] );
if(Temp)
{
Model = Temp->m_actor->GetObject()->m_ProjectileModel;
// Model = Temp->m_actor->GetObject()->m_ProjectileModel;
if( !Model )
{
err = "No projectile model is defined for that entity's actor.";
@@ -21,6 +21,7 @@
#include "ICmpProjectileManager.h"
#include "ICmpPosition.h"
#include "ICmpVisual.h"
#include "simulation2/MessageTypes.h"
#include "graphics/Frustum.h"
@@ -30,6 +31,7 @@
#include "maths/Matrix3D.h"
#include "maths/Quaternion.h"
#include "maths/Vector3D.h"
#include "ps/CLogger.h"
#include "renderer/Scene.h"
class CCmpProjectileManager : public ICmpProjectileManager
@@ -125,10 +127,20 @@ void CCmpProjectileManager::LaunchProjectile(entity_id_t source, CFixedVector3D
if (!m_Context->HasUnitManager())
return; // do nothing if graphics are disabled
Projectile projectile;
CmpPtr<ICmpVisual> sourceVisual(*m_Context, source);
if (sourceVisual.null())
return;
std::wstring name = sourceVisual->GetProjectileActor();
if (name.empty())
{
LOGERROR(L"Unit with actor '%ls' launched a projectile but has no actor on 'projectile' attachpoint", sourceVisual->GetActor().c_str());
return;
}
std::set<CStr> selections;
std::string name = "props/units/weapons/arrow_front.xml"; // TODO: get from somewhere proper (entity or actor?)
Projectile projectile;
projectile.unit = m_Context->GetUnitManager().CreateUnit(name, NULL, selections);
if (!projectile.unit)
{
@@ -79,11 +79,11 @@ public:
// TODO: we should do some fancy animation of under-construction buildings rising from the ground,
// but for now we'll just use the foundation actor and ignore the normal one
std::string name;
std::wstring name;
if (paramNode.GetChild("Foundation").IsOk() && paramNode.GetChild("FoundationActor").IsOk())
name = utf8_from_wstring(paramNode.GetChild("FoundationActor").ToString());
name = paramNode.GetChild("FoundationActor").ToString();
else
name = utf8_from_wstring(paramNode.GetChild("Actor").ToString());
name = paramNode.GetChild("Actor").ToString();
std::set<CStr> selections;
m_Unit = context.GetUnitManager().CreateUnit(name, NULL, selections);
@@ -116,7 +116,7 @@ public:
if (m_Unit == NULL)
serialize.StringASCII("actor", "[none]", 0, 256);
else
serialize.String("actor", m_Unit->GetObject()->m_Base->m_Name, 0, 256);
serialize.String("actor", m_Unit->GetObject().m_Base->m_Name, 0, 256);
}
// TODO: store random variation. This ought to be synchronised across saved games
@@ -176,6 +176,20 @@ public:
return m_Unit->GetModel()->GetTransform().GetTranslation();
}
virtual std::wstring GetActor()
{
if (!m_Unit)
return L"";
return m_Unit->GetObject().m_Base->m_Name;
}
virtual std::wstring GetProjectileActor()
{
if (!m_Unit)
return L"";
return m_Unit->GetObject().m_ProjectileModelName;
}
virtual void SelectAnimation(std::string name, bool once, float speed, std::wstring soundgroup)
{
if (!m_Unit)
@@ -41,6 +41,18 @@ public:
*/
virtual CVector3D GetPosition() = 0;
/**
* Return the filename of the actor that's being displayed, or the empty string on error.
* (Not safe for use in simulation code.)
*/
virtual std::wstring GetActor() = 0;
/**
* Return the filename of the actor to be used for projectiles from this unit, or the empty string if none.
* (Not safe for use in simulation code.)
*/
virtual std::wstring GetProjectileActor() = 0;
/**
* Start playing the given animation. If there are multiple possible animations then it will
* pick one at random (not network-synchronised).
@@ -69,7 +69,7 @@ namespace
if (unit->GetEntity())
return (unit->GetEntity()->m_base->m_anchorType != L"Ground");
else
return unit->GetObject()->m_Base->m_Properties.m_FloatOnWater;
return unit->GetObject().m_Base->m_Properties.m_FloatOnWater;
}
CUnitManager& GetUnitManager()
@@ -219,7 +219,7 @@ QUERYHANDLER(GetObjectSettings)
settings.player = unit->GetPlayerID();
// Get the unit's possible variants and selected variants
std::vector<std::vector<CStr> > groups = unit->GetObject()->m_Base->GetVariantGroups();
std::vector<std::vector<CStr> > groups = unit->GetObject().m_Base->GetVariantGroups();
const std::set<CStr>& selections = unit->GetActorSelections();
// Iterate over variant groups
@@ -69,7 +69,7 @@ CEntity* SimState::Entity::Thaw()
SimState::Nonentity SimState::Nonentity::Freeze(CUnit* unit)
{
Nonentity n;
n.actorName = unit->GetObject()->m_Base->m_Name;
n.actorName = unit->GetObject().m_Base->m_Name;
n.unitID = unit->GetID();
n.selections = unit->GetActorSelections();
n.position = unit->GetModel()->GetTransform().GetTranslation();