-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfleet.cpp
More file actions
162 lines (130 loc) · 4.27 KB
/
fleet.cpp
File metadata and controls
162 lines (130 loc) · 4.27 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
Copyright (c) 2013 Auston Sterling
See license.txt for copying permission.
-----Fleet Class Definition-----
Auston Sterling
austonst@gmail.com
Contains the definition for the Fleet class.
*/
#ifndef _fleet_cpp_
#define _fleep_cpp_
#include "fleet.h"
#include <cmath>
//Default constructor, should probably not be used
Fleet::Fleet():pos_(0,0), dest_(NULL), speed_(0), lastTicks_(0), owner_(0)
{
}
//Regular constructor
Fleet::Fleet(int inships, int intype, ShipStats shipstats, Planet* begin, Planet* end):
pos_(begin->x() + (UNSCALED_PLANET_RADIUS * begin->size()),
begin->y() + (UNSCALED_PLANET_RADIUS * begin->size())),
dest_(end),
speed_(shipstats.speed),
ships_(inships),
type_(intype),
lastTicks_(0),
lastIntercept_(0),
owner_(begin->owner()),
damage_(0)
{
}
//Returns a unit vector of the velocity of the fleet
Vec2f Fleet::vel() const
{
//Get the center of the planet
Vec2f tar(dest_->x() + (UNSCALED_PLANET_RADIUS * dest_->size()),
dest_->y() + (UNSCALED_PLANET_RADIUS * dest_->size()));
//Find the difference and normalize
Vec2f diff = tar-pos_;
diff.normalize();
return diff;
}
//Returns the total attack power of the fleet
float Fleet::totalAttack(const std::vector<ShipStats> & shipstats) const
{
return float(ships_) * shipstats[type_].attack;
}
//Returns the total defense of the fleet
float Fleet::totalDefense(const std::vector<ShipStats> & shipstats) const
{
return float(ships_) * shipstats[type_].defense;
}
//Update function
void Fleet::update()
{
//Check for first call
if (lastTicks_ == 0)
{
lastTicks_ = SDL_GetTicks();
lastIntercept_ = SDL_GetTicks();
return;
}
//Find change in time
int newtime = SDL_GetTicks();
int dt = newtime - lastTicks_;
lastTicks_ = newtime;
//Move fleet towards destination
//Find target coordinates
Vec2f tar(dest_->x() + (UNSCALED_PLANET_RADIUS * dest_->size()),
dest_->y() + (UNSCALED_PLANET_RADIUS * dest_->size()));
//Find the proper vector to add
Vec2f diff = tar-pos_;
diff.normalize();
diff *= speed_*(dt/1000.0);
//Move the fleet
pos_ += diff;
}
//Display function
void Fleet::display(SDL_Surface* screen, const SDL_Rect& camera)
{
//For now, just draw a rectangle
SDL_Rect rect = {Sint16(pos_.x() - 10 - camera.x), Sint16(pos_.y() - 10 - camera.y), 20, 20};
SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0, 0, 0));
}
//Applies damage to the fleet
//Returns false if this hit would destroy the fleet
bool Fleet::takeHit(int damage, const std::vector<ShipStats> & shipstats)
{
//Add in any extra damage from last time
damage += damage_;
//Convert damage to ship loss
int shiploss = damage / shipstats[type_].defense;
//If we can wipe out the whole fleet
if (shiploss >= ships_) return false;
//Otherwise, deal some damage
ships_ -= shiploss;
//Keep track of any extra accumulated damage
damage_ = damage % int(shipstats[type_].defense);
return true;
}
//Attempts to intercept the target fleet. Returns 0 if nothing happens
//Returns 1 if the fleets are properly placed for interception, but the attack is on CD
//Returns 2 and damages the target fleet if successful
//Returns 3 instead if the target fleet is destroyed because of it
char Fleet::intercept(Fleet* target, const std::vector<ShipStats> & shipstats)
{
//Don't compare against itself
if (this == target) return 0;
//Can't intercept your own ships
if (owner_ == target->owner()) return 0;
//Target must be within interception range
if ((target->pos()-pos_).length() > shipstats[type_].interceptRange) return 0;
//Get the position difference vector and the two velocity vectors
Vec2f diff = target->pos()-pos_;
Vec2f vi = vel();
Vec2f vj = target->vel();
//Ensure we are appropriately behind the target
//Compare diff to vj
if (diff.angleBetween(vj) > M_PI/3) return 0;
//Ensure we are facing the defender
if (diff.angleBetween(vi) > M_PI/4) return 0;
//Now, we know we're in place to intercept
//If we can't fire a shot now, end here
int ticks = SDL_GetTicks();
if (ticks - lastIntercept_ < shipstats[type_].interceptCD) return 1;
//Set lastIntercept to now
lastIntercept_ = ticks;
//Deal damage to the target and return
return (target->takeHit(shipstats[type_].interceptDamage*ships_, shipstats))?2:3;
}
#endif