Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
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