File: skel.lua

package info (click to toggle)
naev 0.8.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 386,084 kB
  • sloc: ansic: 93,149; xml: 87,292; python: 2,347; sh: 904; makefile: 654; lisp: 162; awk: 4
file content (252 lines) | stat: -rw-r--r-- 7,308 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
--[[
   Simple skeleton for your standard faction. This is more or less what the
   standard behaviour can be, but from here you can let your imagination go
   wild.
--]]

-- Faction caps.
_fcap_kill       = 20 -- Kill cap
_fdelta_distress = {-1, 0} -- Maximum change constraints
_fdelta_kill     = {-5, 1} -- Maximum change constraints
_fcap_misn       = 30 -- Starting mission cap, gets overwritten
_fcap_misn_var   = nil -- Mission variable to use for limits

-- Secondary hit modifiers.
_fmod_distress_enemy  = 0 -- Distress of the faction's enemies
_fmod_distress_friend = 0.3 -- Distress of the faction's allies
_fmod_kill_enemy      = 0.3 -- Kills of the faction's enemies
_fmod_kill_friend     = 0.3 -- Kills of the faction's allies
_fmod_misn_enemy      = 0.3 -- Missions done for the faction's enemies
_fmod_misn_friend     = 0.3 -- Missions done for the faction's allies

_fstanding_friendly = 70
_fstanding_neutral = 0


_ftext_standing = {}
_ftext_standing[100] = _("Legend")
_ftext_standing[90]  = _("Hero")
_ftext_standing[70]  = _("Comrade")
_ftext_standing[50]  = _("Ally")
_ftext_standing[30]  = _("Partner")
_ftext_standing[10]  = _("Associate")
_ftext_standing[0]   = _("Neutral")
_ftext_standing[-1]  = _("Outlaw")
_ftext_standing[-30] = _("Criminal")
_ftext_standing[-50] = _("Enemy")

_ftext_friendly = _("Friendly")
_ftext_neutral  = _("Neutral")
_ftext_hostile  = _("Hostile")
_ftext_bribed   = _("Bribed")


--[[
   @brief Clamps a value x between low and high.
--]]
function clamp( low, high, x )
   return math.max( low, math.min( high, x ) )
end


--[[
   @brief Linearly interpolates x between x1,y1 and x2,y2
--]]
function lerp( x, x1, y1, x2, y2 )
   local m = (y1-y2)/(x1-x2)
   local b = y1-m*x1
   return m*x + b
end


--[[
   @brief Same as lerp but clamps to [0,1].
--]]
function clerp( x, x1, y1, x2, y2 )
   return clamp( 0, 1, lerp( x, x1, y1, x2, y2 ) )
end


--[[
   @brief Duplicates a table to avoid clobbering.
--]]
function clone(t)
   local new = {}
   for k, v in pairs(t) do
      new[k] = v
   end
   return new
end


--[[
   @brief Handles a faction hit for a faction.

   Possible sources:
    - "kill" : Pilot death.
    - "distress" : Pilot distress signal.
    - "script" : Either a mission or an event.

      @param current Current faction player has.
      @param amount Amount of faction being changed.
      @param source Source of the faction hit.
      @param secondary Flag that indicates whether this is a secondary (through ally or enemy) hit.
      @return The faction amount to set to.
--]]
function default_hit( current, amount, source, secondary )
   -- Comfort macro
   local f = current
   local delta = {-200, 200}

   -- Set caps and/or deltas based on source
   local cap
   local mod = 1
   if source == "distress" then
      cap   = _fcap_kill
      delta = clone(_fdelta_distress)

      -- Adjust for secondary hit
      if secondary then
         if amount > 0 then
            mod = mod * _fmod_distress_enemy
         else
            mod = mod * _fmod_distress_friend
         end
      end
   elseif source == "kill" then
      cap   = _fcap_kill
      delta = clone(_fdelta_kill)

      -- Adjust for secondary hit
      if secondary then
         if amount > 0 then
            mod = mod * _fmod_kill_enemy
         else
            mod = mod * _fmod_kill_friend
         end
      end
   else
      if _fcap_misn_var == nil then
         cap   = _fcap_misn
      else
         cap   = var.peek( _fcap_misn_var )
         if cap == nil then
            cap = _fcap_misn
            var.push( _fcap_misn_var, cap )
         end
      end

      -- Adjust for secondary hit
      if secondary then
         if amount > 0 then
            mod = mod * _fmod_misn_friend
         else
            mod = mod * _fmod_misn_enemy
         end
      end
   end

   amount = mod * amount
   delta[1] = mod * delta[1]
   delta[2] = mod * delta[2]

   -- Faction gain
   if amount > 0 then
      -- Must be under cap
      if f < cap then
         if source == "kill" then
            local has_planet
            -- Positive kill, which means an enemy of this faction got killed.
            -- We need to check if this happened in the faction's territory, otherwise it doesn't count.
            -- NOTE: virtual assets are NOT counted when determining territory!
            for _, planet in ipairs(system.cur():planets()) do
                if planet:faction() == _fthis then
                   -- Planet belonging to this faction found. Modify reputation.
                   f = math.min( cap, f + math.min(delta[2], amount * clerp( f, 0, 1, cap, 0.2 )) )
                   has_planet = true
                   break
                end
            end
            local witness = pilot.get( { _fthis } )
            if not has_planet and witness then
               for _, pilot in ipairs(witness) do
                  if player.pos():dist( pilot:pos() ) < 5000 then
                     -- Halve impact relative to a normal secondary hit.
                     f = math.min( cap, f + math.min(delta[2], amount * 0.5 * clerp( f, 0, 1, cap, 0.2 )) )
                     break
                  end
               end
            end
         else
            -- Script induced change. No diminishing returns on these.
            f = math.min( cap, f + math.min(delta[2], amount) )
         end
      end
   -- Faction loss.
   else
      -- No diminishing returns on loss.
      f = math.max( -100, f + math.max(delta[1], amount) )
   end
   return f
end


--[[
   @brief Returns a text representation of the player's standing.

      @param standing Current standing of the player.
      @return The text representation of the current standing.
--]]
function faction_standing_text( standing )
   for i = math.floor( standing ), 0, ( standing < 0 and 1 or -1 ) do
      if _ftext_standing[i] ~= nil then
         return _ftext_standing[i]
      end
   end
   return _ftext_standing[0]
end


--[[
   @brief Returns whether or not the player is a friend of the faction.

      @param standing Current standing of the player.
      @return true if the player is a friend, false otherwise.
--]]
function faction_player_friend( standing )
   return standing >= _fstanding_friendly
end


--[[
   @brief Returns whether or not the player is an enemy of the faction.

      @param standing Current standing of the player.
      @return true if the player is an enemy, false otherwise.
--]]
function faction_player_enemy( standing )
   return standing < _fstanding_neutral
end


--[[
   @brief Returns a text representation of the player's broad standing.

      @param standing Current standing of the player.
      @param bribed Whether or not the respective pilot is bribed.
      @param override If positive it should be set to ally, if negative it should be set to hostile.
      @return The text representation of the current broad standing.
--]]
function faction_standing_broad( standing, bribed, override )
   if override == nil then override = 0 end

   if bribed then
      return _ftext_bribed
   elseif override > 0 or faction_player_friend( standing ) then
      return _ftext_friendly
   elseif override < 0 or faction_player_enemy( standing ) then
      return _ftext_hostile
   else
      return _ftext_neutral
   end
end