mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-08 00:39:30 +02:00
226 lines
7.4 KiB
Lua
226 lines
7.4 KiB
Lua
local math_random = math.random
|
|
local Global = require 'utils.global'
|
|
local visuals_delay = 1800
|
|
local level_up_floating_text_color = {0, 205, 0}
|
|
local xp_floating_text_color = {157, 157, 157}
|
|
local experience_levels = {0}
|
|
|
|
local xp_t = {}
|
|
local last_built_entities = {}
|
|
|
|
Global.register(
|
|
{xp_t=xp_t},
|
|
function(tbl)
|
|
xp_t = tbl.xp_t
|
|
last_built_entities = tbl.last_built_entities
|
|
end
|
|
)
|
|
|
|
local Public = {}
|
|
|
|
function Public.get_table()
|
|
return xp_t
|
|
end
|
|
function Public.lost_xp(player, amount)
|
|
xp_t[player.index].xp = xp_t[player.index].xp - amount
|
|
end
|
|
local xp_yield = {
|
|
["behemoth-biter"] = 16,
|
|
["behemoth-spitter"] = 16,
|
|
["behemoth-worm-turret"] = 64,
|
|
["big-biter"] = 8,
|
|
["big-spitter"] = 8,
|
|
["big-worm-turret"] = 48,
|
|
["biter-spawner"] = 64,
|
|
["character"] = 16,
|
|
["gun-turret"] = 8,
|
|
["laser-turret"] = 16,
|
|
["medium-biter"] = 4,
|
|
["medium-spitter"] = 4,
|
|
["medium-worm-turret"] = 32,
|
|
["small-biter"] = 1,
|
|
["small-spitter"] = 1,
|
|
["small-worm-turret"] = 16,
|
|
["spitter-spawner"] = 64,
|
|
}
|
|
|
|
local function gain_xp(player, amount)
|
|
if not player.force == "spectator" then
|
|
amount = math.round(amount, 2)
|
|
xp_t[player.index].xp = xp_t[player.index].xp + amount
|
|
xp_t[player.index].xp_since_last_floaty_text = xp_t[player.index].xp_since_last_floaty_text + amount
|
|
if xp_t[player.index].last_floaty_text > game.tick then return end
|
|
player.create_local_flying_text{text="+" .. xp_t[player.index].xp_since_last_floaty_text .. " xp", position=player.position, color=xp_floating_text_color, time_to_live=120, speed=2}
|
|
xp_t[player.index].xp_since_last_floaty_text = 0
|
|
xp_t[player.index].last_floaty_text = game.tick + visuals_delay
|
|
end
|
|
end
|
|
function Public.xp_reset_player(player)
|
|
if not player.character then
|
|
player.set_controller({type=defines.controllers.god})
|
|
player.create_character()
|
|
end
|
|
xp_t[player.index] = {
|
|
xp = 0, points_to_distribute = 0, last_floaty_text = visuals_delay, xp_since_last_floaty_text = 0,
|
|
rotated_entity_delay = 0, last_mined_entity_position = {x = 0, y = 0},
|
|
}
|
|
end
|
|
|
|
function Public.xp_reset_all_players()
|
|
for _, p in pairs(game.players) do
|
|
rpg_t[p.index] = nil
|
|
end
|
|
for _, p in pairs(game.connected_players) do
|
|
Public.xp_reset_player(p)
|
|
end
|
|
end
|
|
|
|
local function on_entity_died(event)
|
|
if not event.entity.valid then return end
|
|
|
|
--Grant XP for hand placed land mines
|
|
if event.entity.last_user then
|
|
if event.entity.type == "land-mine" then
|
|
if event.cause then
|
|
if event.cause.valid then
|
|
if event.cause.force.index == event.entity.force.index then return end
|
|
end
|
|
end
|
|
gain_xp(event.entity.last_user, 1)
|
|
return
|
|
end
|
|
end
|
|
|
|
if not event.cause then return end
|
|
if not event.cause.valid then return end
|
|
if event.cause.force.index == event.entity.force.index then return end
|
|
if not get_cause_player[event.cause.type] then return end
|
|
|
|
local players = get_cause_player[event.cause.type](event.cause)
|
|
if not players then return end
|
|
if not players[1] then return end
|
|
|
|
--Grant modified XP for health boosted units
|
|
if global.biter_health_boost then
|
|
if event.entity.type == "unit" then
|
|
for _, player in pairs(players) do
|
|
if xp_yield[event.entity.name] then
|
|
gain_xp(player, xp_yield[event.entity.name] * global.biter_health_boost)
|
|
else
|
|
gain_xp(player, 0.5 * global.biter_health_boost)
|
|
end
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
--Grant normal XP
|
|
for _, player in pairs(players) do
|
|
if xp_yield[event.entity.name] then
|
|
gain_xp(player, xp_yield[event.entity.name])
|
|
else
|
|
gain_xp(player, 0.5)
|
|
end
|
|
end
|
|
end
|
|
local function on_player_repaired_entity(event)
|
|
if math_random(1, 4) ~= 1 then return end
|
|
local player = game.players[event.player_index]
|
|
if not player.character then return end
|
|
gain_xp(player, 0.40)
|
|
end
|
|
|
|
local function on_player_rotated_entity(event)
|
|
local player = game.players[event.player_index]
|
|
if not player.character then return end
|
|
if xp_t[player.index].rotated_entity_delay > game.tick then return end
|
|
xp_t[player.index].rotated_entity_delay = game.tick + 20
|
|
gain_xp(player, 0.20)
|
|
end
|
|
|
|
local function on_player_changed_position(event)
|
|
if math_random(1, 64) ~= 1 then return end
|
|
local player = game.players[event.player_index]
|
|
if not player.character then return end
|
|
if player.character.driving then return end
|
|
gain_xp(player, 1.0)
|
|
end
|
|
|
|
local building_and_mining_blacklist = {
|
|
["tile-ghost"] = true,
|
|
["entity-ghost"] = true,
|
|
["item-entity"] = true,
|
|
}
|
|
|
|
local function is_replaced_entity(entity)
|
|
if not last_built_entities[entity.position.x .. "_" .. entity.position.y] then return end
|
|
for key, tick in pairs(last_built_entities) do
|
|
if tick < game.tick then last_built_entities[key] = nil end
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function on_pre_player_mined_item(event)
|
|
local entity = event.entity
|
|
if not entity.valid then return end
|
|
if building_and_mining_blacklist[entity.type] then return end
|
|
|
|
local player = game.players[event.player_index]
|
|
|
|
if is_replaced_entity(entity) then
|
|
gain_xp(player, -0.1)
|
|
return
|
|
end
|
|
|
|
if xp_t[player.index].last_mined_entity_position.x == event.entity.position.x and xp_t[player.index].last_mined_entity_position.y == event.entity.position.y then return end
|
|
xp_t[player.index].last_mined_entity_position.x = entity.position.x
|
|
xp_t[player.index].last_mined_entity_position.y = entity.position.y
|
|
if entity.type == "resource" then gain_xp(player, 0.5) return end
|
|
if entity.force.name == "neutral" then gain_xp(player, 1.5 + event.entity.prototype.max_health * 0.0035) return end
|
|
gain_xp(player, 0.1 + event.entity.prototype.max_health * 0.0005)
|
|
end
|
|
|
|
local function on_built_entity(event)
|
|
local created_entity = event.created_entity
|
|
if not created_entity.valid then return end
|
|
if building_and_mining_blacklist[created_entity.type] then return end
|
|
last_built_entities[created_entity.position.x .. "_" .. created_entity.position.y] = game.tick + 1800
|
|
local player = game.players[event.player_index]
|
|
gain_xp(player, 0.1)
|
|
end
|
|
|
|
local function on_player_crafted_item(event)
|
|
if not event.recipe.energy then return end
|
|
local player = game.players[event.player_index]
|
|
gain_xp(player, event.recipe.energy * 0.20)
|
|
end
|
|
|
|
local function on_player_respawned(event)
|
|
local player = game.players[event.player_index]
|
|
if not xp_t[player.index] then Public.xp_reset_player(player) return end
|
|
end
|
|
|
|
local function on_player_joined_game(event)
|
|
local player = game.players[event.player_index]
|
|
if not xp_t[player.index] then Public.xp_reset_player(player) end
|
|
end
|
|
|
|
local function on_init(event)
|
|
end
|
|
|
|
local event = require 'utils.event'
|
|
event.on_init(on_init)
|
|
event.add(defines.events.on_built_entity, on_built_entity)
|
|
event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
|
event.add(defines.events.on_entity_died, on_entity_died)
|
|
event.add(defines.events.on_gui_click, on_gui_click)
|
|
event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
|
event.add(defines.events.on_player_crafted_item, on_player_crafted_item)
|
|
event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
|
event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
|
|
event.add(defines.events.on_player_respawned, on_player_respawned)
|
|
event.add(defines.events.on_player_rotated_entity, on_player_rotated_entity)
|
|
event.add(defines.events.on_pre_player_mined_item, on_pre_player_mined_item)
|
|
|
|
return Public
|