Skip to content

Commit 106006f

Browse files
authored
Merge pull request #2226 from mrkubax10/fix_triggers
Fix triggers
2 parents 7345094 + ad4b689 commit 106006f

File tree

3 files changed

+72
-25
lines changed

3 files changed

+72
-25
lines changed

src/trigger/climbable.cpp

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const float POSITION_FIX_AY = 50; // y-wise acceleration applied to player when
3535

3636
Climbable::Climbable(const ReaderMapping& reader) :
3737
climbed_by(),
38-
activate_try_timer(),
38+
trying_to_climb(),
3939
message(),
4040
new_size(0.0f, 0.0f)
4141
{
@@ -52,7 +52,7 @@ Climbable::Climbable(const ReaderMapping& reader) :
5252

5353
Climbable::Climbable(const Rectf& area) :
5454
climbed_by(),
55-
activate_try_timer(),
55+
trying_to_climb(),
5656
message(),
5757
new_size(0.0f, 0.0f)
5858
{
@@ -65,6 +65,7 @@ Climbable::~Climbable()
6565
player->stop_climbing(*this);
6666

6767
climbed_by.clear();
68+
trying_to_climb.clear();
6869
}
6970

7071
ObjectSettings
@@ -91,11 +92,40 @@ Climbable::after_editor_set() {
9192
}
9293

9394
void
94-
Climbable::update(float /*dt_sec*/)
95+
Climbable::update(float dt_sec)
9596
{
96-
for (auto* player : climbed_by)
97-
if (!may_climb(*player))
98-
player->stop_climbing(*this);
97+
TriggerBase::update(dt_sec);
98+
auto it = climbed_by.begin();
99+
while (it != climbed_by.end())
100+
{
101+
if (!may_climb(**it))
102+
{
103+
(*it)->stop_climbing(*this);
104+
it = climbed_by.erase(it);
105+
continue;
106+
}
107+
it++;
108+
}
109+
auto it2 = trying_to_climb.begin();
110+
while (it2 != trying_to_climb.end())
111+
{
112+
if (it2->m_activate_try_timer->started())
113+
{
114+
// the "-20" to y velocity prevents Tux from walking in place on the ground for horizonal adjustments
115+
if (it2->m_player->get_bbox().get_left() < m_col.m_bbox.get_left() - GRACE_DX) it2->m_player->add_velocity(Vector(POSITION_FIX_AX,-20));
116+
if (it2->m_player->get_bbox().get_right() > m_col.m_bbox.get_right() + GRACE_DX) it2->m_player->add_velocity(Vector(-POSITION_FIX_AX,-20));
117+
if (it2->m_player->get_bbox().get_top() < m_col.m_bbox.get_top() - GRACE_DY) it2->m_player->add_velocity(Vector(0,POSITION_FIX_AY));
118+
if (it2->m_player->get_bbox().get_bottom() > m_col.m_bbox.get_bottom() + GRACE_DY) it2->m_player->add_velocity(Vector(0,-POSITION_FIX_AY));
119+
}
120+
if (may_climb(*(it2->m_player)))
121+
{
122+
climbed_by.push_back(it2->m_player);
123+
it2->m_player->start_climbing(*this);
124+
it2 = trying_to_climb.erase(it2);
125+
continue;
126+
}
127+
it2++;
128+
}
99129
}
100130

101131
void
@@ -118,20 +148,19 @@ Climbable::draw(DrawingContext& context)
118148
void
119149
Climbable::event(Player& player, EventType type)
120150
{
121-
if ((type == EVENT_ACTIVATE) || (activate_try_timer.started())) {
151+
if (type == EVENT_ACTIVATE) {
122152
if (player.get_grabbed_object() == nullptr){
123-
if (may_climb(player)) {
124-
climbed_by.push_back(&player);
125-
player.start_climbing(*this);
126-
activate_try_timer.stop();
127-
} else {
128-
if (type == EVENT_ACTIVATE) activate_try_timer.start(ACTIVATE_TRY_FOR);
129-
// the "-13" to y velocity prevents Tux from walking in place on the ground for horizonal adjustments
130-
if (player.get_bbox().get_left() < m_col.m_bbox.get_left() - GRACE_DX) player.add_velocity(Vector(POSITION_FIX_AX,-13));
131-
if (player.get_bbox().get_right() > m_col.m_bbox.get_right() + GRACE_DX) player.add_velocity(Vector(-POSITION_FIX_AX,-13));
132-
if (player.get_bbox().get_top() < m_col.m_bbox.get_top() - GRACE_DY) player.add_velocity(Vector(0,POSITION_FIX_AY));
133-
if (player.get_bbox().get_bottom() > m_col.m_bbox.get_bottom() + GRACE_DY) player.add_velocity(Vector(0,-POSITION_FIX_AY));
153+
auto it = std::find_if(trying_to_climb.begin(), trying_to_climb.end(),
154+
[&player](ClimbPlayer& element)
155+
{
156+
return element.m_player == &player;
157+
});
158+
if (it == trying_to_climb.end()) {
159+
trying_to_climb.push_back(ClimbPlayer{&player, std::make_unique<Timer>()});
160+
it = trying_to_climb.begin() + (trying_to_climb.size() - 1);
134161
}
162+
if (!may_climb(player))
163+
it->m_activate_try_timer->start(ACTIVATE_TRY_FOR);
135164
}
136165
}
137166

@@ -145,6 +174,14 @@ Climbable::event(Player& player, EventType type)
145174
else
146175
it++;
147176
}
177+
auto it2 = trying_to_climb.begin();
178+
while (it2 != trying_to_climb.end())
179+
{
180+
if (it2->m_player == &player)
181+
it2 = trying_to_climb.erase(it2);
182+
else
183+
it2++;
184+
}
148185
}
149186
}
150187

src/trigger/climbable.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,16 @@ class ReaderMapping;
3030

3131
class Climbable final : public TriggerBase
3232
{
33+
private:
34+
struct ClimbPlayer
35+
{
36+
Player* m_player;
37+
std::unique_ptr<Timer> m_activate_try_timer;
38+
};
39+
40+
private:
3341
static Color text_color;
42+
3443
public:
3544
Climbable(const ReaderMapping& reader);
3645
Climbable(const Rectf& area);
@@ -51,8 +60,8 @@ class Climbable final : public TriggerBase
5160
bool may_climb(Player& player) const;
5261

5362
protected:
54-
std::vector<Player*> climbed_by; /**< set to player who's currently climbing us, null if nobody is */
55-
Timer activate_try_timer; /**< try to correct mis-alignment while this timer runs */
63+
std::vector<Player*> climbed_by; /** contains players who's currently climbing us, empty if nobody is. */
64+
std::vector<ClimbPlayer> trying_to_climb; /** Contains players that are trying to climb */
5665
std::string message;
5766

5867
private:

src/trigger/trigger_base.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ TriggerBase::~TriggerBase()
4848
void
4949
TriggerBase::update(float )
5050
{
51-
for (auto it = m_losetouch_listeners.end(); it != m_losetouch_listeners.end(); it++)
51+
for (unsigned i = 0; i < m_losetouch_listeners.size(); i++)
5252
{
53-
if (std::find(m_hit.begin(), m_hit.end(), *it) == m_hit.end())
53+
if (std::find(m_hit.begin(), m_hit.end(), m_losetouch_listeners[i]) == m_hit.end())
5454
{
55-
event(**it, EVENT_LOSETOUCH);
56-
(*it)->del_remove_listener(this);
57-
it = m_losetouch_listeners.erase(it);
55+
event(*m_losetouch_listeners[i], EVENT_LOSETOUCH);
56+
m_losetouch_listeners[i]->del_remove_listener(this);
57+
m_losetouch_listeners.erase(m_losetouch_listeners.begin() + i);
58+
i--;
5859
}
5960
}
6061

0 commit comments

Comments
 (0)