-
Notifications
You must be signed in to change notification settings - Fork 9
/
pbem_msgs.lua
628 lines (574 loc) · 20.7 KB
/
pbem_msgs.lua
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
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
--[[
----------------------------------------------
IKE
pbem_msgs.lua
----------------------------------------------
Contains definitions for functions that deal with
storing turn/side info in special messages.
----------------------------------------------
]]--
function PBEM_SetContactRegister(sidenum, contacts)
StoreString("__SIDE_"..tostring(sidenum)..'_CONTACTS', contacts)
end
function PBEM_GetContactRegister(sidenum)
return string.sub(GetString("__SIDE_"..tostring(sidenum)..'_CONTACTS'), 0)
end
function PBEM_SetKillRegister(sidenum, kills)
StoreString("__SIDE_"..tostring(sidenum)..'_KILLS', kills)
end
function PBEM_GetKillRegister(sidenum)
return string.sub(GetString("__SIDE_"..tostring(sidenum)..'_KILLS'), 0)
end
function PBEM_SetLossRegister(sidenum, kills)
StoreString("__SIDE_"..tostring(sidenum)..'_LOSSES', kills)
end
function PBEM_GetLossRegister(sidenum)
return string.sub(GetString("__SIDE_"..tostring(sidenum)..'_LOSSES'), 0)
end
function PBEM_GetDamageRegister(sidenum)
return string.sub(GetString("__SIDE_"..tostring(sidenum)..'_DAMAGES'), 0)
end
function PBEM_SetDamageRegister(sidenum, damages)
StoreString("__SIDE_"..tostring(sidenum)..'_DAMAGES', damages)
end
function PBEM_GetHitRegister(sidenum)
return string.sub(GetString("__SIDE_"..tostring(sidenum)..'_HITS'), 0)
end
function PBEM_SetHitRegister(sidenum, hits)
StoreString("__SIDE_"..tostring(sidenum)..'_HITS', hits)
end
function PBEM_GetFratricideRegister(sidenum)
return string.sub(GetString("__SIDE_"..tostring(sidenum)..'_FRAT'), 0)
end
function PBEM_SetFratricideRegister(sidenum, hits)
StoreString("__SIDE_"..tostring(sidenum)..'_FRAT', hits)
end
function Message_Header(text)
return '<br/><hr><br/><center><b>'..text..'</b></center><br/><hr><br/>'
end
function PBEM_RegisterNewContact()
local contact = ScenEdit_UnitC()
local detector = ScenEdit_UnitY()
local contacttime = PBEM_CurrentTimeMilitary()
if not contact then
return
end
local contactname = contact.name
local function __RegisterContactForSide(d_side)
if d_side ~= Turn_GetCurSideName() then
local actual_unit = ScenEdit_GetUnit({
guid=contact.actualunitid
})
if not actual_unit then
return
end
-- do not notify if unit is on our side, or on allied side
-- to avoid contact spam
local is_allied_unit = false
if actual_unit.side == d_side then
is_allied_unit = true
else
local posture_to = ScenEdit_GetSidePosture(
actual_unit.side,
d_side
)
local posture_from = ScenEdit_GetSidePosture(
d_side,
actual_unit.side
)
is_allied_unit = (posture_to == "F" or posture_from == "F")
end
if is_allied_unit == true then
return
end
local sidenum = PBEM_SideNumberByName(d_side)
local contacts = PBEM_GetContactRegister(sidenum)
local detection_data = ""
if detector then
local detector_unit = detector.unit
if detector_unit then
detection_data = Format(
LocalizeForSide(
d_side,
"DETECTED_MARKER"
),
{
contactname,
detector_unit.name
}
)
end
end
contacts = contacts.."<i>"..contacttime.."</i> // "..detection_data.."<br/>"
PBEM_SetContactRegister(sidenum, contacts)
--mark contact on the map
if PBEM_GetPreferenceForSide(
d_side,
"EVENT_MARK_RP"
) then
local rp = ScenEdit_AddReferencePoint({
side=d_side,
name=Format(
LocalizeForSide(
d_side,
"CONTACT_MARKER"
),
{
contactname,
contacttime
}
),
lat=contact.latitude,
lon=contact.longitude,
highlighted=true
})
PBEM_RegisterEventRPWithSide(
d_side,
rp
)
end
end
end
local detecting_side = contact.fromside.name
if IsIn(detecting_side, PBEM_PLAYABLE_SIDES) then
-- report it if we're a playable side
__RegisterContactForSide(detecting_side)
end
-- report to any allied players if they exist
for _, sidecheck in ipairs(PBEM_PLAYABLE_SIDES) do
if sidecheck ~= detecting_side then
local posture = ScenEdit_GetSidePosture(
detecting_side,
sidecheck
)
if posture == "F" then
__RegisterContactForSide(sidecheck)
end
end
end
end
PBEM_WEAPON_CODES = {
[2001] = "ID_GUIDEDWEAP",
[2002] = "ID_ROCKET",
[2003] = "ID_BOMB",
[2004] = "ID_GUNS",
[2010] = "ID_SUICIDEBOMB",
[2011] = "ID_SABOTAGEBOMB",
[2012] = "ID_GUIDEDPROJ",
[4001] = "ID_TORPEDO",
[4002] = "ID_DEPTHCHARGE",
[4004] = "ID_MINE",
[4005] = "ID_MINE",
[4006] = "ID_MINE",
[4007] = "ID_MINE",
[4008] = "ID_MINE",
[4009] = "ID_MINE",
[4011] = "ID_MINE",
[6001] = "ID_LASER"
}
function PBEM_KnownWeaponName(weapon_unit, detecting_side)
-- determine the name of the weapon by how much is known about it
local detecting_side_guid = SideGUIDByName(detecting_side)
local weap_name = LocalizeForSide(detecting_side, "UNKNOWN_WEAPON")
if weapon_unit then
-- find generic name of weapon
local subtype = tonumber(weapon_unit.subtype)
if subtype then
local weap_locale_id = PBEM_WEAPON_CODES[subtype]
if weap_locale_id then
weap_name = LocalizeForSide(detecting_side, weap_locale_id)
end
end
-- see if we have enough info to get more specific
for k, contact in ipairs(weapon_unit.ascontact) do
if contact.side == detecting_side_guid then
local success, con = pcall(
ScenEdit_GetContact,
{
side=detecting_side,
guid=contact.guid
}
)
if con then
if tonumber(con.classificationlevel) >= 3 then
weap_name = weapon_unit.classname
end
end
break
end
end
end
return weap_name
end
function PBEM_RegisterUnitDamaged()
local damaged = ScenEdit_UnitX()
local damager = ScenEdit_UnitY()
local damage_time = PBEM_CurrentTimeMilitary()
local damager_unit = nil
local damager_side = ""
local damager_side_guid = ""
local dguid = string.upper(damaged.guid)
if damager then
if damager.unit then
damager_unit = damager.unit
damager_side = damager_unit.side
damager_side_guid = SideGUIDByName(damager_side)
if damaged then
StoreString("__LD_"..dguid, damager_side)
end
end
end
if damaged.type == "Aircraft" then
-- don't push aircraft damage to our turn log
return
end
-- register damage
if IsIn(damaged.side, PBEM_PLAYABLE_SIDES) then
if damaged.side ~= Turn_GetCurSideName() then
local damaged_side = damaged.side
local sidenum = PBEM_SideNumberByName(damaged_side)
local damage_register = PBEM_GetDamageRegister(sidenum)
local unitname
if damaged.name == damaged.classname then
unitname = damaged.name
else
unitname = damaged.name..' ('..damaged.classname..')'
end
-- find the name of the weapon by how much is known about it
local weap_name = PBEM_KnownWeaponName(damager_unit, damaged_side)
StoreString("__LDCLASS_"..dguid, weap_name)
unitname = unitname.." "..Format(
LocalizeForSide(damaged_side, "DAMAGE_LISTING"),
{
weap_name
}
)
damage_register = damage_register.."<i>"..damage_time.."</i> // "..unitname.."<br/>"
PBEM_SetDamageRegister(sidenum, damage_register)
end
end
--register hit
if damager_unit then
if IsIn(damager_side, PBEM_PLAYABLE_SIDES) and (damager_side ~= damaged.side) then
if damager_side ~= Turn_GetCurSideName() then
-- record the hit for the player
local sidenum = PBEM_SideNumberByName(damager_side)
local hits = PBEM_GetHitRegister(sidenum)
local known_name = damaged.type
for k, contact in ipairs(damaged.ascontact) do
if contact.side == damager_side_guid then
known_name = contact.name
break
end
end
local unitname = known_name
if damager_unit.classname then
unitname = known_name.." "..Format(
LocalizeForSide(damager_side, "HIT_LISTING"),
{
damager_unit.classname
}
)
end
hits = hits.."<i>"..damage_time.."</i> // "..unitname.."<br/>"
PBEM_SetHitRegister(sidenum, hits)
end
end
end
end
function PBEM_RegisterUnitKilled()
local killed = ScenEdit_UnitX()
local killer = ScenEdit_UnitY()
local killtime = PBEM_CurrentTimeMilitary()
local killer_unit = nil
local kguid = string.upper(killed.guid)
local damstore_id = "__LD_"..kguid
local damclass_id = "__LDCLASS_"..kguid
local killer_side = GetString(damstore_id)
local damclass_default = GetString(damclass_id)
local killer_side_guid = ""
StoreString(damstore_id, "")
StoreString(damclass_id, "")
if killer then
if killer.unit then
killer_unit = killer.unit
killer_side = killer_unit.side
end
end
if killer_side ~= "" then
killer_side_guid = SideGUIDByName(killer_side)
end
local is_fratricide = (killer_side == killed.side)
-- register loss
if IsIn(killed.side, PBEM_PLAYABLE_SIDES) then
if killed.side ~= Turn_GetCurSideName() then
local killed_side = killed.side
local sidenum = PBEM_SideNumberByName(killed_side)
local losses
if is_fratricide == true then
losses = PBEM_GetFratricideRegister(sidenum)
else
losses = PBEM_GetLossRegister(sidenum)
end
local unitname
if killed.name == killed.classname then
unitname = killed.name
else
unitname = killed.name..' ('..killed.classname..')'
end
-- find the name of the weapon by how much is known about it
local weap_name = damclass_default
if killer_unit or (weap_name == "") then
weap_name = PBEM_KnownWeaponName(killer_unit, killed_side)
end
unitname = unitname.." "..Format(
LocalizeForSide(killed_side, "LOSS_LISTING"),
{
weap_name
}
)
losses = losses.."<i>"..killtime.."</i> // "..unitname.."<br/>"
if is_fratricide == true then
PBEM_SetFratricideRegister(sidenum, losses)
else
PBEM_SetLossRegister(sidenum, losses)
end
--mark loss on the map
if PBEM_GetPreferenceForSide(
killed_side,
"EVENT_MARK_RP"
) then
local rp = ScenEdit_AddReferencePoint({
side=killed_side,
name=Format(
LocalizeForSide(killed_side, "LOSS_MARKER"),
{
killed.name
}
),
lat=killed.latitude,
lon=killed.longitude,
highlighted=true
})
PBEM_RegisterEventRPWithSide(
killed_side,
rp
)
end
end
end
if is_fratricide == true then
-- no need to mark the kill
return
end
-- register and mark kill
if killer_unit or (killer_side ~= "") then
if IsIn(killer_side, PBEM_PLAYABLE_SIDES) then
if killer_side ~= Turn_GetCurSideName() then
-- record the kill for the player
local sidenum = PBEM_SideNumberByName(killer_side)
local kills = PBEM_GetKillRegister(sidenum)
local known_name = killed.type
for k, contact in ipairs(killed.ascontact) do
if contact.side == killer_side_guid then
known_name = contact.name
break
end
end
local unitname = known_name
if killer_unit then
if killer_unit.classname then
unitname = unitname.." "..Format(
LocalizeForSide(killer_side, "KILL_LISTING"),
{
killer_unit.classname
}
)
end
end
kills = kills.."<i>"..killtime.."</i> // "..unitname.."<br/>"
PBEM_SetKillRegister(sidenum, kills)
--mark kill on the map
if PBEM_GetPreferenceForSide(
killer_side,
"EVENT_MARK_RP"
) then
local rp = ScenEdit_AddReferencePoint({
side=killer_side,
name=Format(
LocalizeForSide(killer_side, "KILL_MARKER"),
{
known_name
}
),
lat=killed.latitude,
lon=killed.longitude,
highlighted=true
})
PBEM_RegisterEventRPWithSide(
killer_side,
rp
)
end
end
end
end
end
function PBEM_ScoreSummary(score_tbl)
local scoretxt = ""
for i=1,#PBEM_PLAYABLE_SIDES do
local sidename = PBEM_PLAYABLE_SIDES[i]
local finalscore = score_tbl[i]
scoretxt = scoretxt..'<center><b>'..sidename..': '..finalscore..'</b></center><br/>'
end
return scoretxt
end
function PBEM_ShowTurnIntro()
-- first deal with variable turn length issues
if PBEM_HasVariableTurnLengths() then
PBEM_CheckTacticalTime()
PBEM_CheckIntermediateTime()
end
local cursidenum = Turn_GetCurSide()
local turnnum = Turn_GetTurnNumber()
local lossreport = ""
-- show new contacts from previous turn
local contacts = PBEM_GetContactRegister(cursidenum)
if contacts ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("CONTACTS_REPORTED").."</u><br/><br/>"..contacts
PBEM_SetContactRegister(cursidenum, "")
end
-- show hits from previous turn
local hits = PBEM_GetHitRegister(cursidenum)
if hits ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("HITS_REPORTED").."</u><br/><br/>"..hits
PBEM_SetHitRegister(cursidenum, "")
end
-- show kills from previous turn
local kills = PBEM_GetKillRegister(cursidenum)
if kills ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("KILLS_REPORTED").."</u><br/><br/>"..kills
PBEM_SetKillRegister(cursidenum, "")
end
-- show damages from previous turn
local damages = PBEM_GetDamageRegister(cursidenum)
if damages ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("DAMAGES_REPORTED").."</u><br/><br/>"..damages
PBEM_SetDamageRegister(cursidenum, "")
end
-- show losses from previous turn
local losses = PBEM_GetLossRegister(cursidenum)
if losses ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("LOSSES_REPORTED").."</u><br/><br/>"..losses
PBEM_SetLossRegister(cursidenum, "")
end
-- show fratricides from previous turn
local frats = PBEM_GetFratricideRegister(cursidenum)
if frats ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("FRATRICIDES_REPORTED").."</u><br/><br/>"..frats
PBEM_SetFratricideRegister(cursidenum, "")
end
-- get any special messages we missed
local prev_msgs = GetString("__SCEN_PREVMSGS_"..cursidenum)
if prev_msgs ~= "" then
lossreport = lossreport.."<br/><u>"..Localize("MESSAGES_RECEIVED").."</u><br/>"..prev_msgs
StoreString("__SCEN_PREVMSGS_"..cursidenum, "")
end
local msg_header
local turn_len_min = math.floor(PBEM_TURN_LENGTH / 60)
local orderNumStr = Format(Localize("ORDER_PHASE_DIVIDER"), {
"1",
math.floor(PBEM_TURN_LENGTH / PBEM_ORDER_INTERVAL) + 1
})
msg_header = Format(Localize("START_ORDER_HEADER"), {
PBEM_SIDENAME,
tostring(turnnum),
turn_len_min,
orderNumStr
})
local msg = Message_Header(msg_header)
msg = msg..Localize("START_ORDER_MESSAGE").."<br/><br/>"
msg = msg..lossreport
PBEM_SpecialMessage('playerside', msg, nil, true)
end
function PBEM_MakeScheduledMessage(side_num, targetside, time, msg)
local base_id = "__SCEN_SCHEDULEDMSG_"..side_num
StoreBoolean(base_id, true)
StoreString(base_id.."_TARGET", targetside)
StoreNumber(base_id.."_TIME", time)
StoreString(base_id.."_MSG", msg)
table.insert(PBEM_SCHEDULED_MESSAGES, {
from = side_num,
target = targetside,
time = time,
msg = msg
})
end
function PBEM_ClearScheduledMessage(side_num)
local base_id = "__SCEN_SCHEDULEDMSG_"..side_num
StoreBoolean(base_id, false)
StoreString(base_id.."_TARGET", "")
StoreNumber(base_id.."_TIME", 0)
StoreString(base_id.."_MSG", "")
end
function PBEM_PrecacheScheduledMessages()
PBEM_SCHEDULED_MESSAGES = {}
for i=1, #PBEM_PLAYABLE_SIDES do
local base_id = "__SCEN_SCHEDULEDMSG_"..i
if GetBoolean(base_id) then
table.insert(PBEM_SCHEDULED_MESSAGES, {
from = i,
target = GetString(base_id.."_TARGET"),
time = GetNumber(base_id.."_TIME"),
msg = GetString(base_id.."_MSG")
})
end
end
end
function PBEM_CheckScheduledMessages()
local cur_time = ScenEdit_CurrentTime()
for i = #PBEM_SCHEDULED_MESSAGES, 1, -1 do
local message = PBEM_SCHEDULED_MESSAGES[i]
if cur_time >= message.time then
ScenEdit_SpecialMessage(
message.target,
Format(Localize("CHAT_MSG_FORM"), {
PBEM_PLAYABLE_SIDES[message.from],
message.msg
})
)
PBEM_ClearScheduledMessage(message.from)
table.remove(PBEM_SCHEDULED_MESSAGES, i)
end
end
end
function PBEM_RegisterEventRPWithSide(sidename, rp)
local arrname = "EVENT_RPS_"..PBEM_SideNumberByName(sidename)
AppendStringArray(arrname, rp.guid)
end
function PBEM_CollectEventRPs()
local sidenum = Turn_GetCurSide()
local arrname = "EVENT_RPS_"..sidenum
local rp_guids = GetStringArray(arrname)
ClearStringArray(arrname)
arrname = "LASTTURN_EVENT_RPS_"..sidenum
StoreStringArray(arrname, rp_guids)
end
function PBEM_HandleLastTurnEventRPs()
local sidename = Turn_GetCurSideName()
local arrname = "LASTTURN_EVENT_RPS_"..Turn_GetCurSide()
if PBEM_GetPreference("EVENT_RP_DELETE_ENDTURN") == true then
-- wipe all event RPs from the previous turn
local rp_guids = GetStringArray(arrname)
for k, v in ipairs(rp_guids) do
pcall(
ScenEdit_DeleteReferencePoint,
{
side=sidename,
guid=v
}
)
end
end
ClearStringArray(arrname)
end