Last active
November 4, 2019 23:53
-
-
Save wende/ba26e224d4fb65a9fcd53d4fd5aab327 to your computer and use it in GitHub Desktop.
BlueBuild - Fixed demo for longreach, optimized and fix for recent print bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Find ghosts to place. Then find buildings to destruct. | |
function runOnce() | |
global.runOnce = true | |
if not global.blueBuildFirstTick then | |
global.blueBuildFirstTick = {} | |
end | |
if not global.bluePositions then | |
global.bluePosition = {} | |
end | |
if not global.blueBuildToggle then | |
global.blueBuildToggle = {} | |
end | |
if not global.blueDemoToggle then | |
global.blueDemoToggle = {} | |
end | |
if not global.blueLastDemo then | |
global.blueLastDemo = {} | |
end | |
if not global.ghostWannabes then | |
global.ghostWannabes = {} | |
end | |
for n, p in pairs(game.players) do | |
initPlayer(p) | |
end | |
end | |
function initPlayer(player) | |
player.print("Initializing Bluebuild.") | |
global.blueBuildToggle[player.index] = true | |
global.blueDemoToggle[player.index] = true | |
global.blueBuildFirstTick[player.index] = game.tick | |
global.blueLastDemo[player.index] = game.tick | |
global.ghostWannabes[player.index] = {} | |
end | |
function playerloop() | |
for _, player in pairs(game.players) do | |
if player.connected then | |
if global.blueBuildFirstTick[player.index] and game.tick > global.blueBuildFirstTick[player.index] + 5 then | |
bluecheck(player) | |
end | |
end | |
end | |
end | |
function bluecheck(builder) | |
local pos = builder.position | |
--game.print("Checking player.") | |
-- if global.bluePosition[builder.index] and global.bluePosition[builder.index] == pos then | |
if global.bluePosition[builder.index] and global.bluePosition[builder.index].x == pos.x and global.bluePosition[builder.index].y == pos.y then | |
--We haven't moved. Good, let's continue. | |
--game.print("Player hasn't moved.") | |
if global.blueBuildToggle[builder.index] then | |
-- Make magic happen. | |
if bluebuild(builder) == true then | |
global.blueBuildFirstTick[builder.index] = game.tick | |
return | |
end | |
end | |
if global.blueBuildToggle[builder.index] then | |
if blueUpgrade(builder) == true then | |
global.blueBuildFirstTick[builder.index] = game.tick | |
return | |
end | |
end | |
--Still here? Sleep for 6 ticks anyway. | |
global.blueBuildFirstTick[builder.index] = game.tick | |
if global.blueDemoToggle[builder.index] == true then | |
--if global.blueLastDemo[builder.index] and game.tick > global.blueLastDemo[builder.index] + 5 then | |
--global.blueLastDemo[builder.index] = game.tick | |
-- Destructive magic happens here | |
if bluedemo(builder) == true then | |
global.blueBuildFirstTick[builder.index] = game.tick | |
return | |
--game.print("Last demo " .. global.blueLastDemo[builder.index] .. " current tick " .. game.tick) | |
--global.blueBuildFirstTick[builder.index] = game.tick | |
--global.blueLastDemo[builder.index] = game.tick | |
end | |
--end | |
end | |
else | |
-- Player moved. Reset progress. | |
global.bluePosition[builder.index] = pos | |
global.blueBuildFirstTick[builder.index] = game.tick | |
end | |
end | |
function bluebuild(builder) | |
local pos = builder.position | |
--local searchArea = {{pos.x - reachDistance, pos.y - reachDistance}, {pos.x + reachDistance, pos.y + reachDistance}} | |
-- Bluebuild 1.1 - Switch to a maintained list of ghosts instead of constant searching. | |
if (not global.ghosts) or (not global.ghosts[builder.surface.name]) then | |
return | |
end | |
--areaList = global.ghosts[builder.surface.name] | |
local areaList = builder.surface.find_entities_filtered{position = pos, radius = builder.reach_distance, type = {"entity-ghost", "tile-ghost"}, force=builder.force, limit=200 } | |
--local tileList = builder.surface.find_entities_filtered{position = pos, radius = builder.reach_distance, type = "tile-ghost", force=builder.force } | |
-- Merge the lists | |
-- for key, value in pairs(tileList) do | |
-- if not areaList then | |
-- areaList = {} | |
-- end | |
-- table.insert(areaList, value) | |
-- end | |
-- game.print("Found " .. #areaList .. " ghosts in area.") | |
for index, ghost in pairs(areaList) do | |
if ghost == nil or not ghost.valid then | |
table.remove(areaList, index) | |
return false | |
end | |
--if builder.can_reach_entity(ghost) and builder.force == ghost.force then | |
-- Need a fudge factor since my distance formula seems off. Game likely measures from nearest colliding point? | |
--if ghost.force == builder.force and distance(builder, ghost) < math.min(builder.build_distance + 1, 128) then | |
if ghost.force == builder.force and builder.can_reach_entity(ghost) then | |
-- game.print("Checking for items in inventory.") | |
local materials = ghost.ghost_prototype.items_to_place_this | |
local moduleList | |
if ghost.type == "entity-ghost" then | |
moduleList = ghost.item_requests --{"name"=..., "count"=...} | |
end | |
for __, item in pairs(materials) do | |
if builder.get_item_count(item.name) >= item.count then | |
if ghost.type == "tile-ghost" then | |
builder.remove_item({name=item.name, count=item.count}) | |
ghost.revive() | |
return true | |
end | |
local tmp, revive = ghost.revive() | |
-- game.print("Placing item " .. revive.name .. ".") | |
if revive and revive.valid then | |
for module, modulecount in pairs(moduleList) do | |
-- game.print("moduleList == " .. moduleItem.item ) | |
if builder.get_item_count(module) > 0 then | |
local modStack = {name=module, count=math.min(builder.get_item_count(module), modulecount)} | |
revive.insert(modStack) | |
builder.remove_item(modStack) | |
end | |
end | |
-- game.print("Removing item from inventory.") | |
--"revive" flag is just a way to signal to other mods that this was raised by script. | |
script.raise_event(defines.events.on_put_item, {position=revive.position, player_index=builder.index, shift_build=false, built_by_moving=false, direction=revive.direction, revive=true}) | |
script.raise_event(defines.events.on_built_entity, {created_entity=revive, player_index=builder.index, tick=game.tick, name="on_built_entity", revive=true}) | |
table.remove(areaList, index) | |
builder.remove_item({name=item.name, count=item.count}) | |
return true | |
end | |
end | |
end | |
end | |
end | |
-- Are we still here? | |
return false | |
end | |
function bluedemo(builder) | |
local pos = builder.position | |
if not global.blueLastDemo[builder.index] then | |
initPlayer(builder.index) | |
end | |
--Now calculate mining time and destroy | |
for index, ent in pairs(global.ghostWannabes[builder.index]) do | |
if ent and distance(builder, ent) < builder.reach_distance then | |
if ent.name == "deconstructible-tile-proxy" then --In case we're trying to demo floor tiles. | |
tile = ent.surface.get_tile(ent.position) | |
--game.print(ent.prototype.mineable_properties) | |
builder.mine_tile(tile) | |
remove_wannabe(builder.index, ent) | |
return true | |
end | |
--Mining time is player... Nevermind, player.mining_power does not yet exist. We'll just assume mining power of 2.5 (iron pickaxe) | |
-- TODO: This is busted. Everything is mining instantly! | |
if ent.prototype.mineable_properties.mining_time * 60 + global.blueLastDemo[builder.index] < game.tick then | |
-- This might all be obsolete now thanks to player.mine_entity(entity) | |
--global.blueLastDemo[builder.index] = game.tick | |
if builder.mine_entity(ent) then | |
remove_wannabe(builder.index, ent) | |
return true | |
end --Could not mine target for whatever reason. Inventory probably full. | |
end | |
end | |
end | |
return false | |
end | |
function blueUpgrade(builder) | |
local pos = builder.position | |
local reachDistance = math.max(math.min(builder.reach_distance, 128), 1) | |
local areaList = builder.surface.find_entities_filtered{position = pos, radius = reachDistance, to_be_upgraded=true, limit=150} | |
for _, target in pairs(areaList) do | |
local itemsNeeded = target and target.valid and target.get_upgrade_target() and target.get_upgrade_target().items_to_place_this[1] | |
local upgrade = target.get_upgrade_target() | |
if itemsNeeded and builder.get_item_count(itemsNeeded.name) >= itemsNeeded.count then | |
builder.remove_item{name=itemsNeeded.name, count=itemsNeeded.count} | |
builder.surface.play_sound{position=target.position, path="entity-build/" .. upgrade.name} | |
builder.surface.create_entity{position=target.position, name=upgrade.name, force=builder.force, direction=target.direction, fast_replace=true, player=builder, raise_built=true} | |
return true | |
end | |
end | |
end | |
--Reinventing the wheel | |
function distance(ent1, ent2) | |
return math.floor( math.sqrt( (ent1.position.x - ent2.position.x)^2 + (ent1.position.y - ent2.position.y)^2 ) ) | |
end | |
function updateGhosts() | |
if not global.ghosts then | |
global.ghosts = {} | |
end | |
for __, surface in pairs(game.surfaces) do | |
-- type(surface) is string | |
if not global.ghosts[surface.name] then | |
global.ghosts[surface.name] = {} | |
end | |
global.ghosts[surface.name] = game.surfaces[surface.name].find_entities_filtered{name="entity-ghost"} | |
end | |
end | |
function remove_wannabe(player_index, entity) | |
for index, et in pairs(global.ghostWannabes[player_index]) do | |
if et and et == entity then | |
global.ghostWannabes[player_index][index] = nil | |
end | |
end | |
end | |
script.on_event(defines.events.on_built_entity, function(event) | |
if not global.ghosts then | |
global.ghosts = {} | |
end | |
if event.created_entity and (event.created_entity.name == "entity-ghost" or event.created_entity.name == "tile-ghost") then | |
if not global.ghosts[event.created_entity.surface.name] then | |
global.ghosts[event.created_entity.surface.name] = {} | |
end | |
table.insert(global.ghosts[event.created_entity.surface.name], event.created_entity) | |
end | |
end) | |
script.on_event(defines.events.on_player_joined_game, function(event) | |
initPlayer(game.players[event.player_index]) | |
end) | |
script.on_event(defines.events.on_tick, function(event) | |
playerloop() | |
-- Update ghost list every 5 minutes. | |
-- if (game.tick + 500) % (60 * 60 * 5) == 0 then | |
-- updateGhosts() | |
-- end | |
end) | |
script.on_event(defines.events.on_marked_for_deconstruction, function(event) | |
if not global.ghostWannabes[event.player_index] then | |
global.ghostWannabes[event.player_index] = {} | |
end | |
table.insert(global.ghostWannabes[event.player_index], event.entity) | |
end) | |
script.on_event(defines.events.on_cancelled_deconstruction, function(event) | |
remove_wannabe(event.player_index, event.entity) | |
end) | |
script.on_event('bluebuild-autobuild', function(event) | |
global.blueBuildToggle[event.player_index] = not global.blueBuildToggle[event.player_index] | |
game.players[event.player_index].print("Bluebuild autobuild set to " .. tostring(global.blueBuildToggle[event.player_index]) .. ".") | |
global.blueBuildFirstTick[event.player_index] = game.tick | |
end) | |
script.on_event('bluebuild-autodemo', function(event) | |
global.blueDemoToggle[event.player_index] = not global.blueDemoToggle[event.player_index] | |
game.players[event.player_index].print("Bluebuild autodemo set to " .. tostring(global.blueDemoToggle[event.player_index]) .. ".") | |
global.blueBuildFirstTick[event.player_index] = game.tick | |
end) | |
script.on_init(function() | |
runOnce() | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bec1f45ac439bb004e3e211d011be1872c0616eb Adds removing demolition when player cancelled it