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