1 /* Battle Tanks Game
2 * Copyright (C) 2006-2009 Battle Tanks team
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (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, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*
20 * Additional rights can be granted beyond the GNU General Public License
21 * on the terms provided in the Exception. If you modify this file,
22 * you may extend this exception to your version of the file,
23 * but you are not obligated to do so. If you do not wish to provide this
24 * exception without modification, you must delete this exception statement
25 * from your version and license this file solely under the GPL without exception.
26 */
27
28 #include "registrar.h"
29 #include "config.h"
30 #include "object.h"
31 #include "item.h"
32 #include "ai/waypoints.h"
33
34 class Car: public Object {
35 public:
Car(const std::string & classname)36 Car(const std::string &classname) : Object(classname), _alt_fire(1, false) {}
37 virtual void calculate(const float dt);
38 virtual void tick(const float dt);
39 virtual void on_spawn();
clone() const40 virtual Object * clone() const { return new Car(*this); }
41
42 void emit(const std::string &event, Object * emitter);
43
serialize(mrt::Serializator & s) const44 virtual void serialize(mrt::Serializator &s) const {
45 Object::serialize(s);
46 s.add(_alt_fire);
47 }
deserialize(const mrt::Serializator & s)48 virtual void deserialize(const mrt::Serializator &s) {
49 Object::deserialize(s);
50 s.get(_alt_fire);
51 }
52
53
54 protected:
55 Alarm _alt_fire;
56 private:
57 virtual void get_impassability_penalty(const float impassability, float &base, float &base_value, float &penalty) const;
58 };
59
on_spawn()60 void Car::on_spawn() {
61 if (registered_name.compare(0, 7, "static-") == 0) {
62 disown();
63 disable_ai = true;
64 }
65 _variants.add("safe");
66 play("hold", true);
67 }
68
get_impassability_penalty(const float impassability,float & base,float & base_value,float & penalty) const69 void Car::get_impassability_penalty(const float impassability, float &base, float &base_value, float &penalty) const {
70 if (impassability >= 0.2) {
71 base = 0.2;
72 base_value = 0.5;
73 penalty = 0;
74 return;
75 }
76 }
77
emit(const std::string & event,Object * emitter)78 void Car::emit(const std::string &event, Object * emitter) {
79 if (event == "death") {
80 spawn("corpse", "dead-" + animation, v2<float>(), v2<float>());
81 _dead = true;
82 detachVehicle();
83 Object::emit(event, emitter);
84 return;
85 } else if (emitter != NULL && !_velocity.is0() && event == "collision" && animation == "harvester") {
86 const std::string &classname = emitter->classname;
87 if (!emitter->get_variants().has("player") && (classname == "trooper" || classname == "civilian" || classname == "kamikaze" || classname == "monster")) {
88 //LOG_DEBUG(("bloody harvest"));
89 emitter->emit("death", NULL);
90 if (classname != "monster")
91 heal(5);
92 }
93 } else if (event == "collision" && !_variants.has("safe")) {
94 if (emitter != NULL && emitter->speed > 0) {
95 if (emitter->registered_name == "machinegunner" && registered_name.compare(0, 7, "static-") == 0) {
96 return;
97 }
98 Item * item = dynamic_cast<Item *>(emitter);
99 //no items.
100 if (item == NULL) {
101 GET_CONFIG_VALUE("objects.car.damage", int, d, 5);
102 emitter->add_damage(this, d);
103 emitter->add_effect("stunned", 0.1f);
104 emit("death", emitter);
105 }
106 }
107 }
108 Object::emit(event, emitter);
109 }
110
calculate(const float dt)111 void Car::calculate(const float dt) {
112 Object::calculate(dt);
113 GET_CONFIG_VALUE("objects." + registered_name + ".rotation-time", float, rt, 0.05f);
114 limit_rotation(dt, rt, true, false);
115 }
116
tick(const float dt)117 void Car::tick(const float dt) {
118 if (_alt_fire.tick(dt) && _state.alt_fire) {
119 _alt_fire.reset();
120 play_random_sound("klaxon", false);
121 }
122 Object::tick(dt);
123 if (_velocity.is0() && get_state() != "hold") {
124 cancel_all();
125 play("hold", true);
126 } else if (!_velocity.is0() && get_state() != "move") {
127 cancel_all();
128 play("move", true);
129 }
130 }
131
132 class AICar : public Car, public ai::Waypoints {
133 public:
AICar(const std::string & classname)134 AICar(const std::string &classname) : Car(classname){}
135 virtual void calculate(const float dt);
clone() const136 virtual Object * clone() const {return new AICar(*this);}
137 virtual void on_spawn();
138
serialize(mrt::Serializator & s) const139 virtual void serialize(mrt::Serializator &s) const {
140 Car::serialize(s);
141 ai::Waypoints::serialize(s);
142 }
deserialize(const mrt::Serializator & s)143 virtual void deserialize(const mrt::Serializator &s) {
144 Car::deserialize(s);
145 ai::Waypoints::deserialize(s);
146 }
147
148 private:
149 virtual void onObstacle(const Object *o);
150 };
151
on_spawn()152 void AICar::on_spawn() {
153 Car::on_spawn();
154 //obstacle_filter.insert("car");
155 //obstacle_filter.insert("civilian");
156 //obstacle_filter.insert("trooper");
157 //obstacle_filter.insert("fighting-vehicle");
158 _avoid_obstacles = true;
159
160 ai::Waypoints::on_spawn(this);
161 _alt_fire.set(5);
162 //GET_CONFIG_VALUE("objects.car.refreshing-path-interval", float, rpi, 1);
163 //_refresh_waypoints.set(rpi);
164
165 disown();
166 }
167
168
onObstacle(const Object * o)169 void AICar::onObstacle(const Object *o) {
170 /*
171 if ((idx % 21) == 1) { //approx once per 5 second
172 play_random_sound("klaxon", false);
173 }
174 */
175 _state.alt_fire = true;
176 }
177
calculate(const float dt)178 void AICar::calculate(const float dt) {
179 ai::Waypoints::calculate(this, dt);
180
181 float rt;
182 Config->get("objects." + registered_name + ".rotation-time", rt, 0.05f);
183 limit_rotation(dt, rt, true, false);
184 update_state_from_velocity();
185 }
186
187 REGISTER_OBJECT("static-car", AICar, ("vehicle"));
188 REGISTER_OBJECT("car", AICar, ("car"));
189