source: trunk/orbital/snake.h @ 1390

Last change on this file since 1390 was 1390, checked in by sam, 11 years ago

orbital: destroyed nodes flash when hit! except they're not hit yet.

File size: 5.5 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2012 Various People
5//
6
7/* FIXME: this file is pure crap; it's only a test. */
8
9#if !defined __SNAKE_H__
10#define __SNAKE_H__
11
12class Snake : public WorldEntity
13{
14public:
15    Snake(int nodes)
16      : m_steer(0.f),
17        m_ready(false)
18    {
19        m_head.SendCommand("sc1,1,1,1,afcb10,10,10,1,sc.9,.6,.1,1,afcb30,3,3,.8,fl");
20        m_head.SendCommand("sc1,1,1,1,afcb.4,.4,12,.4,tz3,tx8,mx,fl");
21        m_head.SendCommand("sc1,1,1,1,afcb.4,.4,12,.4,tz3,tx12,mx,fl");
22        m_head.SendCommand("sc.4,.6,.8,.6,afcb5,8,8,1,ty3,tz3,fl");
23
24        m_body.SendCommand("sc1,1,1,1,afcb6,6,12,1,sc.9,.6,.1,1,afcb3,20,3,.8,afcb20,3,3,.8,fl");
25        m_body.SendCommand("sc1,1,1,1,afcb.4,.4,7,.4,ty8,my,fl");
26        m_body.SendCommand("sc1,1,1,1,afcb.4,.4,7,.4,tx8,mx,fl");
27
28        m_tail.SendCommand("sc1,1,1,1,afcb6,6,10,1,tz-1,fl");
29        m_tail.SendCommand("sc.9,.6,.1,1,afcb3,15,3,.8,ty8,fl");
30        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,ty8,fl");
31        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,ty12,fl");
32        m_tail.SendCommand("sc.9,.6,.1,1,afcb15,3,3,.8,tx8,fl");
33        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,tx8,fl");
34        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,tx12,fl");
35
36        m_position = vec3(RandF(0.f, 100.f), 20.f, RandF(150.f, 250.f));
37        m_rotation = quat::rotate(RandF(30.f, 70.f), 0.f, 1.f, 0.f);;
38
39        /* The last node is actually the tail */
40        for (int i = 0; i < nodes; i++)
41            m_nodes.Push(m_rotation.transform(vec3(-12.f, 0.f, 0.f)),
42                         0.f, 100.f, 0.f);
43        m_nodes.Push(vec3(0.f, 0.f, 0.f), 45.f, 100.f, 0.f);
44    }
45
46    ~Snake()
47    {
48    }
49
50    char const *GetName() { return "<snake>"; }
51
52    vec3 GetBarycenter()
53    {
54        vec3 new_camera_pos = m_position;
55        for (int i = 0; i < m_nodes.Count(); i++)
56            new_camera_pos += m_nodes[i].m1;
57        new_camera_pos /= (float)(m_nodes.Count() + 1);
58
59        return new_camera_pos;
60    }
61
62protected:
63    virtual void TickGame(float seconds)
64    {
65        WorldEntity::TickGame(seconds);
66
67        m_steer += 2.f * seconds;
68
69        /* Destruction test */
70        if (m_nodes.Count() >= 3 && m_steer > 30
71             && (int)m_steer / 6 != (int)(m_steer - 2.f * seconds) / 6)
72        {
73            int tohit = (int)RandF(m_nodes.Count() - 2);
74            m_nodes[tohit + 1].m4 += 150.f;
75            m_nodes[tohit + 2].m4 += 150.f;
76        }
77
78        float test = sinf(m_steer) * 100.f + 30.f;
79        m_rotation *= quat::rotate(seconds * test, vec3(0, 1, 0));
80
81        m_velocity = 60.f * m_rotation.transform(vec3(0, 0, 1));
82        vec3 deltapos = seconds * m_velocity;
83        m_position += deltapos;
84
85        /* Remove dead nodes */
86        for (int i = m_nodes.Count(); --i; )
87        {
88            if (m_nodes[i].m3 < 0.f)
89            {
90                m_nodes[i + 1].m1 += m_nodes[i].m1;
91                m_nodes.Remove(i);
92            }
93        }
94
95        /* Regrow! FIXME: just a test */
96        if (m_nodes.Count() < 5)
97        {
98            m_nodes.Empty();
99            for (int i = 0; i < 35; i++)
100                m_nodes.Push(m_rotation.transform(vec3(-12.f, 0.f, 0.f)),
101                             0.f, 100.f, 0.f);
102            m_nodes.Push(vec3(0.f, 0.f, 0.f), 45.f, 100.f, 0.f);
103        }
104
105        for (int i = 0; i < m_nodes.Count(); i++)
106        {
107            /* The current node is dragged by the previous one */
108            vec3 new_delta = m_nodes[i].m1 - deltapos;
109            float new_distance = length(new_delta);
110            if (new_distance > 12.f)
111            {
112                new_delta /= new_distance;
113                new_distance = std::max(12.f, new_distance - seconds * 80.f);
114                new_delta *= new_distance;
115            }
116            deltapos = new_delta + deltapos - m_nodes[i].m1;
117            m_nodes[i].m1 = new_delta;
118
119            /* If the current node is not the tail, rotate */
120            if (i != m_nodes.Count() - 1)
121                m_nodes[i].m2 += seconds * ((i & 1) ? 200.f : -200.f);
122
123            /* Apply damage */
124            float damage = std::min(m_nodes[i].m4, 30.f * seconds);
125            m_nodes[i].m3 -= damage;
126            m_nodes[i].m4 -= damage;
127        }
128    }
129
130    virtual void TickDraw(float seconds)
131    {
132        WorldEntity::TickDraw(seconds);
133
134        if (!m_ready)
135        {
136            m_head.SendCommand("irb");
137            m_body.SendCommand("irb");
138            m_tail.SendCommand("irb");
139            m_ready = true;
140        }
141
142        vec3 pos = m_position;
143        quat rot = m_rotation;
144        float y_angle = 0.f;
145        mat4 model = mat4::translate(pos) * mat4(rot);
146        m_head.Render(model);
147
148        for (int i = 0; i < m_nodes.Count(); i++)
149        {
150            pos += m_nodes[i].m1;
151            y_angle = (180.f / M_PI) * atan2(m_nodes[i].m1.x, m_nodes[i].m1.z);
152            rot = quat::rotate(y_angle, 0.f, 1.f, 0.f)
153                * quat::rotate(m_nodes[i].m2, 0.f, 0.f, 1.f);
154            model = mat4::translate(pos) * mat4(rot);
155            if (i != m_nodes.Count() - 1 && m_nodes[i].m4)
156                m_body.Render(model, sin(2.f * m_nodes[i].m3) * .5f + .5f);
157            else if (i != m_nodes.Count() - 1)
158                m_body.Render(model);
159            else
160                m_tail.Render(model);
161        }
162    }
163
164private:
165    Mesh m_head, m_body, m_tail;
166    float m_steer;
167    /* List of nodes (position, self-rotation angle, life, damage) */
168    Array<vec3, float, float, float> m_nodes;
169    bool m_ready;
170};
171
172#endif /* __SNAKE_H__ */
173
Note: See TracBrowser for help on using the repository browser.