mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
# 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:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user