Skip to content

Commit

Permalink
close EE-367
Browse files Browse the repository at this point in the history
  • Loading branch information
stohrendorf committed Sep 19, 2021
1 parent 9aaef31 commit c379408
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 99 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ set( EDISONENGINE_SRCS
engine/objects/teethspikes.cpp
engine/objects/thorhammer.h
engine/objects/thorhammer.cpp
engine/objects/trapdoordown.h
engine/objects/trapdoordown.cpp
engine/objects/trapdoorup.h
engine/objects/trapdoorup.cpp
engine/objects/trex.h
Expand Down
4 changes: 4 additions & 0 deletions src/engine/objects/door.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ Door::Door(const std::string& name,
#endif

getSkeleton()->getRenderState().setScissorTest(false);
getSkeleton()->getRenderState().setPolygonOffsetFill(true);
getSkeleton()->getRenderState().setPolygonOffset(-1, -1);
}

void Door::update()
Expand Down Expand Up @@ -146,6 +148,8 @@ void Door::serialize(const serialization::Serializer<world::World>& ser)
if(ser.loading)
{
getSkeleton()->getRenderState().setScissorTest(false);
getSkeleton()->getRenderState().setPolygonOffsetFill(true);
getSkeleton()->getRenderState().setPolygonOffset(-1, -1);

ser.lazy(
[this](const serialization::Serializer<world::World>& /*ser*/)
Expand Down
101 changes: 101 additions & 0 deletions src/engine/objects/trapdoordown.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "trapdoordown.h"

#include "core/angle.h"
#include "core/id.h"
#include "core/magic.h"
#include "core/vec.h"
#include "engine/location.h"
#include "engine/skeletalmodelnode.h"
#include "modelobject.h"
#include "objectstate.h"
#include "qs/qs.h"
#include "serialization/serialization.h" // IWYU pragma: keep

#include <boost/assert.hpp>
#include <gl/renderstate.h>
#include <memory>
#include <optional>

namespace engine::objects
{
TrapDoorDown::TrapDoorDown(const std::string& name,
const gsl::not_null<world::World*>& world,
const gsl::not_null<const world::Room*>& room,
const loader::file::Item& item,
const gsl::not_null<const world::SkeletalModelType*>& animatedModel)
: ModelObject{name, world, room, item, true, animatedModel}
{
getSkeleton()->getRenderState().setScissorTest(false);
getSkeleton()->getRenderState().setPolygonOffsetFill(true);
getSkeleton()->getRenderState().setPolygonOffset(-1, -1);
}

void TrapDoorDown::serialize(const serialization::Serializer<world::World>& ser)
{
ModelObject::serialize(ser);
if(ser.loading)
{
getSkeleton()->getRenderState().setScissorTest(false);
getSkeleton()->getRenderState().setPolygonOffsetFill(true);
getSkeleton()->getRenderState().setPolygonOffset(-1, -1);
}
}

void TrapDoorDown::update()
{
if(m_state.updateActivationTimeout())
{
if(m_state.current_anim_state == 0_as)
m_state.goal_anim_state = 1_as;
}
else if(m_state.current_anim_state == 1_as)
{
m_state.goal_anim_state = 0_as;
}

ModelObject::update();
}

void TrapDoorDown::patchFloor(const core::TRVec& pos, core::Length& y)
{
if(m_state.current_anim_state != 0_as || !possiblyOnTrapdoor(pos) || pos.Y > m_state.location.position.Y
|| y <= m_state.location.position.Y)
return;

y = m_state.location.position.Y;
}

void TrapDoorDown::patchCeiling(const core::TRVec& pos, core::Length& y)
{
if(m_state.current_anim_state != 0_as || !possiblyOnTrapdoor(pos) || pos.Y <= m_state.location.position.Y
|| y > m_state.location.position.Y)
return;

y = m_state.location.position.Y + core::QuarterSectorSize;
}

bool TrapDoorDown::possiblyOnTrapdoor(const core::TRVec& pos) const
{
const auto trapdoorSectorX = m_state.location.position.X / core::SectorSize;
const auto trapdoorSectorZ = m_state.location.position.Z / core::SectorSize;
const auto posSectorX = pos.X / core::SectorSize;
const auto posSectorZ = pos.Z / core::SectorSize;
auto trapdoorAxis = axisFromAngle(m_state.rotation.Y, 1_au);
BOOST_ASSERT(trapdoorAxis.has_value());

if(*trapdoorAxis == core::Axis::PosZ && trapdoorSectorX == posSectorX
&& (trapdoorSectorZ + 1 == posSectorZ || trapdoorSectorZ == posSectorZ))
return true;
if(*trapdoorAxis == core::Axis::NegZ && trapdoorSectorX == posSectorX
&& (trapdoorSectorZ - 1 == posSectorZ || trapdoorSectorZ == posSectorZ))
return true;
if(*trapdoorAxis == core::Axis::PosX && trapdoorSectorZ == posSectorZ
&& (trapdoorSectorX + 1 == posSectorX || trapdoorSectorX == posSectorX))
return true;
if(*trapdoorAxis == core::Axis::NegX && trapdoorSectorZ == posSectorZ
&& (trapdoorSectorX - 1 == posSectorX || trapdoorSectorX == posSectorX))
return true;

return false;
}
} // namespace engine::objects
94 changes: 42 additions & 52 deletions src/engine/objects/trapdoordown.h
Original file line number Diff line number Diff line change
@@ -1,71 +1,61 @@
#pragma once

#include "core/units.h"
#include "modelobject.h"
#include "serialization/serialization_fwd.h"

#include <gsl/gsl-lite.hpp>
#include <string>

// IWYU pragma: no_forward_declare serialization::Serializer

namespace core
{
struct TRVec;
}

namespace engine
{
struct Location;
}

namespace engine::world
{
class World;
struct Room;
struct SkeletalModelType;
} // namespace engine::world

namespace loader::file
{
struct Item;
}

namespace engine::objects
{
class TrapDoorDown final : public ModelObject
{
public:
MODELOBJECT_DEFAULT_CONSTRUCTORS(TrapDoorDown, true)

void update() override
TrapDoorDown(const gsl::not_null<world::World*>& world, const Location& location)
: ModelObject{world, location}
{
if(m_state.updateActivationTimeout())
{
if(m_state.current_anim_state == 0_as)
m_state.goal_anim_state = 1_as;
}
else if(m_state.current_anim_state == 1_as)
{
m_state.goal_anim_state = 0_as;
}

ModelObject::update();
}

void patchFloor(const core::TRVec& pos, core::Length& y) override
{
if(m_state.current_anim_state != 0_as || !possiblyOnTrapdoor(pos) || pos.Y > m_state.location.position.Y
|| y <= m_state.location.position.Y)
return;
TrapDoorDown(const std::string& name,
const gsl::not_null<world::World*>& world,
const gsl::not_null<const world::Room*>& room,
const loader::file::Item& item,
const gsl::not_null<const world::SkeletalModelType*>& animatedModel);

y = m_state.location.position.Y;
}

void patchCeiling(const core::TRVec& pos, core::Length& y) override
{
if(m_state.current_anim_state != 0_as || !possiblyOnTrapdoor(pos) || pos.Y <= m_state.location.position.Y
|| y > m_state.location.position.Y)
return;
void update() override;

y = m_state.location.position.Y + core::QuarterSectorSize;
}
void patchFloor(const core::TRVec& pos, core::Length& y) override;

private:
bool possiblyOnTrapdoor(const core::TRVec& pos) const
{
const auto trapdoorSectorX = m_state.location.position.X / core::SectorSize;
const auto trapdoorSectorZ = m_state.location.position.Z / core::SectorSize;
const auto posSectorX = pos.X / core::SectorSize;
const auto posSectorZ = pos.Z / core::SectorSize;
auto trapdoorAxis = axisFromAngle(m_state.rotation.Y, 1_au);
BOOST_ASSERT(trapdoorAxis.has_value());
void patchCeiling(const core::TRVec& pos, core::Length& y) override;

if(*trapdoorAxis == core::Axis::PosZ && trapdoorSectorX == posSectorX
&& (trapdoorSectorZ + 1 == posSectorZ || trapdoorSectorZ == posSectorZ))
return true;
if(*trapdoorAxis == core::Axis::NegZ && trapdoorSectorX == posSectorX
&& (trapdoorSectorZ - 1 == posSectorZ || trapdoorSectorZ == posSectorZ))
return true;
if(*trapdoorAxis == core::Axis::PosX && trapdoorSectorZ == posSectorZ
&& (trapdoorSectorX + 1 == posSectorX || trapdoorSectorX == posSectorX))
return true;
if(*trapdoorAxis == core::Axis::NegX && trapdoorSectorZ == posSectorZ
&& (trapdoorSectorX - 1 == posSectorX || trapdoorSectorX == posSectorX))
return true;
void serialize(const serialization::Serializer<world::World>& ser) override;

return false;
}
private:
bool possiblyOnTrapdoor(const core::TRVec& pos) const;
};
} // namespace engine::objects
77 changes: 77 additions & 0 deletions src/engine/objects/trapdoorup.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
#include "trapdoorup.h"

#include "core/angle.h"
#include "core/id.h"
#include "core/magic.h"
#include "core/vec.h"
#include "engine/location.h"
#include "engine/skeletalmodelnode.h"
#include "modelobject.h"
#include "objectstate.h"
#include "qs/qs.h"
#include "serialization/serialization.h" // IWYU pragma: keep

#include <boost/assert.hpp>
#include <gl/renderstate.h>
#include <memory>
#include <optional>

namespace engine::objects
{
Expand All @@ -11,4 +24,68 @@ void TrapDoorUp::update()
m_state.location.updateRoom();
setCurrentRoom(m_state.location.room);
}

TrapDoorUp::TrapDoorUp(const std::string& name,
const gsl::not_null<world::World*>& world,
const gsl::not_null<const world::Room*>& room,
const loader::file::Item& item,
const gsl::not_null<const world::SkeletalModelType*>& animatedModel)
: ModelObject{name, world, room, item, true, animatedModel}
{
getSkeleton()->getRenderState().setScissorTest(false);
getSkeleton()->getRenderState().setPolygonOffsetFill(true);
getSkeleton()->getRenderState().setPolygonOffset(-1, -1);
}

void TrapDoorUp::serialize(const serialization::Serializer<world::World>& ser)
{
ModelObject::serialize(ser);
if(ser.loading)
{
getSkeleton()->getRenderState().setScissorTest(false);
getSkeleton()->getRenderState().setPolygonOffsetFill(true);
getSkeleton()->getRenderState().setPolygonOffset(-1, -1);
}
}

void TrapDoorUp::patchFloor(const core::TRVec& pos, core::Length& y)
{
if(m_state.current_anim_state != 1_as || !possiblyOnTrapdoor(pos) || pos.Y > m_state.location.position.Y)
return;

y = m_state.location.position.Y;
}

void TrapDoorUp::patchCeiling(const core::TRVec& pos, core::Length& y)
{
if(m_state.current_anim_state != 1_as || !possiblyOnTrapdoor(pos) || pos.Y <= m_state.location.position.Y)
return;

y = m_state.location.position.Y + core::QuarterSectorSize;
}

bool TrapDoorUp::possiblyOnTrapdoor(const core::TRVec& pos) const
{
const auto trapdoorSectorX = m_state.location.position.X / core::SectorSize;
const auto trapdoorSectorZ = m_state.location.position.Z / core::SectorSize;
const auto posSectorX = pos.X / core::SectorSize;
const auto posSectorZ = pos.Z / core::SectorSize;
auto trapdoorAxis = axisFromAngle(m_state.rotation.Y, 1_au);
BOOST_ASSERT(trapdoorAxis.has_value());

if(*trapdoorAxis == core::Axis::PosZ && trapdoorSectorX == posSectorX
&& (trapdoorSectorZ - 1 == posSectorZ || trapdoorSectorZ - 2 == posSectorZ))
return true;
if(*trapdoorAxis == core::Axis::NegZ && trapdoorSectorX == posSectorX
&& (trapdoorSectorZ + 1 == posSectorZ || trapdoorSectorZ + 2 == posSectorZ))
return true;
if(*trapdoorAxis == core::Axis::PosX && trapdoorSectorZ == posSectorZ
&& (trapdoorSectorX - 1 == posSectorX || trapdoorSectorX - 2 == posSectorX))
return true;
if(*trapdoorAxis == core::Axis::NegX && trapdoorSectorZ == posSectorZ
&& (trapdoorSectorX + 1 == posSectorX || trapdoorSectorX + 2 == posSectorX))
return true;

return false;
}
} // namespace engine::objects
Loading

0 comments on commit c379408

Please sign in to comment.