mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-03-25 21:29:06 +02:00
Merge branch 'ComfyFactory:develop' into develop
This commit is contained in:
commit
25efb28a93
27
.github/workflows/CheckMaps.yml
vendored
Normal file
27
.github/workflows/CheckMaps.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: CheckMaps
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the develop branch
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
pull_request:
|
||||
branches: [develop]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check if requestor has made a boo boo
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Factorio Control comment
|
||||
uses: Gerkiz/FactorioControlChecker@v1.0.6
|
||||
id: factorio_control_runner
|
||||
|
||||
- name: Check control.lua
|
||||
if: steps.factorio_control_runner.outputs.should_run == 1
|
||||
run: |
|
||||
echo "Maps are required in control.lua - please fix these."
|
||||
exit 1
|
@ -18,6 +18,7 @@ require 'utils.datastore.quickbar_data'
|
||||
require 'utils.datastore.message_on_join_data'
|
||||
require 'utils.datastore.player_tag_data'
|
||||
require 'utils.datastore.supporters'
|
||||
require 'utils.datastore.banhandler'
|
||||
require 'utils.chatbot'
|
||||
require 'utils.commands'
|
||||
require 'utils.antigrief'
|
||||
|
@ -9,19 +9,20 @@ spidertron_unlocked=[color=blue]Mapkeeper:[/color]\nAttention! Spidertron has be
|
||||
wall_breached=[color=blue]Mapkeeper:[/color]\nSurvivor! Well done. You have completed zone __1__!
|
||||
first_to_reach=[color=blue]Mapkeeper:[/color]\n__1__ was the first to reach zone __2__.
|
||||
artillery_warning=[color=blue]Mapkeeper:[/color]\nWarning, Artillery have been spotted north!
|
||||
cheating_through=__1__ tried to cheat their way north with their spidertron!
|
||||
hinder=You are too far away from the main locomotive. You cannot go beyond this point.
|
||||
cheating_through=[color=blue]Mapkeeper:[/color] __1__ tried to cheat their way north with their spidertron!
|
||||
hinder=[color=blue]Mapkeeper:[/color] You are too far away from the main locomotive. You cannot go beyond this point.
|
||||
heavy_legs=[color=blue]Mapkeeper:[/color] Your legs feels all of a sudden very heavy.
|
||||
|
||||
|
||||
[entity]
|
||||
treasure_1=You notice an old crate within the rubble. It's filled with treasure!
|
||||
treasure_2=You find a chest underneath the broken rocks. It's filled with goodies!
|
||||
treasure_3=We has found the precious!
|
||||
treasure_rare_1=Your magic improves. You have found a chest that is filled with rare treasures!
|
||||
treasure_rare_2=Oh how wonderful. You found a chest underneath the broken rocks. It's filled with rare goodies!
|
||||
treasure_rare_3=You're a wizard! We have found the rare precious!
|
||||
treasure_1=[color=blue]Mapkeeper:[/color] You notice an old crate within the rubble. It's filled with treasure!
|
||||
treasure_2=[color=blue]Mapkeeper:[/color] You find a chest underneath the broken rocks. It's filled with goodies!
|
||||
treasure_3=[color=blue]Mapkeeper:[/color] We has found the precious!
|
||||
treasure_rare_1=[color=blue]Mapkeeper:[/color] Your magic improves. You have found a chest that is filled with rare treasures!
|
||||
treasure_rare_2=[color=blue]Mapkeeper:[/color] Oh how wonderful. You found a chest underneath the broken rocks. It's filled with rare goodies!
|
||||
treasure_rare_3=[color=blue]Mapkeeper:[/color] You're a wizard! We have found the rare precious!
|
||||
defeated_1=[color=blue]Mapkeeper:[/color]\nOh no, the biters nom'ed the train away!\nBetter luck next time.
|
||||
defeated_2=[color=blue]Mapkeeper:[/color]\nI'm not 100% sure, but - apparently the train was chewed away.\nBetter luck next time.
|
||||
defeated_2=[color=blue]Mapkeeper:[/color]\nApparently the train was chewed away.\nBetter luck next time.
|
||||
defeated_3=[color=blue]Mapkeeper:[/color]\nYou had one objective - defend the train *-*\nBetter luck next time.
|
||||
defeated_4=[color=blue]Mapkeeper:[/color]\nLooks like we're resetting cause you did not defend the train ._.\nBetter luck next time.
|
||||
reset_game=*** Soft-reset is disabled! Server will restart from scenario to load new changes. ***
|
||||
@ -30,8 +31,8 @@ shutdown_game=*** Soft-reset is disabled! Server will shutdown. Most likely beca
|
||||
notify_shutdown=Soft-reset is disabled! Server will shutdown. Most likely because of updates.
|
||||
train_taking_damage=[color=blue]Comfylatron:[/color]\nTrain is taking heavy damage.\nDeploying defense mechanisms.
|
||||
entity_limit_reached=__1__ limit reached. Purchase more slots at the market!
|
||||
found_car=__1__ has found a car underneath the rumble!
|
||||
radar_limit=Another radar is found nearby!
|
||||
found_car=[color=blue]Mapkeeper:[/color] __1__ has found a car underneath the rumble!
|
||||
radar_limit=[color=blue]Mapkeeper:[/color] Another radar is found nearby!
|
||||
|
||||
|
||||
[gui]
|
||||
@ -91,18 +92,18 @@ locomotive_health=__1__ unlocked the last missing piece for the mystical chest!\
|
||||
|
||||
|
||||
[main_market]
|
||||
chest=Upgrades the amount of chests that can be placed outside.\nCan be purchased multiple times. [__1__/7]
|
||||
locomotive_max_health=Upgrades the train health.\nCan be purchased multiple times. [__1__/99]
|
||||
locomotive_xp_aura=Upgrades the XP aura that is around the train. [__1__]
|
||||
chest=Upgrades the amount of chests that can be placed outside.\nCan be purchased multiple times. [__1__/__2__]
|
||||
locomotive_max_health=Upgrades the train health.\nCan be purchased multiple times. [__1__/__2__]
|
||||
locomotive_aura_radius=Upgrades the XP aura that is around the train. [__1__/__2__]\n[Limited to save UPS]
|
||||
global_car_health_modifier=Grants all cars/tanks/spidertrons a global health modifier.
|
||||
xp_points_boost=Upgrades the amount of XP points you get inside the XP aura [__1__]
|
||||
xp_points_boost=Upgrades the amount of XP points you get inside the XP aura [__1__/♾]
|
||||
mystical_chest=Rerolls the mystical chest.
|
||||
explosive_bullets=Upgrades ordinary SMG ammo to explosive bullets.
|
||||
reroll_market_items=Will reroll the items in the market and shuffle prices.
|
||||
purchase_pickaxe=Upgrade the teams Pickaxe to tier: __1__ [__2__/58]
|
||||
purchase_pickaxe=Upgrade the teams Pickaxe to tier: __1__ [__2__/__3__]
|
||||
sold_out=Sold out!
|
||||
flamethrower_turret=Upgrades the amount of flamethrowers that can be placed. [__1__]
|
||||
land_mine=Upgrades the amount of landmines that can be placed. [__1__]
|
||||
flamethrower_turret=Upgrades the amount of flamethrowers that can be placed. [__1__/♾]
|
||||
land_mine=Upgrades the amount of landmines that can be placed. [__1__/♾]
|
||||
car=Portable Car Surface\nCan be killed easily.
|
||||
tank=Portable Tank Surface\nChonk tank, can resist heavy damage.
|
||||
tank_cannon_na=Tank Cannon\nAvailable after wave __1__.
|
||||
@ -118,7 +119,13 @@ death_message_6=__1__ got obliterated!
|
||||
death_message_7=__1__ tried to cheat their way north!
|
||||
forcefield=Forcefield does not approve.
|
||||
greeting=[color=blue]Comfylatron:[/color]\nGreetings, __1__!\nPlease read the map info.
|
||||
death_mode_warning=[color=blue]Comfylatron:[/color]\nCAUTION! Walking outside of the locomotive aura will kill you!
|
||||
aura_upgrade_warning=[color=blue]Comfylatron:[/color]\nThe locomotive aura range has been upgraded!
|
||||
damage_mode_warning=[color=blue]Comfylatron:[/color]\nCAUTION! Walking outside of the locomotive aura will slowly kill you!
|
||||
cleaner=[color=blue]Cleaner:[/color]\n__1__ has left his goodies! Be quick and fetch them!
|
||||
reset_in=Game will __1__ in __2__ seconds!
|
||||
diff_set=Difficulty has been set! Game has been set to: [color=green]__1__[/color]
|
||||
diff_tooltip=Wave Defense is based on amount of players.\nBonus XP on join: __1__.\nMining speed boost: __2__.\nRunning speed boost: __3__.\nCrafting speed boost: __4__.\nMaximum coin per harvest: __5__.\nFlame Turret limit: __6__.\nLandmine limit: __7__.\nLocomotive health: __8__.\nHidden Treasure has __9__ chance to spawn.\nGrace period: __10__ minutes\nSpidertrons unlocks at zone __11__.
|
||||
|
||||
[functions]
|
||||
researched_complete=__1__ has been researched!
|
||||
|
@ -130,6 +130,9 @@ pointy_explosives=Detonate Chest
|
||||
repair_aoe=Repair AOE
|
||||
charge=Charge
|
||||
eternal_blades=Eternal Blades
|
||||
drone_enemy=Drone - Enemy
|
||||
drone_mine=Drone - Mine
|
||||
|
||||
|
||||
|
||||
[allocations]
|
||||
|
@ -101,7 +101,7 @@ spidertron_not_allowed=Паукотроны не допускаются на п
|
||||
[mountain_fortress]
|
||||
map_info_main_caption=Г О Р Н А Я К Р Е П О С Т Ь
|
||||
map_info_sub_caption= ..копаю копаю чух чух..
|
||||
map_info_text=Кусаки уловили запах рыбы в грузовом вагоне.\nПроводите поезд в гору и защищайте его как можно дольше!\nЭто, однако, будет нелёгкой задачей,\nпоскольку их сила и численность со временем увеличиваются.\n\nКроме того, южные земли со временем разрушаются.\n\nПродвигайтесь глубже для больших сокровищ, и сталкивайтесь с возрастающими опасностями.\nИсследование продуктивности добычи приведет к улучшению вашего добывающего оборудования,\nусилит вашу кирку, а также увеличит размер вашего рюкзака.\n\nКогда вы будете копать, вы встретите непроходимые темные пропасти или реки.\nНемного взрывчатки может заставить части потолка рассыпаться, заполняя пустоту, создавая новые пути.\nВсё, что вам нужно, это контейнер и прицельный выстрел.\n\nВы можете найти полезные припасы, если войдете в вагон.\nУдачи вам в пути!
|
||||
map_info_text=Кусаки уловили запах рыбы в грузовом вагоне.\nПроводите поезд в гору и защищайте его как можно дольше!\nЭто, однако, будет нелёгкой задачей,\nпоскольку их сила и численность со временем увеличиваются.\n\nКроме того, южные земли со временем разрушаются.\n\nПродвигайтесь глубже, находите больше сокровищ, но и опасности возрастают.\nИсследование продуктивности добычи приведет к улучшению вашего добывающего оборудования,\nусилит вашу кирку, а также увеличит размер вашего рюкзака.\n\nКогда вы будете копать, вы встретите непроходимые темные пропасти или реки.\nНемного взрывчатки может заставить части потолка рассыпаться, заполняя пустоту, создавая новые пути.\nВсё, что вам нужно, это контейнер и точный выстрел.\n\nВы можете найти полезные припасы, если войдете в вагон.\nУдачи вам в пути!
|
||||
|
||||
[rocks_yield_ore_veins]
|
||||
coal=угля
|
||||
@ -142,6 +142,7 @@ angels-ore6=коричневое
|
||||
gui_1=Первая волна через
|
||||
gui_2=Волна:
|
||||
gui_3=Угроза:
|
||||
gui_4=Пауза на:
|
||||
tooltip_1=Высокая угроза может усилить кусак.\nЗдоровье кусак: __1__%\nМаксимум активных кусак: __2__~
|
||||
tooltip_2=доход / минуту
|
||||
|
||||
|
@ -17,6 +17,9 @@ turret_filler_label_enabled=Включено:
|
||||
turret_filler_label_amount=Количество:
|
||||
turret_filler_ammo_type=Боеприпасы:
|
||||
turret_filler_ammo_lower=Включить предыдущие уровни?
|
||||
blueprint_requesting=Запрос по чертежу
|
||||
blueprint_requesting_desc=Если положить чертёж в [entity=logistic-chest-requester] или [entity=logistic-chest-buffer], то сундук запросит предметы, нужные для постройки чертежа. Запрос формируется при закрытии сундука.
|
||||
blueprint_requesting_notify=На этом сервере включена функция "Запрос по чертежу". Если положить чертёж в [entity=logistic-chest-requester] или [entity=logistic-chest-buffer], то сундук запросит предметы, нужные для постройки чертежа. Вы можете отключить функцию в меню Comfy -> Config.
|
||||
|
||||
[modules_towny]
|
||||
map_info=__1__\n\n__2__\n\n__3__\n\n__4__\n\n__5__
|
||||
|
@ -1,7 +1,7 @@
|
||||
[mountain_fortress_v3]
|
||||
map_info_main_caption=Г О Р Н А Я К Р Е П О С Т Ь V3
|
||||
map_info_sub_caption= ~~ копаю копаю чух чух ~~
|
||||
map_info_text=[color=red]ПРОЧТИТЕ ЭТО!\nЕсли встретите ошибки или десинхронизацию, сообщите @Gerkiz!\nЕсли встретятся ошибки, ломающие игру, карта может быть перезагружена для исправления.[/color]\n\nКусаки уловили запах рыбы в грузовом вагоне.\nПроводите поезд в гору и защищайте его как можно дольше!\nЭто, однако, будет нелёгкой задачей,\nпоскольку их сила и численность со временем увеличиваются.\n\nКроме того, южные земли со временем разрушаются.\n\nПродвигайтесь глубже для больших сокровищ, и сталкивайтесь с возрастающими опасностями.\nИсследование продуктивности добычи приведет к улучшению вашего добывающего оборудования, и увеличит размер вашего рюкзака.\n\nКогда вы будете копать, вы встретите непроходимые тёмные пропасти или реки.\nПо вам будет стрелять артиллерия! Копайте быстро, копайте на север!\n\nНемного взрывчатки может вызвать обвал гор, заполняя пустоту, создавая новые пути.\nВсё, что вам нужно, это контейнер и точный выстрел.\n\nВойдите в грузовой вагон, чтобы открыть пространство вагона!\n\nСлучайные здания, генерирующие ресурсы, могут быть найдены в мире.\n\nРазмещение стальных сундуков рядом с грузовыми вагонами позволить быстро перемещать содержимое.\n\nНахождение в зоне локомотива предотвращает появление кусак при добыче объектов.\n\nИнтерфейс RPG отключается внутри локомотива.\nОтсоединение вагонов отключено.\nВы не можете отменить крафт, находясь в зоне локомотива.\n\nНе пытайтесь идти на север на Паукотроне, если поезд не рядом с вами.\nВы были предупреждены.\nУ буров большой бонус производительности, и его можно увеличить исследованиями, используйте по возможности!\nЗагадочный сундук в локомотиве предлагает некоторые награды.\nЕго нужно накормить, чтобы получить награды.\n\nУдачи вам в пути!
|
||||
map_info_text=[color=red]ПРОЧТИТЕ ЭТО!\nЕсли встретите ошибки или десинхронизацию, сообщите @Gerkiz!\nЕсли встретятся ошибки, ломающие игру, карта может быть перезагружена для исправления.[/color]\n\nКусаки уловили запах рыбы в грузовом вагоне.\nПроводите поезд в гору и защищайте его как можно дольше!\nЭто, однако, будет нелёгкой задачей,\nпоскольку их сила и численность со временем увеличиваются.\n\nКроме того, южные земли со временем разрушаются.\n\nПродвигайтесь глубже для больших сокровищ, и сталкивайтесь с возрастающими опасностями.\nИсследование продуктивности добычи приведет к улучшению вашего добывающего оборудования, и увеличит размер вашего рюкзака.\n\nКогда вы будете копать, вы встретите непроходимые тёмные пропасти или реки.\nПо вам будет стрелять артиллерия! Копайте быстро, копайте на север!\n\nНемного взрывчатки может вызвать обвал гор, заполняя пустоту, создавая новые пути.\nВсё, что вам нужно, это контейнер и точный выстрел.\n\nВойдите в грузовой вагон, чтобы открыть пространство вагона!\n\nСлучайные здания, генерирующие ресурсы, могут быть найдены в мире.\n\nРазмещение стальных сундуков рядом с грузовыми вагонами позволить быстро перемещать содержимое.\n\nНахождение в зоне локомотива предотвращает появление кусак при добыче объектов.\n\nРадары нельзя строить рядом друг с другом.\n\nИнтерфейс RPG отключается внутри локомотива.\nОтсоединение вагонов отключено.\nВы не можете отменить крафт, находясь в зоне локомотива.\n\nНе пытайтесь идти на север на Паукотроне, если поезд не рядом с вами.\nВы были предупреждены.\nУ буров большой бонус производительности, и его можно увеличить исследованиями, используйте по возможности!\nЗагадочный сундук в локомотиве предлагает некоторые награды.\nЕго нужно накормить, чтобы получить награды.\n\nУдачи вам в пути!
|
||||
|
||||
[breached_wall]
|
||||
collapse_start=[color=blue]Хранитель карты:[/color]\nПредупреждение, начинается коллапс!
|
||||
@ -30,6 +30,7 @@ notify_shutdown=Мягкий сброс отключён! Сервер буде
|
||||
train_taking_damage=[color=blue]Комфилатрон:[/color]\nПоезд получает большой урон.\nАктивирую защитные механизмы.
|
||||
entity_limit_reached=__1__: достигнут предел. Приобретите больше ячеек на рынке!
|
||||
found_car=__1__ нашёл машину под обломками!
|
||||
radar_limit=Другой радар обнаружен неподалёку!
|
||||
|
||||
[gui]
|
||||
global_pool_tooltip=Копай, создавай или беги, чтобы увеличить общий опыт!
|
||||
@ -49,7 +50,7 @@ map_off=ВЫКЛ
|
||||
[locomotive]
|
||||
upgrades=Улучшения:
|
||||
items=Предметы:
|
||||
shoo=^-^ Пожалуйста, не пугайте меня ^-^
|
||||
shoo=[Братан Десинхрона]
|
||||
not_trusted=Чтобы купить это, вам нужно быть доверенным.
|
||||
coins_left=Монет осталось: __1__
|
||||
market_name=Рынок
|
||||
@ -89,7 +90,7 @@ locomotive_health=__1__ разблокировал последнюю недос
|
||||
[main_market]
|
||||
chest=Увеличивает количество сундуков, которые можно разместить снаружи.\nМожно купить несколько раз. [__1__/7]
|
||||
locomotive_max_health=Улучшает здоровье поезда.\nМожно купить несколько раз. [__1__/99]
|
||||
locomotive_xp_aura=Улучшает зону опыта вокруг поезда. [__1__]
|
||||
locomotive_aura_radius=Улучшает зону опыта вокруг поезда. [__1__]
|
||||
global_car_health_modifier=Даёт всем автомобилям/танкам/паукотронам глобальный модификатор здоровья.
|
||||
xp_points_boost=Увеличивает количество очков опыта, которые вы получаете внутри зоны опыта. [__1__]
|
||||
mystical_chest=Обновляет содержимое загадочного сундука.
|
||||
|
39
locale/ru/pirates.cfg
Normal file
39
locale/ru/pirates.cfg
Normal file
@ -0,0 +1,39 @@
|
||||
[pirates]
|
||||
softmod_info_header_before_version_number==== Пиратский корабль v
|
||||
softmod_info_header_after_version_number= ===
|
||||
softmod_info_body_1=Новости и чат: getcomfy.eu/discord
|
||||
softmod_info_game_description_1=Описание игры
|
||||
softmod_info_game_description_2=Отправляйтесь в плавание в этом многопользовательском сценарии. Собирайте ресурсы и заправляйте корабль, чтобы выжить как можно больше лиг. Корабль движется с помощью магии кода. У каждой команды есть капитан, который выполняет такие действия, как решение, когда отплывать. Дублоны можно потратить на различных рынках на протяжении всей игры.\n\nЧем меньше команда, тем медленнее игровой прогресс.\n\n[font=default-bold]Условие победы:[/font] Пройдите 1000 лиг.\n[font=default-bold]Условие проигрыша:[/font] У корабля закончилось топливо или уничтожена пушка.
|
||||
softmod_info_bugs_1=Известные недоработки
|
||||
softmod_info_bugs_2=•
|
||||
softmod_info_new_players_1=Для новых игроков
|
||||
softmod_info_new_players_2=Добывайте уголь и другие ресурсы и приносите их на корабль, чтобы поддерживать работу, или попробуйте попросить капитана о более конкретных задачах.
|
||||
softmod_info_tips_1=Особенности игры, с которыми сложно справиться в одиночку
|
||||
softmod_info_tips_2=• Вы можете управлять лодкой из вороньего гнезда, поместив 100 светофоров в один из синих ящиков.\n• Ресурсы, предоставленные кораблю, появляются в каюте капитана.\n• Зарядка шахты запускает ракету. Это вызывает загрязнение и эволюцию, но дает награду в виде топлива и дублонов.\n• Зарядка ракетной шахты высасывает энергию из всего остального в её сети.\n• Количество руды, доступной на острове, не зависит от порядка, в котором вы разрушаете камни.\n• Пассивное загрязнение на каждом острове со временем увеличивается.\n• Сила атак пропорциональна количеству оставшихся гнёзд. (Скорость эволюции, основанная на времени, также пропорциональна гнездам, но разрушение гнезда немедленно поднимет эволюцию на большую часть величины, которую оно «заработало бы», если бы оно выжило.)\n• Крытые рынки возвращают все плиты, потраченные на их разблокировку.\n• Производительность лабораторий увеличивается с каждой лигой.\n• Игрок, который дольше всех был капитаном между лигами 0 и 1000 (эксклюзивно), записывается в таблицу рекордов.\n• Вышедшие из игры игроки сохраняют свои предметы при себе на какое-то время — за исключением «важных» предметов, которые немедленно возвращаются команде.\n• Команды: /ccolor дает вам забавный цвет. /classinfo {имя класса} дает описание именованного класса. Чтобы управлять своим классом, используйте /take {имя класса} или /giveup. У капитанов также есть /undoc, /req, /officer, /plank.
|
||||
softmod_info_updates_1=Недавние изменения
|
||||
softmod_info_updates_2=v1.1.2.2.2\n- Перебалансирована сложность Nightmare\n\nv1.1.2.2.1\n- Понижение некоторых классов удалено.\n- Мелкие исправления.\n\nv1.1.2.2.0\n- Реквизиция монет заменена «налогом», который берет только 10% монет каждого игрока.\n- Увеличена монетная экономика; Награды за ракетные монеты теперь по умолчанию относятся ко второму сундуку с наградами.\n- Палубный матрос урезан в возможностях.
|
||||
softmod_info_credits_1=Создатели
|
||||
softmod_info_credits_2=Пиратский корабль разработан и написан thesixthroc. Кодовая база Comfy и помощь от Gerkiz, Hanakocz и Mew @ Comfy Industries (https://getcomfy.eu). Некоторые чертежи структуры острова предоставлены Mattisso.\n\nthesixthroc ищет программистов, которые помогут реализовать запланированные функции для этого мода. Приходите поболтать с нами: https://getcomfy.eu/discord\n\n"Эти белые перчатки. Я никогда не забуду их до самой смерти." - Доктор Джон
|
||||
softmod_info_credits_2_old=Мод разработан и написан thesixthroc. Кодовая база Comfy и помощь от Gerkiz, Hanakocz и Mew @ Comfy Industries (https://getcomfy.eu). Некоторые чертежи структуры острова предоставлены Mattisso. Спрайт золота от Clint Bellanger. Спрайты попугая от @pixelthen.\n\n"Эти белые перчатки. Я никогда не забуду их до самой смерти." - Доктор Джон
|
||||
softmod_info_body_promote=от thesixthroc
|
||||
softmod_info_body_promote_old2=patreon.com/thesixthroc
|
||||
softmod_info_body_clicky=Нажмите, чтобы закрыть.
|
||||
softmod_info_body_some_old_stuff="Эти белые перчатки. Я никогда не забуду их до самой смерти." - Доктор Джон
|
||||
proposal_displayform=__1__ — __2__
|
||||
run_displayform= __2__
|
||||
crewmember_displayform=[color=__2__,__3__,__4__]__5__[/color] [color=1,1,1]__6__[/color]
|
||||
capacity_tooltip=Вместимость. Установите максимальное количество членов команды.
|
||||
difficulty_tooltip=Сложность.\n\nБолее высокие сложности имеют более высокое загрязнение и эволюцию, более высокий урон от кусак, меньшую добычу золота, но более высокую добычу из сундуков, наряду с небольшими эффектами на время на остров, требования к квестам и положение ракетной шахты.\n\nСложность также определяет материал, из которого сделан корабль.
|
||||
mode_tooltip=Режим.
|
||||
auto_undock_tooltip=Максимальное время пребывания в этом месте.\n\nПо истечении этого времени лодка автоматически отплывает. Капитан может дать команду отплыть раньше, нажав эту кнопку.
|
||||
atsea_loading_tooltip=Следующий пункт назначения загружается.
|
||||
leave_anytime_tooltip=Капитан выбирает, когда отстыковать корабль.\n\nОни могут отстыковаться, нажав эту кнопку.
|
||||
resources_needed_tooltip_0=В следующем пункте назначения эти ресурсы понадобятся для отстыковки.
|
||||
resources_needed_tooltip_1=В следующем пункте назначения эти ресурсы потребуются для ранней отстыковки.\n\nЧем дольше вы остаётесь, тем меньше ресурсов потребуется, и в конечном итоге они уменьшатся до нуля.
|
||||
resources_needed_tooltip_2=Капитан может отстыковаться досрочно, нажав эту кнопку, но только в том случае, если в каюте капитана хранится достаточно ресурсов.\n\nСтоимость по прибытии: __1__\nПри отходе сейчас будет потрачено: __2__
|
||||
resources_needed_tooltip_3=Капитан может отстыковаться, нажав эту кнопку, но только если в каюте капитана хранится достаточно ресурсов.
|
||||
resources_needed_tooltip_0_rocketvariant=В следующем пункте назначения эти ресурсы потребуются для отстыковки.\n\nРакетная шахта представляет собой запуск ракеты, а не ресурс.
|
||||
resources_needed_tooltip_1_rocketvariant=В следующем пункте назначения эти ресурсы потребуются для ранней отстыковки.\n\nЧем дольше вы остаётесь, тем меньше ресурсов потребуется, и в конечном итоге их количество упадет до нуля.\n\nРакетная шахта представляет собой запуск ракеты, а не ресурс.
|
||||
resources_needed_tooltip_2_rocketvariant=Капитан может отстыковаться раньше, нажав эту кнопку, но только в том случае, если в каюте капитана хранится достаточно ресурсов.\n\nРакетная шахта представляет собой запуск ракеты, а не ресурс.\n\nСтоимость по прибытии: __1__\nПри отходе сейчас будет потрачено : __2__
|
||||
resources_needed_tooltip_3_rocketvariant=Капитан может отстыковаться, нажав эту кнопку, но только в том случае, если в каюте капитана хранится достаточно ресурсов.\n\nРакетная шахта представляет собой запуск ракеты, а не ресурс.
|
||||
fuel_tooltip=Запас топлива: __1__.\n\nЧтобы запасти больше, отправьте его в каюту капитана. Если у корабля закончится топливо, экипаж проиграл.
|
@ -2,6 +2,7 @@
|
||||
no_valid_surface=Название поверхности не указано
|
||||
flame_boots_worn_out=Ваши огненные сапоги износились.
|
||||
flame_mana_remaining=Маны осталось: __1__
|
||||
aoe_punch_text=АОЕ-УДАР
|
||||
mana_casting_too_fast=Как быстро выяснил __1__, в магии было гораздо больше, чем просто взмахнуть палочкой и произнести несколько забавных слов.
|
||||
low_level=Вам не хватает уровня для произнесения этого заклинания.
|
||||
not_inside_pos=Вы машете палочкой, но понимаете, что это вне досягаемости.
|
||||
@ -58,6 +59,8 @@ mana_max=Это ваша максимальная мана. Вы можете у
|
||||
mining_name=СКОРОСТЬ\nДОБЫЧИ
|
||||
slot_name=БОНУС\nЯЧЕЕК
|
||||
melee_name=УРОН\nРУКАМИ
|
||||
aoe_punch_chance=Жизни за удар: __1__\nШанс AOE-удара: __2__ % \n+__3__ [img=recipe.defender-capsule]
|
||||
aoe_punch_disabled=АОЕ-удар отключен.
|
||||
bonus_tooltip=Бонус дальности досягаемости: __1__\nБонус дистанции строительства: __2__\nБонус дальности выпадения предметов: __3__\nБонус дальности подбора добычи: __4__\nБонус дальности подбора предметов: __5__\nБонус дальности досягаемости ресурсов: __6__\nСкорость ремонта: __7__
|
||||
reach_distance=РАДИУС\nДЕЙСТВИЙ
|
||||
crafting_speed=СКОРОСТЬ\nКРАФТА
|
||||
@ -82,6 +85,9 @@ no_mana=Недостаточно маны!
|
||||
mana_label=Настройки маны:
|
||||
tooltip_check=Отмечено: правда\nНе отмечено: ложь
|
||||
info_text_label=Общие настройки RPG. Это основа для каждого игрока.
|
||||
spellbook_label=Книга заклинаний - объясняет требования для каждого заклинания.
|
||||
entity_spells_label=Обычные заклинания
|
||||
special_spells_label=Особые заклинания
|
||||
health_text_label=Показывать полоски здоровья/маны?
|
||||
health_only_text_label=Показывать полоску здоровья?
|
||||
reset_text_label=Сбросить очки умений?
|
||||
@ -92,6 +98,9 @@ movement_text_label=Включить бонус скорости передви
|
||||
movement_text_tooltip=Хотите бегать, как Флэш?\nВы можете переключить это здесь.
|
||||
stone_path_label=Включить каменную тропу при добыче?
|
||||
stone_path_tooltip=Включение этого автоматически создаст тропу из камня при добыче.
|
||||
aoe_punch_label=Включить АОЕ-удар?
|
||||
aoe_punch_tooltip=Включение этого параметра даст шанс создать AOE-удар по кусакам.\nAOE-удар работает только в том случае, если и боеприпасы, и оружие не экипированы.
|
||||
aoe_punch_globally=Включено глобально.\nAOE-удар работает только в том случае, если и боеприпасы, и оружие не экипированы.
|
||||
flameboots_label=Включить огненные сапоги?
|
||||
flameboots_tooltip=Когда пуль просто недостаточно.
|
||||
explosive_bullets_label=Включить разрывные пули?
|
||||
@ -101,10 +110,7 @@ toggle_cast_spell_label=Включает возможность произнос
|
||||
cast_spell_enabled_label=Произнесение заклинаний с помощью рыбы включено!
|
||||
cast_spell_disabled_label=Произнесение заклинаний с помощью рыбы отключено!
|
||||
magic_tooltip=Когда простого конструирования предметов недостаточно.\nПРИМЕЧАНИЕ! Используйте сырую рыбу, чтобы читать заклинания.
|
||||
magic_spell=Выберите сущность для создания
|
||||
magic_item_requirement=__1__ [item=__2__] требует __3__ маны для создания. Уровень: __4__\n
|
||||
magic_entity_requirement=__1__ [entity=__2__] требует __3__ маны для создания. Уровень: __4__\n
|
||||
magic_special_requirement=__1__ __2__ требует __3__ маны для создания. Уровень: __4__\n
|
||||
magic_spell=Выберите заклинание:
|
||||
allocation_settings_label=Настройки распределения:
|
||||
allocation_label=Выберите умение для авто-распределения.
|
||||
allocation_tooltip=Это автоматически распределит все доступные очки данному умению.
|
||||
@ -120,6 +126,8 @@ distractor=Капсула с дронами-приманками
|
||||
warp=Врата телепорта
|
||||
pointy_explosives=Взорвать сундук
|
||||
repair_aoe=Починить вокруг
|
||||
charge=Заряд
|
||||
eternal_blades=Вечные клинки
|
||||
|
||||
[allocations]
|
||||
deactivated=Отключено
|
||||
|
@ -77,7 +77,7 @@ new_items_at_market=火车市场已经解锁了新物品!
|
||||
[main_market]
|
||||
chest=提高了可以在外面放置的箱子数量.\n可以多次购买.
|
||||
locomotive_max_health=升级火车生命.\n可以多次购买
|
||||
locomotive_xp_aura=升级火车周围的经验光环。
|
||||
locomotive_aura_radius=升级火车周围的经验光环。
|
||||
xp_points_boost=升级您在经验光环中获得的经验值
|
||||
explosive_bullets=将普通的SMG弹药升级为爆炸子弹.
|
||||
reroll_market_items=重置市场的商品并调整价格.
|
||||
|
@ -947,7 +947,7 @@ local function market_kill_visuals()
|
||||
|
||||
local m = 32
|
||||
local m2 = m * 0.005
|
||||
for i = 1, 1024, 1 do
|
||||
for _ = 1, 1024, 1 do
|
||||
surface.create_particle(
|
||||
{
|
||||
name = 'branch-particle',
|
||||
@ -1015,7 +1015,7 @@ local function on_entity_died(event)
|
||||
surface.create_entity {name = 'big-biter', position = p}
|
||||
end
|
||||
end
|
||||
for i = 1, random(1, 2), 1 do
|
||||
for _ = 1, random(1, 2), 1 do
|
||||
local p = surface.find_non_colliding_position('medium-biter', event.entity.position, 3, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'medium-biter', position = p}
|
||||
@ -1035,9 +1035,8 @@ local function on_entity_died(event)
|
||||
Public.set('market_age', game.tick - last_reset)
|
||||
Public.set('game_has_ended', true)
|
||||
is_game_lost()
|
||||
local name = Server.get_server_name()
|
||||
local date = Server.get_start_time()
|
||||
game.server_save('Final_' .. name .. '_' .. tostring(date))
|
||||
game.server_save('Final_Fish_Defender_v2_' .. tostring(date))
|
||||
return
|
||||
end
|
||||
|
||||
@ -1050,7 +1049,7 @@ local function on_entity_died(event)
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local player = game.players[event.player_index]
|
||||
local player = game.get_player(event.player_index)
|
||||
local active_surface_index = Public.get('active_surface_index')
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
if not surface or not surface.valid then
|
||||
@ -1089,7 +1088,7 @@ local function deny_building(event)
|
||||
if entity.position.x >= 254 then
|
||||
if entity.name ~= 'entity-ghost' then
|
||||
if event.player_index then
|
||||
game.players[event.player_index].insert({name = entity.name, count = 1})
|
||||
game.get_player(event.player_index).insert({name = entity.name, count = 1})
|
||||
else
|
||||
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
||||
inventory.insert({name = entity.name, count = 1})
|
||||
@ -1249,7 +1248,7 @@ local function on_player_respawned(event)
|
||||
if not market_age then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
local player = game.get_player(event.player_index)
|
||||
player.character.destructible = false
|
||||
end
|
||||
|
||||
|
@ -51,7 +51,7 @@ local function enemy_weapon_damage()
|
||||
}
|
||||
|
||||
for k, v in pairs(data) do
|
||||
local new = Difficulty.get().difficulty_vote_value * v
|
||||
local new = Difficulty.get().value * v
|
||||
|
||||
local e_old = e.get_ammo_damage_modifier(k)
|
||||
|
||||
|
@ -131,22 +131,25 @@ local compare_player_pos = function(player)
|
||||
end
|
||||
|
||||
local zone = floor((abs(p.y / zone_settings.zone_depth)) % adjusted_zones.size) + 1
|
||||
local rpg_t = RPG.get_value_from_player(index)
|
||||
|
||||
if adjusted_zones.scrap[zone] then
|
||||
RPG.set_value_to_player(index, 'scrap_zone', true)
|
||||
if rpg_t and not rpg_t.scrap_zone then
|
||||
rpg_t.scrap_zone = true
|
||||
end
|
||||
else
|
||||
local has_scrap = RPG.get_value_from_player(index, 'scrap_zone')
|
||||
if has_scrap then
|
||||
RPG.set_value_to_player(index, 'scrap_zone', false)
|
||||
if rpg_t and rpg_t.scrap_zone then
|
||||
rpg_t.scrap_zone = false
|
||||
end
|
||||
end
|
||||
|
||||
if adjusted_zones.forest[zone] then
|
||||
RPG.set_value_to_player(index, 'forest_zone', true)
|
||||
if rpg_t and not rpg_t.forest_zone then
|
||||
rpg_t.forest_zone = true
|
||||
end
|
||||
else
|
||||
local is_in_forest = RPG.get_value_from_player(index, 'forest_zone')
|
||||
if is_in_forest then
|
||||
RPG.set_value_to_player(index, 'forest_zone', false)
|
||||
if rpg_t and rpg_t.forest_zone then
|
||||
rpg_t.forest_zone = false
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -290,7 +293,7 @@ end
|
||||
local function on_player_changed_position(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
local surface_name = player.surface.name
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if sub(surface_name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -304,6 +307,7 @@ local function on_player_changed_position(event)
|
||||
|
||||
distance(player)
|
||||
end
|
||||
|
||||
local function on_player_driving_changed_state(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not (player and player.valid) then
|
||||
|
@ -14,6 +14,7 @@ Global.register(
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
local round = math.round
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
@ -79,6 +80,7 @@ local function spawn_biters(data)
|
||||
end
|
||||
|
||||
local unit_to_create
|
||||
WD.wave_defense_set_unit_raffle(h * 0.20)
|
||||
|
||||
if random(1, 3) == 1 then
|
||||
unit_to_create = WD.wave_defense_roll_spitter_name()
|
||||
@ -86,10 +88,15 @@ local function spawn_biters(data)
|
||||
unit_to_create = WD.wave_defense_roll_biter_name()
|
||||
end
|
||||
|
||||
if not unit_to_create then
|
||||
print('buried_enemies - unit_to_create was nil?')
|
||||
return
|
||||
end
|
||||
|
||||
local modified_unit_health = WD.get('modified_unit_health')
|
||||
local modified_boss_unit_health = WD.get('modified_boss_unit_health')
|
||||
|
||||
WD.wave_defense_set_unit_raffle(h * 0.20)
|
||||
local unit_settings = WD.get('unit_settings')
|
||||
|
||||
local unit = surface.create_entity({name = unit_to_create, position = position})
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
@ -97,7 +104,11 @@ local function spawn_biters(data)
|
||||
if random(1, 30) == 1 then
|
||||
BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
|
||||
else
|
||||
BiterHealthBooster.add_unit(unit, modified_unit_health.current_value)
|
||||
local final_health = round(modified_unit_health.current_value * unit_settings.scale_units_by_health[unit.name], 3)
|
||||
if final_health < 1 then
|
||||
final_health = 1
|
||||
end
|
||||
BiterHealthBooster.add_unit(unit, final_health)
|
||||
end
|
||||
return true
|
||||
end
|
||||
@ -124,10 +135,17 @@ local function spawn_worms(data)
|
||||
local unit = surface.create_entity({name = unit_to_create, position = position})
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
|
||||
local worm_unit_settings = WD.get('worm_unit_settings')
|
||||
|
||||
if random(1, 30) == 1 then
|
||||
BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
|
||||
else
|
||||
BiterHealthBooster.add_unit(unit, modified_unit_health.current_value)
|
||||
local final_health = round(modified_unit_health.current_value * worm_unit_settings.scale_units_by_health[unit.name], 3)
|
||||
if final_health < 1 then
|
||||
final_health = 1
|
||||
end
|
||||
|
||||
BiterHealthBooster.add_unit(unit, final_health)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -156,6 +156,40 @@ commands.add_command(
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'toggle_orbital_strikes',
|
||||
'Usable only for admins - toggles orbital strikes!',
|
||||
function()
|
||||
local player = game.player
|
||||
|
||||
if not player and player.valid then
|
||||
return
|
||||
end
|
||||
if not player.admin then
|
||||
player.print("[ERROR] You're not admin!", Color.fail)
|
||||
return
|
||||
end
|
||||
|
||||
local this = WPT.get()
|
||||
|
||||
if not this.orbital_strikes_are_you_sure then
|
||||
this.orbital_strikes_are_you_sure = true
|
||||
player.print('[WARNING] This command will disable the orbital_strikes in-game, run this command again if you really want to do this!', Color.warning)
|
||||
return
|
||||
end
|
||||
|
||||
if this.orbital_strikes.enabled then
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the orbital_strikes module!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
this.orbital_strikes.enabled = false
|
||||
else
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the orbital_strikes module!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
this.orbital_strikes.enabled = true
|
||||
end
|
||||
|
||||
this.orbital_strikes_are_you_sure = nil
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'get_queue_speed',
|
||||
'Usable only for admins - gets the queue speed of this map!',
|
||||
|
@ -310,7 +310,7 @@ local function protect_entities(data)
|
||||
end
|
||||
|
||||
local function is_protected(e)
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(e.surface.name, 0, #map_name) ~= map_name then
|
||||
return true
|
||||
@ -728,7 +728,7 @@ local function on_player_mined_entity(event)
|
||||
end
|
||||
local rpg_char = RPG.get_value_from_player(player.index)
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -772,7 +772,7 @@ local function on_robot_mined_entity(event)
|
||||
return
|
||||
end
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -968,7 +968,7 @@ local function on_entity_died(event)
|
||||
|
||||
local cause = event.cause
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -1194,11 +1194,14 @@ local function show_mvps(player)
|
||||
local collapse_amount = Collapse.get_amount()
|
||||
|
||||
local diff = Diff.get()
|
||||
if not diff then
|
||||
return
|
||||
end
|
||||
local time_played = Core.format_time(game.ticks_played)
|
||||
local total_players = #game.players
|
||||
local pickaxe_tiers = WPT.pickaxe_upgrades
|
||||
local tier = WPT.get('pickaxe_tier')
|
||||
local pick_tier = pickaxe_tiers[tier]
|
||||
local pickaxe_upgrades = WPT.pickaxe_upgrades
|
||||
local upgrades = WPT.get('upgrades')
|
||||
local pick_tier = pickaxe_upgrades[upgrades.pickaxe_tier]
|
||||
|
||||
local server_name_matches = Server.check_server_name('Mtn Fortress')
|
||||
if WPT.get('prestige_system_enabled') then
|
||||
@ -1207,7 +1210,7 @@ local function show_mvps(player)
|
||||
local date = Server.get_start_time()
|
||||
game.server_save('Final_Mtn_Fortress_v3_' .. tostring(date))
|
||||
local text = {
|
||||
title = 'Game over <:helper:627426785918713877>',
|
||||
title = 'Game over!',
|
||||
description = 'Game statistics from the game is below',
|
||||
color = 'failure',
|
||||
field1 = {
|
||||
@ -1241,7 +1244,7 @@ local function show_mvps(player)
|
||||
},
|
||||
field6 = {
|
||||
text1 = 'Pickaxe Upgrade:',
|
||||
text2 = pick_tier .. ' (' .. tier .. ')',
|
||||
text2 = pick_tier .. ' (' .. upgrades.pickaxe_tier .. ')',
|
||||
inline = 'true',
|
||||
emptyField = 'true',
|
||||
emptyInline = 'true'
|
||||
@ -1389,7 +1392,7 @@ local function on_built_entity(event)
|
||||
return
|
||||
end
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -1486,7 +1489,7 @@ local function on_robot_built_entity(event)
|
||||
return
|
||||
end
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -1580,7 +1583,7 @@ end
|
||||
local on_player_or_robot_built_tile = function(event)
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
|
@ -1,8 +1,8 @@
|
||||
local Server = require 'utils.server'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Color = require 'utils.color_presets'
|
||||
local ICW = require 'maps.mountain_fortress_v3.icw.main'
|
||||
local ICT_Functions = require 'maps.mountain_fortress_v3.ic.functions'
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Alert = require 'utils.alert'
|
||||
@ -15,6 +15,7 @@ local ICW_Func = require 'maps.mountain_fortress_v3.icw.functions'
|
||||
local math2d = require 'math2d'
|
||||
local Misc = require 'utils.commands.misc'
|
||||
local Core = require 'utils.core'
|
||||
local Beams = require 'modules.render_beam'
|
||||
local zone_settings = WPT.zone_settings
|
||||
|
||||
local this = {
|
||||
@ -73,8 +74,8 @@ local Public = {}
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local round = math.round
|
||||
local remove = table.remove
|
||||
local sqrt = math.sqrt
|
||||
local remove = table.remove
|
||||
local magic_crafters_per_tick = 3
|
||||
local magic_fluid_crafters_per_tick = 8
|
||||
local tile_damage = 50
|
||||
@ -294,10 +295,58 @@ local artillery_target_callback =
|
||||
end
|
||||
)
|
||||
|
||||
local function difficulty_and_adjust_prices()
|
||||
local fixed_prices = WPT.get('marked_fixed_prices')
|
||||
local difficulty_index = Difficulty.get('index')
|
||||
|
||||
for index, price in pairs(fixed_prices) do
|
||||
if difficulty_index == 2 then
|
||||
fixed_prices[index] = price * 1.5
|
||||
elseif difficulty_index == 3 then
|
||||
fixed_prices[index] = price * 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_beams_away()
|
||||
local wave_number = WD.get_wave()
|
||||
local orbital_strikes = WPT.get('orbital_strikes')
|
||||
if not orbital_strikes.enabled then
|
||||
return
|
||||
end
|
||||
|
||||
if wave_number > 1000 then
|
||||
local difficulty_index = Difficulty.get('index')
|
||||
local wave_nth = 9999
|
||||
if difficulty_index == 1 then
|
||||
wave_nth = 1000
|
||||
elseif difficulty_index == 2 then
|
||||
wave_nth = 500
|
||||
elseif difficulty_index == 3 then
|
||||
wave_nth = 250
|
||||
end
|
||||
|
||||
if wave_number % wave_nth == 0 then
|
||||
local active_surface_index = WPT.get('active_surface_index')
|
||||
local surface = game.get_surface(active_surface_index)
|
||||
|
||||
if not orbital_strikes[wave_number] then
|
||||
orbital_strikes[wave_number] = true
|
||||
Beams.new_beam_delayed(surface, random(500, 3000))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_artillery_turrets_targets()
|
||||
local art_table = this.art_table
|
||||
local index = art_table.index
|
||||
|
||||
local difficulty_index = Difficulty.get('index')
|
||||
if difficulty_index == 3 then
|
||||
return
|
||||
end
|
||||
|
||||
if index > #art_table then
|
||||
art_table.index = 1
|
||||
return
|
||||
@ -376,6 +425,7 @@ local function tick()
|
||||
do_magic_crafters()
|
||||
do_magic_fluid_crafters()
|
||||
do_artillery_turrets_targets()
|
||||
do_beams_away()
|
||||
end
|
||||
|
||||
Public.deactivate_callback =
|
||||
@ -699,93 +749,6 @@ function Public.do_random_loot(entity, weights, loot)
|
||||
entity.insert {name = stack.name, count = count}
|
||||
end
|
||||
|
||||
function Public.remove_offline_players()
|
||||
local offline_players_enabled = WPT.get('offline_players_enabled')
|
||||
if not offline_players_enabled then
|
||||
return
|
||||
end
|
||||
local offline_players = WPT.get('offline_players')
|
||||
local offline_players_surface_removal = WPT.get('offline_players_surface_removal')
|
||||
local active_surface_index = WPT.get('active_surface_index')
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
local player_inv = {}
|
||||
local items = {}
|
||||
if #offline_players > 0 then
|
||||
for i = 1, #offline_players, 1 do
|
||||
if offline_players[i] and offline_players[i].index then
|
||||
local target = game.players[offline_players[i].index]
|
||||
if target and target.connected then
|
||||
offline_players[i] = nil
|
||||
else
|
||||
if target and offline_players[i].tick < game.tick - 108000 then
|
||||
local name = offline_players[i].name
|
||||
player_inv[1] = target.get_inventory(defines.inventory.character_main)
|
||||
player_inv[2] = target.get_inventory(defines.inventory.character_armor)
|
||||
player_inv[3] = target.get_inventory(defines.inventory.character_guns)
|
||||
player_inv[4] = target.get_inventory(defines.inventory.character_ammo)
|
||||
player_inv[5] = target.get_inventory(defines.inventory.character_trash)
|
||||
if offline_players_surface_removal then
|
||||
ICT_Functions.remove_surface(target) -- remove empty surface
|
||||
end
|
||||
|
||||
if target.get_item_count() == 0 then -- if the player has zero items, don't do anything
|
||||
offline_players[i] = nil
|
||||
goto final
|
||||
end
|
||||
|
||||
local pos = game.forces.player.get_spawn_position(surface)
|
||||
local e =
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'character',
|
||||
position = pos,
|
||||
force = 'neutral'
|
||||
}
|
||||
)
|
||||
local inv = e.get_inventory(defines.inventory.character_main)
|
||||
e.character_inventory_slots_bonus = #player_inv[1]
|
||||
for ii = 1, 5, 1 do
|
||||
if player_inv[ii].valid then
|
||||
for iii = 1, #player_inv[ii], 1 do
|
||||
if player_inv[ii][iii].valid then
|
||||
items[#items + 1] = player_inv[ii][iii]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #items > 0 then
|
||||
for item = 1, #items, 1 do
|
||||
if items[item].valid then
|
||||
inv.insert(items[item])
|
||||
end
|
||||
end
|
||||
|
||||
local message = ({'main.cleaner', name})
|
||||
local data = {
|
||||
position = pos
|
||||
}
|
||||
Alert.alert_all_players_location(data, message)
|
||||
|
||||
e.die('neutral')
|
||||
else
|
||||
e.destroy()
|
||||
end
|
||||
|
||||
for ii = 1, 5, 1 do
|
||||
if player_inv[ii].valid then
|
||||
player_inv[ii].clear()
|
||||
end
|
||||
end
|
||||
offline_players[i] = nil
|
||||
break
|
||||
end
|
||||
::final::
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function calc_players()
|
||||
local players = game.connected_players
|
||||
local check_afk_players = WPT.get('check_afk_players')
|
||||
@ -891,6 +854,9 @@ function Public.set_difficulty()
|
||||
return
|
||||
end
|
||||
local Diff = Difficulty.get()
|
||||
if not Diff then
|
||||
return
|
||||
end
|
||||
local wave_defense_table = WD.get_table()
|
||||
local check_if_threat_below_zero = WPT.get('check_if_threat_below_zero')
|
||||
local collapse_amount = WPT.get('collapse_amount')
|
||||
@ -902,16 +868,16 @@ function Public.set_difficulty()
|
||||
local wave_number = WD.get_wave()
|
||||
local player_count = calc_players()
|
||||
|
||||
if not Diff.difficulty_vote_value then
|
||||
Diff.difficulty_vote_value = 0.1
|
||||
if not Diff.value then
|
||||
Diff.value = 0.1
|
||||
end
|
||||
|
||||
if Diff.name == "I'm too young to die" then
|
||||
wave_defense_table.max_active_biters = 768 + player_count * (90 * Diff.difficulty_vote_value)
|
||||
elseif Diff.name == 'Hurt me plenty' then
|
||||
wave_defense_table.max_active_biters = 845 + player_count * (90 * Diff.difficulty_vote_value)
|
||||
elseif Diff.name == 'Ultra-violence' then
|
||||
wave_defense_table.max_active_biters = 1000 + player_count * (90 * Diff.difficulty_vote_value)
|
||||
if Diff.index == 1 then
|
||||
wave_defense_table.max_active_biters = 768 + player_count * (90 * Diff.value)
|
||||
elseif Diff.index == 2 then
|
||||
wave_defense_table.max_active_biters = 845 + player_count * (90 * Diff.value)
|
||||
elseif Diff.index == 3 then
|
||||
wave_defense_table.max_active_biters = 1000 + player_count * (90 * Diff.value)
|
||||
end
|
||||
|
||||
if wave_defense_table.max_active_biters >= 4000 then
|
||||
@ -919,12 +885,12 @@ function Public.set_difficulty()
|
||||
end
|
||||
|
||||
-- threat gain / wave
|
||||
if Diff.name == "I'm too young to die" then
|
||||
wave_defense_table.threat_gain_multiplier = 1.2 + player_count * Diff.difficulty_vote_value * 0.1
|
||||
elseif Diff.name == 'Hurt me plenty' then
|
||||
wave_defense_table.threat_gain_multiplier = 2 + player_count * Diff.difficulty_vote_value * 0.1
|
||||
elseif Diff.name == 'Ultra-violence' then
|
||||
wave_defense_table.threat_gain_multiplier = 4 + player_count * Diff.difficulty_vote_value * 0.1
|
||||
if Diff.index == 1 then
|
||||
wave_defense_table.threat_gain_multiplier = 1.2 + player_count * Diff.value * 0.1
|
||||
elseif Diff.index == 2 then
|
||||
wave_defense_table.threat_gain_multiplier = 2 + player_count * Diff.value * 0.1
|
||||
elseif Diff.index == 3 then
|
||||
wave_defense_table.threat_gain_multiplier = 4 + player_count * Diff.value * 0.1
|
||||
end
|
||||
|
||||
-- local amount = player_count * 0.40 + 2 -- too high?
|
||||
@ -942,7 +908,7 @@ function Public.set_difficulty()
|
||||
threat_check = wave_defense_table.threat <= 0
|
||||
end
|
||||
|
||||
if Diff.name == "I'm too young to die" then
|
||||
if Diff.index == 1 then
|
||||
if player_count < 10 then
|
||||
wave_defense_table.wave_interval = 4500
|
||||
else
|
||||
@ -951,7 +917,7 @@ function Public.set_difficulty()
|
||||
if wave_defense_table.wave_interval < 2200 or threat_check then
|
||||
wave_defense_table.wave_interval = 2200
|
||||
end
|
||||
elseif Diff.name == 'Hurt me plenty' then
|
||||
elseif Diff.index == 2 then
|
||||
if player_count < 10 then
|
||||
wave_defense_table.wave_interval = 3000
|
||||
else
|
||||
@ -960,7 +926,7 @@ function Public.set_difficulty()
|
||||
if wave_defense_table.wave_interval < 1900 or threat_check then
|
||||
wave_defense_table.wave_interval = 1900
|
||||
end
|
||||
elseif Diff.name == 'Ultra-violence' then
|
||||
elseif Diff.index == 3 then
|
||||
if player_count < 10 then
|
||||
wave_defense_table.wave_interval = 2000
|
||||
else
|
||||
@ -1123,17 +1089,16 @@ function Public.boost_difficulty()
|
||||
local breached_wall = WPT.get('breached_wall')
|
||||
|
||||
local difficulty = Difficulty.get()
|
||||
local name = difficulty.difficulties[difficulty.difficulty_vote_index].name
|
||||
|
||||
if game.tick < difficulty.difficulty_poll_closing_timeout and breached_wall <= 1 then
|
||||
if not difficulty then
|
||||
return
|
||||
end
|
||||
|
||||
Difficulty.get().name = name
|
||||
Difficulty.get().difficulty_poll_closing_timeout = game.tick
|
||||
local index = difficulty.index
|
||||
local name = difficulty.name
|
||||
|
||||
Difficulty.get().button_tooltip = difficulty.tooltip[difficulty.difficulty_vote_index]
|
||||
Difficulty.difficulty_gui()
|
||||
if game.tick < difficulty.closing_timeout and breached_wall <= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local message = ({'main.diff_set', name})
|
||||
local data = {
|
||||
@ -1143,22 +1108,126 @@ function Public.boost_difficulty()
|
||||
|
||||
local force = game.forces.player
|
||||
|
||||
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 0.5
|
||||
force.character_running_speed_modifier = 0.15
|
||||
force.manual_crafting_speed_modifier = 0.15
|
||||
WPT.set('coin_amount', 1)
|
||||
WPT.set('upgrades').flame_turret.limit = 12
|
||||
WPT.set('upgrades').landmine.limit = 50
|
||||
WPT.set('locomotive_health', 10000)
|
||||
WPT.set('locomotive_max_health', 10000)
|
||||
WPT.set('bonus_xp_on_join', 500)
|
||||
WD.set('next_wave', game.tick + 3600 * 15)
|
||||
WPT.set('spidertron_unlocked_at_zone', 10)
|
||||
WD.set_normal_unit_current_health(1.0)
|
||||
WD.set_unit_health_increment_per_wave(0.15)
|
||||
WD.set_boss_unit_current_health(2)
|
||||
WD.set_boss_health_increment_per_wave(1.5)
|
||||
WPT.set('difficulty_set', true)
|
||||
local active_surface_index = WPT.get('active_surface_index')
|
||||
local surface = game.get_surface(active_surface_index)
|
||||
|
||||
if index == 1 then
|
||||
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 0.5
|
||||
force.character_running_speed_modifier = 0.15
|
||||
force.manual_crafting_speed_modifier = 0.15
|
||||
WPT.set('coin_amount', 1)
|
||||
WPT.set('upgrades').flame_turret.limit = 12
|
||||
WPT.set('upgrades').landmine.limit = 50
|
||||
WPT.set('locomotive_health', 10000)
|
||||
WPT.set('locomotive_max_health', 10000)
|
||||
WPT.set('bonus_xp_on_join', 500)
|
||||
WD.set('next_wave', game.tick + 3600 * 15)
|
||||
WPT.set('spidertron_unlocked_at_zone', 10)
|
||||
WD.set_normal_unit_current_health(1.0)
|
||||
WD.set_unit_health_increment_per_wave(0.15)
|
||||
WD.set_boss_unit_current_health(2)
|
||||
WD.set_boss_health_increment_per_wave(1.5)
|
||||
WD.set('death_mode', false)
|
||||
WPT.set('difficulty_set', true)
|
||||
elseif index == 2 then
|
||||
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 0.25
|
||||
force.character_running_speed_modifier = 0.1
|
||||
force.manual_crafting_speed_modifier = 0.1
|
||||
WPT.set('coin_amount', 2)
|
||||
WPT.set('upgrades').flame_turret.limit = 10
|
||||
WPT.set('upgrades').landmine.limit = 50
|
||||
WPT.set('locomotive_health', 7000)
|
||||
WPT.set('locomotive_max_health', 7000)
|
||||
WPT.set('bonus_xp_on_join', 300)
|
||||
WD.set('next_wave', game.tick + 3600 * 8)
|
||||
WPT.set('spidertron_unlocked_at_zone', 8)
|
||||
WD.set_normal_unit_current_health(1.6)
|
||||
WD.set_unit_health_increment_per_wave(0.5)
|
||||
WD.set_boss_unit_current_health(3)
|
||||
WD.set_boss_health_increment_per_wave(5)
|
||||
WD.set('death_mode', false)
|
||||
WPT.set('difficulty_set', true)
|
||||
local damage_warning = ({'main.damage_mode_warning'})
|
||||
Alert.alert_all_players_location(data, damage_warning)
|
||||
Core.iter_players(
|
||||
function(player)
|
||||
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
else
|
||||
pos = game.forces.player.get_spawn_position(surface)
|
||||
player.teleport(pos, surface)
|
||||
end
|
||||
end
|
||||
)
|
||||
local upgrades = WPT.get('upgrades')
|
||||
if WPT.get('circle') then
|
||||
rendering.destroy(WPT.get('circle'))
|
||||
end
|
||||
local locomotive = WPT.get('locomotive')
|
||||
WPT.set(
|
||||
'circle',
|
||||
rendering.draw_circle {
|
||||
surface = active_surface_index,
|
||||
target = locomotive,
|
||||
color = locomotive.color,
|
||||
filled = false,
|
||||
radius = upgrades.locomotive_aura_radius,
|
||||
only_in_alt_mode = false
|
||||
}
|
||||
)
|
||||
difficulty_and_adjust_prices()
|
||||
elseif index == 3 then
|
||||
force.character_running_speed_modifier = 0
|
||||
force.manual_crafting_speed_modifier = 0
|
||||
WPT.set('coin_amount', 4)
|
||||
WPT.set('upgrades').flame_turret.limit = 3
|
||||
WPT.set('upgrades').landmine.limit = 10
|
||||
WPT.set('locomotive_health', 5000)
|
||||
WPT.set('locomotive_max_health', 5000)
|
||||
WPT.set('bonus_xp_on_join', 50)
|
||||
WD.set('next_wave', game.tick + 3600 * 5)
|
||||
WPT.set('spidertron_unlocked_at_zone', 6)
|
||||
WD.set_normal_unit_current_health(2)
|
||||
WD.set_unit_health_increment_per_wave(1)
|
||||
WD.set_boss_unit_current_health(4)
|
||||
WD.set_boss_health_increment_per_wave(10)
|
||||
WD.set('death_mode', true)
|
||||
WPT.set('difficulty_set', true)
|
||||
Core.iter_players(
|
||||
function(player)
|
||||
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
else
|
||||
pos = game.forces.player.get_spawn_position(surface)
|
||||
player.teleport(pos, surface)
|
||||
end
|
||||
end
|
||||
)
|
||||
local upgrades = WPT.get('upgrades')
|
||||
upgrades.locomotive_aura_radius = upgrades.locomotive_aura_radius + 20
|
||||
if WPT.get('circle') then
|
||||
rendering.destroy(WPT.get('circle'))
|
||||
end
|
||||
local locomotive = WPT.get('locomotive')
|
||||
WPT.set(
|
||||
'circle',
|
||||
rendering.draw_circle {
|
||||
surface = active_surface_index,
|
||||
target = locomotive,
|
||||
color = locomotive.color,
|
||||
filled = false,
|
||||
radius = upgrades.locomotive_aura_radius,
|
||||
only_in_alt_mode = false
|
||||
}
|
||||
)
|
||||
local aura_upgrade = ({'main.aura_upgrade_warning'})
|
||||
Alert.alert_all_players_location(data, aura_upgrade)
|
||||
local death_warning = ({'main.death_mode_warning'})
|
||||
Alert.alert_all_players_location(data, death_warning)
|
||||
difficulty_and_adjust_prices()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set_spawn_position()
|
||||
@ -1289,6 +1358,10 @@ function Public.on_player_joined_game(event)
|
||||
end
|
||||
local message = ({'main.greeting', player.name})
|
||||
Alert.alert_player(player, 15, message)
|
||||
if WPT.get('death_mode') then
|
||||
local death_message = ({'main.death_mode_warning'})
|
||||
Alert.alert_player(player, 15, death_message)
|
||||
end
|
||||
for item, amount in pairs(starting_items) do
|
||||
player.insert({name = item, count = amount})
|
||||
end
|
||||
@ -1345,24 +1418,6 @@ function Public.disable_creative()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.on_pre_player_left_game(event)
|
||||
local offline_players_enabled = WPT.get('offline_players_enabled')
|
||||
if not offline_players_enabled then
|
||||
return
|
||||
end
|
||||
|
||||
local offline_players = WPT.get('offline_players')
|
||||
local player = game.players[event.player_index]
|
||||
local ticker = game.tick
|
||||
if player.character then
|
||||
offline_players[#offline_players + 1] = {
|
||||
index = event.player_index,
|
||||
name = player.name,
|
||||
tick = ticker
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function Public.on_player_respawned(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
@ -1381,7 +1436,7 @@ function Public.on_player_changed_position(event)
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(player.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -1468,6 +1523,15 @@ function Public.on_research_finished(event)
|
||||
local bonus_drill = game.forces.bonus_drill
|
||||
local player = game.forces.player
|
||||
|
||||
local research_name = research.name
|
||||
local force = research.force
|
||||
|
||||
local technology_prototypes = game.technology_prototypes
|
||||
|
||||
if WPT.get('print_tech_to_discord') and force.name == 'player' then
|
||||
Server.to_discord_bold({'functions.researched_complete', technology_prototypes[research_name].localised_name}, true)
|
||||
end
|
||||
|
||||
research.force.character_inventory_slots_bonus = player.mining_drill_productivity_bonus * 50 -- +5 Slots /
|
||||
bonus_drill.mining_drill_productivity_bonus = bonus_drill.mining_drill_productivity_bonus + 0.03
|
||||
if bonus_drill.mining_drill_productivity_bonus >= 3 then
|
||||
@ -1515,14 +1579,12 @@ local on_player_joined_game = Public.on_player_joined_game
|
||||
local on_player_left_game = Public.on_player_left_game
|
||||
local on_research_finished = Public.on_research_finished
|
||||
local on_player_changed_position = Public.on_player_changed_position
|
||||
local on_pre_player_left_game = Public.on_pre_player_left_game
|
||||
local on_player_respawned = Public.on_player_respawned
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_left_game, on_player_left_game)
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
||||
Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.on_nth_tick(10, tick)
|
||||
|
||||
|
@ -410,8 +410,6 @@ function Public.update_gui(player)
|
||||
local mined_scrap = WPT.get('mined_scrap')
|
||||
local biters_killed = WPT.get('biters_killed')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
local train_upgrades = WPT.get('train_upgrades')
|
||||
local chest_limit_outside_upgrades = WPT.get('chest_limit_outside_upgrades')
|
||||
|
||||
if rpg_extra.global_pool == 0 then
|
||||
gui.global_pool.caption = 'XP: 0'
|
||||
@ -424,12 +422,11 @@ function Public.update_gui(player)
|
||||
gui.scrap_mined.caption = ' [img=entity.tree-01][img=entity.rock-huge]: ' .. format_number(mined_scrap, true)
|
||||
gui.scrap_mined.tooltip = ({'gui.amount_harvested'})
|
||||
|
||||
local pickaxe_tiers = WPT.pickaxe_upgrades
|
||||
local tier = WPT.get('pickaxe_tier')
|
||||
local pick_tier = pickaxe_tiers[tier]
|
||||
local pickaxe_upgrades = WPT.pickaxe_upgrades
|
||||
local pick_tier = pickaxe_upgrades[upgrades.pickaxe_tier]
|
||||
local speed = math.round((player.force.manual_mining_speed_modifier + player.character_mining_speed_modifier + 1) * 100)
|
||||
|
||||
gui.pickaxe_tier.caption = ' [img=item.dummy-steel-axe]: ' .. pick_tier .. ' (' .. tier .. ')'
|
||||
gui.pickaxe_tier.caption = ' [img=item.dummy-steel-axe]: ' .. pick_tier .. ' (' .. upgrades.pickaxe_tier .. ')'
|
||||
gui.pickaxe_tier.tooltip = ({'gui.current_pickaxe_tier', pick_tier, speed})
|
||||
|
||||
gui.biters_killed.caption = ' [img=entity.small-biter]: ' .. format_number(biters_killed, true)
|
||||
@ -441,10 +438,10 @@ function Public.update_gui(player)
|
||||
gui.flame_turret.caption = ' [img=entity.flamethrower-turret]: ' .. format_number(upgrades.flame_turret.built, true) .. ' / ' .. format_number(upgrades.flame_turret.limit, true)
|
||||
gui.flame_turret.tooltip = ({'gui.flamethrowers_placed'})
|
||||
|
||||
gui.train_upgrades.caption = ' [img=entity.locomotive]: ' .. format_number(train_upgrades, true)
|
||||
gui.train_upgrades.caption = ' [img=entity.locomotive]: ' .. format_number(upgrades.train_upgrades, true)
|
||||
gui.train_upgrades.tooltip = ({'gui.train_upgrades'})
|
||||
|
||||
gui.chest_upgrades.caption = ' [img=entity.steel-chest]: ' .. format_number(chest_limit_outside_upgrades, true)
|
||||
gui.chest_upgrades.caption = ' [img=entity.steel-chest]: ' .. format_number(upgrades.chests_outside_upgrades, true)
|
||||
gui.chest_upgrades.tooltip = ({'gui.chest_placed'})
|
||||
end
|
||||
|
||||
|
@ -5,6 +5,8 @@ local Token = require 'utils.token'
|
||||
local IC = require 'maps.mountain_fortress_v3.ic.table'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
local OfflinePlayers = require 'modules.clear_vacant_players'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local Public = {}
|
||||
local main_tile_name = 'black-refined-concrete'
|
||||
@ -211,7 +213,7 @@ local function get_saved_entity(entity, index)
|
||||
end
|
||||
|
||||
local function replace_entity(cars, entity, index)
|
||||
local has_upgraded_health_pool = WPT.get('has_upgraded_health_pool')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
local unit_number = entity.unit_number
|
||||
local health = floor(2000 * entity.health * 0.002)
|
||||
for k, car in pairs(cars) do
|
||||
@ -222,7 +224,7 @@ local function replace_entity(cars, entity, index)
|
||||
cars[unit_number].saved_entity = nil
|
||||
cars[unit_number].transfer_entities = car.transfer_entities
|
||||
cars[unit_number].health_pool = {
|
||||
enabled = has_upgraded_health_pool or false,
|
||||
enabled = upgrades.has_upgraded_health_pool or false,
|
||||
health = health,
|
||||
max = health
|
||||
}
|
||||
@ -376,10 +378,7 @@ local function kick_players_from_surface(car)
|
||||
if validate_entity(main_surface) then
|
||||
for _, e in pairs(surface.find_entities_filtered({area = car.area})) do
|
||||
if validate_entity(e) and e.name == 'character' and e.player then
|
||||
e.player.teleport(
|
||||
main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0, 5),
|
||||
main_surface
|
||||
)
|
||||
e.player.teleport(main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0, 5), main_surface)
|
||||
end
|
||||
end
|
||||
check_if_players_are_in_nauvis()
|
||||
@ -424,10 +423,7 @@ local function kick_player_from_surface(player, target)
|
||||
if p then
|
||||
target.teleport(p, car.entity.surface)
|
||||
else
|
||||
target.teleport(
|
||||
main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0, 5),
|
||||
main_surface
|
||||
)
|
||||
target.teleport(main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0, 5), main_surface)
|
||||
end
|
||||
target.print('You were kicked out of ' .. player.name .. ' vehicle.', Color.warning)
|
||||
end
|
||||
@ -649,9 +645,7 @@ local find_remove_car =
|
||||
return
|
||||
end
|
||||
|
||||
for _, dropped_ent in pairs(
|
||||
surface.find_entities_filtered {type = 'item-entity', area = {{position.x - 10, position.y - 10}, {position.x + 10, position.y + 10}}}
|
||||
) do
|
||||
for _, dropped_ent in pairs(surface.find_entities_filtered {type = 'item-entity', area = {{position.x - 10, position.y - 10}, {position.x + 10, position.y + 10}}}) do
|
||||
if dropped_ent and dropped_ent.valid and dropped_ent.stack then
|
||||
if types[dropped_ent.stack.name] then
|
||||
dropped_ent.destroy()
|
||||
@ -1104,7 +1098,7 @@ function Public.create_car(event)
|
||||
end
|
||||
|
||||
local renders = IC.get('renders')
|
||||
local has_upgraded_health_pool = WPT.get('has_upgraded_health_pool')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
|
||||
local name, mined = get_player_entity(player)
|
||||
|
||||
@ -1118,10 +1112,7 @@ function Public.create_car(event)
|
||||
|
||||
local storage = get_trusted_system(player)
|
||||
|
||||
if
|
||||
get_owner_car_name(player) == 'car' and ce.name == 'tank' or get_owner_car_name(player) == 'car' and ce.name == 'spidertron' or
|
||||
get_owner_car_name(player) == 'tank' and ce.name == 'spidertron'
|
||||
then
|
||||
if get_owner_car_name(player) == 'car' and ce.name == 'tank' or get_owner_car_name(player) == 'car' and ce.name == 'spidertron' or get_owner_car_name(player) == 'tank' and ce.name == 'spidertron' then
|
||||
if storage.auto_upgrade and storage.auto_upgrade == 'right' then
|
||||
return
|
||||
end
|
||||
@ -1157,7 +1148,7 @@ function Public.create_car(event)
|
||||
},
|
||||
doors = {},
|
||||
health_pool = {
|
||||
enabled = has_upgraded_health_pool or false,
|
||||
enabled = upgrades.has_upgraded_health_pool or false,
|
||||
health = health,
|
||||
max = health
|
||||
},
|
||||
@ -1361,7 +1352,7 @@ function Public.check_entity_healths()
|
||||
['spidertron'] = 3000
|
||||
}
|
||||
|
||||
for k, car in pairs(cars) do
|
||||
for _, car in pairs(cars) do
|
||||
local m = car.health_pool.health / car.health_pool.max
|
||||
|
||||
if car.health_pool.health > car.health_pool.max then
|
||||
@ -1434,4 +1425,16 @@ Public.get_entity_from_player_surface = get_entity_from_player_surface
|
||||
Public.get_owner_car_object = get_owner_car_object
|
||||
Public.render_owner_text = render_owner_text
|
||||
|
||||
Event.add(
|
||||
OfflinePlayers.events.remove_surface,
|
||||
function(event)
|
||||
local target = event.target
|
||||
if not target then
|
||||
return
|
||||
end
|
||||
|
||||
Public.remove_surface(target)
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
||||
|
@ -102,8 +102,8 @@ local function on_tick()
|
||||
|
||||
if tick % 20 == 1 then
|
||||
Functions.item_transfer()
|
||||
local has_upgraded_health_pool = WPT.get('has_upgraded_health_pool')
|
||||
if has_upgraded_health_pool then
|
||||
local upgrades = WPT.get('upgrades')
|
||||
if upgrades.has_upgraded_health_pool then
|
||||
Functions.check_entity_healths()
|
||||
end
|
||||
end
|
||||
@ -214,8 +214,8 @@ local function on_gui_switch_state_changed(event)
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local has_upgraded_health_pool = WPT.get('has_upgraded_health_pool')
|
||||
if not has_upgraded_health_pool then
|
||||
local upgrades = WPT.get('upgrades')
|
||||
if not upgrades.has_upgraded_health_pool then
|
||||
return
|
||||
end
|
||||
|
||||
@ -252,8 +252,8 @@ local function on_entity_damaged(event)
|
||||
end
|
||||
|
||||
local function on_player_repaired_entity(event)
|
||||
local has_upgraded_health_pool = WPT.get('has_upgraded_health_pool')
|
||||
if not has_upgraded_health_pool then
|
||||
local upgrades = WPT.get('upgrades')
|
||||
if not upgrades.has_upgraded_health_pool then
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -71,10 +71,7 @@ local function kick_players_from_surface(wagon)
|
||||
if validate_entity(main_surface) then
|
||||
for _, e in pairs(wagon.surface.find_entities_filtered({area = wagon.area})) do
|
||||
if validate_entity(e) and e.name == 'character' and e.player then
|
||||
e.player.teleport(
|
||||
main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0, 5),
|
||||
main_surface
|
||||
)
|
||||
e.player.teleport(main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0, 5), main_surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -960,10 +957,7 @@ local function move_room_to_train(icw, train, wagon)
|
||||
|
||||
train.top_y = destination_area.right_bottom.y
|
||||
|
||||
if
|
||||
destination_area.left_top.x == wagon.area.left_top.x and destination_area.left_top.y == wagon.area.left_top.y and
|
||||
wagon.surface.name == train.surface.name
|
||||
then
|
||||
if destination_area.left_top.x == wagon.area.left_top.x and destination_area.left_top.y == wagon.area.left_top.y and wagon.surface.name == train.surface.name then
|
||||
return
|
||||
end
|
||||
kick_players_from_surface(wagon)
|
||||
@ -1049,9 +1043,7 @@ local function get_connected_rolling_stock(entity, direction, carriages)
|
||||
return nil
|
||||
end
|
||||
|
||||
angle =
|
||||
math.atan2(-(connected_stock.position.x - entity.position.x), connected_stock.position.y - entity.position.y) / (2 * math.pi) -
|
||||
connected_stock.orientation
|
||||
angle = math.atan2(-(connected_stock.position.x - entity.position.x), connected_stock.position.y - entity.position.y) / (2 * math.pi) - connected_stock.orientation
|
||||
while angle < -0.5 do
|
||||
angle = angle + 1
|
||||
end
|
||||
@ -1165,9 +1157,7 @@ function Public.draw_minimap(icw, player, surface, position)
|
||||
end
|
||||
local element = frame['icw_sub_frame']
|
||||
if not frame.icw_auto_switch then
|
||||
frame.add(
|
||||
{type = 'switch', name = 'icw_auto_switch', allow_none_state = false, left_label_caption = {'gui.map_on'}, right_label_caption = {'gui.map_off'}}
|
||||
)
|
||||
frame.add({type = 'switch', name = 'icw_auto_switch', allow_none_state = false, left_label_caption = {'gui.map_on'}, right_label_caption = {'gui.map_off'}})
|
||||
end
|
||||
if not element then
|
||||
element =
|
||||
@ -1252,7 +1242,7 @@ end
|
||||
function Public.on_player_or_robot_built_tile(event)
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) == map_name then
|
||||
return
|
||||
|
@ -13,7 +13,7 @@ local function on_entity_died(event)
|
||||
end
|
||||
local wagon_types = ICW.get('wagon_types')
|
||||
|
||||
if not wagon_types[entity.type] then
|
||||
if entity and entity.valid and not wagon_types[entity.type] then
|
||||
return
|
||||
end
|
||||
local icw = ICW.get()
|
||||
|
@ -9,7 +9,6 @@ local Difficulty = require 'modules.difficulty_vote_by_amount'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
local Gui = require 'utils.gui'
|
||||
local Alert = require 'utils.alert'
|
||||
local Math2D = require 'math2d'
|
||||
local PermissionGroups = require 'maps.mountain_fortress_v3.locomotive.permission_groups'
|
||||
|
||||
local Public = {}
|
||||
@ -18,6 +17,7 @@ local rpg_main_frame = RPG.main_frame_name
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local round = math.round
|
||||
local sub = string.sub
|
||||
|
||||
local clear_items_upon_surface_entry = {
|
||||
['entity-ghost'] = true,
|
||||
@ -33,6 +33,11 @@ local valid_armors = {
|
||||
['power-armor-mk2'] = true
|
||||
}
|
||||
|
||||
local non_valid_vehicles = {
|
||||
['car'] = true,
|
||||
['spider-vehicle'] = true
|
||||
}
|
||||
|
||||
local function add_random_loot_to_main_market(rarity)
|
||||
local main_market_items = WPT.get('main_market_items')
|
||||
local items = Market.get_random_item(rarity, true, false)
|
||||
@ -72,25 +77,132 @@ local function add_random_loot_to_main_market(rarity)
|
||||
end
|
||||
end
|
||||
|
||||
local function validate_player(player)
|
||||
if not player then
|
||||
return false
|
||||
local function death_effects(player)
|
||||
local position = {x = player.position.x - 0.75, y = player.position.y - 1}
|
||||
local b = 0.75
|
||||
for _ = 1, 5, 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)
|
||||
}
|
||||
player.surface.create_entity({name = 'flying-text', position = p, text = '☠️', color = {255, math.random(0, 100), 0}})
|
||||
end
|
||||
if not player.valid then
|
||||
return false
|
||||
end
|
||||
if not player.character then
|
||||
return false
|
||||
end
|
||||
if not player.connected then
|
||||
return false
|
||||
end
|
||||
if not game.get_player(player.name) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
player.play_sound {path = 'utility/axe_fighting', volume_modifier = 0.9}
|
||||
end
|
||||
|
||||
local messages = {
|
||||
' likes to play in magma.',
|
||||
' got melted.',
|
||||
' tried to swim in lava.',
|
||||
' was incinerated.',
|
||||
" couldn't put the fire out.",
|
||||
' was turned into their molten form.'
|
||||
}
|
||||
|
||||
local function is_around_train(data)
|
||||
local entity = data.entity
|
||||
local locomotive_aura_radius = data.locomotive_aura_radius + 20
|
||||
local loco = data.locomotive.position
|
||||
local position = entity.position
|
||||
local inside = ((position.x - loco.x) ^ 2 + (position.y - loco.y) ^ 2) < locomotive_aura_radius ^ 2
|
||||
|
||||
if inside then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function hurt_players_outside_of_aura()
|
||||
local Diff = Difficulty.get()
|
||||
if not Diff then
|
||||
return
|
||||
end
|
||||
local difficulty_set = WPT.get('difficulty_set')
|
||||
if not difficulty_set then
|
||||
return
|
||||
end
|
||||
local death_mode = false
|
||||
if Diff.index == 1 then
|
||||
return
|
||||
elseif Diff.index == 3 then
|
||||
death_mode = true
|
||||
end
|
||||
|
||||
local loco_surface = WPT.get('loco_surface')
|
||||
if not (loco_surface and loco_surface.valid) then
|
||||
return
|
||||
end
|
||||
local locomotive = WPT.get('locomotive')
|
||||
local loco = locomotive.position
|
||||
|
||||
local upgrades = WPT.get('upgrades')
|
||||
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
if not player or not player.valid then
|
||||
goto pre_exit
|
||||
end
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if sub(player.surface.name, 0, #map_name) == map_name then
|
||||
local position = player.position
|
||||
local inside = ((position.x - loco.x) ^ 2 + (position.y - loco.y) ^ 2) < upgrades.locomotive_aura_radius ^ 2
|
||||
if not inside then
|
||||
local entity = player.character
|
||||
if entity and entity.valid then
|
||||
death_effects(player)
|
||||
player.surface.create_entity({name = 'fire-flame', position = position})
|
||||
if random(1, 3) == 1 then
|
||||
player.surface.create_entity({name = 'medium-scorchmark', position = position, force = 'neutral'})
|
||||
end
|
||||
local max_health = floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus)
|
||||
local vehicle = player.vehicle
|
||||
if vehicle and vehicle.valid and non_valid_vehicles[vehicle.type] then
|
||||
player.driving = false
|
||||
end
|
||||
if death_mode then
|
||||
if entity.name == 'character' then
|
||||
game.print(player.name .. messages[random(1, #messages)], {r = 200, g = 0, b = 0})
|
||||
end
|
||||
if entity.valid then
|
||||
entity.die()
|
||||
end
|
||||
else
|
||||
local armor_inventory = player.get_inventory(defines.inventory.character_armor)
|
||||
if not armor_inventory.valid then
|
||||
goto pre_exit
|
||||
end
|
||||
local armor = armor_inventory[1]
|
||||
if not armor.valid_for_read then
|
||||
goto pre_exit
|
||||
end
|
||||
local grid = armor.grid
|
||||
if not grid or not grid.valid then
|
||||
goto pre_exit
|
||||
end
|
||||
local equip = grid.equipment
|
||||
for _, piece in pairs(equip) do
|
||||
if piece.valid then
|
||||
piece.energy = 0
|
||||
end
|
||||
end
|
||||
local damage = (max_health / 18)
|
||||
if entity.valid then
|
||||
if entity.health - damage <= 0 then
|
||||
if entity.name == 'character' then
|
||||
game.print(player.name .. messages[random(1, #messages)], {r = 200, g = 0, b = 0})
|
||||
end
|
||||
end
|
||||
end
|
||||
entity.damage(damage, 'enemy')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
::pre_exit::
|
||||
end
|
||||
end
|
||||
local function give_passive_xp(data)
|
||||
local xp_floating_text_color = {r = 188, g = 201, b = 63}
|
||||
local visuals_delay = 1800
|
||||
@ -98,33 +210,30 @@ local function give_passive_xp(data)
|
||||
if not (loco_surface and loco_surface.valid) then
|
||||
return
|
||||
end
|
||||
local locomotive_xp_aura = WPT.get('locomotive_xp_aura')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
local locomotive = WPT.get('locomotive')
|
||||
local xp_points = WPT.get('xp_points')
|
||||
local aura = locomotive_xp_aura
|
||||
local rpg = data.rpg
|
||||
local loco = locomotive.position
|
||||
local area = {
|
||||
left_top = {x = loco.x - aura, y = loco.y - aura},
|
||||
right_bottom = {x = loco.x + aura, y = loco.y + aura}
|
||||
}
|
||||
|
||||
for _, player in pairs(game.connected_players) do
|
||||
if not validate_player(player) then
|
||||
return
|
||||
if not player or not player.valid then
|
||||
goto pre_exit
|
||||
end
|
||||
local position = player.position
|
||||
local inside = ((position.x - loco.x) ^ 2 + (position.y - loco.y) ^ 2) < upgrades.locomotive_aura_radius ^ 2
|
||||
if player.afk_time < 200 and not RPG.get_last_spell_cast(player) then
|
||||
if Math2D.bounding_box.contains_point(area, player.position) or player.surface.index == loco_surface.index then
|
||||
if inside or player.surface.index == loco_surface.index then
|
||||
if player.surface.index == loco_surface.index then
|
||||
PermissionGroups.add_player_to_permission_group(player, 'limited')
|
||||
elseif ICFunctions.get_player_surface(player) then
|
||||
return PermissionGroups.add_player_to_permission_group(player, 'limited')
|
||||
PermissionGroups.add_player_to_permission_group(player, 'limited')
|
||||
goto pre_exit
|
||||
else
|
||||
PermissionGroups.add_player_to_permission_group(player, 'near_locomotive')
|
||||
end
|
||||
|
||||
local pos = player.position
|
||||
RPG.gain_xp(player, 0.5 * (rpg[player.index].bonus + xp_points))
|
||||
RPG.gain_xp(player, 0.5 * (rpg[player.index].bonus + upgrades.xp_points))
|
||||
|
||||
player.create_local_flying_text {
|
||||
text = '+' .. '',
|
||||
@ -139,7 +248,7 @@ local function give_passive_xp(data)
|
||||
if player.gui.screen[rpg_main_frame] then
|
||||
local f = player.gui.screen[rpg_main_frame]
|
||||
local d = Gui.get_data(f)
|
||||
if d.exp_gui and d.exp_gui.valid then
|
||||
if d and d.exp_gui and d.exp_gui.valid then
|
||||
d.exp_gui.caption = floor(rpg[player.index].xp)
|
||||
end
|
||||
end
|
||||
@ -153,25 +262,10 @@ local function give_passive_xp(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
::pre_exit::
|
||||
end
|
||||
end
|
||||
|
||||
local function is_around_train(data)
|
||||
local entity = data.entity
|
||||
local aura = data.aura + 20
|
||||
local loco = data.locomotive.position
|
||||
local area = {
|
||||
left_top = {x = loco.x - aura, y = loco.y - aura},
|
||||
right_bottom = {x = loco.x + aura, y = loco.y + aura}
|
||||
}
|
||||
local pos = entity.position
|
||||
|
||||
if Math2D.bounding_box.contains_point(area, pos) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function fish_tag()
|
||||
local locomotive_cargo = WPT.get('locomotive_cargo')
|
||||
if not (locomotive_cargo and locomotive_cargo.valid) then
|
||||
@ -373,7 +467,7 @@ end
|
||||
|
||||
local function on_player_changed_surface(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not validate_player(player) then
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
@ -488,13 +582,13 @@ function Public.is_around_train(entity)
|
||||
end
|
||||
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
local aura = WPT.get('locomotive_xp_aura')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
|
||||
local data = {
|
||||
locomotive = locomotive,
|
||||
surface = surface,
|
||||
entity = entity,
|
||||
aura = aura
|
||||
locomotive_aura_radius = upgrades.locomotive_aura_radius
|
||||
}
|
||||
|
||||
local success = is_around_train(data)
|
||||
@ -508,43 +602,49 @@ function Public.render_train_hp()
|
||||
local locomotive_health = WPT.get('locomotive_health')
|
||||
local locomotive_max_health = WPT.get('locomotive_max_health')
|
||||
local locomotive = WPT.get('locomotive')
|
||||
local locomotive_xp_aura = WPT.get('locomotive_xp_aura')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
|
||||
WPT.set().health_text =
|
||||
WPT.set(
|
||||
'health_text',
|
||||
rendering.draw_text {
|
||||
text = 'HP: ' .. locomotive_health .. ' / ' .. locomotive_max_health,
|
||||
surface = surface,
|
||||
target = locomotive,
|
||||
target_offset = {0, -4.5},
|
||||
color = locomotive.color,
|
||||
scale = 1.40,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
text = 'HP: ' .. locomotive_health .. ' / ' .. locomotive_max_health,
|
||||
surface = surface,
|
||||
target = locomotive,
|
||||
target_offset = {0, -4.5},
|
||||
color = locomotive.color,
|
||||
scale = 1.40,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
)
|
||||
|
||||
WPT.set().caption =
|
||||
WPT.set(
|
||||
'caption',
|
||||
rendering.draw_text {
|
||||
text = 'Comfy Choo Choo',
|
||||
surface = surface,
|
||||
target = locomotive,
|
||||
target_offset = {0, -6.25},
|
||||
color = locomotive.color,
|
||||
scale = 1.80,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
text = 'Comfy Choo Choo',
|
||||
surface = surface,
|
||||
target = locomotive,
|
||||
target_offset = {0, -6.25},
|
||||
color = locomotive.color,
|
||||
scale = 1.80,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
)
|
||||
|
||||
WPT.set().circle =
|
||||
WPT.set(
|
||||
'circle',
|
||||
rendering.draw_circle {
|
||||
surface = surface,
|
||||
target = locomotive,
|
||||
color = locomotive.color,
|
||||
filled = false,
|
||||
radius = locomotive_xp_aura,
|
||||
only_in_alt_mode = true
|
||||
}
|
||||
surface = surface,
|
||||
target = locomotive,
|
||||
color = locomotive.color,
|
||||
filled = false,
|
||||
radius = upgrades.locomotive_aura_radius,
|
||||
only_in_alt_mode = true
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
function Public.transfer_pollution()
|
||||
@ -567,7 +667,7 @@ function Public.transfer_pollution()
|
||||
|
||||
local total_interior_pollution = surface.get_total_pollution()
|
||||
|
||||
local pollution = surface.get_total_pollution() * (3 / (4 / 3 + 1)) * Difficulty.get().difficulty_vote_value
|
||||
local pollution = surface.get_total_pollution() * (3 / (4 / 3 + 1)) * Difficulty.get().value
|
||||
active_surface.pollute(locomotive.position, pollution)
|
||||
game.pollution_statistics.on_flow('locomotive', pollution - total_interior_pollution)
|
||||
surface.clear_pollution()
|
||||
@ -583,10 +683,12 @@ local function tick()
|
||||
set_locomotive_health()
|
||||
validate_index()
|
||||
fish_tag()
|
||||
hurt_players_outside_of_aura()
|
||||
end
|
||||
|
||||
if ticker % 120 == 0 then
|
||||
-- tp_player()
|
||||
|
||||
boost_players()
|
||||
end
|
||||
|
||||
|
@ -16,7 +16,7 @@ local function contains_positions(area)
|
||||
for _, wagon in pairs(wagons) do
|
||||
if wagon.entity and wagon.entity.valid then
|
||||
if wagon.entity.name == 'cargo-wagon' then
|
||||
if inside(wagon.entity.position, area) then
|
||||
if inside(wagon.entity.position) then
|
||||
return true, wagon.entity
|
||||
end
|
||||
end
|
||||
@ -35,7 +35,7 @@ local function on_built_entity(event)
|
||||
return
|
||||
end
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -54,15 +54,15 @@ local function on_built_entity(event)
|
||||
|
||||
local outside_chests = WPT.get('outside_chests')
|
||||
local chests_linked_to = WPT.get('chests_linked_to')
|
||||
local chest_limit_outside_upgrades = WPT.get('chest_limit_outside_upgrades')
|
||||
local upgrades = WPT.get('upgrades')
|
||||
local chest_created
|
||||
local increased = false
|
||||
|
||||
for k, data in pairs(outside_chests) do
|
||||
for _, data in pairs(outside_chests) do
|
||||
if data and data.chest and data.chest.valid then
|
||||
if chests_linked_to[train.unit_number] then
|
||||
local linked_to = chests_linked_to[train.unit_number].count
|
||||
if linked_to == chest_limit_outside_upgrades then
|
||||
if linked_to == upgrades.chests_outside_upgrades then
|
||||
return
|
||||
end
|
||||
outside_chests[entity.unit_number] = {chest = entity, position = entity.position, linked = train.unit_number}
|
||||
@ -80,7 +80,8 @@ local function on_built_entity(event)
|
||||
end
|
||||
|
||||
::continue::
|
||||
rendering.draw_text {
|
||||
outside_chests[entity.unit_number].render =
|
||||
rendering.draw_text {
|
||||
text = '♠',
|
||||
surface = entity.surface,
|
||||
target = entity,
|
||||
@ -102,7 +103,8 @@ local function on_built_entity(event)
|
||||
chests_linked_to[train.unit_number] = {count = 1}
|
||||
chests_linked_to[train.unit_number][entity.unit_number] = true
|
||||
|
||||
rendering.draw_text {
|
||||
outside_chests[entity.unit_number].render =
|
||||
rendering.draw_text {
|
||||
text = '♠',
|
||||
surface = entity.surface,
|
||||
target = entity,
|
||||
@ -159,6 +161,9 @@ local function divide_contents()
|
||||
if not (chest and chest.valid) then
|
||||
if chests_linked_to[data.linked] then
|
||||
if chests_linked_to[data.linked][key] then
|
||||
if data.render and rendering.is_valid(data.render) then
|
||||
rendering.destroy(data.render)
|
||||
end
|
||||
chests_linked_to[data.linked][key] = nil
|
||||
chests_linked_to[data.linked].count = chests_linked_to[data.linked].count - 1
|
||||
if chests_linked_to[data.linked].count <= 0 then
|
||||
@ -175,12 +180,16 @@ local function divide_contents()
|
||||
target_chest = entity
|
||||
else
|
||||
if chests_linked_to[data.linked] then
|
||||
if chests_linked_to[data.linked][key] then
|
||||
if data then
|
||||
if data.render and rendering.is_valid(data.render) then
|
||||
rendering.destroy(data.render)
|
||||
end
|
||||
chests_linked_to[data.linked][key] = nil
|
||||
chests_linked_to[data.linked].count = chests_linked_to[data.linked].count - 1
|
||||
if chests_linked_to[data.linked].count <= 0 then
|
||||
chests_linked_to[data.linked] = nil
|
||||
end
|
||||
outside_chests[key] = nil
|
||||
end
|
||||
end
|
||||
goto continue
|
||||
|
@ -4,6 +4,7 @@ local ICW = require 'maps.mountain_fortress_v3.icw.main'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Session = require 'utils.datastore.session_data'
|
||||
local Difficulty = require 'modules.difficulty_vote_by_amount'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
local Gui = require 'utils.gui'
|
||||
local Server = require 'utils.server'
|
||||
@ -44,34 +45,28 @@ local function add_space(frame)
|
||||
end
|
||||
|
||||
local function get_items()
|
||||
local chest_limit_outside_upgrades = WPT.get('chest_limit_outside_upgrades')
|
||||
local health_upgrades = WPT.get('health_upgrades')
|
||||
local pickaxe_tier = WPT.get('pickaxe_tier')
|
||||
local aura_upgrades = WPT.get('aura_upgrades')
|
||||
local market_limits = WPT.get('market_limits')
|
||||
local main_market_items = WPT.get('main_market_items')
|
||||
local xp_points_upgrade = WPT.get('xp_points_upgrade')
|
||||
local flame_turret = WPT.get('upgrades').flame_turret.bought
|
||||
local landmine = WPT.get('upgrades').landmine.bought
|
||||
local upgrades = WPT.get('upgrades')
|
||||
local fixed_prices = WPT.get('marked_fixed_prices')
|
||||
local health_upgrades_limit = WPT.get('health_upgrades_limit')
|
||||
local has_upgraded_health_pool = WPT.get('has_upgraded_health_pool')
|
||||
|
||||
local chest_limit_cost = round(fixed_prices.chest_limit_cost * (1 + chest_limit_outside_upgrades))
|
||||
local health_cost = round(fixed_prices.health_cost * (1 + health_upgrades))
|
||||
local pickaxe_cost = round(fixed_prices.pickaxe_cost * (0.1 + pickaxe_tier / 2))
|
||||
local aura_cost = round(fixed_prices.aura_cost * (1 + aura_upgrades))
|
||||
local xp_point_boost_cost = round(fixed_prices.xp_point_boost_cost * (1 + xp_points_upgrade))
|
||||
local chests_outside_cost = round(fixed_prices.chests_outside_cost * (1 + upgrades.chests_outside_upgrades))
|
||||
local health_cost = round(fixed_prices.health_cost * (1 + upgrades.health_upgrades))
|
||||
local pickaxe_cost = round(fixed_prices.pickaxe_cost * (0.1 + upgrades.pickaxe_tier / 2))
|
||||
local aura_cost = round(fixed_prices.aura_cost * (1 + upgrades.aura_upgrades))
|
||||
local xp_point_boost_cost = round(fixed_prices.xp_point_boost_cost * (1 + upgrades.xp_points_upgrade))
|
||||
local explosive_bullets_cost = round(fixed_prices.explosive_bullets_cost)
|
||||
local redraw_mystical_chest_cost = round(fixed_prices.redraw_mystical_chest_cost)
|
||||
local flamethrower_turrets_cost = round(fixed_prices.flamethrower_turrets_cost * (1 + flame_turret))
|
||||
local land_mine_cost = round(fixed_prices.land_mine_cost * (1 + landmine))
|
||||
local land_mine_cost = round(fixed_prices.land_mine_cost * (1 + upgrades.landmine.bought))
|
||||
local car_health_upgrade_pool = fixed_prices.car_health_upgrade_pool_cost
|
||||
|
||||
local pickaxe_tiers = WPT.pickaxe_upgrades
|
||||
local tier = WPT.get('pickaxe_tier')
|
||||
local offer = pickaxe_tiers[tier]
|
||||
local pickaxe_upgrades = WPT.pickaxe_upgrades
|
||||
|
||||
if pickaxe_tier >= 59 then
|
||||
local offer = pickaxe_upgrades[upgrades.pickaxe_tier]
|
||||
|
||||
if upgrades.pickaxe_tier >= market_limits.pickaxe_tier_limit then
|
||||
main_market_items['upgrade_pickaxe'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
@ -87,7 +82,7 @@ local function get_items()
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = pickaxe_cost,
|
||||
tooltip = ({'main_market.purchase_pickaxe', offer, pickaxe_tier - 1}),
|
||||
tooltip = ({'main_market.purchase_pickaxe', offer, upgrades.pickaxe_tier, market_limits.pickaxe_tier_limit}),
|
||||
sprite = 'achievement/delivery-service',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
@ -95,11 +90,11 @@ local function get_items()
|
||||
}
|
||||
end
|
||||
|
||||
if chest_limit_outside_upgrades == 8 then
|
||||
if upgrades.chests_outside_upgrades == market_limits.chests_outside_limit then
|
||||
main_market_items['chest_limit_outside'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = chest_limit_cost,
|
||||
price = chests_outside_cost,
|
||||
tooltip = ({'locomotive.limit_reached'}),
|
||||
sprite = 'achievement/so-long-and-thanks-for-all-the-fish',
|
||||
enabled = false,
|
||||
@ -110,8 +105,8 @@ local function get_items()
|
||||
main_market_items['chest_limit_outside'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = chest_limit_cost,
|
||||
tooltip = ({'main_market.chest', chest_limit_outside_upgrades - 1}),
|
||||
price = chests_outside_cost,
|
||||
tooltip = ({'main_market.chest', upgrades.chests_outside_upgrades, market_limits.chests_outside_limit}),
|
||||
sprite = 'achievement/so-long-and-thanks-for-all-the-fish',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
@ -119,7 +114,7 @@ local function get_items()
|
||||
}
|
||||
end
|
||||
|
||||
if health_upgrades >= health_upgrades_limit then
|
||||
if upgrades.health_upgrades >= market_limits.health_upgrades_limit then
|
||||
main_market_items['locomotive_max_health'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
@ -135,7 +130,7 @@ local function get_items()
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = health_cost,
|
||||
tooltip = ({'main_market.locomotive_max_health', health_upgrades - 1}),
|
||||
tooltip = ({'main_market.locomotive_max_health', upgrades.health_upgrades, market_limits.health_upgrades_limit}),
|
||||
sprite = 'achievement/getting-on-track',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
@ -143,18 +138,31 @@ local function get_items()
|
||||
}
|
||||
end
|
||||
|
||||
main_market_items['locomotive_xp_aura'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = aura_cost,
|
||||
tooltip = ({'main_market.locomotive_xp_aura', aura_upgrades}),
|
||||
sprite = 'achievement/tech-maniac',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
static = true
|
||||
}
|
||||
if upgrades.locomotive_aura_radius == market_limits.aura_limit then
|
||||
main_market_items['locomotive_aura_radius'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = aura_cost,
|
||||
tooltip = ({'locomotive.limit_reached'}),
|
||||
sprite = 'achievement/tech-maniac',
|
||||
enabled = false,
|
||||
upgrade = true,
|
||||
static = true
|
||||
}
|
||||
else
|
||||
main_market_items['locomotive_aura_radius'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = aura_cost,
|
||||
tooltip = ({'main_market.locomotive_aura_radius', upgrades.locomotive_aura_radius, market_limits.aura_limit}),
|
||||
sprite = 'achievement/tech-maniac',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
static = true
|
||||
}
|
||||
end
|
||||
|
||||
if has_upgraded_health_pool then
|
||||
if upgrades.has_upgraded_health_pool then
|
||||
main_market_items['car_health_upgrade_pool'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
@ -181,7 +189,7 @@ local function get_items()
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = xp_point_boost_cost,
|
||||
tooltip = ({'main_market.xp_points_boost', xp_points_upgrade}),
|
||||
tooltip = ({'main_market.xp_points_boost', upgrades.xp_points_upgrade}),
|
||||
sprite = 'achievement/trans-factorio-express',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
@ -199,7 +207,7 @@ local function get_items()
|
||||
static = true
|
||||
}
|
||||
|
||||
if WPT.get('explosive_bullets') then
|
||||
if upgrades.explosive_bullets_purchased then
|
||||
main_market_items['explosive_bullets'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
@ -222,6 +230,7 @@ local function get_items()
|
||||
static = true
|
||||
}
|
||||
end
|
||||
|
||||
main_market_items['flamethrower_turrets'] = {
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
@ -236,7 +245,7 @@ local function get_items()
|
||||
stack = 1,
|
||||
value = 'coin',
|
||||
price = land_mine_cost,
|
||||
tooltip = ({'main_market.land_mine', landmine}),
|
||||
tooltip = ({'main_market.land_mine', upgrades.landmine.bought}),
|
||||
sprite = 'achievement/watch-your-step',
|
||||
enabled = true,
|
||||
upgrade = true,
|
||||
@ -802,6 +811,9 @@ local function gui_opened(event)
|
||||
end
|
||||
|
||||
local frame, inside_table = Gui.add_main_frame_with_toolbar(player, 'screen', main_frame_name, nil, close_market_gui_name, 'Market')
|
||||
if not inside_table then
|
||||
return
|
||||
end
|
||||
frame.auto_center = true
|
||||
|
||||
player.opened = frame
|
||||
@ -933,11 +945,10 @@ local function gui_click(event)
|
||||
if name == 'upgrade_pickaxe' then
|
||||
player.remove_item({name = item.value, count = item.price})
|
||||
|
||||
this.pickaxe_tier = this.pickaxe_tier + item.stack
|
||||
this.upgrades.pickaxe_tier = this.upgrades.pickaxe_tier + item.stack
|
||||
|
||||
local pickaxe_tiers = WPT.pickaxe_upgrades
|
||||
local tier = this.pickaxe_tier
|
||||
local offer = pickaxe_tiers[tier]
|
||||
local pickaxe_upgrades = WPT.pickaxe_upgrades
|
||||
local offer = pickaxe_upgrades[this.upgrades.pickaxe_tier]
|
||||
|
||||
local message = ({
|
||||
'locomotive.pickaxe_bought_info',
|
||||
@ -949,7 +960,7 @@ local function gui_click(event)
|
||||
Alert.alert_all_players(5, message)
|
||||
Server.to_discord_bold(
|
||||
table.concat {
|
||||
player.name .. ' has upgraded the teams pickaxe to tier ' .. tier .. ' for ' .. format_number(item.price, true) .. ' coins.'
|
||||
player.name .. ' has upgraded the teams pickaxe to tier ' .. this.upgrades.pickaxe_tier .. ' for ' .. format_number(item.price, true) .. ' coins.'
|
||||
}
|
||||
)
|
||||
|
||||
@ -963,9 +974,10 @@ local function gui_click(event)
|
||||
return
|
||||
end
|
||||
if name == 'chest_limit_outside' then
|
||||
if this.chest_limit_outside_upgrades == 7 then
|
||||
if this.upgrades.chests_outside_upgrades == this.market_limits.chests_outside_limit then
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
player.print(({'locomotive.chests_full'}), {r = 0.98, g = 0.66, b = 0.22})
|
||||
return
|
||||
end
|
||||
player.remove_item({name = item.value, count = item.price})
|
||||
|
||||
@ -976,7 +988,7 @@ local function gui_click(event)
|
||||
player.name .. ' has bought the chest limit upgrade for ' .. format_number(item.price, true) .. ' coins.'
|
||||
}
|
||||
)
|
||||
this.chest_limit_outside_upgrades = this.chest_limit_outside_upgrades + item.stack
|
||||
this.upgrades.chests_outside_upgrades = this.upgrades.chests_outside_upgrades + item.stack
|
||||
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
redraw_coins_left(data.coins_left, player)
|
||||
@ -1017,8 +1029,8 @@ local function gui_click(event)
|
||||
end
|
||||
end
|
||||
|
||||
this.train_upgrades = this.train_upgrades + item.stack
|
||||
this.health_upgrades = this.health_upgrades + item.stack
|
||||
this.upgrades.train_upgrades = this.upgrades.train_upgrades + item.stack
|
||||
this.upgrades.health_upgrades = this.upgrades.health_upgrades + item.stack
|
||||
rendering.set_text(this.health_text, 'HP: ' .. round(this.locomotive_health) .. ' / ' .. round(this.locomotive_max_health))
|
||||
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
@ -1026,7 +1038,12 @@ local function gui_click(event)
|
||||
|
||||
return
|
||||
end
|
||||
if name == 'locomotive_xp_aura' then
|
||||
if name == 'locomotive_aura_radius' then
|
||||
if this.upgrades.locomotive_aura_radius == this.market_limits.aura_limit then
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
player.print(({'locomotive.limit_reached'}), {r = 0.98, g = 0.66, b = 0.22})
|
||||
return
|
||||
end
|
||||
player.remove_item({name = item.value, count = item.price})
|
||||
|
||||
local message = ({'locomotive.aura_bought_info', shopkeeper, player.name, format_number(item.price, true)})
|
||||
@ -1037,21 +1054,28 @@ local function gui_click(event)
|
||||
player.name .. ' has bought the locomotive xp aura modifier for ' .. format_number(item.price, true) .. ' coins.'
|
||||
}
|
||||
)
|
||||
this.locomotive_xp_aura = this.locomotive_xp_aura + 5
|
||||
this.aura_upgrades = this.aura_upgrades + item.stack
|
||||
this.train_upgrades = this.train_upgrades + item.stack
|
||||
this.upgrades.locomotive_aura_radius = this.upgrades.locomotive_aura_radius + 5
|
||||
this.upgrades.aura_upgrades = this.upgrades.aura_upgrades + item.stack
|
||||
this.upgrades.train_upgrades = this.upgrades.train_upgrades + item.stack
|
||||
|
||||
if this.circle then
|
||||
rendering.destroy(this.circle)
|
||||
end
|
||||
local difficulty_index = Difficulty.get('index')
|
||||
|
||||
local fill_circle = false
|
||||
if difficulty_index == 2 or difficulty_index == 3 then
|
||||
fill_circle = true
|
||||
end
|
||||
|
||||
this.circle =
|
||||
rendering.draw_circle {
|
||||
surface = game.surfaces[this.active_surface_index],
|
||||
target = this.locomotive,
|
||||
color = this.locomotive.color,
|
||||
filled = false,
|
||||
radius = this.locomotive_xp_aura,
|
||||
only_in_alt_mode = true
|
||||
radius = this.upgrades.locomotive_aura_radius,
|
||||
only_in_alt_mode = fill_circle
|
||||
}
|
||||
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
@ -1070,9 +1094,9 @@ local function gui_click(event)
|
||||
player.name .. ' has bought the XP points modifier for ' .. format_number(item.price) .. ' coins.'
|
||||
}
|
||||
)
|
||||
this.xp_points = this.xp_points + 0.5
|
||||
this.xp_points_upgrade = this.xp_points_upgrade + item.stack
|
||||
this.train_upgrades = this.train_upgrades + item.stack
|
||||
this.upgrades.xp_points = this.upgrades.xp_points + 0.5
|
||||
this.upgrades.xp_points_upgrade = this.upgrades.xp_points_upgrade + item.stack
|
||||
this.upgrades.train_upgrades = this.upgrades.train_upgrades + item.stack
|
||||
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
redraw_coins_left(data.coins_left, player)
|
||||
@ -1115,7 +1139,7 @@ local function gui_click(event)
|
||||
}
|
||||
)
|
||||
RPG.enable_explosive_bullets(true)
|
||||
this.explosive_bullets = true
|
||||
this.upgrades.explosive_bullets_purchased = true
|
||||
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
redraw_coins_left(data.coins_left, player)
|
||||
@ -1138,8 +1162,7 @@ local function gui_click(event)
|
||||
player.name .. ' has bought the global car health modifier for ' .. format_number(item.price) .. ' coins.'
|
||||
}
|
||||
)
|
||||
this.has_upgraded_health_pool = true
|
||||
this.explosive_bullets = true
|
||||
this.upgrades.has_upgraded_health_pool = true
|
||||
|
||||
redraw_market_items(data.item_frame, player, data.search_text)
|
||||
redraw_coins_left(data.coins_left, player)
|
||||
|
@ -14,10 +14,15 @@ function Public.add_player_to_permission_group(player, group, forced)
|
||||
local session = Session.get_session_table()
|
||||
local AG = Antigrief.get()
|
||||
local allow_decon = WPT.get('allow_decon')
|
||||
local allow_decon_main_surface = WPT.get('allow_decon_main_surface')
|
||||
|
||||
local default_group = game.permissions.get_group('Default')
|
||||
default_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
default_group.set_allows_action(defines.input_action.activate_cut, false)
|
||||
if allow_decon_main_surface then
|
||||
default_group.set_allows_action(defines.input_action.deconstruct, true)
|
||||
else
|
||||
default_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
end
|
||||
|
||||
if not game.permissions.get_group('limited') then
|
||||
local limited_group = game.permissions.create_group('limited')
|
||||
@ -35,13 +40,21 @@ function Public.add_player_to_permission_group(player, group, forced)
|
||||
local near_locomotive_group = game.permissions.create_group('near_locomotive')
|
||||
near_locomotive_group.set_allows_action(defines.input_action.cancel_craft, false)
|
||||
near_locomotive_group.set_allows_action(defines.input_action.drop_item, false)
|
||||
near_locomotive_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
if allow_decon_main_surface then
|
||||
near_locomotive_group.set_allows_action(defines.input_action.deconstruct, true)
|
||||
else
|
||||
near_locomotive_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
end
|
||||
near_locomotive_group.set_allows_action(defines.input_action.activate_cut, false)
|
||||
end
|
||||
|
||||
if not game.permissions.get_group('main_surface') then
|
||||
local main_surface_group = game.permissions.create_group('main_surface')
|
||||
main_surface_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
if allow_decon_main_surface then
|
||||
main_surface_group.set_allows_action(defines.input_action.deconstruct, true)
|
||||
else
|
||||
main_surface_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
end
|
||||
main_surface_group.set_allows_action(defines.input_action.activate_cut, false)
|
||||
end
|
||||
|
||||
@ -54,6 +67,7 @@ function Public.add_player_to_permission_group(player, group, forced)
|
||||
not_trusted.set_allows_action(defines.input_action.add_permission_group, false)
|
||||
not_trusted.set_allows_action(defines.input_action.admin_action, false)
|
||||
not_trusted.set_allows_action(defines.input_action.drop_item, false)
|
||||
not_trusted.set_allows_action(defines.input_action.cancel_research, false)
|
||||
not_trusted.set_allows_action(defines.input_action.disconnect_rolling_stock, false)
|
||||
not_trusted.set_allows_action(defines.input_action.connect_rolling_stock, false)
|
||||
not_trusted.set_allows_action(defines.input_action.open_train_gui, false)
|
||||
|
@ -41,9 +41,9 @@ local AntiGrief = require 'utils.antigrief'
|
||||
local Misc = require 'utils.commands.misc'
|
||||
local Modifiers = require 'utils.player_modifiers'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local Reset = require 'functions.soft_reset'
|
||||
local JailData = require 'utils.datastore.jail_data'
|
||||
local RPG_Progression = require 'utils.datastore.rpg_data'
|
||||
local OfflinePlayers = require 'modules.clear_vacant_players'
|
||||
|
||||
require 'maps.mountain_fortress_v3.locomotive.market'
|
||||
require 'maps.mountain_fortress_v3.locomotive.linked_chests'
|
||||
@ -142,14 +142,11 @@ local announce_new_map =
|
||||
)
|
||||
|
||||
function Public.reset_map()
|
||||
local Diff = Difficulty.get()
|
||||
local this = WPT.get()
|
||||
local wave_defense_table = WD.get_table()
|
||||
Misc.set('creative_are_you_sure', false)
|
||||
Misc.set('creative_enabled', false)
|
||||
|
||||
Reset.enable_mapkeeper(true)
|
||||
|
||||
this.active_surface_index = CS.create_surface()
|
||||
-- this.soft_reset_counter = CS.get_reset_counter()
|
||||
|
||||
@ -167,6 +164,10 @@ function Public.reset_map()
|
||||
game.reset_time_played()
|
||||
WPT.reset_table()
|
||||
|
||||
OfflinePlayers.set_active_surface_index(this.active_surface_index)
|
||||
OfflinePlayers.set_offline_players_enabled(true)
|
||||
-- OfflinePlayers.set_offline_players_surface_removal(true)
|
||||
|
||||
RPG.rpg_reset_all_players()
|
||||
RPG.set_surface_name(game.surfaces[this.active_surface_index].name)
|
||||
RPG.enable_health_and_mana_bars(true)
|
||||
@ -225,6 +226,8 @@ function Public.reset_map()
|
||||
AntiGrief.enable_jail(true)
|
||||
AntiGrief.damage_entity_threshold(20)
|
||||
AntiGrief.explosive_threshold(32)
|
||||
AntiGrief.decon_surface_blacklist(surface.name)
|
||||
AntiGrief.filtered_types_on_decon({'tree', 'simple-entity', 'fish'})
|
||||
|
||||
PL.show_roles_in_list(true)
|
||||
PL.rpg_enabled(true)
|
||||
@ -244,8 +247,8 @@ function Public.reset_map()
|
||||
raise_event(Gui_mf.events.reset_map, {player_index = player.index})
|
||||
end
|
||||
|
||||
Difficulty.reset_difficulty_poll({difficulty_poll_closing_timeout = game.tick + 36000})
|
||||
Diff.gui_width = 20
|
||||
Difficulty.reset_difficulty_poll({closing_timeout = game.tick + 36000})
|
||||
Difficulty.set_gui_width(20)
|
||||
|
||||
Collapse.set_kill_entities(false)
|
||||
Collapse.set_kill_specific_entities(collapse_kill)
|
||||
@ -489,7 +492,6 @@ local on_tick = function()
|
||||
|
||||
if tick % 1000 == 0 then
|
||||
collapse_after_wave_200()
|
||||
Functions.remove_offline_players()
|
||||
Functions.set_difficulty()
|
||||
Functions.is_creativity_mode_on()
|
||||
end
|
||||
|
@ -1,8 +1,11 @@
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local RPG = require 'modules.rpg.main'
|
||||
local Event = require 'utils.event'
|
||||
local Ai = require 'modules.ai'
|
||||
require 'modules.check_fullness'
|
||||
|
||||
local Public = {}
|
||||
local Public = {events = {on_entity_mined = Event.generate_event_name('on_entity_mined')}}
|
||||
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local sqrt = math.sqrt
|
||||
@ -337,7 +340,12 @@ local function randomness(data)
|
||||
end
|
||||
end
|
||||
local particle = particles[harvest]
|
||||
create_particles(player.surface, particle, position, 64, {x = player.position.x, y = player.position.y})
|
||||
|
||||
if data.script_character then
|
||||
create_particles(player.surface, particle, position, 64, {x = data.script_character.position.x, y = data.script_character.position.y})
|
||||
else
|
||||
create_particles(player.surface, particle, position, 64, {x = player.position.x, y = player.position.y})
|
||||
end
|
||||
end
|
||||
|
||||
local function randomness_scrap(data)
|
||||
@ -390,7 +398,11 @@ local function randomness_scrap(data)
|
||||
end
|
||||
end
|
||||
local particle = particles[harvest]
|
||||
create_particles(player.surface, particle, position, 64, {x = player.position.x, y = player.position.y})
|
||||
if data.script_character then
|
||||
create_particles(player.surface, particle, position, 64, {x = data.script_character.position.x, y = data.script_character.position.y})
|
||||
else
|
||||
create_particles(player.surface, particle, position, 64, {x = player.position.x, y = player.position.y})
|
||||
end
|
||||
end
|
||||
|
||||
function Public.on_player_mined_entity(event)
|
||||
@ -413,13 +425,19 @@ function Public.on_player_mined_entity(event)
|
||||
local buffer = event.buffer
|
||||
|
||||
if valid_rocks[entity.name] or valid_trees[entity.name] or is_scrap then
|
||||
buffer.clear()
|
||||
if buffer then
|
||||
buffer.clear()
|
||||
end
|
||||
|
||||
local data = {
|
||||
entity = entity,
|
||||
player = player
|
||||
}
|
||||
|
||||
if event.script_character then
|
||||
data.script_character = event.script_character
|
||||
end
|
||||
|
||||
local index = player.index
|
||||
|
||||
local scrap_zone = RPG.get_value_from_player(index, 'scrap_zone')
|
||||
@ -433,4 +451,26 @@ function Public.on_player_mined_entity(event)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(
|
||||
Public.events.on_entity_mined,
|
||||
function(event)
|
||||
if not event then
|
||||
return
|
||||
end
|
||||
|
||||
Public.on_player_mined_entity(event)
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
Ai.events.on_entity_mined,
|
||||
function(event)
|
||||
if not event then
|
||||
return
|
||||
end
|
||||
|
||||
Public.on_player_mined_entity(event)
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
||||
|
@ -99,9 +99,7 @@ function Public.soft_reset_map(old_surface, map_gen_settings, player_starting_it
|
||||
table.concat(
|
||||
{
|
||||
mapkeeper,
|
||||
' The world has been reshaped, welcome to ',
|
||||
this.original_surface_name,
|
||||
' number ',
|
||||
' The world has been reshaped, welcome to attempt number ',
|
||||
tostring(this.soft_reset_counter),
|
||||
'!'
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
local Global = require 'utils.global'
|
||||
local surface_name = 'mountain_fortress_v3'
|
||||
local surface_name = 'mtn_v3'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local Reset = require 'maps.mountain_fortress_v3.soft_reset'
|
||||
local zone_settings = WPT.zone_settings
|
||||
@ -99,4 +99,4 @@ function Public.get(key)
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
||||
return Public
|
||||
|
@ -95,6 +95,7 @@ function Public.reset_table()
|
||||
-- @end
|
||||
this.icw_locomotive = nil
|
||||
this.game_lost = false
|
||||
this.death_mode = false
|
||||
this.fullness_enabled = true
|
||||
this.locomotive_health = 10000
|
||||
this.locomotive_max_health = 10000
|
||||
@ -112,16 +113,14 @@ function Public.reset_table()
|
||||
}
|
||||
this.force_chunk = false
|
||||
this.allow_decon = true
|
||||
this.train_upgrades = 0
|
||||
this.allow_decon_main_surface = true
|
||||
this.flamethrower_damage = {}
|
||||
this.mined_scrap = 0
|
||||
this.print_tech_to_discord = true
|
||||
this.biters_killed = 0
|
||||
this.cleared_nauvis = false
|
||||
this.locomotive_xp_aura = 40
|
||||
this.locomotive_pos = {tbl = {}}
|
||||
this.trusted_only_car_tanks = true
|
||||
this.xp_points = 0
|
||||
this.xp_points_upgrade = 0
|
||||
--!grief prevention
|
||||
this.enable_arties = 6 -- default to callback 6
|
||||
--!snip
|
||||
@ -142,13 +141,22 @@ function Public.reset_table()
|
||||
unit_number = {
|
||||
landmine = {},
|
||||
flame_turret = {}
|
||||
}
|
||||
},
|
||||
has_upgraded_health_pool = false,
|
||||
explosive_bullets_purchased = false,
|
||||
xp_points_upgrade = 0,
|
||||
aura_upgrades = 0,
|
||||
locomotive_aura_radius = 40,
|
||||
train_upgrades = 0,
|
||||
xp_points = 0,
|
||||
health_upgrades = 0,
|
||||
pickaxe_tier = 1,
|
||||
chests_outside_upgrades = 1
|
||||
}
|
||||
this.orbital_strikes = {
|
||||
enabled = true
|
||||
}
|
||||
this.aura_upgrades = 0
|
||||
this.pickaxe_tier = 1
|
||||
this.pickaxe_speed_per_purchase = 0.07
|
||||
this.health_upgrades = 1
|
||||
this.health_upgrades_limit = 100
|
||||
this.breached_wall = 1
|
||||
this.left_top = {
|
||||
x = 0,
|
||||
@ -167,15 +175,20 @@ function Public.reset_table()
|
||||
this.spill_items_to_surface = false
|
||||
this.outside_chests = {}
|
||||
this.chests_linked_to = {}
|
||||
this.chest_limit_outside_upgrades = 1
|
||||
this.placed_trains_in_zone = {
|
||||
limit = 2,
|
||||
randomized = false,
|
||||
zones = {}
|
||||
}
|
||||
this.market_limits = {
|
||||
chests_outside_limit = 8,
|
||||
aura_limit = 100, -- limited to save UPS
|
||||
pickaxe_tier_limit = 59,
|
||||
health_upgrades_limit = 100
|
||||
}
|
||||
this.marked_fixed_prices = {
|
||||
chest_limit_cost = 3000,
|
||||
health_cost = 7000,
|
||||
chests_outside_cost = 3000,
|
||||
health_cost = 14000,
|
||||
pickaxe_cost = 3000,
|
||||
aura_cost = 4000,
|
||||
xp_point_boost_cost = 5000,
|
||||
@ -186,12 +199,8 @@ function Public.reset_table()
|
||||
redraw_mystical_chest_cost = 3000
|
||||
}
|
||||
this.collapse_grace = true
|
||||
this.explosive_bullets = false
|
||||
this.locomotive_biter = nil
|
||||
this.disconnect_wagon = false
|
||||
this.offline_players_enabled = true
|
||||
this.offline_players = {}
|
||||
this.offline_players_surface_removal = false
|
||||
this.collapse_amount = false
|
||||
this.collapse_speed = false
|
||||
this.y_value_position = 20
|
||||
@ -220,7 +229,6 @@ function Public.reset_table()
|
||||
this.market_announce = game.tick + 1200
|
||||
this.check_heavy_damage = true
|
||||
this.prestige_system_enabled = false
|
||||
this.has_upgraded_health_pool = false
|
||||
this.mystical_chest_enabled = true
|
||||
this.check_if_threat_below_zero = true
|
||||
this.mc_rewards = {
|
||||
@ -230,6 +238,7 @@ function Public.reset_table()
|
||||
this.adjusted_zones = {
|
||||
scrap = {},
|
||||
forest = {},
|
||||
slow_movement = {},
|
||||
size = nil,
|
||||
shuffled_zones = nil
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ local function wall(p, data)
|
||||
entities[#entities + 1] = {
|
||||
name = 'stone-wall',
|
||||
position = p,
|
||||
force = 'player',
|
||||
force = 'neutral',
|
||||
callback = stone_wall
|
||||
}
|
||||
if not alert_zone_1 and data.y >= -zone_settings.zone_depth then
|
||||
@ -402,7 +402,7 @@ local function wall(p, data)
|
||||
entities[#entities + 1] = {
|
||||
name = 'stone-wall',
|
||||
position = p,
|
||||
force = 'player',
|
||||
force = 'neutral',
|
||||
callback = stone_wall
|
||||
}
|
||||
end
|
||||
@ -817,6 +817,7 @@ local function zone_10(x, y, data, _, adjusted_zones)
|
||||
local entities = data.entities
|
||||
local buildings = data.buildings
|
||||
local treasure = data.treasure
|
||||
data.forest_zone = true
|
||||
|
||||
local scrapyard = get_perlin('scrapyard', p, seed)
|
||||
local smol_areas = get_perlin('smol_areas', p, seed + 45000)
|
||||
@ -2589,6 +2590,7 @@ local function init_terrain(adjusted_zones)
|
||||
shuffle_again[inc] = map
|
||||
end
|
||||
end
|
||||
shuffle_again = shuffle(shuffle_again)
|
||||
|
||||
adjusted_zones.size = size
|
||||
adjusted_zones.shuffled_zones = shuffle_again
|
||||
@ -2722,7 +2724,7 @@ function Public.heavy_functions(data)
|
||||
local adjusted_zones = WPT.get('adjusted_zones')
|
||||
init_terrain(adjusted_zones)
|
||||
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
@ -2762,7 +2764,7 @@ Event.add(
|
||||
defines.events.on_chunk_generated,
|
||||
function(e)
|
||||
local surface = e.surface
|
||||
local map_name = 'mountain_fortress_v3'
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
|
@ -9,7 +9,7 @@ local Server = require 'utils.server'
|
||||
local MapFuntions = require 'tools.map_functions'
|
||||
local CommonFunctions = require 'utils.common'
|
||||
local LayersFunctions = require 'maps.planet_prison.mod.layers'
|
||||
local AIFunctions = require 'utils.ai'
|
||||
local AIFunctions = require 'maps.planet_prison.ai'
|
||||
local Blueprints = require 'maps.planet_prison.mod.bp'
|
||||
local AfkFunctions = require 'maps.planet_prison.mod.afk'
|
||||
local Timers = require 'utils.timers'
|
||||
|
531
modules/ai.lua
Normal file
531
modules/ai.lua
Normal file
@ -0,0 +1,531 @@
|
||||
--- created by Gerkiz
|
||||
local Event = require 'utils.event'
|
||||
local Color = require 'utils.color_presets'
|
||||
local Utils = require 'utils.common'
|
||||
local Global = require 'utils.global'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
|
||||
local this = {
|
||||
timers = {},
|
||||
characters = {},
|
||||
characters_unit_numbers = {}
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {events = {on_entity_mined = Event.generate_event_name('on_entity_mined')}}
|
||||
|
||||
local max_keepalive = 54000 -- 15 minutes
|
||||
local remove = table.remove
|
||||
local round = math.round
|
||||
local default_radius = 5
|
||||
|
||||
Public.command = {
|
||||
noop = 0,
|
||||
seek_and_destroy_cmd = 1,
|
||||
seek_and_mine_cmd = 2
|
||||
}
|
||||
|
||||
local clear_corpse_token =
|
||||
Token.register(
|
||||
function(event)
|
||||
local position = event.position
|
||||
local surface = game.get_surface(event.surface_index)
|
||||
local search_info = {
|
||||
type = 'character-corpse',
|
||||
position = position,
|
||||
radius = 1
|
||||
}
|
||||
|
||||
local corpses = surface.find_entities_filtered(search_info)
|
||||
if corpses and #corpses > 0 then
|
||||
for _, corpse in pairs(corpses) do
|
||||
if corpse and corpse.valid then
|
||||
if corpse.character_corpse_player_index == 65536 then
|
||||
corpse.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function char_callback(callback)
|
||||
local entities = this.characters
|
||||
|
||||
for i = 1, #entities do
|
||||
local data = entities[i]
|
||||
if data and data.entity and data.entity.valid then
|
||||
callback(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_near_position(entity)
|
||||
return {x = round(entity.position.x, 0), y = round(entity.position.y, 0)}
|
||||
end
|
||||
|
||||
local function is_mining_target_taken(selected)
|
||||
if not selected then
|
||||
return false
|
||||
end
|
||||
|
||||
char_callback(
|
||||
function(data)
|
||||
local entity = data.entity
|
||||
if entity.selected == selected then
|
||||
return true
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function add_character(player_index, entity, render_id, data)
|
||||
local index = #this.characters + 1
|
||||
if not this.characters[index] then
|
||||
this.characters[index] = {
|
||||
player_index = player_index,
|
||||
index = index,
|
||||
unit_number = entity.unit_number,
|
||||
entity = entity,
|
||||
ttl = game.tick + (data.ttl or max_keepalive),
|
||||
command = data.command,
|
||||
radius = default_radius,
|
||||
max_radius_mine = 20,
|
||||
max_radius_destroy = 150,
|
||||
render_id = render_id,
|
||||
search_local = data.search_local or false,
|
||||
walking_position = {count = 1, position = get_near_position(entity)}
|
||||
}
|
||||
end
|
||||
if not this.characters_unit_numbers[entity.unit_number] then
|
||||
this.characters_unit_numbers[entity.unit_number] = true
|
||||
end
|
||||
end
|
||||
|
||||
local function exists_character(unit_number)
|
||||
if not next(this.characters_unit_numbers) then
|
||||
return
|
||||
end
|
||||
|
||||
if this.characters_unit_numbers[unit_number] then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function remove_character(unit_number)
|
||||
if not next(this.characters) then
|
||||
return
|
||||
end
|
||||
|
||||
for index, data in pairs(this.characters) do
|
||||
if data and data.unit_number == unit_number then
|
||||
if data.entity and data.entity.valid then
|
||||
data.entity.destroy()
|
||||
end
|
||||
if rendering.is_valid(data.render_id) then
|
||||
rendering.destroy(data.render_id)
|
||||
end
|
||||
remove(this.characters, index)
|
||||
end
|
||||
end
|
||||
|
||||
if this.characters_unit_numbers[unit_number] then
|
||||
this.characters_unit_numbers[unit_number] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function get_dir(src, dest)
|
||||
local src_x = Utils.get_axis(src, 'x')
|
||||
local src_y = Utils.get_axis(src, 'y')
|
||||
local dest_x = Utils.get_axis(dest, 'x')
|
||||
local dest_y = Utils.get_axis(dest, 'y')
|
||||
|
||||
local step = {
|
||||
x = nil,
|
||||
y = nil
|
||||
}
|
||||
|
||||
local precision = Utils.rand_range(1, 10)
|
||||
if dest_x - precision > src_x then
|
||||
step.x = 1
|
||||
elseif dest_x < src_x - precision then
|
||||
step.x = -1
|
||||
else
|
||||
step.x = 0
|
||||
end
|
||||
|
||||
if dest_y - precision > src_y then
|
||||
step.y = 1
|
||||
elseif dest_y < src_y - precision then
|
||||
step.y = -1
|
||||
else
|
||||
step.y = 0
|
||||
end
|
||||
|
||||
return Utils.direction_lookup[step.x][step.y]
|
||||
end
|
||||
|
||||
local function move_to(entity, target, min_distance)
|
||||
local state = {
|
||||
walking = false
|
||||
}
|
||||
|
||||
local distance = Utils.get_distance(target.position, entity.position)
|
||||
if min_distance < distance then
|
||||
local dir = get_dir(entity.position, target.position)
|
||||
if dir then
|
||||
state = {
|
||||
walking = true,
|
||||
direction = dir
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
entity.walking_state = state
|
||||
return state.walking
|
||||
end
|
||||
|
||||
local function refill_ammo(entity)
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
local weapon = entity.get_inventory(defines.inventory.character_guns)[entity.selected_gun_index]
|
||||
if weapon and weapon.valid_for_read then
|
||||
local selected_ammo = entity.get_inventory(defines.inventory.character_ammo)[entity.selected_gun_index]
|
||||
if selected_ammo then
|
||||
if not selected_ammo.valid_for_read then
|
||||
if weapon.name == 'shotgun' then
|
||||
entity.insert({name = 'shotgun-shell', count = 5})
|
||||
end
|
||||
if weapon.name == 'pistol' then
|
||||
entity.insert({name = 'firearm-magazine', count = 5})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function shoot_at(entity, target)
|
||||
entity.selected = target
|
||||
entity.shooting_state = {
|
||||
state = defines.shooting.shooting_enemies,
|
||||
position = target.position
|
||||
}
|
||||
end
|
||||
|
||||
local function check_progress_and_raise_event(data)
|
||||
if data.entity.selected and data.entity.character_mining_progress >= 0.95 then
|
||||
if not data.raised_event then
|
||||
data.raised_event = true
|
||||
Event.raise(
|
||||
Public.events.on_entity_mined,
|
||||
{
|
||||
player_index = data.player_index,
|
||||
entity = data.entity.selected,
|
||||
surface = data.entity.surface,
|
||||
script_character = data.entity
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function mine_entity(data, target)
|
||||
data.entity.selected = target
|
||||
data.entity.mining_state = {mining = true, position = target.position}
|
||||
end
|
||||
|
||||
local function shoot_stop(entity)
|
||||
entity.shooting_state = {
|
||||
state = defines.shooting.not_shooting,
|
||||
position = {0, 0}
|
||||
}
|
||||
end
|
||||
|
||||
local function insert_weapons(entity)
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
local weapon = entity.get_inventory(defines.inventory.character_guns)[entity.selected_gun_index]
|
||||
if weapon and weapon.valid_for_read then
|
||||
return
|
||||
end
|
||||
|
||||
if Utils.rand_range(1, 15) == 1 then
|
||||
entity.insert({name = 'shotgun', count = 1})
|
||||
entity.insert({name = 'shotgun-shell', count = 5})
|
||||
elseif Utils.rand_range(1, 10) == 1 then
|
||||
entity.insert({name = 'submachine-gun', count = 1})
|
||||
entity.insert({name = 'firearm-magazine', count = 5})
|
||||
else
|
||||
entity.insert({name = 'pistol', count = 1})
|
||||
entity.insert({name = 'firearm-magazine', count = 5})
|
||||
end
|
||||
end
|
||||
|
||||
local function seek_and_mine(data)
|
||||
if data.radius >= data.max_radius_mine then
|
||||
if data.overriden_command then
|
||||
data.command = data.overriden_command
|
||||
data.overriden_command = nil
|
||||
return
|
||||
else
|
||||
data.radius = 1
|
||||
end
|
||||
end
|
||||
|
||||
local entity = data.entity
|
||||
if not entity or not entity.valid then
|
||||
remove_character(data.unit_number)
|
||||
return
|
||||
end
|
||||
|
||||
local surface = entity.surface
|
||||
local player_index = data.player_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid or not player.connected then
|
||||
remove_character(data.unit_number)
|
||||
return
|
||||
end
|
||||
|
||||
local position
|
||||
|
||||
if data.search_local then
|
||||
position = entity.position
|
||||
else
|
||||
position = player.position
|
||||
end
|
||||
|
||||
local search_info = {
|
||||
position = position,
|
||||
radius = data.radius,
|
||||
type = {
|
||||
'simple-entity-with-owner',
|
||||
'simple-entity',
|
||||
'tree'
|
||||
},
|
||||
force = {
|
||||
'neutral'
|
||||
}
|
||||
}
|
||||
|
||||
local closest = surface.find_entities_filtered(search_info)
|
||||
|
||||
if #closest ~= 0 then
|
||||
local target = Utils.get_closest_neighbour_non_player(entity.position, closest)
|
||||
if not target then
|
||||
data.radius = data.radius + 1
|
||||
return
|
||||
end
|
||||
|
||||
data.radius = 1
|
||||
|
||||
if not move_to(entity, target, 1) then
|
||||
if not is_mining_target_taken(target) then
|
||||
if data.raised_event then
|
||||
data.raised_event = nil
|
||||
end
|
||||
|
||||
if entity.can_reach_entity(target) then
|
||||
mine_entity(data, target)
|
||||
else
|
||||
move_to(entity, target, 1)
|
||||
end
|
||||
end
|
||||
if data.overriden_command then
|
||||
data.command = data.overriden_command
|
||||
data.overriden_command = nil
|
||||
end
|
||||
end
|
||||
else
|
||||
data.radius = data.radius + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function seek_enemy_and_destroy(data)
|
||||
if data.radius >= data.max_radius_destroy then
|
||||
remove_character(data.unit_number)
|
||||
return
|
||||
end
|
||||
|
||||
local entity = data.entity
|
||||
if not entity or not entity.valid then
|
||||
remove_character(data.unit_number)
|
||||
return
|
||||
end
|
||||
|
||||
local surface = entity.surface
|
||||
local player_index = data.player_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid or not player.connected then
|
||||
remove_character(data.unit_number)
|
||||
return
|
||||
end
|
||||
|
||||
local search_info = {
|
||||
type = {'unit', 'unit-spawner', 'turret'},
|
||||
position = entity.position,
|
||||
radius = data.radius,
|
||||
force = 'enemy'
|
||||
}
|
||||
|
||||
local closest = surface.find_entities_filtered(search_info)
|
||||
|
||||
if #closest ~= 0 then
|
||||
local target = Utils.get_closest_neighbour_non_player(entity.position, closest)
|
||||
if not target then
|
||||
data.radius = data.radius + 5
|
||||
return
|
||||
end
|
||||
data.radius = default_radius
|
||||
insert_weapons(entity)
|
||||
refill_ammo(entity)
|
||||
|
||||
local inside = ((entity.position.x - data.walking_position.position.x) ^ 2 + (entity.position.y - data.walking_position.position.y) ^ 2) < 1 ^ 2
|
||||
data.walking_position.position = get_near_position(entity)
|
||||
|
||||
if inside then
|
||||
data.walking_position.count = data.walking_position.count + 1
|
||||
end
|
||||
|
||||
if data.walking_position.count == 3 then
|
||||
data.radius = 1
|
||||
data.walking_position.count = 1
|
||||
data.overriden_command = data.command
|
||||
data.command = Public.command.seek_and_mine_cmd
|
||||
seek_and_mine(data)
|
||||
else
|
||||
if not move_to(entity, target, Utils.rand_range(5, 10)) then
|
||||
shoot_at(entity, target)
|
||||
else
|
||||
shoot_stop(entity)
|
||||
end
|
||||
end
|
||||
else
|
||||
data.radius = data.radius + 5
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a new character that seeks and does stuff.
|
||||
---@param data table
|
||||
----- @usage local Ai = require 'modules.ai' Ai.create_char({player_index = game.player.index, command = 1})
|
||||
function Public.create_char(data)
|
||||
if not data or not type(data) == 'table' then
|
||||
return error('No data was provided or the provided data was not a table.', 2)
|
||||
end
|
||||
|
||||
if not data.player_index or not data.command then
|
||||
return error('No correct data was not provided.', 2)
|
||||
end
|
||||
|
||||
if data.command ~= Public.command.seek_and_destroy_cmd and data.command ~= Public.command.attack_objects_cmd and data.command ~= Public.command.seek_and_mine_cmd then
|
||||
return error('No correct command was not provided.', 2)
|
||||
end
|
||||
|
||||
local player = game.get_player(data.player_index)
|
||||
if not player or not player.valid or not player.connected then
|
||||
return error('Provided player was not valid or not connected.', 2)
|
||||
end
|
||||
|
||||
local surface = player.surface
|
||||
local valid_position = surface.find_non_colliding_position('character', {x = player.position.x, y = player.position.y + 2}, 3, 0.5)
|
||||
if not valid_position then
|
||||
return
|
||||
end
|
||||
local entity = surface.create_entity {name = 'character', position = valid_position, force = player.force}
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
entity.associated_player = player
|
||||
if player.character_health_bonus >= 200 then
|
||||
entity.character_health_bonus = player.character_health_bonus / 2
|
||||
end
|
||||
|
||||
entity.color = player.color
|
||||
local index = #this.characters + 1
|
||||
|
||||
local render_id =
|
||||
rendering.draw_text {
|
||||
text = player.name .. "'s drone #" .. index,
|
||||
surface = player.surface,
|
||||
target = entity,
|
||||
target_offset = {0, -2.25},
|
||||
color = Color.orange,
|
||||
scale = 1.00,
|
||||
font = 'default-large-semibold',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
add_character(player.index, entity, render_id, data)
|
||||
end
|
||||
|
||||
Event.on_nth_tick(
|
||||
2,
|
||||
function()
|
||||
char_callback(
|
||||
function(data)
|
||||
check_progress_and_raise_event(data)
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
Event.on_nth_tick(
|
||||
10,
|
||||
function()
|
||||
local tick = game.tick
|
||||
char_callback(
|
||||
function(data)
|
||||
if data.ttl <= tick then
|
||||
remove_character(data.unit_number)
|
||||
return
|
||||
end
|
||||
|
||||
local command = data.command
|
||||
|
||||
if command == Public.command.seek_and_destroy_cmd then
|
||||
seek_enemy_and_destroy(data)
|
||||
elseif command == Public.command.seek_and_mine_cmd then
|
||||
seek_and_mine(data)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_entity_died,
|
||||
function(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.type ~= 'character' then
|
||||
return
|
||||
end
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
if not exists_character(unit_number) then
|
||||
return
|
||||
end
|
||||
|
||||
Task.set_timeout_in_ticks(1, clear_corpse_token, {position = entity.position, surface_index = entity.surface.index})
|
||||
|
||||
remove_character(unit_number)
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
@ -5,10 +5,12 @@ local Global = require 'utils.global'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local Event = require 'utils.event'
|
||||
local BottomFrame = require 'utils.gui.bottom_frame'
|
||||
local ComfyGui = require 'utils.gui'
|
||||
local Gui = require 'utils.gui'
|
||||
local floor = math.floor
|
||||
local print_color = {r = 120, g = 255, b = 0}
|
||||
|
||||
local auto_stash_button_name = Gui.uid()
|
||||
|
||||
local this = {
|
||||
floating_text_y_offsets = {},
|
||||
whitelist = {},
|
||||
@ -191,16 +193,6 @@ local function get_nearby_chests(player, a, furnace, wagon)
|
||||
return {chest = chests, inventory = inventories}
|
||||
end
|
||||
|
||||
local function does_inventory_contain_item_type(inventory, item_subgroup)
|
||||
for name, _ in pairs(inventory.get_contents()) do
|
||||
local t = game.item_prototypes[name]
|
||||
if t and t.subgroup.name == item_subgroup then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function insert_to_furnace(player_inventory, chests, name, count, floaty_text_list)
|
||||
local try = 0
|
||||
|
||||
@ -369,8 +361,8 @@ local function insert_item_into_chest(stack, chests, filtered_chests, name, floa
|
||||
for chestnr, chest in pairs(chests.chest) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = chests.inventory[chestnr]
|
||||
if chest_inventory and chest_inventory.can_insert(stack) then
|
||||
if chest_inventory.find_item_stack(stack.name) then
|
||||
if chest_inventory and chest_inventory.find_item_stack(stack.name) then
|
||||
if chest_inventory.can_insert(stack) then
|
||||
local inserted_count = chest_inventory.insert(stack)
|
||||
stack.count = stack.count - inserted_count
|
||||
prepare_floaty_text(floaty_text_list, chest.surface, chest.position, name, inserted_count)
|
||||
@ -386,32 +378,43 @@ local function insert_item_into_chest(stack, chests, filtered_chests, name, floa
|
||||
for chestnr, chest in pairs(filtered_chests.chest) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = filtered_chests.inventory[chestnr]
|
||||
if chest_inventory and chest_inventory.can_insert(stack) then
|
||||
if chest_inventory.is_empty() then
|
||||
local inserted_count = chest_inventory.insert(stack)
|
||||
stack.count = stack.count - inserted_count
|
||||
prepare_floaty_text(floaty_text_list, chest.surface, chest.position, name, inserted_count)
|
||||
if stack.count <= 0 then
|
||||
return chestnr
|
||||
end
|
||||
if not chest_inventory then
|
||||
break
|
||||
end
|
||||
local count = chest_inventory.get_item_count() == 0
|
||||
if count then
|
||||
local inserted_count = chest_inventory.insert(stack)
|
||||
stack.count = stack.count - inserted_count
|
||||
prepare_floaty_text(floaty_text_list, chest.surface, chest.position, name, inserted_count)
|
||||
if stack.count <= 0 then
|
||||
return chestnr
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local item_prototypes = game.item_prototypes
|
||||
|
||||
--Attempt to store in chests with same item subgroup.
|
||||
local item_subgroup = game.item_prototypes[name].subgroup.name
|
||||
if item_subgroup then
|
||||
for chestnr, chest in pairs(filtered_chests.chest) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = filtered_chests.inventory[chestnr]
|
||||
if chest_inventory and chest_inventory.can_insert(stack) then
|
||||
if does_inventory_contain_item_type(chest_inventory, item_subgroup) then
|
||||
local inserted_count = chest_inventory.insert(stack)
|
||||
stack.count = stack.count - inserted_count
|
||||
prepare_floaty_text(floaty_text_list, chest.surface, chest.position, name, inserted_count)
|
||||
if stack.count <= 0 then
|
||||
return chestnr
|
||||
if not chest_inventory then
|
||||
break
|
||||
end
|
||||
local content = chest_inventory.get_contents()
|
||||
if chest_inventory.can_insert(stack) then
|
||||
for equal_name, _ in pairs(content) do
|
||||
local t = item_prototypes[equal_name]
|
||||
if t and t.subgroup.name == item_subgroup then
|
||||
local inserted_count = chest_inventory.insert(stack)
|
||||
stack.count = stack.count - inserted_count
|
||||
prepare_floaty_text(floaty_text_list, chest.surface, chest.position, name, inserted_count)
|
||||
if stack.count <= 0 then
|
||||
return chestnr
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -423,6 +426,9 @@ local function insert_item_into_chest(stack, chests, filtered_chests, name, floa
|
||||
for chestnr, chest in pairs(filtered_chests.chest) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = filtered_chests.inventory[chestnr]
|
||||
if not chest_inventory then
|
||||
break
|
||||
end
|
||||
if chest_inventory.can_insert(stack) then
|
||||
local inserted_count = chest_inventory.insert(stack)
|
||||
stack.count = stack.count - inserted_count
|
||||
@ -581,12 +587,12 @@ local function create_gui_button(player)
|
||||
end
|
||||
end
|
||||
else
|
||||
if ComfyGui.get_mod_gui_top_frame() then
|
||||
ComfyGui.add_mod_button(
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
Gui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = 'auto_stash',
|
||||
name = auto_stash_button_name,
|
||||
sprite = 'item/wooden-chest',
|
||||
tooltip = tooltip
|
||||
}
|
||||
@ -597,7 +603,7 @@ local function create_gui_button(player)
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/wooden-chest',
|
||||
name = 'auto_stash',
|
||||
name = auto_stash_button_name,
|
||||
tooltip = tooltip
|
||||
}
|
||||
)
|
||||
@ -641,31 +647,21 @@ local function on_player_joined_game(event)
|
||||
create_gui_button(game.players[event.player_index])
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
if not event.element then
|
||||
return
|
||||
end
|
||||
if not event.element.valid then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
local name = 'auto_stash'
|
||||
if this.bottom_button then
|
||||
local data = BottomFrame.get('bottom_quickbar_button')
|
||||
if data and data[player.index] then
|
||||
data = data[player.index]
|
||||
name = data.name
|
||||
end
|
||||
end
|
||||
|
||||
if event.element.name == name then
|
||||
local is_spamming = SpamProtection.is_spamming(player, nil, 'Autostash Click')
|
||||
Gui.on_click(
|
||||
auto_stash_button_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Autostash click')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
auto_stash(player, event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
auto_stash(event.player, event)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function Public.insert_into_furnace(value)
|
||||
if value then
|
||||
@ -698,6 +694,14 @@ Event.on_configuration_changed(do_whitelist)
|
||||
|
||||
Event.on_init(do_whitelist)
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
|
||||
Event.add(
|
||||
BottomFrame.events.bottom_quickbar_button_name,
|
||||
function(data)
|
||||
local event = data.event
|
||||
local player = event.player
|
||||
auto_stash(player, event)
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
||||
|
161
modules/clear_vacant_players.lua
Normal file
161
modules/clear_vacant_players.lua
Normal file
@ -0,0 +1,161 @@
|
||||
local Global = require 'utils.global'
|
||||
local Alert = require 'utils.alert'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local this = {
|
||||
settings = {
|
||||
offline_players_enabled = false,
|
||||
offline_players_surface_removal = false,
|
||||
active_surface_index = nil, -- needs to be set else this will fail
|
||||
required_online_time = 18000, -- nearest prime to 5 minutes in ticks
|
||||
clear_player_after_tick = 108000 -- nearest prime to 30 minutes in ticks
|
||||
},
|
||||
offline_players = {}
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {events = {remove_surface = Event.generate_event_name('remove_surface')}}
|
||||
|
||||
function Public.remove_offline_players()
|
||||
if not this.settings.offline_players_enabled then
|
||||
return
|
||||
end
|
||||
local tick = game.tick
|
||||
if tick < 50 then
|
||||
return
|
||||
end
|
||||
|
||||
if not this.settings.active_surface_index then
|
||||
return error('An active surface index must be set', 2)
|
||||
end
|
||||
local surface = game.get_surface(this.settings.active_surface_index)
|
||||
local player_inv = {}
|
||||
local items = {}
|
||||
if #this.offline_players > 0 then
|
||||
for i = 1, #this.offline_players, 1 do
|
||||
if this.offline_players[i] and this.offline_players[i].index then
|
||||
local target = game.get_player(this.offline_players[i].index)
|
||||
if target and target.valid then
|
||||
if target.connected then
|
||||
this.offline_players[i] = nil
|
||||
else
|
||||
if this.offline_players[i].tick < tick then
|
||||
local name = this.offline_players[i].name
|
||||
player_inv[1] = target.get_inventory(defines.inventory.character_main)
|
||||
player_inv[2] = target.get_inventory(defines.inventory.character_armor)
|
||||
player_inv[3] = target.get_inventory(defines.inventory.character_guns)
|
||||
player_inv[4] = target.get_inventory(defines.inventory.character_ammo)
|
||||
player_inv[5] = target.get_inventory(defines.inventory.character_trash)
|
||||
if this.offline_players_surface_removal then
|
||||
Event.raise(this.events.remove_surface, {target = target})
|
||||
end
|
||||
|
||||
if target.get_item_count() == 0 then -- if the player has zero items, don't do anything
|
||||
this.offline_players[i] = nil
|
||||
goto final
|
||||
end
|
||||
|
||||
local pos = game.forces.player.get_spawn_position(surface)
|
||||
local e =
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'character',
|
||||
position = pos,
|
||||
force = 'neutral'
|
||||
}
|
||||
)
|
||||
local inv = e.get_inventory(defines.inventory.character_main)
|
||||
e.character_inventory_slots_bonus = #player_inv[1]
|
||||
for ii = 1, 5, 1 do
|
||||
if player_inv[ii].valid then
|
||||
for iii = 1, #player_inv[ii], 1 do
|
||||
if player_inv[ii][iii].valid then
|
||||
items[#items + 1] = player_inv[ii][iii]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #items > 0 then
|
||||
for item = 1, #items, 1 do
|
||||
if items[item].valid then
|
||||
inv.insert(items[item])
|
||||
end
|
||||
end
|
||||
|
||||
local message = ({'main.cleaner', name})
|
||||
local data = {
|
||||
position = pos
|
||||
}
|
||||
Alert.alert_all_players_location(data, message)
|
||||
|
||||
e.die('neutral')
|
||||
else
|
||||
e.destroy()
|
||||
end
|
||||
|
||||
for ii = 1, 5, 1 do
|
||||
if player_inv[ii].valid then
|
||||
player_inv[ii].clear()
|
||||
end
|
||||
end
|
||||
this.offline_players[i] = nil
|
||||
break
|
||||
end
|
||||
::final::
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Activates the offline player module
|
||||
---@param value boolean
|
||||
function Public.set_offline_players_enabled(value)
|
||||
this.settings.offline_players_enabled = value or false
|
||||
end
|
||||
|
||||
--- Activates the surface removal for the module IC
|
||||
---@param value boolean
|
||||
function Public.set_offline_players_surface_removal(value)
|
||||
this.settings.offline_players_surface_removal = value or false
|
||||
end
|
||||
|
||||
--- Sets the active surface for this module, needs to be set else it will fail
|
||||
---@param value string
|
||||
function Public.set_active_surface_index(value)
|
||||
this.settings.active_surface_index = value or nil
|
||||
end
|
||||
|
||||
local remove_offline_players = Public.remove_offline_players
|
||||
|
||||
Event.on_nth_tick(200, remove_offline_players)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_pre_player_left_game,
|
||||
function(event)
|
||||
if not this.settings.offline_players_enabled then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
local ticker = game.tick
|
||||
if player.online_time >= this.settings.required_online_time then
|
||||
if player.character then
|
||||
this.offline_players[#this.offline_players + 1] = {
|
||||
index = event.player_index,
|
||||
name = player.name,
|
||||
tick = ticker + this.settings.clear_player_after_tick
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
@ -50,11 +50,11 @@ local this = {
|
||||
[2] = '',
|
||||
[3] = ''
|
||||
},
|
||||
difficulty_vote_value = 0.75,
|
||||
difficulty_vote_index = 1,
|
||||
value = 0.75,
|
||||
index = 1,
|
||||
fair_vote = false,
|
||||
difficulty_poll_closing_timeout = 54000,
|
||||
difficulty_player_votes = {},
|
||||
closing_timeout = 54000,
|
||||
all_votes = {},
|
||||
gui_width = 108,
|
||||
name = "I'm too young to die",
|
||||
strength_modifier = 1.00,
|
||||
@ -78,24 +78,24 @@ local function clear_main_frame(player)
|
||||
end
|
||||
|
||||
function Public.difficulty_gui()
|
||||
local tooltip = 'Current difficulty of the map is ' .. this.difficulties[this.difficulty_vote_index].name .. '.'
|
||||
local tooltip = 'Current difficulty of the map is ' .. this.difficulties[this.index].name .. '.'
|
||||
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local top = player.gui.top
|
||||
if top[top_button_name] then
|
||||
top[top_button_name].caption = this.difficulties[this.difficulty_vote_index].name
|
||||
top[top_button_name].caption = this.difficulties[this.index].name
|
||||
top[top_button_name].tooltip = this.button_tooltip or tooltip
|
||||
top[top_button_name].style.font_color = this.difficulties[this.difficulty_vote_index].print_color
|
||||
top[top_button_name].style.font_color = this.difficulties[this.index].print_color
|
||||
else
|
||||
local b =
|
||||
top.add {
|
||||
type = 'button',
|
||||
caption = this.difficulties[this.difficulty_vote_index].name,
|
||||
caption = this.difficulties[this.index].name,
|
||||
tooltip = tooltip,
|
||||
name = top_button_name
|
||||
}
|
||||
b.style.font = 'heading-2'
|
||||
b.style.font_color = this.difficulties[this.difficulty_vote_index].print_color
|
||||
b.style.font_color = this.difficulties[this.index].print_color
|
||||
b.style.minimal_height = 37
|
||||
b.style.maximal_height = 37
|
||||
b.style.minimal_width = this.gui_width
|
||||
@ -148,9 +148,9 @@ local function poll_difficulty(player)
|
||||
clear_main_frame(player)
|
||||
end
|
||||
|
||||
if game.tick > this.difficulty_poll_closing_timeout then
|
||||
if game.tick > this.closing_timeout then
|
||||
if player.online_time ~= 0 then
|
||||
local t = math.abs(math.floor((this.difficulty_poll_closing_timeout - game.tick) / 3600))
|
||||
local t = math.abs(math.floor((this.closing_timeout - game.tick) / 3600))
|
||||
local str = 'Votes have closed ' .. t
|
||||
str = str .. ' minute'
|
||||
if t > 1 then
|
||||
@ -163,6 +163,9 @@ local function poll_difficulty(player)
|
||||
end
|
||||
|
||||
local _, inside_frame = Gui.add_main_frame_with_toolbar(player, 'center', main_frame_name, nil, close_main_frame, 'Difficulty')
|
||||
if not inside_frame then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, #this.difficulties, 1 do
|
||||
local button_flow =
|
||||
@ -198,7 +201,7 @@ local function poll_difficulty(player)
|
||||
timeleft_flow.add(
|
||||
{
|
||||
type = 'button',
|
||||
caption = math.floor((this.difficulty_poll_closing_timeout - game.tick) / 3600) .. ' minutes left.'
|
||||
caption = math.floor((this.closing_timeout - game.tick) / 3600) .. ' minutes left.'
|
||||
}
|
||||
)
|
||||
b.style.font_color = {r = 0.66, g = 0.0, b = 0.66}
|
||||
@ -215,23 +218,25 @@ local function set_difficulty()
|
||||
return
|
||||
end
|
||||
|
||||
if this.difficulty_vote_index ~= index then
|
||||
if this.index ~= index then
|
||||
local message = table.concat({'*** Map difficulty has changed to ', this.difficulties[index].name, ' difficulty! ***'})
|
||||
game.print(message, this.difficulties[index].print_color)
|
||||
Server.to_discord_embed(message)
|
||||
end
|
||||
this.difficulty_vote_index = index
|
||||
this.difficulty_vote_value = this.difficulties[index].value
|
||||
this.index = index
|
||||
this.name = this.difficulties[index].name
|
||||
this.value = this.difficulties[index].value
|
||||
this.boss_modifier = this.difficulties[index].boss_modifier
|
||||
this.strength_modifier = this.difficulties[index].strength_modifier
|
||||
this.button_tooltip = this.tooltip[index]
|
||||
end
|
||||
|
||||
function Public.reset_difficulty_poll(tbl)
|
||||
if tbl then
|
||||
this.difficulty_vote_value = tbl.difficulty_vote_value or 0.75
|
||||
this.difficulty_vote_index = tbl.difficulty_vote_index or 1
|
||||
this.difficulty_player_votes = {}
|
||||
this.difficulty_poll_closing_timeout = tbl.difficulty_poll_closing_timeout or game.tick + 54000
|
||||
this.value = tbl.value or 0.75
|
||||
this.index = tbl.index or 1
|
||||
this.all_votes = {}
|
||||
this.closing_timeout = tbl.closing_timeout or game.tick + 54000
|
||||
for _, p in pairs(game.connected_players) do
|
||||
if p.gui.center[main_frame_name] then
|
||||
clear_main_frame(p)
|
||||
@ -243,10 +248,10 @@ function Public.reset_difficulty_poll(tbl)
|
||||
end
|
||||
Public.difficulty_gui()
|
||||
else
|
||||
this.difficulty_vote_value = 0.75
|
||||
this.difficulty_vote_index = 1
|
||||
this.difficulty_player_votes = {}
|
||||
this.difficulty_poll_closing_timeout = game.tick + 54000
|
||||
this.value = 0.75
|
||||
this.index = 1
|
||||
this.all_votes = {}
|
||||
this.closing_timeout = game.tick + 54000
|
||||
for _, p in pairs(game.connected_players) do
|
||||
if p.gui.center[main_frame_name] then
|
||||
clear_main_frame(p)
|
||||
@ -262,8 +267,8 @@ end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if game.tick < this.difficulty_poll_closing_timeout then
|
||||
if not this.difficulty_player_votes[player.name] then
|
||||
if game.tick < this.closing_timeout then
|
||||
if not this.all_votes[player.name] then
|
||||
poll_difficulty(player)
|
||||
end
|
||||
else
|
||||
@ -273,19 +278,19 @@ local function on_player_joined_game(event)
|
||||
end
|
||||
|
||||
local function on_player_left_game(event)
|
||||
if game.tick > this.difficulty_poll_closing_timeout then
|
||||
if game.tick > this.closing_timeout then
|
||||
return
|
||||
end
|
||||
local player = game.get_player(event.player_index)
|
||||
if not this.difficulty_player_votes[player.name] then
|
||||
if not this.all_votes[player.name] then
|
||||
return
|
||||
end
|
||||
local index = this.difficulty_player_votes[player.name].index
|
||||
local index = this.all_votes[player.name].index
|
||||
this.difficulties[index].count = this.difficulties[index].count - 1
|
||||
if this.difficulties[index].count <= 0 then
|
||||
this.difficulties[index].count = 0
|
||||
end
|
||||
this.difficulty_player_votes[player.name] = nil
|
||||
this.all_votes[player.name] = nil
|
||||
set_difficulty()
|
||||
Public.difficulty_gui()
|
||||
end
|
||||
@ -303,7 +308,13 @@ function Public.set_difficulties(...)
|
||||
end
|
||||
|
||||
function Public.set_poll_closing_timeout(...)
|
||||
this.difficulty_poll_closing_timeout = ...
|
||||
this.closing_timeout = ...
|
||||
end
|
||||
|
||||
--- Sets gui width
|
||||
---@param number number
|
||||
function Public.set_gui_width(number)
|
||||
this.gui_width = number
|
||||
end
|
||||
|
||||
function Public.get_fair_vote()
|
||||
@ -322,6 +333,17 @@ function Public.get(key)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set(key, value)
|
||||
if key and (value or value == false) then
|
||||
this[key] = value
|
||||
return this[key]
|
||||
elseif key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
Gui.on_click(
|
||||
selection_button_name,
|
||||
function(event)
|
||||
@ -341,14 +363,19 @@ Gui.on_click(
|
||||
|
||||
local i = tonumber(element.parent.name)
|
||||
|
||||
if this.difficulty_player_votes[player.name] and this.difficulty_player_votes[player.name].index == i then
|
||||
if game.tick > this.closing_timeout then
|
||||
clear_main_frame(player)
|
||||
return
|
||||
end
|
||||
|
||||
if this.all_votes[player.name] and this.all_votes[player.name].index == i then
|
||||
player.print('You have already voted for ' .. this.difficulties[i].name .. '.', this.difficulties[i].print_color)
|
||||
clear_main_frame(player)
|
||||
return
|
||||
end
|
||||
|
||||
if this.difficulty_player_votes[player.name] then
|
||||
local index = this.difficulty_player_votes[player.name].index
|
||||
if this.all_votes[player.name] then
|
||||
local index = this.all_votes[player.name].index
|
||||
this.difficulties[index].count = this.difficulties[index].count - 1
|
||||
if this.difficulties[index].count <= 0 then
|
||||
this.difficulties[index].count = 0
|
||||
@ -356,7 +383,7 @@ Gui.on_click(
|
||||
end
|
||||
|
||||
this.difficulties[i].count = this.difficulties[i].count + 1
|
||||
this.difficulty_player_votes[player.name] = {voted = true, index = i}
|
||||
this.all_votes[player.name] = {voted = true, index = i}
|
||||
|
||||
set_difficulty()
|
||||
Public.difficulty_gui()
|
||||
@ -378,7 +405,7 @@ Gui.on_click(
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
if game.tick > this.difficulty_poll_closing_timeout then
|
||||
if game.tick > this.closing_timeout then
|
||||
clear_main_frame(player)
|
||||
return
|
||||
end
|
||||
|
@ -94,11 +94,10 @@ local function on_player_joined_game(event)
|
||||
Gui.call_existing_tab(player, 'Map Info')
|
||||
end
|
||||
end
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
|
||||
Gui.add_tab_to_gui({name = module_name, caption = 'Map Info', id = create_map_intro_token, admin = false})
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
|
||||
Gui.on_click(
|
||||
module_name,
|
||||
function(event)
|
||||
|
352
modules/render_beam.lua
Normal file
352
modules/render_beam.lua
Normal file
@ -0,0 +1,352 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Gui = require 'utils.gui'
|
||||
|
||||
local this = {
|
||||
renders = {}
|
||||
}
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.metatable = {__index = Public}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
for _, render in pairs(this.renders) do
|
||||
setmetatable(render, Public.metatable)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local target_entities = {
|
||||
'character',
|
||||
'tank',
|
||||
'car',
|
||||
'radar',
|
||||
'lab',
|
||||
'furnace',
|
||||
'locomotive',
|
||||
'cargo-wagon',
|
||||
'fluid-wagon',
|
||||
'artillery-wagon',
|
||||
'artillery-turret',
|
||||
'laser-turret',
|
||||
'gun-turret',
|
||||
'flamethrower-turret',
|
||||
'silo',
|
||||
'spidertron'
|
||||
}
|
||||
|
||||
local sqrt = math.sqrt
|
||||
local random = math.random
|
||||
local remove = table.remove
|
||||
local speed = 0.06
|
||||
|
||||
--- Draws a new render.
|
||||
---@return integer
|
||||
function Public:new_render()
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
self.render_id = rendering.draw_sprite {target = self.position, sprite = self.sprite, surface = surface}
|
||||
end
|
||||
|
||||
--- Sets a new target for a given render.
|
||||
---@return table
|
||||
---@return table
|
||||
function Public:new_target()
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
local position
|
||||
local entities = surface.find_entities_filtered {type = target_entities}
|
||||
if entities and #entities > 0 then
|
||||
position = entities[random(#entities)].position
|
||||
end
|
||||
|
||||
local chunk = surface.get_random_chunk()
|
||||
local random_position = {x = (chunk.x + random()) * 32, y = (chunk.y + random()) * 32}
|
||||
|
||||
return position, random_position
|
||||
end
|
||||
|
||||
--- Subtracts the given positions
|
||||
---@return table|integer
|
||||
function Public:subtr()
|
||||
if not self.position and self.target_position then
|
||||
return 0
|
||||
end
|
||||
return {x = self.target_position.x - self.position.x, y = self.target_position.y - self.position.y}
|
||||
end
|
||||
|
||||
--- Sets the render scale.
|
||||
function Public:set_render_scalar_size()
|
||||
if not self.render_id then
|
||||
return self:validate()
|
||||
end
|
||||
|
||||
rendering.set_y_scale(self.render_id, 3.5) -- 1.5
|
||||
rendering.set_x_scale(self.render_id, 7) -- 2
|
||||
rendering.set_color(
|
||||
self.render_id,
|
||||
{
|
||||
r = 1,
|
||||
g = 0.7,
|
||||
b = 0.7
|
||||
}
|
||||
)
|
||||
end
|
||||
--- Gets a random position.
|
||||
---@return table
|
||||
function Public:random_position()
|
||||
return {x = self.position.x + (random() - 0.5) * 64, y = self.position.y + (random() - 0.5) * 64}
|
||||
end
|
||||
|
||||
--- Changes the position of a render.
|
||||
---@param max_abs number
|
||||
---@param value boolean
|
||||
---@return table|nil
|
||||
function Public:change_position(max_abs, value)
|
||||
if not self.position or not self.target_position then
|
||||
return
|
||||
end
|
||||
local scalar = 0.9
|
||||
local subtr = self:subtr()
|
||||
if value then
|
||||
subtr.y = subtr.y / scalar
|
||||
end
|
||||
local multiply = sqrt(subtr.x * subtr.x + subtr.y * subtr.y)
|
||||
if (multiply > max_abs) then
|
||||
local close = max_abs / multiply
|
||||
subtr = {x = subtr.x * close, y = subtr.y * close}
|
||||
end
|
||||
if value then
|
||||
subtr.y = subtr.y * scalar
|
||||
end
|
||||
return {x = self.position.x + subtr.x, y = self.position.y + subtr.y}
|
||||
end
|
||||
|
||||
--- If a render is stuck, give it a new position.
|
||||
function Public:switch_position()
|
||||
if random() < 0.4 then
|
||||
self.target_position = self:random_position()
|
||||
else
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
local chunk = surface.get_random_chunk()
|
||||
self.target_position = {x = (chunk.x + math.random()) * 32, y = (chunk.y + math.random()) * 32}
|
||||
end
|
||||
end
|
||||
|
||||
--- Notifies for a new render
|
||||
function Public:notify_new_beam()
|
||||
if not self.notify then
|
||||
self.notify = true
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
game.print('[Orbital] A new orbital strike has been spotted at: [gps=' .. self.position.x .. ',' .. self.position.y .. ',' .. surface.name .. ']')
|
||||
end
|
||||
end
|
||||
|
||||
--- Renders a new chart
|
||||
function Public:render_chart()
|
||||
if self.chart then
|
||||
self.chart.destroy()
|
||||
end
|
||||
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
self.chart =
|
||||
game.forces[self.force].add_chart_tag(
|
||||
surface,
|
||||
{
|
||||
icon = {type = 'virtual', name = 'signal-info'},
|
||||
position = self.position,
|
||||
text = 'Beam'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
--- Sets a new position for a render.
|
||||
function Public:set_new_position()
|
||||
self.position = self:change_position(speed, false)
|
||||
|
||||
if not self.random_pos_set then
|
||||
self.random_pos_set = true
|
||||
self.random_pos_tick = game.tick + 300
|
||||
end
|
||||
if self.position.x == self.target_position.x and self.position.y == self.target_position.y then
|
||||
self:switch_position()
|
||||
end
|
||||
|
||||
if self:validate() then
|
||||
rendering.set_target(self.render_id, self.position)
|
||||
self:set_render_scalar_size()
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates fire flame.
|
||||
function Public:render_fire_damage()
|
||||
if random(1, 15) == 1 then
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
surface.create_entity({name = 'fire-flame', position = {x = self.position.x, y = self.position.y + 5}})
|
||||
if random(1, 5) == 1 then
|
||||
surface.create_entity({name = 'medium-scorchmark', position = {x = self.position.x, y = self.position.y + 5}, force = 'neutral'})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Damages entities nearby.
|
||||
function Public:damage_entities_nearby()
|
||||
if random(1, 3) == 1 then
|
||||
local surface = game.get_surface(self.surface_id)
|
||||
local damage = random(10, 15)
|
||||
local entities = surface.find_entities_filtered({position = self.position, radius = 20, type = 'simple-entity', invert = true})
|
||||
for _, entity in pairs(entities) do
|
||||
if entity.valid then
|
||||
if entity.health then
|
||||
if entity.force.name ~= 'enemy' then
|
||||
entity.damage(damage, 'enemy')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Validates if a render is valid.
|
||||
---@return boolean|integer
|
||||
function Public:validate()
|
||||
if not self.render_id then
|
||||
return self:new_render()
|
||||
end
|
||||
if rendering.is_valid(self.render_id) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Destroys a render.
|
||||
function Public:destroy_render()
|
||||
if rendering.is_valid(self.render_id) then
|
||||
rendering.destroy(self.render_id)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Destroys a render.
|
||||
function Public:destroy_chart()
|
||||
if self.chart then
|
||||
self.chart.destroy()
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a render.
|
||||
function Public:remove_render()
|
||||
self:destroy_render()
|
||||
self:destroy_chart()
|
||||
|
||||
remove(this.renders, self.id)
|
||||
return self
|
||||
end
|
||||
|
||||
function Public:work(tick)
|
||||
if tick < self.ttl then
|
||||
self:render_chart()
|
||||
self:notify_new_beam()
|
||||
self:set_new_position()
|
||||
self:render_fire_damage()
|
||||
self:damage_entities_nearby()
|
||||
if self.random_pos_set and tick > self.random_pos_tick then
|
||||
self:switch_position()
|
||||
self.random_pos_set = nil
|
||||
self.random_pos_tick = nil
|
||||
end
|
||||
else
|
||||
self:remove_render()
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a new render.
|
||||
---@param sprite string
|
||||
---@param surface userdata
|
||||
---@param ttl integer|nil
|
||||
---@param scalar table|nil
|
||||
---@param delayed number|nil
|
||||
---@return table
|
||||
function Public.new(sprite, surface, ttl, scalar, delayed)
|
||||
local render = setmetatable({}, Public.metatable)
|
||||
render.surface_id = surface.index
|
||||
local position, random_position = render:new_target()
|
||||
render.position = position
|
||||
render.sprite = sprite
|
||||
render.force = 'player'
|
||||
render.target_position = random_position
|
||||
render.id = #this.renders + 1
|
||||
if delayed then
|
||||
render.delayed = game.tick + delayed
|
||||
render.ttl = ttl or (game.tick + delayed) + 7200 -- 2 minutes duration
|
||||
else
|
||||
render.ttl = ttl or game.tick + 7200 -- 2 minutes duration
|
||||
render:validate()
|
||||
if not scalar then
|
||||
render:set_render_scalar_size()
|
||||
end
|
||||
end
|
||||
render.ttl = ttl or game.tick + 7200 -- 2 minutes duration
|
||||
|
||||
this.renders[render.id] = render
|
||||
|
||||
return render
|
||||
end
|
||||
|
||||
--- Creates a new defined beam
|
||||
---@param surface userdata
|
||||
function Public.new_beam(surface)
|
||||
Public.new(Gui.beam, surface)
|
||||
end
|
||||
|
||||
--- Creates a new defined beam with a delayed action
|
||||
---@param surface userdata
|
||||
---@param time number
|
||||
function Public.new_beam_delayed(surface, time)
|
||||
Public.new(Gui.beam, surface, nil, nil, time)
|
||||
end
|
||||
|
||||
Event.add(
|
||||
defines.events.on_tick,
|
||||
function()
|
||||
if #this.renders == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local tick = game.tick
|
||||
|
||||
for id = 1, #this.renders, 1 do
|
||||
local render = this.renders[id]
|
||||
if render then
|
||||
if render.delayed then
|
||||
if tick > render.delayed then
|
||||
render:work(tick)
|
||||
end
|
||||
else
|
||||
render:work(tick)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
if _DEBUG then
|
||||
commands.add_command(
|
||||
'laser',
|
||||
'new laser',
|
||||
function()
|
||||
local player = game.player
|
||||
if player and player.valid then
|
||||
if not player.admin then
|
||||
return
|
||||
end
|
||||
|
||||
Public.new_beam_delayed(player.surface, 222)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
return Public
|
@ -226,4 +226,42 @@ if _DEBUG then
|
||||
)
|
||||
end
|
||||
|
||||
local RPG_Interface = {
|
||||
rpg_reset_player = function(player_name)
|
||||
if player_name then
|
||||
local player = game.get_player(player_name)
|
||||
if player and player.valid then
|
||||
return Public.rpg_reset_player(player)
|
||||
else
|
||||
error('Remote call parameter to RPG rpg_reset_player must be a valid player name and not nil.')
|
||||
end
|
||||
else
|
||||
error('Remote call parameter to RPG rpg_reset_player must be a valid player name and not nil.')
|
||||
end
|
||||
end,
|
||||
give_xp = function(amount)
|
||||
if type(amount) == 'number' then
|
||||
return Public.give_xp(amount)
|
||||
else
|
||||
error('Remote call parameter to RPG give_xp must be number and not nil.')
|
||||
end
|
||||
end,
|
||||
gain_xp = function(player_name, amount)
|
||||
if player_name then
|
||||
local player = game.get_player(player_name)
|
||||
if player and player.valid and type(amount) == 'number' then
|
||||
return Public.gain_xp(player, amount)
|
||||
else
|
||||
error('Remote call parameter to RPG give_xp must be a valid player name and contain amount(number) and not nil.')
|
||||
end
|
||||
else
|
||||
error('Remote call parameter to RPG give_xp must be a valid player name and contain amount(number) and not nil.')
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
if not remote.interfaces['RPG'] then
|
||||
remote.add_interface('RPG', RPG_Interface)
|
||||
end
|
||||
|
||||
return Public
|
||||
|
@ -19,6 +19,7 @@ local round = math.round
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
local sub = string.sub
|
||||
|
||||
--RPG Frames
|
||||
local main_frame_name = Public.main_frame_name
|
||||
@ -444,7 +445,7 @@ function Public.remove_mana(player, mana_to_remove)
|
||||
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
|
||||
if data and data.mana and data.mana.valid then
|
||||
data.mana.caption = rpg_t.mana
|
||||
end
|
||||
end
|
||||
@ -483,7 +484,7 @@ function Public.update_mana(player)
|
||||
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
|
||||
if data and data.mana and data.mana.valid then
|
||||
data.mana.caption = rpg_t.mana
|
||||
end
|
||||
end
|
||||
@ -542,7 +543,7 @@ function Public.reward_mana(player, mana_to_add)
|
||||
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
|
||||
if data and data.mana and data.mana.valid then
|
||||
data.mana.caption = rpg_t.mana
|
||||
end
|
||||
end
|
||||
@ -589,7 +590,7 @@ function Public.update_health(player)
|
||||
if player.gui.screen[main_frame_name] then
|
||||
local f = player.gui.screen[main_frame_name]
|
||||
local data = Gui.get_data(f)
|
||||
if data.health and data.health.valid then
|
||||
if data and data.health and data.health.valid then
|
||||
data.health.caption = (round(player.character.health * 10) / 10)
|
||||
end
|
||||
local shield_gui = player.character.get_inventory(defines.inventory.character_armor)
|
||||
@ -597,10 +598,10 @@ function Public.update_health(player)
|
||||
if shield_gui[1].grid then
|
||||
local shield = math.floor(shield_gui[1].grid.shield)
|
||||
local shield_max = math.floor(shield_gui[1].grid.max_shield)
|
||||
if data.shield and data.shield.valid then
|
||||
if data and data.shield and data.shield.valid then
|
||||
data.shield.caption = shield
|
||||
end
|
||||
if data.shield_max and data.shield_max.valid then
|
||||
if data and data.shield_max and data.shield_max.valid then
|
||||
data.shield_max.caption = shield_max
|
||||
end
|
||||
end
|
||||
@ -993,6 +994,36 @@ function Public.give_xp(amount)
|
||||
end
|
||||
end
|
||||
|
||||
-- Checks if the player is on the correct surface.
|
||||
function Public.check_is_surface_valid(player)
|
||||
if is_game_modded() then
|
||||
return true
|
||||
end
|
||||
|
||||
local is_surface_valid = false
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if type(surface_name) == 'table' then
|
||||
for _, tbl_surface in pairs(surface_name) do
|
||||
if sub(player.surface.name, 0, #surface_name) == tbl_surface then
|
||||
is_surface_valid = true
|
||||
end
|
||||
end
|
||||
else
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if not is_surface_valid then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.rpg_reset_player(player, one_time_reset)
|
||||
if not player.character then
|
||||
player.set_controller({type = defines.controllers.god})
|
||||
|
@ -30,33 +30,66 @@ local spell1_button_name = Public.spell1_button_name
|
||||
local spell2_button_name = Public.spell2_button_name
|
||||
local spell3_button_name = Public.spell3_button_name
|
||||
|
||||
local sub = string.sub
|
||||
local round = math.round
|
||||
local floor = math.floor
|
||||
|
||||
function Public.draw_gui_char_button(player)
|
||||
if player.gui.top[draw_main_frame_name] then
|
||||
return
|
||||
if ComfyGui.get_mod_gui_top_frame() then
|
||||
local b =
|
||||
ComfyGui.add_mod_button(
|
||||
player,
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = draw_main_frame_name,
|
||||
caption = '[RPG]',
|
||||
tooltip = 'RPG'
|
||||
}
|
||||
)
|
||||
if b then
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
b.style.minimal_width = 50
|
||||
b.style.padding = 0
|
||||
b.style.margin = 0
|
||||
end
|
||||
else
|
||||
if player.gui.top[draw_main_frame_name] then
|
||||
return
|
||||
end
|
||||
local b = player.gui.top.add({type = 'sprite-button', name = draw_main_frame_name, caption = '[RPG]', tooltip = 'RPG'})
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
b.style.minimal_width = 50
|
||||
b.style.padding = 0
|
||||
b.style.margin = 0
|
||||
end
|
||||
local b = player.gui.top.add({type = 'sprite-button', name = draw_main_frame_name, caption = '[RPG]', tooltip = 'RPG'})
|
||||
b.style.font_color = {165, 165, 165}
|
||||
b.style.font = 'heading-3'
|
||||
b.style.minimal_height = 38
|
||||
b.style.maximal_height = 38
|
||||
b.style.minimal_width = 50
|
||||
b.style.padding = 0
|
||||
b.style.margin = 0
|
||||
end
|
||||
|
||||
function Public.update_char_button(player)
|
||||
local rpg_t = Public.get_value_from_player(player.index)
|
||||
if not player.gui.top[draw_main_frame_name] then
|
||||
Public.draw_gui_char_button(player)
|
||||
end
|
||||
if rpg_t.points_left > 0 then
|
||||
player.gui.top[draw_main_frame_name].style.font_color = {245, 0, 0}
|
||||
|
||||
if ComfyGui.get_mod_gui_top_frame() then
|
||||
if not ComfyGui.get_button_flow(player)[draw_main_frame_name] or not ComfyGui.get_button_flow(player)[draw_main_frame_name].valid then
|
||||
Public.draw_gui_char_button(player)
|
||||
end
|
||||
if rpg_t.points_left > 0 then
|
||||
ComfyGui.get_button_flow(player)[draw_main_frame_name].style.font_color = {245, 0, 0}
|
||||
else
|
||||
ComfyGui.get_button_flow(player)[draw_main_frame_name].style.font_color = {175, 175, 175}
|
||||
end
|
||||
else
|
||||
player.gui.top[draw_main_frame_name].style.font_color = {175, 175, 175}
|
||||
if not player.gui.top[draw_main_frame_name] then
|
||||
Public.draw_gui_char_button(player)
|
||||
end
|
||||
if rpg_t.points_left > 0 then
|
||||
player.gui.top[draw_main_frame_name].style.font_color = {245, 0, 0}
|
||||
else
|
||||
player.gui.top[draw_main_frame_name].style.font_color = {175, 175, 175}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -162,7 +195,11 @@ local function draw_main_frame(player, location)
|
||||
if location then
|
||||
main_frame.location = location
|
||||
else
|
||||
main_frame.location = {x = 1, y = 40}
|
||||
if ComfyGui.get_mod_gui_top_frame() then
|
||||
main_frame.location = {x = 1, y = 55}
|
||||
else
|
||||
main_frame.location = {x = 1, y = 45}
|
||||
end
|
||||
end
|
||||
|
||||
local data = {}
|
||||
@ -715,8 +752,7 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -742,8 +778,7 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -808,8 +843,7 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -836,8 +870,7 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -861,8 +894,7 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -886,8 +918,7 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -19,7 +19,6 @@ local nth_tick = Public.nth_tick
|
||||
--RPG Frames
|
||||
local main_frame_name = Public.main_frame_name
|
||||
|
||||
local sub = string.sub
|
||||
local round = math.round
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
@ -48,8 +47,7 @@ local function on_gui_click(event)
|
||||
end
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -459,8 +457,7 @@ local function on_entity_damaged(event)
|
||||
|
||||
local p = cause.player
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(p.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(p) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -670,8 +667,7 @@ local function on_pre_player_mined_item(event)
|
||||
return
|
||||
end
|
||||
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -851,7 +847,6 @@ end
|
||||
|
||||
local function on_player_used_capsule(event)
|
||||
local enable_mana = Public.get('rpg_extra').enable_mana
|
||||
local surface_name = Public.get('rpg_extra').surface_name
|
||||
if not enable_mana then
|
||||
return
|
||||
end
|
||||
@ -868,7 +863,7 @@ local function on_player_used_capsule(event)
|
||||
return
|
||||
end
|
||||
|
||||
if sub(player.surface.name, 0, #surface_name) ~= surface_name then
|
||||
if not Public.check_is_surface_valid(player) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -915,12 +910,12 @@ local function on_player_used_capsule(event)
|
||||
right_bottom = {x = position.x + radius, y = position.y + radius}
|
||||
}
|
||||
|
||||
if rpg_t.level < spell.level then
|
||||
if not spell.enabled then
|
||||
return Public.cast_spell(player, true)
|
||||
end
|
||||
|
||||
if not spell.enabled then
|
||||
return
|
||||
if rpg_t.level < spell.level then
|
||||
return Public.cast_spell(player, true)
|
||||
end
|
||||
|
||||
if not Math2D.bounding_box.contains_point(area, player.position) then
|
||||
|
@ -28,7 +28,7 @@ local function get_comparator(sort_by)
|
||||
return comparators[sort_by]
|
||||
end
|
||||
|
||||
local function create_input_element(frame, type, value, items, index)
|
||||
local function create_input_element(frame, type, value, items, index, tooltip)
|
||||
if type == 'slider' then
|
||||
return frame.add({type = 'slider', value = value, minimum_value = 0, maximum_value = 1})
|
||||
end
|
||||
@ -38,6 +38,7 @@ local function create_input_element(frame, type, value, items, index)
|
||||
if type == 'label' then
|
||||
local label = frame.add({type = 'label', caption = value})
|
||||
label.style.font = 'default-listbox'
|
||||
label.tooltip = tooltip or ''
|
||||
return label
|
||||
end
|
||||
if type == 'dropdown' then
|
||||
@ -46,7 +47,7 @@ local function create_input_element(frame, type, value, items, index)
|
||||
return frame.add({type = 'text-box', text = value})
|
||||
end
|
||||
|
||||
local function create_custom_label_element(frame, sprite, localised_string, value)
|
||||
local function create_custom_label_element(frame, sprite, localised_string, value, tooltip)
|
||||
local t = frame.add({type = 'flow'})
|
||||
t.add({type = 'label', caption = '[' .. sprite .. ']'})
|
||||
local heading = t.add({type = 'label', caption = localised_string})
|
||||
@ -54,6 +55,8 @@ local function create_custom_label_element(frame, sprite, localised_string, valu
|
||||
local subheading = t.add({type = 'label', caption = value})
|
||||
subheading.style.font = 'default-listbox'
|
||||
|
||||
t.tooltip = tooltip or ''
|
||||
|
||||
return subheading
|
||||
end
|
||||
|
||||
@ -710,13 +713,15 @@ function Public.settings_tooltip(player)
|
||||
table.sort(spells, comparator)
|
||||
|
||||
for _, entity in pairs(spells) do
|
||||
local cooldown = (entity.cooldown / 60) .. 's'
|
||||
if entity.type == 'item' then
|
||||
local text = '[item=' .. entity.entityName .. '] ▪️ Level: [font=default-bold]' .. entity.level .. '[/font] Mana: [font=default-bold]' .. entity.mana_cost .. '[/font]. Cooldown: [font=default-bold]' .. cooldown .. '[/font]'
|
||||
create_input_element(normal_spell_grid, 'label', text)
|
||||
elseif entity.type == 'entity' then
|
||||
local text = '[entity=' .. entity.entityName .. '] ▪️ Level: [font=default-bold]' .. entity.level .. '[/font] Mana: [font=default-bold]' .. entity.mana_cost .. '[/font]. Cooldown: [font=default-bold]' .. cooldown .. '[/font]'
|
||||
create_input_element(normal_spell_grid, 'label', text)
|
||||
if entity.enabled then
|
||||
local cooldown = (entity.cooldown / 60) .. 's'
|
||||
if entity.type == 'item' then
|
||||
local text = '[item=' .. entity.entityName .. '] ▪️ Level: [font=default-bold]' .. entity.level .. '[/font] Mana: [font=default-bold]' .. entity.mana_cost .. '[/font]. Cooldown: [font=default-bold]' .. cooldown .. '[/font]'
|
||||
create_input_element(normal_spell_grid, 'label', text, nil, nil, entity.tooltip)
|
||||
elseif entity.type == 'entity' then
|
||||
local text = '[entity=' .. entity.entityName .. '] ▪️ Level: [font=default-bold]' .. entity.level .. '[/font] Mana: [font=default-bold]' .. entity.mana_cost .. '[/font]. Cooldown: [font=default-bold]' .. cooldown .. '[/font]'
|
||||
create_input_element(normal_spell_grid, 'label', text, nil, nil, entity.tooltip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -741,10 +746,12 @@ function Public.settings_tooltip(player)
|
||||
local special_spell_grid = special_spell_pane.add({type = 'table', column_count = 1})
|
||||
|
||||
for _, entity in pairs(spells) do
|
||||
local cooldown = (entity.cooldown / 60) .. 's'
|
||||
if entity.type == 'special' then
|
||||
local text = '▪️ Level: [font=default-bold]' .. entity.level .. '[/font] Mana: [font=default-bold]' .. entity.mana_cost .. '[/font]. Cooldown: [font=default-bold]' .. cooldown .. '[/font]'
|
||||
create_custom_label_element(special_spell_grid, entity.special_sprite, entity.name, text)
|
||||
if entity.enabled then
|
||||
local cooldown = (entity.cooldown / 60) .. 's'
|
||||
if entity.type == 'special' then
|
||||
local text = '▪️ Level: [font=default-bold]' .. entity.level .. '[/font] Mana: [font=default-bold]' .. entity.mana_cost .. '[/font]. Cooldown: [font=default-bold]' .. cooldown .. '[/font]'
|
||||
create_custom_label_element(special_spell_grid, entity.special_sprite, entity.name, text, entity.tooltip)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,7 @@
|
||||
local Public = require 'modules.rpg.table'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Ai = require 'modules.ai'
|
||||
|
||||
local spells = {}
|
||||
local random = math.random
|
||||
@ -120,6 +121,7 @@ local function do_projectile(player_surface, name, _position, _force, target, ma
|
||||
create_build_effect_smoke = false
|
||||
}
|
||||
)
|
||||
return true
|
||||
end
|
||||
|
||||
local function create_projectiles(data)
|
||||
@ -168,6 +170,7 @@ local function create_projectiles(data)
|
||||
end
|
||||
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
|
||||
local function create_entity(data)
|
||||
@ -194,7 +197,7 @@ local function create_entity(data)
|
||||
local e = surface.create_entity({name = self.entityName, position = position, force = force})
|
||||
tame_unit_effects(player, e)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return
|
||||
return true
|
||||
end
|
||||
|
||||
if self.aoe then
|
||||
@ -226,6 +229,7 @@ local function create_entity(data)
|
||||
end
|
||||
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
|
||||
local function insert_onto(data)
|
||||
@ -235,6 +239,7 @@ local function insert_onto(data)
|
||||
player.insert({name = self.entityName, count = self.amount})
|
||||
Public.cast_spell(player)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return true
|
||||
end
|
||||
|
||||
spells[#spells + 1] = {
|
||||
@ -535,7 +540,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/shotgun-shell',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -553,7 +558,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/grenade',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -571,7 +576,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/cluster-grenade',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -589,7 +594,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/cannon-shell',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -607,7 +612,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/explosive-cannon-shell',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -625,7 +630,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/uranium-cannon-shell',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -644,7 +649,7 @@ spells[#spells + 1] = {
|
||||
log_spell = true,
|
||||
sprite = 'recipe/rocket',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -687,6 +692,7 @@ spells[#spells + 1] = {
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
end
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
end
|
||||
}
|
||||
@ -733,6 +739,7 @@ spells[#spells + 1] = {
|
||||
|
||||
Public.cast_spell(player)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return true
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -771,6 +778,7 @@ spells[#spells + 1] = {
|
||||
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -825,7 +833,7 @@ spells[#spells + 1] = {
|
||||
sprite = 'item/raw-fish',
|
||||
special_sprite = 'item=raw-fish',
|
||||
callback = function(data)
|
||||
insert_onto(data)
|
||||
return insert_onto(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -845,7 +853,7 @@ spells[#spells + 1] = {
|
||||
sprite = 'item/explosives',
|
||||
special_sprite = 'item=explosives',
|
||||
callback = function(data)
|
||||
insert_onto(data)
|
||||
return insert_onto(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -873,6 +881,7 @@ spells[#spells + 1] = {
|
||||
Public.suicidal_comfylatron(position, surface)
|
||||
Public.cast_spell(player)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return true
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -891,7 +900,7 @@ spells[#spells + 1] = {
|
||||
sprite = 'recipe/distractor-capsule',
|
||||
special_sprite = 'recipe=distractor-capsule',
|
||||
callback = function(data)
|
||||
create_projectiles(data)
|
||||
return create_projectiles(data)
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -922,6 +931,7 @@ spells[#spells + 1] = {
|
||||
Public.damage_player_over_time(player, random(8, 16))
|
||||
player.play_sound {path = 'utility/armor_insert', volume_modifier = 1}
|
||||
Public.cast_spell(player)
|
||||
return true
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -952,6 +962,7 @@ spells[#spells + 1] = {
|
||||
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)
|
||||
return true
|
||||
end
|
||||
}
|
||||
spells[#spells + 1] = {
|
||||
@ -1016,6 +1027,59 @@ spells[#spells + 1] = {
|
||||
|
||||
Public.cast_spell(player)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
spells[#spells + 1] = {
|
||||
name = {'spells.drone_enemy'},
|
||||
entityName = 'drone_enemy',
|
||||
target = false,
|
||||
force = 'player',
|
||||
level = 200,
|
||||
type = 'special',
|
||||
mana_cost = 1000,
|
||||
cooldown = 18000,
|
||||
enabled = false,
|
||||
enforce_cooldown = true,
|
||||
log_spell = true,
|
||||
sprite = 'virtual-signal/signal-info',
|
||||
special_sprite = 'virtual-signal=signal-info',
|
||||
tooltip = 'Creates a drone that searches for enemies and destroys them.',
|
||||
callback = function(data)
|
||||
local self = data.self
|
||||
local player = data.player
|
||||
Ai.create_char({player_index = player.index, command = 1, search_local = true})
|
||||
|
||||
Public.cast_spell(player)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
spells[#spells + 1] = {
|
||||
name = {'spells.drone_mine'},
|
||||
entityName = 'drone_mine',
|
||||
target = false,
|
||||
force = 'player',
|
||||
level = 200,
|
||||
type = 'special',
|
||||
mana_cost = 1000,
|
||||
cooldown = 18000,
|
||||
enabled = false,
|
||||
enforce_cooldown = true,
|
||||
log_spell = true,
|
||||
sprite = 'virtual-signal/signal-info',
|
||||
special_sprite = 'virtual-signal=signal-info',
|
||||
tooltip = 'Creates a drone mines entities around you.',
|
||||
callback = function(data)
|
||||
local self = data.self
|
||||
local player = data.player
|
||||
Ai.create_char({player_index = player.index, command = 2, search_local = false})
|
||||
|
||||
Public.cast_spell(player)
|
||||
Public.remove_mana(player, self.mana_cost)
|
||||
return true
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ Public.auto_allocate_nodes_func = {
|
||||
'Vitality'
|
||||
}
|
||||
|
||||
function Public.reset_table()
|
||||
function Public.reset_table(migrate)
|
||||
this.rpg_extra.debug = false
|
||||
this.rpg_extra.breached_walls = 1
|
||||
this.rpg_extra.reward_new_players = 0
|
||||
@ -127,7 +127,9 @@ function Public.reset_table()
|
||||
['pipe'] = true
|
||||
}
|
||||
this.tweaked_crafting_items_enabled = false
|
||||
this.rpg_t = {}
|
||||
if not migrate then
|
||||
this.rpg_t = {}
|
||||
end
|
||||
this.rpg_extra.rpg_xp_yield = {
|
||||
['behemoth-biter'] = 16,
|
||||
['behemoth-spitter'] = 16,
|
||||
@ -160,8 +162,8 @@ function Public.get(key)
|
||||
end
|
||||
|
||||
--- Gets value from player rpg_t table
|
||||
---@param key string
|
||||
---@param value string
|
||||
---@param key string|integer
|
||||
---@param value string|nil
|
||||
function Public.get_value_from_player(key, value)
|
||||
if key and value then
|
||||
if (this.rpg_t[key] and this.rpg_t[key][value]) then
|
||||
@ -180,8 +182,8 @@ end
|
||||
|
||||
--- Sets value to player rpg_t table
|
||||
---@param key string
|
||||
---@param value string
|
||||
---@param setter string
|
||||
---@param value string|boolean|number|nil
|
||||
---@param setter string|boolean|number|nil
|
||||
function Public.set_value_to_player(key, value, setter)
|
||||
if key and value then
|
||||
if (this.rpg_t[key] and this.rpg_t[key][value]) then
|
||||
@ -227,12 +229,8 @@ function Public.set(key)
|
||||
end
|
||||
|
||||
--- Toggle debug - when you need to troubleshoot.
|
||||
function Public.toggle_debug()
|
||||
if this.rpg_extra.debug then
|
||||
this.rpg_extra.debug = false
|
||||
else
|
||||
this.rpg_extra.debug = true
|
||||
end
|
||||
function Public.toggle_debug(value)
|
||||
this.rpg_extra.debug = value or false
|
||||
|
||||
return this.rpg_extra.debug
|
||||
end
|
||||
@ -278,6 +276,55 @@ function Public.enable_health_and_mana_bars(value)
|
||||
return this.rpg_extra.enable_health_and_mana_bars
|
||||
end
|
||||
|
||||
--- Toggles the mod gui state.
|
||||
---@param value boolean
|
||||
---@param read boolean
|
||||
function Public.enable_mod_gui(value, read)
|
||||
if not read then
|
||||
Gui.set_mod_gui_top_frame(value or false)
|
||||
end
|
||||
|
||||
if Gui.get_mod_gui_top_frame() then
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local top = player.gui.top
|
||||
if top.mod_gui_top_frame and top.mod_gui_top_frame.valid then
|
||||
top.mod_gui_top_frame.visible = true
|
||||
end
|
||||
for _, child in pairs(top.children) do
|
||||
if child.caption == '[RPG]' then
|
||||
child.destroy()
|
||||
Public.draw_gui_char_button(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local players = game.connected_players
|
||||
local count = 0
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local top = Gui.get_button_flow(player)
|
||||
for _, child in pairs(top.children) do
|
||||
count = count + 1
|
||||
if child.caption == '[RPG]' then
|
||||
child.destroy()
|
||||
Public.draw_gui_char_button(player)
|
||||
end
|
||||
end
|
||||
if count == 0 then
|
||||
if player.gui.top.mod_gui_top_frame and player.gui.top.mod_gui_top_frame.valid then
|
||||
player.gui.top.mod_gui_top_frame.visible = false
|
||||
end
|
||||
else
|
||||
if player.gui.top.mod_gui_top_frame and player.gui.top.mod_gui_top_frame.valid then
|
||||
player.gui.top.mod_gui_top_frame.visible = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Enables the mana feature that allows players to spawn entities.
|
||||
---@param value boolean
|
||||
function Public.enable_mana(value)
|
||||
@ -388,6 +435,44 @@ function Public.tweaked_crafting_items(tbl)
|
||||
return this.tweaked_crafting_items
|
||||
end
|
||||
|
||||
function Public.migrate_new_rpg_tbl(player)
|
||||
local rpg_t = Public.get_value_from_player(player.index, nil)
|
||||
if rpg_t then
|
||||
rpg_t.flame_boots = nil
|
||||
rpg_t.one_punch = nil
|
||||
rpg_t.points_left = rpg_t.points_to_distribute or 0
|
||||
rpg_t.points_to_distribute = nil
|
||||
|
||||
rpg_t.aoe_punch = false
|
||||
rpg_t.auto_toggle_features = {
|
||||
aoe_punch = false,
|
||||
stone_path = false
|
||||
}
|
||||
end
|
||||
|
||||
Public.enable_mod_gui(false, true)
|
||||
|
||||
local screen = player.gui.screen
|
||||
for _, child in pairs(screen.children) do
|
||||
if child.caption and child.caption[1] == 'rpg_settings.spell_name' then
|
||||
child.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.migrate_to_new_version()
|
||||
Public.reset_table(true)
|
||||
if this.rpg_spells then
|
||||
this.rpg_spells = nil
|
||||
end
|
||||
|
||||
local players = game.players
|
||||
|
||||
for _, player in pairs(players) do
|
||||
Public.migrate_new_rpg_tbl(player)
|
||||
end
|
||||
end
|
||||
|
||||
Public.settings_frame_name = settings_frame_name
|
||||
Public.settings_tooltip_frame = settings_tooltip_frame
|
||||
Public.close_settings_tooltip_frame = close_settings_tooltip_frame
|
||||
@ -411,4 +496,11 @@ end
|
||||
|
||||
Event.on_init(on_init)
|
||||
|
||||
Event.on_configuration_changed(
|
||||
function()
|
||||
print('[RPG] Migrating to new version')
|
||||
Public.migrate_to_new_version()
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
||||
|
@ -12,6 +12,7 @@ Global.register(
|
||||
end
|
||||
)
|
||||
|
||||
local round = math.round
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
@ -66,6 +67,7 @@ local function spawn_biters(data)
|
||||
return
|
||||
end
|
||||
end
|
||||
Public.wave_defense_set_unit_raffle(h * 0.20)
|
||||
|
||||
local unit_to_create
|
||||
|
||||
@ -78,14 +80,18 @@ local function spawn_biters(data)
|
||||
local modified_unit_health = Public.get('modified_unit_health')
|
||||
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
|
||||
|
||||
Public.wave_defense_set_unit_raffle(h * 0.20)
|
||||
local unit_settings = Public.get('unit_settings')
|
||||
|
||||
local unit = surface.create_entity({name = unit_to_create, position = position})
|
||||
|
||||
if random(1, 30) == 1 then
|
||||
BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
|
||||
else
|
||||
BiterHealthBooster.add_unit(unit, modified_unit_health.current_value * 2)
|
||||
local final_health = round(modified_unit_health.current_value * unit_settings.scale_units_by_health[unit.name], 3)
|
||||
if final_health < 1 then
|
||||
final_health = 1
|
||||
end
|
||||
BiterHealthBooster.add_unit(unit, final_health)
|
||||
end
|
||||
end
|
||||
|
||||
@ -100,11 +106,16 @@ local function spawn_worms(data)
|
||||
local unit_to_create = Public.wave_defense_roll_worm_name(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
|
||||
|
||||
local unit = surface.create_entity({name = unit_to_create, position = position})
|
||||
local worm_unit_settings = Public.get('worm_unit_settings')
|
||||
|
||||
if random(1, 30) == 1 then
|
||||
BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
|
||||
else
|
||||
BiterHealthBooster.add_unit(unit, modified_unit_health.current_value * 2)
|
||||
local final_health = round(modified_unit_health.current_value * worm_unit_settings.scale_units_by_health[unit.name], 3)
|
||||
if final_health < 1 then
|
||||
final_health = 1
|
||||
end
|
||||
BiterHealthBooster.add_unit(unit, final_health)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -29,6 +29,13 @@ commands.add_command(
|
||||
return Public.spawn_unit_group(true, true)
|
||||
end
|
||||
|
||||
if param == 'set_wave_1500' then
|
||||
for _ = 1, 1500 do
|
||||
Public.set_next_wave()
|
||||
end
|
||||
return Public.spawn_unit_group(true, true)
|
||||
end
|
||||
|
||||
if param == 'log_all' then
|
||||
return Public.toggle_debug()
|
||||
end
|
||||
|
@ -3,6 +3,7 @@ local Event = require 'utils.event'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local Difficulty = require 'modules.difficulty_vote_by_amount'
|
||||
local Alert = require 'utils.alert'
|
||||
local Server = require 'utils.server'
|
||||
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
@ -535,7 +536,7 @@ local function increase_biter_damage()
|
||||
end
|
||||
|
||||
local e = game.forces.enemy
|
||||
local new = Difficulty.get().difficulty_vote_value * 0.04
|
||||
local new = Difficulty.get('value') * 0.04
|
||||
local melee = new
|
||||
local bio = new - 0.02
|
||||
local e_old_melee = e.get_ammo_damage_modifier('melee')
|
||||
@ -618,6 +619,12 @@ local function set_next_wave()
|
||||
end
|
||||
end
|
||||
|
||||
local log_wave_to_discord = Public.get('log_wave_to_discord')
|
||||
|
||||
if wave_number % 100 == 0 and log_wave_to_discord then
|
||||
Server.to_discord_embed('Current wave: ' .. wave_number)
|
||||
end
|
||||
|
||||
local threat = Public.get('threat')
|
||||
Public.set('threat', threat + floor(threat_gain))
|
||||
|
||||
|
@ -50,6 +50,7 @@ function Public.reset_wave_defense()
|
||||
this.biter_raffle = {}
|
||||
this.debug = false
|
||||
this.debug_health = false
|
||||
this.log_wave_to_discord = true
|
||||
this.paused = false
|
||||
this.game_lost = false
|
||||
this.get_random_close_spawner_attempts = 5
|
||||
@ -135,6 +136,10 @@ function Public.reset_wave_defense()
|
||||
this.worm_unit_settings = {
|
||||
-- note that final health modifier isn't lower than 1
|
||||
scale_units_by_health = {
|
||||
['land-mine'] = 0.5, -- not active as of now
|
||||
['gun-turret'] = 0.5, -- not active as of now
|
||||
['flamethrower-turret'] = 0.4, -- not active as of now
|
||||
['artillery-turret'] = 0.25, -- not active as of now
|
||||
['small-worm-turret'] = 0.8,
|
||||
['medium-worm-turret'] = 0.6,
|
||||
['big-worm-turret'] = 0.4,
|
||||
|
@ -231,7 +231,7 @@ end
|
||||
---Message all players at a given location
|
||||
---@param player LuaPlayer
|
||||
---@param message string
|
||||
---@param color string
|
||||
---@param color string|nil
|
||||
function Public.alert_all_players_location(player, message, color, duration)
|
||||
local length = duration or 15
|
||||
Public.alert_all_players_template(
|
||||
@ -264,7 +264,7 @@ end
|
||||
---@param player LuaPlayer
|
||||
---@param duration number
|
||||
---@param message string
|
||||
---@param color string
|
||||
---@param color string|nil
|
||||
function Public.alert_player(player, duration, message, color, sprite, volume)
|
||||
Public.alert_player_template(
|
||||
player,
|
||||
@ -321,7 +321,7 @@ end
|
||||
---Message to all players
|
||||
---@param duration number
|
||||
---@param message string
|
||||
---@param color string
|
||||
---@param color string|nil
|
||||
function Public.alert_all_players(duration, message, color, sprite, volume)
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
|
@ -10,16 +10,19 @@ local Color = require 'utils.color_presets'
|
||||
local Server = require 'utils.server'
|
||||
local Jail = require 'utils.datastore.jail_data'
|
||||
local FancyTime = require 'tools.fancy_time'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
|
||||
local Public = {}
|
||||
local match = string.match
|
||||
local capsule_bomb_threshold = 8
|
||||
local de = defines.events
|
||||
|
||||
local sub = string.sub
|
||||
local format = string.format
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
local max_count_decon = 500
|
||||
|
||||
local this = {
|
||||
enabled = true,
|
||||
@ -31,6 +34,7 @@ local this = {
|
||||
corpse_history = {},
|
||||
message_history = {},
|
||||
cancel_crafting_history = {},
|
||||
deconstruct_history = {},
|
||||
whitelist_types = {},
|
||||
permission_group_editing = {},
|
||||
players_warned = {},
|
||||
@ -45,6 +49,11 @@ local this = {
|
||||
required_playtime = 2592000,
|
||||
damage_entity_threshold = 20,
|
||||
explosive_threshold = 16,
|
||||
enable_jail_when_decon = true,
|
||||
filtered_types_on_decon = {},
|
||||
decon_surface_blacklist = 'nauvis',
|
||||
players_warn_when_decon = {},
|
||||
on_cancelled_deconstruction = {tick = 0, count = 0},
|
||||
limit = 2000
|
||||
}
|
||||
|
||||
@ -75,6 +84,17 @@ local chests = {
|
||||
['logistic-container'] = true
|
||||
}
|
||||
|
||||
-- Clears the player from players_warn_when_decon tbl.
|
||||
local clear_player_decon_warnings =
|
||||
Token.register(
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
if this.players_warn_when_decon[player_index] then
|
||||
this.players_warn_when_decon[player_index] = nil
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(t)
|
||||
@ -187,7 +207,7 @@ local function on_marked_for_deconstruction(event)
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if Session.get_trusted_player(player.name) or this.do_not_check_trusted then
|
||||
if Session.get_trusted_player(player) or this.do_not_check_trusted then
|
||||
return
|
||||
end
|
||||
|
||||
@ -210,7 +230,7 @@ local function on_player_ammo_inventory_changed(event)
|
||||
if player.admin then
|
||||
return
|
||||
end
|
||||
if Session.get_trusted_player(player.name) or this.do_not_check_trusted then
|
||||
if Session.get_trusted_player(player) or this.do_not_check_trusted then
|
||||
return
|
||||
end
|
||||
|
||||
@ -232,7 +252,7 @@ end
|
||||
local function on_player_joined_game(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not this.enabled then
|
||||
if not Session.get_trusted_player(player.name) then
|
||||
if not Session.get_trusted_player(player) then
|
||||
Session.set_trusted_player(player.name)
|
||||
end
|
||||
return
|
||||
@ -289,7 +309,7 @@ local function on_built_entity(event)
|
||||
if player.admin then
|
||||
return
|
||||
end
|
||||
if Session.get_trusted_player(player.name) or this.do_not_check_trusted then
|
||||
if Session.get_trusted_player(player) or this.do_not_check_trusted then
|
||||
return
|
||||
end
|
||||
|
||||
@ -313,7 +333,7 @@ local function on_player_used_capsule(event)
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
|
||||
if Session.get_trusted_player(player.name) or this.do_not_check_trusted then
|
||||
if this.do_not_check_trusted then
|
||||
return
|
||||
end
|
||||
|
||||
@ -678,7 +698,7 @@ local function on_player_cursor_stack_changed(event)
|
||||
if player.admin then
|
||||
return
|
||||
end
|
||||
if Session.get_trusted_player(player.name) or this.do_not_check_trusted then
|
||||
if Session.get_trusted_player(player) or this.do_not_check_trusted then
|
||||
return
|
||||
end
|
||||
|
||||
@ -762,7 +782,6 @@ local function on_init()
|
||||
return
|
||||
end
|
||||
local branch_version = '0.18.35'
|
||||
local sub = string.sub
|
||||
local is_branch_18 = sub(branch_version, 3, 4)
|
||||
local get_active_version = sub(game.active_mods.base, 3, 4)
|
||||
local default = game.permissions.get_group('Default')
|
||||
@ -809,6 +828,136 @@ local function on_permission_group_deleted(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_deconstructed_area(event)
|
||||
if not this.enabled then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
|
||||
local surface_name = this.decon_surface_blacklist
|
||||
if sub(surface.name, 0, #surface_name) ~= surface_name then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
local area = event.area
|
||||
local count = surface.count_entities_filtered({area = area, type = 'resource', invert = true})
|
||||
local max_count = 0
|
||||
local is_trusted = Session.get_trusted_player(player)
|
||||
if is_trusted then
|
||||
max_count = max_count_decon
|
||||
end
|
||||
|
||||
if next(this.filtered_types_on_decon) then
|
||||
local filtered_count = surface.count_entities_filtered({area = area, type = this.filtered_types_on_decon})
|
||||
if filtered_count and filtered_count > 0 then
|
||||
surface.cancel_deconstruct_area {
|
||||
area = area,
|
||||
force = player.force
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if count and count >= max_count then
|
||||
surface.cancel_deconstruct_area {
|
||||
area = area,
|
||||
force = player.force
|
||||
}
|
||||
if not is_trusted then
|
||||
return
|
||||
end
|
||||
|
||||
local msg = '[Deconstruct] ' .. player.name .. ' tried to deconstruct: ' .. count .. ' entities!'
|
||||
Utils.print_to(nil, msg)
|
||||
Server.to_discord_embed(msg)
|
||||
|
||||
if not this.deconstruct_history then
|
||||
this.deconstruct_history = {}
|
||||
end
|
||||
if #this.deconstruct_history > this.limit then
|
||||
overflow(this.deconstruct_history)
|
||||
end
|
||||
|
||||
local t = abs(floor((game.tick) / 60))
|
||||
t = FancyTime.short_fancy_time(t)
|
||||
local str = '[' .. t .. '] '
|
||||
str = str .. msg
|
||||
str = str .. ' at lt_x:'
|
||||
str = str .. floor(area.left_top.x)
|
||||
str = str .. ' at lt_y:'
|
||||
str = str .. floor(area.left_top.y)
|
||||
str = str .. ' at rb_x:'
|
||||
str = str .. floor(area.right_bottom.x)
|
||||
str = str .. ' at rb_y:'
|
||||
str = str .. floor(area.right_bottom.y)
|
||||
str = str .. ' '
|
||||
str = str .. 'surface:' .. player.surface.index
|
||||
increment(this.deconstruct_history, str)
|
||||
|
||||
if this.enable_jail_when_decon and not player.admin then
|
||||
if not this.players_warn_when_decon[player.index] then
|
||||
this.players_warn_when_decon[player.index] = 1
|
||||
local r = random(7200, 18000)
|
||||
Task.set_timeout_in_ticks(r, clear_player_decon_warnings, {player_index = player.index})
|
||||
end
|
||||
local warnings = this.players_warn_when_decon[player.index]
|
||||
if warnings then
|
||||
if warnings == 1 or warnings == 2 then
|
||||
Utils.print_to(player, '[Deconstruct] Warning! Do not deconstruct that many entities at once!')
|
||||
this.players_warn_when_decon[player.index] = this.players_warn_when_decon[player.index] + 1
|
||||
elseif warnings == 3 then
|
||||
Utils.print_to(player, '[Deconstruct] Warning! Do not deconstruct that many entities at once! This is your final warning!')
|
||||
this.players_warn_when_decon[player.index] = this.players_warn_when_decon[player.index] + 1
|
||||
else
|
||||
Jail.try_ul_data(player, true, 'script', 'Deconstructed ' .. count .. ' entities. Has been warned 3 times before getting jailed.')
|
||||
this.players_warn_when_decon[player.index] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_cancelled_deconstruction(event)
|
||||
local player_index = event.player_index
|
||||
if player_index then
|
||||
return
|
||||
end
|
||||
|
||||
local tick = event.tick
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local handler = this.on_cancelled_deconstruction
|
||||
|
||||
if tick ~= handler.tick then
|
||||
handler.tick = tick
|
||||
handler.count = 0
|
||||
end
|
||||
|
||||
handler.count = handler.count + 1
|
||||
|
||||
local player = entity.last_user
|
||||
if player and player.valid and player.connected then
|
||||
local is_trusted = Session.get_trusted_player(player)
|
||||
if not is_trusted then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if entity.force.name == 'neutral' then
|
||||
return
|
||||
end
|
||||
|
||||
if tick == handler.tick and handler.count >= max_count_decon then
|
||||
return
|
||||
end
|
||||
|
||||
entity.order_deconstruction(entity.force)
|
||||
end
|
||||
|
||||
local function on_permission_group_edited(event)
|
||||
if not this.enabled then
|
||||
return
|
||||
@ -891,7 +1040,7 @@ end
|
||||
|
||||
--- Add entity type to the whitelist so it gets logged.
|
||||
---@param key string
|
||||
---@param value string
|
||||
---@param value string|boolean
|
||||
function Public.whitelist_types(key, value)
|
||||
if key and value then
|
||||
this.whitelist_types[key] = value
|
||||
@ -901,35 +1050,49 @@ function Public.whitelist_types(key, value)
|
||||
end
|
||||
|
||||
--- If the event should also check trusted players.
|
||||
---@param value string
|
||||
---@param value boolean
|
||||
function Public.do_not_check_trusted(value)
|
||||
this.do_not_check_trusted = value or false
|
||||
return this.do_not_check_trusted
|
||||
end
|
||||
|
||||
--- If ANY actions should be performed when a player misbehaves.
|
||||
---@param value string
|
||||
---@param value boolean
|
||||
function Public.enable_capsule_warning(value)
|
||||
this.enable_capsule_warning = value or false
|
||||
return this.enable_capsule_warning
|
||||
end
|
||||
|
||||
--- If ANY actions should be performed when a player misbehaves.
|
||||
---@param value string
|
||||
---@param value boolean
|
||||
function Public.enable_capsule_cursor_warning(value)
|
||||
this.enable_capsule_cursor_warning = value or false
|
||||
return this.enable_capsule_cursor_warning
|
||||
end
|
||||
|
||||
--- If the script should jail a person instead of kicking them
|
||||
---@param value string
|
||||
---@param value boolean
|
||||
function Public.enable_jail(value)
|
||||
this.enable_jail = value or false
|
||||
return this.enable_jail
|
||||
end
|
||||
|
||||
--- Defines what the threshold for amount of explosives in chest should be - logged or not.
|
||||
--- If the script should jail a person whenever they deconstruct multiple times.
|
||||
---@param value boolean
|
||||
function Public.enable_jail_when_decon(value)
|
||||
this.enable_jail_when_decon = value or false
|
||||
return this.enable_jail_when_decon
|
||||
end
|
||||
|
||||
--- If the script should jail a person whenever they deconstruct multiple times.
|
||||
---@param value string
|
||||
function Public.decon_surface_blacklist(value)
|
||||
this.decon_surface_blacklist = value or 'nauvis'
|
||||
return this.decon_surface_blacklist
|
||||
end
|
||||
|
||||
--- Defines what the threshold for amount of explosives in chest should be - logged or not.
|
||||
---@param value number
|
||||
function Public.explosive_threshold(value)
|
||||
if value then
|
||||
this.explosive_threshold = value
|
||||
@ -938,8 +1101,16 @@ function Public.explosive_threshold(value)
|
||||
return this.explosive_threshold
|
||||
end
|
||||
|
||||
--- Defines if on_player_deconstructed_area should also check for other types.
|
||||
---@param tbl table
|
||||
function Public.filtered_types_on_decon(tbl)
|
||||
if tbl then
|
||||
this.filtered_types_on_decon = tbl
|
||||
end
|
||||
end
|
||||
|
||||
--- Defines what the threshold for amount of times before the script should take action.
|
||||
---@param value string
|
||||
---@param value number
|
||||
function Public.damage_entity_threshold(value)
|
||||
if value then
|
||||
this.damage_entity_threshold = value
|
||||
@ -964,6 +1135,8 @@ Event.add(de.on_entity_died, on_entity_died)
|
||||
Event.add(de.on_built_entity, on_built_entity)
|
||||
Event.add(de.on_gui_opened, on_gui_opened)
|
||||
Event.add(de.on_marked_for_deconstruction, on_marked_for_deconstruction)
|
||||
Event.add(de.on_player_deconstructed_area, on_player_deconstructed_area)
|
||||
Event.add(de.on_cancelled_deconstruction, on_cancelled_deconstruction)
|
||||
Event.add(de.on_player_ammo_inventory_changed, on_player_ammo_inventory_changed)
|
||||
Event.add(de.on_player_built_tile, on_player_built_tile)
|
||||
Event.add(de.on_pre_player_mined_item, on_pre_player_mined_item)
|
||||
|
@ -554,4 +554,32 @@ Public.get_closest_neighbour = function(position, objects)
|
||||
return closest
|
||||
end
|
||||
|
||||
--[[
|
||||
get_closest_neighbour - Return object whose is closest to given position.
|
||||
@param position - Position, origin point
|
||||
@param object - Table of objects that have any sort of position datafield.
|
||||
--]]
|
||||
Public.get_closest_neighbour_non_player = function(position, objects)
|
||||
local closest = objects[1]
|
||||
local min_dist = Public.get_distance(position, closest)
|
||||
|
||||
local object, dist
|
||||
for i = #objects, 1, -1 do
|
||||
object = objects[i]
|
||||
if object and object.valid and object.destructible then
|
||||
dist = Public.get_distance(position, object)
|
||||
if dist < min_dist then
|
||||
closest = object
|
||||
min_dist = dist
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if closest and closest.valid and not closest.destructible then
|
||||
return false
|
||||
end
|
||||
|
||||
return closest
|
||||
end
|
||||
|
||||
return Public
|
||||
|
@ -109,7 +109,21 @@ function Public.iter_connected_players(callback)
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
callback(player)
|
||||
if player and player.valid then
|
||||
callback(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Iterates over all players
|
||||
---@param callback function
|
||||
function Public.iter_players(callback)
|
||||
local players = game.players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
if player and player.valid then
|
||||
callback(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
--luacheck: ignore
|
||||
local branch_version = '1.1' -- define what game version we're using
|
||||
local sub = string.sub
|
||||
|
||||
-- Non-applicable stages are commented out.
|
||||
_STAGE = {
|
||||
--settings = 1,
|
||||
@ -13,46 +9,3 @@ _STAGE = {
|
||||
config_change = 7,
|
||||
runtime = 8
|
||||
}
|
||||
|
||||
function get_game_version()
|
||||
local get_active_branch = sub(game.active_mods.base, 3, 4)
|
||||
local is_branch_experimental = sub(branch_version, 3, 4)
|
||||
if get_active_branch >= is_branch_experimental then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function is_loaded(module)
|
||||
local res = _G.package.loaded[module]
|
||||
if res then
|
||||
return res
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function is_game_modded()
|
||||
local i = 0
|
||||
for k, _ in pairs(game.active_mods) do
|
||||
i = i + 1
|
||||
if i > 1 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function is_mod_loaded(module)
|
||||
if not module then
|
||||
return false
|
||||
end
|
||||
|
||||
local res = script.active_mods[module]
|
||||
if res then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
146
utils/datastore/banhandler.lua
Normal file
146
utils/datastore/banhandler.lua
Normal file
@ -0,0 +1,146 @@
|
||||
local Event = require 'utils.event'
|
||||
local Server = require 'utils.server'
|
||||
local Token = require 'utils.token'
|
||||
|
||||
local len = string.len
|
||||
local gmatch = string.gmatch
|
||||
local insert = table.insert
|
||||
local ban_by_join_enabled = false
|
||||
|
||||
local try_get_ban = Server.try_get_ban
|
||||
|
||||
--- Jail dataset.
|
||||
local jailed_data_set = 'jailed'
|
||||
|
||||
local try_get_is_banned_token =
|
||||
Token.register(
|
||||
function(data)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
local username = data.username
|
||||
if not username then
|
||||
return
|
||||
end
|
||||
|
||||
local state = data.state
|
||||
|
||||
if state == true then
|
||||
game.ban_player(data.username, data.reason)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_joined_game,
|
||||
function(event)
|
||||
if not ban_by_join_enabled then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local secs = Server.get_current_time()
|
||||
if secs == nil then
|
||||
return
|
||||
else
|
||||
try_get_ban(player.name, try_get_is_banned_token)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_console_command,
|
||||
function(event)
|
||||
local cmd = event.command
|
||||
|
||||
local user = event.parameters
|
||||
if not user then
|
||||
return
|
||||
end
|
||||
|
||||
if len(user) <= 2 then
|
||||
return
|
||||
end
|
||||
|
||||
local player_index
|
||||
local reason
|
||||
local str = ''
|
||||
|
||||
local t = {}
|
||||
for i in gmatch(user, '%S+') do
|
||||
insert(t, i)
|
||||
end
|
||||
|
||||
player_index = t[1]
|
||||
|
||||
for i = 2, #t do
|
||||
str = str .. t[i] .. ' '
|
||||
reason = str
|
||||
end
|
||||
|
||||
if not player_index then
|
||||
return print('[on_console_command] - player_index was undefined.')
|
||||
end
|
||||
|
||||
local target
|
||||
if game.get_player(player_index) then
|
||||
target = game.get_player(player_index)
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if event.player_index then
|
||||
local player = game.get_player(event.player_index)
|
||||
if player and player.valid and player.admin then
|
||||
-- if target.index == player.index then
|
||||
-- return
|
||||
-- end
|
||||
|
||||
local data = Server.build_embed_data()
|
||||
data.username = target.name
|
||||
data.admin = player.name
|
||||
|
||||
if cmd == 'ban' then
|
||||
Server.set_data(jailed_data_set, target.name, nil) -- this is added here since we don't want to clutter the jail dataset.
|
||||
if not reason then
|
||||
data.reason = 'Not specified.'
|
||||
Server.to_banned_embed(data)
|
||||
return
|
||||
else
|
||||
data.reason = reason
|
||||
Server.to_banned_embed(data)
|
||||
return
|
||||
end
|
||||
elseif cmd == 'unban' then
|
||||
Server.to_unbanned_embed(data)
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
local data = Server.build_embed_data()
|
||||
data.username = target.name
|
||||
data.admin = '<Server>'
|
||||
|
||||
if cmd == 'ban' then
|
||||
Server.set_data(jailed_data_set, target.name, nil) -- this is added here since we don't want to clutter the jail dataset.
|
||||
if not reason then
|
||||
data.reason = 'Not specified.'
|
||||
Server.to_banned_embed(data)
|
||||
return
|
||||
else
|
||||
data.reason = reason
|
||||
Server.to_banned_embed(data)
|
||||
return
|
||||
end
|
||||
elseif cmd == 'unban' then
|
||||
Server.to_unbanned_embed(data)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
@ -478,7 +478,7 @@ local function jail(player, griefer, msg, raised)
|
||||
end
|
||||
|
||||
if not msg then
|
||||
return
|
||||
msg = 'Jailed by script'
|
||||
end
|
||||
|
||||
if not game.get_player(griefer) then
|
||||
@ -589,7 +589,10 @@ function Public.try_dl_data(key)
|
||||
end
|
||||
|
||||
--- Tries to get data from the webpanel and updates the local table with values.
|
||||
-- @param data_set player token
|
||||
-- @param key LuaPlayer
|
||||
-- @param value boolean
|
||||
-- @param player LuaPlayer or <script>
|
||||
-- @param message string
|
||||
function Public.try_ul_data(key, value, player, message)
|
||||
if type(key) == 'table' then
|
||||
key = key.name
|
||||
|
@ -12,6 +12,10 @@ local Public = {}
|
||||
local fetch =
|
||||
Token.register(
|
||||
function(data)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
local key = data.key
|
||||
local value = data.value
|
||||
local player = game.players[key]
|
||||
|
@ -95,6 +95,9 @@ Gui.on_click(
|
||||
|
||||
local left_panel = element.parent.parent
|
||||
local left_panel_data = Gui.get_data(left_panel)
|
||||
if not left_panel_data then
|
||||
return
|
||||
end
|
||||
local right_panel = left_panel_data.right_panel
|
||||
local selected_header = left_panel_data.selected_header
|
||||
|
||||
|
@ -133,6 +133,9 @@ Gui.on_text_changed(
|
||||
function(event)
|
||||
local element = event.element
|
||||
local gui_table = Gui.get_data(element)
|
||||
if not gui_table then
|
||||
return
|
||||
end
|
||||
|
||||
local filter = element.text:gsub(' ', '_')
|
||||
|
||||
@ -149,6 +152,10 @@ Gui.on_click(
|
||||
function(event)
|
||||
local element = event.element
|
||||
local data = Gui.get_data(element)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
local filter_textfield = data.filter_textfield
|
||||
local gui_table = data.gui_table
|
||||
|
||||
|
@ -158,11 +158,17 @@ Gui.on_click(
|
||||
function(event)
|
||||
local element = event.element
|
||||
local header_data = Gui.get_data(element)
|
||||
if not header_data then
|
||||
return
|
||||
end
|
||||
local values = header_data.values
|
||||
local player_index = header_data.player_index
|
||||
|
||||
local player_panel = element.parent.parent
|
||||
local data = Gui.get_data(player_panel)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
local element_panel = data.element_panel
|
||||
local selected_player_header = data.selected_player_header
|
||||
local input_text_box = data.input_text_box
|
||||
@ -191,11 +197,17 @@ Gui.on_click(
|
||||
function(event)
|
||||
local element = event.element
|
||||
local header_data = Gui.get_data(element)
|
||||
if not header_data then
|
||||
return
|
||||
end
|
||||
local stored_data = header_data.stored_data
|
||||
local element_index = header_data.element_index
|
||||
|
||||
local player_panel = element.parent.parent
|
||||
local data = Gui.get_data(player_panel)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
local data_panel = data.data_panel
|
||||
local selected_element_header = data.selected_element_header
|
||||
local input_text_box = data.input_text_box
|
||||
@ -246,6 +258,9 @@ Gui.on_click(
|
||||
function(event)
|
||||
local element = event.element
|
||||
local data = Gui.get_data(element)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
local input_text_box = data.input_text_box
|
||||
local player_panel = data.player_panel
|
||||
@ -263,6 +278,9 @@ Gui.on_click(
|
||||
Gui.clear(element_panel)
|
||||
if selected_player_header then
|
||||
local player_header_data = Gui.get_data(selected_player_header)
|
||||
if not player_header_data then
|
||||
return
|
||||
end
|
||||
local values = player_header_data.values
|
||||
|
||||
local selected_element_header = draw_element_headers(element_panel, values, selected_element_index)
|
||||
|
@ -34,7 +34,7 @@ function Public.open_debug(player)
|
||||
return
|
||||
end
|
||||
|
||||
frame = screen.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3003', direction = 'vertical'}
|
||||
frame = screen.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3004', direction = 'vertical'}
|
||||
frame.auto_center = true
|
||||
local frame_style = frame.style
|
||||
frame_style.height = 600
|
||||
@ -73,6 +73,9 @@ Gui.on_click(
|
||||
function(event)
|
||||
local element = event.element
|
||||
local data = Gui.get_data(element)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
local index = data.index
|
||||
local frame_data = data.frame_data
|
||||
|
@ -87,6 +87,9 @@ Gui.on_click(
|
||||
|
||||
local left_panel = element.parent.parent
|
||||
local data = Gui.get_data(left_panel)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
local selected_file_label = data.selected_file_label
|
||||
|
||||
@ -125,7 +128,7 @@ Gui.on_click(
|
||||
|
||||
local top_panel = element.parent.parent
|
||||
local data = Gui.get_data(top_panel)
|
||||
if not data or not data.valid then
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
local Gui = require 'utils.gui'
|
||||
local Global = require 'utils.global'
|
||||
local Token = require 'utils.token'
|
||||
local Color = require 'utils.color_presets'
|
||||
local Model = require 'utils.debug.model'
|
||||
|
||||
@ -89,10 +88,10 @@ Gui.on_click(
|
||||
element.style.font_color = Color.orange
|
||||
data.selected_header = element
|
||||
|
||||
input_text_box.text = concat {'global.tokens[', token_id, ']'}
|
||||
input_text_box.text = concat {'global.tokens.', token_id}
|
||||
input_text_box.style.font_color = Color.black
|
||||
|
||||
local id = Token.get_global(token_id)
|
||||
local id = Global.get_global(token_id)
|
||||
local content = dump(id) or 'Could not load data.'
|
||||
if content:find('function_handlers') then
|
||||
content = '{}' -- desync handler
|
||||
|
@ -108,6 +108,7 @@ local core_on_load = EventCore.on_load
|
||||
local core_on_nth_tick = EventCore.on_nth_tick
|
||||
local core_on_configuration_changed = EventCore.on_configuration_changed
|
||||
local stage_load = _STAGE.load
|
||||
local raise_event = script.raise_event
|
||||
local script_on_event = script.on_event
|
||||
local script_on_nth_tick = script.on_nth_tick
|
||||
local generate_event_name = script.generate_event_name
|
||||
@ -182,6 +183,17 @@ function Event.on_init(handler)
|
||||
core_on_init(handler)
|
||||
end
|
||||
|
||||
--- This exists only to become more easily available if you are already requiring the event module.
|
||||
function Event.raise(handler, data)
|
||||
if data then
|
||||
if not type(data) == 'table' then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
raise_event(handler, data)
|
||||
end
|
||||
|
||||
--- Register a handler for the script.on_load event.
|
||||
-- This function must be called in the control stage or in Event.on_init or Event.on_load
|
||||
-- See documentation at top of file for details on using events.
|
||||
|
BIN
utils/files/beam.png
Normal file
BIN
utils/files/beam.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
@ -114,7 +114,7 @@ end
|
||||
@return the created entity
|
||||
]]
|
||||
function Game.print_player_floating_text_position(player_index, text, color, x_offset, y_offset)
|
||||
local player = Game.get_player_by_index(player_index)
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
@ -1,39 +1,57 @@
|
||||
local Event = require 'utils.event_core'
|
||||
local Token = require 'utils.token'
|
||||
local Global = {
|
||||
names = {},
|
||||
index = 0,
|
||||
filepath = {}
|
||||
}
|
||||
|
||||
global.tokens = {}
|
||||
|
||||
local Global = {}
|
||||
local concat = table.concat
|
||||
|
||||
local names = {}
|
||||
Global.names = names
|
||||
--- Sets a new global
|
||||
---@param tbl any
|
||||
---@return integer
|
||||
---@return string
|
||||
function Global.set_global(tbl)
|
||||
local filepath = debug.getinfo(3, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5):gsub('/', '_')
|
||||
|
||||
Global.index = Global.index + 1
|
||||
Global.filepath[filepath] = Global.index
|
||||
Global.names[filepath] = concat {Global.filepath[filepath], ' - ', filepath}
|
||||
|
||||
global.tokens[filepath] = tbl
|
||||
|
||||
return Global.index, filepath
|
||||
end
|
||||
|
||||
--- Gets a global from global
|
||||
---@param token number|string
|
||||
---@return any|nil
|
||||
function Global.get_global(token)
|
||||
if global.tokens[token] then
|
||||
return global.tokens[token]
|
||||
end
|
||||
end
|
||||
|
||||
function Global.register(tbl, callback)
|
||||
if _LIFECYCLE ~= _STAGE.control then
|
||||
error('can only be called during the control stage', 2)
|
||||
end
|
||||
|
||||
local filepath = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5)
|
||||
local token = Token.register_global(tbl)
|
||||
|
||||
names[token] = concat {token, ' - ', filepath}
|
||||
local token, filepath = Global.set_global(tbl)
|
||||
|
||||
Event.on_load(
|
||||
function()
|
||||
callback(Token.get_global(token))
|
||||
if global.tokens[token] then
|
||||
callback(Global.get_global(token))
|
||||
else
|
||||
callback(Global.get_global(filepath))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return token
|
||||
return filepath
|
||||
end
|
||||
|
||||
function Global.register_init(tbl, init_handler, callback)
|
||||
if _LIFECYCLE ~= _STAGE.control then
|
||||
error('can only be called during the control stage', 2)
|
||||
end
|
||||
local filepath = debug.getinfo(2, 'S').source:match('^.+/currently%-playing/(.+)$'):sub(1, -5)
|
||||
local token = Token.register_global(tbl)
|
||||
|
||||
names[token] = concat {token, ' - ', filepath}
|
||||
local token, filepath = Global.set_global(tbl)
|
||||
|
||||
Event.on_init(
|
||||
function()
|
||||
@ -44,11 +62,14 @@ function Global.register_init(tbl, init_handler, callback)
|
||||
|
||||
Event.on_load(
|
||||
function()
|
||||
callback(Token.get_global(token))
|
||||
if global.tokens[token] then
|
||||
callback(Global.get_global(token))
|
||||
else
|
||||
callback(Global.get_global(filepath))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return token
|
||||
return filepath
|
||||
end
|
||||
|
||||
return Global
|
||||
|
@ -34,6 +34,7 @@ Public.token =
|
||||
end
|
||||
)
|
||||
|
||||
Public.beam = 'file/utils/files/beam.png'
|
||||
Public.settings_white_icon = 'file/utils/files/settings-white.png'
|
||||
Public.settings_black_icon = 'file/utils/files/settings-black.png'
|
||||
Public.pin_white_icon = 'file/utils/files/pin-white.png'
|
||||
@ -396,7 +397,7 @@ end
|
||||
|
||||
--- This adds the given gui to the top gui.
|
||||
---@param player userdata
|
||||
---@param frame userdata
|
||||
---@param frame userdata|table
|
||||
function Public.add_mod_button(player, frame)
|
||||
if Public.get_button_flow(player)[frame.name] and Public.get_button_flow(player)[frame.name].valid then
|
||||
return
|
||||
@ -577,6 +578,7 @@ end
|
||||
|
||||
local function draw_main_frame(player)
|
||||
local tabs = main_gui_tabs
|
||||
|
||||
Public.clear_all_active_frames(player)
|
||||
|
||||
if Public.get_main_frame(player) then
|
||||
@ -584,7 +586,6 @@ local function draw_main_frame(player)
|
||||
end
|
||||
|
||||
local frame, inside_frame = Public.add_main_frame_with_toolbar(player, 'left', main_frame_name, nil, close_button_name, 'Comfy Panel')
|
||||
|
||||
local tabbed_pane = inside_frame.add({type = 'tabbed-pane', name = 'tabbed_pane'})
|
||||
|
||||
for name, func in pairs(tabs) do
|
||||
|
@ -247,7 +247,8 @@ local function draw_events(data)
|
||||
['Mining Override History'] = antigrief.whitelist_mining_history,
|
||||
['Landfill History'] = antigrief.landfill_history,
|
||||
['Corpse Looting History'] = antigrief.corpse_history,
|
||||
['Cancel Crafting History'] = antigrief.cancel_crafting_history
|
||||
['Cancel Crafting History'] = antigrief.cancel_crafting_history,
|
||||
['Deconstruct History'] = antigrief.deconstruct_history
|
||||
}
|
||||
|
||||
local scroll_pane
|
||||
@ -358,6 +359,10 @@ local function create_admin_panel(data)
|
||||
local player = data.player
|
||||
local frame = data.frame
|
||||
local antigrief = AntiGrief.get()
|
||||
if not antigrief then
|
||||
return
|
||||
end
|
||||
|
||||
frame.clear()
|
||||
|
||||
local player_names = {}
|
||||
@ -508,6 +513,9 @@ local function create_admin_panel(data)
|
||||
if antigrief.cancel_crafting_history then
|
||||
table.insert(histories, 'Cancel Crafting History')
|
||||
end
|
||||
if antigrief.deconstruct_history then
|
||||
table.insert(histories, 'Deconstruct History')
|
||||
end
|
||||
|
||||
if #histories == 0 then
|
||||
return
|
||||
|
@ -19,6 +19,8 @@ Global.register(
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.events = {bottom_quickbar_button_name = Event.generate_event_name('bottom_quickbar_button_name')}
|
||||
|
||||
local main_frame_name = Gui.uid_name()
|
||||
local clear_corpse_button_name = Gui.uid_name()
|
||||
local bottom_quickbar_button_name = Gui.uid_name()
|
||||
@ -225,6 +227,17 @@ Gui.on_click(
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
bottom_quickbar_button_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Custom Bottom_quickbar_button_name')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
Event.raise(Public.events.bottom_quickbar_button_name, {player = event.player, event = event})
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_joined_game,
|
||||
function(event)
|
||||
|
@ -82,7 +82,7 @@ end
|
||||
local function spaghett()
|
||||
local spaghetti = this.gui_config.spaghett
|
||||
if spaghetti.noop then
|
||||
return
|
||||
return
|
||||
end
|
||||
if spaghetti.enabled then
|
||||
for _, f in pairs(game.forces) do
|
||||
@ -355,6 +355,40 @@ local fortress_functions = {
|
||||
get_actor(event, '[Decon]', 'has disabled decon on car/tanks/trains.', true)
|
||||
end
|
||||
end,
|
||||
['allow_decon_main_surface'] = function(event)
|
||||
local WPT = is_loaded('maps.mountain_fortress_v3.table')
|
||||
if event.element.switch_state == 'left' then
|
||||
local near_locomotive_group = game.permissions.get_group('near_locomotive')
|
||||
if near_locomotive_group then
|
||||
near_locomotive_group.set_allows_action(defines.input_action.deconstruct, true)
|
||||
end
|
||||
local default_group = game.permissions.get_group('Default')
|
||||
if default_group then
|
||||
default_group.set_allows_action(defines.input_action.deconstruct, true)
|
||||
end
|
||||
local main_surface_group = game.permissions.get_group('main_surface')
|
||||
if main_surface_group then
|
||||
main_surface_group.set_allows_action(defines.input_action.deconstruct, true)
|
||||
end
|
||||
WPT.set('allow_decon_main_surface', true)
|
||||
get_actor(event, '[Decon]', 'has allowed decon on main surface.', true)
|
||||
else
|
||||
local near_locomotive_group = game.permissions.get_group('near_locomotive')
|
||||
if near_locomotive_group then
|
||||
near_locomotive_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
end
|
||||
local default_group = game.permissions.get_group('Default')
|
||||
if default_group then
|
||||
default_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
end
|
||||
local main_surface_group = game.permissions.get_group('main_surface')
|
||||
if main_surface_group then
|
||||
main_surface_group.set_allows_action(defines.input_action.deconstruct, false)
|
||||
end
|
||||
WPT.set('allow_decon_main_surface', false)
|
||||
get_actor(event, '[Decon]', 'has disabled decon on main surface.', true)
|
||||
end
|
||||
end,
|
||||
['christmas_mode'] = function(event)
|
||||
local WPT = is_loaded('maps.mountain_fortress_v3.table')
|
||||
if event.element.switch_state == 'left' then
|
||||
@ -667,8 +701,17 @@ local function build_config_gui(data)
|
||||
if Module.allow_decon then
|
||||
switch_state = 'left'
|
||||
end
|
||||
add_switch(scroll_pane, switch_state, 'allow_decon', 'Deconstruct', 'On = Allows decon on car/tanks/trains.\nOff = Disables decon on car/tanks/trains.')
|
||||
add_switch(scroll_pane, switch_state, 'allow_decon', 'Deconstruct IC', 'On = Allows decon on car/tanks/trains.\nOff = Disables decon on car/tanks/trains.')
|
||||
scroll_pane.add({type = 'line'})
|
||||
|
||||
switch_state = 'right'
|
||||
if Module.allow_decon_main_surface then
|
||||
switch_state = 'left'
|
||||
end
|
||||
add_switch(scroll_pane, switch_state, 'allow_decon_main_surface', 'Deconstruct Surface', 'On = Allows decon on main surface.\nOff = Disables decon on main surface.')
|
||||
scroll_pane.add({type = 'line'})
|
||||
|
||||
switch_state = 'right'
|
||||
if Module.christmas_mode then
|
||||
switch_state = 'left'
|
||||
end
|
||||
|
@ -950,14 +950,14 @@ local function on_player_left_game()
|
||||
end
|
||||
|
||||
--- If the different roles should be shown in the player_list.
|
||||
---@param value string
|
||||
---@param value boolean
|
||||
function Public.show_roles_in_list(value)
|
||||
this.show_roles_in_list = value or false
|
||||
return this.show_roles_in_list
|
||||
end
|
||||
|
||||
--- Notifies player_list if RPG is enabled or not.
|
||||
---@param value string
|
||||
---@param value boolean
|
||||
function Public.rpg_enabled(value)
|
||||
this.rpg_enabled = value or false
|
||||
return this.rpg_enabled
|
||||
|
@ -1,7 +1,6 @@
|
||||
local Gui = require 'utils.gui'
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Server = require 'utils.server'
|
||||
local session = require 'utils.datastore.session_data'
|
||||
local Config = require 'utils.gui.config'
|
||||
@ -186,7 +185,7 @@ local function redraw_poll_viewer_content(data)
|
||||
if next(edited_by_players) then
|
||||
local edit_names = {'Edited by '}
|
||||
for pi, _ in pairs(edited_by_players) do
|
||||
local p = Game.get_player_by_index(pi)
|
||||
local p = game.get_player(pi)
|
||||
if p and p.valid then
|
||||
insert(edit_names, p.name)
|
||||
insert(edit_names, ', ')
|
||||
@ -762,7 +761,7 @@ local function vote(event)
|
||||
end
|
||||
|
||||
local function player_joined(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
129
utils/server.lua
129
utils/server.lua
@ -2,7 +2,6 @@ local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Print = require('utils.print_override')
|
||||
|
||||
-- local constants
|
||||
@ -13,8 +12,7 @@ local concat = table.concat
|
||||
local serialize = serpent.serialize
|
||||
local remove = table.remove
|
||||
local tostring = tostring
|
||||
local len = string.len
|
||||
local gmatch = string.gmatch
|
||||
|
||||
local raw_print = Print.raw_print
|
||||
local minutes_to_ticks = 60 * 60
|
||||
local hours_to_ticks = 60 * 60 * 60
|
||||
@ -50,9 +48,6 @@ Global.register(
|
||||
end
|
||||
)
|
||||
|
||||
--- Jail dataset.
|
||||
local jailed_data_set = 'jailed'
|
||||
|
||||
--- Web panel framework.
|
||||
local discord_tag = '[DISCORD]'
|
||||
local discord_raw_tag = '[DISCORD-RAW]'
|
||||
@ -82,6 +77,7 @@ local start_scenario_tag = '[START-SCENARIO]'
|
||||
local stop_scenario_tag = '[STOP-SCENARIO]'
|
||||
local ping_tag = '[PING]'
|
||||
local data_set_tag = '[DATA-SET]'
|
||||
local ban_get_tag = '[BAN-GET]'
|
||||
local data_get_tag = '[DATA-GET]'
|
||||
local data_get_and_print_tag = '[DATA-GET-AND-PRINT]'
|
||||
local data_get_all_tag = '[DATA-GET-ALL]'
|
||||
@ -522,6 +518,10 @@ end
|
||||
|
||||
local function double_escape(str)
|
||||
-- Excessive escaping because the data is serialized twice.
|
||||
if not str then
|
||||
return ''
|
||||
end
|
||||
|
||||
return str:gsub('\\', '\\\\\\\\'):gsub('"', '\\\\\\"'):gsub('\n', '\\\\n')
|
||||
end
|
||||
|
||||
@ -589,6 +589,16 @@ local function validate_arguments(data_set, key, callback_token)
|
||||
end
|
||||
end
|
||||
|
||||
local function validate_arguments_of_ban(username, callback_token)
|
||||
if type(username) ~= 'string' then
|
||||
error('username must be a string', 3)
|
||||
end
|
||||
|
||||
if type(callback_token) ~= 'number' then
|
||||
error('callback_token must be a number', 3)
|
||||
end
|
||||
end
|
||||
|
||||
local function send_try_get_data(data_set, key, callback_token)
|
||||
data_set = double_escape(data_set)
|
||||
key = double_escape(key)
|
||||
@ -597,6 +607,13 @@ local function send_try_get_data(data_set, key, callback_token)
|
||||
raw_print(message)
|
||||
end
|
||||
|
||||
local function send_try_get_ban(username, callback_token)
|
||||
username = double_escape(username)
|
||||
|
||||
local message = concat {ban_get_tag, callback_token, ' {', 'username:"', username, '"}'}
|
||||
raw_print(message)
|
||||
end
|
||||
|
||||
local function send_try_get_data_and_print(data_set, key, to_print, callback_token)
|
||||
data_set = double_escape(data_set)
|
||||
key = double_escape(key)
|
||||
@ -658,6 +675,13 @@ function Public.try_get_data(data_set, key, callback_token)
|
||||
send_try_get_data(data_set, key, callback_token)
|
||||
end
|
||||
|
||||
--- Same as try_get_data returns if a user is banned.
|
||||
function Public.try_get_ban(username, callback_token)
|
||||
validate_arguments_of_ban(username, callback_token)
|
||||
|
||||
send_try_get_ban(username, callback_token)
|
||||
end
|
||||
|
||||
--- Same as try_get_data but prints the returned value to the given player who ran the command.
|
||||
function Public.try_get_data_and_print(data_set, key, to_print, callback_token)
|
||||
validate_arguments(data_set, key, callback_token)
|
||||
@ -1288,7 +1312,7 @@ commands.add_command(
|
||||
Event.add(
|
||||
defines.events.on_player_joined_game,
|
||||
function(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
@ -1324,97 +1348,6 @@ Event.add(
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_console_command,
|
||||
function(event)
|
||||
local cmd = event.command
|
||||
|
||||
local user = event.parameters
|
||||
if not user then
|
||||
return
|
||||
end
|
||||
|
||||
if len(user) <= 2 then
|
||||
return
|
||||
end
|
||||
|
||||
local userIndex
|
||||
local reason
|
||||
local str = ''
|
||||
|
||||
local t = {}
|
||||
for i in gmatch(user, '%S+') do
|
||||
insert(t, i)
|
||||
end
|
||||
|
||||
userIndex = t[1]
|
||||
|
||||
for i = 2, #t do
|
||||
str = str .. t[i] .. ' '
|
||||
reason = str
|
||||
end
|
||||
|
||||
if not userIndex then
|
||||
return log('Log to Discord when a user is banned failed. userIndex was undefined.')
|
||||
end
|
||||
|
||||
local banishedPlayer
|
||||
if game.get_player(userIndex) then
|
||||
banishedPlayer = game.get_player(userIndex)
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if event.player_index then
|
||||
local player = game.get_player(event.player_index)
|
||||
if player and player.valid and player.admin then
|
||||
if banishedPlayer.index == player.index then
|
||||
return
|
||||
end
|
||||
|
||||
local data = build_embed_data()
|
||||
data.username = banishedPlayer.name
|
||||
data.admin = player.name
|
||||
|
||||
if cmd == 'ban' then
|
||||
Public.set_data(jailed_data_set, banishedPlayer.name, nil) -- this is added here since we don't want to clutter the jail dataset.
|
||||
if not reason then
|
||||
data.reason = 'Not specified.'
|
||||
Public.to_banned_embed(data)
|
||||
return
|
||||
else
|
||||
data.reason = reason
|
||||
Public.to_banned_embed(data)
|
||||
return
|
||||
end
|
||||
elseif cmd == 'unban' then
|
||||
Public.to_unbanned_embed(data)
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
local data = build_embed_data()
|
||||
data.username = banishedPlayer.name
|
||||
data.admin = '<Server>'
|
||||
|
||||
if cmd == 'ban' then
|
||||
if not reason then
|
||||
data.reason = 'Not specified.'
|
||||
Public.to_banned_embed(data)
|
||||
return
|
||||
else
|
||||
data.reason = reason
|
||||
Public.to_banned_embed(data)
|
||||
return
|
||||
end
|
||||
elseif cmd == 'unban' then
|
||||
Public.to_unbanned_embed(data)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_died,
|
||||
function(event)
|
||||
|
@ -4,6 +4,8 @@ local Poll = {
|
||||
}
|
||||
local Token = require 'utils.token'
|
||||
local Server = require 'utils.server'
|
||||
local branch_version = '1.1' -- define what game version we're using
|
||||
local sub = string.sub
|
||||
|
||||
--- This module is for the web server to call functions and raise events.
|
||||
-- Not intended to be called by scripts.
|
||||
@ -49,4 +51,48 @@ if not remote.interfaces['ServerCommands'] then
|
||||
remote.add_interface('ServerCommands', SC_Interface)
|
||||
end
|
||||
|
||||
function get_game_version()
|
||||
local get_active_branch = sub(game.active_mods.base, 3, 4)
|
||||
local is_branch_experimental = sub(branch_version, 3, 4)
|
||||
if get_active_branch >= is_branch_experimental then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function is_loaded(module)
|
||||
local res = _G.package.loaded[module]
|
||||
if res then
|
||||
return res
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function is_game_modded()
|
||||
local active_mods = game.active_mods
|
||||
local i = 0
|
||||
for _, _ in pairs(active_mods) do
|
||||
i = i + 1
|
||||
if i > 1 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function is_mod_loaded(module)
|
||||
if not module then
|
||||
return false
|
||||
end
|
||||
|
||||
local res = game.active_mods[module]
|
||||
if res then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return ServerCommands
|
||||
|
@ -26,26 +26,9 @@ function Token.get(token_id)
|
||||
return tokens[token_id]
|
||||
end
|
||||
|
||||
global.tokens = {}
|
||||
|
||||
function Token.register_global(var)
|
||||
local c = #global.tokens + 1
|
||||
|
||||
global.tokens[c] = var
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function Token.get_global(token_id)
|
||||
return global.tokens[token_id]
|
||||
end
|
||||
|
||||
function Token.set_global(token_id, var)
|
||||
global.tokens[token_id] = var
|
||||
end
|
||||
|
||||
local uid_counter = 100
|
||||
|
||||
---@return integer
|
||||
function Token.uid()
|
||||
uid_counter = uid_counter + 1
|
||||
|
||||
|
@ -117,4 +117,11 @@ Module.format_time = function(ticks)
|
||||
return table.concat(result, ' ')
|
||||
end
|
||||
|
||||
function Module.inside(pos, area)
|
||||
local lt = area.left_top
|
||||
local rb = area.right_bottom
|
||||
|
||||
return pos.x >= lt.x and pos.y >= lt.y and pos.x <= rb.x and pos.y <= rb.y
|
||||
end
|
||||
|
||||
return Module
|
||||
|
Loading…
x
Reference in New Issue
Block a user