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