1
2 /* Battle Tanks Game
3 * Copyright (C) 2006-2009 Battle Tanks team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 /*
21 * Additional rights can be granted beyond the GNU General Public License
22 * on the terms provided in the Exception. If you modify this file,
23 * you may extend this exception to your version of the file,
24 * but you are not obligated to do so. If you do not wish to provide this
25 * exception without modification, you must delete this exception statement
26 * from your version and license this file solely under the GPL without exception.
27 */
28 #include "heli.h"
29 #include "config.h"
30 #include "registrar.h"
31 #include "player_manager.h"
32 #include "player_slot.h"
33
34 class RaiderHeli : public Heli {
35 public:
clone() const36 virtual Object * clone() const { return new RaiderHeli(*this); }
RaiderHeli()37 RaiderHeli() : Heli("helicopter"), _player(-1), _leaving(false), _toggle(true), _moving_time(0) {}
38
39 virtual void on_spawn();
40 void calculate(const float dt);
serialize(mrt::Serializator & s) const41 virtual void serialize(mrt::Serializator &s) const {
42 Heli::serialize(s);
43 s.add(_player);
44 s.add(_leaving);
45 s.add(_toggle);
46 s.add(_moving_time);
47 }
deserialize(const mrt::Serializator & s)48 virtual void deserialize(const mrt::Serializator &s) {
49 Heli::deserialize(s);
50 s.get(_player);
51 s.get(_leaving);
52 s.get(_toggle);
53 s.get(_moving_time);
54 }
55
56 private:
57 int _player;
58 Alarm _leaving, _toggle;
59 float _moving_time;
60 };
61
62
on_spawn()63 void RaiderHeli::on_spawn() {
64 Heli::on_spawn();
65 _player = -1;
66 /*
67 */
68 }
69
70 #include "tmx/map.h"
71
calculate(const float dt)72 void RaiderHeli::calculate(const float dt) {
73 if (_player == -1) {
74 //deferred initialization
75 int players = 0;
76 int i, n = PlayerManager->get_slots_count();
77 for(i = 0; i < n; ++i) {
78 const PlayerSlot &slot = PlayerManager->get_slot(i);
79 if (slot.empty())
80 continue;
81 ++players;
82 }
83
84 if (players == 0) {
85 LOG_DEBUG(("no players... "));
86 emit("death", NULL);
87 return;
88 }
89 LOG_DEBUG(("setting up %d players", players));
90 float attack = 20.0f;
91 //Config->get("objects." + registered_name + ".attack-duration", attack, 30.0f);
92 _toggle.set(attack);
93 _leaving.set(attack * players * 2);
94 _player = 0;
95 }
96
97 if (!_variants.has("no-escape") && _leaving.tick(dt)) {
98 v2<int> pos, map_size = Map->get_size();
99 get_position(pos);
100 pos += (size * 0.9).convert<int>();
101 if (pos.x > map_size.x || pos.y > map_size.y) {
102 LOG_DEBUG(("escaped"));
103 Object::emit("death", NULL);
104 }
105 _velocity = v2<float>(4, 3);
106
107 goto done;
108 }
109
110 {
111 //main ai
112 PlayerSlot &slot = PlayerManager->get_slot(_player);
113 Object *player = slot.getObject();
114 if (player == NULL || _toggle.tick(dt)) {
115 (++_player) %= PlayerManager->get_slots_count();
116 //LOG_DEBUG(("changing player to %d", _player));
117 return;
118 }
119 //LOG_DEBUG(("attacking player %d", _player));
120
121 v2<float> pos, vel;
122 pos = get_relative_position(player);
123 player->get_velocity(vel);
124 vel.normalize();
125
126 float est = pos.length() / speed;
127
128 v2<float> dir = pos + speed * vel * est - v2<float>(0, 128); //bomb correction
129 if (dir.length() > 64) {
130 dir.normalize();
131 _velocity.normalize();
132 _velocity = _velocity * 2 + dir * 3;
133 _velocity.normalize();
134 } else {
135 _velocity = _direction;
136 //LOG_DEBUG(("idle velocity %g %g", _velocity.x, _velocity.y));
137 }
138 }
139
140 done:
141 //common part
142 GET_CONFIG_VALUE("engine.mass-acceleration-divisor", float, ac_div, 1000.0f);
143 if (!_velocity.is0()) {
144 _moving_time += dt;
145 } else {
146 _moving_time = 0;
147 }
148
149 const float ac_t = mass / ac_div * 0.8;
150 _state.alt_fire = _moving_time >= ac_t;
151
152 calculate_way_velocity();
153
154 GET_CONFIG_VALUE("objects.helicopter.rotation-time", float, rt, 0.2f);
155 limit_rotation(dt, rt, false, false);
156 update_state_from_velocity();
157 }
158
159 REGISTER_OBJECT("raider-helicopter", RaiderHeli, ());
160