1 #include "main.h"
2 #include "zone.h"
3 #include "playerInfo.h"
4 #include "particleEffect.h"
5 #include "explosionEffect.h"
6 #include "pathPlanner.h"
7 
8 #include "math/triangulate.h"
9 #include "math/centerOfMass.h"
10 
11 #include "scriptInterface.h"
12 
13 /// A zone area
REGISTER_SCRIPT_SUBCLASS(Zone,SpaceObject)14 REGISTER_SCRIPT_SUBCLASS(Zone, SpaceObject)
15 {
16     /// Set corners of n-gon to x_1, y_1, x_2, y_2, ..., x_n, y_n.
17     /// Recall that x goes right and y goes down.
18     /// Example: zone = Zone():setPoints(2000, 0, 0, 3000, -2000, 0)
19     REGISTER_SCRIPT_CLASS_FUNCTION(Zone, setPoints);
20     /// Example: zone:setColor(255, 140, 0)
21     REGISTER_SCRIPT_CLASS_FUNCTION(Zone, setColor);
22     REGISTER_SCRIPT_CLASS_FUNCTION(Zone, setLabel);
23     REGISTER_SCRIPT_CLASS_FUNCTION(Zone, getLabel);
24     REGISTER_SCRIPT_CLASS_FUNCTION(Zone, isInside);
25 }
26 
27 REGISTER_MULTIPLAYER_CLASS(Zone, "Zone");
Zone()28 Zone::Zone()
29 : SpaceObject(1, "Zone")
30 {
31     has_weight = false;
32     color = sf::Color(255, 255, 255, 0);
33 
34     registerMemberReplication(&outline);
35     registerMemberReplication(&triangles);
36     registerMemberReplication(&color);
37     registerMemberReplication(&label);
38 }
39 
drawOnRadar(sf::RenderTarget & window,sf::Vector2f position,float scale,float rotation,bool long_range)40 void Zone::drawOnRadar(sf::RenderTarget& window, sf::Vector2f position, float scale, float rotation, bool long_range)
41 {
42     if (!long_range || color.a == 0)
43         return;
44 
45     sf::VertexArray outline_array(sf::LinesStrip, outline.size() + 1);
46     sf::VertexArray triangle_array(sf::Triangles, triangles.size());
47     for(unsigned int n=0; n<outline.size() + 1; n++)
48     {
49         outline_array[n].position = position + sf::rotateVector(outline[n % outline.size()] * scale, -rotation);
50         outline_array[n].color = color;
51         outline_array[n].color.a = 128;
52     }
53     for(unsigned int n=0; n<triangles.size(); n++)
54     {
55         triangle_array[n].position = position + sf::rotateVector(triangles[n] * scale, -rotation);
56         triangle_array[n].color = color;
57         triangle_array[n].color.a = 64;
58     }
59     window.draw(triangle_array);
60     window.draw(outline_array);
61 
62     if (label.length() > 0)
63     {
64         int font_size = getRadius() * scale / label.length();
65         sf::Text text_element(label, *main_font, font_size);
66 
67         float x = position.x - text_element.getLocalBounds().width / 2.0 - text_element.getLocalBounds().left;
68         float y = position.y - font_size + font_size * 0.35;
69 
70         text_element.setPosition(x, y);
71         text_element.setColor(sf::Color(color.r, color.g, color.b, 128));
72         window.draw(text_element);
73     }
74 }
75 
drawOnGMRadar(sf::RenderTarget & window,sf::Vector2f position,float scale,float rotation,bool long_range)76 void Zone::drawOnGMRadar(sf::RenderTarget& window, sf::Vector2f position, float scale, float rotation, bool long_range)
77 {
78     if (long_range && color.a == 0)
79     {
80         color.a = 255;
81         drawOnRadar(window, position, scale, rotation, long_range);
82         color.a = 0;
83     }
84 }
85 
setColor(int r,int g,int b)86 void Zone::setColor(int r, int g, int b)
87 {
88     color = sf::Color(r, g, b);
89 }
90 
setPoints(std::vector<sf::Vector2f> points)91 void Zone::setPoints(std::vector<sf::Vector2f> points)
92 {
93     triangles.clear();
94 
95     sf::Vector2f position = centerOfMass(points);
96     float radius = 1;
97     for(auto& p : points)
98     {
99         p -= position;
100         radius = std::max(radius, sf::length(p));
101     }
102 
103     outline = points;
104     Triangulate<float>::process(points, triangles);
105 
106     setPosition(position);
107     setRadius(radius);
108     setCollisionRadius(1);
109 }
110 
setLabel(string label)111 void Zone::setLabel(string label)
112 {
113     this->label = label;
114 }
115 
getLabel()116 string Zone::getLabel()
117 {
118     return this->label;
119 }
120 
isInside(P<SpaceObject> obj)121 bool Zone::isInside(P<SpaceObject> obj)
122 {
123     if (!obj)
124         return false;
125     return insidePolygon(outline, obj->getPosition() - getPosition());
126 }
127