1 /*
2 Copyright (C) 2009 Facundo Domínguez
3
4 This file is part of Spacejunk.
5
6 Spacejunk is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Foobar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "starship.h"
21 #include <math.h>
22 #include "runtimeopts.h"
23 #include "soundcollection.h"
24
25 #include <iostream>
26 #include <iomanip>
27
28 using namespace std;
29
30 extern SoundCollection * sounds;
31
32 // This is an interesting velocity (-sqrt(G*2.5e14),0)
Starship(const string & graphicid,Vector2d pos,Vector2d vel,real m,real w)33 Starship::Starship(const string & graphicid,Vector2d pos,Vector2d vel,real m,real w)
34 :GameBody(graphicid,pos,vel,m,w),GraphicSeq(&flame), power(false), flame("flame") {
35 maxFuel=timeToFuel(1000);
36 fuel=maxFuel*0.8;
37 shipMass=mass;
38 mass+=fuel;
39 setAngle(getAngle());
40 flame.setFrame(flame.getImageCount());
41 initcount=0;
42 };
43
turn_on_engine()44 void Starship::turn_on_engine() {
45 if (power || fuel<=0)
46 return;
47 power=true;
48 hold=true;
49 setFrameSequence(0,flame.getImageCount()-1,false,true);
50 if (sounds) {
51 sounds->engineinit.play();
52 initcount=150;
53 }
54 }
55
turn_off_engine()56 void Starship::turn_off_engine() {
57 if (!power)
58 return;
59 power=false;
60 hold=false;
61 setFrameSequence(flame.getImageCount()-1,0,false,false);
62 if (sounds) {
63 /*if (initcount)*/
64 sounds->engineinit.stop();
65 /*else*/
66 sounds->engine.stop();
67 sounds->engineend.play();
68 }
69 }
70
71
72 //#define ANGLE_ACC 0.00005
73 #define ANGLE_VEL 0.5
74
75 // Velocity at which the fuel is fired
76 #define FUEL_VEL 3
77
78 // Rate of mass of fuel burned
79 #define MASS_PER_MILLISECOND 0.025
80
turn_left()81 void Starship::turn_left() {
82 w=-ANGLE_VEL;
83 }
84
turn_right()85 void Starship::turn_right() {
86 w=ANGLE_VEL;
87 }
88
stop_turning()89 void Starship::stop_turning() {
90 w=0;
91 }
92
setAngle(real a)93 void Starship::setAngle(real a) {
94 real x,y;
95 sincos((a-90)*M_PI/180,&y,&x);
96 dir.x=x;
97 dir.y=y;
98 GameBody::setAngle(a);
99 };
100
timeToFuel(real delta)101 real Starship::timeToFuel(real delta) {
102 return MASS_PER_MILLISECOND*delta;
103 };
104
fuelToTime(real fuel)105 real Starship::fuelToTime(real fuel) {
106 return fuel/MASS_PER_MILLISECOND;
107 };
108
stepShip(int delta)109 void Starship::stepShip(int delta) {
110 stepSeq(delta);
111 if (power) {
112 real tempfuel=timeToFuel(delta);
113 real oldfuel=fuel/maxFuel;
114 if (fuel<=tempfuel) {
115 setFuel(0);
116 turn_off_engine();
117 } else
118 setFuel(getFuel()-tempfuel);
119 if (sounds && oldfuel>=0.25 && 0.25>fuel/maxFuel)
120 sounds->lowFuel.play(1);
121 if (initcount>0 && sounds) {
122 if (initcount<=int(delta)) {
123 initcount=0;
124 sounds->engine.play(-1);
125 } else
126 initcount-=delta;
127 }
128 }
129 }
130
getDirection()131 Vector2d Starship::getDirection() {
132 return dir;
133 }
134
getAcceleration(real delta)135 Vector2d Starship::getAcceleration(real delta) {
136 if (power) {
137 if (fuel>0) {
138 real tempfuel=timeToFuel(delta);
139 if (fuel<tempfuel) {
140 tempfuel=fuel;
141 delta=fuelToTime(fuel);
142 }
143 real temp=MASS_PER_MILLISECOND/(mass-delta*MASS_PER_MILLISECOND)*FUEL_VEL;
144 return dir*temp;
145 };
146 }
147 return Vector2d();
148 }
149
saveState()150 void Starship::saveState() {
151 GameBody::saveState();
152 }
153
clone()154 PhysicBody * Starship::clone() {
155 Starship *s=new Starship(*this);
156 s->seqg=&s->flame;
157 return s;
158 };
159
copy(PhysicBody * pb) const160 void Starship::copy(PhysicBody * pb) const {
161 Starship *s=dynamic_cast<Starship*>(pb);
162 *s=*this;
163 s->seqg=&s->flame;
164 };
165
collectTrash(GameBody * t)166 void Starship::collectTrash(GameBody* t) {
167 collected.push_front(TrashData(t->mass));
168 mass+=t->mass;
169 };
170
popTrash()171 TrashData Starship::popTrash() {
172 TrashData temp=collected.front();
173 collected.pop_front();
174 mass-=temp.mass;
175 return temp;
176 };
177
getTrashCount()178 int Starship::getTrashCount() {
179 return collected.size();
180 };
181
draw(int x,int y,real zoom,real angle)182 void Starship::draw(int x,int y,real zoom,real angle) {
183 flame.draw(int(x-dir.x*(getWidth()+7)*zoom),int(y-dir.y*(getWidth()+7)*zoom),zoom,angle);
184 GameBody::draw(x,y,zoom,angle);
185 }
186
setFuel(real fuel)187 void Starship::setFuel(real fuel) {
188 mass -= this->fuel;
189 this->fuel = fuel;
190 mass += fuel;
191 }
192
setFuelNoMass(real fuel)193 void Starship::setFuelNoMass(real fuel) {
194 this->fuel = fuel;
195 }
196
getFuel()197 real Starship::getFuel() {
198 return fuel;
199 }
200
201