Refactor CObject interface related to crash spheres
parent
5a68558f4c
commit
b0ac2f8326
|
@ -164,6 +164,7 @@ set(BASE_SOURCES
|
|||
object/motion/motiontoto.cpp
|
||||
object/motion/motionvehicle.cpp
|
||||
object/motion/motionworm.cpp
|
||||
object/object.cpp
|
||||
object/object_factory.cpp
|
||||
object/object_manager.cpp
|
||||
object/old_object.cpp
|
||||
|
|
|
@ -3742,11 +3742,11 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos,
|
|||
if (dist < min)
|
||||
best = obj;
|
||||
|
||||
// Test with all spheres of the object.
|
||||
int j = 0;
|
||||
float oRadius;
|
||||
while (obj->GetCrashSphere(j++, oPos, oRadius))
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
if ( oPos.x+oRadius < box1.x || oPos.x-oRadius > box2.x || // outside the box?
|
||||
oPos.y+oRadius < box1.y || oPos.y-oRadius > box2.y ||
|
||||
oPos.z+oRadius < box1.z || oPos.z-oRadius > box2.z ) continue;
|
||||
|
|
|
@ -86,14 +86,9 @@ bool CPyro::Create(PyroType type, CObject* obj, float force)
|
|||
|
||||
DisplayError(type, obj); // displays eventual messages
|
||||
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
int i = 0;
|
||||
// Copies all spheres of the object.
|
||||
for (; i < 50; i++)
|
||||
{
|
||||
if ( !obj->GetCrashSphere(i, m_crashSpherePos[i], m_crashSphereRadius[i]) ) break;
|
||||
}
|
||||
m_crashSphereUsed = i;
|
||||
m_crashSpheres.push_back(crashSphere.sphere);
|
||||
}
|
||||
|
||||
// Calculates the size of the effect.
|
||||
|
@ -641,18 +636,19 @@ bool CPyro::EventProcess(const Event &event)
|
|||
{
|
||||
m_lastParticle = m_time;
|
||||
|
||||
if ( m_crashSphereUsed > 0 )
|
||||
if (m_crashSpheres.size() > 0)
|
||||
{
|
||||
int i = rand()%m_crashSphereUsed;
|
||||
Math::Vector pos = m_crashSpherePos[i];
|
||||
pos.x += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
|
||||
pos.z += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
|
||||
int i = rand() % m_crashSpheres.size();
|
||||
Math::Vector pos = m_crashSpheres[i].pos;
|
||||
float radius = m_crashSpheres[i].radius;
|
||||
pos.x += (Math::Rand()-0.5f)*radius*2.0f;
|
||||
pos.z += (Math::Rand()-0.5f)*radius*2.0f;
|
||||
Math::Vector speed;
|
||||
speed.x = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
|
||||
speed.z = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
|
||||
speed.y = Math::Rand()*m_crashSphereRadius[i]*1.0f;
|
||||
speed.x = (Math::Rand()-0.5f)*radius*0.5f;
|
||||
speed.z = (Math::Rand()-0.5f)*radius*0.5f;
|
||||
speed.y = Math::Rand()*radius*1.0f;
|
||||
Math::Point dim;
|
||||
dim.x = Math::Rand()*m_crashSphereRadius[i]*0.5f+m_crashSphereRadius[i]*0.75f*m_force;
|
||||
dim.x = Math::Rand()*radius*0.5f+radius*0.75f*m_force;
|
||||
dim.y = dim.x;
|
||||
m_particle->CreateParticle(pos, speed, dim, PARTISMOKE1, 3.0f);
|
||||
}
|
||||
|
@ -723,16 +719,17 @@ bool CPyro::EventProcess(const Event &event)
|
|||
{
|
||||
m_lastParticle = m_time;
|
||||
|
||||
if ( m_crashSphereUsed > 0 )
|
||||
if (m_crashSpheres.size() > 0)
|
||||
{
|
||||
int i = rand()%m_crashSphereUsed;
|
||||
Math::Vector pos = m_crashSpherePos[i];
|
||||
pos.x += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
|
||||
pos.z += (Math::Rand()-0.5f)*m_crashSphereRadius[i]*2.0f;
|
||||
int i = rand() % m_crashSpheres.size();
|
||||
Math::Vector pos = m_crashSpheres[i].pos;
|
||||
float radius = m_crashSpheres[i].radius;
|
||||
pos.x += (Math::Rand()-0.5f)*radius*2.0f;
|
||||
pos.z += (Math::Rand()-0.5f)*radius*2.0f;
|
||||
Math::Vector speed;
|
||||
speed.x = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
|
||||
speed.z = (Math::Rand()-0.5f)*m_crashSphereRadius[i]*0.5f;
|
||||
speed.y = Math::Rand()*m_crashSphereRadius[i]*1.0f;
|
||||
speed.x = (Math::Rand()-0.5f)*radius*0.5f;
|
||||
speed.z = (Math::Rand()-0.5f)*radius*0.5f;
|
||||
speed.y = Math::Rand()*radius*1.0f;
|
||||
Math::Point dim;
|
||||
dim.x = 1.0f*m_force;
|
||||
dim.y = dim.x;
|
||||
|
@ -2198,9 +2195,7 @@ void CPyro::FallStart()
|
|||
|
||||
CObject* CPyro::FallSearchBeeExplo()
|
||||
{
|
||||
Math::Vector iPos;
|
||||
float iRadius = 0.0f;
|
||||
m_object->GetCrashSphere(0, iPos, iRadius);
|
||||
auto bulletCrashSphere = m_object->GetFirstCrashSphere();
|
||||
|
||||
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
|
@ -2261,32 +2256,28 @@ CObject* CPyro::FallSearchBeeExplo()
|
|||
float shieldRadius = obj->GetShieldRadius();
|
||||
if ( shieldRadius > 0.0f )
|
||||
{
|
||||
float distance = Math::Distance(oPos, iPos);
|
||||
float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos);
|
||||
if (distance <= shieldRadius)
|
||||
return obj;
|
||||
}
|
||||
|
||||
if ( oType == OBJECT_BASE )
|
||||
{
|
||||
float distance = Math::Distance(oPos, iPos);
|
||||
float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos);
|
||||
if (distance < 25.0f)
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Test the center of the object, which is necessary for objects
|
||||
// that have no sphere in the center (station).
|
||||
float distance = Math::Distance(oPos, iPos)-4.0f;
|
||||
float distance = Math::Distance(oPos, bulletCrashSphere.sphere.pos)-4.0f;
|
||||
if (distance < 5.0f)
|
||||
return obj;
|
||||
|
||||
// Test with all spheres of the object.
|
||||
Math::Vector ooPos;
|
||||
float ooRadius = 0.0f;
|
||||
int j = 0;
|
||||
while (obj->GetCrashSphere(j++, ooPos, ooRadius))
|
||||
for (const auto& objCrashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
distance = Math::Distance(ooPos, iPos);
|
||||
if (distance <= iRadius+ooRadius)
|
||||
if (Math::DistanceBetweenSpheres(objCrashSphere.sphere, bulletCrashSphere.sphere) <= 0.0f)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,11 @@
|
|||
#include "graphics/core/color.h"
|
||||
#include "graphics/engine/pyro_type.h"
|
||||
|
||||
#include "math/sphere.h"
|
||||
|
||||
#include "object/object_type.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class CObject;
|
||||
class CRobotMain;
|
||||
|
@ -180,9 +183,7 @@ protected:
|
|||
float m_fallBulletTime;
|
||||
bool m_fallEnding;
|
||||
|
||||
int m_crashSphereUsed; // number of spheres used
|
||||
Math::Vector m_crashSpherePos[50];
|
||||
float m_crashSphereRadius[50];
|
||||
std::vector<Math::Sphere> m_crashSpheres;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "math/vector.h"
|
||||
|
||||
namespace Math {
|
||||
|
||||
struct Sphere
|
||||
{
|
||||
Sphere(const Vector& pos = Vector(), float radius = 0.0f)
|
||||
: pos(pos), radius(radius) {}
|
||||
|
||||
Vector pos;
|
||||
float radius;
|
||||
};
|
||||
|
||||
//! Compute distance between given \a point and \a sphere
|
||||
inline float DistanceToSphere(const Vector& point, const Sphere& sphere)
|
||||
{
|
||||
return Math::Distance(point, sphere.pos) - sphere.radius;
|
||||
}
|
||||
|
||||
inline float DistanceBetweenSpheres(const Sphere& sphere1, const Sphere& sphere2)
|
||||
{
|
||||
return Math::Distance(sphere1.pos, sphere2.pos) - sphere1.radius - sphere2.radius;
|
||||
}
|
||||
|
||||
} // namespace Math
|
|
@ -1298,11 +1298,10 @@ Error CAutoBase::CheckCloseDoor()
|
|||
ObjectType type = obj->GetType();
|
||||
if ( type == OBJECT_PORTICO ) continue;
|
||||
|
||||
int j = 0;
|
||||
Math::Vector oPos;
|
||||
float oRad = 0.0f;
|
||||
while ( obj->GetCrashSphere(j++, oPos, oRad) )
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRad = crashSphere.sphere.radius;
|
||||
float dist = Math::DistanceProjected(m_pos, oPos);
|
||||
if ( dist+oRad > 32.0f &&
|
||||
dist-oRad < 72.0f )
|
||||
|
|
|
@ -462,12 +462,11 @@ bool CAutoConvert::SearchVehicle()
|
|||
type != OBJECT_BEE &&
|
||||
type != OBJECT_WORM ) continue;
|
||||
|
||||
Math::Vector oPos;
|
||||
float oRadius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
|
||||
float dist = Math::Distance(oPos, cPos)-oRadius;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
if ( dist < 8.0f ) return true;
|
||||
auto crashSphere = obj->GetFirstCrashSphere();
|
||||
if (Math::DistanceToSphere(cPos, crashSphere.sphere) < 8.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -484,11 +484,11 @@ bool CAutoDerrick::SearchFree(Math::Vector pos)
|
|||
ObjectType type = obj->GetType();
|
||||
if ( type == OBJECT_DERRICK ) continue;
|
||||
|
||||
int j = 0;
|
||||
Math::Vector sPos;
|
||||
float sRadius = 0.0f;
|
||||
while ( obj->GetCrashSphere(j++, sPos, sRadius) )
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector sPos = crashSphere.sphere.pos;
|
||||
float sRadius = crashSphere.sphere.radius;
|
||||
|
||||
float distance = Math::Distance(sPos, pos);
|
||||
distance -= sRadius;
|
||||
if ( distance < 2.0f ) return false; // location occupied
|
||||
|
|
|
@ -433,12 +433,11 @@ bool CAutoEnergy::SearchVehicle()
|
|||
type != OBJECT_BEE &&
|
||||
type != OBJECT_WORM ) continue;
|
||||
|
||||
Math::Vector oPos;
|
||||
float oRadius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
|
||||
float dist = Math::Distance(oPos, cPos)-oRadius;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
if ( dist < 10.0f ) return true;
|
||||
auto crashSphere = obj->GetFirstCrashSphere();
|
||||
if (Math::DistanceToSphere(cPos, crashSphere.sphere) < 10.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -605,12 +605,11 @@ bool CAutoFactory::NearestVehicle()
|
|||
type != OBJECT_BEE &&
|
||||
type != OBJECT_WORM ) continue;
|
||||
|
||||
Math::Vector oPos;
|
||||
float oRadius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
|
||||
float dist = Math::Distance(oPos, cPos)-oRadius;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
if ( dist < 10.0f ) return true;
|
||||
auto crashSphere = obj->GetFirstCrashSphere();
|
||||
if (Math::DistanceToSphere(cPos, crashSphere.sphere) < 10.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -153,11 +153,11 @@ bool CAutoNest::SearchFree(Math::Vector pos)
|
|||
ObjectType type = obj->GetType();
|
||||
if ( type == OBJECT_NEST ) continue;
|
||||
|
||||
int j = 0;
|
||||
Math::Vector sPos;
|
||||
float sRadius = 0.0f;
|
||||
while ( obj->GetCrashSphere(j++, sPos, sRadius) )
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector sPos = crashSphere.sphere.pos;
|
||||
float sRadius = crashSphere.sphere.radius;
|
||||
|
||||
float distance = Math::Distance(sPos, pos);
|
||||
distance -= sRadius;
|
||||
if ( distance < 2.0f ) return false; // location occupied
|
||||
|
|
|
@ -368,12 +368,11 @@ bool CAutoNuclear::SearchVehicle()
|
|||
type != OBJECT_BEE &&
|
||||
type != OBJECT_WORM ) continue;
|
||||
|
||||
Math::Vector oPos;
|
||||
float oRadius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
|
||||
float dist = Math::Distance(oPos, m_pos)-oRadius;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
if ( dist < 10.0f ) return true;
|
||||
auto crashSphere = obj->GetFirstCrashSphere();
|
||||
if (Math::DistanceToSphere(m_pos, crashSphere.sphere) < 10.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -240,7 +240,7 @@ bool CAutoSafe::EventProcess(const Event &event)
|
|||
m_main->CreateShortcuts();
|
||||
}
|
||||
|
||||
m_object->FlushCrashShere();
|
||||
m_object->DeleteAllCrashSpheres();
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f);
|
||||
|
||||
m_sound->Play(SOUND_FINDING, m_object->GetPosition(0));
|
||||
|
|
|
@ -293,9 +293,9 @@ CObject* CAutoTower::SearchTarget(Math::Vector &impact)
|
|||
}
|
||||
}
|
||||
|
||||
Math::Vector oPos;
|
||||
float radius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, radius) ) continue;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
Math::Vector oPos = obj->GetFirstCrashSphere().sphere.pos;
|
||||
float distance = Math::Distance(oPos, iPos);
|
||||
if ( distance > TOWER_SCOPE ) continue; // too far
|
||||
if ( distance < min )
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "math/sphere.h"
|
||||
#include "math/vector.h"
|
||||
|
||||
#include "sound/sound_type.h"
|
||||
|
||||
/**
|
||||
* \struct CrashSphere
|
||||
* \brief Sphere used to detect object collisions
|
||||
*/
|
||||
struct CrashSphere
|
||||
{
|
||||
CrashSphere(const Math::Vector& pos = Math::Vector(),
|
||||
float radius = 0.0f,
|
||||
SoundType _sound = SOUND_NONE,
|
||||
float _hardness = 0.45f)
|
||||
: sphere(pos, radius)
|
||||
, sound(_sound)
|
||||
, hardness(_hardness)
|
||||
{}
|
||||
|
||||
//! Sphere (position + radius)
|
||||
//! Sphere position is given in either object or world coordinates
|
||||
//! (see CObject functions for more info)
|
||||
Math::Sphere sphere;
|
||||
//! Sound to be played on collision
|
||||
SoundType sound;
|
||||
//! "Hardness" of the sphere
|
||||
float hardness;
|
||||
};
|
|
@ -85,7 +85,7 @@ void CMotionAnt::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
|
||||
// A vehicle must have necessarily a collision
|
||||
//with a sphere of center (0, y, 0) (see GetCrashSphere).
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
|
||||
m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f);
|
||||
|
||||
// Creates the head.
|
||||
|
|
|
@ -83,7 +83,7 @@ void CMotionBee::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
|
||||
// A vehicle must have an obligatory collision
|
||||
// with a sphere of center (0, y, 0) (see GetCrashSphere).
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
|
||||
m_object->SetGlobalSphere(Math::Vector(-1.0f, 1.0f, 0.0f), 5.0f);
|
||||
|
||||
// Creates the head.
|
||||
|
|
|
@ -149,7 +149,7 @@ void CMotionHuman::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
m_object->SetAngleY(0, angle);
|
||||
|
||||
// A vehicle must have an obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere).
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f));
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 4.0f);
|
||||
|
||||
// Creates the head.
|
||||
|
|
|
@ -84,7 +84,7 @@ void CMotionMother::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
|
||||
// A vehicle must have a obligatory collision
|
||||
//with a sphere of center (0, y, 0) (see GetCrashSphere).
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f));
|
||||
m_object->SetGlobalSphere(Math::Vector(-2.0f, 10.0f, 0.0f), 25.0f);
|
||||
|
||||
// Creates the head.
|
||||
|
|
|
@ -110,7 +110,7 @@ void CMotionSpider::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
|
||||
// A vehicle must have a obligatory collision
|
||||
// with a sphere of center (0, y, 0) (see GetCrashSphere).
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
|
||||
m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f);
|
||||
|
||||
// Creates the abdomen.
|
||||
|
|
|
@ -191,26 +191,26 @@ void CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
type == OBJECT_MOBILErr ||
|
||||
type == OBJECT_MOBILErs)
|
||||
{
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f));
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f);
|
||||
}
|
||||
else if (type == OBJECT_MOBILEsa)
|
||||
{
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f));
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f);
|
||||
}
|
||||
else if (type == OBJECT_MOBILEdr)
|
||||
{
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f));
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f);
|
||||
}
|
||||
else if (type == OBJECT_APOLLO2)
|
||||
{
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f));
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.0f);
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ void CMotionWorm::Create(Math::Vector pos, float angle, ObjectType type,
|
|||
m_object->SetAngleY(0, angle);
|
||||
|
||||
// A vehicle must have a obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere).
|
||||
m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
|
||||
m_object->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f));
|
||||
m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 5.0f);
|
||||
|
||||
px = 1.0f+WORM_PART/2;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include "object/object.h"
|
||||
|
||||
CObject::CObject(int id, ObjectType type)
|
||||
: m_id(id)
|
||||
, m_type(type)
|
||||
{
|
||||
m_implementedInterfaces.fill(false);
|
||||
}
|
||||
|
||||
CObject::~CObject()
|
||||
{
|
||||
}
|
||||
|
||||
void CObject::AddCrashSphere(const CrashSphere& crashSphere)
|
||||
{
|
||||
m_crashSpheres.push_back(crashSphere);
|
||||
}
|
||||
|
||||
CrashSphere CObject::GetFirstCrashSphere()
|
||||
{
|
||||
assert(m_crashSpheres.size() >= 1);
|
||||
|
||||
CrashSphere transformedFirstCrashSphere = m_crashSpheres[0];
|
||||
TransformCrashSphere(transformedFirstCrashSphere.sphere);
|
||||
return transformedFirstCrashSphere;
|
||||
}
|
||||
|
||||
std::vector<CrashSphere> CObject::GetAllCrashSpheres()
|
||||
{
|
||||
std::vector<CrashSphere> allCrashSpheres;
|
||||
|
||||
for (const auto& crashSphere : m_crashSpheres)
|
||||
{
|
||||
CrashSphere transformedCrashSphere = crashSphere;
|
||||
TransformCrashSphere(transformedCrashSphere.sphere);
|
||||
allCrashSpheres.push_back(transformedCrashSphere);
|
||||
}
|
||||
|
||||
return allCrashSpheres;
|
||||
}
|
||||
|
||||
int CObject::GetCrashSphereCount()
|
||||
{
|
||||
return m_crashSpheres.size();
|
||||
}
|
||||
|
||||
void CObject::DeleteAllCrashSpheres()
|
||||
{
|
||||
m_crashSpheres.clear();
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "object/crash_sphere.h"
|
||||
#include "object/object_interface_type.h"
|
||||
#include "object/old_object_interface.h"
|
||||
|
||||
|
@ -49,19 +50,13 @@ class CObject : public COldObjectInterface
|
|||
{
|
||||
protected:
|
||||
//! Constructor only accessible to subclasses
|
||||
CObject(int id, ObjectType type)
|
||||
: m_id(id)
|
||||
, m_type(type)
|
||||
{
|
||||
m_implementedInterfaces.fill(false);
|
||||
}
|
||||
CObject(int id, ObjectType type);
|
||||
|
||||
public:
|
||||
CObject(const CObject&) = delete;
|
||||
CObject& operator=(const CObject&) = delete;
|
||||
|
||||
virtual ~CObject()
|
||||
{}
|
||||
virtual ~CObject();
|
||||
|
||||
//! Returns object type
|
||||
inline ObjectType GetType() const
|
||||
|
@ -86,9 +81,27 @@ public:
|
|||
return m_implementedInterfaces[static_cast<int>(type)];
|
||||
}
|
||||
|
||||
//! Adds a new crash sphere
|
||||
/** Crash sphere position is given in object coordinates */
|
||||
void AddCrashSphere(const CrashSphere& crashSphere);
|
||||
//! Returns total number of crash spheres
|
||||
int GetCrashSphereCount();
|
||||
//! Returns the first crash sphere (assumes it exists)
|
||||
/** Crash sphere position is returned in world coordinates */
|
||||
CrashSphere GetFirstCrashSphere();
|
||||
//! Returns all crash spheres
|
||||
/** Crash sphere position is returned in world coordinates */
|
||||
std::vector<CrashSphere> GetAllCrashSpheres();
|
||||
//! Removes all crash spheres
|
||||
void DeleteAllCrashSpheres();
|
||||
|
||||
protected:
|
||||
//! Transform crash sphere by object's world matrix
|
||||
virtual void TransformCrashSphere(Math::Sphere& crashSphere) = 0;
|
||||
|
||||
protected:
|
||||
const int m_id; //!< unique identifier
|
||||
ObjectType m_type; //!< object type
|
||||
std::string m_name; //!< object class name
|
||||
ObjectInterfaceTypes m_implementedInterfaces; //! interfaces that the object implements
|
||||
ObjectInterfaceTypes m_implementedInterfaces; //!< interfaces that the object implements
|
||||
std::vector<CrashSphere> m_crashSpheres; //!< crash spheres
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -286,7 +286,7 @@ COldObject::COldObject(int id)
|
|||
m_cmdLine[i] = NAN;
|
||||
}
|
||||
|
||||
FlushCrashShere();
|
||||
DeleteAllCrashSpheres();
|
||||
m_globalSpherePos = Math::Vector(0.0f, 0.0f, 0.0f);
|
||||
m_globalSphereRadius = 0.0f;
|
||||
m_jostlingSpherePos = Math::Vector(0.0f, 0.0f, 0.0f);
|
||||
|
@ -1061,86 +1061,30 @@ int COldObject::SearchDescendant(int parent, int n)
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Removes all spheres used for collisions.
|
||||
|
||||
void COldObject::FlushCrashShere()
|
||||
void COldObject::TransformCrashSphere(Math::Sphere& crashSphere)
|
||||
{
|
||||
m_crashSphereUsed = 0;
|
||||
}
|
||||
|
||||
// Adds a new sphere.
|
||||
|
||||
int COldObject::CreateCrashSphere(Math::Vector pos, float radius, SoundType sound,
|
||||
float hardness)
|
||||
{
|
||||
float zoom;
|
||||
|
||||
if ( m_crashSphereUsed >= MAXCRASHSPHERE ) return -1;
|
||||
|
||||
zoom = GetZoomX(0);
|
||||
m_crashSpherePos[m_crashSphereUsed] = pos;
|
||||
m_crashSphereRadius[m_crashSphereUsed] = radius*zoom;
|
||||
m_crashSphereHardness[m_crashSphereUsed] = hardness;
|
||||
m_crashSphereSound[m_crashSphereUsed] = sound;
|
||||
return m_crashSphereUsed++;
|
||||
}
|
||||
|
||||
// Returns the number of spheres.
|
||||
|
||||
int COldObject::GetCrashSphereTotal()
|
||||
{
|
||||
return m_crashSphereUsed;
|
||||
}
|
||||
|
||||
// Returns a sphere for collisions.
|
||||
// The position is absolute in the world.
|
||||
|
||||
bool COldObject::GetCrashSphere(int rank, Math::Vector &pos, float &radius)
|
||||
{
|
||||
if ( rank < 0 || rank >= m_crashSphereUsed )
|
||||
{
|
||||
pos = m_objectPart[0].position;
|
||||
radius = 0.0f;
|
||||
return false;
|
||||
}
|
||||
crashSphere.radius *= GetZoomX(0);
|
||||
|
||||
// Returns to the sphere collisions,
|
||||
// which ignores the inclination of the vehicle.
|
||||
// which ignores the tilt of the vehicle.
|
||||
// This is necessary to collisions with vehicles,
|
||||
// so as not to reflect SetTilt, for example.
|
||||
// The sphere must necessarily have a center (0, y, 0).
|
||||
if ( rank == 0 && m_crashSphereUsed == 1 &&
|
||||
m_crashSpherePos[0].x == 0.0f &&
|
||||
m_crashSpherePos[0].z == 0.0f )
|
||||
if (m_crashSpheres.size() == 1 &&
|
||||
crashSphere.pos.x == 0.0f &&
|
||||
crashSphere.pos.z == 0.0f )
|
||||
{
|
||||
pos = m_objectPart[0].position + m_crashSpherePos[0];
|
||||
radius = m_crashSphereRadius[0];
|
||||
return true;
|
||||
crashSphere.pos += m_objectPart[0].position;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_objectPart[0].bTranslate ||
|
||||
m_objectPart[0].bRotate )
|
||||
if (m_objectPart[0].bTranslate ||
|
||||
m_objectPart[0].bRotate)
|
||||
{
|
||||
UpdateTransformObject();
|
||||
}
|
||||
pos = Math::Transform(m_objectPart[0].matWorld, m_crashSpherePos[rank]);
|
||||
radius = m_crashSphereRadius[rank];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns the hardness of a sphere.
|
||||
|
||||
SoundType COldObject::GetCrashSphereSound(int rank)
|
||||
{
|
||||
return m_crashSphereSound[rank];
|
||||
}
|
||||
|
||||
// Returns the hardness of a sphere.
|
||||
|
||||
float COldObject::GetCrashSphereHardness(int rank)
|
||||
{
|
||||
return m_crashSphereHardness[rank];
|
||||
crashSphere.pos = Math::Transform(m_objectPart[0].matWorld, crashSphere.pos);
|
||||
}
|
||||
|
||||
// Specifies the global sphere, relative to the object.
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
// The father of all parts must always be the part number zero!
|
||||
const int OBJECTMAXPART = 40;
|
||||
const int MAXCRASHSPHERE = 40;
|
||||
const int OBJECTMAXDESELLIST = 10;
|
||||
const int OBJECTMAXCMDLINE = 20;
|
||||
|
||||
|
@ -102,12 +101,6 @@ public:
|
|||
int GetShadowLight() override;
|
||||
int GetEffectLight() override;
|
||||
|
||||
void FlushCrashShere() override;
|
||||
int CreateCrashSphere(Math::Vector pos, float radius, SoundType sound, float hardness=0.45f) override;
|
||||
int GetCrashSphereTotal() override;
|
||||
bool GetCrashSphere(int rank, Math::Vector &pos, float &radius) override;
|
||||
float GetCrashSphereHardness(int rank) override;
|
||||
SoundType GetCrashSphereSound(int rank) override;
|
||||
void SetGlobalSphere(Math::Vector pos, float radius) override;
|
||||
void GetGlobalSphere(Math::Vector &pos, float &radius) override;
|
||||
void GetJostlingSphere(Math::Vector &pos, float &radius) override;
|
||||
|
@ -319,6 +312,7 @@ protected:
|
|||
bool UpdateTransformObject(int part, bool bForceUpdate);
|
||||
bool UpdateTransformObject();
|
||||
void UpdateSelectParticle();
|
||||
void TransformCrashSphere(Math::Sphere &crashSphere) override;
|
||||
|
||||
protected:
|
||||
Gfx::CEngine* m_engine;
|
||||
|
@ -391,11 +385,6 @@ protected:
|
|||
float m_param;
|
||||
int m_team;
|
||||
|
||||
int m_crashSphereUsed; // number of spheres used
|
||||
Math::Vector m_crashSpherePos[MAXCRASHSPHERE];
|
||||
float m_crashSphereRadius[MAXCRASHSPHERE];
|
||||
float m_crashSphereHardness[MAXCRASHSPHERE];
|
||||
SoundType m_crashSphereSound[MAXCRASHSPHERE];
|
||||
Math::Vector m_globalSpherePos;
|
||||
float m_globalSphereRadius;
|
||||
Math::Vector m_jostlingSpherePos;
|
||||
|
|
|
@ -98,12 +98,6 @@ public:
|
|||
virtual int GetShadowLight() = 0;
|
||||
virtual int GetEffectLight() = 0;
|
||||
|
||||
virtual void FlushCrashShere() = 0;
|
||||
virtual int CreateCrashSphere(Math::Vector pos, float radius, SoundType sound, float hardness=0.45f) = 0;
|
||||
virtual int GetCrashSphereTotal() = 0;
|
||||
virtual bool GetCrashSphere(int rank, Math::Vector &pos, float &radius) = 0;
|
||||
virtual float GetCrashSphereHardness(int rank) = 0;
|
||||
virtual SoundType GetCrashSphereSound(int rank) = 0;
|
||||
virtual void SetGlobalSphere(Math::Vector pos, float radius) = 0;
|
||||
virtual void GetGlobalSphere(Math::Vector &pos, float &radius) = 0;
|
||||
virtual void GetJostlingSphere(Math::Vector &pos, float &radius) = 0;
|
||||
|
|
|
@ -4212,11 +4212,11 @@ float CRobotMain::SearchNearestObject(Math::Vector center, CObject *exclu)
|
|||
min = Math::Min(min, dist);
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
Math::Vector oPos;
|
||||
float oRadius;
|
||||
while (obj->GetCrashSphere(j++, oPos, oRadius))
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
float dist = Math::Distance(center, oPos)-oRadius;
|
||||
if (dist < 0.0f) dist = 0.0f;
|
||||
min = Math::Min(min, dist);
|
||||
|
@ -4348,10 +4348,9 @@ void CRobotMain::ShowDropZone(CObject* metal, CObject* transporter)
|
|||
}
|
||||
else
|
||||
{
|
||||
int j = 0;
|
||||
while (obj->GetCrashSphere(j++, oPos, oRadius))
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
float dist = Math::Distance(center, oPos)-oRadius;
|
||||
float dist = Math::Distance(center, crashSphere.sphere.pos)-crashSphere.sphere.radius;
|
||||
oMax = Math::Min(oMax, dist);
|
||||
}
|
||||
}
|
||||
|
@ -4375,10 +4374,9 @@ void CRobotMain::ShowDropZone(CObject* metal, CObject* transporter)
|
|||
type == OBJECT_SAFE ||
|
||||
type == OBJECT_HUSTON ) // building?
|
||||
{
|
||||
int j = 0;
|
||||
while (obj->GetCrashSphere(j++, oPos, oRadius))
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
float dist = Math::Distance(center, oPos)-oRadius-BUILDMARGIN;
|
||||
float dist = Math::Distance(center, crashSphere.sphere.pos)-crashSphere.sphere.radius-BUILDMARGIN;
|
||||
oMax = Math::Min(oMax, dist);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,8 +86,8 @@ std::unique_ptr<CExchangePost> CExchangePost::Create(
|
|||
obj->SetAngleY(2+i*2, 2.0f*Math::PI/3.0f*i);
|
||||
}
|
||||
|
||||
obj->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f);
|
||||
obj->CreateCrashSphere(Math::Vector(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f);
|
||||
obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->AddCrashSphere(CrashSphere(Math::Vector(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f));
|
||||
obj->SetGlobalSphere(Math::Vector(0.0f, 5.0f, 0.0f), 6.0f);
|
||||
|
||||
obj->CreateShadowCircle(8.0f, 1.0f);
|
||||
|
|
|
@ -575,7 +575,7 @@ bool CTaskBuild::Abort()
|
|||
Error CTaskBuild::FlatFloor()
|
||||
{
|
||||
ObjectType type;
|
||||
Math::Vector center, pos, oPos, bPos;
|
||||
Math::Vector center, pos, bPos;
|
||||
Math::Point c, p;
|
||||
float radius, max, oRadius, bRadius = 0.0f, angle, dist;
|
||||
int j;
|
||||
|
@ -624,21 +624,23 @@ Error CTaskBuild::FlatFloor()
|
|||
type = pObj->GetType();
|
||||
if ( type == OBJECT_BASE )
|
||||
{
|
||||
oPos = pObj->GetPosition(0);
|
||||
Math::Vector oPos = pObj->GetPosition(0);
|
||||
dist = Math::Distance(center, oPos)-80.0f;
|
||||
if ( dist < max )
|
||||
{
|
||||
max = dist;
|
||||
bPos = oPos;
|
||||
bRadius = oRadius;
|
||||
bRadius = 0.0f;
|
||||
bBase = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
dist = Math::Distance(center, oPos)-oRadius;
|
||||
if ( dist < max )
|
||||
{
|
||||
|
@ -686,9 +688,11 @@ Error CTaskBuild::FlatFloor()
|
|||
type == OBJECT_SAFE ||
|
||||
type == OBJECT_HUSTON ) // building?
|
||||
{
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
dist = Math::Distance(center, oPos)-oRadius;
|
||||
if ( dist < max )
|
||||
{
|
||||
|
|
|
@ -552,11 +552,11 @@ CObject* CTaskGoto::WormSearch(Math::Vector &impact)
|
|||
|
||||
if ( obj->GetVirusMode() ) continue; // object infected?
|
||||
|
||||
Math::Vector oPos;
|
||||
float radius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, radius) ) continue;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
Math::Vector oPos = obj->GetFirstCrashSphere().sphere.pos;
|
||||
float distance = Math::DistanceProjected(oPos, iPos);
|
||||
if ( distance < min )
|
||||
if (distance < min)
|
||||
{
|
||||
min = distance;
|
||||
best = obj;
|
||||
|
@ -1294,50 +1294,44 @@ bool CTaskGoto::GetHotPoint(CObject *pObj, Math::Vector &pos,
|
|||
|
||||
bool CTaskGoto::LeakSearch(Math::Vector &pos, float &delay)
|
||||
{
|
||||
CObject *pObstacle = nullptr;
|
||||
Math::Vector iPos, oPos, bPos;
|
||||
float iRadius, oRadius, bRadius, dist, min, dir;
|
||||
int j;
|
||||
if (!m_physics->GetLand()) return false; // in flight?
|
||||
|
||||
if ( !m_physics->GetLand() ) return false; // in flight?
|
||||
Math::Sphere crashSphere = m_object->GetFirstCrashSphere().sphere;
|
||||
|
||||
m_object->GetCrashSphere(0, iPos, iRadius);
|
||||
|
||||
min = 100000.0f;
|
||||
bRadius = 0.0f;
|
||||
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
float min = 100000.0f;
|
||||
CObject* obstacle = nullptr;
|
||||
Math::Sphere obstacleCrashSphere;
|
||||
for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
if ( pObj == m_object ) continue;
|
||||
if ( !pObj->GetActive() ) continue;
|
||||
if ( pObj->GetTransporter() != 0 ) continue; // object transported?
|
||||
if ( obj == m_object ) continue;
|
||||
if ( !obj->GetActive() ) continue;
|
||||
if ( obj->GetTransporter() != nullptr ) continue; // object transported?
|
||||
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& objCrashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
dist = Math::DistanceProjected(oPos, iPos);
|
||||
if ( dist < min )
|
||||
float dist = Math::DistanceProjected(crashSphere.pos, objCrashSphere.sphere.pos);
|
||||
if (dist < min)
|
||||
{
|
||||
min = dist;
|
||||
bPos = oPos;
|
||||
bRadius = oRadius;
|
||||
pObstacle = pObj;
|
||||
obstacleCrashSphere = objCrashSphere.sphere;
|
||||
obstacle = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( min > iRadius+bRadius+4.0f ) return false;
|
||||
if (min > crashSphere.radius + obstacleCrashSphere.radius + 4.0f) return false;
|
||||
|
||||
m_bLeakRecede = false;
|
||||
|
||||
dist = 4.0f;
|
||||
dir = 1.0f;
|
||||
if ( pObstacle->GetType() == OBJECT_FACTORY )
|
||||
float dist = 4.0f;
|
||||
float dir = 1.0f;
|
||||
if (obstacle->GetType() == OBJECT_FACTORY)
|
||||
{
|
||||
dist = 16.0f;
|
||||
dir = -1.0f;
|
||||
m_bLeakRecede = true; // simply recoils
|
||||
}
|
||||
|
||||
pos = bPos;
|
||||
pos = obstacleCrashSphere.pos;
|
||||
delay = m_physics->GetLinTimeLength(dist, dir);
|
||||
return true;
|
||||
}
|
||||
|
@ -1394,10 +1388,8 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
|
|||
}
|
||||
#else
|
||||
ObjectType iType, oType;
|
||||
Math::Vector iPos, oPos;
|
||||
Math::Point repulse;
|
||||
float gDist, add, addi, fac, dist, iRadius, oRadius;
|
||||
int j;
|
||||
float gDist, add, addi, fac, dist;
|
||||
bool bAlien;
|
||||
|
||||
dir.x = 0.0f;
|
||||
|
@ -1407,7 +1399,10 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
|
|||
iType = m_object->GetType();
|
||||
if ( iType == OBJECT_WORM || iType == OBJECT_CONTROLLER ) return;
|
||||
|
||||
m_object->GetCrashSphere(0, iPos, iRadius);
|
||||
auto firstCrashSphere = m_object->GetFirstCrashSphere();
|
||||
Math::Vector iPos = firstCrashSphere.sphere.pos;
|
||||
float iRadius = firstCrashSphere.sphere.radius;
|
||||
|
||||
gDist = Math::Distance(iPos, m_goal);
|
||||
|
||||
add = m_physics->GetLinStopLength()*1.1f; // braking distance
|
||||
|
@ -1524,9 +1519,11 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
|
|||
addi = 2.0f; // between wasps, do not annoy too much
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
if ( oPos.y-oRadius > iPos.y+iRadius ) continue;
|
||||
if ( oPos.y+oRadius < iPos.y-iRadius ) continue;
|
||||
|
||||
|
@ -1559,34 +1556,33 @@ void CTaskGoto::ComputeRepulse(Math::Point &dir)
|
|||
|
||||
void CTaskGoto::ComputeFlyingRepulse(float &dir)
|
||||
{
|
||||
ObjectType oType;
|
||||
Math::Vector iPos, oPos;
|
||||
float add, fac, dist, iRadius, oRadius, repulse;
|
||||
int j;
|
||||
auto firstCrashSphere = m_object->GetFirstCrashSphere();
|
||||
Math::Vector iPos = firstCrashSphere.sphere.pos;
|
||||
float iRadius = firstCrashSphere.sphere.radius;
|
||||
|
||||
m_object->GetCrashSphere(0, iPos, iRadius);
|
||||
|
||||
add = 0.0f;
|
||||
fac = 1.5f;
|
||||
float add = 0.0f;
|
||||
float fac = 1.5f;
|
||||
dir = 0.0f;
|
||||
|
||||
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
if ( pObj == m_object ) continue;
|
||||
if ( pObj->GetTransporter() != 0 ) continue;
|
||||
if ( pObj->GetTransporter() != nullptr ) continue;
|
||||
|
||||
oType = pObj->GetType();
|
||||
ObjectType oType = pObj->GetType();
|
||||
|
||||
if ( oType == OBJECT_WORM ) continue;
|
||||
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
oRadius += iRadius+add;
|
||||
dist = Math::DistanceProjected(oPos, iPos);
|
||||
float dist = Math::DistanceProjected(oPos, iPos);
|
||||
if ( dist <= oRadius )
|
||||
{
|
||||
repulse = iPos.y-oPos.y;
|
||||
float repulse = iPos.y-oPos.y;
|
||||
|
||||
dist = powf(dist/oRadius, fac);
|
||||
dist = 0.2f-0.2f*dist;
|
||||
|
@ -1873,30 +1869,28 @@ bool CTaskGoto::BitmapTestLine(const Math::Vector &start, const Math::Vector &go
|
|||
|
||||
void CTaskGoto::BitmapObject()
|
||||
{
|
||||
ObjectType type;
|
||||
Math::Vector iPos, oPos;
|
||||
float iRadius, oRadius, h;
|
||||
int j;
|
||||
|
||||
m_object->GetCrashSphere(0, iPos, iRadius);
|
||||
auto firstCrashSphere = m_object->GetFirstCrashSphere();
|
||||
float iRadius = firstCrashSphere.sphere.radius;
|
||||
|
||||
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
type = pObj->GetType();
|
||||
ObjectType type = pObj->GetType();
|
||||
|
||||
if ( pObj == m_object ) continue;
|
||||
if ( pObj == m_bmCargoObject ) continue;
|
||||
if ( pObj->GetTransporter() != 0 ) continue;
|
||||
|
||||
h = m_terrain->GetFloorLevel(pObj->GetPosition(0), false);
|
||||
float h = m_terrain->GetFloorLevel(pObj->GetPosition(0), false);
|
||||
if ( m_physics->GetType() == TYPE_FLYING && m_altitude > 0.0f )
|
||||
{
|
||||
h += m_altitude;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRadius = crashSphere.sphere.radius;
|
||||
|
||||
if ( m_physics->GetType() == TYPE_FLYING && m_altitude > 0.0f ) // flying?
|
||||
{
|
||||
if ( oPos.y-oRadius > h+8.0f ||
|
||||
|
|
|
@ -953,16 +953,18 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
|
|||
Character* character;
|
||||
CObject* pPower;
|
||||
Math::Matrix* mat;
|
||||
Math::Vector iPos, oPos;
|
||||
ObjectType type, powerType;
|
||||
float iAngle, iRad, oAngle, oLimit, aLimit, dLimit;
|
||||
float iAngle, oAngle, oLimit, aLimit, dLimit;
|
||||
|
||||
distance = 1000000.0f;
|
||||
angle = 0.0f;
|
||||
|
||||
if ( m_bSubm ) return 0; // impossible with the submarine
|
||||
|
||||
if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0;
|
||||
if (m_object->GetCrashSphereCount() == 0) return 0;
|
||||
|
||||
Math::Vector iPos = m_object->GetFirstCrashSphere().sphere.pos;
|
||||
|
||||
iAngle = m_object->GetAngleY(0);
|
||||
iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
|
||||
|
||||
|
@ -1027,7 +1029,7 @@ CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
|
|||
|
||||
mat = pObj->GetWorldMatrix(0);
|
||||
character = pObj->GetCharacter();
|
||||
oPos = Transform(*mat, character->posPower);
|
||||
Math::Vector oPos = Transform(*mat, character->posPower);
|
||||
|
||||
oAngle = pObj->GetAngleY(0);
|
||||
if ( type == OBJECT_TOWER ||
|
||||
|
@ -1330,12 +1332,9 @@ bool CTaskManip::IsFreeDeposeObject(Math::Vector pos)
|
|||
if ( !obj->GetActive() ) continue; // inactive?
|
||||
if ( obj->GetTransporter() != nullptr ) continue; // object transported?
|
||||
|
||||
Math::Vector oPos;
|
||||
float oRadius = 0.0f;
|
||||
int j = 0;
|
||||
while ( obj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : obj->GetAllCrashSpheres())
|
||||
{
|
||||
if ( Math::Distance(iPos, oPos)-(oRadius+1.0f) < 2.0f )
|
||||
if ( Math::Distance(iPos, crashSphere.sphere.pos)-(crashSphere.sphere.radius+1.0f) < 2.0f )
|
||||
{
|
||||
return false; // location occupied
|
||||
}
|
||||
|
|
|
@ -318,12 +318,11 @@ bool CTaskReset::SearchVehicle()
|
|||
type != OBJECT_BEE &&
|
||||
type != OBJECT_WORM ) continue;
|
||||
|
||||
Math::Vector oPos;
|
||||
float oRadius = 0.0f;
|
||||
if ( !obj->GetCrashSphere(0, oPos, oRadius) ) continue;
|
||||
float dist = Math::Distance(oPos, m_goal)-oRadius;
|
||||
if (obj->GetCrashSphereCount() == 0) continue;
|
||||
|
||||
if ( dist < 5.0f ) return true;
|
||||
auto crashSphere = obj->GetFirstCrashSphere();
|
||||
if (Math::DistanceToSphere(m_goal, crashSphere.sphere) < 5.0f)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -364,11 +364,15 @@ CObject* CTaskTake::SearchFriendObject(float &angle,
|
|||
Character* character;
|
||||
CObject* pPower;
|
||||
Math::Matrix* mat;
|
||||
Math::Vector iPos, oPos;
|
||||
ObjectType type, powerType;
|
||||
float iAngle, iRad, distance;
|
||||
float iAngle, distance;
|
||||
|
||||
if (m_object->GetCrashSphereCount() == 0) return 0;
|
||||
|
||||
auto crashSphere = m_object->GetFirstCrashSphere();
|
||||
Math::Vector iPos = crashSphere.sphere.pos;
|
||||
float iRad = crashSphere.sphere.radius;
|
||||
|
||||
if ( !m_object->GetCrashSphere(0, iPos, iRad) ) return 0;
|
||||
iAngle = m_object->GetAngleY(0);
|
||||
iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI
|
||||
|
||||
|
@ -422,7 +426,7 @@ CObject* CTaskTake::SearchFriendObject(float &angle,
|
|||
|
||||
mat = pObj->GetWorldMatrix(0);
|
||||
character = pObj->GetCharacter();
|
||||
oPos = Transform(*mat, character->posPower);
|
||||
Math::Vector oPos = Transform(*mat, character->posPower);
|
||||
|
||||
distance = fabs(Math::Distance(oPos, iPos) - (iRad+1.0f));
|
||||
if ( distance <= dLimit )
|
||||
|
@ -555,13 +559,8 @@ bool CTaskTake::TransporterDeposeObject()
|
|||
|
||||
bool CTaskTake::IsFreeDeposeObject(Math::Vector pos)
|
||||
{
|
||||
Math::Matrix* mat;
|
||||
Math::Vector iPos, oPos;
|
||||
float oRadius;
|
||||
int j;
|
||||
|
||||
mat = m_object->GetWorldMatrix(0);
|
||||
iPos = Transform(*mat, pos);
|
||||
Math::Matrix* mat = m_object->GetWorldMatrix(0);
|
||||
Math::Vector iPos = Transform(*mat, pos);
|
||||
|
||||
for (CObject* pObj : CObjectManager::GetInstancePointer()->GetAllObjects())
|
||||
{
|
||||
|
@ -569,10 +568,9 @@ bool CTaskTake::IsFreeDeposeObject(Math::Vector pos)
|
|||
if ( !pObj->GetActive() ) continue; // inactive?
|
||||
if ( pObj->GetTransporter() != 0 ) continue; // object transported?
|
||||
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
if ( Math::Distance(iPos, oPos)-(oRadius+1.0f) < 1.0f )
|
||||
if ( Math::Distance(iPos, crashSphere.sphere.pos)-(crashSphere.sphere.radius+1.0f) < 1.0f )
|
||||
{
|
||||
return false; // location occupied
|
||||
}
|
||||
|
|
|
@ -2511,10 +2511,9 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
{
|
||||
CPhysics* ph;
|
||||
Math::Matrix matRotate;
|
||||
Math::Vector iPos, oPos, iiPos, oAngle, oSpeed;
|
||||
SoundType sound;
|
||||
float iRad, oRad, distance, force, volume;
|
||||
int j, colType;
|
||||
Math::Vector iPos, oAngle, oSpeed;
|
||||
float distance, force, volume;
|
||||
int colType;
|
||||
ObjectType iType, oType;
|
||||
|
||||
if ( m_object->GetRuin() ) return 0; // is burning or exploding?
|
||||
|
@ -2522,7 +2521,10 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
|
||||
// iiPos = sphere center is the old position.
|
||||
// iPos = sphere center has the new position.
|
||||
m_object->GetCrashSphere(0, iiPos, iRad);
|
||||
auto firstCrashSphere = m_object->GetFirstCrashSphere();
|
||||
Math::Vector iiPos = firstCrashSphere.sphere.pos;
|
||||
float iRad = firstCrashSphere.sphere.radius;
|
||||
|
||||
iPos = iiPos + (pos - m_object->GetPosition(0));
|
||||
iType = m_object->GetType();
|
||||
|
||||
|
@ -2547,10 +2549,12 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
if ( iType == OBJECT_MOTHER && oType == OBJECT_EGG ) continue;
|
||||
if ( iType == OBJECT_EGG && oType == OBJECT_MOTHER ) continue;
|
||||
|
||||
pObj->GetJostlingSphere(oPos, oRad);
|
||||
if ( oRad > 0.0f )
|
||||
Math::Vector jostlingSpherePos;
|
||||
float jostlingSphereRadius = 0.0f;
|
||||
pObj->GetJostlingSphere(jostlingSpherePos, jostlingSphereRadius);
|
||||
if ( jostlingSphereRadius > 0.0f )
|
||||
{
|
||||
JostleObject(pObj, iPos, iRad, oPos, oRad);
|
||||
JostleObject(pObj, iPos, iRad, jostlingSpherePos, jostlingSphereRadius);
|
||||
}
|
||||
|
||||
if ( iType == OBJECT_MOTHER ||
|
||||
|
@ -2580,7 +2584,7 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
!m_object->GetResetBusy() &&
|
||||
m_object->GetTrainer() ) // driving vehicle?
|
||||
{
|
||||
oPos = pObj->GetPosition(0);
|
||||
Math::Vector oPos = pObj->GetPosition(0);
|
||||
distance = Math::DistanceProjected(oPos, iPos);
|
||||
if ( distance < 4.0f )
|
||||
{
|
||||
|
@ -2591,7 +2595,7 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
|
||||
if ( oType == OBJECT_TARGET2 )
|
||||
{
|
||||
oPos = pObj->GetPosition(0);
|
||||
Math::Vector oPos = pObj->GetPosition(0);
|
||||
distance = Math::Distance(oPos, iPos);
|
||||
if ( distance < 10.0f*1.5f )
|
||||
{
|
||||
|
@ -2600,9 +2604,11 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
while ( pObj->GetCrashSphere(j++, oPos, oRad) )
|
||||
for (const auto& crashSphere : pObj->GetAllCrashSpheres())
|
||||
{
|
||||
Math::Vector oPos = crashSphere.sphere.pos;
|
||||
float oRad = crashSphere.sphere.radius;
|
||||
|
||||
if ( iType == OBJECT_MOTHER && oRad <= 1.2f ) continue;
|
||||
if ( iType == OBJECT_ANT && oRad <= 1.2f ) continue;
|
||||
if ( iType == OBJECT_SPIDER && oRad <= 1.2f ) continue;
|
||||
|
@ -2618,11 +2624,10 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
m_bCollision = true;
|
||||
m_bObstacle = true;
|
||||
|
||||
sound = pObj->GetCrashSphereSound(j-1);
|
||||
if ( sound != SOUND_CLICK )
|
||||
if (crashSphere.sound != SOUND_CLICK)
|
||||
{
|
||||
force = fabs(m_linMotion.realSpeed.x);
|
||||
force *= pObj->GetCrashSphereHardness(j-1)*2.0f;
|
||||
force *= crashSphere.hardness*2.0f;
|
||||
if ( ExploOther(iType, pObj, oType, force) ) continue;
|
||||
colType = ExploHimself(iType, oType, force);
|
||||
if ( colType == 2 ) return 2; // destroyed?
|
||||
|
@ -2630,12 +2635,12 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle)
|
|||
}
|
||||
|
||||
force = m_linMotion.realSpeed.Length();
|
||||
force *= pObj->GetCrashSphereHardness(j-1);
|
||||
force *= crashSphere.hardness;
|
||||
volume = fabs(force*0.05f);
|
||||
if ( volume > 1.0f ) volume = 1.0f;
|
||||
if ( sound != SOUND_CLICK )
|
||||
if ( crashSphere.sound != SOUND_CLICK )
|
||||
{
|
||||
m_sound->Play(sound, m_object->GetPosition(0), volume);
|
||||
m_sound->Play(crashSphere.sound, m_object->GetPosition(0), volume);
|
||||
}
|
||||
if ( iType == OBJECT_HUMAN && volume > 0.5f )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue