1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-11-25 22:32:18 +02:00
This commit is contained in:
Gerkiz
2022-04-18 01:18:25 +02:00
parent 378dfe373d
commit a3cd26b88f
8 changed files with 717 additions and 431 deletions

View File

@@ -86,6 +86,9 @@ no_mana=Not enough mana!
mana_label=Mana Settings:
tooltip_check=Checked: true\nUnchecked: false
info_text_label=Common RPG settings. These settings are per player basis.
spellbook_label=Spellbook - explains the requirement for each spell.
entity_spells_label=Normal Spells
special_spells_label=Special Spells
health_text_label=Show health/mana bar?
health_only_text_label=Show health bar?
reset_text_label=Reset your skillpoints?
@@ -109,9 +112,6 @@ cast_spell_enabled_label=Casting spells with fish has been enabled!
cast_spell_disabled_label=Casting spells with fish has been disabled!
magic_tooltip=When simply constructing items is not enough.\nNOTE! Use Raw-fish to cast spells.
magic_spell=Select what entity to spawn
magic_item_requirement=__1__ [item=__2__] requires __3__ mana to cast. Level: __4__\n
magic_entity_requirement=__1__ [entity=__2__] requires __3__ mana to cast. Level: __4__\n
magic_special_requirement=__1__ __2__ requires __3__ mana to cast. Level: __4__\n
allocation_settings_label=Allocations Settings:
allocation_label=Select what skill to auto-allocate.
allocation_tooltip=This will automatically allocate all available points to the given node.
@@ -128,6 +128,8 @@ distractor=Distractor Capsule
warp=Warp Gate
pointy_explosives=Detonate Chest
repair_aoe=Repair AOE
charge=Charge
eternal_blades=Eternal Blades
[allocations]

View File

@@ -122,7 +122,7 @@ commands.add_command(
player.play_sound {path = 'utility/scenario_message', volume_modifier = 1}
player.print(msg)
else
player.print('Please type a name of a player who is connected.', Color.warning)
player.print('[Stats] Please type a name of a player who is connected.', Color.warning)
end
end
)

View File

@@ -2,6 +2,7 @@ local Public = require 'modules.rpg.table'
local Task = require 'utils.task'
local Gui = require 'utils.gui'
local Color = require 'utils.color_presets'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local P = require 'utils.player_modifiers'
local Token = require 'utils.token'
local Alert = require 'utils.alert'
@@ -12,9 +13,11 @@ local xp_floating_text_color = Public.xp_floating_text_color
local experience_levels = Public.experience_levels
local points_per_level = Public.points_per_level
local settings_level = Public.gui_settings_levels
local round = math.round
local floor = math.floor
local random = math.random
local round = math.round
local abs = math.abs
--RPG Frames
local main_frame_name = Public.main_frame_name
@@ -41,7 +44,7 @@ local desync =
end
local surface = data.surface
local fake_shooter = surface.create_entity({name = 'character', position = entity.position, force = 'enemy'})
for i = 1, 3 do
for _ = 1, 3 do
surface.create_entity(
{
name = 'explosive-rocket',
@@ -155,6 +158,98 @@ local function level_up(player)
Public.level_up_effects(player)
end
local function has_health_boost(entity, damage, final_damage_amount, cause)
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool
if not entity.valid then
return
end
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
get_health_pool = health_pool[1]
--Set entity health relative to health pool
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(entity.prototype.max_health * m)
health_pool[1] = round(health_pool[1] + final_damage_amount)
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
entity.health = final_health
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
end
end
else
entity.health = entity.health + final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
end
else
--Handle vanilla damage.
entity.health = entity.health + final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
end
return get_health_pool
end
local function set_health_boost(entity, damage, cause)
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool
if not entity.valid then
return
end
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
get_health_pool = health_pool[1]
--Set entity health relative to health pool
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(entity.prototype.max_health * m)
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
entity.health = final_health
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
end
end
end
end
return get_health_pool
end
local function add_to_global_pool(amount, personal_tax)
local rpg_extra = Public.get('rpg_extra')
@@ -480,6 +575,95 @@ function Public.update_health(player)
end
end
function Public.log_aoe_punch(callback)
local debug = Public.get('rpg_extra').debug_aoe_punch
if not debug then
return
end
callback()
end
--Melee damage modifier
function Public.aoe_punch(character, target, damage, get_health_pool)
if not (target and target.valid) then
return
end
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 = 'blood-explosion-huge', position = target.position})
if abs(vector[1]) > abs(vector[2]) then
local d = abs(vector[1])
if abs(vector[1]) > 0 then
vector[1] = vector[1] / d
end
if abs(vector[2]) > 0 then
vector[2] = vector[2] / d
end
else
local d = abs(vector[2])
if abs(vector[2]) > 0 then
vector[2] = vector[2] / d
end
if 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.20
local cs = character.surface
local cp = character.position
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 = {cp.x + x + vector[1] * i, cp.y + y + vector[2] * i}
cs.create_trivial_smoke({name = 'train-smoke', position = p})
for _, e in pairs(cs.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
if get_health_pool then
local max_unit_health = floor(get_health_pool * 0.00015)
if max_unit_health <= 0 then
max_unit_health = 4
end
if max_unit_health >= 10 then
max_unit_health = 10
end
local final = floor(damage * max_unit_health)
set_health_boost(e, final, character)
if e.valid and e.health <= 0 and get_health_pool <= 0 then
e.die(e.force.name, character)
end
else
if e.valid 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
end
end
function Public.level_limit_exceeded(player, value)
local rpg_extra = Public.get('rpg_extra')
local rpg_t = Public.get_value_from_player(player.index)
@@ -617,6 +801,19 @@ function Public.get_melee_modifier(player)
return total
end
function Public.get_area_of_effect_range(player)
local rpg_t = Public.get_value_from_player(player.index)
if not rpg_t then
return false
end
local total = (rpg_t.level - 10) * 0.05
if rpg_t.level < 10 then
total = 1
end
return total
end
function Public.get_final_damage_modifier(player)
local rpg_t = Public.get_value_from_player(player.index)
if not rpg_t then
@@ -774,7 +971,6 @@ function Public.rpg_reset_player(player, one_time_reset)
dropdown_select_index2 = 1,
dropdown_select_index3 = 1,
allocate_index = 1,
flame_boots = false,
explosive_bullets = false,
enable_entity_spawn = false,
health_bar = rpg_t.health_bar,
@@ -817,7 +1013,6 @@ function Public.rpg_reset_player(player, one_time_reset)
dropdown_select_index2 = 1,
dropdown_select_index3 = 1,
allocate_index = 1,
flame_boots = false,
explosive_bullets = false,
enable_entity_spawn = false,
points_left = 0,
@@ -983,8 +1178,6 @@ function Public.global_pool(players, count)
end
rpg_extra.global_pool = rpg_extra.leftover_pool or 0
return
end
local damage_player_over_time_token =
@@ -1021,4 +1214,7 @@ function Public.distribute_pool()
print('Distributed the global XP pool')
end
Public.has_health_boost = has_health_boost
Public.set_health_boost = set_health_boost
Public.add_to_global_pool = add_to_global_pool

View File

@@ -17,6 +17,9 @@ local main_frame_name = Public.main_frame_name
local draw_main_frame_name = Public.draw_main_frame_name
local close_main_frame_name = Public.close_main_frame_name
local settings_button_name = Public.settings_button_name
local settings_tooltip_frame = Public.settings_tooltip_frame
local close_settings_tooltip_frame = Public.close_settings_tooltip_frame
local settings_tooltip_name = Public.settings_tooltip_name
local settings_frame_name = Public.settings_frame_name
local discard_button_name = Public.discard_button_name
local save_button_name = Public.save_button_name
@@ -459,6 +462,21 @@ function Public.remove_frame(player)
end
end
function Public.clear_settings_frames(player)
local screen = player.gui.screen
local center = player.gui.center
local setting_tooltip_frame = center[settings_tooltip_frame]
local setting_frame = screen[settings_frame_name]
if setting_tooltip_frame then
remove_target_frame(setting_tooltip_frame)
end
if setting_frame then
remove_target_frame(setting_frame)
end
end
local toggle = Public.toggle
Public.remove_main_frame = remove_main_frame
@@ -501,7 +519,6 @@ Gui.on_click(
local spell_gui_input3 = data.spell_gui_input3
local magic_pickup_gui_input = data.magic_pickup_gui_input
local movement_speed_gui_input = data.movement_speed_gui_input
local flame_boots_gui_input = data.flame_boots_gui_input
local explosive_bullets_gui_input = data.explosive_bullets_gui_input
local enable_entity_gui_input = data.enable_entity_gui_input
local stone_path_gui_input = data.stone_path_gui_input
@@ -539,14 +556,6 @@ Gui.on_click(
end
end
if flame_boots_gui_input and flame_boots_gui_input.valid then
if not flame_boots_gui_input.state then
rpg_t.flame_boots = false
elseif flame_boots_gui_input.state then
rpg_t.flame_boots = true
end
end
if explosive_bullets_gui_input and explosive_bullets_gui_input.valid then
if not explosive_bullets_gui_input.state then
rpg_t.explosive_bullets = false
@@ -672,6 +681,26 @@ Gui.on_click(
end
)
Gui.on_click(
close_settings_tooltip_frame,
function(event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'RPG Close Button')
if is_spamming then
return
end
local player = event.player
local center = player.gui.center
if not player or not player.valid or not player.character then
return
end
local main_frame = center[settings_tooltip_frame]
if main_frame and main_frame.valid then
remove_target_frame(main_frame)
end
end
)
Gui.on_click(
settings_button_name,
function(event)
@@ -695,11 +724,41 @@ Gui.on_click(
Gui.remove_data_recursively(frame)
frame.destroy()
else
ComfyGui.clear_all_center_frames(player)
Public.extra_settings(player)
end
end
)
Gui.on_click(
settings_tooltip_name,
function(event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'RPG Settings Tooltip Button')
if is_spamming then
return
end
local player = event.player
if not player or not player.valid or not player.character then
return
end
local surface_name = Public.get('rpg_extra').surface_name
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
return
end
local center = player.gui.center
local main_frame = center[settings_tooltip_frame]
if main_frame and main_frame.valid then
remove_target_frame(main_frame)
else
ComfyGui.clear_all_center_frames(player)
ComfyGui.clear_all_screen_frames(player)
Public.settings_tooltip(player)
end
end
)
Gui.on_click(
enable_spawning_frame_name,
function(event)

View File

@@ -6,6 +6,7 @@ local AntiGrief = require 'utils.antigrief'
local SpamProtection = require 'utils.spam_protection'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Explosives = require 'modules.explosives'
local ComfyGui = require 'utils.gui'
local WD = require 'modules.wave_defense.table'
local Math2D = require 'math2d'
@@ -24,15 +25,6 @@ local round = math.round
local floor = math.floor
local random = math.random
local sqrt = math.sqrt
local abs = math.abs
local function log_aoe_punch(callback)
local debug = Public.get('rpg_extra').debug_aoe_punch
if not debug then
return
end
callback()
end
local function on_gui_click(event)
if not event then
@@ -408,233 +400,6 @@ local function regen_mana_player(players)
end
end
local function give_player_flameboots(player)
local rpg_t = Public.get_value_from_player(player.index)
if not rpg_t then
return
end
if not rpg_t.flame_boots then
return
end
if not player.character then
return
end
if player.character.driving then
return
end
if not rpg_t.mana then
return
end
if rpg_t.mana <= 0 then
player.print(({'rpg_main.flame_boots_worn_out'}), {r = 0.22, g = 0.77, b = 0.44})
rpg_t.flame_boots = false
return
end
if rpg_t.mana % 500 == 0 then
player.print(({'rpg_main.flame_mana_remaining', rpg_t.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.mana = rpg_t.mana - 5
if rpg_t.mana <= 0 then
rpg_t.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.mana
end
end
end
local function has_health_boost(entity, damage, final_damage_amount, cause)
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
get_health_pool = health_pool[1]
--Set entity health relative to health pool
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(entity.prototype.max_health * m)
health_pool[1] = round(health_pool[1] + final_damage_amount)
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
entity.health = final_health
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
end
end
else
entity.health = entity.health + final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
end
else
--Handle vanilla damage.
entity.health = entity.health + final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
end
return get_health_pool
end
local function set_health_boost(entity, damage, cause)
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
get_health_pool = health_pool[1]
--Set entity health relative to health pool
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(entity.prototype.max_health * m)
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
entity.health = final_health
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
end
end
end
end
return get_health_pool
end
--Melee damage modifier
local function aoe_punch(character, target, damage, get_health_pool)
if not (target and target.valid) then
return
end
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 = ({'rpg_main.aoe_punch_text'}),
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 abs(vector[1]) > abs(vector[2]) then
local d = abs(vector[1])
if abs(vector[1]) > 0 then
vector[1] = vector[1] / d
end
if abs(vector[2]) > 0 then
vector[2] = vector[2] / d
end
else
local d = abs(vector[2])
if abs(vector[2]) > 0 then
vector[2] = vector[2] / d
end
if 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.20
local cs = character.surface
local cp = character.position
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 = {cp.x + x + vector[1] * i, cp.y + y + vector[2] * i}
cs.create_trivial_smoke({name = 'train-smoke', position = p})
for _, e in pairs(cs.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
if get_health_pool then
local max_unit_health = floor(get_health_pool * 0.00015)
if max_unit_health <= 0 then
max_unit_health = 4
end
if max_unit_health >= 10 then
max_unit_health = 10
end
local final = floor(damage * max_unit_health)
set_health_boost(e, final, character)
if e.valid and e.health <= 0 and get_health_pool <= 0 then
e.die(e.force.name, character)
end
else
if e.valid 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
end
end
local function is_position_near(area, entity)
local status = false
@@ -645,7 +410,7 @@ local function is_position_near(area, entity)
return pos.x >= lt.x and pos.y >= lt.y and pos.x <= rb.x and pos.y <= rb.y
end
if inside(entity, area) then
if inside(entity) then
status = true
end
@@ -755,7 +520,7 @@ local function on_entity_damaged(event)
)
end
local get_health_pool = has_health_boost(entity, damage, final_damage_amount, cause)
local get_health_pool = Public.has_health_boost(entity, damage, final_damage_amount, cause)
--Cause a one punch.
if enable_aoe_punch then
@@ -763,7 +528,7 @@ local function on_entity_damaged(event)
local chance = Public.get_aoe_punch_chance(cause.player) * 10
local chance_to_hit = random(0, 999)
local success = chance_to_hit < chance
log_aoe_punch(
Public.log_aoe_punch(
function()
if success then
print('[OnePunch]: Chance: ' .. chance .. ' Chance to hit: ' .. chance_to_hit .. ' Success: true' .. ' Damage: ' .. damage)
@@ -772,10 +537,11 @@ local function on_entity_damaged(event)
end
end
)
if success then
aoe_punch(cause, entity, damage, get_health_pool) -- only kill the biters if their health is below or equal to zero
-- if success then
log(serpent.block('hit'))
Public.aoe_punch(cause, entity, damage, get_health_pool) -- only kill the biters if their health is below or equal to zero
return
end
-- end
end
end
@@ -844,12 +610,6 @@ local function on_player_changed_position(event)
return
end
local enable_flame_boots = Public.get('rpg_extra').enable_flame_boots
if enable_flame_boots then
give_player_flameboots(player)
end
if random(1, 64) ~= 1 then
return
end
@@ -1011,7 +771,7 @@ end
local function get_near_coord_modifier(range)
local coord = {x = (range * -1) + random(0, range * 2), y = (range * -1) + random(0, range * 2)}
for i = 1, 5, 1 do
for _ = 1, 5, 1 do
local new_coord = {x = (range * -1) + random(0, range * 2), y = (range * -1) + random(0, range * 2)}
if new_coord.x ^ 2 + new_coord.y ^ 2 < coord.x ^ 2 + coord.y ^ 2 then
coord = new_coord
@@ -1090,7 +850,7 @@ local function on_player_used_capsule(event)
return
end
local conjure_items = Public.spells
local conjure_items = Public.all_spells
local projectile_types = Public.get_projectiles
local player = game.players[event.player_index]
@@ -1133,8 +893,8 @@ local function on_player_used_capsule(event)
local mana = rpg_t.mana
local surface = player.surface
local object = conjure_items[rpg_t.dropdown_select_index]
if not object then
local spell = conjure_items[rpg_t.dropdown_select_index]
if not spell then
return
end
@@ -1149,11 +909,11 @@ local function on_player_used_capsule(event)
right_bottom = {x = position.x + radius, y = position.y + radius}
}
if rpg_t.level < object.level then
if rpg_t.level < spell.level then
return Public.cast_spell(player, true)
end
if not object.enabled then
if not spell.enabled then
return
end
@@ -1162,34 +922,41 @@ local function on_player_used_capsule(event)
return
end
if mana < object.mana_cost then
if mana < spell.mana_cost then
return Public.cast_spell(player, true)
end
local target_pos
if object.target then
if spell.target then
target_pos = {position.x, position.y}
elseif projectile_types[object.entityName] then
local coord_modifier = get_near_coord_modifier(projectile_types[object.entityName].max_range)
elseif projectile_types[spell.entityName] then
local coord_modifier = get_near_coord_modifier(projectile_types[spell.entityName].max_range)
target_pos = {position.x + coord_modifier.x, position.y + coord_modifier.y}
end
local range
if object.range then
range = object.range
if spell.range then
range = spell.range
else
range = 0
end
local force
if object.force then
force = object.force
if spell.force then
force = spell.force
else
force = 'player'
end
if spell.check_if_active then
if rpg_t.has_custom_spell_active then
Public.cast_spell(player, true)
return
end
end
local data = {
self = object,
self = spell,
player = player,
damage_entity = damage_entity,
position = position,
@@ -1202,14 +969,14 @@ local function on_player_used_capsule(event)
rpg_t = rpg_t
}
object.callback(data)
spell.callback(data)
local msg = player.name .. ' casted ' .. object.entityName .. '. '
local msg = player.name .. ' casted ' .. spell.entityName .. '. '
rpg_t.last_spawned = game.tick + object.tick
rpg_t.last_spawned = game.tick + spell.tick
Public.update_mana(player)
local reward_xp = object.mana_cost * 0.085
local reward_xp = spell.mana_cost * 0.085
if reward_xp < 1 then
reward_xp = 1
end
@@ -1232,7 +999,6 @@ local function tick()
local ticker = game.tick
local players = game.connected_players
local count = #players
local enable_flameboots = Public.get('rpg_extra').enable_flameboots
local enable_mana = Public.get('rpg_extra').enable_mana
if ticker % nth_tick == 0 then
@@ -1244,9 +1010,6 @@ local function tick()
if enable_mana then
regen_mana_player(players)
end
if enable_flameboots then
give_player_flameboots(players)
end
end
end
@@ -1268,4 +1031,16 @@ Event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
Event.add(defines.events.on_player_removed, on_player_removed)
Event.on_nth_tick(10, tick)
Event.add(
defines.events.on_gui_closed,
function(event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
end
Public.clear_settings_frames(player)
end
)
return Public

View File

@@ -4,6 +4,9 @@ local P = require 'utils.player_modifiers'
local Session = require 'utils.datastore.session_data'
local settings_frame_name = Public.settings_frame_name
local close_settings_tooltip_frame = Public.close_settings_tooltip_frame
local settings_tooltip_frame = Public.settings_tooltip_frame
local settings_tooltip_name = Public.settings_tooltip_name
local save_button_name = Public.save_button_name
local discard_button_name = Public.discard_button_name
local spell_gui_button_name = Public.spell_gui_button_name
@@ -15,6 +18,16 @@ local spell3_button_name = Public.spell3_button_name
local settings_level = Public.gui_settings_levels
local comparators = {
['levels'] = function(a, b)
return a.level < b.level
end
}
local function get_comparator(sort_by)
return comparators[sort_by]
end
local function create_input_element(frame, type, value, items, index)
if type == 'slider' then
return frame.add({type = 'slider', value = value, minimum_value = 0, maximum_value = 1})
@@ -22,12 +35,22 @@ local function create_input_element(frame, type, value, items, index)
if type == 'boolean' then
return frame.add({type = 'checkbox', state = value})
end
if type == 'label' then
return frame.add({type = 'label', caption = value})
end
if type == 'dropdown' then
return frame.add({type = 'drop-down', items = items, selected_index = index})
end
return frame.add({type = 'text-box', text = value})
end
local function create_custom_label_element(frame, sprite, localised_string, value)
local t = frame.add({type = 'flow'})
t.add({type = 'label', caption = '[' .. sprite .. ']'})
t.add({type = 'label', caption = localised_string})
return t.add({type = 'label', caption = value})
end
function Public.update_spell_gui_indicator(player)
local rpg_t = Public.get_value_from_player(player.index)
local main_frame = player.gui.screen[spell_gui_frame_name]
@@ -155,25 +178,12 @@ function Public.extra_settings(player)
local rpg_extra = Public.get('rpg_extra')
local rpg_t = Public.get_value_from_player(player.index)
local trusted = Session.get_trusted_table()
local main_frame =
player.gui.screen.add(
{
type = 'frame',
name = settings_frame_name,
caption = ({'rpg_settings.name'}),
direction = 'vertical'
}
)
main_frame.auto_center = true
local main_frame, inside_table = Gui.add_main_frame_with_toolbar(player, 'screen', settings_frame_name, settings_tooltip_name, nil, 'RPG Settings', true)
local main_frame_style = main_frame.style
main_frame_style.width = 500
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 0
main_frame.auto_center = true
inside_table.add({type = 'line'})
@@ -327,7 +337,6 @@ function Public.extra_settings(player)
local spell_gui_input1
local spell_gui_input2
local spell_gui_input3
local flame_boots_gui_input
local explosive_bullets_gui_input
local stone_path_gui_input
local aoe_punch_gui_input
@@ -412,48 +421,6 @@ function Public.extra_settings(player)
end
end
if rpg_extra.enable_flame_boots then
local flame_boots_label =
setting_grid.add(
{
type = 'label',
caption = ({'rpg_settings.flameboots_label'}),
tooltip = ({'rpg_settings.flameboots_tooltip'})
}
)
local flame_boots_label_style = flame_boots_label.style
flame_boots_label_style.horizontally_stretchable = true
flame_boots_label_style.height = 35
flame_boots_label_style.vertical_align = 'center'
local flame_boots_input = setting_grid.add({type = 'flow'})
local flame_boots_input_style = flame_boots_input.style
flame_boots_input_style.height = 35
flame_boots_input_style.vertical_align = 'center'
local flame_mod
if rpg_t.flame_boots then
flame_mod = rpg_t.flame_boots
else
flame_mod = false
end
flame_boots_gui_input = create_input_element(flame_boots_input, 'boolean', flame_mod)
if rpg_t.mana > 50 then
if rpg_t.level < settings_level['flameboots_label'] then
flame_boots_gui_input.enabled = false
flame_boots_gui_input.tooltip = ({'rpg_settings.low_level', 100})
flame_boots_label.tooltip = ({'rpg_settings.low_level', 100})
else
flame_boots_gui_input.enabled = true
flame_boots_gui_input.tooltip = ({'rpg_settings.tooltip_check'})
end
else
flame_boots_gui_input.enabled = false
flame_boots_gui_input.tooltip = ({'rpg_settings.no_mana'})
end
end
if rpg_extra.enable_explosive_bullets_globally then
local explosive_bullets_label =
setting_grid.add(
@@ -556,7 +523,7 @@ function Public.extra_settings(player)
{
type = 'label',
caption = ({'rpg_settings.magic_spell'}),
tooltip = ''
tooltip = 'Check the info button at upper right for more information'
}
)
@@ -573,33 +540,6 @@ function Public.extra_settings(player)
conjure_input_style.vertical_align = 'center'
conjure_gui_input = create_input_element(conjure_input, 'dropdown', false, names, rpg_t.dropdown_select_index)
for _, entity in pairs(spells) do
if entity.type == 'item' then
conjure_label.tooltip = ({
'rpg_settings.magic_item_requirement',
conjure_label.tooltip,
entity.entityName,
entity.mana_cost,
entity.level
})
elseif entity.type == 'entity' then
conjure_label.tooltip = ({
'rpg_settings.magic_entity_requirement',
conjure_label.tooltip,
entity.entityName,
entity.mana_cost,
entity.level
})
elseif entity.type == 'special' then
conjure_label.tooltip = ({
'rpg_settings.magic_special_requirement',
conjure_label.tooltip,
entity.name,
entity.mana_cost,
entity.level
})
end
end
if not spells[rpg_t.dropdown_select_index1] then
rpg_t.dropdown_select_index1 = 1
end
@@ -686,10 +626,6 @@ function Public.extra_settings(player)
data.enable_entity_gui_input = enable_entity_gui_input
end
if rpg_extra.enable_flame_boots then
data.flame_boots_gui_input = flame_boots_gui_input
end
if rpg_extra.enable_explosive_bullets_globally then
data.explosive_bullets_gui_input = explosive_bullets_gui_input
end
@@ -725,3 +661,89 @@ function Public.extra_settings(player)
player.opened = main_frame
end
function Public.settings_tooltip(player)
local rpg_extra = Public.get('rpg_extra')
local main_frame, inside_table = Gui.add_main_frame_with_toolbar(player, 'center', settings_tooltip_frame, nil, close_settings_tooltip_frame, 'Spell info')
local inside_table_style = inside_table.style
inside_table_style.width = 500
inside_table.add({type = 'line'})
local info_text = inside_table.add({type = 'label', caption = ({'rpg_settings.spellbook_label'})})
local info_text_style = info_text.style
info_text_style.font = 'heading-2'
info_text_style.padding = 0
info_text_style.left_padding = 10
info_text_style.horizontal_align = 'left'
info_text_style.vertical_align = 'bottom'
info_text_style.font_color = {0.55, 0.55, 0.99}
if rpg_extra.enable_mana then
local normal_spell_pane = inside_table.add({type = 'scroll-pane'})
local ns = normal_spell_pane.style
ns.vertically_squashable = true
ns.bottom_padding = 5
ns.left_padding = 5
ns.right_padding = 5
ns.top_padding = 5
normal_spell_pane.add({type = 'line'})
local entity_spells = normal_spell_pane.add({type = 'label', caption = ({'rpg_settings.entity_spells_label'})})
local entity_spells_style = entity_spells.style
entity_spells_style.font = 'heading-3'
entity_spells_style.padding = 0
entity_spells_style.left_padding = 10
entity_spells_style.horizontal_align = 'left'
entity_spells_style.font_color = {0.55, 0.55, 0.99}
local normal_spell_grid = normal_spell_pane.add({type = 'table', column_count = 2})
local spells = Public.rebuild_spells()
local comparator = get_comparator('levels')
table.sort(spells, comparator)
for _, entity in pairs(spells) do
if entity.type == 'item' then
local text = '[item=' .. entity.entityName .. '] requires ' .. entity.mana_cost .. ' mana to cast. Level: ' .. entity.level
create_input_element(normal_spell_grid, 'label', text)
elseif entity.type == 'entity' then
local text = '[entity=' .. entity.entityName .. '] requires ' .. entity.mana_cost .. ' mana to cast. Level: ' .. entity.level
create_input_element(normal_spell_grid, 'label', text)
end
end
normal_spell_pane.add({type = 'line'})
local special_spell_pane = inside_table.add({type = 'scroll-pane'})
local ss = special_spell_pane.style
ss.vertically_squashable = true
ss.bottom_padding = 5
ss.left_padding = 5
ss.right_padding = 5
ss.top_padding = 5
local special_spells = special_spell_pane.add({type = 'label', caption = ({'rpg_settings.special_spells_label'})})
local special_spells_style = special_spells.style
special_spells_style.font = 'heading-3'
special_spells_style.padding = 0
special_spells_style.left_padding = 10
special_spells_style.horizontal_align = 'left'
special_spells_style.font_color = {0.55, 0.55, 0.99}
local special_spell_grid = special_spell_pane.add({type = 'table', column_count = 1})
for _, entity in pairs(spells) do
if entity.type == 'special' then
local text = 'requires ' .. entity.mana_cost .. ' mana to cast. Level: ' .. entity.level
create_custom_label_element(special_spell_grid, entity.sprite, entity.name, text)
end
end
end
player.opened = main_frame
end

View File

@@ -1,11 +1,128 @@
local Public = require 'modules.rpg.table'
local Token = require 'utils.token'
local Task = require 'utils.task'
local spells = {}
local random = math.random
local floor = math.floor
local states = {
['attack'] = 'nuclear-smoke',
['support'] = 'poison-capsule-smoke'
}
local repair_buildings =
Token.register(
function(data)
local entity = data.entity
if entity and entity.valid then
local rng = 0.1
if random(1, 5) == 1 then
rng = 0.2
elseif random(1, 8) == 1 then
rng = 0.4
end
local to_heal = entity.prototype.max_health * rng
if entity.health and to_heal then
entity.health = entity.health + to_heal
end
end
end
)
local function get_area(pos, dist)
local area = {
left_top = {
x = pos.x - dist,
y = pos.y - dist
},
right_bottom = {
x = pos.x + dist,
y = pos.y + dist
}
}
return area
end
local function area_of_effect(player, position, state, radius, callback, find_entities)
if not radius then
return
end
local cs = player.surface
local cp = position or player.position
if radius and radius > 256 then
radius = 256
end
local area = get_area(cp, radius)
if not states[state] then
return
end
for x = area.left_top.x, area.right_bottom.x, 1 do
for y = area.left_top.y, area.right_bottom.y, 1 do
local d = floor((cp.x - x) ^ 2 + (cp.y - y) ^ 2)
if d < radius then
local p = {x = x, y = y}
if find_entities then
for _, e in pairs(cs.find_entities_filtered({position = p})) do
if e and e.valid and e.name ~= 'character' and e.health and e.destructible and e.type ~= 'simple-entity' and e.type ~= 'simple-entity-with-owner' then
callback(e, p)
end
end
else
callback(p)
end
cs.create_trivial_smoke({name = states[state], position = p})
end
end
end
end
local restore_movement_speed_token =
Token.register(
function(event)
local player_index = event.player_index
local old_speed = event.old_speed
local rpg_t = event.rpg_t
if rpg_t then
rpg_t.has_custom_spell_active = nil
end
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
player.character.character_running_speed_modifier = old_speed
end
)
local function do_projectile(player_surface, name, _position, _force, target, max_range)
player_surface.create_entity(
{
name = name,
position = _position,
force = _force,
source = _position,
target = target or nil,
max_range = max_range or nil,
speed = 0.4,
fast_replace = true,
create_build_effect_smoke = false
}
)
end
local function create_projectiles(data)
local self = data.self
local player = data.player
local rpg_t = data.rpg_t
local damage_entity = data.damage_entity
local position = data.position
local surface = data.surface
@@ -13,22 +130,12 @@ local function create_projectiles(data)
local target_pos = data.target_pos
local range = data.range
local function do_projectile(player_surface, name, _position, _force, target, max_range)
player_surface.create_entity(
{
name = name,
position = _position,
force = _force,
source = _position,
target = target,
max_range = max_range,
speed = 0.4
}
)
end
if self.aoe then
for _ = 1, self.amount do
if self.mana_cost > rpg_t.mana then
break
end
local damage_area = {
left_top = {x = position.x - 2, y = position.y - 2},
right_bottom = {x = position.x + 2, y = position.y + 2}
@@ -37,6 +144,7 @@ local function create_projectiles(data)
if self.damage then
for _, e in pairs(surface.find_entities_filtered({area = damage_area})) do
damage_entity(e)
Public.remove_mana(player, self.mana_cost)
end
end
end
@@ -46,14 +154,16 @@ local function create_projectiles(data)
right_bottom = {x = position.x + 2, y = position.y + 2}
}
do_projectile(surface, self.entityName, position, force, target_pos, range)
if self.damage then
for _, e in pairs(surface.find_entities_filtered({area = damage_area})) do
damage_entity(e)
end
end
end
Public.cast_spell(player)
Public.remove_mana(player, self.mana_cost)
end
end
end
Public.cast_spell(player)
end
local function create_entity(data)
@@ -93,8 +203,8 @@ local function create_entity(data)
Public.remove_mana(player, self.mana_cost)
end
end
Public.cast_spell(player)
Public.remove_mana(player, self.mana_cost)
end
local function insert_onto(data)
@@ -520,7 +630,7 @@ spells[#spells + 1] = {
mana_cost = 100,
tick = 100,
enabled = true,
sprite = 'recipe/explosives',
sprite = 'recipe=explosives',
callback = function(data)
local self = data.self
local player = data.player
@@ -561,13 +671,31 @@ spells[#spells + 1] = {
mana_cost = 150,
tick = 100,
enabled = true,
sprite = 'recipe/repair-pack',
sprite = 'recipe=repair-pack',
callback = function(data)
local self = data.self
local rpg_t = data.rpg_t
local player = data.player
local position = data.position
Public.repair_aoe(player, position)
local range = Public.get_area_of_effect_range(player)
area_of_effect(
player,
position,
'support',
range,
function(entity)
if entity.prototype.max_health ~= entity.health then
if self.mana_cost < rpg_t.mana then
Task.set_timeout_in_ticks(10, repair_buildings, {entity = entity})
Public.remove_mana(player, self.mana_cost)
end
end
end,
true
)
Public.cast_spell(player)
Public.remove_mana(player, self.mana_cost)
end
@@ -585,9 +713,30 @@ spells[#spells + 1] = {
mana_cost = 70,
tick = 100,
enabled = true,
sprite = 'virtual-signal/signal-S',
sprite = 'virtual-signal=signal-S',
callback = function(data)
create_projectiles(data)
local self = data.self
local rpg_t = data.rpg_t
local player = data.player
local position = data.position
local range = Public.get_area_of_effect_range(player)
area_of_effect(
player,
position,
'attack',
range,
function(p)
if self.mana_cost < rpg_t.mana then
do_projectile(player.surface, 'acid-stream-spitter-big', p, player.force, p)
Public.remove_mana(player, self.mana_cost)
end
end,
false
)
Public.cast_spell(player)
end
}
spells[#spells + 1] = {
@@ -601,7 +750,7 @@ spells[#spells + 1] = {
mana_cost = 10000, -- they who know, will know
tick = 320,
enabled = false,
sprite = 'entity/tank',
sprite = 'entity=tank',
callback = function(data)
create_entity(data)
end
@@ -617,7 +766,7 @@ spells[#spells + 1] = {
mana_cost = 19500, -- they who know, will know
tick = 320,
enabled = false,
sprite = 'entity/spidertron',
sprite = 'entity=spidertron',
callback = function(data)
create_entity(data)
end
@@ -636,7 +785,7 @@ spells[#spells + 1] = {
mana_cost = 140,
tick = 320,
enabled = true,
sprite = 'item/raw-fish',
sprite = 'item=raw-fish',
callback = function(data)
insert_onto(data)
end
@@ -655,7 +804,7 @@ spells[#spells + 1] = {
mana_cost = 140,
tick = 320,
enabled = true,
sprite = 'item/explosives',
sprite = 'item=explosives',
callback = function(data)
insert_onto(data)
end
@@ -673,7 +822,7 @@ spells[#spells + 1] = {
mana_cost = 150,
tick = 320,
enabled = true,
sprite = 'entity/compilatron',
sprite = 'entity=compilatron',
callback = function(data)
local self = data.self
local player = data.player
@@ -698,7 +847,7 @@ spells[#spells + 1] = {
mana_cost = 220,
tick = 320,
enabled = true,
sprite = 'recipe/distractor-capsule',
sprite = 'recipe=distractor-capsule',
callback = function(data)
create_projectiles(data)
end
@@ -713,7 +862,7 @@ spells[#spells + 1] = {
mana_cost = 340,
tick = 2000,
enabled = true,
sprite = 'virtual-signal/signal-W',
sprite = 'virtual-signal=signal-W',
callback = function(data)
local player = data.player
local surface = data.surface
@@ -731,6 +880,93 @@ spells[#spells + 1] = {
Public.cast_spell(player)
end
}
spells[#spells + 1] = {
name = {'spells.charge'},
entityName = 'haste',
target = false,
force = 'player',
level = 25,
type = 'special',
mana_cost = 100,
tick = 2000,
check_if_active = true,
enabled = true,
sprite = 'virtual-signal=signal-info',
callback = function(data)
local self = data.self
local player = data.player
local rpg_t = data.rpg_t
rpg_t.has_custom_spell_active = true
Public.remove_mana(player, self.mana_cost)
for _ = 1, 3 do
player.play_sound {path = 'utility/armor_insert', volume_modifier = 1}
end
Task.set_timeout_in_ticks(300, restore_movement_speed_token, {player_index = player.index, old_speed = player.character.character_running_speed_modifier, rpg_t = rpg_t})
player.character.character_running_speed_modifier = player.character.character_running_speed_modifier + 1
Public.cast_spell(player)
end
}
spells[#spells + 1] = {
name = {'spells.eternal_blades'},
entityName = 'eternal_blades',
target = false,
force = 'player',
level = 25,
type = 'special',
mana_cost = 100,
tick = 2000,
check_if_active = true,
enabled = false,
sprite = 'virtual-signal=signal-info',
callback = function(data)
local self = data.self
local player = data.player
local position = data.position
local range = Public.get_area_of_effect_range(player)
local damage = 34
area_of_effect(
player,
position,
'attack',
range,
function(entity)
if entity.force.index ~= player.force.index then
local get_health_pool = Public.has_health_boost(entity, damage, damage, player.character)
if get_health_pool then
local max_unit_health = floor(get_health_pool * 0.00015)
if max_unit_health <= 0 then
max_unit_health = 4
end
if max_unit_health >= 10 then
max_unit_health = 10
end
local final = floor(damage * max_unit_health)
Public.set_health_boost(entity, final, player.character)
if entity.valid and entity.health <= 0 and get_health_pool <= 0 then
entity.die(entity.force.name, player.character)
end
else
if entity.valid then
entity.health = entity.health - damage * 0.05
if entity.health <= 0 then
entity.die(entity.force.name, player.character)
end
end
end
end
end,
true
)
Public.cast_spell(player)
Public.remove_mana(player, self.mana_cost)
end
}
Public.projectile_types = {
['explosives'] = {name = 'grenade', count = 0.5, max_range = 32, tick_speed = 1},
@@ -772,7 +1008,7 @@ Public.projectile_types = {
}
Public.get_projectiles = Public.projectile_types
Public.spells = spells
Public.all_spells = spells
--- Retrieves the spells table or a given spell.
---@param key string
@@ -780,10 +1016,10 @@ function Public.get_spells(key)
if game then
return error('Calling Public.get_spells() after on_init() or on_load() has run is a desync risk.', 2)
end
if Public.spells[key] then
return Public.spells[key]
if Public.all_spells[key] then
return Public.all_spells[key]
else
return Public.spells
return Public.all_spells
end
end
@@ -798,10 +1034,10 @@ function Public.disable_spell(key)
if type(key) == 'table' then
for _, k in pairs(key) do
Public.spells[k].enabled = false
Public.all_spells[k].enabled = false
end
elseif Public.spells[key] then
Public.spells[key].enabled = false
elseif Public.all_spells[key] then
Public.all_spells[key].enabled = false
end
end
@@ -811,7 +1047,7 @@ function Public.clear_spell_table()
return error('Calling Public.clear_spell_table() after on_init() or on_load() has run is a desync risk.', 2)
end
Public.spells = {}
Public.all_spells = {}
end
--- Adds a spell to the rpg_spells
@@ -859,7 +1095,7 @@ function Public.set_new_spell(tbl)
return error('A spell requires enabled. boolean', 2)
end
Public.spells[#Public.spells + 1] = tbl
Public.all_spells[#Public.all_spells + 1] = tbl
end
end
@@ -894,7 +1130,7 @@ function Public.disable_cooldowns_on_spells()
end
end
Public.spells = new_spells
Public.all_spells = new_spells
return new_spells
end

View File

@@ -10,6 +10,9 @@ local this = {
--! Gui Frames
local settings_frame_name = Gui.uid_name()
local settings_tooltip_frame = Gui.uid_name()
local close_settings_tooltip_frame = Gui.uid_name()
local settings_tooltip_name = Gui.uid_name()
local save_button_name = Gui.uid_name()
local discard_button_name = Gui.uid_name()
local draw_main_frame_name = Gui.uid_name()
@@ -43,7 +46,6 @@ Public.gui_settings_levels = {
['reset_text_label'] = 50,
['stone_path_label'] = 20,
['aoe_punch_label'] = 30,
['flameboots_label'] = 100,
['explosive_bullets_label'] = 50
}
@@ -103,7 +105,6 @@ function Public.reset_table()
this.rpg_extra.enable_mana = false
this.rpg_extra.mana_limit = 100000
this.rpg_extra.enable_wave_defense = false
this.rpg_extra.enable_flame_boots = false
this.rpg_extra.enable_explosive_bullets = false
this.rpg_extra.enable_explosive_bullets_globally = false
this.rpg_extra.enable_range_buffs = false
@@ -294,14 +295,6 @@ function Public.enable_wave_defense(value)
return this.rpg_extra.enable_wave_defense
end
--- Enables/disabled flame boots.
---@param value boolean
function Public.enable_flame_boots(value)
this.rpg_extra.enable_flame_boots = value or false
return this.rpg_extra.enable_flame_boots
end
--- Enables/disabled explosive bullets globally.
---@param value boolean
function Public.enable_explosive_bullets_globally(value)
@@ -396,6 +389,9 @@ function Public.tweaked_crafting_items(tbl)
end
Public.settings_frame_name = settings_frame_name
Public.settings_tooltip_frame = settings_tooltip_frame
Public.close_settings_tooltip_frame = close_settings_tooltip_frame
Public.settings_tooltip_name = settings_tooltip_name
Public.save_button_name = save_button_name
Public.discard_button_name = discard_button_name
Public.draw_main_frame_name = draw_main_frame_name