1
0
forked from 0ad/0ad

Support multiple props on each attachpoint. Fixes #242

This was SVN commit r6689.
This commit is contained in:
Ykkrosh 2009-02-18 10:36:27 +00:00
parent edaf87288a
commit 8d9b9ca413
6 changed files with 44 additions and 45 deletions

View File

@ -428,16 +428,6 @@ void CModel::AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry
model->SetTransform(point->m_Transform);
model->m_Parent = this;
// check if we're already using this point, and remove it if so
// (when a prop is removed it will also remove the prop point)
for (size_t i = 0; i < m_Props.size(); i++) {
if (m_Props[i].m_Point == point) {
delete m_Props[i].m_Model;
break;
}
}
// not using point; add new prop
Prop prop;
prop.m_Point = point;
prop.m_Model = model;
@ -446,14 +436,13 @@ void CModel::AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RemoveProp: remove a prop from the given point
// RemoveProp: remove any props from the given point
void CModel::RemoveProp(SPropPoint* point)
{
for (size_t i=0;i<m_Props.size();i++) {
if (m_Props[i].m_Point==point) {
for (size_t i = 0; i < m_Props.size(); i++) {
if (m_Props[i].m_Point == point) {
delete m_Props[i].m_Model;
// (when a prop is removed it will automatically remove its prop point)
break;
}
}
}

View File

@ -139,7 +139,7 @@ public:
// add a prop to the model on the given point
void AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry);
// remove a prop from the given point
// remove any props from the given point
void RemoveProp(SPropPoint* point);
// return prop list
std::vector<Prop>& GetProps() { return m_Props; }

View File

@ -239,7 +239,7 @@ std::vector<u8> CObjectBase::CalculateVariationKey(const std::vector<std::set<CS
std::vector<u8> choices;
std::map<CStr, CStr> chosenProps;
std::multimap<CStr, CStr> chosenProps;
for (std::vector<std::vector<CObjectBase::Variant> >::iterator grp = m_VariantGroups.begin();
grp != m_VariantGroups.end();
@ -287,20 +287,23 @@ std::vector<u8> CObjectBase::CalculateVariationKey(const std::vector<std::set<CS
choices.push_back(match);
// Remember which props were chosen. (Later-defined props override
// earlier props at the same prop point.)
// Remember which props were chosen, so we can call CalculateVariationKey on them
// at the end.
CObjectBase::Variant& var ((*grp)[match]);
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
{
if (! it->m_ModelName.empty())
chosenProps[it->m_PropPointName] = it->m_ModelName;
else
// Erase all existing props which are overridden by this variant:
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
chosenProps.erase(it->m_PropPointName);
// and then insert the new ones:
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
if (! it->m_ModelName.empty())
chosenProps.insert(make_pair(it->m_PropPointName, it->m_ModelName));
}
}
// Load each prop, and add their CalculateVariationKey to our key:
for (std::map<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
for (std::multimap<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
{
CObjectBase* prop = m_ObjectManager.FindObjectBase(it->second);
if (prop)
@ -354,18 +357,19 @@ const CObjectBase::Variation CObjectBase::BuildVariation(const std::vector<u8>&
if (! var.m_Color.empty())
variation.color = var.m_Color;
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
{
if (! it->m_ModelName.empty())
variation.props[it->m_PropPointName] = *it;
else
variation.props.erase(it->m_PropPointName);
}
// If one variant defines one animation called e.g. "attack", and this
// variant defines two different animations with the same name, the one
// If one variant defines one prop attached to e.g. "root", and this
// variant defines two different props with the same attachpoint, the one
// original should be erased, and replaced by the two new ones.
//
// So, erase all existing props which are overridden by this variant:
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
variation.props.erase(it->m_PropPointName);
// and then insert the new ones:
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
if (! it->m_ModelName.empty()) // if the name is empty then the overridden prop is just deleted
variation.props.insert(make_pair(it->m_PropPointName, *it));
// Same idea applies for animations.
// So, erase all existing animations which are overridden by this variant:
for (std::vector<CObjectBase::Anim>::iterator it = var.m_Anims.begin(); it != var.m_Anims.end(); ++it)
variation.anims.erase(it->m_AnimName);
@ -381,7 +385,7 @@ std::set<CStr> CObjectBase::CalculateRandomVariation(const std::set<CStr>& initi
{
std::set<CStr> selections = initialSelections;
std::map<CStr, CStr> chosenProps;
std::multimap<CStr, CStr> chosenProps;
// Calculate a complete list of selections, so there is at least one
// (and in most cases only one) per group.
@ -463,20 +467,23 @@ std::set<CStr> CObjectBase::CalculateRandomVariation(const std::set<CStr>& initi
}
}
// Remember which props were chosen. (Later-defined props override
// earlier props at the same prop point.)
// Remember which props were chosen, so we can call CalculateRandomVariation on them
// at the end.
CObjectBase::Variant& var ((*grp)[match]);
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
{
if (! it->m_ModelName.empty())
chosenProps[it->m_PropPointName] = it->m_ModelName;
else
// Erase all existing props which are overridden by this variant:
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
chosenProps.erase(it->m_PropPointName);
// and then insert the new ones:
for (std::vector<CObjectBase::Prop>::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it)
if (! it->m_ModelName.empty())
chosenProps.insert(make_pair(it->m_PropPointName, it->m_ModelName));
}
}
// Load each prop, and add their required selections to ours:
for (std::map<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
for (std::multimap<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
{
CObjectBase* prop = m_ObjectManager.FindObjectBase(it->second);
if (prop)

View File

@ -56,7 +56,7 @@ public:
CStr texture;
CStr model;
CStr color;
std::map<CStr, CObjectBase::Prop> props;
std::multimap<CStr, CObjectBase::Prop> props;
std::multimap<CStr, CObjectBase::Anim> anims;
};

View File

@ -62,7 +62,7 @@ bool CObjectEntry::BuildVariation(const std::vector<std::set<CStr> >& selections
std::vector<CObjectBase::Prop> props;
for (std::map<CStr, CObjectBase::Prop>::iterator it = variation.props.begin(); it != variation.props.end(); ++it)
for (std::multimap<CStr, CObjectBase::Prop>::iterator it = variation.props.begin(); it != variation.props.end(); ++it)
props.push_back(it->second);
// Build the model:

View File

@ -54,6 +54,9 @@ void CUnit::ShowAmmunition()
{
if (!m_Object->m_AmmunitionModel || !m_Object->m_AmmunitionPoint)
return;
// Remove any previous ammunition prop, in case there's still one left on there
m_Model->RemoveProp(m_Object->m_AmmunitionPoint);
// Then add the new prop
m_Model->AddProp(m_Object->m_AmmunitionPoint, m_Object->m_AmmunitionModel->Clone(), m_Object);
}
@ -62,7 +65,10 @@ void CUnit::HideAmmunition()
if (!m_Object->m_AmmunitionModel || !m_Object->m_AmmunitionPoint)
return;
// Find out what the usual prop is:
// Remove the ammunition prop
m_Model->RemoveProp(m_Object->m_AmmunitionPoint);
// Restore the original props that were on the ammo attachpoint, by copying them from
// the base model
std::vector<CModel::Prop>& props = m_Object->m_Model->GetProps();
std::vector<CModel::Prop>::iterator it;
for (it = props.begin(); it != props.end(); ++it)
@ -70,11 +76,8 @@ void CUnit::HideAmmunition()
if (it->m_Point == m_Object->m_AmmunitionPoint)
{
m_Model->AddProp(m_Object->m_AmmunitionPoint, it->m_Model->Clone(), m_Object);
return;
}
}
// No usual prop.
m_Model->RemoveProp(m_Object->m_AmmunitionPoint);
}