sometimes when using the platform behavior it's difficult to implement features that would require the platformer to temporarily ignore certain types of obstacles. For instance, an elevator carrying a platformer through the next floor will stay on the next floor after the elevator moves past if the floor is a platform, or will hit the ceiling and fall if it's a solid. Stairways are much more difficult to implement for the same reasons, and the added trouble that they are always in the way on the bottom floor and impossible to get to through the top floor. Those are the first examples that come to mind, but there are other cases, mostly moving platform scenarios, but other things, like ladders, or ghosts that can phase through walls the character can't, but should still obey the ground.
The following proposed additions are to alleviate this problem by allowing the behavior to temporarily ignore user-specified object types.
the altered files are here:
http://dl.dropbox.com/u/1013446/platform/Platform.rar
and the changes are summarized below:
changes:
in MAIN:
added one vector for objecttypes to ignore, and the function for checking the ignore list
vector<CRunObjType*> ignorelist;
bool IsIgnoring(CRunObjType* objtype);[/code:vtkaqhm8]
ACETABLE:
added three actions, Add Object to ignore list, Remove Object from ignore list, and Clear ignore list
[code:vtkaqhm8] ADDPARAM(PARAM_OBJECT, "ObjectType to Ignore", "Ignore platforms and solids of this object type");
ADDACT("Add Object to ignore list", "Ignore", "Add %0 to ignore list", &ExtObject::aAddToIgnoreList, "AddToIgnoreList", 0);
ADDPARAM(PARAM_OBJECT, "ObjectType to Stop Ignoring", "Stop Ignoring platforms of this object type");
ADDACT("Remove Object from ignore list", "Ignore", "Remove %0 from ignore list", &ExtObject::aRemoveFromIgnoreList, "RemoveFromIgnoreList", 0);
ADDACT("Clear ignore list", "Ignore", "Clear ignore list", &ExtObject::aClearIgnoreList, "ClearIgnoreList", 0);[/code:vtkaqhm8]
ACTIONS:
implement the three actions with simple vector commands, doublechecking to make sure the user doesn't add the same type twice
[code:vtkaqhm8] long ExtObject::aAddToIgnoreList(LPVAL theParams)
{
for(int i=0;i<ignorelist.size();i++)
{
if (ignorelist[i]==theParams->GetObjectParam(pRuntime))
return 0;
}
ignorelist.push_back(theParams->GetObjectParam(pRuntime));
return 0;
}
//ADDPARAM(PARAM_OBJECT, "Object to Stop Ignoring", "Stop Ignoring platforms of this object type");
//ADDACT("Remove Object from ignore list", "Ignore", "Remove %0 from ignore list", &ExtObject::aRemoveFromIgnoreList, "RemoveFromIgnoreList", 0);
long ExtObject::aRemoveFromIgnoreList(LPVAL theParams)
{
for(int i=0;i<ignorelist.size();i++)
{
if (ignorelist[i]==theParams->GetObjectParam(pRuntime))
{
vector<CRunObjType*>::iterator it=ignorelist.begin()+i;
ignorelist.erase(it);
}
}
return 0;
}
//ADDACT("Clear ignore list", "Ignore", "Clear ignore list", &ExtObject::aClearIgnoreList, "ClearIgnoreList", 0);
long ExtObject::aClearIgnoreList(LPVAL theParams)
{
ignorelist.clear();
return 0;
}[/code:vtkaqhm8]
RUNTIME:
implementation of IsIgnoring
[code:vtkaqhm8] bool ExtObject::IsIgnoring(CRunObjType* objtype)
{
for (int j = 0; j < ignorelist.size(); j++)
{
if (ignorelist[j]==objtype)
{
return true;
}
}
return false;
}[/code:vtkaqhm8]
Add IsIgnoring check to the beginning of OverlapTest
[code:vtkaqhm8] bool ExtObject::OverlapTest(CRunObject* pObj)
{
if(IsIgnoring(pObj->pType))
return false;
...
...
...
}[/code:vtkaqhm8]
Add two IsIgnoring checks to IsOverlapping, one for the platform check, and one for the Solid check, and change the check solids to manually checking one by one, so that each object can be checked against the ignore list
[code:vtkaqhm8]bool ExtObject::IsOverlapping( bool solids_only )
{
...
...
...
...
int count;
CRunObject **objs;
pRuntime->GetTypeSelectedInstances(pObstacles, objs, count);
for(int i = 0; i < count; i++)
{
{
CRunObject* platform = objs[i]; // do here
if (!IsIgnoring(platform->pType))
{
if(pRuntime->QueryCollision(pLink, platform))
{;
pLink->info.x = fx;
pLink->info.y = fy;
pRuntime->UpdateBoundingBox(pLink);
return true;
}
}
}
}
...
...
...
if(platforms_inside.find(platform) == platforms_inside.end())
{
if(!IsIgnoring(platform->pType))
{
if(pRuntime->QueryCollision(pLink, platform))
{
pLink->info.x = fx;
pLink->info.y = fy;
pRuntime->UpdateBoundingBox(pLink);
return true;
...
...
...
}
[/code:vtkaqhm8]