Any new game causes the issue. There are two scenarios of desync:
- 1. When using the old mod and loading a save. At this point I don't care about this since I can't get other players not to desync on 2.
2. After building from the ground up, finishing the intial configuration, and "starting the game" where ticks are used.
I am suspecting the on_tick to be the issue, but I do not know why.
The following is the code from the ticker helper, but is called from control.lua and some other helper lua files.
Code: Select all
function register_tick_helper(f, name)
global._tick_helper[name] = f;
end
function destroy_tick_helper(name)
global._tick_helper[name] = nil;
end
function tick_all_helper(tick)
for k,f in pairs(global._tick_helper) do
pcall(f,tick);
end
end
function tick_all_helper_if_valid(tick)
for k,data in pairs(global._tick_helper_v) do
if data.next_tick == tick then
if data.running == false then
global._tick_helper_v[k].running = true;
local status, r = pcall(data.if_valid, tick);
if status and r then
pcall(data.tick_helper,tick);
global._tick_helper_v[k].running = false;
destroy_tick_helper_if_valid(k);
else
global._tick_helper_v[k].next_tick = tick + global.TICK_INTERVAL--data.tick_interval
global._tick_helper_v[k].running = false;
end
end
end
end
end
function register_tick_helper_if_valid(name, tick_helper, tick_interval, if_valid)
global._tick_helper_v[name] = {
tick_helper=tick_helper,
name = name,
if_valid = if_valid,
--tick_interval = global.TICK_INTERVAL,
next_tick = game.tick + global.TICK_INTERVAL,
running = false
}
end
function destroy_tick_helper_if_valid(name)
global._tick_helper_v[name] = nil;
end
Here is the control.lua
Code: Select all
require("constants")
require("utility.event")
require("utility.map_helpers")
require("utility.math")
require("utility.position")
require("utility.table")
require("utility.tick_helper")
require("utility.utilities")
require("utility.configuration_gui")
function areTeamsEnabled()
return global.TEAMS_ENABLED or false;
end
function setTeamsEnabled()
global.TEAMS_ENABLED = true;
end
function areTeamsEnabledStartup()
return global.TEAMS_ENABLED_STARTUP or false;
end
function setTeamsEnabledStartup()
global.TEAMS_ENABLED_STARTUP = true;
end
function isConfigWritten()
return global.CONFIG_WRITTEN or false;
end
function setConfigWritten()
if isConfigWritten() == false then
global.CONFIG_WRITTEN_TIME = game.tick
end
global.CONFIG_WRITTEN = true;
end
function make_forces()
global.LAST_POINT = nil
global.USED_POINTS = {}
global.s = game.surfaces["nauvis"]
table.each(global.forcesData, function(data, k)
if data.cords == nil then
global.RANDOM_POINT = MM_get_random_point(global.USED_POINTS, global.LAST_POINT);
global.LAST_POINT = global.RANDOM_POINT;
global.RANDOM_POINT.x = Rnd(220,1060)
global.RANDOM_POINT.y = Rnd(220,1060)
global.forcesData[k].team_x = global.RANDOM_POINT.x
global.forcesData[k].team_y = global.RANDOM_POINT.y
global.forcesData[k].team_position = { global.forcesData[k].team_x, global.forcesData[k].team_y }
global.forcesData[k].cords = { x = global.forcesData[k].team_x, y = global.forcesData[k].team_y }
global.forcesData[k].team_area = { { global.forcesData[k].team_x - global.distance, global.forcesData[k].team_y - global.distance }, { global.forcesData[k].team_x + global.distance, global.forcesData[k].team_y + global.distance } }
global.LAST_POINT = global.forcesData[k].cords
table.insert(global.USED_POINTS, global.LAST_POINT)
-- logTable(global.forcesData[k],k);
end
MM_create_force(data);
end);
end
function Rnd(min,max,adseed)
min = min or 1
max = max or 1
adseed = adseed or game.tick
global.adseed = global.adseed or 42
global.adseed = global.adseed + adseed
global.adseed = global.adseed < 0 and 0 - global.adseed or global.adseed
global.adseed = global.adseed >= 2^32-1 and 1 or global.adseed
global.seed = game.tick + math.floor(tonumber(tostring({}):sub(8,-4))) + adseed
global.seed = global.seed < 0 and 0 - global.seed or global.seed
global.seed = global.seed >= 2^32-1 and game.tick or global.seed
if not global.generator then
global.generator = game.create_random_generator(global.seed)
else
global.generator.re_seed(global.seed)
end
return math.min(max, math.max(min, math.floor(global.generator(min, math.max(min, max + global.adseed)) % max) ) )
end
function set_spawns()
global.s = game.surfaces['nauvis'];
game.daytime = 0.9
table.each(global.forcesData, function(data)
MM_set_spawns(data);
end)
end
function set_starting_areas()
global.s = game.surfaces['nauvis'];
table.each(global.forcesData, function(data)
MM_set_starting_area(data);
end)
end
function make_team_option(player)
if global.player.gui.left.choose_team == nil then
global.frame = global.player.gui.left.add { name = "choose_team", type = "frame", direction = "vertical", caption = { "resources.team-choose" } }
table.each(global.forcesData, function(data)
global.frame.add { type = "button", caption = { 'resources.team-join', data.title }, name = 'choose_team_' .. data.name }.style.font_color = data.color
end)
global.frame.add { type = "button", caption = { "resources.team-auto-assign"}, name = "autoAssign" }
global.frame.add { type = "button", caption = { "resources.team-check-number" }, name = "team_number_check" }.style.font_color = { r = 0.9, g = 0.9, b = 0.9 }
end
end
function make_lobby()
game.create_surface("Lobby", { width = 96, height = 32, starting_area = "big", water = "none" })
end
function on_init(event)
make_lobby()
-- global information modified from initial config
if global.forcesData == nil then
global.forcesData = {}
end
if global.points == nil then
global.points = {
startingAreaRadius = 50, -- in this radius every tree will be destroyed
start = {
-- defines start point of map
x = 0,--math.random(220, 1060),
y = 0--math.random(220, 1060)
}, -- defines distance between spawn points for teams
distance = {
min = 1200,
max = 1800,
},
numberOfTrysBeforeError = 40 -- this is just a helper value (if we try to locate a non colliding point, we try it max XX times before we abort)
}
end
if global.distance == nil then
global.distance = 60 * 3
end
if global.big_distance == nil then
global.big_distance = 40 * 3 * 3
end
if global.researchMessage == nil then
global.researchMessage = {
enabled = true
}
end
if global.attackMessage == nil then
global.attackMessage = {
enabled = true,
interval = 5*MINUTES
}
end
if global.enableTeams == nil then
global.enableTeams = {
after = 30 * SECONDS, -- teams are eneabled after XX Seconds
messageInterval = 10 * SECONDS -- message interval /(when are the teams unlocked)
}
end
if global.teamBalance == nil then
global.teamBalance = {
enabled = true, -- wether team balance should be enabled or not
}
end
if global.teamMessageGui == nil then
global.teamMessageGui = {
enabled = true
}
end
if global.allianceGui == nil then
global.allianceGui = {
enabled = true,
changeAbleTick = 5 * MINUTES -- alliances could only be changed every XXX ticks
}
end
global._tick_helper = {};
global._tick_helper_v = {};
end
function on_player_created(event)
--Get the player that just joined
global.player = game.players[event.player_index]
--Take them to the lobby
global.player.teleport({ 0, 8 }, game.surfaces["Lobby"])
PrintToAllPlayers("A challenger has approached.")
--If the host player and configuration was not set.
if global.player.index == 1 and not isConfigWritten() then
PrintToAllPlayers('Creating configuration gui');
ConfigurationGui:createConfigurationGui(global.player);
end
--Print messages to new arrivals
if areTeamsEnabled() then
PrintToAllPlayers({"resources.please-select-team-msg"})
make_team_option(global.player)
else
PrintToAllPlayers({"resources.teams-have-not-been-set-msg"})
end
global.player.get_inventory(defines.inventory.player_ammo).clear();
global.player.get_inventory(defines.inventory.chest).clear();
global.player.get_inventory(defines.inventory.player_guns).clear();
global.player.get_inventory(defines.inventory.player_main).clear();
global.player.get_inventory(defines.inventory.player_quickbar).clear();
end
script.on_init(on_init);
script.on_event(defines.events.on_player_created, on_player_created);
function after_lobby_tick(event)
tick_all_helper(event.tick);
tick_all_helper_if_valid(event.tick);
end
function triggerTeamsEnabling()
global.TRIGGER_TEAMS_SECONDS = 10;
global.TICK_INTERVAL = global.TRIGGER_TEAMS_SECONDS * SECONDS;
PrintToAllPlayers({ "resources.teams-enable-wait-to-be-charted" })
-- PrintToAllPlayers('Wait for team areas to be charted');
global.checked_teams = {};
global.if_valid = function(tick)
PrintToAllPlayers("checking if valid")
for _, data in pairs(global.forcesData) do
PrintToAllPlayers(checked_teams[data.name])
if checked_teams[data.name] == nil then
PrintToAllPlayers("Checked teams is nil")
if is_area_charted(round_area_to_chunk_save(SquareArea(data.cords, global.big_distance)), global.s) == false then
PrintToAllPlayers("is area charted check")
--PrintToAllPlayers({ 'resources.teams-enable-not-charted-yet', data.title, seconds })
return false;
end
PrintToAllPlayers("set true for team")
--PrintToAllPlayers({ 'resources.team-area-charted', data.title })
checked_teams[data.name] = true;
end
end
return true;
end
global.tick_helper = function(tick)
table.each(global.forcesData, function(data)
MM_set_spawns(data);
MM_set_starting_area(data);
end)
setTeamsEnabled();
table.each(game.players, function(p)
make_team_option(p);
end)
end
register_tick_helper_if_valid('CREATE_TEAMS', global.tick_helper, global.tick_interval, global.if_valid);
end
function putPlayerInTeam(player, forceData)
global.s = game.surfaces['nauvis'];
global.player.teleport(game.forces[forceData.cName].get_spawn_position(global.s), global.s)
global.player.color = forceData.color
global.player.force = game.forces[forceData.cName]
player.gui.left.choose_team.destroy()
global.player.insert { name = "iron-plate", count = 8 }
global.player.insert { name = "pistol", count = 1 }
global.player.insert { name = "firearm-magazine", count = 10 }
global.player.insert { name = "burner-mining-drill", count = 1 }
global.player.insert { name = "stone-furnace", count = 1 }
Alliance:make_alliance_overlay_button(player);
TeamChat:make_team_chat_button(player);
PrintToAllPlayers({ 'teams.player-msg-team-join', global.player.name, forceData.title })
end
function couldJoinIntoForce(forceName)
if global.teamBalance.enabled == false then
return true;
end
global.check = {}
global.lastValue = 0;
global.onlyOne = false;
table.each(global.forcesData, function(data)
global.c = 0;
table.each(game.players, function(p)
if data.cName == global.player.force.name then c = c + 1 end
end)
check[data.cName] = global.c;
if global.lastValue == global.c then -- check if all teams have the same amount of players
global.onlyOne = true;
else
global.onlyOne = false;
end
global.lastValue = global.c
end)
if global.onlyOne == true then -- if all teams have the same amount of players, then it is possible to join this team
return true;
end
for k,v in spairs(check) do
return check[forceName] < v -- only join, if wanted force has fewer amount of players as the largest team
end
return true;
end
function lobby_tick(event)
tick_all_helper(event.tick);
tick_all_helper_if_valid(event.tick);
if game.tick >= global.CONFIG_WRITTEN_TIME + global.enableTeams.after then
-- fix if game is saved and reload during generation
PrintToAllPlayers("Are teams enabled:")
PrintToAllPlayers(areTeamsEnabledStartup())
--teamsEnablingStarted = areTeamsEnabledStartup();
if areTeamsEnabledStartup() == false then
--teamsEnablingStarted = true;
setTeamsEnabledStartup();
triggerTeamsEnabling();
end
elseif game.tick <= global.CONFIG_WRITTEN_TIME + global.enableTeams.after and game.tick % global.enableTeams.messageInterval == 0 then
global.enableTick = (global.CONFIG_WRITTEN_TIME + global.enableTeams.after) - game.tick;
global.seconds = Math.round(global.enableTick / SECONDS);
PrintToAllPlayers({ 'resources.teams-enable-in', global.seconds })
end
if (areTeamsEnabled()) then
script.on_event(defines.events.on_tick, nil)
script.on_event(defines.events.on_tick, after_lobby_tick)
end
end
script.on_event(defines.events.on_tick,
function(event)
if isConfigWritten() then
--PrintToAllPlayers("on_tick event - config written")
script.on_event(defines.events.on_tick, lobby_tick);
end
--fire armor
if event.tick % 60 == 0 then --common trick to reduce how often this runs, we don't want it running every tick, just 1/second
for index,player in pairs(game.connected_players) do --loop through all online players on the server
--if they're wearing our armor
if global.player.character and global.player.get_inventory(defines.inventory.player_armor).get_item_count("fire-armor") >= 1 then
--create the fire where they're standing
global.player.surface.create_entity{name="fire-flame", position=global.player.position, force="neutral"}
end
end
end
end
)
--Handling the gui clicks
script.on_event(defines.events.on_gui_click,
function(event)
global.s = game.surfaces.nauvis;
global.element = event.element
if global.element.valid ~= true then
return;
end
global.eventName = global.element.name;
global.player = game.players[event.player_index];
--Frame related
if global.eventName == 'next_step' then
ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].saveStep, global.player);
ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].destroyStep, global.player);
ConfigurationGui.currentStep = ConfigurationGui.steps[ConfigurationGui.currentStep].nextStep;
global.g = ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].createStep, global.player);
ConfigurationGui:createNextAndPrev(global.g);
elseif global.eventName == 'prev_step' then
ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].saveStep, global.player);
ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].destroyStep, global.player);
ConfigurationGui.currentStep = ConfigurationGui.steps[ConfigurationGui.currentStep].prevStep;
global.g = ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].createStep, global.player);
ConfigurationGui:createNextAndPrev(global.g);
elseif global.eventName == 'start_game' then
ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].saveStep, global.player);
ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].destroyStep, global.player);
PrintToAllPlayers({ "lobby.lobby-msg-config-finished", game.players[1].name })
make_forces()
setConfigWritten();
elseif global.eventName == 'force_cancel' then
if global.player.gui.center.create_force ~= nil and global.player.gui.center.create_force.valid then
global.player.gui.center.create_force.destroy();
end
ConfigurationGui:createNextAndPrev(ConfigurationGui.steps.teams.createFrame(global.player));
--Force related
elseif global.eventName == 'force_save' then
if global.player.gui.center.create_force ~= nil and global.player.gui.center.create_force.valid then
if global.player.gui.center.create_force.caption ~= nil then
global.forcesData[global.player.gui.center.create_force.caption] = nil;
end
global.forceData = ConfigurationGui.steps.teams.getForceData(global.player.gui.center.create_force);
if global.forceData.cName ~= '' then
global.forcesData[global.forceData.cName] = global.forceData;
global.player.gui.center.create_force.destroy();
end
end
ConfigurationGui:createNextAndPrev(ConfigurationGui.steps.teams.createFrame(global.player));
elseif global.eventName == 'force_remove' then
global.parent = global.element.parent;
table.each(global.forcesData, function(forceData, k)
if global.parent.name == 'force_frame_' .. forceData.name then
global.forcesData[k] = nil;
end
end)
ConfigurationGui:createNextAndPrev(ConfigurationGui.steps.teams.createFrame(global.player));
elseif string.match(global.eventName,'force_edit_(.*)') ~= nil then
table.each(global.forcesData, function(forceData)
if global.element.valid and global.element.name == 'force_edit_' .. forceData.name then
if global.player.gui.center.teams_gui ~= nil then
global.player.gui.center.teams_gui.destroy();
end
ConfigurationGui.steps.teams.createForceGuiWithData(global.player, forceData);
return;
end
end)
elseif global.eventName == 'force_new' then
if global.player.gui.center.teams_gui ~= nil then
global.player.gui.center.teams_gui.destroy();
end
ConfigurationGui.steps.teams.createForceGui(p);
--team realated
elseif global.eventName == 'team_number_check' then
table.each(global.forcesData, function(data)
global.c = 0;
table.each(game.players, function(p)
if data.cName == global.player.force.name then global.c = global.c + 1 end
end)
global.player.print({ 'resources.player-msg-team-number', data.title, global.c })
end)
elseif global.eventName == 'autoAssign' then
global.check = {}
table.each(global.forcesData, function(data)
global.c = 0;
table.each(game.players, function(p)
if data.cName == global.p.force.name then global.c = global.c + 1 end
end)
global.check[data.cName] = global.c;
end)
for k,v in spairs(global.check, function (t,a,b) return t[a] < t[b] end) do
putPlayerInTeam(global.player, global.forcesData[k]);
break
end
elseif string.match(global.eventName, 'choose_team_.*') ~= nil then
table.each(global.forcesData, function(data)
if global.eventName == 'choose_team_' .. data.name then
if couldJoinIntoForce(data.cName) then
putPlayerInTeam(global.player, data);
else
global.player.print( { 'resources.player-msg-could-not-join', data.title } )
end
end
end)
end
end
) --end event handler for gui click
-- Normal Events for game changes (launching rocket, dieing)
script.on_event(defines.events.on_rocket_launched, function(event)
local force = event.rocket.force
if event.rocket.get_item_count("satellite") > 0 then
if global.satellite_sent == nil then
global.satellite_sent = {}
end
if global.satellite_sent[force.name] == nil then
game.set_game_state { game_finished = true, player_won = true, can_continue = true }
global.satellite_sent[force.name] = 1
else
global.satellite_sent[force.name] = global.satellite_sent[force.name] + 1
end
for index, player in pairs(force.players) do
if global.player.gui.left.rocket_score == nil then
local frame = global.player.gui.left.add { name = "rocket_score", type = "frame", direction = "horizontal", caption = { "score" } }
frame.add { name = "rocket_count_label", type = "label", caption = { "", { "rockets-sent" }, "" } }
frame.add { name = "rocket_count", type = "label", caption = "1" }
else
global.player.gui.left.rocket_score.rocket_count.caption = tostring(global.satellite_sent[force.name])
end
end
else
if (#game.players <= 1) then
game.show_message_dialog { text = { "gui-rocket-silo.rocket-launched-without-satellite" } }
else
for index, player in pairs(force.players) do
global.player.print({ "gui-rocket-silo.rocket-launched-without-satellite" })
end
end
end
end)
script.on_event(defines.events.on_research_started, function(event)
if global.researchMessage.enabled then
local force = event.research.force
PrintToAllPlayers({ 'teams.team-research-start', global.forcesData[force.name].title, { 'research-name' .. event.research.name } })
-- ResearchNotification.log('Team ' .. force.name .. ' has starting research ' .. event.research.name, force.name);
end
end)
script.on_event(defines.events.on_research_finished, function(event)
if global.researchMessage.enabled then
local force = event.research.force
PrintToAllPlayers({ 'teams.team-research-end', global.forcesData[force.name].title, { 'research-name' .. event.research.name } })
end
end)
script.on_event(defines.events.on_entity_died, function(event)
if global.attackMessage.enabled then
global.entity = event.entity;
global.force = event.force;
if global.force ~= nil and global.entity.force.name ~= 'neutral' then
if global.entity.force.name == 'enemy' then
if global.entity.name ~= "spitter-spawner"
and global.entity.name ~= "biter-spawner"
and global.entity.name ~= "small-worm-turret"
and global.entity.name ~= "medium-worm-turret"
and global.entity.name ~= "big-worm-turret"
then
return
end
end
if global.entity.force ~= nil and global.entity.force ~= global.force then
global.attacked = global.entity.force.name;
global.attackedFrom = global.force.name;
if global.attacked == 'enemy' then
global.attacked = 'Aliens'
end
if global.attackedFrom == 'enemy' then
global.attackedFrom = 'Aliens';
end
PrintToAllPlayers({ 'teams.team-attacked-by-team', global.attacked, global.attackedFrom })
end
end
end
end)
For reference, the gui that configuration setup is through is laid out in the following configuration_gui.lua
Code: Select all
ConfigurationGui = {}
ConfigurationGui.steps = {
teams = {
prevStep = nil,
nextStep = 'enable',
caption = { 'resources-gui.forces-gui-caption' },
createFrame = function(player)
--if it already exists, close it
if player.gui.center.teams_gui ~= nil then
player.gui.center.teams_gui.destroy();
end
--create the frame
global.frame = ConfigurationGui:createFrame(player.gui.center, 'teams_gui', { 'resources-gui.create-gui-caption' });
PrintToAllPlayers("Debug for table each.")
table.each(global.forcesData, function(forceData)
global.forceFrame = global.frame.add {
name = 'force_frame_' .. forceData.name,
type = 'flow',
direction = 'horizontal'
}
global.forceFrame.add {
type = 'label',
--name = 'name', @2.1.1
caption = forceData.title
}.style.font_color = forceData.color
global.forceFrame.add {
type = 'button',
name = 'force_edit_' .. forceData.name,
caption = { 'resources-gui.force-edit-caption' }
}
if game.forces[forceData.name] == nil then
global.forceFrame.add {
type = 'button',
name = 'force_remove',
caption = { 'resources-gui.force-remove-caption' }
}
end
end)
global.frame.add {
type = 'button',
name = 'force_new',
caption = { 'resources-gui.force-new-caption' }
}
return global.frame;
end,
createForceGuiWithData = function(player, forceData)
if global.player.gui.center.create_force ~= nil then
global.player.gui.center.create_force.destroy();
end
global.frame = ConfigurationGui:createFrame(global.player.gui.center, 'create_force', { 'resources-gui.create-gui-caption' });
if forceData.cName ~= '' then
global.frame.caption = forceData.cName;
end
for k, v in pairs({
'name',
'title',
'cName'
}) do
global.flow = global.frame.add {
type = 'flow',
name = "force_" .. v,
direction = 'vertical'
}
global.flow.add {
type = "label",
caption = { 'resources-gui.force-' .. v .. '-caption' }
}
global.flow.add {
name = "textfield",
type = "textfield",
text = forceData[v],
}
end
global.color = global.frame.add {
type = 'frame',
direction = 'vertical',
name = 'color',
caption = { 'resources-gui.force-color-caption' }
}
global.forceColor = ConfigurationGui:colorToRgb(forceData.color)
for k, v in pairs(global.forceColor) do
global.flow = global.color.add {
type = 'flow',
direction = 'horizontal',
name = k
}
global.flow.add {
type = "label",
caption = { 'resources-gui.force-color-' .. k .. '-caption' }
}
global.flow.add {
name = "textfield",
text = v,
type = "textfield",
}
end
global.frame.add {
type = 'button',
name = 'force_cancel',
caption = { 'resources-gui.force-cancel-caption' }
}
global.frame.add {
type = 'button',
name = 'force_save',
caption = { 'resources-gui.force-save-caption' }
}
end,
createForceGui = function(player)
local forceData = {
name = "",
title = "",
cName = '',
color = { r = 1, g = 1, b = 1, a = 1 }
}
ConfigurationGui.steps.teams.createForceGuiWithData(player, forceData);
end,
getForceData = function(frame)
return {
name = frame.force_name.textfield.text,
title = frame.force_title.textfield.text,
cName = frame.force_cName.textfield.text,
color = ConfigurationGui:rgbToColor({
r = frame.color.r.textfield.text,
g = frame.color.g.textfield.text,
b = frame.color.b.textfield.text,
a = frame.color.a.textfield.text
})
}
end,
createStep = function(player)
return ConfigurationGui.steps.teams.createFrame(player);
end,
saveStep = function(player) end,
destroyStep = function(player)
if player.gui.center.teams_gui ~= nil then
player.gui.center.teams_gui.destroy();
end
end
},
enable = {
prevStep = 'teams',
nextStep = 'points',
caption = { 'enable-gui.caption' },
createStep = function(player)
global.frame = ConfigurationGui:createFrame(player.gui.center, 'enable_gui', { 'enable-gui.caption' });
--table.each({
-- "attackMessage",
-- "researchMessage",
-- "teamMessageGui",
-- "allianceGui",
-- "teamBalance"
-- },
--function(name)
ConfigurationGui:createCheckboxFlow(global.frame, "attackMessage", { 'enable-gui.label-' .. "attackMessage" }, global.attackMessage.enabled)
ConfigurationGui:createCheckboxFlow(global.frame, "researchMessage", { 'enable-gui.label-' .. "researchMessage" }, global.researchMessage.enabled)
ConfigurationGui:createCheckboxFlow(global.frame, "teamMessageGui", { 'enable-gui.label-' .. "teamMessageGui" }, global.teamMessageGui.enabled)
ConfigurationGui:createCheckboxFlow(global.frame, "allianceGui", { 'enable-gui.label-' .. "allianceGui" }, global.allianceGui.enabled)
ConfigurationGui:createCheckboxFlow(global.frame, "teamBalance", { 'enable-gui.label-' .. "teamBalance" }, global.teamBalance.enabled)
--end
--)
return global.frame
end,
saveStep = function(player)
--table.each({
-- "attackMessage",
-- "researchMessage",
-- "teamMessageGui",
-- "allianceGui",
-- "teamBalance"
--},
--function(name)
global.attackMessage.enabled = player.gui.center.enable_gui["attackMessage"].checkbox.state
global.researchMessage.enabled = player.gui.center.enable_gui["researchMessage"].checkbox.state
global.teamMessageGui.enabled = player.gui.center.enable_gui["teamMessageGui"].checkbox.state
global.allianceGui.enabled = player.gui.center.enable_gui["allianceGui"].checkbox.state
global.teamBalance.enabled = player.gui.center.enable_gui["teamBalance"].checkbox.state
-- end
-- )
end,
destroyStep = function(player)
if player.gui.center.enable_gui ~= nil then
player.gui.center.enable_gui.destroy();
end
end
},
points = {
prevStep = 'enable',
nextStep = nil,
caption = { 'point-gui.caption' },
createStep = function(player)
global.frame = ConfigurationGui:createFrame(player.gui.center, 'point_gui', { 'point-gui.caption' });
ConfigurationGui:createTextFieldFlow(global.frame, 'startingAreaRadius', { 'point-gui.label-startingAreaRadius' }, global.points.startingAreaRadius);
ConfigurationGui:createTextFieldFlow(global.frame, 'pointsMin', { 'point-gui.label-distance-min' }, global.points.distance.min);
ConfigurationGui:createTextFieldFlow(global.frame, 'pointsMax', { 'point-gui.label-distance-max' }, global.points.distance.max);
ConfigurationGui:createTextFieldFlow(global.frame, 'd', { 'point-gui.label-distance' }, global.distance);
ConfigurationGui:createTextFieldFlow(global.frame, 'bd', { 'point-gui.label-big-distance' }, global.big_distance);
return global.frame;
end,
saveStep = function(player)
global.gui = player.gui.center.point_gui;
global.distance = tonumber(global.gui.d.textfield.text);
global.big_distance = tonumber(global.gui.bd.textfield.text);
global.points.startingAreaRadius = tonumber(global.gui.startingAreaRadius.textfield.text);
global.points.distance.min = tonumber(global.gui.pointsMin.textfield.text);
global.points.distance.max = tonumber(global.gui.pointsMax.textfield.text);
end,
destroyStep = function(player)
if player.gui.center.point_gui ~= nil then
player.gui.center.point_gui.destroy();
end
end
}
}
function ConfigurationGui:createNextAndPrev(gui)
global.f = gui.add {
type = 'flow',
direction = 'horizontal'
}
global.s = ConfigurationGui.steps[ConfigurationGui.currentStep];
if global.s.prevStep ~= nil then
global.f.add {
type = 'button',
name = 'prev_step',
caption = { '', '< ', ConfigurationGui.steps[global.s.prevStep].caption }
}
end
if global.s.nextStep == nil then
if global.forcesData ~= nil and table.length(global.forcesData) > 0 then
global.f.add {
type = 'button',
name = 'start_game',
caption = { 'config-gui.start' }
}
else
global.f.add {
type = 'label',
caption = { 'config-gui.min-one-team' }
}
end
else
global.f.add {
type = 'button',
name = 'next_step',
caption = { '', ConfigurationGui.steps[global.s.nextStep].caption, ' >' }
}
end
end
ConfigurationGui.currentStep = 'teams';
function ConfigurationGui:createConfigurationGui(player)
-- init first step
global.g = ConfigurationGui:try(ConfigurationGui.steps[ConfigurationGui.currentStep].createStep, player);
ConfigurationGui:createNextAndPrev(global.g);
end
function ConfigurationGui:try(f, ...)
global.status, r = pcall(f, ...);
if not global.status then
PrintToAllPlayers(r);
end
return r;
end
function ConfigurationGui:createFrame(parent, name, caption)
return parent.add {
type = 'frame',
name = name,
direction = 'vertical',
caption = caption
}
end
function ConfigurationGui:createTextFieldFlow(gui, name, caption, value)
global.flow = gui.add {
type = 'flow',
direction = 'horizontal',
name = name
}
global.flow.add {
type = "label",
caption = caption
}
global.flow.add {
name = "textfield",
type = "textfield",
text = value,
}
end
function ConfigurationGui:createCheckboxFlow(gui, name, caption, value)
global.flow = gui.add {
type = 'flow',
direction = 'horizontal',
name = name
}
global.flow.add {
type = "label",
caption = caption
}
global.flow.add {
name = "checkbox",
type = "checkbox",
state = value,
}
end
function ConfigurationGui:colorToRgb(color)
return {
r = color.r * 255,
g = color.g * 255,
b = color.b * 255,
a = color.a
}
end
function ConfigurationGui:rgbToColor(rgb)
return {
r = rgb.r / 255,
g = rgb.g / 255,
b = rgb.b / 255,
a = rgb.a
}
end