Forest of Assassins - Battle of Rung Sat - 9/21/55 - AAR (AI vs. AI)
Follow the main action at:
https://www.matrixgames.com/forums/view ... 7#p4996747
Additional commentary (and discussion) of a more general or technical nature will be posted here.
What's your Strategy?
https://forums.matrixgames.com:443/
The Campaign Series Event Engine, hereinafter referred to as the CSEE, is a standard, built-in extension to the game engine giving you the ability to script special messaging and all manner of in-game events...
One way to implement an "event engine" is by means of an "event editor" -- typically a GUI (Graphical User Interface), a set of dialogs with radio buttons, check boxes, input fields, and so on. This approach is rigid and constricting, however. What if you want to do something out of the ordinary that the event editor designers never anticipated? No can do; you are stuck with the current event editor limitations unless and until the game designers add the new feature in the next update, if and whenever that might happen.
No, a better way we think is to program events by means of a scripting language. This approach is far more flexible.
We could design our own customized scripting language. Much easier, however, to adapt a general purpose scripting language to our game's special environment and needs.
There is a variety of embedded scripting languages available. One of the better known is Lua. From the official Lua site (http://www.lua.org):
"Lua is a powerful, efficient, lightweight, embeddable scripting language. It supports procedural programming, object-oriented programming, functional programming, data-driven programming, and data description...
"Lua" (pronounced LOO-ah) means "Moon" in Portuguese. As such, it is neither an acronym nor an abbreviation, but a noun. More specifically, "Lua" is a name, the name of the Earth's moon and the name of the language. Like most names, it should be written in lower case with an initial capital, that is, "Lua". Please do not write it as "LUA", which is both ugly and confusing..."
Certainly, in the gaming world, Lua is a popular choice for an event scripting language, used in quite a number of high-profile and popular games (e.g., Command: Modern Air Naval Operations; Civilization V & VI; Hearts of Iron III; Napoleon: Total War; World of Warcraft; and many others).
Although quite capable, and very powerful "under the hood," you can do many things with simple Lua scripts. A Lua "script" is a computer program like any other, but is generally short and lean, typically just a few dozen or hundreds of lines long, and (in CS usage) mainly just a series of if-then-else statements (although other, fancier control structures are available).
Lua syntax is not "fussy". There are few punctuation characters to trip over and spacing is free-form. Although you can mangle Lua code like you can with any other computing language, spotting and fixing errors is usually not difficult. In the CSEE Lua implementation, besides the language-intrinsic error messages (which come in the form of pop-up dialogs), we additionally have several other features to assist in you in debugging your mistakes.
The simplicity of Lua -- at least in our implementation -- this is important. If we don't keep it simple, if scenario designers and modders find it too difficult to work with, it won't get used. We don't want the game fora to be flooded with Lua questions and cries for help. If that happens, we have done something wrong. No, better to KISS it.
Even though we combine the CS Lua Event engine with the game engine into one integrated whole, vnengine.exe (in Vietnam, for example), on game launch, it is useful to think of the two engines as two separate programs running side by side. The game engine has its own environment, with its own data, procedures, and processing thread; while the Lua EE is in like manner its own separate environment. The ability of the two engines to communicate and inter-operate with each other is limited. There is data sharing; one engine can call procedures in the other; but the interactions are confined, and typically not instantaneous. In some cases, for some events and data, the game engine will only contact the Lua EE once at the beginning of each phase, or at the beginning of a turn. Usually, the game engine remains in control. It is the more active agent, while the Lua EE tends to be more passive.
When you launch the game engine (for example, vnengine.exe), the CSEE starts up with it. At startup, the CSEE loads and processes the file init.lua, located in the top-level game folder right alongside the other game EXEs.
init.lua is, as you might guess, a collection of initializations -- setting up data structures, assigning data values, also defining some of the more basic, low-level functions, either referenced directly or called by other, higher-level functions.
Next, the CSEE loads and processes the file user.lua, if it exists. user.lua is also in the top-level game folder. user.lua serves a similar purpose as init.lua, but with these differences:
- Unlike init.lua, which is absolutely necessary, user.lua is optional.
- init.lua has mandatory content (in order for the CSEE to work as designed), while user.lua can be rudimentary, devoid of all content even.
- init.lua is off-limits. DO NOT MAKE ANY CHANGES TO INIT.LUA! If you break init.lua, then the entire CSEE collapses; it won't work. So leave it alone!
- user.lua is intended for your own personal customizations to the CSEE. Unlike init.lua (do with user.lua as you wish.
After init.lua and (optionally) user.lua processing, and after you have made your scenario selection, the CSEE looks to see if a scenario-specific .lua file exists, and if so, loads and processes it also. Like scenario-specific .ai files, scenario-specific .lua files are entirely optional. The game will load and play fine without them -- but without benefit of the CSEE. The <scenario>.lua files are located in the scenarios folder. For example, in the Scenarios folder, you might see:
VN_550429_Saigon.ai
VN_550429_Saigon.aix
VN_550429_Saigon.bmp
VN_550429_Saigon.lua
VN_550429_Saigon.map
VN_550429_Saigon.org
VN_550429_Saigon.scn
where the .lua file is entirely optional (and so too the .ai file).
In the scenario-specific .lua files, you will see a set of standard "trigger" function definitions, where every trigger function is on_*() something or other.
Here are the standard on_*() trigger functions:
on_air_attack ()
on_arty_attack ()
on_build_barrier ()
on_build_light_bridge ()
on_build_vehicle_bridge ()
on_clear_hex ()
on_clear_lz ()
on_damage ()
on_entrench_hex ()
on_hex_assault ()
on_hex_attack ()
on_ied_attack ()
on_improve_hex ()
on_lay_mine_field ()
on_mine_attack ()
on_next_phase ()
on_next_turn ()
on_objective_capture ()
on_resume ()
on_set_ied ()
on_shutdown ()
on_startup ()
on_unit_arty_fire ()
on_unit_attack ()
on_unit_clockwise ()
on_unit_counterclockwise ()
on_unit_fire ()
on_unit_kill ()
on_unit_merge ()
on_unit_move ()
on_unit_reduce ()
on_unit_reinforce ()
on_unit_release ()
on_unit_remove ()
on_unit_to_top ()
on_unit_to_bottom ()
In the current VN_550429_Saigon.lua file, for example, here is the default function definition for the trigger function on_next_turn():
function on_next_turn (turn) -- DO NOT REMOVE
end
By default, all of the trigger functions are like that -- empty templates. They don't seem to do anything, right? Right! It is the job of the scenario designer/modder to fill in the blanks.
Look again at the list of trigger functions above. When any one of those things happen in the game engine, it triggers a call to the CSEE. The CSEE then processes the event, and may or may not pass information back to the game engine.
For example, if an objective hex is newly captured in game, the game engine calls the on_objective_capture() function in the CSEE, passing the function arguments:
on_objective_capture (hc, value, values, side)
Depending on the on_objective_capture() definition, that function might then do any of the following:
- display an in-game message dialog
- award extra Event Points (EPs) to the occupying side (or subtract points from the other side's EP total)
- raise or lower one side's or the other's general morale level
- trigger fixed units to release early somewhere else on the map
and so on -- whatever the on_objective_capture() function definition says.
Likewise, if any of the other triggering events occur in game, the game engine will call the appropriate on_*() trigger function in the CSEE.
on_next_phase()
on_next_turn()
on_startup()
will always be called, but whether or not the other trigger functions are called, that is more or less likely, but it all depends.
As you might guess, on_startup() is called, once and only once, on scenario startup. Whenever you save and later reload the scenario, the on_resume() function is called instead.
on_next_phase() is called every time the phase passes from one side to the next. And on_next_turn() is called at the start of every new turn, obviously.
Like on_startup(), on_shutdown() is called just once, at scenario's end, just before the final Victory Dialog displays. on_shutdown() is rather like the on_next_turn() function (but at scenario's end, there is no next turn!).
The trigger functions – also nearly 600 other functions in the CSEE – are documented in the LUA_FUNCTIONS_REFERENCE.txt. Look for it in the game Manual folder.
Code: Select all
function on_next_phase (turn, side) -- DO NOT REMOVE
...
--[[ commonly used, uncomment and adapt as necessary:
-- every phase, adjust downward the NVA assault_attack_aggressiveness_effect bonus per their current loss rate
adjust_adaptive_ai (sideof(NORTH_VIETNAM_NATION), NORTH_VIETNAM_NATION, "assault_attack_aggressiveness_effect", - math.floor(total_loss_rate(sideof(NORTH_VIETNAM_NATION))/2))
--]]
...
end
Code: Select all
function on_next_phase (turn, side) -- DO NOT REMOVE
...
-- every phase, adjust downward the NVA assault_attack_aggressiveness_effect bonus per their current loss rate
adjust_adaptive_ai (sideof(NORTH_VIETNAM_NATION), NORTH_VIETNAM_NATION, "assault_attack_aggressiveness_effect", - math.floor(total_loss_rate(sideof(NORTH_VIETNAM_NATION))/2))
...
end
Code: Select all
------------------------------------------------------------------------------------------------------------------------
-- VN_550921_Rung_Sat_TEST.lua
-- Author:
-- Scripter:
------------------------------------------------------------------------------------------------------------------------
function on_startup () -- DO NOT REMOVE
...
init_constants ()
init_variables ()
set_org_lists()
end
------------------------------------------------------------------------------------------------------------------------
function on_resume () -- DO NOT REMOVE
init_constants ()
set_org_lists(current_turn(), current_side())
end
------------------------------------------------------------------------------------------------------------------------
function init_constants ()
-- initialize names and labels unvarying through the course of the scenario
-- also define here lists with "holes" (index gaps) (such lists are not saved)
-- called in on_startup(), and potentially again (and again) in any subsequent on_resume()
-- Side "a" and "b" values with descriptive names
SIDE_A = "a" -- _NATION ## (in user.lua)
SIDE_B = "b" -- _NATION ## (in user.lua
...
end
------------------------------------------------------------------------------------------------------------------------
function set_org_lists (turn, side)
-- called in on_startup(), in every on_next_turn(), and potentially again (and again) in any subsequent on_resume()
...
end
------------------------------------------------------------------------------------------------------------------------
function init_variables ()
-- initialize values possibly varying through the course of the scenario
-- called once only, in on_startup()
...
end
------------------------------------------------------------------------------------------------------------------------
function show_briefing (side) -- DO NOT REMOVE
if side == SIDE_A then
...
elseif side == SIDE_B then
...
end
end
------------------------------------------------------------------------------------------------------------------------
function on_shutdown () -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_next_turn (turn) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_next_phase (turn, side) -- DO NOT REMOVE
...
set_org_lists(turn, side)
if turn == 1 then
show_briefing(side)
end
battle_plan(turn, side)
...
end
------------------------------------------------------------------------------------------------------------------------
function battle_plan (turn, side)
...
if side == SIDE_A and is_ai(side) then
battle_plan_a(turn, side)
elseif side == SIDE_B and is_ai(side) then
battle_plan_b(turn, side)
end
end
------------------------------------------------------------------------------------------------------------------------
function battle_plan_a (turn, side)
...
end
------------------------------------------------------------------------------------------------------------------------
function battle_plan_b (turn, side)
...
end
------------------------------------------------------------------------------------------------------------------------
function on_objective_capture (hc, value, values, side) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_move (hc_from, hc_to, trackid) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_fire (hc, trackid, pid, name, side, nation, oid, orgname, strength) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_arty_fire (hc, trackid, pid, name, side, nation, oid, orgname, strength) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_attack (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader, attype) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_reduce (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader, loss, combat) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_kill (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_reinforce (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_release (trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_remove (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_merge (hc, trackid0, pid0, name0, side0, nation0, oid0, orgname0, points0, strength0, HQ0, Leader0, trackid1, pid1, name1, side1, nation1, oid1, orgname1, points1, strength1, HQ1, Leader1) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_to_top (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_to_bottom (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_clockwise (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_unit_counterclockwise (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_hex_attack (hc, side, nation, attype) -- DO NOT REMOVE
...
end
------------------------------------------------------------------------------------------------------------------------
function on_hex_assault (hc, side) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_air_attack (hc, pid, name, side, nation, points, strength) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_arty_attack (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_mine_attack (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_ied_attack (hc, trackid, pid, name, side, nation, oid, orgname, points, strength, HQ, Leader) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_build_vehicle_bridge (hc, dir, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_build_light_bridge (hc, dir, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_lay_mine_field (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_set_ied (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_build_barrier (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_damage (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_improve_hex (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_entrench_hex (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_clear_lz (hc, trackid, pid, name, side, nation, oid, orgname) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
function on_clear_hex (hc) -- DO NOT REMOVE
end
------------------------------------------------------------------------------------------------------------------------
Code: Select all
------------------------------------------------------------------------------------------------------------------------
--[[
user.lua -- called each time a scenario is started, or resumed (after a save and scenario restart).
Intended for global identifiers, "uber functions" (unofficial, subject to change), and other shared, common odds & ends.
--]]
------------------------------------------------------------------------------------------------------------------------
--[[
-- With DEBUG=true, user.lua, init.lua, and all [scenario filename].lua files in Scenarios folder will adapt to this setting;
-- use when debugging your Event files.
-- Hand edit the DEBUG toggle here, maybe, but better to set DEBUG at the game engine command line with the -G switch
-- (sets DEBUG to true; omitting the switch, DEBUG defaults to false); and/or use Ctrl+Alt+G in-game to goggle DEBUG=true
-- DEBUG=false.
DEBUG = false
#DEBUG = true
-- Note also that the command-line switch -E toggles on/off Lua script execution tracing.
-- In addition to the command-line switch -L# (e.g., -L3) to raise/lower the game engine LogLevel (higher is more verbose,
-- and slower).
-- With all logging cranked up to the max -- ... -G -E -L5 ... -- the game will run glacially s-l-o-w, so beware!
--]]
------------------------------------------------------------------------------------------------------------------------
-- Some standard identifiers.
TRUE = 1
FALSE = 0
ON = 1
OFF = 0
...
------------------------------------------------------------------------------------------------------------------------
-- Nation IDs with descriptive names
...
------------------------------------------------------------------------------------------------------------------------
-- Nation (Side) specific commendations
------------------------------------------------------------------------------------------------------------------------
-- csee_check() -- do diagnostic QA checks (usually called in on_next_phase()) (for diagnostic purposes; not intended for ordinary scripter/modder use)
------------------------------------------------------------------------------------------------------------------------
function csee_check (turn, side, memceil)
...
end
------------------------------------------------------------------------------------------------------------------------
function luaval_dump (all)
...
end
------------------------------------------------------------------------------------------------------------------------
function victory_dump (turn, side)
...
end
------------------------------------------------------------------------------------------------------------------------
function losses_dump (turn, side)
...
end
------------------------------------------------------------------------------------------------------------------------
function ground_transport_passengers (trackids, loadpt, unloadpt, assemblypt)
...
end
------------------------------------------------------------------------------------------------------------------------
function ground_transport_carriers (trackids, loadpt, unloadpt, roundtrip)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_ground_transport (ptrackids, ctrackids, loadpt, unloadpt, assemblypt, roundtrip)
...
end
------------------------------------------------------------------------------------------------------------------------
function column_move (trackids, hc, dir, radius, actprob)
...
end
------------------------------------------------------------------------------------------------------------------------
function water_transport_passengers (trackids, embarkpt, loadpt, unloadpt, disembarkpt, assemblypt)
...
end
------------------------------------------------------------------------------------------------------------------------
function water_transport_carriers (trackids, loadpt, unloadpt, roundtrip)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_water_transport (ptrackids, ctrackids, embarkpt, loadpt, unloadpt, disembarkpt, assemblypt, roundtrip)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_transport_passengers (trackids, loadpt, unloadpt, assemblypt, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_transport_carriers (trackids, loadpt, unloadpt, roundtrip, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_air_transport (ptrackids, ctrackids, loadpt, unloadpt, assemblypt, roundtrip, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_mission_fire (trackids, basept, targetpt, proximity, _range, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_mission_gunship_sortie (trackids, entrypt, targetpt, proximity, _range, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_mission_spot (trackids, basept, targetpt, proximity, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_transport_reinforce (trackids, entrypt, unloadpt, roundtrip, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function air_transport_evacuate (trackids, entrypt, loadpt, roundtrip, airlevel)
...
end
------------------------------------------------------------------------------------------------------------------------
function attack_org (trackids, otrackids, dir, radius, actprob, attype, ground_only, unverified)
...
end
------------------------------------------------------------------------------------------------------------------------
function attack_nearest (trackids, dir, radius, actprob, attype, ground_only, unverified)
...
end
------------------------------------------------------------------------------------------------------------------------
function attack_nearest_way_point (trackids, hcs, dir, radius, actprob, attype, ground_only, unverified)
...
end
------------------------------------------------------------------------------------------------------------------------
function fire_direct_area (trackids, hc, dir, radius, actprob, verified_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function fire_direct_nearest (trackids, actprob, ground_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function fire_direct_nearest_to_hex (trackids, hc, actprob, verified_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function attack_nearest_to_hex (trackids, hc, dir, radius, actprob, attype, ground_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function fire_indirect_area (trackids, hc, dir, radius, actprob, verified_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function fire_indirect_nearest (trackids, actprob, ground_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function fire_indirect_nearest_to_hex (trackids, hc, actprob, verified_only)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_fire_way_point (trackids, hcs, dir, radius, actprob)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_fire (trackids, hc, dir, radius, actprob)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_wary_way_point (trackids, hcs, dir, radius, actprob, foe_count)
...
end
------------------------------------------------------------------------------------------------------------------------
function move_wary (trackids, hc, dir, radius, actprob, foe_count)
...
end
------------------------------------------------------------------------------------------------------------------------
function attack_supply (trackids, extent)
...
end
------------------------------------------------------------------------------------------------------------------------
function company_kill_check (trackid, coys, sides, eps, nations, mshifts, reveal, phase)
...
end
------------------------------------------------------------------------------------------------------------------------
function company_reduce_check (trackid, coys, sides, eps, nations, mshifts, rate, reveal, phase)
...
end
------------------------------------------------------------------------------------------------------------------------
function adjust_adaptive_ai (side, nation, parameter, adjustment)
...
end
------------------------------------------------------------------------------------------------------------------------
function unload_scatter (trackids, hc, dir, extent, actprob, off_center)
...
end
------------------------------------------------------------------------------------------------------------------------
function attack_scatter (trackids, hc, dir, extent, actprob, off_center, attype)
...
end
------------------------------------------------------------------------------------------------------------------------
function defend_scatter (trackids, hc, dir, extent, actprob, off_center, dftype)
...
end
------------------------------------------------------------------------------------------------------------------------
function allot_airstrikes(turn, side, allotment, limit, replenishment, halt_text, resume_text, night)
...
end
------------------------------------------------------------------------------------------------------------------------
Code: Select all
-- _C2_1ST_5TH_RIFLE_COY_48_US_73 -- C2/1st/5th Rifle Company 48 - US
do local units = _C2_1ST_5TH_RIFLE_COY_48_US_73
end
Code: Select all
do
...
end
Code: Select all
do local units ...
...
end
Code: Select all
do local units = _C2_1ST_5TH_RIFLE_COY_48_US_73
...
end
halt(units)
Code: Select all
-- _C2_1ST_5TH_RIFLE_COY_48_US_73 -- C2/1st/5th Rifle Company 48 - US
do local units = _C2_1ST_5TH_RIFLE_COY_48_US_73
if counter_exists(_C2_1ST_5TH_RIFLE_COY_48_US_73_POST) then
local objective = counter_hex(_C2_1ST_5TH_RIFLE_COY_48_US_73_POST)
if not within(units, objective, DOWNLEFTDIR, 2) then
move_norush(units, objective, NODIR, 0, 100)
else
defend_scatter(units, objective, DOWNLEFTDIR, 2, 50, true, DEFEND_STRONG)
end
else
defend_way_point(units, {"71,64", "71,61", "73,61", OBJECTIVES[19]}, UPRIGHTDIR, 1, 100, DEFEND_STRONG)
end
end
Code: Select all
-- _C2_1ST_5TH_RIFLE_COY_48_US_73 -- C2/1st/5th Rifle Company 48 - US
if counter_exists(_C2_1ST_5TH_RIFLE_COY_48_US_73_POST) then
local objective = counter_hex(_C2_1ST_5TH_RIFLE_COY_48_US_73_POST)
if not within(_C2_1ST_5TH_RIFLE_COY_48_US_73, objective, DOWNLEFTDIR, 2) then
move_norush(_C2_1ST_5TH_RIFLE_COY_48_US_73, objective, NODIR, 0, 100)
else
defend_scatter(_C2_1ST_5TH_RIFLE_COY_48_US_73, objective, DOWNLEFTDIR, 2, 50, true, DEFEND_STRONG)
end
else
defend_way_point(_C2_1ST_5TH_RIFLE_COY_48_US_73, {"71,64", "71,61", "73,61", OBJECTIVES[19]}, UPRIGHTDIR, 1, 100, DEFEND_STRONG)
end
Code: Select all
-- _C3_1ST_1ST_RIFLE_COY_48_US_16 -- C3/1st/1st Rifle Company 48 - US
if counter_exists(_C2_1ST_5TH_RIFLE_COY_48_US_73_POST) then
local objective = counter_hex(_C2_1ST_5TH_RIFLE_COY_48_US_73_POST)
if not within(_C2_1ST_5TH_RIFLE_COY_48_US_73, objective, DOWNLEFTDIR, 2) then
move_norush(_C2_1ST_5TH_RIFLE_COY_48_US_73, objective, NODIR, 0, 100)
else
defend_scatter(_C2_1ST_5TH_RIFLE_COY_48_US_73, objective, DOWNLEFTDIR, 2, 50, true, DEFEND_STRONG)
end
else
defend_way_point(_C2_1ST_5TH_RIFLE_COY_48_US_73, {"71,64", "71,61", "73,61", OBJECTIVES[19]}, UPRIGHTDIR, 1, 100, DEFEND_STRONG)
end
Code: Select all
-- _C4_1ST_5TH_DAI_DOI_HOA_LUC_48_81MM_83 -- C4/1st/5th Dai Doi Hoa Luc 48 - 81mm
do local units = _C4_1ST_5TH_DAI_DOI_HOA_LUC_48_81MM_83
end
-- _MORTAR_84 -- VM 81mm Mortars
Code: Select all
-- _MORTAR_84 -- VM 81mm Mortars
Code: Select all
-- _C4_1ST_5TH_DAI_DOI_HOA_LUC_48_81MM_83 -- C4/1st/5th Dai Doi Hoa Luc 48 - 81mm
do local units = difference(_C4_1ST_5TH_DAI_DOI_HOA_LUC_48_81MM_83, _MORTAR_84)
... [code applying only to the infantry; i.e., referencing 'units']
end
-- _MORTAR_84 -- VM 81mm Mortars
... [code applying only to the mortars; no reference to units]
Code: Select all
-- _AAMG_491 -- VM Anti-Aircraft Machine Gun
do local units = _AAMG_491
defend_normal(units)
end
Code: Select all
defend_normal(_AAMG_491)
Code: Select all
_AAMG_491 = {491} -- [P] [75,57] [212065] VM Anti-Aircraft Machine Gun
Code: Select all
defend_normal({491})
Code: Select all
defend_normal(491)
Code: Select all
defend_normal(491)
Code: Select all
defend_normal(_AAMG_491[1])
Code: Select all
OBJECTIVES = {}
OBJECTIVES[1] = "27,38" -- 1-40[2/2] 11
OBJECTIVES[2] = "34,33" -- 1-40[2/2] 11
OBJECTIVES[3] = "42,55" -- 1-40[2/2] 21
OBJECTIVES[4] = "43,35" -- 1-40[2/2] 21
...
OBJECTIVES[31] = "93,24" -- 1-40[2/2] 21
OBJECTIVES[32] = "95,50" -- 1-40[2/2] 21
OBJECTIVES[33] = "98,26" -- 1-40[2/2] 21
OBJECTIVES[34] = "101,20" -- 1-40[2/2] 21
Code: Select all
OBJECTIVES = {"27,38", "34,33", "42,55", "43,35", ... , "93,24", "95,50", "98,26", "101,20"}
Code: Select all
defend_normal(645, 646, "28,34", NODIR, 0, 50)
Code: Select all
defend_normal(645, 646)
Code: Select all
defend_normal({645, 646}, "28,34", NODIR, 0, 50)
Code: Select all
defend_normal({645, 646})
Code: Select all
defend_normal(units, "28,34", NODIR, 0, 50)
defend_normal(units, "28,34", NODIR, 0)
defend_normal(units, "28,34", NODIR)
defend_normal(units, "28,34")
defend_normal(units)
Code: Select all
function defend_normal (trackids, hc, dir, radius, actprob)
if not trackids then return false end
local tl
if type(trackids) == "table" then
if #trackids == 0 then return false end
tl = trackids
elseif type(trackids) == "number" then
tl = {trackids}
else
return false
end
hc = hc or HEXUNKNOWN
if (hc ~= HEXUNKNOWN) and not on_map(hc) then
log(APPLOG, LOG_WARNING, "in defend_normal(), mistaken (off-map or nonsensical) hc " .. hc .. ", order not given")
return false
end
dir = dir or NODIR
radius = radius or -1
actprob = actprob or 50
...
end
Code: Select all
defend_normal(units, "28,34", 0, 50)
Code: Select all
defend_normal(units)
Code: Select all
defend_normal(units, HEXUNKNOWN, NODIR, UNKNOWN, 50)
Code: Select all
defend_normal(units, "28,34", NODIR, 0, dieroll(100))
defend_normal(units, "28,34", NODIR, random_pick(0,0,1,2))
defend_normal(units, hex_adjacent(OBJECTIVES[9], UPDIR))
Code: Select all
_2ND_5TH_PARACHUTE_COY_55_A_447 = {448,449,450} -- [C] [1102243] 2nd/5th Parachute Company 55 - A
_1ST_PLT_448 = {448} -- [P] [T3: 67,13] [112022] Parachute Platoon 55 A
_2ND_PLT_449 = {449} -- [P] [T3: 67,13] [112022] Parachute Platoon 55 A
_3RD_PLT_450 = {450} -- [P] [T3: 67,13] [112022] Parachute Platoon 55 A
Code: Select all
-- _2ND_5TH_PARACHUTE_COY_55_A_447 -- 2nd/5th Parachute Company 55 - A
do local units = _2ND_5TH_PARACHUTE_COY_55_A_447
if _5TH_PARACHUTE_BTN_55_A_441_READY_TURN then
if obj13_threatened then
attack_nearest_to_hex(units, OBJECTIVES[13], NODIR, 1, 100, ATTACK_STRONG)
else
if not _2ND_5TH_PARACHUTE_COY_55_A_447_ORDER then -- set one time only
_2ND_5TH_PARACHUTE_COY_55_A_447_ORDER = 1 -- random_pick({1,2})
end
if _2ND_5TH_PARACHUTE_COY_55_A_447_ORDER == 1 then
if loss_rate(units) > 65 then
if not _2ND_5TH_PARACHUTE_COY_55_A_447_RETIRE_PT then
local cch = counters_center_hex(units)
local hno = hexes_not_occupied (hexes_habitat(), BX_SIDE)
_2ND_5TH_PARACHUTE_COY_55_A_447_RETIRE_PT = random_pick(hexes_nearest (cch, hno))
end
defend_weak(units, _2ND_5TH_PARACHUTE_COY_55_A_447_RETIRE_PT, NODIR, 1)
else
if objective_owner(OBJECTIVES[16]) == BX_SIDE then
move_way_point(units, {"65,8", "66,4"})
if within(difference(join({_3RD_5TH_PARACHUTE_COY_55_A_451, _5TH_PARACHUTE_WEAPONS_COY_55_455}), _MMG_457), OBJECTIVES[16], NODIR, 4) then
attack_strong(units, OBJECTIVES[16], {DOWNDIR, DOWNLEFTDIR, UPLEFTDIR, UPDIR, UPRIGHTDIR}, 1)
end
elseif objective_owner(OBJECTIVES[17]) == BX_SIDE then
attack_strong(units, OBJECTIVES[17], NODIR, 2)
end
end
elseif _2ND_5TH_PARACHUTE_COY_55_A_447_ORDER == 2 then
defend_normal(units, OBJECTIVES[13], NODIR, 1)
end
end
end
end
Code: Select all
attack_strong(units, OBJECTIVES[16], {DOWNDIR, DOWNLEFTDIR, UPLEFTDIR, UPDIR, UPRIGHTDIR}, 1)
Code: Select all
function attack_strong (trackids, hc, dir, radius, actprob)
if not trackids then return false end
hc = hc or HEXUNKNOWN
if not on_map(hc) then
log(APPLOG, LOG_WARNING, "in attack_strong(), mistaken (off-map or nonsensical) hc " .. hc .. ", order not given")
return false
end
dir = dir or NODIR
radius = radius or -1
actprob = actprob or 100 -- by default, 100 chance of assault
return set_ai(trackids, hc, dir2hexdir(dir), radius, actprob, ATTACK_STRONG)
end
Code: Select all
return set_ai(trackids, hc, dir2hexdir(dir), radius, actprob, ATTACK_STRONG)
Code: Select all
function set_ai (trackids, hc, hexdir, radius, actprob, order)
...
set_xai (trackid, x(hc))
set_yai (trackid, y(hc))
set_aidir (trackid, hexdir)
set_airadius (trackid, radius)
set_aiactprob (trackid, actprob)
set_aiorder (trackid, order)
...
return true
end
Code: Select all
set_aiorder (trackid, order)
Code: Select all
-- _2ND_5TH_PARACHUTE_COY_55_A_447 -- 2nd/5th Parachute Company 55 - A
...
if obj13_threatened then
attack_nearest_to_hex(units, OBJECTIVES[13], NODIR, 1, 100, ATTACK_STRONG)
else
...
attack_strong(units, OBJECTIVES[16], {DOWNDIR, DOWNLEFTDIR, UPLEFTDIR, UPDIR, UPRIGHTDIR}, 1)
end
...
Code: Select all
function battle_plan_a (turn, side)
-- standard orders, uncomment as necessary:
if turn >= 1 then
-- all Side A units halt initially (or maybe use hold())
halt(ALLA)
end
...
-- _1ST_5TH_PARACHUTE_COY_55_A_443 -- 1st/5th Parachute Company 55 - A
do local units = _1ST_5TH_PARACHUTE_COY_55_A_443
if _5TH_PARACHUTE_BTN_55_A_441_READY_TURN then
if not _1ST_5TH_PARACHUTE_COY_55_A_443_ORDER and
obj13_threatened then
attack_nearest_to_hex(units, OBJECTIVES[13], NODIR, 1, 100, ATTACK_STRONG)
else
if not _1ST_5TH_PARACHUTE_COY_55_A_443_ORDER then -- set one time only
_1ST_5TH_PARACHUTE_COY_55_A_443_ORDER = 1
end
if loss_rate(units) > 65 then
if not _1ST_5TH_PARACHUTE_COY_55_A_443_RETIRE_PT then
local cch = counters_center_hex(units)
local hno = hexes_not_occupied (hexes_habitat(), BX_SIDE)
_1ST_5TH_PARACHUTE_COY_55_A_443_RETIRE_PT = random_pick(hexes_nearest (cch, hno))
end
defend_weak(units, _1ST_5TH_PARACHUTE_COY_55_A_443_RETIRE_PT, NODIR, 1)
elseif not attack_nearest_arc(units, UPLEFTDIR, 2, ATTACK_NORMAL, true, true) and
(objective_owner(OBJECTIVES[8]) == BX_SIDE) then
attack_way_point(units, {"59,12", "50,6", OBJECTIVES[8]}, UPDIR, 2, 50, ATTACK_STRONG)
end
end
end
end
...
end
Code: Select all
-- _2ND_5TH_PARACHUTE_COY_55_A_447 -- 2nd/5th Parachute Company 55 - A
do local units = _2ND_5TH_PARACHUTE_COY_55_A_447
...
if not _2ND_5TH_PARACHUTE_COY_55_A_447_ORDER then -- set one time only
_2ND_5TH_PARACHUTE_COY_55_A_447_ORDER = 1 -- random_pick({1,2})
end
if _2ND_5TH_PARACHUTE_COY_55_A_447_ORDER == 1 then
[join 3rd/5th & Weapons in attacking OBJECTIVES[16] etc.]
elseif _2ND_5TH_PARACHUTE_COY_55_A_447_ORDER == 2 then
[stay behind to help defend OBJECTIVES[13]]
end
...
end
Code: Select all
_FIRE_SUPPORT_COY_50_82MM_128_ATTACK_TURN = _FIRE_SUPPORT_COY_50_82MM_128_ATTACK_TURN or random_pick({21,22,23,24,25})