Files
gamedir/Data-UB/Scripts/initmines.lua
T

363 lines
10 KiB
Lua

--[[
*************
** Remarks **
*************
The purpose of this Lua script is to provide the code and data needed to
initialize the strategic mines. There are two reasons for the game to make
calls to this script:
1. The strategic layer gets initialized.
Right after a new game is started, the program calls InitializeMines to
gather the data defining the mines (see §1.). It then uses that data to
actually create the mines.
2. The player enters a mine sector.
When a mine sector gets loaded (tactical mode), the program calls
InitializeHeadMiners to collect information on creation of head miners
and how to distribute them among the mines (see §2.).
**********************
** Global variables **
**********************
- newDIFFICULTY_LEVEL (Start new game setting)
1 = easy
2 = experienced
3 = expert
4 = insane
- iniWHICH_MINE_SHUTS_DOWN (ja2_options.ini setting)
-1 = Game chooses a mine randomly.
0 = No mine will shut down!
2 = Drassen
3 = Alma
4 = Cambria
5 = Chitzena
6 = Grumm
]]
-- For debugging purposes you might want to have some basic logging output
-- from the game. Uncommenting the following line will create "initmines.log"
-- in your profile directory.
--logging = true
----------------------------------------
-- §0. Some setup code to get started --
----------------------------------------
-- Initialize the pseudo random number generator
math.randomseed( os.time() ); math.random(); math.random(); math.random()
-- http://lua-users.org/wiki/MathLibraryTutorial
MineType = { Silver = 0, Gold = 1 }
-----------------------------
-- §1. Mine initialization --
-----------------------------
--[[
function InitializeMines()
Gets called on initialization of strategic layer.
This function is supposed to return an array table of initialization data
for each mine. Every element itself must be a table consisting of the
following members:
- Location (required)
String, defining the sector to place the mine, e.g. "A10".
- Type
Use MineType.Gold or MineType.Silver (cp. §0.).
- MaxRemovalRate
Amount of income to be gained at each production period ( = 1/4 of
daily income).
- RemainingOreSupply
Total amount of money available to be extracted.
- Infectible (0/1)
Boolean, specifying whether or not a mine can be infected by crepitus.
This is kind of a hack until creature quest becomes externalized.
Do not set this to 1 for mines other than Drassen, Alma, Cambria, Grumm.
- AssociatedUnderground
Array table of strings specifying sector coordinates, e.g. "A10-1".
This relates underground sectors to the mine. In these sectors the game
adds miners working underground, and also uses that information to build
the sector name.
]]
function InitializeMines()
--------------------------------------
-- §1.1. Set up initial mine status --
--------------------------------------
local mines = {
--UB mine--
-- Abandoned mine near Varrez
{
Location = "I13", Type = MineType.Gold,
MinimumProduction = 0,
AssociatedUnderground = { "I13-1", "J13-1", "K14-1", "K15-1", "K15-2", "L15-2", "L15-3" },
},
--[[
-- San Mona
{
Location = "D4", Type = MineType.Gold,
MinimumProduction = 0,
AssociatedUnderground = { "D4-1", "D5-1" },
},
-- Drassen
{
Location = "D13", Type = MineType.Silver,
MinimumProduction = 1000,
AssociatedUnderground = { "D13-1", "E13-1" },
Infectible = 1,
},
-- Alma
{
Location = "I14", Type = MineType.Silver,
MinimumProduction = 1500,
AssociatedUnderground = { "I14-1", "J14-1" },
Infectible = 1,
},
-- Cambria
{
Location = "H8", Type = MineType.Silver,
MinimumProduction = 1500,
AssociatedUnderground = { "H8-1", "H9-1" },
Infectible = 1,
},
-- Chitzena
{
Location = "B2", Type = MineType.Silver,
MinimumProduction = 500,
AssociatedUnderground = { "B2-1" },
},
-- Grumm
{
Location = "H3", Type = MineType.Gold,
MinimumProduction = 2000,
AssociatedUnderground = { "H3-1", "I3-1", "I3-2", "H3-2", "H4-2" },
Infectible = 1,
},
]]
}
-----------------------------------
-- §1.2. Vanilla JA2 logic below --
-----------------------------------
--[[
-- create variables for easy identification at quest related stuff
local DrassenMine = mines[2]
local AlmaMine = mines[3]
-- more initialization
for i = 1, #mines do
local m = mines[i]
m.MaxRemovalRate = m.MinimumProduction
if m.MinimumProduction > 0 then
m.RemainingOreSupply = 999999999
else
m.RemainingOreSupply = 0
end
end
-- Randomize the exact size of each mine. The total production is always
-- the same and depends on the game difficulty, but some mines will
-- produce more in one game than another, while others produce less.
local numProductionIncreases = ({ 25, 25, 20, 15 })[newDIFFICULTY_LEVEL]
while numProductionIncreases > 0 do
local m
-- pick a producing mine at random and increase its production
repeat
m = mines[math.random(#mines)]
until m.MinimumProduction > 0
-- increase mine production by 20% of the base (minimum) rate
m.MaxRemovalRate = m.MaxRemovalRate + m.MinimumProduction / 5
numProductionIncreases = numProductionIncreases - 1
end
-- Incorporate cheat option...
-- switch on iniWHICH_MINE_SHUTS_DOWN
-- 0: no mine runs out, skip this altogether
-- -1: choose mine randomly
-- >0: ID of the mine that shall run out
if iniWHICH_MINE_SHUTS_DOWN ~= 0 then
local m
if iniWHICH_MINE_SHUTS_DOWN == -1 then
-- Choose which mine will run out of production.
-- This will never be the Alma mine or an empty mine (San Mona)...
-- choose randomly
repeat
m = mines[math.random(#mines)]
-- Alma mine can't run out for quest-related reasons
until m.MinimumProduction > 0 and m ~= AlmaMine
else
-- Select mine by given index
-- No safety checks whatsoever, any error will be pretty much in
-- your face. If it breaks it's all their fault, I don't care...
m = mines[iniWHICH_MINE_SHUTS_DOWN]
end
if m == DrassenMine then
minDaysBeforeDepletion = 20
else
minDaysBeforeDepletion = 10
end
m.RemainingOreSupply = minDaysBeforeDepletion * 4 * m.MaxRemovalRate
-- We don't want the creatures to infect the mine that runs out.
m.Infectible = 0
end
]]
return mines;
end -- function InitializeMines
------------------------------------
-- §2. Head miners initialization --
------------------------------------
--[[
function InitializeHeadMiners(mines, currentMine)
This function is called when the player enters a mine sector.
It can return either nil or the head miners initialization and
distribution. If it returns nil, it will be called again when a mine
sector gets loaded. If it returns a value other than nil, it will not be
called again.
Parameters:
- mines
An array of tables featuring only the following member:
- MaxRemovalRate
- currentMine
This is the index of the mine being entered by the player (cp. §1.1.).
If the function does not return nil but the head miners distribution, it
must return an array of tables consisting of the following members:
- Profile
The profile ID of the head miner.
- Quotes
Array of exactly four integers defining the quote IDs of the head miner
for the following strategic events:
1. RUNNING_OUT
2. CREATURES_ATTACK
3. CREATURES_GONE
4. CREATURES_AGAIN
It is valid to insert -1 for missing quotes.
- MineID
The index of the mine the head miner is assigned to (cp. §1.1.).
]]
function InitializeHeadMiners(mines, currentMine)
local headMinerInfo = {
-- Fred
{ Profile = 106, Quotes = { 17, 18, 27, 26 }, },
-- Matt
{ Profile = 148, Quotes = { -1, 18, 32, 31 }, },
-- Oswald
{ Profile = 156, Quotes = { 14, 15, 24, 23 }, },
-- Calvin
{ Profile = 157, Quotes = { 14, 15, 24, 23 }, },
-- Carl
{ Profile = 158, Quotes = { 14, 15, 24, 23 }, },
}
local Fred = headMinerInfo[1]
local Matt = headMinerInfo[2]
local AlmaID = 3 -- cp. §1.1.
-- don't place miners until player enters a producing mine
if mines[currentMine].MaxRemovalRate == 0 then
return nil
end
-- Matt is always head miner in Alma
Matt.MineID = AlmaID
-- Fred is the first miner the player encounters unless it's Alma
if currentMine ~= AlmaID then
Fred.MineID = currentMine
end
-- collect IDs of all producing mines except Alma mine and Fred's
local MinesLeft = {}
for i = 1, #mines do
if i ~= AlmaID and i ~= currentMine then
if mines[i].MaxRemovalRate > 0 then
table.insert(MinesLeft, i)
end
end
end
-- randomly distribute miners
for i = 1, #headMinerInfo do
if headMinerInfo[i].MineID == nil then
local index = math.random(#MinesLeft)
headMinerInfo[i].MineID = MinesLeft[index]
table.remove(MinesLeft, index)
end
end
return headMinerInfo
end -- function InitializeHeadMiners