blob: 133f4e05e4a91226fdcad211b90620a81d639338 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
base/spacemine.cc
This file is part of the Osirion project and is distributed under
the terms and conditions of the GNU General Public License version 2
*/
#include "base/spacemine.h"
#include "base/game.h"
#include "math/functions.h"
namespace game
{
const Template *SpaceMine::spacemine_template = 0;
SpaceMine::SpaceMine(const Weapon *weapon) : EntityDynamic()
{
entity_moduletypeid = spacemine_enttype;
set_name("Space mine");
set_label("spacemine");
set_flag(core::Entity::KeepAlive);
set_shape(core::Entity::Sphere);
// setting
set_radius(0);
set_damage(0.0f);
// use template settings if available
if (spacemine_template) {
spacemine_template->apply(this);
}
// item type model overrides template
if (weapon) {
set_info(weapon);
if (weapon->modelname().size()) {
set_modelname(weapon->modelname());
}
set_name(weapon->name());
set_label(weapon->label());
set_damage(weapon->damage());
}
// radius fallback
if (!radius()) {
if (model()->radius()) {
set_radius(model()->radius());
} else {
set_radius(0.1f);
}
}
spacemine_detonated_timestamp = 0;
// activate physics
set_mass(radius());
reset();
const float damp = Game::g_damping->value();
body()->setDamping(damp, damp);
}
SpaceMine::~SpaceMine()
{
}
void SpaceMine::upkeep(const unsigned long timestamp)
{
// space mines dissapear on upkeep
die();
}
void SpaceMine::collision(core::Entity *other)
{
if (state() == core::Entity::Destroyed) {
return;
}
// mines explode on impact
if ((other->type() == core::Entity::Dynamic) || (other->type() == core::Entity::Controlable)) {
core::EntityDynamic *entity = static_cast<core::EntityDynamic *>(other);
math::Vector3f explosion_direction(entity->location() - location());
explosion_direction.normalize();
math::Vector3f explosion_torque(math::randomf(2.0f) - 1.0f, math::randomf(2.0f) - 1.0f, math::randomf(2.0f) - 1.0f);
explosion_torque.normalize();
const float force = math::max(entity->mass(), entity->radius() * 100.0f);
entity->body()->applyCentralImpulse(math::to_btVector3(explosion_direction * force ));
entity->body()->applyTorqueImpulse(math::to_btVector3(explosion_torque * force * 0.1f));
entity->hit(this);
}
spacemine_detonated_timestamp = core::game()->time();
set_state(core::Entity::Destroyed);
// this method is a bullet callback, we can not reset() here
}
void SpaceMine::frame(const unsigned long elapsed)
{
EntityDynamic::frame(elapsed);
if (state() == core::Entity::Destroyed) {
if (body()) {
reset();
}
if (spacemine_detonated_timestamp + 5.0f < core::game()->time()) {
die();
}
}
}
} // namespace game
|