/
dsh_hud_fx.script
300 lines (279 loc) · 8.97 KB
/
dsh_hud_fx.script
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
local cur_wpn = {}
local wpn_fx = dsh_hud_fx_data.wpn_fx
local stand_power = get_float("actor_condition", "stand_power")
local time_factor = get_float("alife", "time_factor")
local nlc7_act_breath = {
[ "wht" ] = {
{ "actor\\nlc7\\without_mask_1_", 2, 1.2 },
{ "actor\\nlc7\\without_mask_2_", 2, 1.1 },
{ "actor\\nlc7\\without_mask_3_", 6, 1 },
},
[ "gas" ] = {
{ "actor\\nlc7\\gas_mask_1_", 6, 1.2 },
{ "actor\\nlc7\\gas_mask_2_", 6, 1.0 },
{ "actor\\nlc7\\gas_mask_3_", 10, 0.9 },
{ "actor\\nlc7\\gas_mask_4_", 10, 0.8 },
},
[ "exo" ] = {
{ "actor\\nlc7\\exo_mask_1_", 9, 1.7 },
{ "actor\\nlc7\\exo_mask_2_", 9, 1.5 },
{ "actor\\nlc7\\exo_mask_3_", 9, 1.3 },
{ "actor\\nlc7\\exo_mask_4_", 8, 1.1 },
},
[ "scn" ] = {
{ "actor\\nlc7\\scient_mask_1_", 2, 1.8 },
{ "actor\\nlc7\\scient_mask_2_", 2, 1.6 },
{ "actor\\nlc7\\scient_mask_3_", 2, 1.4 },
{ "actor\\nlc7\\scient_mask_4_", 6, 1.2 },
},
}
local time_distortion = 0
local breath_rnd = 1
local breath_size = 0
local function start_breath_distortion(min, max)
if breath_distortion_timer then
breath_distortion_timer:stop()
breath_distortion_timer = nil
end
breath_distortion_timer = dsh.wait_condition(
function()
min = min > max and min - 100 or min + 100
breath_size = min
shader_set_custom_param("breath_size", game_options.opt_breath and min / 10000 or 0.0)
shader_set_custom_param("breath_idx", breath_rnd)
return min == max
end,
function()
breath_distortion_timer = nil
end,
function()
ogsr_signals.get_mgr():reschedule(time_distortion)
end)
end
function attach(sm)
sm:subscribe({signal = "on_actor_weapon_fire", fun = this.on_actor_weapon_fire})
sm:subscribe({signal = "on_update", fun = this.on_update_heart})
end
local cur_wpn = {}
function get_wpn_info(wpn)
local t = cur_wpn
if (not t.name) or t.name ~= wpn:name() then
t.const_dev_t = 0
t.dispersion_start = get_u32(wpn:section(), "dispersion_start")
t.fire_power_loss = get_fire_power_loss(wpn)
t.hit_power = get_float(wpn:section(), "hit_power")
t.hit_power_2 = get_float(wpn:section(), "hit_power_2")
t.id = wpn:id()
t.inv_weight = get_float(wpn:section(), "inv_weight", 0)
t.is_knife = wpn:is_knife()
t.name = wpn:name()
t.zoom_body_state = "unknown"
t.zoom_enabled = get_bool(wpn:section(), "zoom_enabled", true)
end
t.wpn = wpn
return cur_wpn
end
function get_fire_power_loss(wpn)
local sect = wpn:section()
local fire_power_loss_k = get_float(sect, "dsh_wpn.fire_power_loss_k", 1)
return stand_power * time_factor * fire_power_loss_k
end
local cached_wpn = {}
function get_wpn_params(sect)
if not cached_wpn[sect] then
local t = {}
t.wpn_fx = get_string(sect, "dsh_hud_fx.wpn_fx")
t.wpn_fx_creep = get_string(sect, "dsh_hud_fx.wpn_fx_creep")
cached_wpn[sect] = t
end
return cached_wpn[sect]
end
function on_actor_weapon_fire(wpn)
local cur_wpn = get_wpn_info(wpn)
local shot_n = wpn:is_weapon_magazined() and wpn:get_weapon_m().shot_num or 1
if cur_wpn.dispersion_start then
local qs = ogse_wpn_utils.get_queue_size(wpn)
if qs < 0 or qs >= cur_wpn.dispersion_start then
if shot_n < cur_wpn.dispersion_start then
return
end
end
end
local params
if cur_wpn.gl_mode then
if cur_wpn.gl_name then
params = get_wpn_params(cur_wpn.gl_name)
else
return
end
else
params = get_wpn_params(wpn:section())
end
local aobj = get_actor_obj()
local sect
if aobj:is_actor_creep() then
sect = params.wpn_fx_creep or params.wpn_fx
else
sect = params.wpn_fx
end
if not wpn_fx[sect] then
return
end
local anims = {}
local s = wpn_fx[sect].s
local sc = table.getn(s)
if sc > 1 then
if wpn_fx[sect].r == 1 then
s = s[math.random(table.getn(s))]
elseif wpn_fx[sect].r == 2 then
if shot_n == 1 then
s = s[1]
else
s = s[math.random(2, table.getn(s))]
end
else
sc = (shot_n <= sc) and shot_n or (sc > 2 and math.random(sc - 1, sc)) or sc
s = s[sc]
end
else
s = s[1]
end
local ammo_r = 1
local fov_r = ammo_r * (db.actor:zoom_mode() and 0.13 or 1)
for i, v in ipairs(wpn_fx[sect].e) do
cnt, r = math.modf(v[1] * fov_r)
if r ~= 0 and cnt > 4 then -- fmb
cnt = cnt - cnt * math.random(0, r * 100) / 100 -- fmb
cnt, r = math.modf(cnt)
end
if r ~= 0 and math.random() < r then
cnt = cnt + 1
end
if cnt > 0 then
table.insert(anims, {
e = i,
d = v[2] or math.random(0, 1),
c = cnt
})
end
end
for i, a in ipairs(anims) do
local n = string.format([[shoot\s%s_e%s_%s.anm]], s, a.e, a.d)
for ii = 1, a.c do
game.play_hud_anm(n, 2, 1, 1, false, true)
level.add_cam_effector(n, math.random(5000, 8000), false, "")
end
end
for k, v in pairs(wpn_fx[sect].p) do
local n = string.format([[shoot\%s_s%s.ppe]], k, s)
local eid = math.random(1500, 3000)
level.add_pp_effector(n, eid, false)
if v > 0 then
level.set_pp_effector_factor(eid, v)
end
end
end
local delt = 0
local deltsh = 0
local delt_h = 0
local breath_double
function nlc7_actor_heart()
local npc = db.actor
if not npc then
return
end
local hb = npc.health
if hb <= 0 or not npc:alive() then
return
end
local time_curr = time_global()
local time_delt = 0
local step = 1
if hb < 0.3 then
time_delt = time_curr - delt_h
if time_delt >= math.log(hb * 200) * 200 then
if hb < 0.05 then
step = 3
elseif hb < 0.15 then
step = 2
else
step = 1
end
local snd_fname = "actor\\nlc7\\heartbeat_" .. step .. "_" .. math.random(4)
local snd = sound_object(snd_fname)
snd.volume = 1.5 - 5 * hb
snd:play(db.actor, 0, sound_object.s2d)
delt_h = time_curr
end
end
local r_h = npc.power
local tip = "wht"
local outfit = db.actor:item_in_slot(6)
if outfit then
local outfitname = outfit:section()
local intensity = get_string(outfitname, "intensity")
if intensity == "0.3" then
tip = "gas"
elseif intensity == "0.5" or intensity == "0.6" then
tip = "exo"
elseif intensity == "0.75" then
tip = "scn"
else
tip = "wht"
end
end
if tip ~= "wht" then
if r_h < 0.25 then
step = 4
elseif r_h < 0.5 then
step = 3
elseif r_h < 0.85 then
step = 2
else
step = 1
end
time_delt = time_curr - delt
if time_delt >= r_h * 1500 + 800 then
delt = time_curr
time_distortion = (r_h * 1500 + 800) * 0.001
start_breath_distortion(breath_size, 6000 + (1000 - (1000 * r_h)))
breath_double = true
breath_rnd = math.random(0, 10)
local snd_fname = nlc7_act_breath[tip][step][1] .. math.random(nlc7_act_breath[tip][step][2])
local snd = xr_sound.get_safe_sound_object(snd_fname)
snd.volume = 2.5 - nlc7_act_breath[tip][step][3] - r_h
snd:play(db.actor, 0, sound_object.s2d)
delt = time_curr
elseif time_delt >= (r_h * 1500 + 600) * (0.4 / step) + step * 90 and breath_double then
time_distortion = (1.5 * 1500 + 700) * 0.012
start_breath_distortion(breath_size, 0)
breath_double = false
end
else
if r_h < 0.79 then
time_delt = time_curr - delt
if time_delt >= r_h * 1500 + 800 then
if r_h < 0.25 then
step = 3
elseif r_h < 0.5 then
step = 2
else
step = 1
end
local snd_fname = nlc7_act_breath[tip][step][1] .. math.random(nlc7_act_breath[tip][step][2])
local snd = xr_sound.get_safe_sound_object(snd_fname)
snd.volume = 2.5 - nlc7_act_breath[tip][step][3] - r_h
snd:play(db.actor, 0, sound_object.s2d)
delt = time_curr
cmd("breath_size", 0)
end
end
end
end
function on_update_heart()
ogsr_signals.get_mgr():reschedule(113)
if not db.actor:alive() then
return
end
nlc7_actor_heart()
end