aboutsummaryrefslogtreecommitdiff
path: root/game_overwatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game_overwatch.cpp')
-rw-r--r--game_overwatch.cpp419
1 files changed, 419 insertions, 0 deletions
diff --git a/game_overwatch.cpp b/game_overwatch.cpp
new file mode 100644
index 0000000..32e9ad1
--- /dev/null
+++ b/game_overwatch.cpp
@@ -0,0 +1,419 @@
+#include "stdafx.h"
+
+
+Game_overwatch::Game_overwatch(){
+ //Initialize our population
+ head = NULL;
+ population = 0;
+}
+
+
+void Game_overwatch::move_out(Actor *npc){
+
+ //Moving out means killing a citizen from the citizen linked list.
+
+ citizen *curr, *prev;
+ prev = NULL;
+
+ for(curr=head;curr!=NULL;prev=curr,curr=curr->next){
+ if (curr->val == npc) {
+ if (prev == NULL) {
+ head = curr->next;
+ std::cout << "I have deleted an NPC from the top!\n";
+ } else {
+ prev->next = curr->next;
+ std::cout << "I have deleted an NPC from the middle!\n";
+ }
+
+ delete curr;
+
+ }
+ }
+ population--;
+}
+
+void Game_overwatch::move_in(Actor * npc){
+ //Moving in means adding a citizen to the linkd list.
+
+ citizen *curr;
+ curr = new citizen;
+ curr->val = npc;
+ curr->next = head;
+ head=curr;
+ population++;
+}
+
+int Game_overwatch::get_population(){
+ return population;
+}
+
+void Game_overwatch::draw(SDL_Surface *viewport, Map *mainmap){
+
+ //Generic draw function, iterates over the list and draws
+ //each one of them.
+
+ //NOTE: Further along it may be wise to allow Lua scripts to
+ // override the draw function and just call curr->draw();
+
+ citizen *curr;
+ curr = head;
+ while (curr != NULL){
+ Gfx::drawsurface(curr->val->get_clip_x(),curr->val->get_clip_y(),
+ curr->val->get_w(),curr->val->get_h(),
+ curr->val->get_sprite(),
+ curr->val->get_x()-mainmap->get_sx(),curr->val->get_y()-mainmap->get_sy(),
+ viewport);
+ curr = curr->next;
+ }
+}
+
+void Game_overwatch::act(SDL_Surface *viewport, Map *mainmap, bool keys[323]){
+
+ //Iterates over the list and runs the "act" function from the lua script.
+
+ citizen *curr;
+ curr = head;
+ while (curr != NULL){
+ curr->val->move();
+ handleinput(curr->val, keys);
+
+ //do the lua thing.
+ curr->val->SelectScriptFunction ("act");
+ curr->val->Go ();
+
+ curr = curr->next;
+ }
+}
+
+void Game_overwatch::handleinput(Actor *actor, bool keys[323]){
+
+ //Right now these actions just map keys to variables the scripts can use
+ //In the future it will be wise to abstract the keys to what they do
+ //Also, take into account gamepads.
+ //Preferably, let lua handle this somehow.
+
+ if(keys[SDLK_LEFT]){
+ if(leftkey == 0){
+ leftkey = SDL_GetTicks();
+ }
+ }else{
+ leftkey = 0;
+ }
+
+ if(keys[SDLK_RIGHT]){
+
+ if(rightkey == 0){
+ rightkey = SDL_GetTicks();
+ }
+ }else{
+ rightkey = 0;
+ }
+
+ if(keys[SDLK_z]){
+ if(zkey == 0){
+ zkey = SDL_GetTicks();
+ }
+ }else{
+ zkey = 0;
+ }
+
+ if(keys[SDLK_x]){
+ if(xkey == 0){
+ xkey = SDL_GetTicks();
+ }
+ }else{
+ xkey = 0;
+ }
+
+ if(keys[SDLK_c]){
+ if(ckey == 0){
+ ckey = SDL_GetTicks();
+ }
+ }else{
+ ckey = 0;
+ }
+
+ actor->set_leftkey(leftkey);
+ actor->set_rightkey(rightkey);
+ actor->set_zkey(zkey);
+ actor->set_xkey(xkey);
+ actor->set_ckey(ckey);
+}
+
+void Game_overwatch::animate(){
+ //Iterate and run the animate method.
+
+ citizen *curr;
+ curr = head;
+ while (curr != NULL){
+ curr->val->animate();
+ curr = curr->next;
+ }
+}
+
+void Game_overwatch::check_collisions(Map *mainmap){
+ citizen *curr, *others;
+
+ bool collided = false;
+ curr = head;
+ others = head->next;
+ Actor *ac1, *ac2;
+
+ //now check everyone. Never with itself.
+ //It does line collisions, not corner collisions.
+
+ while (curr != NULL){
+ ac1 = curr->val;
+ while (others != NULL) {
+ ac2 = others->val;
+ collided = false;
+ if (curr->val != others->val) {
+ if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(),
+ ac1->get_y(), ac1->get_h(),
+ ac2->get_x(), ac2->get_w(),
+ ac2->get_y(), ac2->get_h(),
+ UP)){
+
+ ac2->set_collision(true, DOWN);
+ ac2->set_speed(ac1->get_ownspeed());
+ ac2->set_vertical_speed(ac2->get_vertical_speed()+ac1->get_vertical_speed());
+
+ ac1->set_collision(true, UP);
+ collided = true;
+ }
+ if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(),
+ ac1->get_y(), ac1->get_h(),
+ ac2->get_x(), ac2->get_w(),
+ ac2->get_y(), ac2->get_h(),
+ DOWN)){
+
+ ac2->set_collision(true, UP);
+ ac1->set_collision(true, DOWN);
+ collided = true;
+ }
+ if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(),
+ ac1->get_y(), ac1->get_h(),
+ ac2->get_x(), ac2->get_w(),
+ ac2->get_y(), ac2->get_h(),
+ LEFT)){
+
+ ac2->set_collision(true, RIGHT);
+ ac1->set_collision(true, LEFT);
+ collided = true;
+ }
+ if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(),
+ ac1->get_y(), ac1->get_h(),
+ ac2->get_x(), ac2->get_w(),
+ ac2->get_y(), ac2->get_h(),
+ RIGHT)){
+
+ ac2->set_collision(true, LEFT);
+ ac1->set_collision(true, RIGHT);
+ collided = true;
+ }
+ }
+
+ others = others->next;
+ if(collided){
+ collision_callback(ac1, ac2);
+ }
+
+ }
+
+ curr = curr->next;
+ if (curr != NULL){
+ others = curr->next;
+ }
+ }
+}
+
+void Game_overwatch::collision_callback(Actor *ac1, Actor *ac2){
+
+ std::cout << "The collision has called ";
+
+ if (ac1->get_enemy() == WEAPON && !ac2->get_dying()) {
+ if (ac2->get_enemy() == EVIL) {
+ ac1->set_dying(true);
+ ac2->set_dying(true);
+
+
+ std::cout << "And the shot has destroyed the enemy.";
+ }
+ }
+
+ if (ac1->get_enemy() == SUPEREVIL) {
+ ac2->set_dying(true);
+ std::cout << "And the shot has destroyed the enemy.";
+ }
+
+ if (ac1->get_controllable()) {
+ if (ac2->get_enemy() == EVIL) {
+ ac1->set_dying(true);
+
+
+ std::cout << "And the enemy has destroyed the main actor.";
+ }
+ }
+
+ if (ac1->get_enemy() == EVIL) {
+ if (ac2->get_controllable()) {
+ ac2->set_dying(true);
+
+
+ std::cout << "And the enemy has destroyed the main actor.";
+ }
+ }
+
+
+ std::cout << "\n";
+}
+
+
+bool Game_overwatch::line_colliding(int x1, int w1, int y1, int h1, int x2, int w2, int y2, int h2, int direction){
+ switch (direction) {
+ case UP:
+ if (y1 <= y2+h2 && y1 >= y2+(h2/2) &&
+ ((x1 > x2 && x1 < x2+w2) ||
+ (x1+w1 > x2 && x1+w2 < x2+w2))) {
+ std::cout << "Foo' is collidin' top\n";
+ return true;
+ }
+ break;
+ case DOWN:
+ if (y1+h1 >= y2 && y1+h1 <= y2+(h2/2) &&
+ ((x1 > x2 && x1 < x2+w2) ||
+ (x1+w1 > x2 && x1+w2 < x2+w2))) {
+ std::cout << "Foo' is collidin' bottom\n";
+ return true;
+ }
+ break;
+ case LEFT:
+ if (x1 <= x2+w2 && x1 >= x2+(w2/2) &&
+ ((y1 > y2 && y1 < y2+h2) ||
+ (y1+h1 > y2 && y1+h1 < y2+h2))) {
+ std::cout << "Foo' is collidin' left\n";
+ return true;
+ }
+ break;
+ case RIGHT:
+ if (x1+w1 >= x2 && x1+w1 <= x2+(w2/2) &&
+ ((y1 > y2 && y1 < y2+h2) ||
+ (y1+h1 > y2 && y1+h1 < y2+h2))) {
+ std::cout << "Foo' is collidin' right\n";
+ return true;
+ }
+ break;
+ }
+
+ return false;
+}
+
+void Game_overwatch::handlephysics(Map *mainmap, int ticks1, int ticks2){
+ citizen *curr;
+ curr = head;
+ while (curr != NULL){
+
+ //some are not affected by physics.
+ if(curr->val->get_physics()){
+ //can it fall?
+ if(curr->val->can_move(DOWN, curr->val->get_x(), curr->val->get_y())){
+
+ //change sprite to its jump.
+ switch(curr->val->get_oldclip()){
+ case 1:
+ curr->val->set_clip_y(curr->val->get_h()*0);
+ break;
+ case 2:
+ curr->val->set_clip_y(curr->val->get_h()*3);
+ break;
+ }
+
+ //start the fall process
+ if(curr->val->get_falltime() == 0){
+ curr->val->set_falltime(.5);
+ }else{
+ curr->val->set_falltime(curr->val->get_falltime()+(ticks2-ticks1)/1000);
+ }
+
+ }else{
+
+ //stop falling.
+ curr->val->set_clip_y(curr->val->get_h()*curr->val->get_oldclip());
+ curr->val->set_falltime(0);
+ if(curr->val->get_vertical_speed() > 0){
+ curr->val->set_vertical_speed(0);
+ }
+ }
+
+ //check for top collision
+ if( !curr->val->can_move(UP, curr->val->get_x(), curr->val->get_y()) && curr->val->get_vertical_speed() < 0){
+ curr->val->set_vertical_speed(0);
+ }
+
+ //Avoid falling through the ground
+ while(!curr->val->can_move(DOWN, curr->val->get_x(), curr->val->get_y()+curr->val->get_vertical_speed()) && curr->val->get_vertical_speed() > 0){
+ curr->val->set_vertical_speed( curr->val->get_vertical_speed() - 1 );
+ }
+
+ //V=Vo+at
+ curr->val->set_vertical_speed( curr->val->get_vertical_speed() + (GRAVITY*curr->val->get_falltime()));
+
+ //translate.
+ curr->val->set_y( curr->val->get_y() + curr->val->get_vertical_speed());
+ }
+
+ //NEXT
+ curr = curr->next;
+ }
+}
+
+void Game_overwatch::reset_collisions(){
+ citizen *curr;
+ curr = head;
+ while (curr != NULL){
+ curr->val->set_collision(false, LEFT);
+ curr->val->set_collision(false, RIGHT);
+ curr->val->set_collision(false, DOWN);
+ curr->val->set_collision(false, UP);
+ curr = curr->next;
+ }
+}
+
+void Game_overwatch::dieloop(){
+
+ //The kill loop:
+ // Every frame, we find out who needs to be killed
+ // We kill them all.
+
+ citizen *curr;
+ curr = head;
+ while (curr != NULL){
+ bool killthis = false;
+ if ( curr->val->get_dying() ){
+ killthis = true;
+ }
+
+ if (killthis){
+ Actor *victim = curr->val;
+ curr = curr->next;
+ this->kill(victim);
+ }else{
+ curr = curr->next;
+ }
+ }
+}
+
+void Game_overwatch::kill(Actor *actor){
+
+ //This should probably delegate to the lua die function
+ //So it can animate/change states.
+
+ if ( actor->get_controllable() ){
+ actor->set_x(50);
+ actor->set_y(100);
+ actor->set_dying(false);
+ }else{
+ delete actor;
+ actor = NULL;
+ }
+} \ No newline at end of file