248: ----------------------------------------------------------------------
249: ----------------------------------------------------------------------
250: -- Apply the accumulated facilityData to a specific facility.
251: ----------------------------------------------------------------------
252: ----------------------------------------------------------------------
253: 
254: function P.processFacility(facility, facilityData)
255: 
256:     -- If the facility is no-longer capturable, then remove it from
257:     -- the queue.
258: 
259:     if facility:isCaptureEnabled() == false then
260:         P.activeData[facility] = nil
261:         return false
262:     end
263: 
264:     ---TODO: If I just add one point, it then takes 100 * tickInterval_s to capture,
265:     ---TODO: which made capture take 500s.
266:     ---TODO: Should be exposed through wwii_config.capture instead?
267:     ---TODO: Side balance adjustment?
268: 
269:     -- What %age is one tick worth?
270: 
271:     local tickPoint = 1
272: 
273:     -- Query the current progress for this facility.
274: 
275:     -- Number of captures and defenses that weren't subsequently
276:     -- withdrawn because of the player dying/leaving/exiting.
277:     local cappers = facilityData.counted.cap
278:     local defenders = facilityData.counted.def
279:     -- Current progress as a %age of capture. 0 = no capture, 100 = change of owner
280:     local progress = facility:getCaptureProgress()
281: 
282:     local newProgress
283: 
284:     if cappers > 0 then
285:         -- The facility had people submit capture contributions;
286:         ---CURRENT: Does not take into account presence of defenders
287:         ---CURRENT: or factor side balance into the equation.
288: 
289:         -- Search the history to find a currently present player we
290:         -- can credit this capture progression to. The database only
291:         -- supports one player being named as "the capper".
292: 
293:         local capper = P.findPrimaryContributor(facilityData.history.cap)
294: 
295:         -- Check we could find someone. Future-proofs against cases
296:         -- we might not expect where nobody appears to be capping.
297: 
298:         if capper.contrib ~= nil then
299: 
300:             -- Increment progress.
301:             ---CURRENT: Linear multiplication.
302:             ---TODO: Use curved multiplier.
303: 
304:             newProgress = progress + (tickPoint * cappers)
305: 
306:             -- Get printable name of the capper
307: 
308:             local gamename = getGameName(capper.contrib:handle())
309: 
310:             ---EXPERIMENTAL: Periodically allow an announcement to friendlies
311:             ---EXPERIMENTAL: that I have started capture progress.
312:             ---EXPERIMENTAL: - Only applies when you push progress over 10%,
313:             ---EXPERIMENTAL: - Only applies once per 2 minutes
314:             ---EXPERIMENTAL: - Only sent to players with this Objective tuned.
315:             ---TODO: Producer approval,
316:             ---TODO: Move percentage and interval to wwii_config,
317:             ---TODO: Localize messages,
318:             ---TODO: Only send to player's mission?
319: 
320:             if progress < 10 and newProgress >= 10 and facilityData.nextAnnounce < teulClockTime then
321: 
322:                 local effect = "capturing"      -- Assume we are capping.
323:                 if facility.cp.side == capper.contrib:unit():side() then
324:                     effect = "liberating"       -- But catch when we are not.
325:                 end
326: 
327:                 -- Announce to my side only, and only to players with this CP tuned as objective.
328:                 chatSendSideMessage(capper.contrib:unit():side(), facility.cp.fullObjID, LSTR_BETA, LSTR_GENERIC, gamename .. " has started " .. effect .. " " .. facility.name)
329: 
330:                 -- Prevent further announcements for 2 minutes.
331:                 facilityData.nextAnnounce = teulClockTime + timeInSeconds({ minutes = 2 })
332: 
333:             end
334: 
335:             -- Audit trail.
336:             output("f:"..facility.name.." capture contribution to credited "..getGameName(capper.contrib:handle()).." => " .. newProgress .. "%")
337: 
338:             -- Update the capture progress and credit the last capture contributee we saw.
339:             facility:setCaptureProgress(newProgress, capper.contrib)
340:         end
341: 
342:     elseif progress > 0 and progress < 100 then
343: 
344:         -- There were no cappers, and the facility has non-zero/non-complete progress.
345: 
346:         local capper = P.findPrimaryContributor(facilityData.history.def)
347: 
348:         if defenders > 0 and capper.contrib ~= nil then
349: 
350:             -- There were some defenders present
351:             ---CURRENT: Presence of cappers is eliminated by the if/elseif clause,
352:             ---CURRENT: Uses a linear multiplier,
353:             ---TODO: Use curved multplier.
354: 
355:             newProgress = progress - (defenders * tickPoint)
356: 
357:             output("f:"..facility.name..
358:                     " defense contribution credited "..getGameName(capper.contrib:handle())..
359:                     " => " .. newProgress .. "%")
360: 
361:             facility:setCaptureProgress(newProgress, capper.contrib)
362: 
363:         else
364: 
365:             -- The building is unoccupied. Slowly "bleed off" the capture progress.
366: 
367:             newProgress = progress - 0.5
368:             if newProgress < 0 then newProgress = 0 end
369: 
370:             output("f:"..facility.name.." no contributions "..newProgress.. "%")
371: 
372:             -- Create a contribution that represents SYSTEM.
373: 
374:             local contrib = Strat.CaptureContribution(
375:                                 Strat.CaptureContributionEvent.Active
376:                                 , facility
377:                                 , getHandle("SYSTEM")
378:                                 , 0, 0, 0
379:                                 , HCUnit:GetCommandUnit(facility.country, BRANCH_LAND))
380: 
381:             -- Reduce the progress.
382:             facility:setCaptureProgress(newProgress, contrib)
383: 
384:         end
385: 
386:     end
387: 
388:     return true
389: end
390: