mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-08 00:39:30 +02:00
1108 lines
33 KiB
Lua
1108 lines
33 KiB
Lua
local Gui = require 'utils.gui'
|
|
local Event = require 'utils.event'
|
|
local AntiGrief = require 'antigrief'
|
|
local Color = require 'utils.color_presets'
|
|
|
|
local WD = require 'modules.wave_defense.table'
|
|
local Math2D = require 'math2d'
|
|
|
|
--RPG Modules
|
|
local RPG = require 'modules.rpg.table'
|
|
local Functions = require 'modules.rpg.functions'
|
|
local RPG_GUI = require 'modules.rpg.gui'
|
|
|
|
--RPG Settings
|
|
local enemy_types = RPG.enemy_types
|
|
local die_cause = RPG.die_cause
|
|
local points_per_level = RPG.points_per_level
|
|
local nth_tick = RPG.nth_tick
|
|
|
|
--RPG Frames
|
|
local main_frame_name = RPG.main_frame_name
|
|
|
|
local sub = string.sub
|
|
|
|
local function on_gui_click(event)
|
|
if not event.element then
|
|
return
|
|
end
|
|
if not event.element.valid then
|
|
return
|
|
end
|
|
local element = event.element
|
|
local player = game.players[event.player_index]
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
local surface_name = RPG.get('rpg_extra').surface_name
|
|
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
|
return
|
|
end
|
|
|
|
if element.type ~= 'sprite-button' then
|
|
return
|
|
end
|
|
|
|
local shift = event.shift
|
|
|
|
if element.caption ~= '✚' then
|
|
return
|
|
end
|
|
if element.sprite ~= 'virtual-signal/signal-red' then
|
|
return
|
|
end
|
|
|
|
local rpg_t = RPG.get('rpg_t')
|
|
|
|
local index = element.name
|
|
if not rpg_t[player.index][index] then
|
|
return
|
|
end
|
|
if not player.character then
|
|
return
|
|
end
|
|
|
|
if shift then
|
|
local count = rpg_t[player.index].points_to_distribute
|
|
if not count then
|
|
return
|
|
end
|
|
rpg_t[player.index].points_to_distribute = 0
|
|
rpg_t[player.index][index] = rpg_t[player.index][index] + count
|
|
if not rpg_t[player.index].reset then
|
|
rpg_t[player.index].total = rpg_t[player.index].total + count
|
|
end
|
|
RPG_GUI.toggle(player, true)
|
|
RPG_GUI.update_player_stats(player)
|
|
elseif event.button == defines.mouse_button_type.right then
|
|
for _ = 1, points_per_level, 1 do
|
|
if rpg_t[player.index].points_to_distribute <= 0 then
|
|
RPG_GUI.toggle(player, true)
|
|
return
|
|
end
|
|
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute - 1
|
|
rpg_t[player.index][index] = rpg_t[player.index][index] + 1
|
|
if not rpg_t[player.index].reset then
|
|
rpg_t[player.index].total = rpg_t[player.index].total + 1
|
|
end
|
|
RPG_GUI.update_player_stats(player)
|
|
end
|
|
RPG_GUI.toggle(player, true)
|
|
return
|
|
end
|
|
|
|
if rpg_t[player.index].points_to_distribute <= 0 then
|
|
RPG_GUI.toggle(player, true)
|
|
return
|
|
end
|
|
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute - 1
|
|
rpg_t[player.index][index] = rpg_t[player.index][index] + 1
|
|
if not rpg_t[player.index].reset then
|
|
rpg_t[player.index].total = rpg_t[player.index].total + 1
|
|
end
|
|
RPG_GUI.update_player_stats(player)
|
|
RPG_GUI.toggle(player, true)
|
|
end
|
|
|
|
local function train_type_cause(cause)
|
|
local players = {}
|
|
if cause.train.passengers then
|
|
for _, player in pairs(cause.train.passengers) do
|
|
players[#players + 1] = player
|
|
end
|
|
end
|
|
return players
|
|
end
|
|
|
|
local get_cause_player = {
|
|
['character'] = function(cause)
|
|
if not cause.player then
|
|
return
|
|
end
|
|
return {cause.player}
|
|
end,
|
|
['combat-robot'] = function(cause)
|
|
if not cause.last_user then
|
|
return
|
|
end
|
|
if not game.players[cause.last_user.index] then
|
|
return
|
|
end
|
|
return {game.players[cause.last_user.index]}
|
|
end,
|
|
['car'] = function(cause)
|
|
local players = {}
|
|
local driver = cause.get_driver()
|
|
if driver then
|
|
if driver.player then
|
|
players[#players + 1] = driver.player
|
|
end
|
|
end
|
|
local passenger = cause.get_passenger()
|
|
if passenger then
|
|
if passenger.player then
|
|
players[#players + 1] = passenger.player
|
|
end
|
|
end
|
|
return players
|
|
end,
|
|
['locomotive'] = train_type_cause,
|
|
['cargo-wagon'] = train_type_cause,
|
|
['artillery-wagon'] = train_type_cause,
|
|
['fluid-wagon'] = train_type_cause
|
|
}
|
|
|
|
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
|
|
Functions.gain_xp(event.entity.last_user, 1)
|
|
Functions.reward_mana(event.entity.last_user, 1)
|
|
return
|
|
end
|
|
end
|
|
|
|
local rpg_extra = RPG.get('rpg_extra')
|
|
|
|
if rpg_extra.enable_wave_defense then
|
|
if rpg_extra.rpg_xp_yield['big-biter'] <= 16 then
|
|
local wave_number = WD.get_wave()
|
|
if wave_number >= 1000 then
|
|
rpg_extra.rpg_xp_yield['big-biter'] = 16
|
|
rpg_extra.rpg_xp_yield['behemoth-biter'] = 64
|
|
end
|
|
end
|
|
end
|
|
|
|
if not event.cause then
|
|
return
|
|
end
|
|
|
|
if not event.cause.valid then
|
|
return
|
|
end
|
|
|
|
local type = event.cause.type
|
|
if not type then
|
|
goto continue
|
|
end
|
|
|
|
if event.cause.force.index == 1 then
|
|
if die_cause[type] then
|
|
if rpg_extra.rpg_xp_yield[event.entity.name] then
|
|
local amount = rpg_extra.rpg_xp_yield[event.entity.name]
|
|
amount = amount / 5
|
|
if global.biter_health_boost then
|
|
local health_pool = global.biter_health_boost_units[event.entity.unit_number]
|
|
if health_pool then
|
|
amount = amount * (1 / health_pool[2])
|
|
end
|
|
end
|
|
|
|
if rpg_extra.turret_kills_to_global_pool then
|
|
Functions.add_to_global_pool(amount, false)
|
|
end
|
|
else
|
|
Functions.add_to_global_pool(0.5, false)
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
::continue::
|
|
|
|
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 enemy_types[event.entity.type] then
|
|
local health_pool = global.biter_health_boost_units[event.entity.unit_number]
|
|
if health_pool then
|
|
for _, player in pairs(players) do
|
|
if rpg_extra.rpg_xp_yield[event.entity.name] then
|
|
local amount = rpg_extra.rpg_xp_yield[event.entity.name] * (1 / health_pool[2])
|
|
if rpg_extra.turret_kills_to_global_pool then
|
|
local inserted = Functions.add_to_global_pool(amount, true)
|
|
Functions.gain_xp(player, inserted, true)
|
|
else
|
|
Functions.gain_xp(player, amount)
|
|
end
|
|
else
|
|
Functions.gain_xp(player, 0.5 * (1 / health_pool[2]))
|
|
end
|
|
end
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
--Grant normal XP
|
|
for _, player in pairs(players) do
|
|
if rpg_extra.rpg_xp_yield[event.entity.name] then
|
|
local amount = rpg_extra.rpg_xp_yield[event.entity.name]
|
|
if rpg_extra.turret_kills_to_global_pool then
|
|
local inserted = Functions.add_to_global_pool(amount, true)
|
|
Functions.gain_xp(player, inserted, true)
|
|
else
|
|
Functions.gain_xp(player, amount)
|
|
end
|
|
else
|
|
Functions.gain_xp(player, 0.5)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function regen_health_player(players)
|
|
for i = 1, #players do
|
|
local player = players[i]
|
|
local heal_per_tick = Functions.get_heal_modifier(player)
|
|
if heal_per_tick <= 0 then
|
|
goto continue
|
|
end
|
|
heal_per_tick = math.round(heal_per_tick)
|
|
if player and player.valid and not player.in_combat then
|
|
if player.character and player.character.valid then
|
|
player.character.health = player.character.health + heal_per_tick
|
|
end
|
|
end
|
|
|
|
::continue::
|
|
|
|
Functions.update_health(player)
|
|
end
|
|
end
|
|
|
|
local function regen_mana_player(players)
|
|
for i = 1, #players do
|
|
local player = players[i]
|
|
local mana_per_tick = Functions.get_mana_modifier(player)
|
|
local rpg_extra = RPG.get('rpg_extra')
|
|
local rpg_t = RPG.get('rpg_t')
|
|
if mana_per_tick <= 0.1 then
|
|
mana_per_tick = rpg_extra.mana_per_tick
|
|
end
|
|
|
|
if rpg_extra.force_mana_per_tick then
|
|
mana_per_tick = 1
|
|
end
|
|
|
|
if player and player.valid and not player.in_combat then
|
|
if player.character and player.character.valid then
|
|
if rpg_t[player.index].mana < 0 then
|
|
rpg_t[player.index].mana = 0
|
|
end
|
|
if rpg_t[player.index].mana >= rpg_t[player.index].mana_max then
|
|
goto continue
|
|
end
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana + mana_per_tick
|
|
if rpg_t[player.index].mana >= rpg_t[player.index].mana_max then
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana_max
|
|
end
|
|
rpg_t[player.index].mana = (math.round(rpg_t[player.index].mana * 10) / 10)
|
|
end
|
|
end
|
|
|
|
::continue::
|
|
|
|
Functions.update_mana(player)
|
|
end
|
|
end
|
|
|
|
local function give_player_flameboots(player)
|
|
if not player.character then
|
|
return
|
|
end
|
|
if player.character.driving then
|
|
return
|
|
end
|
|
|
|
local rpg_t = RPG.get('rpg_t')
|
|
|
|
if not rpg_t[player.index].mana then
|
|
return
|
|
end
|
|
|
|
if not rpg_t[player.index].flame_boots then
|
|
return
|
|
end
|
|
|
|
if rpg_t[player.index].mana <= 0 then
|
|
player.print('Your flame boots have worn out.', {r = 0.22, g = 0.77, b = 0.44})
|
|
rpg_t[player.index].flame_boots = false
|
|
return
|
|
end
|
|
|
|
if rpg_t[player.index].mana % 500 == 0 then
|
|
player.print('Mana remaining: ' .. rpg_t[player.index].mana, {r = 0.22, g = 0.77, b = 0.44})
|
|
end
|
|
|
|
local p = player.position
|
|
|
|
player.surface.create_entity({name = 'fire-flame', position = p})
|
|
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - 5
|
|
if rpg_t[player.index].mana <= 0 then
|
|
rpg_t[player.index].mana = 0
|
|
end
|
|
if player.gui.screen[main_frame_name] then
|
|
local f = player.gui.screen[main_frame_name]
|
|
local data = Gui.get_data(f)
|
|
if data.mana and data.mana.valid then
|
|
data.mana.caption = rpg_t[player.index].mana
|
|
end
|
|
end
|
|
end
|
|
|
|
--Melee damage modifier
|
|
local function one_punch(character, target, damage)
|
|
local base_vector = {target.position.x - character.position.x, target.position.y - character.position.y}
|
|
|
|
local vector = {base_vector[1], base_vector[2]}
|
|
vector[1] = vector[1] * 1000
|
|
vector[2] = vector[2] * 1000
|
|
|
|
character.surface.create_entity(
|
|
{
|
|
name = 'flying-text',
|
|
position = {character.position.x + base_vector[1] * 0.5, character.position.y + base_vector[2] * 0.5},
|
|
text = 'ONE PUNCH',
|
|
color = {255, 0, 0}
|
|
}
|
|
)
|
|
character.surface.create_entity({name = 'blood-explosion-huge', position = target.position})
|
|
character.surface.create_entity(
|
|
{
|
|
name = 'big-artillery-explosion',
|
|
position = {target.position.x + vector[1] * 0.5, target.position.y + vector[2] * 0.5}
|
|
}
|
|
)
|
|
|
|
if math.abs(vector[1]) > math.abs(vector[2]) then
|
|
local d = math.abs(vector[1])
|
|
if math.abs(vector[1]) > 0 then
|
|
vector[1] = vector[1] / d
|
|
end
|
|
if math.abs(vector[2]) > 0 then
|
|
vector[2] = vector[2] / d
|
|
end
|
|
else
|
|
local d = math.abs(vector[2])
|
|
if math.abs(vector[2]) > 0 then
|
|
vector[2] = vector[2] / d
|
|
end
|
|
if math.abs(vector[1]) > 0 and d > 0 then
|
|
vector[1] = vector[1] / d
|
|
end
|
|
end
|
|
|
|
vector[1] = vector[1] * 1.5
|
|
vector[2] = vector[2] * 1.5
|
|
|
|
local a = 0.25
|
|
|
|
for i = 1, 16, 1 do
|
|
for x = i * -1 * a, i * a, 1 do
|
|
for y = i * -1 * a, i * a, 1 do
|
|
local p = {character.position.x + x + vector[1] * i, character.position.y + y + vector[2] * i}
|
|
character.surface.create_trivial_smoke({name = 'train-smoke', position = p})
|
|
for _, e in pairs(character.surface.find_entities({{p[1] - a, p[2] - a}, {p[1] + a, p[2] + a}})) do
|
|
if e.valid then
|
|
if e.health then
|
|
if e.destructible and e.minable and e.force.index ~= 3 then
|
|
if e.force.index ~= character.force.index then
|
|
e.health = e.health - damage * 0.05
|
|
if e.health <= 0 then
|
|
e.die(e.force.name, character)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_entity_damaged(event)
|
|
if not event.cause then
|
|
return
|
|
end
|
|
if not event.cause.valid then
|
|
return
|
|
end
|
|
if event.cause.force.index == 2 then
|
|
return
|
|
end
|
|
if event.cause.name ~= 'character' then
|
|
return
|
|
end
|
|
|
|
if event.damage_type.name ~= 'physical' then
|
|
return
|
|
end
|
|
|
|
if not event.entity.valid then
|
|
return
|
|
end
|
|
if
|
|
event.cause.get_inventory(defines.inventory.character_ammo)[event.cause.selected_gun_index].valid_for_read and
|
|
event.cause.get_inventory(defines.inventory.character_guns)[event.cause.selected_gun_index].valid_for_read
|
|
then
|
|
return
|
|
end
|
|
if not event.cause.player then
|
|
return
|
|
end
|
|
|
|
local p = event.cause.player
|
|
|
|
local surface_name = RPG.get('rpg_extra').surface_name
|
|
if sub(p.surface.name, 0, #surface_name) ~= surface_name then
|
|
return
|
|
end
|
|
|
|
Functions.reward_mana(event.cause.player, 2)
|
|
|
|
--Grant the player life-on-hit.
|
|
event.cause.health = event.cause.health + Functions.get_life_on_hit(event.cause.player)
|
|
|
|
--Calculate modified damage.
|
|
local damage =
|
|
event.original_damage_amount + event.original_damage_amount * Functions.get_melee_modifier(event.cause.player)
|
|
if event.entity.prototype.resistances then
|
|
if event.entity.prototype.resistances.physical then
|
|
damage = damage - event.entity.prototype.resistances.physical.decrease
|
|
damage = damage - damage * event.entity.prototype.resistances.physical.percent
|
|
end
|
|
end
|
|
damage = math.round(damage, 3)
|
|
if damage < 1 then
|
|
damage = 1
|
|
end
|
|
|
|
local enable_one_punch = RPG.get('rpg_extra').enable_one_punch
|
|
local rpg_t = RPG.get('rpg_t')
|
|
|
|
--Cause a one punch.
|
|
if enable_one_punch then
|
|
if rpg_t[event.cause.player.index].one_punch then
|
|
if math.random(0, 999) < Functions.get_one_punch_chance(event.cause.player) * 10 then
|
|
one_punch(event.cause, event.entity, damage)
|
|
if event.entity.valid then
|
|
event.entity.die(event.entity.force.name, event.cause)
|
|
end
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
--Floating messages and particle effects.
|
|
if math.random(1, 7) == 1 then
|
|
damage = damage * math.random(250, 350) * 0.01
|
|
event.cause.surface.create_entity(
|
|
{
|
|
name = 'flying-text',
|
|
position = event.entity.position,
|
|
text = '‼' .. math.floor(damage),
|
|
color = {255, 0, 0}
|
|
}
|
|
)
|
|
event.cause.surface.create_entity({name = 'blood-explosion-huge', position = event.entity.position})
|
|
else
|
|
damage = damage * math.random(100, 125) * 0.01
|
|
event.cause.player.create_local_flying_text(
|
|
{
|
|
text = math.floor(damage),
|
|
position = event.entity.position,
|
|
color = {150, 150, 150},
|
|
time_to_live = 90,
|
|
speed = 2
|
|
}
|
|
)
|
|
end
|
|
|
|
--Handle the custom health pool of the biter health booster, if it is used in the map.
|
|
if global.biter_health_boost then
|
|
local health_pool = global.biter_health_boost_units[event.entity.unit_number]
|
|
if health_pool then
|
|
health_pool[1] = health_pool[1] + event.final_damage_amount
|
|
health_pool[1] = health_pool[1] - damage
|
|
|
|
--Set entity health relative to health pool
|
|
event.entity.health = health_pool[1] * health_pool[2]
|
|
|
|
if health_pool[1] <= 0 then
|
|
local entity_number = event.entity.unit_number
|
|
event.entity.die(event.entity.force.name, event.cause)
|
|
global.biter_health_boost_units[entity_number] = nil
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
--Handle vanilla damage.
|
|
event.entity.health = event.entity.health + event.final_damage_amount
|
|
event.entity.health = event.entity.health - damage
|
|
if event.entity.health <= 0 then
|
|
event.entity.die(event.entity.force.name, event.cause)
|
|
end
|
|
end
|
|
|
|
local function on_player_repaired_entity(event)
|
|
if math.random(1, 4) ~= 1 then
|
|
return
|
|
end
|
|
|
|
local entity = event.entity
|
|
|
|
if not entity then
|
|
return
|
|
end
|
|
|
|
if not entity.valid then
|
|
return
|
|
end
|
|
|
|
if not entity.health then
|
|
return
|
|
end
|
|
|
|
local player = game.players[event.player_index]
|
|
|
|
if not player or not player.valid or not player.character then
|
|
return
|
|
end
|
|
|
|
Functions.gain_xp(player, 0.05)
|
|
Functions.reward_mana(player, 0.2)
|
|
|
|
local repair_speed = Functions.get_magicka(player)
|
|
if repair_speed <= 0 then
|
|
return
|
|
end
|
|
entity.health = entity.health + repair_speed
|
|
end
|
|
|
|
local function on_player_rotated_entity(event)
|
|
local player = game.players[event.player_index]
|
|
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
if not player.character then
|
|
return
|
|
end
|
|
|
|
local rpg_t = RPG.get('rpg_t')
|
|
if rpg_t[player.index].rotated_entity_delay > game.tick then
|
|
return
|
|
end
|
|
rpg_t[player.index].rotated_entity_delay = game.tick + 20
|
|
Functions.gain_xp(player, 0.20)
|
|
end
|
|
|
|
local function on_player_changed_position(event)
|
|
local player = game.players[event.player_index]
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
local enable_flame_boots = RPG.get('rpg_extra').enable_flame_boots
|
|
|
|
if enable_flame_boots then
|
|
give_player_flameboots(player)
|
|
end
|
|
|
|
if math.random(1, 64) ~= 1 then
|
|
return
|
|
end
|
|
if not player.character then
|
|
return
|
|
end
|
|
if player.character.driving then
|
|
return
|
|
end
|
|
Functions.gain_xp(player, 1.0)
|
|
end
|
|
|
|
local building_and_mining_blacklist = {
|
|
['tile-ghost'] = true,
|
|
['entity-ghost'] = true,
|
|
['item-entity'] = true
|
|
}
|
|
|
|
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
|
|
if entity.force.index ~= 3 then
|
|
return
|
|
end
|
|
local player = game.players[event.player_index]
|
|
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
local surface_name = RPG.get('rpg_extra').surface_name
|
|
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
|
return
|
|
end
|
|
|
|
local rpg_t = RPG.get('rpg_t')
|
|
if
|
|
rpg_t[player.index].last_mined_entity_position.x == event.entity.position.x and
|
|
rpg_t[player.index].last_mined_entity_position.y == event.entity.position.y
|
|
then
|
|
return
|
|
end
|
|
rpg_t[player.index].last_mined_entity_position.x = entity.position.x
|
|
rpg_t[player.index].last_mined_entity_position.y = entity.position.y
|
|
|
|
local distance_multiplier = math.floor(math.sqrt(entity.position.x ^ 2 + entity.position.y ^ 2)) * 0.0005 + 1
|
|
|
|
local xp_amount
|
|
if entity.type == 'resource' then
|
|
xp_amount = 0.5 * distance_multiplier
|
|
else
|
|
xp_amount = (1.5 + event.entity.prototype.max_health * 0.0035) * distance_multiplier
|
|
end
|
|
|
|
if player.gui.screen[main_frame_name] then
|
|
local f = player.gui.screen[main_frame_name]
|
|
local data = Gui.get_data(f)
|
|
if data.exp_gui and data.exp_gui.valid then
|
|
data.exp_gui.caption = math.floor(rpg_t[player.index].xp)
|
|
end
|
|
end
|
|
|
|
Functions.gain_xp(player, xp_amount)
|
|
Functions.reward_mana(player, 0.5 * distance_multiplier)
|
|
end
|
|
|
|
local function on_player_crafted_item(event)
|
|
if not event.recipe.energy then
|
|
return
|
|
end
|
|
local player = game.players[event.player_index]
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
if player.cheat_mode then
|
|
return
|
|
end
|
|
|
|
local amount = 0.30 * math.random(1, 2)
|
|
|
|
Functions.gain_xp(player, event.recipe.energy * amount)
|
|
Functions.reward_mana(player, amount)
|
|
end
|
|
|
|
local function on_player_respawned(event)
|
|
local player = game.players[event.player_index]
|
|
local rpg_t = RPG.get('rpg_t')
|
|
if not rpg_t[player.index] then
|
|
Functions.rpg_reset_player(player)
|
|
return
|
|
end
|
|
RPG_GUI.update_player_stats(player)
|
|
RPG_GUI.draw_level_text(player)
|
|
Functions.update_health(player)
|
|
Functions.update_mana(player)
|
|
end
|
|
|
|
local function on_player_joined_game(event)
|
|
local player = game.players[event.player_index]
|
|
local rpg_t = RPG.get('rpg_t')
|
|
local rpg_extra = RPG.get('rpg_extra')
|
|
if not rpg_t[player.index] then
|
|
Functions.rpg_reset_player(player)
|
|
if rpg_extra.reward_new_players > 10 then
|
|
Functions.gain_xp(player, rpg_extra.reward_new_players)
|
|
end
|
|
end
|
|
for _, p in pairs(game.connected_players) do
|
|
RPG_GUI.draw_level_text(p)
|
|
end
|
|
RPG_GUI.draw_gui_char_button(player)
|
|
if not player.character then
|
|
return
|
|
end
|
|
RPG_GUI.update_player_stats(player)
|
|
end
|
|
|
|
local function create_projectile(surface, name, position, force, target, max_range)
|
|
if max_range then
|
|
surface.create_entity(
|
|
{
|
|
name = name,
|
|
position = position,
|
|
force = force,
|
|
source = position,
|
|
target = target,
|
|
max_range = max_range,
|
|
speed = 0.4
|
|
}
|
|
)
|
|
else
|
|
surface.create_entity(
|
|
{
|
|
name = name,
|
|
position = position,
|
|
force = force,
|
|
source = position,
|
|
target = target,
|
|
speed = 0.4
|
|
}
|
|
)
|
|
end
|
|
end
|
|
|
|
local function get_near_coord_modifier(range)
|
|
local coord = {x = (range * -1) + math.random(0, range * 2), y = (range * -1) + math.random(0, range * 2)}
|
|
for i = 1, 5, 1 do
|
|
local new_coord = {x = (range * -1) + math.random(0, range * 2), y = (range * -1) + math.random(0, range * 2)}
|
|
if new_coord.x ^ 2 + new_coord.y ^ 2 < coord.x ^ 2 + coord.y ^ 2 then
|
|
coord = new_coord
|
|
end
|
|
end
|
|
return coord
|
|
end
|
|
|
|
local function damage_entity(e)
|
|
if not e or not e.valid then
|
|
return
|
|
end
|
|
|
|
if not e.health then
|
|
return
|
|
end
|
|
|
|
if e.force.name == 'player' then
|
|
return
|
|
end
|
|
|
|
e.surface.create_entity({name = 'water-splash', position = e.position})
|
|
|
|
if e.type == 'entity-ghost' then
|
|
e.destroy()
|
|
return
|
|
end
|
|
|
|
e.health = e.health - math.random(30, 90)
|
|
if e.health <= 0 then
|
|
e.die('enemy')
|
|
end
|
|
end
|
|
|
|
local function floaty_hearts(entity, c)
|
|
local position = {x = entity.position.x - 0.75, y = entity.position.y - 1}
|
|
local b = 1.35
|
|
for _ = 1, c, 1 do
|
|
local p = {
|
|
(position.x + 0.4) + (b * -1 + math.random(0, b * 20) * 0.1),
|
|
position.y + (b * -1 + math.random(0, b * 20) * 0.1)
|
|
}
|
|
entity.surface.create_entity(
|
|
{name = 'flying-text', position = p, text = '♥', color = {math.random(150, 255), 0, 255}}
|
|
)
|
|
end
|
|
end
|
|
|
|
local function tame_unit_effects(player, entity)
|
|
floaty_hearts(entity, 7)
|
|
|
|
rendering.draw_text {
|
|
text = '~' .. player.name .. "'s pet~",
|
|
surface = player.surface,
|
|
target = entity,
|
|
target_offset = {0, -2.6},
|
|
color = {
|
|
r = player.color.r * 0.6 + 0.25,
|
|
g = player.color.g * 0.6 + 0.25,
|
|
b = player.color.b * 0.6 + 0.25,
|
|
a = 1
|
|
},
|
|
scale = 1.05,
|
|
font = 'default-large-semibold',
|
|
alignment = 'center',
|
|
scale_with_zoom = false
|
|
}
|
|
end
|
|
|
|
local function on_player_used_capsule(event)
|
|
local enable_mana = RPG.get('rpg_extra').enable_mana
|
|
local surface_name = RPG.get('rpg_extra').surface_name
|
|
if not enable_mana then
|
|
return
|
|
end
|
|
|
|
local conjure_items = RPG.get_spells()
|
|
local projectile_types = RPG.get_projectiles
|
|
|
|
local player = game.players[event.player_index]
|
|
if not player or not player.valid then
|
|
return
|
|
end
|
|
|
|
if not player.character or not player.character.valid then
|
|
return
|
|
end
|
|
|
|
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
|
return
|
|
end
|
|
|
|
local item = event.item
|
|
|
|
if not item then
|
|
return
|
|
end
|
|
|
|
local name = item.name
|
|
|
|
if name ~= 'raw-fish' then
|
|
return
|
|
end
|
|
|
|
local rpg_t = RPG.get('rpg_t')
|
|
|
|
if not rpg_t[player.index].enable_entity_spawn then
|
|
return
|
|
end
|
|
|
|
local p = player.print
|
|
|
|
if rpg_t[player.index].last_spawned >= game.tick then
|
|
return p(
|
|
'There was a lot more to magic, as ' ..
|
|
player.name .. ' quickly found out, than waving their wand and saying a few funny words.',
|
|
Color.warning
|
|
)
|
|
end
|
|
|
|
local mana = rpg_t[player.index].mana
|
|
local surface = player.surface
|
|
|
|
local object = conjure_items[rpg_t[player.index].dropdown_select_index]
|
|
if not object then
|
|
return
|
|
end
|
|
|
|
if rpg_t[player.index].level < object.level then
|
|
return p('You lack the level to cast this spell.', Color.fail)
|
|
end
|
|
|
|
if not object.enabled then
|
|
return
|
|
end
|
|
|
|
local object_name = object.name
|
|
local obj_name = object.obj_to_create
|
|
|
|
local position = event.position
|
|
if not position then
|
|
return
|
|
end
|
|
|
|
local radius = 15
|
|
local area = {
|
|
left_top = {x = position.x - radius, y = position.y - radius},
|
|
right_bottom = {x = position.x + radius, y = position.y + radius}
|
|
}
|
|
|
|
if not Math2D.bounding_box.contains_point(area, player.position) then
|
|
player.print('You wave your wand but realize that it´s out of reach.', Color.fail)
|
|
return
|
|
end
|
|
|
|
if mana < object.mana_cost then
|
|
return p('You don´t have enough mana to cast this spell.', Color.fail)
|
|
end
|
|
|
|
local target_pos
|
|
if object.target then
|
|
target_pos = {position.x, position.y}
|
|
elseif projectile_types[obj_name] then
|
|
local coord_modifier = get_near_coord_modifier(projectile_types[obj_name].max_range)
|
|
local proj_pos = {position.x + coord_modifier.x, position.y + coord_modifier.y}
|
|
target_pos = proj_pos
|
|
end
|
|
|
|
local range
|
|
if object.range then
|
|
range = object.range
|
|
else
|
|
range = 0
|
|
end
|
|
|
|
local force
|
|
if object.force then
|
|
force = object.force
|
|
else
|
|
force = 'player'
|
|
end
|
|
if object.obj_to_create == 'suicidal_comfylatron' then
|
|
Functions.suicidal_comfylatron(position, surface)
|
|
p('You wave your wand and ' .. object_name .. ' is on the run!', Color.success)
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost
|
|
elseif object.obj_to_create == 'warp-gate' then
|
|
player.teleport(
|
|
surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5),
|
|
surface
|
|
)
|
|
rpg_t[player.index].mana = 0
|
|
player.character.health = 10
|
|
player.character.surface.create_entity({name = 'water-splash', position = player.position})
|
|
p('Warped home with minor bruises.', Color.info)
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost
|
|
elseif projectile_types[obj_name] then
|
|
for i = 1, object.amount do
|
|
local damage_area = {
|
|
left_top = {x = position.x - 2, y = position.y - 2},
|
|
right_bottom = {x = position.x + 2, y = position.y + 2}
|
|
}
|
|
create_projectile(surface, obj_name, position, force, target_pos, range)
|
|
if object.damage then
|
|
for _, e in pairs(surface.find_entities_filtered({area = damage_area})) do
|
|
damage_entity(e)
|
|
end
|
|
end
|
|
end
|
|
p('You wave your wand and ' .. object_name .. ' appears.', Color.success)
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost
|
|
else
|
|
if object.target then
|
|
surface.create_entity({name = obj_name, position = position, force = force, target = target_pos, speed = 1})
|
|
p('You wave your wand and ' .. object_name .. ' appears.', Color.success)
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost
|
|
elseif object.obj_to_create == 'fish' then
|
|
player.insert({name = 'raw-fish', count = object.amount})
|
|
p('You wave your wand and ' .. object_name .. ' appears.', Color.success)
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost
|
|
elseif surface.can_place_entity {name = obj_name, position = position} then
|
|
if object.biter then
|
|
local e = surface.create_entity({name = obj_name, position = position, force = force})
|
|
tame_unit_effects(player, e)
|
|
else
|
|
surface.create_entity({name = obj_name, position = position, force = force})
|
|
end
|
|
p('You wave your wand and ' .. object_name .. ' appears.', Color.success)
|
|
rpg_t[player.index].mana = rpg_t[player.index].mana - object.mana_cost
|
|
else
|
|
p('Can´t create entity at given location.', Color.fail)
|
|
return
|
|
end
|
|
end
|
|
|
|
local msg = player.name .. ' casted ' .. object.name .. '. '
|
|
|
|
rpg_t[player.index].last_spawned = game.tick + object.tick
|
|
Functions.update_mana(player)
|
|
|
|
local reward_xp = object.mana_cost * 0.009
|
|
if reward_xp < 1 then
|
|
reward_xp = 1
|
|
end
|
|
|
|
Functions.gain_xp(player, reward_xp)
|
|
|
|
AntiGrief.insert_into_capsule_history(player, position, msg)
|
|
|
|
return
|
|
end
|
|
|
|
local function tick()
|
|
local ticker = game.tick
|
|
local count = #game.connected_players
|
|
local players = game.connected_players
|
|
local enable_flameboots = RPG.get('rpg_extra').enable_flameboots
|
|
local enable_mana = RPG.get('rpg_extra').enable_mana
|
|
|
|
if ticker % nth_tick == 0 then
|
|
Functions.global_pool(players, count)
|
|
end
|
|
|
|
if ticker % 30 == 0 then
|
|
regen_health_player(players)
|
|
if enable_mana then
|
|
regen_mana_player(players)
|
|
end
|
|
if enable_flameboots then
|
|
give_player_flameboots(players)
|
|
end
|
|
end
|
|
end
|
|
|
|
if _DEBUG then
|
|
commands.add_command(
|
|
'give_xp',
|
|
'DEBUG ONLY - if you are seeing this then this map is running on debug-mode.',
|
|
function(cmd)
|
|
local p
|
|
local player = game.player
|
|
local param = tonumber(cmd.parameter)
|
|
|
|
if player then
|
|
if player ~= nil then
|
|
p = player.print
|
|
if not player.admin then
|
|
p("[ERROR] You're not admin!", Color.fail)
|
|
return
|
|
end
|
|
if not param then
|
|
return
|
|
end
|
|
p('Distributed ' .. param .. ' of xp.')
|
|
Functions.give_xp(param)
|
|
end
|
|
end
|
|
end
|
|
)
|
|
end
|
|
|
|
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)
|
|
Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
|
|
Event.on_nth_tick(10, tick)
|