author | nireco |
Sat, 31 Jan 2009 12:33:08 +0200 | |
changeset 443 | 5d1119729f58 |
parent 428 | 712b943195a6 |
permissions | -rw-r--r-- |
417
c503e0c6a740
support for building without Network/Graphics, although the disable-graphics case is kind of hackish still
Tero Marttila <terom@fixme.fi>
parents:
412
diff
changeset
|
1 |
|
c503e0c6a740
support for building without Network/Graphics, although the disable-graphics case is kind of hackish still
Tero Marttila <terom@fixme.fi>
parents:
412
diff
changeset
|
2 |
// XXX: must include Player first, as it contains an instance of Rope |
225 | 3 |
#include "Player.hh" |
4 |
#include "Rope.hh" |
|
5 |
#include "Engine.hh" |
|
417
c503e0c6a740
support for building without Network/Graphics, although the disable-graphics case is kind of hackish still
Tero Marttila <terom@fixme.fi>
parents:
412
diff
changeset
|
6 |
#include "Error.hh" |
412
721c60072091
new graphics code compiles... no, it doesn't work yet
Tero Marttila <terom@fixme.fi>
parents:
408
diff
changeset
|
7 |
|
225 | 8 |
#include <math.h> |
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
9 |
#include <stdexcept> |
225 | 10 |
|
235 | 11 |
Rope::Rope(Player &player) : |
311
440763821484
make Input have its own timer, and add key-repeat handling, and fix some warnings
terom
parents:
305
diff
changeset
|
12 |
PhysicsObject(player.state.world, ROPE_MASS, Vector(0,0), Vector(0,0), ROPE, 0.00, false), |
440763821484
make Input have its own timer, and add key-repeat handling, and fix some warnings
terom
parents:
305
diff
changeset
|
13 |
player(player), |
440763821484
make Input have its own timer, and add key-repeat handling, and fix some warnings
terom
parents:
305
diff
changeset
|
14 |
state(ROPE_FOLDED) |
235 | 15 |
{ |
16 |
// XXX: better shape |
|
225 | 17 |
std::vector<Vector> shape(4); |
18 |
shape[0] = Vector(-1, -1); |
|
19 |
shape[1] = Vector(-1, 1); |
|
20 |
shape[2] = Vector(1, 1); |
|
21 |
shape[3] = Vector(1, -1); |
|
22 |
setShape(shape); |
|
23 |
} |
|
24 |
||
235 | 25 |
void Rope::throwRope (void) { |
427
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
26 |
if (state == ROPE_FIXED) { |
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
27 |
// unset pivot if we re-throw rope |
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
28 |
player.setPivot(NULL); |
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
29 |
} |
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
30 |
|
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
31 |
// update state |
235 | 32 |
state = ROPE_FLYING; |
225 | 33 |
|
235 | 34 |
// XXX: this should probably be more dynamic? |
35 |
length = ROPE_LENGTH; |
|
36 |
||
37 |
// copy position + velocity from player |
|
427
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
38 |
setPosition(player.getPosition()); |
01e77fe8c040
fix ticket:1 and make PhysicsObject setPosition/setVelocity protected
Tero Marttila <terom@fixme.fi>
parents:
417
diff
changeset
|
39 |
setVelocity(player.getVelocity() + player.getDirection() * ROPE_VELOCITY); |
235 | 40 |
|
41 |
// we are FLYING |
|
42 |
inAir = true; |
|
43 |
||
44 |
// enable the physics object |
|
225 | 45 |
enable(); |
241 | 46 |
|
47 |
// inform network |
|
48 |
player.handleRopeState(state); |
|
225 | 49 |
} |
50 |
||
273 | 51 |
void Rope::onCollision (Vector collisionPoint, PhysicsObject *other) { |
322 | 52 |
// Fix the rope to another player if collided with it |
305 | 53 |
if (other != NULL) { |
328 | 54 |
// we collided with another object |
305 | 55 |
if (other->getType() == PLAYER) { |
328 | 56 |
// set our player's pivot to the object that we collided with |
305 | 57 |
Player *target = dynamic_cast<Player*>(other); |
328 | 58 |
|
59 |
// ignore if the rope hits ourself |
|
60 |
if (target == &this->player) |
|
305 | 61 |
return; |
328 | 62 |
|
63 |
// set player's pivot to the other player |
|
64 |
player.setPivot(target); |
|
65 |
||
66 |
// disable ourselves as we're no longer relevant, don't keep colliding with the player |
|
67 |
disable(); |
|
68 |
||
69 |
} else { |
|
70 |
// ignore other objects |
|
305 | 71 |
return; |
72 |
} |
|
328 | 73 |
|
74 |
} else { |
|
75 |
// Collided with terrain, set player's pivot to ourselves |
|
322 | 76 |
player.setPivot(this); |
305 | 77 |
} |
282
e0e4dfc3e528
compiles cleanly with -Wall -Wextra -Wconversion, not tested, but that shouldn't break anything :)
terom
parents:
273
diff
changeset
|
78 |
|
235 | 79 |
// attached to something! |
80 |
state = ROPE_FIXED; |
|
428
712b943195a6
clean up PhysicsObject.hh a bit, make some things private
Tero Marttila <terom@fixme.fi>
parents:
427
diff
changeset
|
81 |
|
712b943195a6
clean up PhysicsObject.hh a bit, make some things private
Tero Marttila <terom@fixme.fi>
parents:
427
diff
changeset
|
82 |
// XXX: reset, except we override tick() in ugly ways |
712b943195a6
clean up PhysicsObject.hh a bit, make some things private
Tero Marttila <terom@fixme.fi>
parents:
427
diff
changeset
|
83 |
setVelocity(Vector(0,0)); |
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
84 |
|
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
85 |
// Ropes location will be used as the pivot point, so move the location to the collisionPoint. |
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
86 |
// Currently the position is something like one pixel away from the collisionPoint where there isn't ground. |
328 | 87 |
setPosition(collisionPoint); |
241 | 88 |
|
89 |
// inform network |
|
90 |
player.handleRopeState(state); |
|
225 | 91 |
} |
92 |
||
93 |
void Rope::release (void) { |
|
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
94 |
// Remove the rope from the PhysicsWorld |
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
95 |
disable(); |
229 | 96 |
|
235 | 97 |
state = ROPE_FOLDED; |
228 | 98 |
|
99 |
// player doesn't have a pivot anymore |
|
235 | 100 |
player.setPivot(NULL); |
241 | 101 |
|
102 |
// inform network |
|
103 |
player.handleRopeState(state); |
|
225 | 104 |
} |
105 |
||
235 | 106 |
void Rope::changeLength (float delta) { |
241 | 107 |
// change length |
235 | 108 |
length += delta; |
241 | 109 |
|
110 |
// minimum length |
|
235 | 111 |
if (length < 0) |
112 |
length = 0; |
|
241 | 113 |
|
114 |
// inform network |
|
115 |
player.handleRopeLength(length); |
|
231 | 116 |
} |
117 |
||
225 | 118 |
RopeState Rope::getState (void) { |
235 | 119 |
return state; |
225 | 120 |
} |
241 | 121 |
|
122 |
float Rope::getLength (void) { |
|
123 |
return length; |
|
124 |
} |
|
125 |
||
328 | 126 |
Player *Rope::getPivotPlayer (void) { |
127 |
if (player.getPivot() == this) |
|
128 |
return NULL; |
|
129 |
else |
|
130 |
return dynamic_cast<Player*>(player.getPivot()); |
|
131 |
} |
|
132 |
||
133 |
void Rope::updateState (RopeState new_state, Vector position, Vector velocity, float new_length, Player *pivot_player) { |
|
241 | 134 |
// update physics enabled/disabled state |
135 |
if (new_state == ROPE_FOLDED || new_state == ROPE_FIXED) |
|
136 |
disable(); |
|
137 |
||
138 |
else // new_state == ROPE_FLYING |
|
139 |
enable(); |
|
140 |
||
328 | 141 |
// update player.pivot to either the given pivot_player, or this rope |
142 |
if (new_state == ROPE_FIXED) { |
|
143 |
if (pivot_player) |
|
144 |
player.setPivot(pivot_player); |
|
145 |
else |
|
146 |
player.setPivot(this); |
|
241 | 147 |
|
328 | 148 |
} else if (this->state == ROPE_FIXED) |
241 | 149 |
player.setPivot(NULL); |
150 |
||
151 |
// update position stuff |
|
264 | 152 |
updatePhysics(position, velocity, true, FACING_RIGHT, 0); |
241 | 153 |
|
154 |
// update vars |
|
155 |
this->state = new_state; |
|
156 |
this->length = new_length; |
|
157 |
} |
|
158 |
||
159 |
void Rope::updateLength (float length) { |
|
160 |
// update length |
|
161 |
this->length = length; |
|
162 |
} |
|
225 | 163 |
|
417
c503e0c6a740
support for building without Network/Graphics, although the disable-graphics case is kind of hackish still
Tero Marttila <terom@fixme.fi>
parents:
412
diff
changeset
|
164 |
#if GRAPHICS_ENABLED |
412
721c60072091
new graphics code compiles... no, it doesn't work yet
Tero Marttila <terom@fixme.fi>
parents:
408
diff
changeset
|
165 |
void Rope::draw (graphics::Display &display, PixelCoordinate camera) { |
328 | 166 |
PixelCoordinate player_pos = player.getCoordinate() - camera; |
167 |
PixelCoordinate target_pos; |
|
377
01d3c340b372
direction normalization functions in vector, change rope color, misc comments+whitespace
terom
parents:
328
diff
changeset
|
168 |
|
01d3c340b372
direction normalization functions in vector, change rope color, misc comments+whitespace
terom
parents:
328
diff
changeset
|
169 |
// figure out what target is |
328 | 170 |
if (state == ROPE_FOLDED) { |
233
ff4ecea83cf5
start using CL_ResourceManager, change most draw methods to take a Graphics*, implment even better input handling, and draw weapon names
terom
parents:
231
diff
changeset
|
171 |
return; |
ff4ecea83cf5
start using CL_ResourceManager, change most draw methods to take a Graphics*, implment even better input handling, and draw weapon names
terom
parents:
231
diff
changeset
|
172 |
|
328 | 173 |
} else if (state == ROPE_FLYING) { |
174 |
// target is us |
|
175 |
target_pos = getCoordinate(); |
|
255
99431fdb0dc8
add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
terom
parents:
254
diff
changeset
|
176 |
|
328 | 177 |
} else { // state == ROPE_FIXED |
178 |
// sanity-check |
|
179 |
if (player.getPivot() == NULL) |
|
180 |
throw Error("Rope::draw in state ROPE_FIXED, yet player.getPivot() is NULL"); |
|
181 |
||
182 |
// target is our pivot |
|
183 |
target_pos = player.getPivot()->getCoordinate(); |
|
184 |
} |
|
377
01d3c340b372
direction normalization functions in vector, change rope color, misc comments+whitespace
terom
parents:
328
diff
changeset
|
185 |
|
328 | 186 |
// align with camera |
187 |
target_pos -= camera; |
|
188 |
||
189 |
// draw a line from the player to the target chosen above |
|
412
721c60072091
new graphics code compiles... no, it doesn't work yet
Tero Marttila <terom@fixme.fi>
parents:
408
diff
changeset
|
190 |
display.get_gc()->draw_line( |
257
549783d71e51
add a handful of consts to PhysicsObject and modify draw to use getCoordinate, and replace old skin.png with new skin.png
terom
parents:
256
diff
changeset
|
191 |
player_pos.x, player_pos.y, |
328 | 192 |
target_pos.x, target_pos.y, |
377
01d3c340b372
direction normalization functions in vector, change rope color, misc comments+whitespace
terom
parents:
328
diff
changeset
|
193 |
ROPE_COLOR_DARK |
233
ff4ecea83cf5
start using CL_ResourceManager, change most draw methods to take a Graphics*, implment even better input handling, and draw weapon names
terom
parents:
231
diff
changeset
|
194 |
); |
225 | 195 |
} |
417
c503e0c6a740
support for building without Network/Graphics, although the disable-graphics case is kind of hackish still
Tero Marttila <terom@fixme.fi>
parents:
412
diff
changeset
|
196 |
#endif |
225 | 197 |
|
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
198 |
void Rope::tick (TimeMS dt) { |
328 | 199 |
if (state == ROPE_FLYING) { |
200 |
// let PhysicsObject handle the flying stage |
|
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
201 |
PhysicsObject::tick(dt); |
322 | 202 |
|
328 | 203 |
} else if (state == ROPE_FIXED) { |
204 |
// if player's pivot is some other player, then don't re-check the terrain |
|
322 | 205 |
if (player.getPivot() != this) |
206 |
return; |
|
207 |
||
328 | 208 |
// If there's no ground on the pivot point anymore, release the rope |
428
712b943195a6
clean up PhysicsObject.hh a bit, make some things private
Tero Marttila <terom@fixme.fi>
parents:
427
diff
changeset
|
209 |
if (!world.terrain.collides(getPosition())) { |
328 | 210 |
// XXX: move to some new method |
322 | 211 |
state = ROPE_FLYING; |
212 |
length = ROPE_LENGTH; |
|
213 |
inAir = true; |
|
214 |
player.setPivot(NULL); |
|
263
8c999cf4c182
weapon projectile radiuses and fix network play (local_player == NULL, Rope releasing upon being hit
terom
parents:
257
diff
changeset
|
215 |
player.handleRopeState(state); |
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
216 |
} |
328 | 217 |
} else { // state == ROPE_FOLDED |
218 |
// ignore ticks when folded |
|
252
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
219 |
} |
25054ce94d07
Rope is released if the ground on the pivot point is destroyed.
ekku
parents:
248
diff
changeset
|
220 |
} |
328 | 221 |