Dumb-ways-to-memorize
2D game
entity.c
Go to the documentation of this file.
1 #include "globals.h"
2 #include "entity.h"
3 #include "graphics.h"
4 #include "player_controller.h"
5 #include <stdio.h>
6 #include <math.h>
7 #include "player.h"
8 #include "parselevel.h"
9 #include "parsepowerup.h"
10 
11 entity_t *gEntities = NULL;
12 int gLastEntity = 0;
13 char **Hazards_str = NULL;
14 char *Collisions_str[] = {"static", "ragdoll", "clip", 0};
15 char *EntityStates_str[] = {"alive", "dead", "other", 0};
16 
17 void DrawGeneric(entity_t *self)
18 {
19  if(!self)
20  {
21  return;
22  }
23  if(!self->mSprites)
24  {
25  return;
26  }
27  if(self->mAnimation)
28  {
29  //IncrementFrame(self->mAnimation);
30  DrawSprite(self->mAnimation, &self->mCurrentFrame, &self->mPosition, gRenderer);
31  } else
32  {
33  //IncrementFrame(self->mSprites[ANIMATION_IDLE]);
34  DrawSprite(self->mSprites[ANIMATION_IDLE], &self->mCurrentFrame, &self->mPosition, gRenderer);
35  }
36 
37 }
38 
39 //Unused for now
40 void DrawPlayer(entity_t *self)
41 {
42  //DrawSprite(self->mSprites, &self->mPosition, gRenderer);
43 }
44 
45 void ThinkGeneric(entity_t *self)
46 {
47  if(!self)
48  {
49  return;
50  }
51  if(self->mHealth <= 0)
52  {
53  self->Think = FreeEntity;
54  }
55 
56  self->mNextThink = gCurrentTime + 2*FRAME_DELAY;
57 }
58 
59 void ThinkPlayer(entity_t *self)
60 {
61  //Do input control
62  if(!self) return;
64  {
65  DoPlayerThink(self, gButtonQ);
66  } else if(SDL_GameControllerGetButton(gController, SDL_CONTROLLER_BUTTON_DPAD_LEFT))
67  {
68  DoPlayerThink(self, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
69  } else if(SDL_GameControllerGetButton(gController, SDL_CONTROLLER_BUTTON_DPAD_RIGHT))
70  {
71  DoPlayerThink(self, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
72  } else if(SDL_GameControllerGetButton(gController, SDL_CONTROLLER_BUTTON_B))
73  {
74  if(gCurrentPowerUp)
75  {
76  //If infinite use
77  if(!gCurrentPowerUp->UpdateUse)
78  {
79  self->PowerUp(gCurrentPowerUp);
80  }
81  }
82  }
83  self->mNextThink = gCurrentTime + 1; //Player always thinks
84  if(self->mHealth < 0)
85  {
86  if(gPlayerLives < 0)
87  {
88  printf("You died, Game over. Start a new game");
92  gGameState = START;
93  } else
94  {
95  printf("You died, select your powerups again \n");
96  gPlayerLives--;
97  gGameState = GUESS;
98  }
99  }
100 }
101 
102 void ThinkEnemy(entity_t *self)
103 {
104  if(!self) return;
105  if(!self->mData) return;
106  if(self->mData->mFlags & AI_FLAG_CHECK_OBJECT)
107  {
108  if(!self->mData->mObjectCheck)
109  {
110  self->mData = self->mData->mLink;
111  return;
112  }
113  if( Distance2Entity(self, FindEntity(self->mData->mObjectCheck)) < self->mData->mVariables[AI_VAR_CHECK])
114  {
115  if(GetFunctionAI(self->mData))
116  {
117  GetFunctionAI(self->mData)(self);
118  }
119  }
120  } else if (self->mData->mFlags & AI_FLAG_CHECK_PLAYER)
121  {
122  if(Distance2Entity(self, (entity_t*)gPlayer) < self->mData->mVariables[AI_VAR_CHECK])
123  {
124  if(GetFunctionAI(self->mData))
125  {
126  GetFunctionAI(self->mData)(self);
127  }
128  }
129  } else
130  {
131  if(GetFunctionAI(self->mData))
132  {
133  GetFunctionAI(self->mData)(self);
134  }
135  }
136 
137 }
138 
139 void TouchGeneric(entity_t *self, entity_t *other, int type)
140 {
141  switch(type)
142  {
143  case(COLLISION_TYPE_STATIC):
144  {
145  if(! (other->mHazards & self->mHazards) )
146  {
147  self->mHealth -= HAZARD_DAMAGE;
148  self->mAnimation = ANIMATION_HIT >= CountMem(self->mSprites, sizeof(sprite_t*)) ? NULL : self->mSprites[ANIMATION_HIT];
149  self->mNextThink += HAZARD_STUN_FRAMES*FRAME_DELAY;
150  }
151  break;
152  }
154  {
155  if(! (other->mHazards & self->mHazards) )
156  {
157  self->mHealth -= HAZARD_DAMAGE;
158  other->mHealth -= HAZARD_DAMAGE;
159  self->mAnimation = ANIMATION_HIT >= CountMem(self->mSprites, sizeof(sprite_t*)) ? NULL : self->mSprites[ANIMATION_HIT];
160  }
161  }
162  default:
163  break;
164  }
165 }
166 
167 //Touch Functions
168 void TouchPlayer(entity_t *self, entity_t *other, int type)
169 {
170  switch(type)
171  {
172  case(COLLISION_TYPE_STATIC):
173  {
174  if(! (other->mHazards & self->mHazards) )
175  {
176  self->mHealth -= HAZARD_DAMAGE;
177  self->mAnimation = ANIMATION_HIT >= CountMem(self->mSprites, sizeof(sprite_t*)) ? NULL : self->mSprites[ANIMATION_HIT];
178  self->mNextThink += HAZARD_STUN_FRAMES*FRAME_DELAY;
179  }
180  break;
181  }
183  {
184  if(! (other->mHazards & self->mHazards) )
185  {
186  self->mHealth -= HAZARD_DAMAGE;
187  self->mAnimation = ANIMATION_HIT >= CountMem(self->mSprites, sizeof(sprite_t*)) ? NULL : self->mSprites[ANIMATION_HIT];
188  self->mNextThink += HAZARD_STUN_FRAMES*FRAME_DELAY;
189  }
190  break;
191  }
192 
193  }
194 }
195 
196 void TouchEnemy(entity_t *self, entity_t *other, int type)
197 {
198  switch(other->mCollisionType)
199  {
201  break;
203  break;
204  default:
205  break;
206  }
207 }
208 
209 void TouchGoal(entity_t* self, entity_t* other, int type)
210 {
211  if(other == gPlayer)
212  {
213  gGameState = CountMem(gUsedPowerUps, sizeof(char*)) >= CountMem(gSelectedPowerUps, sizeof(char*)) ? START : CHOOSE;
214  }
215 }
216 
218 {
219  if( (gEntities = (entity_t*) malloc(sizeof(entity_t)*MAX_ENTITIES)) == NULL )
220  {
221  printf("Couldn't alloc EntitySys");
222  return -1;
223  }
224  if( (gEntityDictionary = (entity_t*) malloc(sizeof(entity_t)*MAX_ENTITIES)) == NULL )
225  {
226  printf("Couldn't alloc EntitySys");
227  return -1;
228  }
229  memset(gEntities, 0, sizeof(entity_t)*MAX_ENTITIES);
230  memset(gEntityDictionary, 0, sizeof(entity_t)*MAX_ENTITIES);
231  gLastEntity = 0;
232  return 0;
233 }
234 
235 entity_t *InitNewEntity()
236 {
237  int pos;
238  entity_t *retVal;
239  if(gEntities == NULL)
240  {
241  printf("Entity system unintialiazeed");
242  exit(-1);
243  }
244 
245  retVal = FindFreeEntity(&pos);
246  gLastEntity = pos;
247  return retVal;
248 }
249 
251 {
252  int i;
253  for(i = 0; gEntityDictionary[i].mName; i++)
254  {
255  ;
256  }
258  {
259  return NULL;
260  }
261  return &gEntityDictionary[i];
262 }
263 
265 {
266  int i;
267  if(!gEntities)
268  {
269  return;
270  }
271  for(i = 0; i < MAX_ENTITIES; i++)
272  {
273  if(!gEntities[i].Draw)
274  {
275  continue;
276  }
277  gEntities[i].Draw(&gEntities[i]);
278  }
279 }
280 
282 {
283  int i;
284  if(!gEntities)
285  {
286  return;
287  }
288  for(i = 0; i < MAX_ENTITIES; i++)
289  {
290  if(!gEntities[i].Think || !gEntities[i].mName)
291  {
292  continue;
293  }
294  if( gCurrentTime > gEntities[i].mNextThink)
295  {
296  gEntities[i].Think(&gEntities[i]);
297  }
298  }
299 }
300 
301 entity_t* FindCachedEntity(const char* name)
302 {
303  int i;
304  for(i = 0; i < MAX_ENTITIES; i++)
305  {
306  if(!gEntityDictionary[i].mName)
307  break;
308  if(!strcmp(name, gEntityDictionary[i].mName))
309  {
310  return &gEntityDictionary[i];
311  }
312  }
313  return NULL;
314 }
315 
316 entity_t* FindEntity(const char* name)
317 {
318  int i;
319  for(i = 0; i < MAX_ENTITIES; i++)
320  {
321  if(!gEntities[i].mName)
322  continue;
323  if(!strcmp(name, gEntities[i].mName))
324  {
325  return &gEntities[i];
326  }
327  }
328  return NULL;
329 }
330 
331 entity_t* FindFreeEntity(int* position)
332 {
333  int i;
334  for(i = gLastEntity; i < MAX_ENTITIES; i++)
335  {
336  if(!gEntities[i].mName)
337  {
338  if(position)
339  *position = i;
340  return &gEntities[i];
341  }
342  }
343  for(i = 0; i < gLastEntity; i++)
344  {
345  if(!gEntities[i].mName)
346  {
347  if(position)
348  *position = i;
349  return &gEntities[i];
350  }
351  }
352  return NULL;
353 }
354 
355 entity_t *LookForEntityAtPos(vec2_t position)
356 {
357  int i;
358  for(i = 0; i < MAX_ENTITIES; i++)
359  {
360  if(!gEntities[i].mName)
361  continue;
362  if( (gEntities[i].mPosition.x > position.x > gEntities[i].mPosition.x + gEntities[i].mSprites[0]->mSize.x)
363  && (gEntities[i].mPosition.y > position.y > gEntities[i].mPosition.x + gEntities[i].mSprites[0]->mSize.y))
364  {
365  return &gEntities[i];
366  }
367  }
368  return NULL;
369 }
370 
371 int Distance2Entity(entity_t* self, entity_t* other)
372 {
373  int x, y;
374  x = self->mPosition.x - other->mPosition.x;
375  y = self->mPosition.y - self->mPosition.y;
376  return powf(powf(x, 2) + powf(y, 2), (float) 1/2);
377 }
378 
379 void FreeEntity(entity_t *ent)
380 {
381  int i, isGlobal = 0;
382  if(!ent)
383  return;
384  i = 0;
385  //if(ent->mSprites)
386  //{
387  //while(ent->mSprites[i])
388  //{
389  //FreeSprite(ent->mSprites[i]);
390  //i++;
391  //}
392  //free(ent->mSprites);
393  //}
394  for(i = 0; i < MAX_ENTITIES; i++)
395  {
396  if(ent == &gEntities[i])
397  {
398  isGlobal = 1;
399  memset(ent, 0, sizeof(entity_t));
400  }
401  }
402  if(!isGlobal)
403  {
404  free(ent);
405  }
406 
407 }
408 
410 {
411  int i , entities;
412  if(!gEntities)
413  {
414  return;
415  }
416 
417  for(i = 0; i < MAX_ENTITIES; i++)
418  {
419  if(&gEntities[i] == (entity_t*) gPlayer)
420  {
421  continue;
422  }
423  FreeEntity(&gEntities[i]);
424  }
425 }
426 
428 {
429  int i;
430  if(!gEntities)
431  return;
432  for(i = 0; i < MAX_ENTITIES; i++)
433  {
434  if(!gEntities[i].mName)
435  continue;
436  FreeEntity(&gEntities[i]);
437  }
438  free(gEntities);
439 }
440 
void TouchEnemy(entity_t *self, entity_t *other, int type)
Definition: entity.c:196
int CountMem(void *src, int size_type)
Definition: mymath.c:51
Definition: globals.h:87
entity_t * gEntityDictionary
Definition: game.c:41
int y
Definition: globals.h:22
#define PLAYER_LIVES
Definition: player.h:6
SDL_Renderer * gRenderer
Definition: graphics.c:10
void DrawEntities()
Definition: entity.c:264
unsigned int gCurrentTime
Definition: game.c:50
entity_t * InitNewEntity()
Definition: entity.c:235
void TouchPlayer(entity_t *self, entity_t *other, int type)
Definition: entity.c:168
void TouchGoal(entity_t *self, entity_t *other, int type)
Definition: entity.c:209
void DrawGeneric(entity_t *self)
Definition: entity.c:17
void FreeNonPlayerEntities()
Definition: entity.c:409
entity_t * FindCachedEntity(const char *name)
Definition: entity.c:301
SDL_GameController * gController
Definition: game.c:48
SDL_GameControllerButton gButtonQ
Definition: game.c:49
#define BUTTON_NO_INPUT
entity_t * FindEntity(const char *name)
Definition: entity.c:316
char ** gUsedPowerUps
Definition: game.c:29
#define HAZARD_STUN_FRAMES
Definition: globals.h:101
Definition: globals.h:88
#define MAX_ENTITIES
Definition: entity.h:8
char * EntityStates_str[]
Definition: entity.c:15
GameState gGameState
Definition: game.c:44
int InitEntitySystem()
Definition: entity.c:217
int gPlayerLives
Definition: player.c:10
char ** Hazards_str
Definition: entity.c:13
entity_t * LookForEntityAtPos(vec2_t position)
Definition: entity.c:355
void ThinkGeneric(entity_t *self)
Definition: entity.c:45
int gLastEntity
Definition: entity.c:12
#define HAZARD_DAMAGE
Definition: globals.h:100
entity_t * gEntities
Definition: entity.c:11
void DoPlayerThink(void *player, SDL_GameControllerButton button)
void DrawPlayer(entity_t *self)
Definition: entity.c:40
char ** gSelectedPowerUps
Definition: game.c:28
#define FRAME_DELAY
Definition: globals.h:135
entity_t * FindFreeEntity(int *position)
Definition: entity.c:331
char * Collisions_str[]
Definition: entity.c:14
int x
Definition: globals.h:21
void(*)(entity_t *) GetFunctionAI(ai_function_t *data)
Definition: ai_interpret.c:238
int DrawSprite(sprite_t *sprite, int *frame, vec2_t *position, SDL_Renderer *renderer)
Definition: graphics.c:152
void FreeEntity(entity_t *ent)
Definition: entity.c:379
void TouchGeneric(entity_t *self, entity_t *other, int type)
Definition: entity.c:139
void ThinkEnemy(entity_t *self)
Definition: entity.c:102
Definition: globals.h:86
power_t * gCurrentPowerUp
Definition: parsepowerup.c:16
entity_t * FindNextFreeCachePos()
Definition: entity.c:250
entity_t * gPlayer
Definition: player.c:9
void Draw()
Definition: game.c:547
void RunEntities()
Definition: entity.c:281
void ShutdownEntitySystem()
Definition: entity.c:427
void ThinkPlayer(entity_t *self)
Definition: entity.c:59
Definition: globals.h:19
int Distance2Entity(entity_t *self, entity_t *other)
Definition: entity.c:371