summaryrefslogtreecommitdiffstats
path: root/Portal.h
blob: 3596bc228a1d129048a38e8c1cab9a21fb5e6619 (plain)
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
#ifndef PORTAL_H_
#define PORTAL_H_

#include "LevelObject.h"
#include "Polygon.h"
#include "VertexProvider.h"
#include "LevelVertex.h"
#include <math.h>


class Portal : public LevelObject, public VertexProvider {
  private:
    float width, height, thickness;
    Vertex pos;
    float orient;
    
    Vertex vertices[4];
    float s, c;
    bool connected[4];
    
    
    void updateVertices() {
      float x = width/2*c;
      float y = width/2*s;
      float ts = thickness/2*s;
      float tc = thickness/2*c;
      
      vertices[0].setLocation(pos.getX()-x-ts, pos.getY()-y+tc);
      vertices[1].setLocation(pos.getX()-x+ts, pos.getY()-y-tc);
      vertices[2].setLocation(pos.getX()+x+ts, pos.getY()+y-tc);
      vertices[3].setLocation(pos.getX()+x-ts, pos.getY()+y+tc);
    }
    
    void updateOrient() {
      s = sinf(orient);
      c = cosf(orient);
      
      updateVertices();
    }
    
    Polygon createPolygon() const {
      Polygon p;
      
      for(int i = 0; i < 4; i++)
        p.push_back(vertices[i]);
      
      return p;
    }
    
  public:
    Portal(float width, float height, float thickness) {
      this->width = width;
      this->height = height;
      this->thickness = thickness;
      
      orient = 0;
      
      for(int i = 0; i < 4; i++) {
        connected[i] = false;
      }
      
      updateOrient();
    }
    
    float getWidth() const {return width;}
    float getHeight() const {return height;}
    float getThickness() const {return thickness;}
    
    const Vertex& getPosition() const {return pos;}
    void setPosition(Vertex v) {pos = v; updateVertices();}
    
    float getOrientation() const {return orient;}
    void setOrientation(float orient) {this->orient = orient; updateOrient();}
    
    virtual std::vector<SharedPtr<LevelObject> > getChildren() {
      std::vector<SharedPtr<LevelObject> > children;
      
      for(size_t i = 0; i < 4; i++)
        children.push_back(SharedPtr<LevelObject>(new LevelVertex(this, i, this)));
      
      return children;
    }
    
    virtual bool hit(const Vertex &v) const {return createPolygon().contains(v);}
    virtual int getPriority() const {return 1;}
    
    virtual const char* getType() const {
      return "Portal";
    }
    
    virtual void move(float x, float y) {
      pos += Vertex(x, y);
      updateVertices();
    }
    
    virtual void rotate(Vertex m, float a) {
      orient = fmodf(orient+a, 2*M_PI);
      
      s = sinf(a);
      c = cosf(a);
      
      pos -= m;
      pos.setLocation(c*pos.getX() - s*pos.getY(), c*pos.getY() + s*pos.getX());
      pos += m;
      
      updateOrient();
    }
    
    virtual const Vertex* getVertex(size_t id) const {
      return &vertices[id];
    }
    
    virtual size_t getVertexCount() const {
      return 1;
    }
    
    virtual bool canMove() const {return true;}
    
    virtual void moveVertex(size_t id, float x, float y) {
      move(x, y);
    }
    
    virtual bool canRotate() const {return true;}
    
    virtual void rotateVertex(size_t id, Vertex m, float a) {
      rotate(m, a);
    }
    
    virtual bool canConnectVertex(size_t id) const {
      return !connected[id];
    }
    
    virtual void connectVertex(size_t id) {
      connected[id] = true;
    }
};

#endif /*PORTAL_H_*/