1 #include "warpJammer.h"
2 #include "playerInfo.h"
3 #include "spaceObjects/playerSpaceship.h"
4 #include "explosionEffect.h"
5 #include "main.h"
6 
7 #include "scriptInterface.h"
8 
9 /// A warp jammer.
REGISTER_SCRIPT_SUBCLASS(WarpJammer,SpaceObject)10 REGISTER_SCRIPT_SUBCLASS(WarpJammer, SpaceObject)
11 {
12     REGISTER_SCRIPT_CLASS_FUNCTION(WarpJammer, setRange);
13     /// Set a function that will be called if the warp jammer is taking damage.
14     /// First argument given to the function will be the warp jammer, the second the instigator SpaceObject (or nil).
15     REGISTER_SCRIPT_CLASS_FUNCTION(WarpJammer, onTakingDamage);
16     /// Set a function that will be called if the warp jammer is destroyed by taking damage.
17     /// First argument given to the function will be the warp jammer, the second the instigator SpaceObject that gave the final blow (or nil).
18     REGISTER_SCRIPT_CLASS_FUNCTION(WarpJammer, onDestruction);
19 }
20 
21 REGISTER_MULTIPLAYER_CLASS(WarpJammer, "WarpJammer");
22 
23 PVector<WarpJammer> WarpJammer::jammer_list;
24 
WarpJammer()25 WarpJammer::WarpJammer()
26 : SpaceObject(100, "WarpJammer")
27 {
28     range = 7000.0;
29     hull = 50;
30 
31     jammer_list.push_back(this);
32     setRadarSignatureInfo(0.05, 0.5, 0.0);
33 
34     registerMemberReplication(&range);
35 
36     model_info.setData("shield_generator");
37 }
38 
39 // Due to a suspected compiler bug this desconstructor needs to be explicity defined
~WarpJammer()40 WarpJammer::~WarpJammer()
41 {
42 }
43 
drawOnRadar(sf::RenderTarget & window,sf::Vector2f position,float scale,float rotation,bool long_range)44 void WarpJammer::drawOnRadar(sf::RenderTarget& window, sf::Vector2f position, float scale, float rotation, bool long_range)
45 {
46     sf::Sprite object_sprite;
47     textureManager.setTexture(object_sprite, "RadarBlip.png");
48     object_sprite.setRotation(getRotation());
49     object_sprite.setPosition(position);
50     if (my_spaceship && my_spaceship->isEnemy(this))
51         object_sprite.setColor(sf::Color(255, 0, 0));
52     else
53         object_sprite.setColor(sf::Color(200, 150, 100));
54     float size = 0.6;
55     object_sprite.setScale(size, size);
56     window.draw(object_sprite);
57 
58     if (long_range)
59     {
60         sf::CircleShape range_circle(range * scale);
61         range_circle.setOrigin(range * scale, range * scale);
62         range_circle.setPosition(position);
63         range_circle.setFillColor(sf::Color::Transparent);
64         if (my_spaceship && my_spaceship->isEnemy(this))
65             range_circle.setOutlineColor(sf::Color(255, 0, 0, 64));
66         else
67             range_circle.setOutlineColor(sf::Color(200, 150, 100, 64));
68         range_circle.setOutlineThickness(2.0);
69         window.draw(range_circle);
70     }
71 }
72 
takeDamage(float damage_amount,DamageInfo info)73 void WarpJammer::takeDamage(float damage_amount, DamageInfo info)
74 {
75     if (info.type == DT_EMP)
76         return;
77     hull -= damage_amount;
78     if (hull <= 0)
79     {
80         P<ExplosionEffect> e = new ExplosionEffect();
81         e->setSize(getRadius());
82         e->setPosition(getPosition());
83         e->setRadarSignatureInfo(0.5, 0.5, 0.1);
84 
85         if (on_destruction.isSet())
86         {
87             if (info.instigator)
88             {
89                 on_destruction.call<void>(P<WarpJammer>(this), P<SpaceObject>(info.instigator));
90             } else {
91                 on_destruction.call<void>(P<WarpJammer>(this));
92             }
93         }
94 
95         destroy();
96     } else {
97         if (on_taking_damage.isSet())
98         {
99             if (info.instigator)
100             {
101                 on_taking_damage.call<void>(P<WarpJammer>(this), P<SpaceObject>(info.instigator));
102             } else {
103                 on_taking_damage.call<void>(P<WarpJammer>(this));
104             }
105         }
106     }
107 }
108 
isWarpJammed(sf::Vector2f position)109 bool WarpJammer::isWarpJammed(sf::Vector2f position)
110 {
111     foreach(WarpJammer, wj, jammer_list)
112     {
113         if (wj->getPosition() - position < wj->range)
114             return true;
115     }
116     return false;
117 }
118 
getFirstNoneJammedPosition(sf::Vector2f start,sf::Vector2f end)119 sf::Vector2f WarpJammer::getFirstNoneJammedPosition(sf::Vector2f start, sf::Vector2f end)
120 {
121     sf::Vector2f startEndDiff = end - start;
122     float startEndLength = sf::length(startEndDiff);
123     P<WarpJammer> first_jammer;
124     float first_jammer_f = startEndLength;
125     sf::Vector2f first_jammer_q;
126     foreach(WarpJammer, wj, jammer_list)
127     {
128         float f = sf::dot(startEndDiff, wj->getPosition() - start) / startEndLength;
129         if (f < 0.0)
130             f = 0;
131         sf::Vector2f q = start + startEndDiff / startEndLength * f;
132         if ((q - wj->getPosition()) < wj->range)
133         {
134             if (!first_jammer || f < first_jammer_f)
135             {
136                 first_jammer = wj;
137                 first_jammer_f = f;
138                 first_jammer_q = q;
139             }
140         }
141     }
142     if (!first_jammer)
143         return end;
144 
145     float d = sf::length(first_jammer_q - first_jammer->getPosition());
146     return first_jammer_q + sf::normalize(start - end) * sqrtf(first_jammer->range * first_jammer->range - d * d);
147 }
148 
onTakingDamage(ScriptSimpleCallback callback)149 void WarpJammer::onTakingDamage(ScriptSimpleCallback callback)
150 {
151     this->on_taking_damage = callback;
152 }
153 
onDestruction(ScriptSimpleCallback callback)154 void WarpJammer::onDestruction(ScriptSimpleCallback callback)
155 {
156     this->on_destruction = callback;
157 }
158 
getExportLine()159 string WarpJammer::getExportLine()
160 {
161     string ret = "WarpJammer():setFaction(\"" + getFaction() + "\"):setPosition(" + string(getPosition().x, 0) + ", " + string(getPosition().y, 0) + ")";
162     if (getRange()!=7000.0) {
163 	    ret += ":setRange("+string(getRange())+")";
164     }
165     return ret;
166 }
167