-
Notifications
You must be signed in to change notification settings - Fork 1
/
Hook.cpp
111 lines (99 loc) · 3.27 KB
/
Hook.cpp
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
#include "Hook.h"
#include "config.h"
#include "util.h"
#include "Mine.h"
#include <string>
#include <algorithm>
extern std::vector<GameObject*> allRenderObjects;
void Hook::pull() {
pulling = true;
}
extern std::vector<Player*> allPlayers;
extern std::vector<Mine*> allMines;
extern GameObject* referenceHook;
extern GameObject* referenceGrapple;
Hook::Hook(int playerNumber, glm::vec3 origin, float dir, PointLight* p, bool grapple)
: GameObject(*referenceHook) {
if(grapple) {
mModel = referenceGrapple->mModel;
}
grappling = grapple;
owner = playerNumber;
mModel.position = origin;
vel = HOOK_SPEED * glm::normalize(glm::vec3(sin(dir), 0, cos(dir)));
collided = 5;
prev = NULL;
pulling = false;
pulled = NULL;
mModel.rotation.y = dir + HOOK_BASE_ROTATION;
mModel.scaling = glm::vec3(HOOK_SCALING, HOOK_SCALING, HOOK_SCALING);
radius = HOOK_RADIUS;
allRenderObjects.push_back(this);
sight = p;
sight->position = mModel.position;
sight->position.y += 0.1f;
}
void Hook::update() {
if (pulling) {
if (!grappling) {
// pull
glm::vec3 follow;
glm::vec3 dif;
if (prev != NULL) {
follow = prev->mModel.position;
} else {
follow = allPlayers[owner]->hookpoint;
}
dif = moveTowards(mModel.position, follow, CHAIN_BASE_PULL) - mModel.position;
mModel.position += dif;
mModel.rotation.y = glm::atan(dif.x, dif.z) + HOOK_BASE_ROTATION + glm::pi<float>();
if(pulled != NULL){
if( std::find(allMines.begin(), allMines.end(), pulled) == allMines.end() || ((Mine*)pulled)->exists) {
pulled->mModel.position = mModel.position;
}
}
}
} else {
// push
glm::vec3 normal = circleCollision(mModel.position, radius, 8.0f, false, false, allPlayers[owner]);
if (collided == 0 && glm::length(normal) != 0.0f) {
if(grappling) {
// grapple
allPlayers[owner]->pull();
} else {
// reflect
vel = HOOK_SPEED * glm::normalize(glm::reflect(vel, glm::normalize(normal)));
mModel.rotation.y = glm::atan(vel.x, vel.z) + HOOK_BASE_ROTATION;
collided = 3;
}
} else {
// just keep going
mModel.position += vel;
collided = std::max(0, collided - 1);
}
}
// check for hits
if (!grappling && pulled == NULL){
// did we hit a player?
for (Player* p : allPlayers) {
if (p->playerNumber != owner && isColliding(*this, *p) && !p->isHit()) {
pulled = p;
p->hit();
allPlayers[owner]->pull();
}
}
// did we hit a mine?
for (Mine* m : allMines) {
if (isColliding(*this, *m)) {
pulled = m;
allPlayers[owner]->pull();
}
}
}
sight->position = mModel.position;
sight->position.y += 0.1f;
}
void Hook::kill() {
allRenderObjects.erase(std::remove(allRenderObjects.begin(), allRenderObjects.end(), this), allRenderObjects.end());
delete this;
}