blob: dba79291b7872b9779a5e9e3b3719b37d9c3247c (
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
124
125
126
127
128
|
/*
base/npc.cc
This file is part of the Osirion project and is distributed under
the terms of the GNU General Public License version 2
*/
#include "base/npc.h"
#include "base/game.h"
namespace game {
// NPC Wingman factory function
NPC *NPC::add_wingman(Ship *leader)
{
if (!leader) {
return 0;
}
if (leader->state() != Entity::Normal) {
return 0;
}
NPC *npc = new NPC(ProfileWingman, leader->shipmodel());
npc->set_leader(leader);
npc->set_owner(leader->owner());
npc->set_name("Wingman");
npc->set_mood(MoodFormation);
npc->set_color(npc->leader()->color());
npc->set_color_second(npc->leader()->color_second());
npc->set_location(leader->location() - leader->axis().forward() * 2.0f * (leader->radius() + npc->radius()));
npc->set_axis(leader->axis());
npc->set_zone(leader->zone());
npc->reset();
return npc;
}
NPC::NPC(const Profile profile, const ShipModel *shipmodel) : Ship(0, shipmodel)
{
npc_profile = profile;
npc_mood = MoodWander;
npc_destroyed_timestamp = 0;
}
void NPC::set_mood(const Mood mood)
{
npc_mood = mood;
}
void NPC::set_leader(Ship *leader)
{
npc_leader = leader;
}
void NPC::frame(const unsigned long elapsed)
{
if (state() == core::Entity::Destroyed) {
if (!npc_destroyed_timestamp) {
npc_destroyed_timestamp = core::game()->time();
} else if (npc_destroyed_timestamp + 10.0f < core::game()->time()) {
// stay alive for 10 more seconds while explosion particles are drawn
die();
}
} else {
// TODO pilot magic and mood witchcraft
if (leader()) {
// verify leader still exists
if (!core::Entity::find(leader())) {
set_leader(0);
explode();
npc_destroyed_timestamp = core::game()->time();
} else if (leader()->zone() == zone()) {
if (leader()->state() == Docked) {
// TODO dock where the leader is docked
if (leader()->dock()) {
frame_autopilot_goto(elapsed, leader()->dock());
}
} else {
if (math::distance(location(), leader()->location()) > 4.0f * ( radius() + leader()->radius())) {
// goto the leader
frame_autopilot_goto(elapsed, leader());
} else {
// formatian flying
frame_autopilot_formation(elapsed, leader());
}
}
} else {
target_direction = 0;
target_pitch = 0;
target_roll = 0;
target_strafe = 0.0f;
target_vstrafe = 0.0f;
target_afterburner = 0.0f;
target_thrust = 0;
if (state() == core::Entity::Impulse) {
func_impulse();
}
}
}
}
// run a ship game frame
Ship::frame(elapsed);
}
} // namespace game
|