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 "object.h"
29 #include "registrar.h"
30 #include "alarm.h"
31 #include "config.h"
32 #include "mrt/random.h"
33 #include "ai/herd.h"
34 #include "special_owners.h"
35
36 class Cow : public Object, public ai::Herd{
37 public:
Cow(const std::string & classname)38 Cow(const std::string &classname) :
39 Object(classname), _reaction(true) {}
40
41 virtual void tick(const float dt);
42 virtual void calculate(const float dt);
43
44 virtual Object * clone() const;
45 virtual void on_spawn();
46 virtual void emit(const std::string &event, Object * emitter = NULL);
47
serialize(mrt::Serializator & s) const48 virtual void serialize(mrt::Serializator &s) const {
49 Object::serialize(s);
50 s.add(_reaction);
51 }
deserialize(const mrt::Serializator & s)52 virtual void deserialize(const mrt::Serializator &s) {
53 Object::deserialize(s);
54 s.get(_reaction);
55 }
56
57 virtual void onIdle(const float dt);
58 const int getComfortDistance(const Object *other) const;
59
60 private:
61 Alarm _reaction;
62 };
63
getComfortDistance(const Object * other) const64 const int Cow::getComfortDistance(const Object *other) const {
65 GET_CONFIG_VALUE("objects.cow.comfort-distance", int, cd, 200);
66 return (other == NULL || other->registered_name == registered_name)?cd:-1; //fixme names if you want
67 }
68
69
onIdle(const float dt)70 void Cow::onIdle(const float dt) {
71 int tt;
72 Config->get("objects." + registered_name + ".targeting-range", tt, 400);
73 ai::Herd::calculateV(_velocity, this, 0, tt);
74 }
75
76
calculate(const float dt)77 void Cow::calculate(const float dt) {
78 if (_reaction.tick(dt) && !has_effect("panic"))
79 onIdle(dt);
80
81 GET_CONFIG_VALUE("objects.cow.rotation-time", float, rt, 0.2);
82 limit_rotation(dt, rt, true, false);
83 }
84
tick(const float dt)85 void Cow::tick(const float dt) {
86 Object::tick(dt);
87
88 if (_velocity.is0()) {
89 if (get_state() != "hold") {
90 cancel_all();
91 play("hold", true);
92 }
93 } else {
94 if (get_state() == "hold") {
95 cancel_all();
96 play("walk", true);
97 }
98 }
99 }
100
on_spawn()101 void Cow::on_spawn() {
102 float rt, drt = 1;
103
104 Config->get("objects." + registered_name + ".reaction-time", rt, drt);
105 mrt::randomize(rt, rt/10);
106 _reaction.set(rt);
107 play("hold", true);
108
109 remove_owner(OWNER_MAP);
110 }
111
emit(const std::string & event,Object * emitter)112 void Cow::emit(const std::string &event, Object * emitter) {
113 if (event == "death") {
114 spawn("corpse", "dead-cow", v2<float>(), v2<float>());
115 } else if (emitter != NULL && emitter->piercing && event == "collision") {
116 v2<float> v;
117 emitter->get_velocity(v);
118 int dirs = get_directions_number();
119 int dir = v.get_direction(dirs);
120 dir = (dirs + dir + dirs / (mrt::random(2)?4:-4)) % dirs;
121 set_direction(dir);
122 _velocity.fromDirection(dir, dirs);
123 _direction = _velocity;
124 add_effect("panic", 3.0f);
125 }
126 Object::emit(event, emitter);
127 }
128
129
clone() const130 Object* Cow::clone() const {
131 return new Cow(*this);
132 }
133
134 REGISTER_OBJECT("cow", Cow, ("creature"));
135