2021-02-06 22:42:10 +02:00
local table_insert = table.insert
2022-09-30 22:23:37 +02:00
local ScenarioTable = require ' maps.scrap_towny_ffa.table '
local Town_center = require ' maps.scrap_towny_ffa.town_center '
2022-10-09 12:11:38 +02:00
local PvPShield = require ' maps.scrap_towny_ffa.pvp_shield '
2021-02-06 22:42:10 +02:00
local upgrade_functions = {
2021-03-24 17:46:00 +02:00
-- Upgrade Town Center Health
[ 1 ] = function ( town_center , player )
local market = town_center.market
local surface = market.surface
2022-09-22 20:19:19 +02:00
if town_center.max_health > 50000 then
2022-03-01 19:55:02 +02:00
return false
2021-03-24 17:46:00 +02:00
end
town_center.health = town_center.health + town_center.max_health
town_center.max_health = town_center.max_health * 2
Town_center.set_market_health ( market , 0 )
surface.play_sound ( { path = ' utility/achievement_unlocked ' , position = player.position , volume_modifier = 1 } )
2022-03-01 19:55:02 +02:00
return true
2021-03-24 17:46:00 +02:00
end ,
-- Upgrade Backpack
[ 2 ] = function ( town_center , player )
local market = town_center.market
local force = market.force
local surface = market.surface
2022-10-08 13:06:46 +02:00
if force.character_inventory_slots_bonus + 5 > 50 then
2022-03-01 19:55:02 +02:00
return false
2021-03-24 17:46:00 +02:00
end
force.character_inventory_slots_bonus = force.character_inventory_slots_bonus + 5
surface.play_sound ( { path = ' utility/achievement_unlocked ' , position = player.position , volume_modifier = 1 } )
2022-03-01 19:55:02 +02:00
return true
2021-03-24 17:46:00 +02:00
end ,
-- Upgrade Mining Productivity
[ 3 ] = function ( town_center , player )
local market = town_center.market
local force = market.force
local surface = market.surface
2022-03-01 19:55:02 +02:00
if town_center.upgrades . mining_prod + 1 > 10 then
return false
2021-03-24 17:46:00 +02:00
end
town_center.upgrades . mining_prod = town_center.upgrades . mining_prod + 1
force.mining_drill_productivity_bonus = force.mining_drill_productivity_bonus + 0.1
surface.play_sound ( { path = ' utility/achievement_unlocked ' , position = player.position , volume_modifier = 1 } )
2022-03-01 19:55:02 +02:00
return true
2021-03-24 17:46:00 +02:00
end ,
2022-03-01 19:55:02 +02:00
-- Upgrade Pickaxe Speed
2021-03-24 17:46:00 +02:00
[ 4 ] = function ( town_center , player )
2022-03-01 19:55:02 +02:00
local market = town_center.market
local force = market.force
local surface = market.surface
if town_center.upgrades . mining_speed + 1 > 10 then
return false
end
town_center.upgrades . mining_speed = town_center.upgrades . mining_speed + 1
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 0.1
surface.play_sound ( { path = ' utility/achievement_unlocked ' , position = player.position , volume_modifier = 1 } )
return true
end ,
-- Upgrade Crafting Speed
[ 5 ] = function ( town_center , player )
local market = town_center.market
local force = market.force
local surface = market.surface
if town_center.upgrades . crafting_speed + 1 > 10 then
return false
end
town_center.upgrades . crafting_speed = town_center.upgrades . crafting_speed + 1
force.manual_crafting_speed_modifier = force.manual_crafting_speed_modifier + 0.1
surface.play_sound ( { path = ' utility/achievement_unlocked ' , position = player.position , volume_modifier = 1 } )
return true
end ,
-- Laser Turret Slot
[ 6 ] = function ( town_center , player )
2021-03-24 17:46:00 +02:00
local market = town_center.market
local surface = market.surface
town_center.upgrades . laser_turret.slots = town_center.upgrades . laser_turret.slots + 1
surface.play_sound ( { path = ' utility/new_objective ' , position = player.position , volume_modifier = 1 } )
2022-03-01 19:55:02 +02:00
return true
2021-03-24 17:46:00 +02:00
end ,
-- Set Spawn Point
2022-03-01 19:55:02 +02:00
[ 7 ] = function ( town_center , player )
2022-09-30 22:23:37 +02:00
local this = ScenarioTable.get_table ( )
2021-03-24 17:46:00 +02:00
local market = town_center.market
local force = market.force
local surface = market.surface
local spawn_point = force.get_spawn_position ( surface )
2022-10-04 17:51:22 +02:00
this.spawn_point [ player.index ] = spawn_point
2021-03-24 17:46:00 +02:00
surface.play_sound ( { path = ' utility/scenario_message ' , position = player.position , volume_modifier = 1 } )
2022-03-01 19:55:02 +02:00
return false
2022-10-09 12:11:38 +02:00
end ,
-- Pause-mode PvP Shield
[ 8 ] = function ( town_center , player )
local this = ScenarioTable.get_table ( )
local market = town_center.market
local force = market.force
local surface = market.surface
local shield_lifetime_ticks = 10 * 60 * 60
if not this.pvp_shields [ player.force . name ] then
-- Double-check with the player to prevent accidental clicks
if this.pvp_shield_warned [ player.force . name ] ~= nil and game.tick - this.pvp_shield_warned [ player.force . name ] < 60 * 60 then
if not Town_center.enemy_players_nearby ( town_center , 100 ) then
PvPShield.add_shield ( surface , force , market.position , shield_lifetime_ticks , 2 * 60 * 60 , true )
surface.play_sound ( { path = ' utility/scenario_message ' , position = player.position , volume_modifier = 1 } )
this.pvp_shield_warned [ player.force . name ] = nil
else
player.print ( " Enemy players are too close, can't deploy PvP shield " )
end
else
player.force . print ( ' You have requested a temporary PvP shield. This will freeze all players in your town for ' .. string.format ( " %.0f " , shield_lifetime_ticks / 60 / 60 ) .. ' minutes to take a break. Click again to confirm. ' )
this.pvp_shield_warned [ player.force . name ] = game.tick
end
else
player.print ( " Your town already has a PvP shield " )
end
return false
2021-03-24 17:46:00 +02:00
end
2021-02-06 22:42:10 +02:00
}
local function clear_offers ( market )
2021-03-24 17:46:00 +02:00
for _ = 1 , 256 , 1 do
local a = market.remove_market_item ( 1 )
if a == false then
return
end
end
2021-02-06 22:42:10 +02:00
end
local function set_offers ( town_center )
2021-03-24 17:46:00 +02:00
local market = town_center.market
local force = market.force
2022-03-01 19:55:02 +02:00
local market_items = { }
2021-02-06 22:42:10 +02:00
2022-03-01 19:55:02 +02:00
-- special offers
2021-03-24 17:46:00 +02:00
local special_offers = { }
2022-09-22 20:19:19 +02:00
if town_center.max_health < 50000 then
2021-03-24 17:46:00 +02:00
special_offers [ 1 ] = { { { ' coin ' , town_center.max_health * 0.1 } } , ' Upgrade Town Center Health ' }
else
2022-03-01 19:55:02 +02:00
special_offers [ 1 ] = { { } , ' Maximum Health upgrades reached! ' }
2021-03-24 17:46:00 +02:00
end
2022-10-08 13:06:46 +02:00
if force.character_inventory_slots_bonus + 5 <= 50 then
2021-03-24 17:46:00 +02:00
special_offers [ 2 ] = { { { ' coin ' , ( force.character_inventory_slots_bonus / 5 + 1 ) * 50 } } , ' Upgrade Backpack +5 Slot ' }
else
2022-03-01 19:55:02 +02:00
special_offers [ 2 ] = { { } , ' Maximum Backpack upgrades reached! ' }
2021-03-24 17:46:00 +02:00
end
2022-03-01 19:55:02 +02:00
if town_center.upgrades . mining_prod + 1 <= 10 then
2022-10-04 17:37:29 +02:00
special_offers [ 3 ] = { { { ' coin ' , ( town_center.upgrades . mining_prod + 1 ) * 1000 } } , ' Upgrade Mining Productivity +10% (Drills, Pumps, Scrap) ' }
2021-03-24 17:46:00 +02:00
else
2022-03-01 19:55:02 +02:00
special_offers [ 3 ] = { { } , ' Maximum Productivity upgrades reached! ' }
end
if town_center.upgrades . mining_speed + 1 <= 10 then
special_offers [ 4 ] = { { { ' coin ' , ( town_center.upgrades . mining_speed + 1 ) * 400 } } , ' Upgrade Mining Speed +10% ' }
else
special_offers [ 4 ] = { { } , ' Maximum Mining Speed upgrades reached! ' }
end
if town_center.upgrades . crafting_speed + 1 <= 10 then
special_offers [ 5 ] = { { { ' coin ' , ( town_center.upgrades . crafting_speed + 1 ) * 400 } } , ' Upgrade Crafting Speed +10% ' }
else
special_offers [ 5 ] = { { } , ' Maximum Crafting Speed upgrades reached! ' }
2021-03-24 17:46:00 +02:00
end
local laser_turret = ' Laser Turret Slot [# ' .. tostring ( town_center.upgrades . laser_turret.slots + 1 ) .. ' ] '
2022-10-07 09:50:19 +02:00
special_offers [ 6 ] = { { { ' coin ' , ( town_center.upgrades . laser_turret.slots * 150 ) } } , laser_turret }
2021-03-24 17:46:00 +02:00
local spawn_point = ' Set Spawn Point '
2022-03-01 19:55:02 +02:00
special_offers [ 7 ] = { { } , spawn_point }
2022-10-09 12:11:38 +02:00
special_offers [ 8 ] = { { } , ' Temporary PvP Shield for pause/AFK ' }
2021-03-24 17:46:00 +02:00
for _ , v in pairs ( special_offers ) do
table_insert ( market_items , { price = v [ 1 ] , offer = { type = ' nothing ' , effect_description = v [ 2 ] } } )
end
2021-02-06 22:42:10 +02:00
2022-09-22 20:19:19 +02:00
-- item purchases
table_insert ( market_items , { price = { { ' coin ' , 25 } } , offer = { type = ' give-item ' , item = ' raw-fish ' , count = 1 } } )
table_insert ( market_items , { price = { { ' coin ' , 6 } } , offer = { type = ' give-item ' , item = ' wood ' , count = 1 } } )
2021-03-24 17:46:00 +02:00
table_insert ( market_items , { price = { { ' coin ' , 1 } } , offer = { type = ' give-item ' , item = ' iron-ore ' , count = 6 } } )
table_insert ( market_items , { price = { { ' coin ' , 1 } } , offer = { type = ' give-item ' , item = ' copper-ore ' , count = 6 } } )
table_insert ( market_items , { price = { { ' coin ' , 1 } } , offer = { type = ' give-item ' , item = ' stone ' , count = 6 } } )
table_insert ( market_items , { price = { { ' coin ' , 1 } } , offer = { type = ' give-item ' , item = ' coal ' , count = 6 } } )
2022-09-22 20:19:19 +02:00
table_insert ( market_items , { price = { { ' coin ' , 1 } } , offer = { type = ' give-item ' , item = ' uranium-ore ' , count = 2 } } )
2022-10-08 15:10:44 +02:00
table_insert ( market_items , { price = { { ' coin ' , 500 } } , offer = { type = ' give-item ' , item = ' laser-turret ' , count = 1 } } )
2021-03-24 17:46:00 +02:00
table_insert ( market_items , { price = { { ' coin ' , 300 } } , offer = { type = ' give-item ' , item = ' loader ' , count = 1 } } )
table_insert ( market_items , { price = { { ' coin ' , 600 } } , offer = { type = ' give-item ' , item = ' fast-loader ' , count = 1 } } )
table_insert ( market_items , { price = { { ' coin ' , 900 } } , offer = { type = ' give-item ' , item = ' express-loader ' , count = 1 } } )
2022-09-22 20:19:19 +02:00
-- item selling
table_insert ( market_items , { price = { { ' raw-fish ' , 1 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 20 } } )
table_insert ( market_items , { price = { { ' wood ' , 1 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 5 } } )
2021-03-24 17:46:00 +02:00
table_insert ( market_items , { price = { { ' iron-ore ' , 7 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
table_insert ( market_items , { price = { { ' copper-ore ' , 7 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
table_insert ( market_items , { price = { { ' stone ' , 7 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
table_insert ( market_items , { price = { { ' coal ' , 7 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
2022-09-22 20:19:19 +02:00
table_insert ( market_items , { price = { { ' uranium-ore ' , 3 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
2021-03-24 17:46:00 +02:00
table_insert ( market_items , { price = { { ' copper-cable ' , 12 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
table_insert ( market_items , { price = { { ' iron-gear-wheel ' , 3 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
table_insert ( market_items , { price = { { ' iron-stick ' , 12 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
table_insert ( market_items , { price = { { ' empty-barrel ' , 1 } } , offer = { type = ' give-item ' , item = ' coin ' , count = 1 } } )
2021-02-06 22:42:10 +02:00
2021-03-24 17:46:00 +02:00
for _ , item in pairs ( market_items ) do
market.add_market_item ( item )
end
2021-02-06 22:42:10 +02:00
end
local function refresh_offers ( event )
2022-09-30 22:23:37 +02:00
local this = ScenarioTable.get_table ( )
2022-03-01 19:55:02 +02:00
local player = game.players [ event.player_index ]
2021-03-24 17:46:00 +02:00
local market = event.entity or event.market
if not market then
return
end
if not market.valid then
return
end
if market.name ~= ' market ' then
return
end
2022-09-30 22:23:37 +02:00
local town_center = this.town_centers [ market.force . name ]
2021-03-24 17:46:00 +02:00
if not town_center then
return
end
2022-03-01 19:55:02 +02:00
if player.force == market.force then
clear_offers ( market )
set_offers ( town_center )
else
if player.opened ~= nil then
player.opened = nil
player.surface . create_entity (
2022-09-30 22:23:37 +02:00
{
name = ' flying-text ' ,
position = { market.position . x - 1.75 , market.position . y } ,
text = ' Sorry, we are closed. ' ,
color = { r = 1 , g = 0.68 , b = 0.26 }
}
2022-03-01 19:55:02 +02:00
)
end
end
2021-02-06 22:42:10 +02:00
end
local function offer_purchased ( event )
2022-09-30 22:23:37 +02:00
local this = ScenarioTable.get_table ( )
2021-03-24 17:46:00 +02:00
local player = game.players [ event.player_index ]
local market = event.market
local offer_index = event.offer_index
local count = event.count
if not upgrade_functions [ offer_index ] then
return
end
2022-09-30 22:23:37 +02:00
local town_center = this.town_centers [ market.force . name ]
2021-03-24 17:46:00 +02:00
if not town_center then
return
end
2022-03-01 19:55:02 +02:00
if upgrade_functions [ offer_index ] ( town_center , player ) then
-- reimburse extra purchased
if count > 1 then
local offers = market.get_market_items ( )
if offers [ offer_index ] . price ~= nil then
local price = offers [ offer_index ] . price [ 1 ] . amount
player.insert ( { name = ' coin ' , count = price * ( count - 1 ) } )
end
end
else
-- reimburse purchase
2021-03-24 17:46:00 +02:00
local offers = market.get_market_items ( )
2022-03-01 19:55:02 +02:00
if offers [ offer_index ] . price ~= nil then
local price = offers [ offer_index ] . price [ 1 ] . amount
player.insert ( { name = ' coin ' , count = price * ( count ) } )
end
2021-03-24 17:46:00 +02:00
end
2021-02-06 22:42:10 +02:00
end
2022-03-01 19:55:02 +02:00
-- called for all gui events
2021-02-06 22:42:10 +02:00
local function on_gui_opened ( event )
2021-03-24 17:46:00 +02:00
local gui_type = event.gui_type
if gui_type ~= defines.gui_type . entity then
return
end
local entity = event.entity
if entity == nil or not entity.valid then
return
end
2022-03-01 19:55:02 +02:00
if entity.name == ' market ' then
2021-03-24 17:46:00 +02:00
refresh_offers ( event )
end
2021-02-06 22:42:10 +02:00
end
2022-03-01 19:55:02 +02:00
-- called for all market events
2021-02-06 22:42:10 +02:00
local function on_market_item_purchased ( event )
2022-03-01 19:55:02 +02:00
local market = event.market
if market.name == ' market ' then
offer_purchased ( event )
refresh_offers ( event )
end
2021-02-06 22:42:10 +02:00
end
local function inside ( pos , area )
2021-03-24 17:46:00 +02:00
return pos.x >= area.left_top . x and pos.x <= area.right_bottom . x and pos.y >= area.left_top . y and pos.y <= area.right_bottom . y
2021-02-06 22:42:10 +02:00
end
2022-03-01 19:55:02 +02:00
local function equal ( pos1 , pos2 )
return pos1.x == pos2.x and pos1.y == pos2.y
end
local function is_loader ( entity )
return entity.name == ' loader ' or entity.name == ' fast-loader ' or entity.name == ' express-loader '
end
local function is_filtered_inserter ( entity )
2022-09-30 22:23:37 +02:00
return entity.name == ' filter-inserter ' or entity.name == ' stack-filter-inserter '
2022-03-01 19:55:02 +02:00
end
local function max_stack_size ( entity )
2022-09-30 22:23:37 +02:00
if is_loader ( entity ) then
return 1
end
if ( entity.name == ' stack-inserter ' or entity.name == ' stack-filter-inserter ' ) then
2022-03-01 19:55:02 +02:00
local override = entity.inserter_stack_size_override
2022-09-30 22:23:37 +02:00
if override > 0 then
return override
end
2022-03-01 19:55:02 +02:00
local capacity = entity.force . stack_inserter_capacity_bonus
return 1 + capacity
else
local override = entity.inserter_stack_size_override
2022-09-30 22:23:37 +02:00
if override > 0 then
return override
end
2022-03-01 19:55:02 +02:00
local bonus = entity.force . inserter_stack_size_bonus
return 1 + bonus
2021-03-24 17:46:00 +02:00
end
2022-03-01 19:55:02 +02:00
end
local function get_connected_entities ( market )
2022-09-30 22:23:37 +02:00
if not market.valid then
return { }
end
2021-03-24 17:46:00 +02:00
local items = {
' burner-inserter ' ,
' inserter ' ,
' long-handed-inserter ' ,
' fast-inserter ' ,
' filter-inserter ' ,
' stack-inserter ' ,
' stack-filter-inserter ' ,
' loader ' ,
' fast-loader ' ,
' express-loader '
}
2022-03-01 19:55:02 +02:00
local items2 = {
2022-09-30 22:23:37 +02:00
' long-handed-inserter '
2022-03-01 19:55:02 +02:00
}
local bb = market.bounding_box
local s = market.surface
local area = { left_top = { bb.left_top . x - 1 , bb.left_top . y - 1 } , right_bottom = { bb.right_bottom . x + 1 , bb.right_bottom . y + 1 } }
local entities = s.find_entities_filtered ( { area = area , name = items } )
local area2 = { left_top = { bb.left_top . x - 2 , bb.left_top . y - 2 } , right_bottom = { bb.right_bottom . x + 2 , bb.right_bottom . y + 2 } }
local entities2 = s.find_entities_filtered ( { area = area2 , name = items2 } )
2022-09-30 22:23:37 +02:00
for k , v in pairs ( entities2 ) do
2022-03-01 19:55:02 +02:00
entities [ k ] = v
end
return entities
end
local function get_inserter_filter ( entity )
-- return the first filter
local filter_mode = entity.inserter_filter_mode
if filter_mode == ' whitelist ' then
return entity.get_filter ( 1 )
end
return nil
end
local function get_loader_filter ( entity , index )
-- return first two filter types
return entity.get_filter ( index )
end
local function get_loader_market_position ( entity )
-- gets the position of the market relative to the loader
2022-09-30 22:23:37 +02:00
local position = { x = entity.position . x , y = entity.position . y }
2022-03-01 19:55:02 +02:00
local orientation = entity.orientation
local type = entity.loader_type
2022-09-30 22:23:37 +02:00
if ( orientation == 0.0 and type == ' input ' ) or ( orientation == 0.5 and type == ' output ' ) then
2022-03-01 19:55:02 +02:00
position.y = position.y - 1.5
end
2022-09-30 22:23:37 +02:00
if ( orientation == 0.25 and type == ' input ' ) or ( orientation == 0.75 and type == ' output ' ) then
2022-03-01 19:55:02 +02:00
position.x = position.x + 1.5
end
2022-09-30 22:23:37 +02:00
if ( orientation == 0.5 and type == ' input ' ) or ( orientation == 0.0 and type == ' output ' ) then
2022-03-01 19:55:02 +02:00
position.y = position.y + 1.5
end
2022-09-30 22:23:37 +02:00
if ( orientation == 0.75 and type == ' input ' ) or ( orientation == 0.25 and type == ' output ' ) then
2022-03-01 19:55:02 +02:00
position.x = position.x - 1.5
end
return position
end
local function output_loader_items ( town_center , trade , entity , index )
local item = trade.offer . item
local line = entity.get_transport_line ( index )
if line.can_insert_at_back ( ) and town_center.output_buffer [ item ] > 0 then
local stack = { name = item , count = 1 }
town_center.output_buffer [ item ] = town_center.output_buffer [ item ] - 1
line.insert_at_back ( stack )
end
end
local function output_inserter_items ( town_center , trade , entity )
local item = trade.offer . item
local stack_size = max_stack_size ( entity )
local count = 0
while town_center.output_buffer [ item ] > 0 and count < stack_size do
town_center.output_buffer [ item ] = town_center.output_buffer [ item ] - 1
count = count + 1
end
if count > 0 then
local stack = { name = item , count = count }
entity.held_stack . set_stack ( stack )
end
end
local function trade_scrap_for_coin ( town_center , market , trade , stack )
local item = stack.name
local amount = stack.count
-- buffer the input in an item buffer that can be sold for coin
if town_center.input_buffer [ item ] == nil then
town_center.input_buffer [ item ] = 0
end
town_center.input_buffer [ item ] = town_center.input_buffer [ item ] + amount
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
local price = trade.price [ 1 ] . amount
local count = trade.offer . count
while town_center.input_buffer [ item ] >= price do
town_center.input_buffer [ item ] = town_center.input_buffer [ item ] - price
town_center.coin_balance = town_center.coin_balance + count
end
Town_center.update_coin_balance ( market.force )
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
end
local function trade_coin_for_items ( town_center , market , trade )
local item = trade.offer . item
local count = trade.offer . count
local price = trade.price [ 1 ] . amount
if town_center.output_buffer [ item ] == nil then
town_center.output_buffer [ item ] = 0
end
while town_center.coin_balance - price >= 0 do
2022-09-30 22:23:37 +02:00
if town_center.output_buffer [ item ] == 0 then
2022-03-01 19:55:02 +02:00
town_center.coin_balance = town_center.coin_balance - price
town_center.output_buffer [ item ] = town_center.output_buffer [ item ] + count
else
break
end
end
Town_center.update_coin_balance ( market.force )
end
local function handle_loader_output ( town_center , market , entity , index )
local line = entity.get_transport_line ( index )
-- get loader filters
local filter = get_loader_filter ( entity , index )
2022-09-30 22:23:37 +02:00
if filter == nil then
return
end
2022-03-01 19:55:02 +02:00
if filter == ' coin ' then
-- output for coins
while town_center.coin_balance > 0 and line.can_insert_at_back ( ) do
town_center.coin_balance = town_center.coin_balance - 1
local stack = { name = ' coin ' , count = 1 }
line.insert_at_back ( stack )
end
Town_center.update_coin_balance ( market.force )
else
-- output for matching purchases
2021-03-24 17:46:00 +02:00
local offers = market.get_market_items ( )
if offers == nil then
set_offers ( town_center )
end
2022-03-01 19:55:02 +02:00
if offers ~= nil then
for _ , trade in ipairs ( offers ) do
if trade.offer . type == ' give-item ' then
local item = trade.price [ 1 ] . name
if item == ' coin ' and trade.offer . item == filter then
trade_coin_for_items ( town_center , market , trade )
output_loader_items ( town_center , trade , entity , index )
2021-03-24 17:46:00 +02:00
end
end
2022-03-01 19:55:02 +02:00
end
end
end
end
local function handle_inserter_output ( town_center , market , entity )
-- get inserter filter
local filter = get_inserter_filter ( entity )
2022-09-30 22:23:37 +02:00
if filter == nil then
return
end
2022-03-01 19:55:02 +02:00
local amount = max_stack_size ( entity )
local stack = { name = ' coin ' , count = amount }
if filter == ' coin ' then
-- output coins
2022-09-30 22:23:37 +02:00
if amount > town_center.coin_balance then
amount = town_center.coin_balance
end
2022-03-01 19:55:02 +02:00
stack.count = amount
if town_center.coin_balance > 0 then
town_center.coin_balance = town_center.coin_balance - amount
entity.held_stack . set_stack ( stack )
end
Town_center.update_coin_balance ( market.force )
else
-- for matching coin purchases
local offers = market.get_market_items ( )
if offers == nil then
set_offers ( town_center )
end
if offers ~= nil then
for _ , trade in ipairs ( offers ) do
if trade.offer . type == ' give-item ' and trade.offer . item == filter then
local item = trade.price [ 1 ] . name
if item == ' coin ' then
trade_coin_for_items ( town_center , market , trade )
output_inserter_items ( town_center , trade , entity )
end
end
end
end
end
end
local function handle_loader_input ( town_center , market , entity , index )
local line = entity.get_transport_line ( index )
-- check for a line item at the back where we can pull
if line.valid then
local length = # line
if length > 1 or ( length == 1 and line.can_insert_at_back ( ) ) then
local line_item = line [ length ] . name
local stack = { name = line_item , count = 1 }
if line_item == ' coin ' then
-- insert coins
line.remove_item ( stack )
town_center.coin_balance = town_center.coin_balance + stack.count
Town_center.update_coin_balance ( market.force )
else
local offers = market.get_market_items ( )
if offers == nil then
set_offers ( town_center )
end
if offers ~= nil then
for _ , trade in ipairs ( offers ) do
if trade.offer . type == ' give-item ' then
local item = trade.price [ 1 ] . name
if item == stack.name and trade.offer . item == ' coin ' then
-- trade scrap for coin
line.remove_item ( stack )
trade_scrap_for_coin ( town_center , market , trade , stack )
2021-03-24 17:46:00 +02:00
end
end
end
end
end
end
end
2021-02-06 22:42:10 +02:00
end
2022-03-01 19:55:02 +02:00
local function handle_inserter_input ( town_center , market , entity )
-- check if stack is coin or resource
local stack = { name = entity.held_stack . name , count = entity.held_stack . count }
if stack.name == ' coin ' and stack.count > 0 then
-- insert coins
entity.remove_item ( stack )
town_center.coin_balance = town_center.coin_balance + stack.count
Town_center.update_coin_balance ( market.force )
else
local offers = market.get_market_items ( )
if offers == nil then
set_offers ( town_center )
end
if offers ~= nil then
for _ , trade in ipairs ( offers ) do
if trade.offer . type == ' give-item ' and trade.offer . item == ' coin ' then
local item = trade.price [ 1 ] . name
if item == stack.name and trade.offer . item == ' coin ' then
-- trade scrap for coin
entity.remove_item ( stack )
trade_scrap_for_coin ( town_center , market , trade , stack )
end
end
end
end
end
end
local function handle_market_input ( town_center , market , entity )
if is_loader ( entity ) then
-- handle loader input
-- we don't care about filters
local max_index = entity.get_max_transport_line_index ( )
for index = 1 , max_index , 1 do
handle_loader_input ( town_center , market , entity , index )
end
else
-- handle inserter input
-- we don't care about filters
local stack = entity.held_stack
if stack ~= nil then
-- if there is a pickup target
local spos = entity.held_stack_position
local dpos = entity.drop_position
if equal ( spos , dpos ) then
if stack.valid_for_read and stack.count > 0 then
-- if there is a stack
-- insert an item into the market
handle_inserter_input ( town_center , market , entity )
end
end
end
end
end
local function handle_market_output ( town_center , market , entity )
if is_loader ( entity ) then
-- handle loader output
local max_index = entity.get_max_transport_line_index ( )
for index = 1 , max_index , 1 do
if get_loader_filter ( entity , index ) ~= nil then
handle_loader_output ( town_center , market , entity , index )
end
end
else
if is_filtered_inserter ( entity ) then
-- handle inserter output
if entity.drop_target ~= nil then
-- if the pickup position is inside the market
--log("inside pickup position and there is a drop target")
local stack = entity.held_stack
local spos = entity.held_stack_position
local ppos = entity.pickup_position
if equal ( spos , ppos ) then
-- if the stack position is inside the market
if stack == nil or stack.count == 0 then
-- if there is space on the stack
-- pull an item from the market
handle_inserter_output ( town_center , market , entity , stack )
end
end
end
end
end
end
local function get_entity_mode ( market , entity )
local bb = market.bounding_box
if is_loader ( entity ) then
local mpos = get_loader_market_position ( entity )
if inside ( mpos , bb ) then
return entity.loader_type
else
return ' none '
end
else
local dpos = entity.drop_position
local ppos = entity.pickup_position
if inside ( dpos , bb ) then
return ' input '
end
if inside ( ppos , bb ) then
return ' output '
end
2022-09-30 22:23:37 +02:00
return ' none '
2022-03-01 19:55:02 +02:00
end
end
local function handle_connected_entity ( town_center , market , entity )
local mode = get_entity_mode ( market , entity )
2022-09-30 22:23:37 +02:00
if mode == ' input ' then
2022-03-01 19:55:02 +02:00
handle_market_input ( town_center , market , entity )
end
2022-09-30 22:23:37 +02:00
if mode == ' output ' then
2022-03-01 19:55:02 +02:00
handle_market_output ( town_center , market , entity )
end
end
local function on_tick ( _ )
2022-09-30 22:23:37 +02:00
local this = ScenarioTable.get_table ( )
if not this.town_centers then
2022-03-01 19:55:02 +02:00
return
end
2022-09-30 22:23:37 +02:00
for _ , town_center in pairs ( this.town_centers ) do
2022-03-01 19:55:02 +02:00
-- get connected entities on markets
local market = town_center.market
local entities = get_connected_entities ( market )
-- handle connected entity
for _ , entity in pairs ( entities ) do
if entity.force == market.force then
handle_connected_entity ( town_center , market , entity )
end
end
end
end
2021-02-06 22:42:10 +02:00
local Event = require ' utils.event '
Event.add ( defines.events . on_tick , on_tick )
Event.add ( defines.events . on_gui_opened , on_gui_opened )
Event.add ( defines.events . on_market_item_purchased , on_market_item_purchased )