texture_type img_laptop_right[3];
texture_type img_money_left[2];
texture_type img_money_right[2];
+texture_type img_mrbomb_left[4];
+texture_type img_mrbomb_right[4];
+texture_type img_stalactite;
+texture_type img_stalactite_broken;
-bitmask *bm_bsod;
-
-void badguy_create_bitmasks()
+BadGuyKind badguykind_from_string(const std::string& str)
{
- /*bm_bsod = img_bsod_left[0];*/
+ if (str == "money")
+ return BAD_MONEY;
+ else if (str == "laptop")
+ return BAD_LAPTOP;
+ else if (str == "bsod")
+ return BAD_BSOD;
+ else if (str == "mrbomb")
+ return BAD_MRBOMB;
+ else if (str == "stalactite")
+ return BAD_STALACTITE;
+ else
+ {
+ printf("Couldn't convert badguy: %s\n", str.c_str());
+ return BAD_BSOD;
+ }
}
-void badguy_init(bad_guy_type* pbad, float x, float y, int kind)
+std::string badguykind_to_string(BadGuyKind kind)
{
- pbad->base.width = 32;
- pbad->base.height = 32;
- pbad->mode = NORMAL;
- pbad->dying = DYING_NOT;
- pbad->kind = kind;
- pbad->base.x = x;
- pbad->base.y = y;
- pbad->base.xm = 1.3;
- pbad->base.ym = 4.8;
- pbad->old_base = pbad->base;
- pbad->dir = LEFT;
- pbad->seen = false;
- timer_init(&pbad->timer, true);
- physic_init(&pbad->physic);
+ switch(kind)
+ {
+ case BAD_MONEY:
+ return "money";
+ break;
+ case BAD_LAPTOP:
+ return "laptop";
+ break;
+ case BAD_BSOD:
+ return "bsod";
+ break;
+ case BAD_MRBOMB:
+ return "mrbomb";
+ break;
+ case BAD_STALACTITE:
+ return "stalactite";
+ break;
+ default:
+ return "bsod";
+ }
}
-void badguy_action(bad_guy_type* pbad)
+void
+BadGuy::init(float x, float y, BadGuyKind kind_)
{
+ base.width = 32;
+ base.height = 32;
+ mode = NORMAL;
+ dying = DYING_NOT;
+ kind = kind_;
+ base.x = x;
+ base.y = y;
+ base.xm = -1.3;
+ base.ym = 4.8;
+ old_base = base;
+ dir = LEFT;
+ seen = false;
+ timer_init(&timer, true);
+ physic_init(&physic);
+
+ if(kind == BAD_BOMB) {
+ timer_start(&timer, 1000);
+ mode = BOMB_TICKING;
+ // hack so that the bomb doesn't hurt until it expldes...
+ dying = DYING_SQUISHED;
+ }
+}
- if (pbad->seen)
- {
- if (pbad->kind == BAD_BSOD)
- {
- /* --- BLUE SCREEN OF DEATH MONSTER: --- */
-
- /* Move left/right: */
- if (pbad->dying == DYING_NOT ||
- pbad->dying == DYING_FALLING)
- {
- if (pbad->dir == RIGHT)
- pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
- else if (pbad->dir == LEFT)
- pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
- }
-
+void BadGuy::action_bsod()
+{
+ /* --- BLUE SCREEN OF DEATH MONSTER: --- */
- /* Move vertically: */
+ /* Move left/right: */
+ if (dying == DYING_NOT ||
+ dying == DYING_FALLING)
+ {
+ base.x += base.xm * frame_ratio;
+ }
- pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
+ /* Move vertically: */
+ base.y = base.y + base.ym * frame_ratio;
- if (pbad->dying != DYING_FALLING)
- collision_swept_object_map(&pbad->old_base,&pbad->base);
- if (pbad->base.y > screen->h)
- bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
+ if (dying != DYING_FALLING)
+ collision_swept_object_map(&old_base,&base);
- /* Bump into things horizontally: */
-
- if (!pbad->dying)
- {
- if (issolid( pbad->base.x, (int) pbad->base.y + 16))
- {
- pbad->dir = RIGHT;
- }
- else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
- {
- pbad->dir = LEFT;
- }
- }
-
- /* Fall if we get off the ground: */
-
- if (pbad->dying != DYING_FALLING)
- {
- if (!issolid(pbad->base.x+16, pbad->base.y + 32))
- {
- if(!physic_is_set(&pbad->physic))
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,2.);
- }
-
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
- else
- {
- /* Land: */
-
- if (pbad->base.ym > 0)
- {
- pbad->base.y = (int)(pbad->base.y / 32) * 32;
- pbad->base.ym = 0;
- }
- physic_init(&pbad->physic);
- }
- }
- else
- {
- if(!physic_is_set(&pbad->physic))
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,2.);
- }
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
-
- if (pbad->base.y > screen->h)
- bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
- }
- else if (pbad->kind == BAD_LAPTOP)
- {
- /* --- LAPTOP MONSTER: --- */
-
- /* Move left/right: */
-
- if (pbad->mode == NORMAL || pbad->mode == KICK)
- {
- if (pbad->dying == DYING_NOT ||
- pbad->dying == DYING_FALLING)
- {
- if (pbad->dir == RIGHT)
- pbad->base.x = pbad->base.x + pbad->base.xm * frame_ratio;
- else if (pbad->dir == LEFT)
- pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
- }
- }
- else if (pbad->mode == HELD)
- { /* FIXME: The pbad object shouldn't know about pplayer objects. */
- /* If we're holding the laptop */
- pbad->dir=tux.dir;
- if(pbad->dir==RIGHT)
- {
- pbad->base.x = tux.base.x + 16;
- pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
- }
- else /* facing left */
- {
- pbad->base.x = tux.base.x - 16;
- pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
- }
- if(collision_object_map(&pbad->base))
- {
- pbad->base.x = tux.base.x;
- pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
- }
-
- if(tux.input.fire != DOWN) /* SHOOT! */
- {
- if(pbad->dir == LEFT)
- pbad->base.x -= 24;
- else
- pbad->base.x += 24;
-
- pbad->mode=KICK;
- pbad->base.xm = 8;
- pbad->base.ym = 8;
- play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
- }
- }
-
-
- /* Move vertically: */
-
- if(pbad->mode != HELD)
- pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
-
- if (pbad->dying != DYING_FALLING)
- collision_swept_object_map(&pbad->old_base,&pbad->base);
- if (pbad->base.y > screen->h)
- bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
- /* Bump into things horizontally: */
-
- /* Bump into things horizontally: */
-
- if (!pbad->dying)
- {
- int changed = pbad->dir;
- if (issolid( pbad->base.x, (int) pbad->base.y + 16))
- {
- pbad->dir = RIGHT;
- }
- else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
- {
- pbad->dir = LEFT;
- }
- if(pbad->mode == KICK && changed != pbad->dir)
- {
- /* handle stereo sound */
- /* FIXME: In theory a badguy object doesn't know anything about player objects */
- if (tux.base.x > pbad->base.x)
- play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
- else if (tux.base.x < pbad->base.x)
- play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
- else
- play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
- }
-
- }
-
-
- /* Fall if we get off the ground: */
-
- if (pbad->dying != DYING_FALLING)
- {
- if (!issolid(pbad->base.x+16, pbad->base.y + 32))
- {
- if(!physic_is_set(&pbad->physic))
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,0.);
- }
-
- if(pbad->mode != HELD)
- {
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
- }
- else
- {
- /* Land: */
-
- if (pbad->base.ym > 0)
- {
- pbad->base.y = (int)(pbad->base.y / 32) * 32;
- pbad->base.ym = 0;
- }
- physic_init(&pbad->physic);
- }
- }
- else
- {
- if(!physic_is_set(&pbad->physic))
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,0.);
- }
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
+ if (!dying)
+ check_horizontal_bump();
+ fall(true);
- }
- else if (pbad->kind == BAD_MONEY)
- {
- /* --- MONEY BAGS: --- */
-
-
- /* Move vertically: */
-
- pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
-
- if (pbad->dying != DYING_FALLING)
- collision_swept_object_map(&pbad->old_base,&pbad->base);
-
- if (pbad->base.y > screen->h)
- bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
-
- if(physic_get_state(&pbad->physic) == -1)
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,0.);
- }
-
- if (pbad->dying != DYING_FALLING)
- {
- if(issolid(pbad->base.x, pbad->base.y + 32))
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,6.);
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
- else if(issolid(pbad->base.x, pbad->base.y))
- { /* This works, but isn't the best solution imagineable */
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,0.);
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- ++pbad->base.y;
- }
- else
- {
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
- }
- else
- {
- if(!physic_is_set(&pbad->physic))
- {
- physic_set_state(&pbad->physic,PH_VT);
- physic_set_start_vy(&pbad->physic,0.);
- }
- pbad->base.ym = physic_get_velocity(&pbad->physic);
- }
- }
- else if (pbad->kind == -1)
- {}
+ // Handle dying timer:
+ if (dying == DYING_SQUISHED)
+ {
+ /* Remove it if time's up: */
+ if(!timer_check(&timer)) {
+ remove_me();
+ return;
+ }
+ }
+}
+void BadGuy::action_laptop()
+{
+ /* Move left/right: */
+ if (mode == NORMAL || mode == KICK)
+ {
+ if (dying == DYING_NOT ||
+ dying == DYING_FALLING)
+ {
+ base.x += base.xm * frame_ratio;
+ }
+ }
+ else if (mode == HELD)
+ { /* FIXME: The pbad object shouldn't know about pplayer objects. */
+ /* If we're holding the laptop */
+ dir=tux.dir;
+ if(dir==RIGHT)
+ {
+ base.x = tux.base.x + 16;
+ base.y = tux.base.y + tux.base.height/1.5 - base.height;
+ }
+ else /* facing left */
+ {
+ base.x = tux.base.x - 16;
+ base.y = tux.base.y + tux.base.height/1.5 - base.height;
+ }
+ if(collision_object_map(&base))
+ {
+ base.x = tux.base.x;
+ base.y = tux.base.y + tux.base.height/1.5 - base.height;
}
- else if (pbad->kind == -1)
- {}
- /* Handle mode timer: */
+ if(tux.input.fire != DOWN) /* SHOOT! */
+ {
+ if(dir == LEFT)
+ base.x -= 24;
+ else
+ base.x += 24;
- if (pbad->mode == FLAT && pbad->mode != HELD)
- {
- if(!timer_check(&pbad->timer))
- {
- pbad->mode = NORMAL;
- pbad->base.xm = 4;
+ mode=KICK;
+ base.xm = 8;
+ base.ym = 8;
+ play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
}
}
- else if (pbad->mode == KICK)
- {
- timer_check(&pbad->timer);
- }
- /* Handle dying timer: */
+ /* Move vertically: */
+ if(mode != HELD)
+ base.y = base.y + base.ym * frame_ratio;
+
+ if (dying != DYING_FALLING)
+ collision_swept_object_map(&old_base,&base);
+ /* Bump into things horizontally: */
- if (pbad->dying == DYING_SQUISHED)
+ if (!dying)
{
- /* Remove it if time's up: */
- if(!timer_check(&pbad->timer))
- bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
+ int changed = dir;
+ check_horizontal_bump();
+ if(mode == KICK && changed != dir)
+ {
+ /* handle stereo sound (number 10 should be tweaked...)*/
+ if (base.x < scroll_x - 10)
+ play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
+ else if (base.x > scroll_x + 10)
+ play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
+ else
+ play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
+ }
}
+ fall();
- /* Remove if it's far off the screen: */
-
- if (pbad->base.x < scroll_x - OFFSCREEN_DISTANCE)
- bad_guys.erase(static_cast<std::vector<bad_guy_type>::iterator>(pbad));
- else /* !seen */
+ /* Handle mode timer: */
+ if (mode == FLAT && mode != HELD)
{
- /* Once it's on screen, it's activated! */
-
- if (pbad->base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
- pbad->seen = true;
+ if(!timer_check(&timer))
+ {
+ mode = NORMAL;
+ base.xm = 4;
+ }
+ }
+ else if (mode == KICK)
+ {
+ timer_check(&timer);
}
- /*}*/
}
-void badguy_draw_bsod(bad_guy_type* pbad)
+void BadGuy::check_horizontal_bump(bool checkcliff)
{
- /* --- BLUE SCREEN OF DEATH MONSTER: --- */
- if (pbad->dying == DYING_NOT)
+ if (dir == LEFT && issolid( base.x, (int) base.y + 16))
{
- /* Alive: */
-
- if (pbad->dir == LEFT)
- {
- texture_draw(&img_bsod_left[(frame / 5) % 4],
- pbad->base.x - scroll_x,
- pbad->base.y);
- }
- else
- {
- texture_draw(&img_bsod_right[(frame / 5) % 4],
- pbad->base.x - scroll_x,
- pbad->base.y);
- }
+ dir = RIGHT;
+ base.xm = -base.xm;
+ return;
}
- else if (pbad->dying == DYING_FALLING)
+ if (dir == RIGHT && issolid( base.x + base.width, (int) base.y + 16))
{
- /* Falling: */
+ dir = LEFT;
+ base.xm = -base.xm;
+ return;
+ }
- if (pbad->dir == LEFT)
- {
- texture_draw(&img_bsod_falling_left,
- pbad->base.x - scroll_x,
- pbad->base.y);
- }
- else
- {
- texture_draw(&img_bsod_falling_right,
- pbad->base.x - scroll_x,
- pbad->base.y);
- }
+ // don't check for cliffs when we're falling
+ if(!checkcliff)
+ return;
+
+ if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + 16))
+ {
+ printf("Cliffcol left\n");
+ dir = RIGHT;
+ base.xm = -base.xm;
+ return;
}
- else if (pbad->dying == DYING_SQUISHED)
+ if(dir == RIGHT && !issolid(base.x + base.width,
+ (int) base.y + base.height + 16))
{
- /* Dying - Squished: */
-
- if (pbad->dir == LEFT)
- {
- texture_draw(&img_bsod_squished_left,
- pbad->base.x - scroll_x,
- pbad->base.y + 24);
- }
- else
- {
- texture_draw(&img_bsod_squished_right,
- pbad->base.x - scroll_x,
- pbad->base.y + 24);
- }
+ printf("Cliffcol right\n");
+ dir = LEFT;
+ base.xm = -base.xm;
+ return;
}
}
-void badguy_draw_laptop(bad_guy_type* pbad)
+void BadGuy::fall(bool dojump)
{
- /* --- LAPTOP MONSTER: --- */
- if (pbad->dying == DYING_NOT)
+ /* Fall if we get off the ground: */
+ if (dying != DYING_FALLING)
{
- /* Alive: */
-
- if (pbad->mode == NORMAL)
+ if (!issolid(base.x+16, base.y + 32))
{
- /* Not flat: */
-
- if (pbad->dir == LEFT)
+ if(!physic_is_set(&physic))
{
- texture_draw(&img_laptop_left[(frame / 5) % 3],
- pbad->base.x - scroll_x,
- pbad->base.y);
+ physic_set_state(&physic,PH_VT);
+ physic_set_start_vy(&physic, dojump ? 2. : 0.);
}
- else
+
+ if(mode != HELD)
{
- texture_draw(&img_laptop_right[(frame / 5) % 3],
- pbad->base.x - scroll_x,
- pbad->base.y);
+ base.ym = physic_get_velocity(&physic);
}
}
else
{
- /* Flat: */
+ /* Land: */
- if (pbad->dir == LEFT)
- {
- texture_draw(&img_laptop_flat_left,
- pbad->base.x - scroll_x,
- pbad->base.y);
- }
- else
+ if (base.ym > 0)
{
- texture_draw(&img_laptop_flat_right,
- pbad->base.x - scroll_x,
- pbad->base.y);
+ base.y = (int)(base.y / 32) * 32;
+ base.ym = 0;
}
+ physic_init(&physic);
}
}
- else if (pbad->dying == DYING_FALLING)
+ else
{
- /* Falling: */
-
- if (pbad->dir == LEFT)
- {
- texture_draw(&img_laptop_falling_left,
- pbad->base.x - scroll_x,
- pbad->base.y);
- }
- else
- {
- texture_draw(&img_laptop_falling_right,
- pbad->base.x - scroll_x,
- pbad->base.y);
+ if(!physic_is_set(&physic))
+ {
+ physic_set_state(&physic,PH_VT);
+ physic_set_start_vy(&physic,0.);
}
+ base.ym = physic_get_velocity(&physic);
}
+
+ // BadGuy fall below the ground
+ if (base.y > screen->h) {
+ remove_me();
+ return;
+ }
}
-void badguy_draw_money(bad_guy_type* pbad)
+void BadGuy::remove_me()
{
- if (pbad->base.ym != 300 /* > -16*/)
+ std::vector<BadGuy>::iterator i;
+ for(i = bad_guys.begin(); i != bad_guys.end(); ++i) {
+ if( & (*i) == this) {
+ bad_guys.erase(i);
+ return;
+ }
+ }
+}
+
+void BadGuy::action_money()
+{
+ /* Move vertically: */
+ base.y = base.y + base.ym * frame_ratio;
+
+ if (dying != DYING_FALLING)
+ collision_swept_object_map(&old_base,&base);
+
+ if (base.y > screen->h) {
+ remove_me();
+ return;
+ }
+
+ if(physic_get_state(&physic) == -1)
{
- if (pbad->dir == LEFT)
+ physic_set_state(&physic,PH_VT);
+ physic_set_start_vy(&physic,0.);
+ }
+
+ if (dying != DYING_FALLING)
+ {
+
+ if(issolid(base.x, base.y + 32))
{
- texture_draw(&img_money_left[0],
- pbad->base.x - scroll_x,
- pbad->base.y);
+ physic_set_state(&physic,PH_VT);
+ physic_set_start_vy(&physic,6.);
+ base.ym = physic_get_velocity(&physic);
}
+ /* // matze: is this code needed?
+ else if(issolid(base.x, base.y))
+ { // This works, but isn't the best solution imagineable
+ physic_set_state(&physic,PH_VT);
+ physic_set_start_vy(&physic,0.);
+ base.ym = physic_get_velocity(&physic);
+ ++base.y;
+ }*/
else
{
- texture_draw(&img_money_right[0],
- pbad->base.x - scroll_x,
- pbad->base.y);
+ base.ym = physic_get_velocity(&physic);
}
}
else
{
- if (pbad->dir == LEFT)
+ if(!physic_is_set(&physic))
{
- texture_draw(&img_money_left[1],
- pbad->base.x - scroll_x,
- pbad->base.y);
+ physic_set_state(&physic,PH_VT);
+ physic_set_start_vy(&physic,0.);
}
- else
+ base.ym = physic_get_velocity(&physic);
+ }
+}
+
+void BadGuy::action_mrbomb()
+{
+ if(mode == NORMAL) {
+ base.x += base.xm * frame_ratio;
+ }
+
+ /* Move vertically: */
+ base.y += base.ym * frame_ratio;
+
+ if (dying != DYING_FALLING)
+ collision_swept_object_map(&old_base,&base);
+
+ check_horizontal_bump(true);
+ fall();
+}
+
+void BadGuy::action_bomb()
+{
+ // eventually fall down
+ base.y += base.ym * frame_ratio;
+ collision_swept_object_map(&old_base,&base);
+ fall();
+
+ if(!timer_check(&timer)) {
+ if(mode == BOMB_TICKING) {
+ mode = BOMB_EXPLODE;
+ dying = DYING_NOT; // now the bomb hurts
+ timer_start(&timer, 1000);
+ } else if(mode == BOMB_EXPLODE) {
+ remove_me();
+ return;
+ }
+ }
+}
+
+void BadGuy::action_stalactite()
+{
+ if(mode == NORMAL) {
+ if(tux.base.x + 32 > base.x - 40 && tux.base.x < base.x + 32 + 40) {
+ timer_start(&timer, 800);
+ mode = STALACTITE_SHAKING;
+ }
+ } if(mode == STALACTITE_SHAKING) {
+ base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer...
+ if(!timer_check(&timer)) {
+ mode = STALACTITE_FALL;
+ }
+ } else if(mode == STALACTITE_FALL) {
+ base.y += base.ym * frame_ratio;
+ /* Destroy if collides land */
+ if(issolid(base.x+16, base.y+32))
+ {
+ timer_start(&timer, 3000);
+ dying = DYING_SQUISHED;
+ mode = FLAT;
+ }
+ }
+}
+
+void
+BadGuy::action()
+{
+ if (seen)
+ {
+ switch (kind)
{
- texture_draw(&img_money_right[1],
- pbad->base.x - scroll_x,
- pbad->base.y);
+ case BAD_BSOD:
+ action_bsod();
+ break;
+
+ case BAD_LAPTOP:
+ action_laptop();
+ break;
+
+ case BAD_MONEY:
+ action_money();
+ break;
+
+ case BAD_MRBOMB:
+ action_mrbomb();
+ break;
+
+ case BAD_BOMB:
+ action_bomb();
+ break;
+
+ case BAD_STALACTITE:
+ action_stalactite();
+ break;
+
}
}
+
+ // Remove if it's far off the screen:
+ if (base.x < scroll_x - OFFSCREEN_DISTANCE)
+ {
+ remove_me();
+ return;
+ }
+ else /* !seen */
+ {
+ // Once it's on screen, it's activated!
+ if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
+ seen = true;
+ }
+}
+
+void
+BadGuy::draw_bsod()
+{
+ texture_type* texture = 0;
+ float y = base.y;
+ if(dying == DYING_NOT) {
+ size_t frame = (global_frame_counter / 5) % 4;
+ texture = (dir == LEFT) ? &img_bsod_left[frame] : &img_bsod_right[frame];
+ } else if(dying == DYING_FALLING) {
+ texture = (dir == LEFT) ? &img_bsod_falling_left : &img_bsod_falling_right;
+ } else if(dying == DYING_SQUISHED) {
+ texture = (dir == LEFT)
+ ? &img_bsod_squished_left : &img_bsod_squished_right;
+ y += 24;
+ }
+
+ texture_draw(texture, base.x - scroll_x, y);
+}
+
+void
+BadGuy::draw_laptop()
+{
+ texture_type* texture;
+ size_t frame = (global_frame_counter / 5) % 3;
+
+ if(dying == DYING_NOT) {
+ if(mode == NORMAL) {
+ if(dir == LEFT)
+ texture = &img_laptop_left[frame];
+ else
+ texture = &img_laptop_right[frame];
+ } else {
+ texture = (dir == LEFT) ? &img_laptop_flat_left : &img_laptop_flat_right;
+ }
+ } else {
+ texture = (dir == LEFT)
+ ? &img_laptop_falling_left : &img_laptop_falling_right;
+ }
+
+ texture_draw(texture, base.x - scroll_x, base.y);
+}
+
+void
+BadGuy::draw_money()
+{
+ texture_type* texture;
+ size_t frame = (base.ym != 300) ? 0 : 1;
+
+ if(tux.base.x + tux.base.width < base.x) {
+ texture = &img_money_left[frame];
+ } else {
+ texture = &img_money_right[frame];
+ }
+
+ texture_draw(texture, base.x - scroll_x, base.y);
+}
+
+void
+BadGuy::draw_mrbomb()
+{
+ texture_type* texture;
+ size_t frame = (global_frame_counter/5) % 4;
+
+ if(dir == LEFT)
+ texture = &img_mrbomb_left[frame];
+ else
+ texture = &img_mrbomb_right[frame];
+
+ texture_draw(texture, base.x - scroll_x, base.y);
+}
+
+void
+BadGuy::draw_bomb()
+{
+ texture_type* texture;
+
+ // TODO add real bomb graphics
+ if(mode == BOMB_TICKING) {
+ texture = &img_bsod_squished_right;
+ } else {
+ texture = &img_bsod_squished_left;
+ }
+
+ texture_draw(texture, base.x - scroll_x, base.y);
+}
+
+void
+BadGuy::draw_stalactite()
+{
+ texture_type* texture;
+ if(mode != FLAT)
+ texture = &img_stalactite;
+ else
+ texture = &img_stalactite_broken;
+
+ texture_draw(texture, base.x - scroll_x, base.y);
}
-void badguy_draw(bad_guy_type* pbad)
+void
+BadGuy::draw()
{
// Don't try to draw stuff that is outside of the screen
- if (pbad->base.x > scroll_x - 32 &&
- pbad->base.x < scroll_x + screen->w)
+ if (base.x > scroll_x - 32 &&
+ base.x < scroll_x + screen->w)
{
- switch (pbad->kind)
+ switch (kind)
{
case BAD_BSOD:
- badguy_draw_bsod(pbad);
+ draw_bsod();
break;
case BAD_LAPTOP:
- badguy_draw_laptop(pbad);
+ draw_laptop();
break;
case BAD_MONEY:
- badguy_draw_money(pbad);
+ draw_money();
+ break;
+
+ case BAD_MRBOMB:
+ draw_mrbomb();
+ break;
+
+ case BAD_BOMB:
+ draw_bomb();
break;
- default:
- puts("Unknown badguy type");
+ case BAD_STALACTITE:
+ draw_stalactite();
break;
}
}
}
-void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
+void
+BadGuy::bump()
+{
+ if(kind == BAD_BSOD || kind == BAD_LAPTOP || kind == BAD_BOMB) {
+ dying = DYING_FALLING;
+ base.ym = -8;
+ play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
+ }
+}
+
+void
+BadGuy::make_player_jump(Player* player)
+{
+ physic_set_state(&player->vphysic,PH_VT);
+ physic_set_start_vy(&player->vphysic,2.);
+ player->base.y = base.y - player->base.height - 1;
+}
+
+void
+BadGuy::squich(Player* player)
+{
+ if(kind == BAD_MRBOMB) {
+ // mrbomb transforms into a bomb now
+ add_bad_guy(base.x, base.y, BAD_BOMB);
+
+ make_player_jump(player);
+ add_score(base.x - scroll_x, base.y, 50 * score_multiplier);
+ play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
+ score_multiplier++;
+
+ remove_me();
+ return;
+
+ } else if(kind == BAD_BSOD) {
+ dying = DYING_SQUISHED;
+ timer_start(&timer,4000);
+
+ make_player_jump(player);
+
+ add_score(base.x - scroll_x, base.y, 50 * score_multiplier);
+ play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
+ score_multiplier++;
+ return;
+
+ } else if (kind == BAD_LAPTOP) {
+ if (mode == NORMAL || mode == KICK)
+ {
+ /* Flatten! */
+ play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
+ mode = FLAT;
+ base.xm = 4;
+
+ timer_start(&timer, 4000);
+ } else if (mode == FLAT) {
+ /* Kick! */
+ play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
+
+ if (player->base.x < base.x + (base.width/2))
+ dir = RIGHT;
+ else
+ dir = LEFT;
+
+ base.xm = 5;
+ mode = KICK;
+
+ timer_start(&timer,5000);
+ }
+
+ make_player_jump(player);
+
+ add_score(base.x - scroll_x,
+ base.y,
+ 25 * score_multiplier);
+ score_multiplier++;
+ return;
+ }
+}
+
+void
+BadGuy::collision(void *p_c_object, int c_object, CollisionType type)
{
- bad_guy_type* pbad_c = NULL;
- player_type* pplayer_c = NULL;
+ BadGuy* pbad_c = NULL;
+
+ if(type == COLLISION_BUMP) {
+ bump();
+ return;
+ }
+ if(type == COLLISION_SQUICH) {
+ Player* player = static_cast<Player*>(p_c_object);
+ squich(player);
+ return;
+ }
switch (c_object)
{
case CO_BULLET:
- pbad->dying = DYING_FALLING;
- pbad->base.ym = -8;
+ if(kind == BAD_BOMB || kind == BAD_STALACTITE)
+ return;
- /* Gain some points: */
+ dying = DYING_FALLING;
+ base.ym = -8;
- if (pbad->kind == BAD_BSOD)
- add_score(pbad->base.x - scroll_x, pbad->base.y,
+ /* Gain some points: */
+ if (kind == BAD_BSOD)
+ add_score(base.x - scroll_x, base.y,
50 * score_multiplier);
- else if (pbad->kind == BAD_LAPTOP)
- add_score(pbad->base.x - scroll_x, pbad->base.y,
+ else if (kind == BAD_LAPTOP)
+ add_score(base.x - scroll_x, base.y,
25 * score_multiplier);
- else if (pbad->kind == BAD_MONEY)
- add_score(pbad->base.x - scroll_x, pbad->base.y,
+ else if (kind == BAD_MONEY)
+ add_score(base.x - scroll_x, base.y,
50 * score_multiplier);
/* Play death sound: */
break;
case CO_BADGUY:
- pbad_c = (bad_guy_type*) p_c_object;
- if (pbad->mode == NORMAL)
+ pbad_c = (BadGuy*) p_c_object;
+ if (mode == NORMAL)
{
/* do nothing */
}
- else if(pbad->mode == KICK)
+ else if(mode == KICK)
{
/* We're in kick mode, kill the other guy
and yourself(wuahaha) : */
pbad_c->base.ym = -8;
play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
- add_score(pbad->base.x - scroll_x,
- pbad->base.y, 100);
+ add_score(base.x - scroll_x,
+ base.y, 100);
pbad_c->dying = DYING_FALLING;
- pbad->dying = DYING_FALLING;
- pbad->base.ym = -8;
+ dying = DYING_FALLING;
+ base.ym = -8;
add_score(pbad_c->base.x - scroll_x,
pbad_c->base.y, 100);
}
break;
-
- case CO_PLAYER:
- pplayer_c = (player_type*) p_c_object;
- if(pbad->kind != BAD_MONEY)
- {
- if (pbad->kind == BAD_BSOD)
- {
- pbad->dying = DYING_SQUISHED;
- timer_start(&pbad->timer,4000);
- physic_set_state(&pplayer_c->vphysic,PH_VT);
- physic_set_start_vy(&pplayer_c->vphysic,2.);
- pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
-
- add_score(pbad->base.x - scroll_x, pbad->base.y,
- 50 * score_multiplier);
-
- play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
- }
- else if (pbad->kind == BAD_LAPTOP)
- {
-
- if (pbad->mode == NORMAL || pbad->mode == KICK)
- {
- /* Flatten! */
-
- play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
- pbad->mode = FLAT;
- pbad->base.xm = 4;
-
- timer_start(&pbad->timer,10000);
-
- physic_set_state(&pplayer_c->vphysic,PH_VT);
- physic_set_start_vy(&pplayer_c->vphysic,2.);
- pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
- }
- else if (pbad->mode == FLAT)
- {
- /* Kick! */
- play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
-
- if (pplayer_c->base.x < pbad->base.x + (pbad->base.width/2))
- pbad->dir = RIGHT;
- else
- pbad->dir = LEFT;
-
- pbad->base.xm = 5;
- pbad->mode = KICK;
-
- timer_start(&pbad->timer,5000);
- }
-
- physic_set_state(&pplayer_c->vphysic,PH_VT);
- physic_set_start_vy(&pplayer_c->vphysic,2.);
- pplayer_c->base.y = pbad->base.y - pplayer_c->base.height - 1;
-
- add_score(pbad->base.x - scroll_x,
- pbad->base.y,
- 25 * score_multiplier);
-
- /* play_sound(sounds[SND_SQUISH]); */
- }
- score_multiplier++;
- }
- break;
}
-
}
+
+// EOF //