1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00
ComfyFactorio/maps/native_war/xp.lua
2021-03-24 20:14:55 +01:00

296 lines
8.5 KiB
Lua

--luacheck: ignore
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