Skip to content

Commit

Permalink
feat(solidity): add solidity rotating with direction changes
Browse files Browse the repository at this point in the history
Make direction and solidity fields auto synchronizable

fix #21
  • Loading branch information
Insineer committed Oct 9, 2019
1 parent 6122b80 commit 51eef56
Show file tree
Hide file tree
Showing 19 changed files with 74 additions and 68 deletions.
12 changes: 9 additions & 3 deletions GameLogic/Engine/Geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def NextDirection(dir: Direction) -> Direction:
raise TypeError("Bad direction type!")


class DirectionSet(eDirectionSet):
class DirectionSet():
"""
A class used to represent a set of directions. You can add directions and check which are already added.
Any composite direction will be broken to its components.
Expand All @@ -304,8 +304,14 @@ class DirectionSet(eDirectionSet):
"""

def __init__(self, impl = eDirectionSet()):
self._impl = impl
def __init__(self, *args):
if len(args) > 0 and isinstance(args[0], eDirectionSet):
self._impl = args[0]
else:
self._impl = eDirectionSet()

if len(args) > 0 and isinstance(args[0], list):
self.Add(args[0])

def Add(self, directions: List[Direction]):
self._impl.Add(directions)
Expand Down
15 changes: 9 additions & 6 deletions GameLogic/Objects/Turfs/Airlock.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from Engine.Geometry import Direction
from Engine.Geometry import Direction, DirectionSet
from Objects.Turf import Turf

class Airlock(Turf):
Expand All @@ -7,12 +7,15 @@ class Airlock(Turf):

def __init__(self):
super().__init__()
self.__closedSolidity = [Direction.CENTER]

self.solidity.Add(self.__closedSolidity)
self.__closedSolidity = DirectionSet()
self.__closedSolidity.Add([Direction.CENTER])

self.solidity = self.__closedSolidity

self.opened = False
self.locked = False

def InteractedBy(self, object):
if not self.IsCloseTo(object):
return False
Expand All @@ -30,7 +33,7 @@ def Activate(self):
return
self.sprite = "airlock"
self.opened = False
self.solidity.Add(self.__closedSolidity)
self.solidity = self.__closedSolidity
else:
if not self.PlayAnimation("airlock_opening", lambda: self.__animationOpeningCallback()):
return
Expand All @@ -44,7 +47,7 @@ def Unlock(self):

def __animationOpeningCallback(self):
self.opened = True
self.solidity.Reset()
self.solidity = DirectionSet()

def __autocloseCallback(self):
if self.opened:
Expand Down
4 changes: 2 additions & 2 deletions GameLogic/Objects/Turfs/Wall.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from Engine.Geometry import Direction
from Engine.Geometry import Direction, DirectionSet
from Objects.Turf import Turf

class Wall(Turf):
Expand All @@ -8,4 +8,4 @@ class Wall(Turf):
def __init__(self):
super().__init__()
self.isWall = True
self.solidity.Add([Direction.CENTER])
self.solidity = DirectionSet([Direction.CENTER])
4 changes: 2 additions & 2 deletions GameLogic/Objects/Turfs/Window.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from Engine.Geometry import Direction
from Engine.Geometry import Direction, DirectionSet
from Engine.World import Object

from Objects.Turf import Turf
Expand All @@ -11,4 +11,4 @@ class Window(Turf):
def __init__(self):
super().__init__()
self.layer = 80
self.solidity.Add([Direction.SOUTH])
self.solidity = DirectionSet([Direction.SOUTH])
16 changes: 8 additions & 8 deletions OSS13 Client/Sources/Graphics/TileGrid/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ Object::Object(network::protocol::ObjectInfo &&objectInfo) {

id = objectInfo.id;
layer = objectInfo.layer;
direction = objectInfo.direction;
density = objectInfo.density;
solidity = objectInfo.solidity;
opacity = objectInfo.opacity;
moveSpeed = objectInfo.moveSpeed;
speed = objectInfo.speed;
Expand Down Expand Up @@ -49,6 +47,13 @@ void Object::Draw(sf::RenderTarget *target, uf::vec2i pos) {
}

void Object::Update(sf::Time timeElapsed) {
if (direction.PopChangedState()) {
for (auto &sprite : sprites) {
if (sprite.IsValid()) sprite.SetDirection(direction);
}
if (animation.IsValid()) animation.SetDirection(direction);
}

// Movement

uf::vec2f deltaShift = uf::phys::countDeltaShift(timeElapsed, shift, moveSpeed, moveIntent, speed);
Expand Down Expand Up @@ -95,13 +100,8 @@ void Object::PlayAnimation(uint id) {
void Object::SetDirection(const uf::Direction newdirection) {
if (newdirection == uf::Direction::NONE)
return;

// cut the diagonal directions
// cut the diagonal directions
direction = uf::Direction(char(newdirection) % 4);
for (auto &sprite : sprites) {
if (sprite.IsValid()) sprite.SetDirection(direction);
}
if (animation.IsValid()) animation.SetDirection(direction);
}

void Object::SetMoveSpeed(float moveSpeed) {
Expand Down
2 changes: 0 additions & 2 deletions OSS13 Client/Sources/Graphics/TileGrid/Object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,9 @@ class Object : public network::sync::ObjectSyncFields {
std::vector<::Sprite> sprites;
::Sprite animation;
bool animationProcess{};
uf::Direction direction{uf::Direction::NONE};
uint layer{};

bool density{};
uf::DirectionSet solidity;
uf::DirectionSetFractional opacity;

uf::vec2f shift;
Expand Down
2 changes: 1 addition & 1 deletion OSS13 Client/Sources/Graphics/TileGrid/Tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,6 @@ bool Tile::IsBlocked() const {

bool Tile::IsBlocked(uf::DirectionSet directions) const {
for (auto &obj : content)
if (obj->GetSolidity().DoesExistOne(directions)) return true;
if (obj->GetSolidity().Rotate(obj->GetDirection()).DoesExistOne(directions)) return true;
return false;
}
8 changes: 0 additions & 8 deletions OSS13 Client/Sources/Graphics/TileGrid/TileGrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,14 +443,6 @@ void TileGrid::PlayAnimation(uint id, uint animation_id) {
}
}

void TileGrid::ChangeObjectDirection(uint id, uf::Direction direction) {
auto iter = objects.find(id);
if (iter != objects.end()) {
Object *obj = iter->second.get();
obj->SetDirection(direction);
}
}

void TileGrid::Stunned(uint id, sf::Time duration) {
if (id == controllable->GetID())
stun = duration;
Expand Down
1 change: 0 additions & 1 deletion OSS13 Client/Sources/Graphics/TileGrid/TileGrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class TileGrid : public Container {
void MoveObject(uint id, uf::Direction direction, float speed);
void UpdateObjectIcons(uint id, const std::vector<uint32_t> &icons);
void PlayAnimation(uint id, uint animation_id);
void ChangeObjectDirection(uint id, uf::Direction direction);
void Stunned(uint id, sf::Time duration);

void ShiftBlocks(apos newFirst);
Expand Down
2 changes: 0 additions & 2 deletions OSS13 Client/Sources/Network/SyncCommandsProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ void SyncCommandsProcessor::commandProcessor_GraphicsUpdateCommand(network::prot
tileGrid->UpdateObjectIcons(diff->objId, diff->iconsIds);
} else if (auto *diff = dynamic_cast<network::protocol::PlayAnimationDiff *>(generalDiff.get())) {
tileGrid->PlayAnimation(diff->objId, diff->animationId);
} else if (auto *diff = dynamic_cast<network::protocol::ChangeDirectionDiff *>(generalDiff.get())) {
tileGrid->ChangeObjectDirection(diff->objId, diff->direction);
} else if (auto *diff = dynamic_cast<network::protocol::StunnedDiff *>(generalDiff.get())) {
tileGrid->Stunned(diff->objId, sf::microseconds(diff->duration.count()));
};
Expand Down
13 changes: 2 additions & 11 deletions OSS13 Server/Sources/World/Objects/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
Object::Object() :
movable(true),
spriteState(Global::ItemSpriteState::DEFAULT),
layer(0),
direction(uf::Direction::NONE),
layer(0),
tile(nullptr),
holder(nullptr),
moveSpeed(0)
Expand Down Expand Up @@ -201,12 +200,6 @@ void Object::SetDirection(uf::Direction direction) {
if (direction > uf::Direction::EAST)
direction = uf::Direction(char(direction) % 4);
this->direction = direction;
if (tile) {
auto changeDirectionDiff = std::make_shared<network::protocol::ChangeDirectionDiff>();
changeDirectionDiff->objId = ID();
changeDirectionDiff->direction = direction;
tile->AddDiff(std::move(changeDirectionDiff), this);
}
}
uf::Direction Object::GetDirection() { return direction; }

Expand Down Expand Up @@ -234,7 +227,7 @@ bool Object::GetDensity() const { return density; }
void Object::SetDensity(bool density) { this->density = density; }

void Object::SetSolidity(uf::DirectionSet directions) { solidity = directions; }
const uf::DirectionSet &Object::GetSolidity() const { return solidity; }
uf::DirectionSet Object::GetSolidity() const { return solidity; }

void Object::SetOpacity(uf::DirectionSetFractional fractionalDirections) { opacity = fractionalDirections; }
const uf::DirectionSetFractional &Object::GetOpacity() const { return opacity; }
Expand Down Expand Up @@ -329,9 +322,7 @@ network::protocol::ObjectInfo Object::GetObjectInfo() const {
objectInfo.id = id;
objectInfo.fields = *this;
objectInfo.layer = layer;
objectInfo.direction = direction;
objectInfo.density = density;
objectInfo.solidity = solidity;
objectInfo.opacity = opacity;
objectInfo.moveSpeed = moveSpeed;
objectInfo.speed = speed;
Expand Down
4 changes: 1 addition & 3 deletions OSS13 Server/Sources/World/Objects/Object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class Object : public network::sync::ObjectSyncFields, public VerbsHolder, publi
bool GetDensity() const;

void SetSolidity(uf::DirectionSet directions);
const uf::DirectionSet &GetSolidity() const;
uf::DirectionSet GetSolidity() const;

void SetOpacity(uf::DirectionSetFractional fractionalDirections);
const uf::DirectionSetFractional &GetOpacity() const;
Expand Down Expand Up @@ -135,10 +135,8 @@ class Object : public network::sync::ObjectSyncFields, public VerbsHolder, publi
uf::Timer animationTimer;
// Object layer 0-100. The smaller layer is lower.
uint layer;
uf::Direction direction;

bool density{false}; // object can't pass through solid objects
uf::DirectionSet solidity;
uf::DirectionSetFractional opacity;
uf::DirectionSetFractional airtightness;

Expand Down
4 changes: 2 additions & 2 deletions OSS13 Server/Sources/World/Tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ const std::list<Object *> &Tile::Content() const {
Object *Tile::GetDenseObject(uf::DirectionSet directions) const
{
for (auto &obj : content)
if (obj->GetSolidity().DoesExistOne(directions)) return obj;
if (obj->GetSolidity().Rotate(obj->GetDirection()).DoesExistOne(directions)) return obj;
return nullptr;
}

Expand All @@ -231,7 +231,7 @@ Map *Tile::GetMap() const { return map; }

bool Tile::IsDense(uf::DirectionSet directions) const {
for (auto &obj : content)
if (obj->GetSolidity().DoesExistOne(directions)) return true;
if (obj->GetSolidity().Rotate(obj->GetDirection()).DoesExistOne(directions)) return true;
return false;
}

Expand Down
25 changes: 25 additions & 0 deletions SharedLibrary/Sources/Shared/Geometry/DirectionSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,31 @@ bool DirectionSet::DoExistAll(const std::list<Direction> &directions) const {
return DoExistAll(DirectionSet(directions));
}

DirectionSet DirectionSet::Rotate(Direction direction) const {
size_t shift;
switch (direction) {
case Direction::WEST:
shift = 1;
break;
case Direction::NORTH:
shift = 2;
break;
case Direction::EAST:
shift = 3;
break;
default:
return *this;
}

DirectionSet result;

for (size_t i = 0; i < 3; i++)
result.buffer[(i + shift) % 4] = buffer[i];
result.buffer[4] = buffer[4];

return result;
}

void DirectionSet::Reset() {
buffer.reset();
}
Expand Down
12 changes: 5 additions & 7 deletions SharedLibrary/Sources/Shared/Geometry/DirectionSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@
#include <list>

#include <Shared/ErrorHandling.h>
#include <Shared/IFaces/ICopyable.h>
#include <Shared/Geometry/Direction.hpp>

namespace uf {

class DirectionSet {
class DirectionSet : public ICopyable {
public:
DirectionSet() = default;
DirectionSet() { };
DirectionSet(std::list<Direction> directions);

DirectionSet(const DirectionSet &) = default;
DirectionSet(DirectionSet &&) = default;
DirectionSet &operator=(const DirectionSet &) = default;
DirectionSet &operator=(DirectionSet &&) = default;

void Add(DirectionSet directions);
void Add(const std::list<Direction> &directions);

Expand All @@ -32,6 +28,8 @@ class DirectionSet {
bool DoExistAll(DirectionSet directions) const;
bool DoExistAll(const std::list<Direction> &directions) const;

DirectionSet Rotate(Direction direction) const;

void Reset();

const std::bitset<5> &GetBuffer() const;
Expand Down
1 change: 0 additions & 1 deletion SharedLibrary/Sources/Shared/Network/ISerializable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ std::unique_ptr<ISerializable> CreateSerializableById(uint32_t id) {
DECLARE_SER(MoveDiff)
DECLARE_SER(UpdateIconsDiff)
DECLARE_SER(PlayAnimationDiff)
DECLARE_SER(ChangeDirectionDiff)
DECLARE_SER(StunnedDiff)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,6 @@ DEFINE_SERIALIZABLE(PlayAnimationDiff, Diff)
}
DEFINE_SERIALIZABLE_END

DEFINE_SERIALIZABLE(ChangeDirectionDiff, Diff)
uf::Direction direction;
void Serialize(uf::Archive &ar) override {
Diff::Serialize(ar);
ar & direction;
}
DEFINE_SERIALIZABLE_END

DEFINE_SERIALIZABLE(StunnedDiff, Diff)
std::chrono::microseconds duration;
void Serialize(uf::Archive &ar) override {
Expand Down
2 changes: 2 additions & 0 deletions SharedLibrary/Sources/Shared/Network/Syncable.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ DEFINE_SERIALIZABLE(GeneralSyncField, uf::ISerializable)
GeneralSyncField(GeneralSyncField &&other) : changed(std::move(other.changed)) { }
GeneralSyncField &operator=(GeneralSyncField &&other) { this->changed = std::move(other.changed); return *this; }

bool PopChangedState() { bool temp = changed; changed = false; return temp; }

protected:
void setChanged();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

#include <Shared/Network/Archive.h>
#include <Shared/Network/Syncable.h>
#include <Shared/Geometry/DirectionSet.h>

namespace network {
namespace sync {

DEFINE_SYNCABLE(ObjectSyncFields)
protected:
uf::SyncField<std::string> name;
uf::SyncField<uf::Direction> direction;
uf::SyncField<uf::DirectionSet> solidity;

public:
ObjectSyncFields() {
DECLARE_SYNCABLE_FIELD(&ObjectSyncFields::name);
DECLARE_SYNCABLE_FIELD(&ObjectSyncFields::name);
DECLARE_SYNCABLE_FIELD(&ObjectSyncFields::direction);
DECLARE_SYNCABLE_FIELD(&ObjectSyncFields::solidity);
};
DEFINE_SYNCABLE_END

Expand Down

0 comments on commit 51eef56

Please sign in to comment.