Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow projectiles to penetrate through ships, dealing damage multiple times #6276

Merged
merged 35 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
16d2759
Create an initial projectile penetration system
Amazinite Feb 8, 2021
3b33721
Penetrating projectiles can now impact multiple ships per frame
Amazinite Sep 30, 2021
0b2df61
Merge remote-tracking branch 'upstream/master' into projectile-penetr…
Amazinite Sep 30, 2021
e71b93a
Don't trigger multiple explosions per frame
Amazinite Sep 30, 2021
550b6be
Housekeeping
Amazinite Sep 30, 2021
0da4237
Make use of a simpler and more understandable Projectile::IsDead func…
Amazinite Oct 1, 2021
eb8f618
Pass the hits to CollisionSet as a pointer
Amazinite Oct 4, 2021
f46b943
Remove unnecessary include
Amazinite Oct 5, 2021
defee70
Allow penetrating projectiles to penetrate through asteroids
Amazinite Nov 24, 2021
b5cefb9
Count projectile penetrations down instead of up
Amazinite Nov 24, 2021
6aceee8
Fix up comments
Amazinite Nov 24, 2021
5bb3190
Merge remote-tracking branch 'upstream/master' into projectile-penetr…
Amazinite Jan 22, 2022
58a9eae
Merge remote-tracking branch 'upstream/master' into projectile-penetr…
Amazinite Mar 2, 2022
a1cfb2d
Merge remote-tracking branch 'upstream/master' into projectile-penetr…
Amazinite Mar 3, 2022
e324a72
Fix merge
Amazinite Mar 3, 2022
46ba014
Merge branch 'master' into projectile-penetration
Amazinite May 22, 2022
f63b3bd
Negative pen values = unlimited pen
Amazinite May 22, 2022
41cade3
The Quyykk method
Amazinite May 22, 2022
0f25fec
Merge branch 'master' into projectile-penetration
Amazinite Aug 13, 2023
9a28ef5
Change variable names types
Amazinite Aug 15, 2023
a8961b5
Merge branch 'master' into projectile-penetration
Amazinite Aug 19, 2023
3ab086f
Merge remote-tracking branch 'upstream/master' into projectile-penetr…
Amazinite Dec 24, 2023
ad18fc0
Revert CollisionSet changes
Amazinite Dec 24, 2023
62ba4e2
Revert Engine changes
Amazinite Dec 24, 2023
66053c9
Revert AsteroidField changes
Amazinite Dec 24, 2023
0149066
Refactor collisions
Amazinite Dec 25, 2023
a67cf1a
IsDead is true for lifetime == 0
Amazinite Dec 25, 2023
812370d
Fix missing file in the cbp
Amazinite Dec 25, 2023
4211a2d
Allow blast radius weapons to explode multiple times in a frame
Amazinite Dec 26, 2023
c643cc9
Feedback changes and updates
Amazinite Dec 29, 2023
8dbbd8d
Erroneous cbp update
Amazinite Dec 29, 2023
47fbda0
Housekeeping
Amazinite Dec 29, 2023
42664ad
And this is why we play test
Amazinite Dec 29, 2023
bdd489b
Merge branch 'master' into projectile-penetration
Amazinite Dec 30, 2023
5f6a3c3
Merge branch 'master' into projectile-penetration
Amazinite Jan 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions EndlessSkyLib.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,18 @@
<Unit filename="source/CategoryList.h" />
<Unit filename="source/CategoryTypes.h" />
<Unit filename="source/ClickZone.h" />
<Unit filename="source/Collision.cpp" />
<Unit filename="source/Collision.h" />
<Unit filename="source/CollisionSet.cpp" />
<Unit filename="source/CollisionSet.h" />
<Unit filename="source/CollisionType.h" />
<Unit filename="source/Color.cpp" />
<Unit filename="source/Color.h" />
<Unit filename="source/Command.cpp" />
<Unit filename="source/Command.h" />
<Unit filename="source/ConditionSet.cpp" />
<Unit filename="source/ConditionSet.h" />
<Unit filename="source/ConditionType.h" />
Amazinite marked this conversation as resolved.
Show resolved Hide resolved
<Unit filename="source/ConditionsStore.cpp" />
<Unit filename="source/ConditionsStore.h" />
<Unit filename="source/Conversation.cpp" />
Expand Down
36 changes: 18 additions & 18 deletions source/AsteroidField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ this program. If not, see <https://www.gnu.org/licenses/>.

#include "AsteroidField.h"

#include "Collision.h"
#include "CollisionType.h"
#include "DrawList.h"
#include "Mask.h"
#include "Minable.h"
Expand All @@ -39,7 +41,8 @@ namespace {

// Constructor, to set up the collision set parameters.
AsteroidField::AsteroidField()
: asteroidCollisions(CELL_SIZE, CELL_COUNT), minableCollisions(CELL_SIZE, CELL_COUNT)
: asteroidCollisions(CELL_SIZE, CELL_COUNT, CollisionType::ASTEROID),
minableCollisions(CELL_SIZE, CELL_COUNT, CollisionType::MINABLE)
{
}

Expand Down Expand Up @@ -121,10 +124,10 @@ void AsteroidField::Draw(DrawList &draw, const Point &center, double zoom) const



// Check if the given projectile collides with any asteroids.
Body *AsteroidField::Collide(const Projectile &projectile, double *closestHit)
// Check if the given projectile collides with any asteroids. This excludes minables.
const vector<Collision> &AsteroidField::CollideAsteroids(const Projectile &projectile)
{
Body *hit = nullptr;
result.clear();

// First, check for collisions with ordinary asteroids, which are tiled.
// Rather than tiling the collision set, tile the projectile.
Expand All @@ -147,22 +150,19 @@ Body *AsteroidField::Collide(const Projectile &projectile, double *closestHit)
for(int x = 0; x < tileX; ++x)
{
Point offset = Point(x, y) * WRAP;
Body *body = asteroidCollisions.Line(from + offset, to + offset, closestHit);
if(body)
hit = body;
const vector<Collision> &newHits = asteroidCollisions.LineAll(from + offset, to + offset);
result.insert(result.end(), newHits.begin(), newHits.end());
}

// Now, check for collisions with minable asteroids. Because this is the
// very last collision check to be done, if a minable asteroid is the
// closest hit, it really is what the projectile struck - that is, we are
// not going to later find a ship or something else that is closer.
Body *body = minableCollisions.Line(projectile, closestHit);
if(body)
{
hit = body;
reinterpret_cast<Minable *>(body)->TakeDamage(projectile);
}
return hit;
return result;
}



// Check if the given projectile collides with any minables.
const vector<Collision> &AsteroidField::CollideMinables(const Projectile &projectile)
{
return minableCollisions.LineAll(projectile);
}


Expand Down
12 changes: 9 additions & 3 deletions source/AsteroidField.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include <string>
#include <vector>

class Collision;
class DrawList;
class Flotsam;
class Minable;
Expand Down Expand Up @@ -58,9 +59,11 @@ class AsteroidField {
void Step(std::vector<Visual> &visuals, std::list<std::shared_ptr<Flotsam>> &flotsam, int step);
// Draw the asteroid field, with the field of view centered on the given point.
void Draw(DrawList &draw, const Point &center, double zoom) const;
// Check if the given projectile has hit any of the asteroids, using the information
// in the collision sets. If a collision occurs, returns a pointer to the hit body.
Body *Collide(const Projectile &projectile, double *closestHit);

// Check if the given projectile collides with any asteroids. This excludes minables.
const std::vector<Collision> &CollideAsteroids(const Projectile &projectile);
// Check if the given projectile collides with any minables.
const std::vector<Collision> &CollideMinables(const Projectile &projectile);

// Get the list of minable asteroids.
const std::list<std::shared_ptr<Minable>> &Minables() const;
Expand Down Expand Up @@ -88,6 +91,9 @@ class AsteroidField {

CollisionSet asteroidCollisions;
CollisionSet minableCollisions;

// Vector for returning the result of CollideAsteroids.
mutable std::vector<Collision> result;
Amazinite marked this conversation as resolved.
Show resolved Hide resolved
};


Expand Down
3 changes: 3 additions & 0 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ target_sources(EndlessSkyLib PRIVATE
CategoryList.h
CategoryTypes.h
ClickZone.h
Collision.cpp
Collision.h
CollisionSet.cpp
CollisionSet.h
CollisionType.h
Color.cpp
Color.h
Command.cpp
Expand Down
54 changes: 54 additions & 0 deletions source/Collision.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* Collision.cpp
Copyright (c) 2023 by Amazinite

Endless Sky 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.

Endless Sky 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 <https://www.gnu.org/licenses/>.
*/

#include "Collision.h"

using namespace std;



Collision::Collision(Body *hit, CollisionType collisionType, double range)
: hit(hit), collisionType(collisionType), range(range)
{

}



Body *Collision::HitBody()
{
return hit;
}



CollisionType Collision::GetCollisionType() const
{
return collisionType;
}



double Collision::IntersectionRange() const
{
return range;
}



bool Collision::operator<(const Collision &rhs) const
{
return range < rhs.range;
}
52 changes: 52 additions & 0 deletions source/Collision.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Collision.h
Copyright (c) 2023 by Amazinite

Endless Sky 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.

Endless Sky 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 <https://www.gnu.org/licenses/>.
*/

#ifndef COLLISION_H_
#define COLLISION_H_

#include "Body.h"
#include "CollisionType.h"

#include <list>
#include <memory>
#include <vector>
Amazinite marked this conversation as resolved.
Show resolved Hide resolved



// Represents a collision between a projectile and a ship, asteroid, or minable.
// Contains information such as the distance
Amazinite marked this conversation as resolved.
Show resolved Hide resolved
class Collision {
public:
// Initialize a Collision, recording the Body that was hit, the type of
// object that the Body is (nothing, a Ship, a Minable, or an Asteroid),
// and the range that the Body was hit at.
Amazinite marked this conversation as resolved.
Show resolved Hide resolved
Collision(Body *hit, CollisionType collisionType, double range);

Body *HitBody();
CollisionType GetCollisionType() const;
double IntersectionRange() const;

bool operator<(const Collision &rhs) const;


private:
Body *hit = nullptr;
Amazinite marked this conversation as resolved.
Show resolved Hide resolved
CollisionType collisionType = CollisionType::NONE;
double range;
};



#endif
Loading