1// SuperTux
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#include "object/bullet.hpp"
18
19#include "math/random.hpp"
20#include "object/camera.hpp"
21#include "sprite/sprite.hpp"
22#include "sprite/sprite_manager.hpp"
23#include "supertux/direction.hpp"
24#include "supertux/sector.hpp"
25#include "video/video_system.hpp"
26#include "video/viewport.hpp"
27
28namespace {
29const float BULLET_XM = 600;
30}
31
32Bullet::Bullet(const Vector& pos, float xm, Direction dir, BonusType type_) :
33 physic(),
34 life_count(3),
35 sprite(),
36 lightsprite(SpriteManager::current()->create("images/objects/lightmap_light/lightmap_light-small.sprite")),
37 type(type_)
38{
39 float speed = dir == Direction::RIGHT ? BULLET_XM : -BULLET_XM;
40 physic.set_velocity_x(speed + xm);
41
42 if (type == FIRE_BONUS) {
43 sprite = SpriteManager::current()->create("images/objects/bullets/firebullet.sprite");
44 lightsprite->set_blend(Blend::ADD);
45 lightsprite->set_color(Color(0.3f, 0.1f, 0.0f));
46 } else if (type == ICE_BONUS) {
47 life_count = 10;
48 sprite = SpriteManager::current()->create("images/objects/bullets/icebullet.sprite");
49 } else {
50 log_warning << "Bullet::Bullet called with unknown BonusType" << std::endl;
51 life_count = 10;
52 sprite = SpriteManager::current()->create("images/objects/bullets/firebullet.sprite");
53 }
54
55 m_col.m_bbox.set_pos(pos);
56 m_col.m_bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
57}
58
59void
60Bullet::update(float dt_sec)
61{
62 // cause fireball color to flicker randomly
63 if (gameRandom.rand(5) != 0) {
64 lightsprite->set_color(Color(0.3f + gameRandom.randf(10) / 100.0f,
65 0.1f + gameRandom.randf(20.0f) / 100.0f,
66 gameRandom.randf(10.0f) / 100.0f));
67 } else
68 lightsprite->set_color(Color(0.3f, 0.1f, 0.0f));
69 // remove bullet when it's offscreen
70 float scroll_x =
71 Sector::get().get_camera().get_translation().x;
72 float scroll_y =
73 Sector::get().get_camera().get_translation().y;
74 if (get_pos().x < scroll_x ||
75 get_pos().x > scroll_x + static_cast<float>(SCREEN_WIDTH) ||
76 // get_pos().y < scroll_y ||
77 get_pos().y > scroll_y + static_cast<float>(SCREEN_HEIGHT) ||
78 life_count <= 0) {
79 remove_me();
80 return;
81 }
82
83 m_col.m_movement = physic.get_movement(dt_sec);
84}
85
86void
87Bullet::draw(DrawingContext& context)
88{
89 sprite->draw(context.color(), get_pos(), LAYER_OBJECTS);
90 if (type == FIRE_BONUS){
91 lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0);
92 }
93}
94
95void
96Bullet::collision_solid(const CollisionHit& hit)
97{
98 if (hit.top || hit.bottom) {
99 physic.set_velocity_y(-physic.get_velocity_y());
100 life_count--;
101 } else if (hit.left || hit.right) {
102 if (type == ICE_BONUS) {
103 physic.set_velocity_x(-physic.get_velocity_x());
104 life_count--;
105 } else
106 remove_me();
107 }
108}
109
110void
111Bullet::ricochet(GameObject& , const CollisionHit& hit)
112{
113 collision_solid(hit);
114}
115
116HitResponse
117Bullet::collision(GameObject& , const CollisionHit& )
118{
119 return FORCE_MOVE;
120}
121
122/* EOF */
123