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 >= 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.left[main_frame_name] then local f = player.gui.left[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.left[main_frame_name] then local f = player.gui.left[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)