1 #ifndef SPACE_OBJECT_H
2 #define SPACE_OBJECT_H
3 
4 #include "engine.h"
5 #include "featureDefs.h"
6 #include "modelInfo.h"
7 #include "factionInfo.h"
8 #include "shipTemplate.h"
9 
10 enum EDamageType
11 {
12     DT_Energy,
13     DT_Kinetic,
14     DT_EMP
15 };
16 
17 class DamageInfo
18 {
19 public:
20     P<SpaceObject> instigator;
21     EDamageType type;
22     sf::Vector2f location;
23     int frequency;
24     ESystem system_target;
25 
DamageInfo()26     DamageInfo()
27     : instigator(), type(DT_Energy), location(0, 0), frequency(-1), system_target(SYS_None)
28     {}
29 
DamageInfo(P<SpaceObject> instigator,EDamageType type,sf::Vector2f location)30     DamageInfo(P<SpaceObject> instigator, EDamageType type, sf::Vector2f location)
31     : instigator(instigator), type(type), location(location), frequency(-1), system_target(SYS_None)
32     {}
33 };
34 
35 // Radar signature data, used by rawScannerDataOverlay.
36 class RawRadarSignatureInfo
37 {
38 public:
39     float gravity;
40     float electrical;
41     float biological;
42 
RawRadarSignatureInfo()43     RawRadarSignatureInfo()
44     : gravity(0), electrical(0), biological(0) {}
45 
RawRadarSignatureInfo(float gravity,float electrical,float biological)46     RawRadarSignatureInfo(float gravity, float electrical, float biological)
47     : gravity(gravity), electrical(electrical), biological(biological) {}
48 
49     RawRadarSignatureInfo& operator+=(const RawRadarSignatureInfo& o)
50     {
51         gravity += o.gravity;
52         electrical += o.electrical;
53         biological += o.biological;
54         return *this;
55     }
56 
57     bool operator!=(const RawRadarSignatureInfo& o)
58     {
59         return gravity != o.gravity || electrical != o.electrical || biological != o.biological;
60     }
61 
62     RawRadarSignatureInfo operator*(const float f) const
63     {
64         return RawRadarSignatureInfo(gravity * f, electrical * f, biological * f);
65     }
66 };
67 
68 enum EScannedState
69 {
70     SS_NotScanned,
71     SS_FriendOrFoeIdentified,
72     SS_SimpleScan,
73     SS_FullScan
74 };
75 
76 class SpaceObject;
77 class PlayerSpaceship;
78 extern PVector<SpaceObject> space_object_list;
79 
80 class SpaceObject : public Collisionable, public MultiplayerObject
81 {
82     float object_radius;
83     uint8_t faction_id;
84     struct
85     {
86         string not_scanned;
87         string friend_of_foe_identified;
88         string simple_scan;
89         string full_scan;
90     } object_description;
91     RawRadarSignatureInfo radar_signature;
92 
93     /*!
94      * Scan state per faction. Implementation wise, this vector is resized when
95      * a scan is done. The vector is indexed by faction ID, which means the
96      * vector can be smaller than the number of available factions.
97      * When the vector is smaller then the required faction ID, the scan state
98      * is SS_NotScanned
99      */
100     std::vector<EScannedState> scanned_by_faction;
101 public:
102     string comms_script_name;
103     ScriptSimpleCallback comms_script_callback;
104 
105     int scanning_complexity_value;
106     int scanning_depth_value;
107     string callsign;
108 
109     SpaceObject(float collisionRange, string multiplayerName, float multiplayer_significant_range=-1);
110     virtual ~SpaceObject();
111 
getRadius()112     float getRadius() { return object_radius; }
setRadius(float radius)113     void setRadius(float radius) { object_radius = radius; setCollisionRadius(radius); }
114 
hasWeight()115     bool hasWeight() { return has_weight; }
116 
117     // Return the object's raw radar signature. The default signature is 0,0,0.
getRadarSignatureInfo()118     virtual RawRadarSignatureInfo getRadarSignatureInfo() { return radar_signature; }
setRadarSignatureInfo(float grav,float elec,float bio)119     void setRadarSignatureInfo(float grav, float elec, float bio) { radar_signature = RawRadarSignatureInfo(grav, elec, bio); }
getRadarSignatureGravity()120     float getRadarSignatureGravity() { return radar_signature.gravity; }
getRadarSignatureElectrical()121     float getRadarSignatureElectrical() { return radar_signature.electrical; }
getRadarSignatureBiological()122     float getRadarSignatureBiological() { return radar_signature.biological; }
123 
getDescription(EScannedState state)124     string getDescription(EScannedState state)
125     {
126         switch(state)
127         {
128         case SS_NotScanned: return object_description.not_scanned;
129         case SS_FriendOrFoeIdentified: return object_description.friend_of_foe_identified;
130         case SS_SimpleScan: return object_description.simple_scan;
131         case SS_FullScan: return object_description.full_scan;
132         }
133         return object_description.full_scan;
134     }
135 
setDescriptionForScanState(EScannedState state,string description)136     void setDescriptionForScanState(EScannedState state, string description)
137     {
138         switch(state)
139         {
140         case SS_NotScanned: object_description.not_scanned = description; break;
141         case SS_FriendOrFoeIdentified: object_description.friend_of_foe_identified = description; break;
142         case SS_SimpleScan: object_description.simple_scan = description; break;
143         case SS_FullScan: object_description.full_scan = description; break;
144         }
145     }
setDescription(string description)146     void setDescription(string description)
147     {
148         setDescriptions(description, description);
149     }
150 
setDescriptions(string unscanned_description,string scanned_description)151     void setDescriptions(string unscanned_description, string scanned_description)
152     {
153         object_description.not_scanned = unscanned_description;
154         object_description.friend_of_foe_identified = unscanned_description;
155         object_description.simple_scan = scanned_description;
156         object_description.full_scan = scanned_description;
157     }
158 
getDescriptionFor(P<SpaceObject> obj)159     string getDescriptionFor(P<SpaceObject> obj)
160     {
161         return getDescription(getScannedStateFor(obj));
162     }
163 
getHeading()164     float getHeading() { float ret = getRotation() - 270; while(ret < 0) ret += 360.0f; while(ret > 360.0f) ret -= 360.0f; return ret; }
setHeading(float heading)165     void setHeading(float heading) { setRotation(heading - 90); }
166 
onDestroyed(ScriptSimpleCallback callback)167     void onDestroyed(ScriptSimpleCallback callback)
168     {
169         on_destroyed = callback;
170     }
171 
172     virtual void draw3D();
draw3DTransparent()173     virtual void draw3DTransparent() {}
174     virtual void drawOnRadar(sf::RenderTarget& window, sf::Vector2f position, float scale, float rotation, bool longRange);
175     virtual void drawOnGMRadar(sf::RenderTarget& window, sf::Vector2f position, float scale, float rotation, bool longRange);
176     virtual void destroy();
177 
setCallSign(string new_callsign)178     virtual void setCallSign(string new_callsign) { callsign = new_callsign; }
getCallSign()179     virtual string getCallSign() { return callsign; }
canBeDockedBy(P<SpaceObject> obj)180     virtual bool canBeDockedBy(P<SpaceObject> obj) { return false; }
canRestockMissiles()181     virtual bool canRestockMissiles() { return false; }
hasShield()182     virtual bool hasShield() { return false; }
canHideInNebula()183     virtual bool canHideInNebula() { return true; }
184     virtual bool canBeTargetedBy(P<SpaceObject> other);
185     virtual bool canBeSelectedBy(P<SpaceObject> other);
186     virtual bool canBeScannedBy(P<SpaceObject> other);
scanningComplexity(P<SpaceObject> target)187     virtual int scanningComplexity(P<SpaceObject> target) { return scanning_complexity_value; }
scanningChannelDepth(P<SpaceObject> target)188     virtual int scanningChannelDepth(P<SpaceObject> target) { return scanning_depth_value; }
189     void setScanningParameters(int complexity, int depth);
190     EScannedState getScannedStateFor(P<SpaceObject> other);
191     void setScannedStateFor(P<SpaceObject> other, EScannedState state);
192     EScannedState getScannedStateForFaction(int faction_id);
193     void setScannedStateForFaction(int faction_id, EScannedState state);
194     bool isScanned();
195     bool isScannedBy(P<SpaceObject> obj);
196     bool isScannedByFaction(string faction);
197     void setScanned(bool scanned);
198     void setScannedByFaction(string faction_name, bool scanned);
199     virtual void scannedBy(P<SpaceObject> other);
200     virtual bool canBeHackedBy(P<SpaceObject> other);
201     virtual std::vector<std::pair<ESystem, float> > getHackingTargets();
202     virtual void hackFinished(P<SpaceObject> source, string target);
takeDamage(float damage_amount,DamageInfo info)203     virtual void takeDamage(float damage_amount, DamageInfo info) {}
getGMInfo()204     virtual std::unordered_map<string, string> getGMInfo() { return std::unordered_map<string, string>(); }
getExportLine()205     virtual string getExportLine() { return ""; }
206 
207     static void damageArea(sf::Vector2f position, float blast_range, float min_damage, float max_damage, DamageInfo info, float min_range);
208 
209     bool isEnemy(P<SpaceObject> obj);
210     bool isFriendly(P<SpaceObject> obj);
setFaction(string faction_name)211     void setFaction(string faction_name) { this->faction_id = FactionInfo::findFactionId(faction_name); }
getFaction()212     string getFaction() { return factionInfo[this->faction_id]->getName(); }
getLocaleFaction()213     string getLocaleFaction() { return factionInfo[this->faction_id]->getLocaleName(); }
setFactionId(unsigned int faction_id)214     void setFactionId(unsigned int faction_id) { this->faction_id = faction_id; }
getFactionId()215     unsigned int getFactionId() { return faction_id; }
216     void setReputationPoints(float amount);
217     int getReputationPoints();
218     bool takeReputationPoints(float amount);
219     void removeReputationPoints(float amount);
220     void addReputationPoints(float amount);
setCommsScript(string script_name)221     void setCommsScript(string script_name) { this->comms_script_name = script_name; this->comms_script_callback.clear(); }
setCommsFunction(ScriptSimpleCallback callback)222     void setCommsFunction(ScriptSimpleCallback callback) { this->comms_script_name = ""; this->comms_script_callback = callback; }
223     bool areEnemiesInRange(float range);
224     PVector<SpaceObject> getObjectsInRange(float range);
225     string getSectorName();
226     bool openCommsTo(P<PlayerSpaceship> target);
227     bool sendCommsMessage(P<PlayerSpaceship> target, string message);
228 
229     ScriptSimpleCallback on_destroyed;
230 
231 protected:
232     ModelInfo model_info;
233     bool has_weight = true;
234 };
235 
236 // Define a script conversion function for the DamageInfo structure.
237 template<> void convert<DamageInfo>::param(lua_State* L, int& idx, DamageInfo& di);
238 // Function to convert a lua parameter to a scan state.
239 template<> void convert<EScannedState>::param(lua_State* L, int& idx, EScannedState& ss);
240 
241 #endif//SPACE_OBJECT_H
242