Pie Noon
An open source project by FPL.
 All Classes Pages
character.h
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef PIE_NOON_CHARACTER_H_
16 #define PIE_NOON_CHARACTER_H_
17 
18 #include "character_state_machine.h"
19 #include "character_state_machine_def_generated.h"
20 #include "config_generated.h"
21 #include "motive/math/angle.h"
22 #include "motive/motivator.h"
23 #include "motive/util.h"
24 #include "pie_noon_common_generated.h"
25 #include "player_controller.h"
26 #include "timeline_generated.h"
27 
28 namespace motive {
29 class MotiveEngine;
30 } // motive
31 
32 namespace fpl {
33 namespace pie_noon {
34 
35 class Controller;
36 
37 typedef int CharacterHealth;
38 
39 // The different kinds of statistics we're gathering for each player:
40 enum PlayerStats {
41  kWins = 0, // Last man standing in round.
42  kLosses, // Died during round.
43  kDraws, // Simultanuous kill.
44  kAttacks, // Pies launched.
45  kHits, // Pies launched that hit without being blocked.
46  kBlocks, // Pies from others that were blocked.
47  kMisses, // Pies launched that were blocked.
48  kMaxStats
49 };
50 
51 enum VictoryState { kResultUnknown, kVictorious, kFailure };
52 
53 // The current state of the character. This class tracks information external
54 // to the state machine, like health.
55 class Character {
56  public:
57  // The Character does not take ownership of the controller or
58  // character_state_machine_def pointers.
59  Character(CharacterId id, Controller* controller, const Config& config,
60  const CharacterStateMachineDef* character_state_machine_def);
61 
62  // Resets the character to the start-of-game state.
63  void Reset(CharacterId target, CharacterHealth health,
64  motive::Angle face_angle, const mathfu::vec3& position,
65  motive::MotiveEngine* engine);
66 
67  // Fake a reaction to input by making the character's face angle
68  // jitter slightly in the requested direction. Does not change the
69  // target face angle.
70  void TwitchFaceAngle(motive::TwitchDirection twitch);
71 
72  // Force the character's target, not worrying about facing angle.
73  void force_target(CharacterId target) { target_ = target; }
74 
75  // Gets the character's current face angle.
76  motive::Angle FaceAngle() const { return motive::Angle(face_angle_.Value()); }
77 
78  // Sets the character's target and our target face angle.
79  void SetTarget(CharacterId target, motive::Angle angle_to_target);
80 
81  // Calculate the renderable id for the character at 'anim_time'.
82  uint16_t RenderableId(WorldTime anim_time) const;
83 
84  // Return the render variant. For characters: 0 for AI, 1 for player
85  // controlled.
86  uint16_t Variant() const;
87 
88  // On-screen color. Used in shader when rendering.
89  mathfu::vec4 Color() const;
90 
91  // Color to tint a button corresponding to this character.
92  mathfu::vec4 ButtonColor() const;
93 
94  // Returns the timeline of the current state.
95  const Timeline* CurrentTimeline() const {
96  return state_machine_.current_state()->timeline();
97  }
98 
99  // Returns the current state from the character-state-machine.
100  uint16_t State() const {
101  return static_cast<uint16_t>(state_machine_.current_state()->id());
102  }
103 
104  uint16_t state_last_update() const { return state_last_update_; }
105 
106  // Saves off whatever our current state is. Should be called once per frame,
107  // just before (potentially) modifying the state.
108  void UpdatePreviousState() { state_last_update_ = State(); }
109 
110  // Returns true if the character is still in the game.
111  bool Active() const { return State() != StateId_KO; }
112 
113  // Play a sound associated with this character.
114  void PlaySound(const char* sound) const;
115 
116  CharacterHealth health() const { return health_; }
117  void set_health(CharacterHealth health) { health_ = health; }
118 
119  CharacterId id() const { return id_; }
120 
121  CharacterId target() const { return target_; }
122 
123  CharacterHealth pie_damage() const { return pie_damage_; }
124  void set_pie_damage(CharacterHealth pie_damage) { pie_damage_ = pie_damage; }
125 
126  mathfu::vec3 position() const { return position_; }
127  void set_position(const mathfu::vec3& position) { position_ = position; }
128 
129  const Controller* controller() const { return controller_; }
130  Controller* controller() { return controller_; }
131  void set_controller(Controller* controller) { controller_ = controller; }
132 
133  const CharacterStateMachine* state_machine() const { return &state_machine_; }
134 
135  CharacterStateMachine* state_machine() { return &state_machine_; }
136 
137  void IncrementStat(PlayerStats stat);
138  uint64_t& GetStat(PlayerStats stat) { return player_stats_[stat]; }
139 
140  void set_score(int score) { score_ = score; }
141  int score() { return score_; }
142 
143  void set_just_joined_game(bool just_joined_game) {
144  just_joined_game_ = just_joined_game;
145  }
146  bool just_joined_game() { return just_joined_game_; }
147 
148  void set_victory_state(VictoryState state) { victory_state_ = state; }
149  VictoryState victory_state() { return victory_state_; }
150 
151  // Resets all stats we've accumulated. Usually called when we have finished
152  // sending them to the server.
153  void ResetStats();
154 
155  bool visible() const { return visible_; }
156  void set_visible(bool visible) { visible_ = visible; }
157 
158  private:
159  // Constant configuration data.
160  const Config* config_;
161 
162  // Our own id.
163  CharacterId id_;
164 
165  // Character that we are currently aiming the pie at.
166  CharacterId target_;
167 
168  // The character's current health. They're out when their health reaches 0.
169  CharacterHealth health_;
170 
171  // Size of the character's pie. Does this much damage on contact.
172  // If unloaded, 0.
173  CharacterHealth pie_damage_;
174 
175  // World angle. Will eventually settle on the angle towards target_.
176  motive::Motivator1f face_angle_;
177 
178  // Position of the character in world space.
179  mathfu::vec3 position_;
180 
181  // The controller used to translate inputs into game actions.
182  Controller* controller_;
183 
184  // Used to track if this character just joined the game.
185  bool just_joined_game_;
186 
187  // The current state of the character.
188  CharacterStateMachine state_machine_;
189 
190  // The stats we're collecting (see PlayerStats enum above).
191  uint64_t player_stats_[kMaxStats];
192 
193  // The score of the current player for this round (separate from stats because
194  // it is not a persisted value.
195  int score_;
196 
197  // If this character is one of the winners or losers of the match.
198  VictoryState victory_state_;
199 
200  // What state the character was in last update.
201  uint16_t state_last_update_;
202 
203  // If the character should be visible.
204  bool visible_;
205 };
206 
207 class AirbornePie {
208  public:
209  AirbornePie(CharacterId original_source, const Character& source,
210  const Character& target, WorldTime start_time,
211  WorldTime flight_time, CharacterHealth original_damage,
212  CharacterHealth damage, float start_height, float peak_height,
213  int rotations, float y_rotation, motive::MotiveEngine* engine);
214 
215  CharacterId original_source() const { return original_source_; }
216  CharacterId source() const { return source_; }
217  CharacterId target() const { return target_; }
218  WorldTime start_time() const { return start_time_; }
219  WorldTime flight_time() const { return flight_time_; }
220  CharacterHealth original_damage() const { return original_damage_; }
221  CharacterHealth damage() const { return damage_; }
222  const mathfu::mat4& Matrix() const { return motivator_.Value(); }
223  mathfu::vec3 Position() const { return motivator_.Position(); }
224 
225  private:
226  CharacterId original_source_;
227  CharacterId source_;
228  CharacterId target_;
229  WorldTime start_time_;
230  WorldTime flight_time_;
231  CharacterHealth original_damage_;
232  CharacterHealth damage_;
233  motive::MatrixMotivator4f motivator_;
234 };
235 
236 // Return index of first item with time >= t.
237 // T is a flatbuffer::Vector; one of the Timeline members.
238 template <class T>
239 inline int TimelineIndexAfterTime(const T& arr, const int start_index,
240  const WorldTime t) {
241  if (!arr) return 0;
242 
243  for (int i = start_index; i < static_cast<int>(arr->Length()); ++i) {
244  if (arr->Get(i)->time() >= t) return i;
245  }
246  return arr->Length();
247 }
248 
249 // Return index of last item with time <= t.
250 // T is a flatbuffer::Vector; one of the Timeline members.
251 template <class T>
252 inline int TimelineIndexBeforeTime(const T& arr, const WorldTime t) {
253  if (!arr || arr->Length() == 0) return 0;
254 
255  for (int i = 1; i < static_cast<int>(arr->Length()); ++i) {
256  if (arr->Get(i)->time() > t) return i - 1;
257  }
258  return arr->Length() - 1;
259 }
260 
261 // Return array of indices with time <= t < end_time.
262 // T is a flatbuffer::Vector; one of the Timeline members.
263 template <class T>
264 inline std::vector<int> TimelineIndicesWithTime(const T& arr,
265  const WorldTime t) {
266  std::vector<int> ret;
267  if (!arr) return ret;
268 
269  for (int i = 0; i < static_cast<int>(arr->Length()); ++i) {
270  const float end_time = arr->Get(i)->end_time();
271  if (arr->Get(i)->time() <= t && (t < end_time || end_time == 0.0f))
272  ret.push_back(i);
273  }
274  return ret;
275 }
276 
277 void ApplyScoringRule(const ScoringRules* scoring_rules, ScoreEvent event,
278  unsigned int damage, Character* character);
279 
280 } // pie_noon
281 } // fpl
282 
283 #endif // PIE_NOON_CHARACTER_H_
Definition: character.h:55
Definition: character_state_machine.h:44
Definition: controller.h:26
Definition: character.h:207