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