1 //
2 //  ElectricGate.cpp -- Electric gateway thingys.
3 //  Copyright (C) 2008  Nick Gasson
4 //
5 //  This program is free software: you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation, either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 //
18 
19 #include "ElectricGate.hpp"
20 #include "Ship.hpp"
21 
22 #include <string>
23 
ElectricGate(Viewport * v,int length,bool vertical,int x,int y)24 ElectricGate::ElectricGate(Viewport* v, int length, bool vertical, int x, int y)
25    : StaticObject(x, y), length(length), vertical(vertical), viewport(v),
26      gateImage("images/gateway.png")
27 {
28    lightning.Build(length * OBJ_GRID_SIZE, vertical);
29 
30    timer = rand() % 70 + 10;
31 }
32 
CheckCollision(Ship & ship)33 bool ElectricGate::CheckCollision(Ship& ship)
34 {
35    int dx = vertical ? 0 : length;
36    int dy = vertical ? length : 0;
37    if (timer > GATEWAY_ACTIVE) {
38       bool collide1 = ship.BoxCollision
39          (xpos*OBJ_GRID_SIZE,
40           ypos*OBJ_GRID_SIZE + OBJ_GRID_TOP,
41           OBJ_GRID_SIZE,
42           OBJ_GRID_SIZE);
43 
44       bool collide2 = ship.BoxCollision
45          ((xpos + dx)*OBJ_GRID_SIZE,
46           (ypos + dy)*OBJ_GRID_SIZE + OBJ_GRID_TOP,
47           OBJ_GRID_SIZE,
48           OBJ_GRID_SIZE);
49 
50       return collide1 || collide2;
51    }
52    else {
53       return ship.BoxCollision
54          (xpos*OBJ_GRID_SIZE,
55           ypos*OBJ_GRID_SIZE + OBJ_GRID_TOP,
56           (dx + 1)*OBJ_GRID_SIZE,
57           (dy + 1)*OBJ_GRID_SIZE);
58    }
59 }
60 
Draw()61 void ElectricGate::Draw()
62 {
63    // Draw first sphere
64    int draw_x = xpos*OBJ_GRID_SIZE - viewport->GetXAdjust();
65    int draw_y = ypos*OBJ_GRID_SIZE + OBJ_GRID_TOP - viewport->GetYAdjust();
66    gateImage.Draw(draw_x, draw_y);
67 
68    // Draw second sphere
69    if (vertical) {
70       draw_x = xpos*OBJ_GRID_SIZE - viewport->GetXAdjust();
71       draw_y = (ypos+length)*OBJ_GRID_SIZE + OBJ_GRID_TOP - viewport->GetYAdjust();
72    }
73    else {
74       draw_x = (xpos+length)*OBJ_GRID_SIZE - viewport->GetXAdjust();
75       draw_y = ypos*OBJ_GRID_SIZE + OBJ_GRID_TOP - viewport->GetYAdjust();
76    }
77    gateImage.Draw(draw_x, draw_y);
78 
79    // Draw the electricity stuff
80    if (--timer < GATEWAY_ACTIVE) {
81       double x = xpos*OBJ_GRID_SIZE + 16 - viewport->GetXAdjust();
82       double y = ypos*OBJ_GRID_SIZE + OBJ_GRID_TOP + 16 - viewport->GetYAdjust();
83 
84       glLoadIdentity();
85       glTranslated(x, y, 0.0);
86       lightning.Draw();
87 
88       if (timer % 5 == 0)
89          lightning.Build(length * OBJ_GRID_SIZE, vertical);
90 
91       // Reset timer
92       if (timer < 0)
93          timer = 100;
94    }
95 }
96 
Build(int length,bool vertical)97 void Lightning::Build(int length, bool vertical)
98 {
99    line.SwapXandY(vertical);
100    line.Clear();
101 
102    const int POINT_STEP = 20;
103    int npoints = (length / POINT_STEP) + 1;
104    double delta = (double)length / (double)(npoints - 1);
105 
106    const double SWING_SIZE = 5;
107    const double MAX_OUT = 25;
108    double y = 0;
109    for (int i = 0; i < npoints; i++) {
110       if (i == npoints - 1)
111          y = 0;
112 
113       line.AddPoint(i*delta, y);
114 
115       double swing = rand() % 2 == 0 ? -1 : 1;
116       y += swing * SWING_SIZE * (double)(rand() % 4);
117       if (y > MAX_OUT)
118          y = MAX_OUT - swing * SWING_SIZE;
119       else if (y < -MAX_OUT)
120          y = -MAX_OUT + swing * SWING_SIZE;
121    }
122 }
123 
Draw() const124 void Lightning::Draw() const
125 {
126    glDisable(GL_TEXTURE_2D);
127    glEnable(GL_BLEND);
128 
129    line.Draw();
130 }
131 
AddPoint(double x,double y)132 void LightLineStrip::AddPoint(double x, double y)
133 {
134    if (swapXandY)
135       points.push_back(Point_t(y, x));
136    else
137       points.push_back(Point_t(x, y));
138 }
139 
Draw() const140 void LightLineStrip::Draw() const
141 {
142    DrawWithOffset(0, 1, 1, 1, 1);
143 
144    DrawWithOffset(1, 0.8, 0.8, 1, 0.8);
145    DrawWithOffset(-1, 0.8, 0.8, 1, 0.8);
146 
147    DrawWithOffset(2, 0.6, 0.6, 1, 0.6);
148    DrawWithOffset(-2, 0.6, 0.6, 1, 0.6);
149 
150    DrawWithOffset(3, 0.4, 0.4, 1, 0.4);
151    DrawWithOffset(-3, 0.4, 0.4, 1, 0.4);
152 
153    DrawWithOffset(4, 0.2, 0.2, 1, 0.2);
154    DrawWithOffset(-4, 0.2, 0.2, 1, 0.2);
155 }
156 
DrawWithOffset(double off,double r,double g,double b,double a) const157 void LightLineStrip::DrawWithOffset(double off, double r, double g, double b,
158                                     double a) const
159 {
160    double y_off = swapXandY ? 0 : off;
161    double x_off = swapXandY ? off : 0;
162 
163    glColor4d(r, g, b, a);
164    glBegin(GL_LINE_STRIP);
165 
166    list<Point_t>::const_iterator it;
167    for (it = points.begin(); it != points.end(); ++it)
168       glVertex2d((*it).first + x_off, (*it).second + y_off);
169 
170    glEnd();
171 }
172 
173