Peoplemon  0.1.0
Peoplemon 3 game source documentation
WanderBehavior.cpp
Go to the documentation of this file.
2 
3 #include <BLIB/Util/Random.hpp>
4 #include <Core/Properties.hpp>
5 
6 namespace core
7 {
8 namespace component
9 {
10 WanderBehavior::WanderBehavior(unsigned int radius, const sf::Vector2i& origin)
11 : origin(origin)
12 , radius(radius)
13 , state(Walking)
14 , stateTime(0.f)
15 , transitionTime(0.f) {
16  switchState();
17 }
18 
19 void WanderBehavior::update(bl::tmap::Position& position, Controllable& controller, float dt) {
20  stateTime += dt;
21  if (stateTime >= transitionTime && state != Paused) { switchState(); }
22 
23  switch (state) {
24  case Walking: {
25  const auto changeDirection = [this, &position]() {
26  if (bl::util::Random::chance(1, 2)) {
27  const int dx = position.getWorldPosition(Properties::PixelsPerTile()).x - origin.x;
28  const float xf = dx + radius;
29  const float p = 1.f - xf / static_cast<float>(2 * radius);
30  if (bl::util::Random::get<float>(0.f, 1.f) < p) {
31  data.walking.dir = bl::tmap::Direction::Right;
32  }
33  else { data.walking.dir = bl::tmap::Direction::Left; }
34  }
35  else {
36  const int dy = position.getWorldPosition(Properties::PixelsPerTile()).y - origin.y;
37  const float yf = dy + radius;
38  const float p = 1.f - yf / static_cast<float>(2 * radius);
39  if (bl::util::Random::get<float>(0.f, 1.f) < p) {
40  data.walking.dir = bl::tmap::Direction::Down;
41  }
42  else { data.walking.dir = bl::tmap::Direction::Up; }
43  }
44 
45  state = Paused;
46  transitionTime -= stateTime;
47  stateTime = 0.f;
48  };
49 
50  if (controller.processControl(input::fromDirection(data.walking.dir))) {
51  data.walking.steps += 1;
52  if (data.walking.steps >= data.walking.total) changeDirection();
53  }
54  else if (!position.moving(Properties::PixelsPerTile())) { changeDirection(); }
55  } break;
56  case Standing:
57  data.standing.update(position, controller);
58  break;
59  case Spinning:
60  data.spinning.update(position, controller, dt);
61  break;
62  case Paused:
63  if (stateTime >= bl::util::Random::get<float>(1.f, 5.f)) {
64  data.walking.total = bl::util::Random::get<unsigned short int>(1, 3);
65  if (position.direction != data.walking.dir)
66  controller.processControl(input::fromDirection(data.walking.dir));
67  state = Walking;
68  }
69 
70  default:
71  break;
72  }
73 }
74 
75 void WanderBehavior::switchState() {
76  switch (state) {
77  case Walking:
78  data.walking.~WalkData();
79  break;
80  case Standing:
81  data.standing.~StandingBehavior();
82  break;
83  case Spinning:
84  data.spinning.~SpinBehavior();
85  break;
86  default:
87  break;
88  }
89 
90  state = static_cast<State>(bl::util::Random::get<int>(0, NUM_STATES));
91  stateTime = 0.f;
92 
93  switch (state) {
94  case Walking:
95  new (&data.walking) WalkData();
96  data.walking.dir =
97  static_cast<bl::tmap::Direction>(bl::util::Random::get<unsigned int>(0, 3));
98  transitionTime = bl::util::Random::get<float>(5.f, 13.f);
99  break;
100  case Standing:
101  new (&data.standing) StandingBehavior(
102  static_cast<bl::tmap::Direction>(bl::util::Random::get<unsigned int>(0, 3)));
103  transitionTime = bl::util::Random::get<float>(1.f, 3.f);
104  break;
105  case Spinning:
106  new (&data.spinning) SpinBehavior(static_cast<file::Behavior::Spinning::Direction>(
107  bl::util::Random::get<unsigned int>(0, 2)));
108  transitionTime = bl::util::Random::get<float>(1.5f, 3.f);
109  break;
110  default:
111  break;
112  }
113 }
114 
115 WanderBehavior::WalkData::WalkData()
116 : dir(bl::tmap::Direction::Down)
117 , total(3)
118 , steps(0) {}
119 
120 WanderBehavior::Data::Data()
121 : walking() {}
122 
123 } // namespace component
124 } // namespace core
Core classes and functionality for both the editor and game.
EntityControl fromDirection(bl::tmap::Direction direction)
Helper method to convert a move direction to a control.
Definition: Control.cpp:36
Adding this component to an entity allows it to be controlled.
bool processControl(input::EntityControl command, bool sprint=false, bool overrideLock=false)
Processes the given command and manipulates the entity accordingly.
WanderBehavior(unsigned int radius, const sf::Vector2i &origin)
Construct a new Wander Behavior component.
void update(bl::tmap::Position &position, Controllable &controller, float dt)
Updates the entity and wanders around.
Direction
The direction to spin.
Definition: Behavior.hpp:51
static int PixelsPerTile()
Definition: Properties.cpp:279