Skip to content

Commit

Permalink
feat(enhancement): Allow ships to define their center of rotation (#9423
Browse files Browse the repository at this point in the history
)
  • Loading branch information
RisingLeaf committed Dec 10, 2023
1 parent 17cece9 commit ab87988
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
45 changes: 45 additions & 0 deletions source/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ this program. If not, see <https://www.gnu.org/licenses/>.
#include "GameData.h"
#include "Mask.h"
#include "MaskManager.h"
#include "pi.h"
#include "Random.h"
#include "Sprite.h"
#include "SpriteSet.h"
Expand Down Expand Up @@ -147,6 +148,13 @@ const Point &Body::Velocity() const



const Point Body::Center() const
{
return -rotatedCenter + position;
}



// Direction this Body is facing in.
const Angle &Body::Facing() const
{
Expand Down Expand Up @@ -231,6 +239,8 @@ void Body::LoadSprite(const DataNode &node)
}
else if(child.Token(0) == "rewind")
rewind = true;
else if(child.Token(0) == "center" && child.Size() >= 3)
center = Point(child.Value(1), child.Value(2));
else
child.PrintTrace("Skipping unrecognized attribute:");
}
Expand Down Expand Up @@ -262,6 +272,8 @@ void Body::SaveSprite(DataWriter &out, const string &tag) const
out.Write("no repeat");
if(rewind)
out.Write("rewind");
if(center)
out.Write("center", center.X(), center.Y());
}
out.EndChild();
}
Expand Down Expand Up @@ -332,6 +344,39 @@ void Body::UnmarkForRemoval()



// Turn this object around its center of rotation.
void Body::Turn(double amount)
{
angle += amount;
if(!center)
return;

auto RotatePointAroundOrigin = [](Point &toRotate, double radians) -> Point {
float si = sin(radians);
float co = cos(radians);
float newX = toRotate.X() * co - toRotate.Y() * si;
float newY = toRotate.X() * si + toRotate.Y() * co;
return Point(newX, newY);
};

rotatedCenter = -RotatePointAroundOrigin(center, (angle - amount).Degrees() * TO_RAD);

position -= rotatedCenter;

rotatedCenter = RotatePointAroundOrigin(rotatedCenter, Angle(amount).Degrees() * TO_RAD);

position += rotatedCenter;
}



void Body::Turn(const Angle &amount)
{
Turn(amount.Degrees());
}



// Set the current time step.
void Body::SetStep(int step) const
{
Expand Down
6 changes: 6 additions & 0 deletions source/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Body {
// Positional attributes.
const Point &Position() const;
const Point &Velocity() const;
const Point Center() const;
const Angle &Facing() const;
Point Unit() const;
double Zoom() const;
Expand Down Expand Up @@ -88,13 +89,18 @@ class Body {
void MarkForRemoval();
// Mark that this object should not be removed (e.g. a launched fighter).
void UnmarkForRemoval();
// Turn this object around its center of rotation.
void Turn(double amount);
void Turn(const Angle &amount);


protected:
// Basic positional attributes.
Point position;
Point velocity;
Angle angle;
Point center;
Point rotatedCenter;
// A zoom of 1 means the sprite should be drawn at half size. For objects
// whose sprites should be full size, use zoom = 2.
float zoom = 1.f;
Expand Down
4 changes: 2 additions & 2 deletions source/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ void Engine::Step(bool isActive)
}
else if(flagship)
{
center = flagship->Position();
center = flagship->Center();
centerVelocity = flagship->Velocity();
Preferences::ExtendedJumpEffects jumpEffectState = Preferences::GetExtendedJumpEffects();
if(flagship->IsHyperspacing() && jumpEffectState != Preferences::ExtendedJumpEffects::OFF)
Expand Down Expand Up @@ -1587,7 +1587,7 @@ void Engine::CalculateStep()
Point newCenterVelocity;
if(flagship)
{
newCenter = flagship->Position();
newCenter = flagship->Center();
newCenterVelocity = flagship->Velocity();
}
draw[calcTickTock].SetCenter(newCenter, newCenterVelocity);
Expand Down
4 changes: 2 additions & 2 deletions source/Ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@ void Ship::Place(Point position, Point velocity, Angle angle, bool isDeparting)
{
this->position = position;
this->velocity = velocity;
this->angle = angle;
this->Turn(angle);

// If landed, place the ship right above the planet.
// Escorts should take off a bit behind their flagships.
Expand Down Expand Up @@ -4267,7 +4267,7 @@ void Ship::DoMovement(bool &isUsingAfterburner)
slowness += scale * attributes.Get("turning slowing");
disruption += scale * attributes.Get("turning disruption");

angle += commands.Turn() * TurnRate() * slowMultiplier;
Turn(commands.Turn() * TurnRate() * slowMultiplier);
}
}
double thrustCommand = commands.Has(Command::FORWARD) - commands.Has(Command::BACK);
Expand Down

0 comments on commit ab87988

Please sign in to comment.