mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-02-09 13:37:02 +02:00
commit
dede244279
@ -157,7 +157,6 @@ local function send_poll_result_to_discord(poll)
|
||||
end
|
||||
|
||||
local function redraw_poll_viewer_content(data)
|
||||
local trusted = session.get_trusted_table()
|
||||
local poll_viewer_content = data.poll_viewer_content
|
||||
local remaining_time_label = data.remaining_time_label
|
||||
local poll_index = data.poll_index
|
||||
|
@ -87,6 +87,9 @@ require 'modules.autostash'
|
||||
--require 'maps.biter_battles_v2.main'
|
||||
--require 'maps.biter_battles.biter_battles'
|
||||
|
||||
--![[A map that imitating MF, defending rocket silos instead of trains]]--
|
||||
-- require 'maps.amap.main'
|
||||
|
||||
--![[Guide a Train through rough terrain, while defending it from the biters]]--
|
||||
-- require 'maps.mountain_fortress_v3.main'
|
||||
--require 'maps.mountain_fortress_v2.main'
|
||||
@ -205,6 +208,7 @@ require 'modules.autostash'
|
||||
--require 'maps.cube'
|
||||
--require 'maps.mountain_race.main'
|
||||
--require 'maps.native_war.main'
|
||||
--require 'maps.scrap_towny_ffa.main'
|
||||
---------------------------------------------------------------
|
||||
|
||||
---------------- MORE MODULES HERE ----------------
|
||||
@ -225,6 +229,7 @@ require 'modules.autostash'
|
||||
--require 'terrain_layouts.scrap_02'
|
||||
--require 'terrain_layouts.watery_world'
|
||||
--require 'terrain_layouts.tree_01'
|
||||
--require 'terrain_layouts.scrap_towny_ffa'
|
||||
---------------------------------------------------------------
|
||||
|
||||
if _DUMP_ENV then
|
||||
|
96
locale/en/amap.cfg
Normal file
96
locale/en/amap.cfg
Normal file
@ -0,0 +1,96 @@
|
||||
[amap]
|
||||
map_info_main_caption= Mountain Defense 1.7
|
||||
map_info_sub_caption= 2021.1.31 edition
|
||||
map_info_text= welcome to moutain defenes! \n \n Many years after the launch of the rocket, the insects made a comeback and wiped out most of the human cities. You and the other survivors have built the last bastion of humanity,. Unfortunately, the insects have found you too. They are organizing troops to march towards us. Before the insects destroy the base, launch rockets to escape from this place! \n Tips: \n 1. You can use RPG button to enhance yourself \n 2. In the RPG settings panel, you can enable magic and select your skills. \n 3. RPG magic can increase your luck \n 4. You can buy vehicles in the main market. They have internal space \n 6. The blue box in the car is enabled. It is allowed to pick up goods from the green box and get goods from the backpack. \n 5. Launching rockets will give a lot of rewards, and the more you launch, the more rewards you get. \n Author: ITAM \n Thanks: hanakoz
|
||||
|
||||
science= research is completed, you get __1__ Skill points and __2__ Gold coins.
|
||||
|
||||
roll= it's time to turn the wheel of destiny! See what happens!
|
||||
what= ? What happened! )
|
||||
sorry= robbery! You lost __1__ gold coins!
|
||||
nbone= your number is 1, you have won __1__ gold coins!
|
||||
nb2= you've got the advice of a world expert! You get __1__ skill points!
|
||||
nb3= you were beaten by the little old man on the side of the road! Reward __1__ points of strength
|
||||
nb4= what to do when the bug comes? Run away boy! Reward __1__ points of dexterity
|
||||
nb5= this is a magic wand?! Bonus __1__ Mana
|
||||
nb6= You start lifing some weights and gain __1__ points of strength!
|
||||
nb7= Er, nothing happened, very calm though, these 25 waves?
|
||||
nb8= oh,damn ,you lost __1__ xp!How can I make this happen?
|
||||
nb9= (⊙o⊙)… You got a fish?
|
||||
nb10= Oh, I went fishing and got __1__ fish. Don't forget to share!
|
||||
nb11= our UAV is ready! You've got __1__ defensive drone capsules!
|
||||
nb12= because of overeating. You're growing faster. Get __1__ XP!
|
||||
nb14= a small gift bag, what's in it?
|
||||
nb13= first prize! __1__ gold coins! congratulations
|
||||
nb15= Please protect the environment and dig less stones,you lost __1__ str point!
|
||||
nb16= Bananas are bananas,what?,where is my Magic wand? you lost __1__ magic point!
|
||||
nb17= My muscles are too sore,oh,maybe i can't move recently.you lost __1__ dex point !
|
||||
nb18= Someone poisoned you! you lost __1__ vil point!
|
||||
|
||||
nopoint= you don;t have enough point , so i will take your 1K coin !
|
||||
joingame= Protect the rocket shaft! Don't let insects destroy it! \n map record:\n single player mode:700 waves! \n record Author: wwwax \n win: no \n \n Multiplayer 985 wave!
|
||||
usecar= you used your car in the first 100 waves and lost the qualification to receive the reward. Continue to work hard next time
|
||||
usecar2= achieve the challenge, get 50 skill points reward, Congratulations!
|
||||
lucknb= your luck value is
|
||||
whatopen= Oh, what will you get
|
||||
noenough= guys, you don't have enough money
|
||||
pass= you have passed the customs!!!!!!! Nice! The clearance wave number is__1__
|
||||
times= you have launched__1__ Every time you launch a rocket, the reward will be repeated!
|
||||
reward= it is __1__ rocket launched! You will be rewarded with __2__ skill points and __3__ gold coins.
|
||||
lost= rocket silo destroyed, game failed! You survived__1__ Wave.
|
||||
openchest= spend 3000 gold coins, open this box, you have a chance to get MK2!
|
||||
buyxp= spend 5000 gold coins, buy 1000 experience points!
|
||||
buyover= you successfully bought 1000 experience points!
|
||||
getxpfromwave= oh, you pass this wave . so you get 10XP !
|
||||
|
||||
relax1= Do you know Rick and morty ? This is Adult cartoon full of strange and eccentric. Rick took Morty and explored the planets. It's very interesting. I strongly recommend that you see it .
|
||||
relax2= When I was young, I only played one game, Warcraft 3. I have played it since primary school. It's been 14 years now!
|
||||
relax3= When I was a child, I always heard strange stories. For example: Bermuda Triangle, Loch Ness water monster, spherical lightning. When I was in junior high school, I thought it was true!
|
||||
relax4= Factory has been out for five years, and it won't be released until 2020. Over the years, Factory has been updated, and has not reduced its price. I think it is a very conscientious game.
|
||||
relax5= Do you think this game is too crazy? Yes, I think so too!
|
||||
relax6= In China, parents will ask their children what they want to do in the future, and then tell their children that they want to be a scientist. (but I don't know if that's the case now)
|
||||
relax7= There is a psychological effect, called Barnum effect. It is easy for people to believe in a general description of personality, and think that it is particularly suitable for themselves and accurately reveals their personality characteristics, even if the content is empty.
|
||||
relax8= Why plant vs. zombie 2, no computer version?
|
||||
relax9= There is a devil living behind the moon. He always catches rabbits from the earth to eat. We must organize an army of astronauts to save rabbits!
|
||||
relax10= Damn, why 1 + 1 = 2 instead of 11? There must be a mistake.
|
||||
relax11= Why is there no magic in this world? Am I in the wrong world?
|
||||
relax12= Do you have a girlfriend? Ah? If you don't have a girlfriend, you still come to play factory?. Go find a girlfriend!
|
||||
relax13= Have you ever tried to drink beer with Coca Cola? What would it taste like?
|
||||
relax14= Can't give up, never give up. Unless you're playing factory
|
||||
relax15= Have you heard of flight training class? You can learn how to fly, er, with your hands for 10000 yuan?
|
||||
relax16= I once picked up 50 yuan at most on the roadside! This is in my primary school, oh, this is the first pot of gold to get rich.
|
||||
relax17= The best way to achieve something is to ask others to help. The second way is to pretend that you can't do anything.then wait other solve it .
|
||||
relax18= Take care of yourself, don't get sick, don't let others worry you .
|
||||
relax19= Unity is strength. We can build a big factory together. or Can we have a cookie, too?
|
||||
relax20= I hope you have a good time, or come to comfy discord to share your happiness!
|
||||
|
||||
single= Warrior, it's not easy to challenge alone. I have something for you. I hope I can help you
|
||||
gambel= spend 1000 coin to get 2500 coin or 0 coin !
|
||||
gambel1= you get 2500 coin!
|
||||
gambel2= well, you get nothing .
|
||||
|
||||
bag_isfull= WTF? my inventory is full ,so these rock attack me ?
|
||||
too_many= you build too many flame turret !
|
||||
ok_many= This is number __1__ flame turret . yous only can build 12 flame turret
|
||||
|
||||
buy_wall_over= __1__ bought health of wall and all turret ,them have __2__ heath now!
|
||||
buy_health_wall= bought 10% heath for wall and all turret
|
||||
|
||||
buy_arty_dam= urgrade arty_damage 10%
|
||||
player_biter_health= urgrade our biter health 10%
|
||||
buy_arty_over= __1__ bought arty damage !,it have __2__ damage now!
|
||||
buy_player_biter_over= __1__ bought our biter health !,our biter have __2__ health now!
|
||||
player_spider_health= urgrade 10% spider health
|
||||
buy_spider_health_over= __1__ bought 10% spider health !,it have __2__ health now!
|
||||
|
||||
|
||||
player_biter_dam= urgrade biter_damage 10%
|
||||
buy_biter_dam= __1__ bought biter damage !,it have __2__ damage now!
|
||||
easy= I want to relax
|
||||
med= Want some challenges
|
||||
hard= I love challenges
|
||||
|
||||
cap_upgrad= this item already reach upgrade at cap of wave_number now
|
||||
|
||||
buy_cap_over= __1__ bought cap of upgrade, we have __2__ cap now !
|
||||
buy_cap= buy cap of upgrade
|
@ -56,7 +56,7 @@ mana_max=This is your max mana. You can increase the regen by increasing your ma
|
||||
mining_name=MINING\nSPEED
|
||||
slot_name=SLOT\nBONUS
|
||||
melee_name=MELEE\nDAMAGE
|
||||
one_punch_chance=Life on-hit: __1__\nOne punch chance: __2__ %
|
||||
one_punch_chance=Life on-hit: __1__\nOne punch chance: __2__ % \n+__3__ [img=recipe.defender-capsule]
|
||||
one_punch_disabled=One Punch is disabled.
|
||||
bonus_tooltip=Reach distance bonus: __1__\nBuild distance bonus: __2__\nItem drop distance bonus: __3__\nLoot pickup distance bonus: __4__\nItem pickup distance bonus: __5__\nResource reach distance bonus: __6__\nRepair speed: __7__
|
||||
reach_distance=REACH\nDISTANCE
|
||||
|
96
locale/zh-CN/amap.cfg
Normal file
96
locale/zh-CN/amap.cfg
Normal file
@ -0,0 +1,96 @@
|
||||
[amap]
|
||||
map_info_main_caption= 山地保卫战1.7
|
||||
map_info_sub_caption= 2021.1.31
|
||||
map_info_text= 欢迎来到山地保卫战 \n 在发射火箭很多年以后,虫子再次卷土重来,消灭了大部分人类城市。你和其他的幸存者建立了人类最后的堡垒,。不幸的是虫子也发现了你们,它们正在组织军队向我们进发,在虫子摧毁基地前,发射火箭逃离这个地方! \n 提示: \n 1.你可以利用RPG按钮来增强自己 \n 2.在RPG设置面板可以启用魔法,选择你的技能。 \n 3.RPG的魔法可以增加,你的好运 \n 4.你可以在主市场购买载具,它们拥有内部空间 \n 6.车内蓝箱子启用允许从绿箱子取货,可以从车背包内获得物品。 \n 6.你可以在车里赌博,买经验,开箱子。 \n 7.发射火箭会给大量奖励,并且发射的越多奖励越多。 \n \n 群号:701077913 \n 作者:itam \n 鸣谢:Hanakoz \n
|
||||
|
||||
science= 科技研发完成,你得到了奖励__1__技能点,__2__金币。
|
||||
roll= 是时候转动命运之轮了!看看会发生什么吧!
|
||||
what= ?发生什么事了(你因为开小差没有参与转盘抽奖!)
|
||||
sorry= 抢劫!你失去了 __1__ 金币!
|
||||
nbone= 你的数字为1,你获得了 __1__ 金币奖励!
|
||||
nb2= 你获得了一个世外高人的指点!奖励 __1__ 点RPG
|
||||
nb3= 你被路边的小老头暴打了一顿!奖励 __1__ 点体力
|
||||
nb4= 虫子来了怎么办?跑把少年! 奖励 __1__ 点敏捷
|
||||
nb5= 这是魔法棒?!奖励 __1__ 点魔法值
|
||||
nb6= 抬杠抬杠,你在无情的抬杠。奖励 __1__ 点力量!
|
||||
nb7= 额,什么也没发生,很平静的度过了,这25波?
|
||||
nb8= ?缩小术,你中了名侦探柯南的暗算,损失 __1__ 经验!
|
||||
nb9= (⊙o⊙)…,你得到了一条鱼?
|
||||
nb10= 哦,出海打渔,捞到了1条鱼,别忘了分别人点!
|
||||
nb11= 我方无人机已就绪!你获得了 __1__ 台防御无人机胶囊!
|
||||
nb12= 因为暴饮暴食。你增长的更快了。获得 __1__ 点xp!
|
||||
nb14= 1个小礼包,里面会有什么呢?
|
||||
nb13= 一等奖! __1__ 金币!恭喜
|
||||
nb15= 请保护环境,少挖石头,你失去了 __1__ 点力量
|
||||
nb16= 你在干嘛?拿香蕉施法吗?你失去了 __1__ 点法力
|
||||
nb17= 你因为服用兴奋剂,而产生了副作用!失去了 __1__ 点敏捷
|
||||
nb18= 有人给你下毒了!快去找解药。失去了 __1__ 点活力!
|
||||
|
||||
nopoint= 你没有足够的点数用来扣除,所以我决定拿走你 __1__ 金币
|
||||
|
||||
joingame= 欢迎,新玩家请阅读地图信息! \n 地图纪录:\n 单人模式:存活700波! \n 纪录作者:wwwax \n 通关: 无 \n \n 多人模式: 985波。\n 交流群:701077913
|
||||
|
||||
usecar= 你在前一百波中使用了汽车,失去了领取奖励的资格,下次继续努力
|
||||
usecar2= 达成挑战,获得50点技能点奖励,恭喜!
|
||||
lucknb= 你的好运值为
|
||||
whatopen= 哦,你开出了什么呢
|
||||
noenough= 兄弟,你钱不够啊
|
||||
pass= 你通关了!!!!!!!Nice!通关波数为__1__
|
||||
times= 你已经发射了__1__个火箭,你每发射1个火箭奖励就会重复一次!
|
||||
reward= 这是第__1__个火箭!,奖励__2__技能点,__3__金币。
|
||||
lost= 火箭发射井被摧毁了,游戏失败!,你存活了__1__波。
|
||||
openchest= 花费3千金币,打开这个箱子,你有机会获得MK2!
|
||||
buyxp= 花费5千金币,购买1000点经验!
|
||||
buyover= 你成功购买了1000点经验!
|
||||
getxpfromwave= 你又坚持了一波,获得10点经验!
|
||||
|
||||
relax1= 你知道瑞克和莫蒂吗?这是一部充满奇怪和古怪的成人动画片。瑞克带着莫蒂去探索行星,路上非常多好玩的事情。这很有趣。我强烈建议你去看看。
|
||||
relax2= 我小的时候只玩一个游戏,就是魔兽争霸3,我从小学就开始玩了。目前已经过去14年了!
|
||||
relax3= 我小时候总是听闻一些奇怪的故事。例如:百慕大三角,尼斯湖水怪,球形闪电。我上初中的时候都还以为这是真的事情!
|
||||
relax4= 异星工厂这个游戏已经出了5年了,直到2020年它才推出了正式版。这么多年来,异星工厂一直保持着更新,并且没有降价过,我觉得它是一个非常良心的游戏。
|
||||
relax5= 你是否觉得这个游戏过于疯狂?是的,我也是这样想的!
|
||||
relax6= 在中国,父母都会问小孩,你将来想要做什么,然后告诉自己的孩子,要立志成为科学家。(但我不知道,现在是不是这样了)
|
||||
relax7= 有个心理学效应,叫巴纳姆效应,人很容易相信一个笼统的一般性的人格描述,并认为它特别适合自己并准确地揭示了自己的人格特点,即使内容空洞。
|
||||
relax8= 为什么植物大战僵尸2,没有电脑版?
|
||||
relax9= 月亮背后住着一个恶魔,它总是从地球上抓兔子来吃。我们必须组织宇航员军队,去解救兔子!
|
||||
relax10= 可恶,为什么1+1=2,而不是11?这一定是哪里弄错了。
|
||||
relax11= 这个世界为什么没有魔法?是我走错世界了吗?
|
||||
relax12= 你有女朋友吗?啊?你没有女朋友还来玩异星工厂,快去找个女朋友!
|
||||
relax13= 你试过把啤酒和可口可乐一起喝吗?会是什么味道呢?
|
||||
relax14= 不能放弃,永远别放弃。除非你玩的是异星工厂
|
||||
relax15= 你听说过飞行培训班吗?你只要花1万块钱,就能学会如何飞行,呃,用手?
|
||||
relax16= 我曾经在路边最多捡到过50块钱!这是在我小学的时候,哦,这是发家致富的第一桶金。
|
||||
relax17= 实现一件事情的最好办法就是叫别人来帮忙,第二个办法就是假装自己什么都不会。
|
||||
relax18= 要照顾好自己,不要生病,不要让人担心
|
||||
relax19= 团结就是力量,我们可以一起建立一个大工厂。也可以一起吃一个小饼干?
|
||||
relax20= 天啊,写地图太累了,这个地图我已经写了一个多月了。从2020年12月开始,到1月20日目前。唉。
|
||||
|
||||
single= 勇士!单人挑战是很不容易的事情,我为你准备了一些物品!注意查收!
|
||||
gambel= 花费1000金币有概率得2500金币,或者,什么都没有。
|
||||
gambel1= 你赢得了2500000金币!
|
||||
gambel2= 哦,你什么也没得到。
|
||||
|
||||
bag_isfull= 卧槽,我背包居然满了,扎了我一手的矿!
|
||||
|
||||
too_many= 你已经有了太多火焰炮塔!
|
||||
ok_many= 这是第 __1__ 个火焰塔,你最多能拥有12个!
|
||||
|
||||
buy_wall_over= __1__ 升级了墙和所有炮塔的生命值,现在墙有__2__ 倍生命了!
|
||||
buy_health_wall= 升级墙和所有炮塔的10%的生命值
|
||||
|
||||
buy_arty_dam= 升级10%的重炮伤害
|
||||
player_biter_health= 升级10%的友军虫子血量
|
||||
buy_arty_over= __1__ 购买了重炮伤害,现在有 __2__ 伤害了!
|
||||
buy_player_biter_over= __1__ 购买了友军虫子血量,现在友军虫子有 __2__ 倍生命了!
|
||||
player_spider_health= 升级蜘蛛10%的生命值
|
||||
buy_spider_health_over= __1__ 升级了蜘蛛10%的生命值!,蜘蛛现在有 __2__ 生命了!
|
||||
|
||||
player_biter_dam= 升级友军虫子 10%的伤害
|
||||
buy_biter_dam= __1__ 购买了虫子伤害 !,我方虫子现在有 __2__ 倍伤害了!
|
||||
easy= 想要放松一下
|
||||
med= 想要有些挑战性
|
||||
hard= 我爱挑战!
|
||||
|
||||
cap_upgrad= 该项目已达目前波次的升级上限!
|
||||
buy_cap_over= __1__ 购买了升级上限,现在升级上限为 __2__ !
|
||||
buy_cap= 购买升级上限。
|
@ -1,15 +1,15 @@
|
||||
[rpg_main]
|
||||
no_valid_surface=无指定操作名
|
||||
flame_boots_worn_out=你的火焰鞋穿坏.
|
||||
flame_boots_worn_out=你的火焰鞋穿坏了.
|
||||
flame_mana_remaining=剩余魔法:__1__
|
||||
one_punch_text=暴击
|
||||
mana_casting_too_fast= __1__ 魔法还有很多, 像 __1__ 迅速创建出, 然后挥舞着他们的魔杖,说一些难以理解的词.
|
||||
mana_casting_too_fast= __1__ 魔法还有很多, 像 __2__ 迅速创建出, 然后挥舞着他们的魔杖,说一些难以理解的词.
|
||||
low_level=等级不够.
|
||||
not_inside_pos=你挥动你的魔杖, 但意识到它不能达到.
|
||||
no_mana=你没有足够的魔力.
|
||||
suicidal_comfylatron=您挥舞着魔杖,__1__在运行!
|
||||
warped_ok=有轻微伤害自己的行为.
|
||||
object_spawned=__1__正在制造.\n 你挥动你的魔杖和 __1__ 出现.
|
||||
object_spawned= 正在施法!.\n 你挥动你的魔杖和 __1__ 出现.
|
||||
out_of_reach=无法在给制定位置创建物体.
|
||||
|
||||
[rpg_functions]
|
||||
@ -56,7 +56,7 @@ mana_max=这是你的最大魔力值。你可以通过增加你的魔法技能
|
||||
mining_name=挖掘\n速度
|
||||
slot_name=背包\n加成
|
||||
melee_name=近战\n伤害
|
||||
one_punch_chance=命中生命: __1__\n暴击几率: __2__ %
|
||||
one_punch_chance=命中生命: __1__\n暴击几率: __2__ %\n +__3__ [img=recipe.defender-capsule]
|
||||
one_punch_disabled=暴击被禁用
|
||||
bonus_tooltip=到达距离加成: __1__\n建筑距离加成: __2__\n物品投掷距离加成: __3__\n拾取战利品距离加成: __4__\n物品拾取距离加成: __5__\n资源到达距离加成: __6__\n修理速度: __7__
|
||||
reach_distance=到达\n距离
|
||||
@ -88,7 +88,7 @@ movement_text_tooltip=不想像闪电一样奔跑吗?\n你可以在这里切
|
||||
stone_path_label=采矿时启用石路?
|
||||
stone_path_tooltip=启用此选项将在您挖掘时自动创建石头路径。
|
||||
one_punch_label=启用暴击?
|
||||
one_punch_tooltip=启用此选项将有一次击打敌人的机会。
|
||||
one_punch_tooltip=启用此选项将有一次击打敌人的机会,不能装备枪和子弹!
|
||||
one_punch_globally=启用全局。
|
||||
flameboots_label=启用火焰靴?
|
||||
flameboots_tooltip=当子弹未击中。
|
||||
@ -103,17 +103,17 @@ allocation_label=选择要自动分配的技能。
|
||||
allocation_tooltip=这将自动将所有可用的点分配给给定的节点。
|
||||
|
||||
[spells]
|
||||
acid_stream=Bitter Spew
|
||||
railgun_beam=Shoop Da Whoop!!
|
||||
raw_fish=Conjure Raw-fish
|
||||
comfylatron=Suicidal Comfylatron
|
||||
distractor=Distractor Capsule
|
||||
warp=Warp Gate
|
||||
acid_stream=沙虫口水
|
||||
railgun_beam=轨道炮
|
||||
raw_fish=生成鱼
|
||||
comfylatron=自爆机器人
|
||||
distractor=防御无人机
|
||||
warp=回城
|
||||
|
||||
|
||||
[allocations]
|
||||
deactivated=Deactivated
|
||||
str=Strength
|
||||
mag=Magicka
|
||||
dex=Dexterity
|
||||
vit=Vitality
|
||||
deactivated=不自动分配
|
||||
str=力量
|
||||
mag=魔法
|
||||
dex=敏捷
|
||||
vit=活力
|
||||
|
314
maps/amap/basic_markets.lua
Normal file
314
maps/amap/basic_markets.lua
Normal file
@ -0,0 +1,314 @@
|
||||
local Public = {}
|
||||
|
||||
local market = {}
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
|
||||
local blacklist = {
|
||||
-- ['cargo-wagon'] = true,
|
||||
-- ['locomotive'] = true,
|
||||
-- ['artillery-wagon'] = true,
|
||||
-- ['artillery-turret'] = true,
|
||||
-- ['fluid-wagon'] = true,
|
||||
-- ['land-mine'] = true,
|
||||
['car'] = true,
|
||||
['tank'] = true,
|
||||
['spidertron'] = true
|
||||
}
|
||||
|
||||
market.weapons = {
|
||||
['pistol'] = {value = 10, rarity = 1},
|
||||
['submachine-gun'] = {value = 50, rarity = 2},
|
||||
['shotgun'] = {value = 40, rarity = 2},
|
||||
['combat-shotgun'] = {value = 400, rarity = 5},
|
||||
['rocket-launcher'] = {value = 500, rarity = 6},
|
||||
['flamethrower-turret'] = {value = 2000, rarity = 5},
|
||||
['land-mine'] = {value = 16, rarity = 4}
|
||||
}
|
||||
|
||||
market.ammo = {
|
||||
['firearm-magazine'] = {value = 3, rarity = 1},
|
||||
['piercing-rounds-magazine'] = {value = 6, rarity = 4},
|
||||
['uranium-rounds-magazine'] = {value = 20, rarity = 8},
|
||||
['shotgun-shell'] = {value = 3, rarity = 1},
|
||||
['piercing-shotgun-shell'] = {value = 8, rarity = 5},
|
||||
['cannon-shell'] = {value = 8, rarity = 4},
|
||||
['explosive-cannon-shell'] = {value = 12, rarity = 5},
|
||||
['uranium-cannon-shell'] = {value = 16, rarity = 7},
|
||||
['explosive-uranium-cannon-shell'] = {value = 20, rarity = 8},
|
||||
['artillery-shell'] = {value = 64, rarity = 7},
|
||||
['rocket'] = {value = 45, rarity = 7},
|
||||
['explosive-rocket'] = {value = 50, rarity = 7},
|
||||
['atomic-bomb'] = {value = 11000, rarity = 10},
|
||||
['flamethrower-ammo'] = {value = 20, rarity = 6},
|
||||
['explosives'] = {value = 3, rarity = 1}
|
||||
}
|
||||
|
||||
market.caspules = {
|
||||
['grenade'] = {value = 16, rarity = 2},
|
||||
['cluster-grenade'] = {value = 64, rarity = 5},
|
||||
['poison-capsule'] = {value = 32, rarity = 6},
|
||||
['slowdown-capsule'] = {value = 8, rarity = 1},
|
||||
['defender-capsule'] = {value = 8, rarity = 1},
|
||||
['distractor-capsule'] = {value = 40, rarity = 3},
|
||||
['destroyer-capsule'] = {value = 80, rarity = 5},
|
||||
['discharge-defense-remote'] = {value = 300, rarity = 8},
|
||||
['artillery-targeting-remote'] = {value = 32, rarity = 7},
|
||||
['raw-fish'] = {value = 10, rarity = 1}
|
||||
}
|
||||
|
||||
market.armor = {
|
||||
['light-armor'] = {value = 25, rarity = 1},
|
||||
['heavy-armor'] = {value = 250, rarity = 4},
|
||||
['modular-armor'] = {value = 750, rarity = 5},
|
||||
['power-armor'] = {value = 2500, rarity = 6},
|
||||
['power-armor-mk2'] = {value = 20000, rarity = 10}
|
||||
}
|
||||
|
||||
market.equipment = {
|
||||
['solar-panel-equipment'] = {value = 240, rarity = 3},
|
||||
['fusion-reactor-equipment'] = {value = 9000, rarity = 7},
|
||||
['energy-shield-equipment'] = {value = 400, rarity = 6},
|
||||
['energy-shield-mk2-equipment'] = {value = 4000, rarity = 8},
|
||||
['battery-equipment'] = {value = 160, rarity = 2},
|
||||
['battery-mk2-equipment'] = {value = 2000, rarity = 8},
|
||||
['personal-laser-defense-equipment'] = {value = 2500, rarity = 7},
|
||||
['discharge-defense-equipment'] = {value = 5000, rarity = 7},
|
||||
['belt-immunity-equipment'] = {value = 200, rarity = 1},
|
||||
['exoskeleton-equipment'] = {value = 800, rarity = 3},
|
||||
['personal-roboport-equipment'] = {value = 500, rarity = 3},
|
||||
['personal-roboport-mk2-equipment'] = {value = 5000, rarity = 8},
|
||||
['night-vision-equipment'] = {value = 250, rarity = 1}
|
||||
}
|
||||
|
||||
market.defense = {
|
||||
['stone-wall'] = {value = 4, rarity = 1},
|
||||
['gate'] = {value = 8, rarity = 1},
|
||||
['repair-pack'] = {value = 8, rarity = 1},
|
||||
['gun-turret'] = {value = 64, rarity = 1},
|
||||
['laser-turret'] = {value = 1024, rarity = 6},
|
||||
['flamethrower-turret'] = {value = 2048, rarity = 6},
|
||||
['artillery-turret'] = {value = 8192, rarity = 8},
|
||||
['rocket-silo'] = {value = 64000, rarity = 10}
|
||||
}
|
||||
|
||||
market.logistic = {
|
||||
['wooden-chest'] = {value = 3, rarity = 1},
|
||||
['iron-chest'] = {value = 10, rarity = 2},
|
||||
['steel-chest'] = {value = 24, rarity = 3},
|
||||
['storage-tank'] = {value = 32, rarity = 4},
|
||||
['transport-belt'] = {value = 4, rarity = 1},
|
||||
['fast-transport-belt'] = {value = 8, rarity = 4},
|
||||
['express-transport-belt'] = {value = 24, rarity = 7},
|
||||
['underground-belt'] = {value = 8, rarity = 1},
|
||||
['fast-underground-belt'] = {value = 32, rarity = 4},
|
||||
['express-underground-belt'] = {value = 64, rarity = 7},
|
||||
['splitter'] = {value = 16, rarity = 1},
|
||||
['fast-splitter'] = {value = 48, rarity = 4},
|
||||
['express-splitter'] = {value = 128, rarity = 7},
|
||||
['loader'] = {value = 256, rarity = 2},
|
||||
['fast-loader'] = {value = 512, rarity = 5},
|
||||
['express-loader'] = {value = 768, rarity = 8},
|
||||
['burner-inserter'] = {value = 4, rarity = 1},
|
||||
['inserter'] = {value = 8, rarity = 1},
|
||||
['long-handed-inserter'] = {value = 12, rarity = 2},
|
||||
['fast-inserter'] = {value = 16, rarity = 4},
|
||||
['filter-inserter'] = {value = 24, rarity = 5},
|
||||
['stack-inserter'] = {value = 96, rarity = 6},
|
||||
['stack-filter-inserter'] = {value = 128, rarity = 7},
|
||||
['small-electric-pole'] = {value = 2, rarity = 1},
|
||||
['medium-electric-pole'] = {value = 12, rarity = 4},
|
||||
['big-electric-pole'] = {value = 24, rarity = 5},
|
||||
['substation'] = {value = 96, rarity = 8},
|
||||
['pipe'] = {value = 2, rarity = 1},
|
||||
['pipe-to-ground'] = {value = 8, rarity = 1},
|
||||
['pump'] = {value = 16, rarity = 4},
|
||||
['logistic-robot'] = {value = 28, rarity = 5},
|
||||
['construction-robot'] = {value = 28, rarity = 3},
|
||||
['logistic-chest-active-provider'] = {value = 128, rarity = 7},
|
||||
['logistic-chest-passive-provider'] = {value = 128, rarity = 6},
|
||||
['logistic-chest-storage'] = {value = 128, rarity = 6},
|
||||
['logistic-chest-buffer'] = {value = 128, rarity = 7},
|
||||
['logistic-chest-requester'] = {value = 128, rarity = 7},
|
||||
['roboport'] = {value = 4096, rarity = 8}
|
||||
}
|
||||
|
||||
market.vehicles = {
|
||||
['rail'] = {value = 4, rarity = 1},
|
||||
['train-stop'] = {value = 32, rarity = 3},
|
||||
['rail-signal'] = {value = 8, rarity = 5},
|
||||
['rail-chain-signal'] = {value = 8, rarity = 5},
|
||||
['locomotive'] = {value = 400, rarity = 4},
|
||||
['cargo-wagon'] = {value = 200, rarity = 4},
|
||||
['fluid-wagon'] = {value = 300, rarity = 5},
|
||||
['artillery-wagon'] = {value = 8192, rarity = 8},
|
||||
['car'] = {value = 80, rarity = 1},
|
||||
['tank'] = {value = 1800, rarity = 5}
|
||||
}
|
||||
|
||||
market.wire = {
|
||||
['small-lamp'] = {value = 4, rarity = 1},
|
||||
['red-wire'] = {value = 4, rarity = 1},
|
||||
['green-wire'] = {value = 4, rarity = 1},
|
||||
['arithmetic-combinator'] = {value = 16, rarity = 1},
|
||||
['decider-combinator'] = {value = 16, rarity = 1},
|
||||
['constant-combinator'] = {value = 16, rarity = 1},
|
||||
['power-switch'] = {value = 16, rarity = 1},
|
||||
['programmable-speaker'] = {value = 24, rarity = 1},
|
||||
['landfill'] = {value = 5, rarity = 3}
|
||||
}
|
||||
|
||||
local function get_types()
|
||||
local types = {}
|
||||
for k, _ in pairs(market) do
|
||||
types[#types + 1] = k
|
||||
end
|
||||
return types
|
||||
end
|
||||
|
||||
local function get_resource_market_sells()
|
||||
local sells = {
|
||||
{price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'wood', count = 50}},
|
||||
{price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}},
|
||||
{price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}},
|
||||
{price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'stone', count = 50}},
|
||||
{price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'coal', count = 50}},
|
||||
{price = {{'coin', random(8, 16)}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}},
|
||||
{price = {{'coin', random(2, 4)}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 1}}
|
||||
}
|
||||
table.shuffle_table(sells)
|
||||
return sells
|
||||
end
|
||||
|
||||
local function get_resource_market_buys()
|
||||
local buys = {
|
||||
{price = {{'wood', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}},
|
||||
{price = {{'iron-ore', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}},
|
||||
{price = {{'copper-ore', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}},
|
||||
{price = {{'stone', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}},
|
||||
{price = {{'coal', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}},
|
||||
{price = {{'uranium-ore', random(8, 10)}}, offer = {type = 'give-item', item = 'coin'}},
|
||||
{price = {{'water-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(1, 2)}},
|
||||
{price = {{'lubricant-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(3, 6)}},
|
||||
{price = {{'sulfuric-acid-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(4, 8)}},
|
||||
{price = {{'light-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(2, 4)}},
|
||||
{price = {{'heavy-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(2, 4)}},
|
||||
{price = {{'petroleum-gas-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(3, 5)}}
|
||||
}
|
||||
table.shuffle_table(buys)
|
||||
return buys
|
||||
end
|
||||
|
||||
local function get_market_item_list(rarity)
|
||||
if rarity < 1 then
|
||||
rarity = 1
|
||||
end
|
||||
if rarity > 10 then
|
||||
rarity = 10
|
||||
end
|
||||
local types = get_types()
|
||||
local list = {}
|
||||
for i = 1, 9 do
|
||||
local branch = market[types[i]]
|
||||
for k, item in pairs(branch) do
|
||||
--if item.rarity <= rarity and item.rarity + 7 >= rarity then
|
||||
if item.rarity <= rarity then
|
||||
local price = random(floor(item.value * 0.75), floor(item.value * 1.25))
|
||||
if price < 1 then
|
||||
price = 1
|
||||
end
|
||||
if price > 64000 then
|
||||
price = 64000
|
||||
end
|
||||
list[#list + 1] = {price = {{'coin', price}}, offer = {type = 'give-item', item = k}}
|
||||
end
|
||||
end
|
||||
end
|
||||
if #list == 0 then
|
||||
return false
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function Public.get_random_item(rarity, sell, buy)
|
||||
rarity = rarity or 0
|
||||
local items = get_market_item_list(rarity)
|
||||
if not items then
|
||||
return
|
||||
end
|
||||
if #items > 0 then
|
||||
table.shuffle_table(items)
|
||||
end
|
||||
|
||||
local items_return = {}
|
||||
|
||||
for i = 1, 25, 1 do
|
||||
local item = items[i]
|
||||
if not item then
|
||||
break
|
||||
end
|
||||
if not blacklist[item.offer.item] then
|
||||
items_return[#items_return + 1] = items[i]
|
||||
end
|
||||
end
|
||||
|
||||
if sell then
|
||||
local sells = get_resource_market_sells()
|
||||
for i = 1, random(1, 25), 1 do
|
||||
items_return[#items_return + 1] = sells[i]
|
||||
end
|
||||
end
|
||||
|
||||
if buy then
|
||||
local buys = get_resource_market_buys()
|
||||
for i = 1, random(1, 25), 1 do
|
||||
items_return[#items_return + 1] = buys[i]
|
||||
end
|
||||
end
|
||||
|
||||
return items_return
|
||||
end
|
||||
|
||||
function Public.mountain_market(surface, position, rarity, buy)
|
||||
if (rarity <= 1)
|
||||
then
|
||||
rarity = 1
|
||||
end
|
||||
-- game.print(rarity)
|
||||
local types = get_types()
|
||||
table.shuffle_table(types)
|
||||
local items = get_market_item_list(rarity)
|
||||
if not items then
|
||||
return
|
||||
end
|
||||
if #items > 0 then
|
||||
table.shuffle_table(items)
|
||||
end
|
||||
local mrk = surface.create_entity({name = 'market', position = position, force = 'neutral'})
|
||||
mrk.destructible = false
|
||||
for i = 1, random(5, 10), 1 do
|
||||
local item = items[i]
|
||||
if not item then
|
||||
break
|
||||
end
|
||||
if not blacklist[item.offer.item] then
|
||||
mrk.add_market_item(items[i])
|
||||
end
|
||||
end
|
||||
|
||||
local sells = get_resource_market_sells()
|
||||
for i = 1, random(1, 3), 1 do
|
||||
mrk.add_market_item(sells[i])
|
||||
end
|
||||
|
||||
if buy then
|
||||
local buys = get_resource_market_buys()
|
||||
for i = 1, random(1, 3), 1 do
|
||||
mrk.add_market_item(buys[i])
|
||||
end
|
||||
end
|
||||
|
||||
return mrk
|
||||
end
|
||||
|
||||
return Public
|
200
maps/amap/biter_pets.lua
Normal file
200
maps/amap/biter_pets.lua
Normal file
@ -0,0 +1,200 @@
|
||||
local WPT = require 'maps.amap.table'
|
||||
|
||||
local nom_msg = {'munch', 'munch', 'yum'}
|
||||
|
||||
local Public = {}
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
|
||||
local function feed_floaty_text(unit)
|
||||
unit.surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = unit.position,
|
||||
text = nom_msg[random(1, #nom_msg)],
|
||||
color = {random(50, 100), 0, 255}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local function floaty_hearts(entity, c)
|
||||
local position = {x = entity.position.x - 0.75, y = entity.position.y - 1}
|
||||
local b = 1.35
|
||||
for _ = 1, c, 1 do
|
||||
local p = {
|
||||
(position.x + 0.4) + (b * -1 + random(0, b * 20) * 0.1),
|
||||
position.y + (b * -1 + random(0, b * 20) * 0.1)
|
||||
}
|
||||
entity.surface.create_entity({name = 'flying-text', position = p, text = '♥', color = {random(150, 255), 0, 255}})
|
||||
end
|
||||
end
|
||||
|
||||
local function tame_unit_effects(player, entity)
|
||||
floaty_hearts(entity, 7)
|
||||
|
||||
rendering.draw_text {
|
||||
text = '~' .. player.name .. "'s pet~",
|
||||
surface = player.surface,
|
||||
target = entity,
|
||||
target_offset = {0, -2.6},
|
||||
color = {
|
||||
r = player.color.r * 0.6 + 0.25,
|
||||
g = player.color.g * 0.6 + 0.25,
|
||||
b = player.color.b * 0.6 + 0.25,
|
||||
a = 1
|
||||
},
|
||||
scale = 1.05,
|
||||
font = 'default-large-semibold',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
end
|
||||
|
||||
local function find_unit(player, entity)
|
||||
local units =
|
||||
player.surface.find_entities_filtered(
|
||||
{
|
||||
type = 'unit',
|
||||
area = {{entity.position.x - 1, entity.position.y - 1}, {entity.position.x + 1, entity.position.y + 1}},
|
||||
limit = 1
|
||||
}
|
||||
)
|
||||
return units[1]
|
||||
end
|
||||
|
||||
local function feed_pet(unit)
|
||||
if unit.prototype.max_health == unit.health then
|
||||
return
|
||||
end
|
||||
unit.health = unit.health + 8 + floor(unit.prototype.max_health * 0.05)
|
||||
feed_floaty_text(unit)
|
||||
floaty_hearts(unit, random(1, 2))
|
||||
return true
|
||||
end
|
||||
|
||||
local function is_valid_player(player, unit)
|
||||
if not player.character then
|
||||
return
|
||||
end
|
||||
if not player.character.valid then
|
||||
return
|
||||
end
|
||||
if player.surface.index ~= unit.surface.index then
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.biter_pets_tame_unit(player, unit, forced)
|
||||
local biter_pets = WPT.get('biter_pets')
|
||||
|
||||
if biter_pets[player.index] then
|
||||
return false
|
||||
end
|
||||
|
||||
if not forced then
|
||||
if random(1, floor(unit.prototype.max_health * 0.01) + 1) ~= 1 then
|
||||
feed_floaty_text(unit)
|
||||
return true
|
||||
end
|
||||
end
|
||||
if unit.force.index == player.force.index then
|
||||
return false
|
||||
end
|
||||
unit.ai_settings.allow_destroy_when_commands_fail = false
|
||||
unit.ai_settings.allow_try_return_to_spawner = false
|
||||
unit.force = player.force
|
||||
unit.set_command({type = defines.command.wander, distraction = defines.distraction.by_enemy})
|
||||
biter_pets[player.index] = {last_command = 0, entity = unit}
|
||||
tame_unit_effects(player, unit)
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.tame_unit_for_closest_player(unit)
|
||||
local valid_players = {}
|
||||
for _, player in pairs(game.connected_players) do
|
||||
if is_valid_player(player, unit) then
|
||||
table.insert(valid_players, player)
|
||||
end
|
||||
end
|
||||
|
||||
local nearest_player = valid_players[1]
|
||||
if not nearest_player then
|
||||
return
|
||||
end
|
||||
|
||||
Public.biter_pets_tame_unit(nearest_player, unit, true)
|
||||
end
|
||||
|
||||
local function command_unit(entity, player)
|
||||
if entity.surface ~= player.surface then
|
||||
return
|
||||
end
|
||||
local square_distance = (player.position.x - entity.position.x) ^ 2 + (player.position.y - entity.position.y) ^ 2
|
||||
|
||||
--Pet will follow, if the player is between a distance of 8 to 160 tiles away from it.
|
||||
if square_distance < 64 or square_distance > 25600 then
|
||||
entity.set_command({type = defines.command.wander, distraction = defines.distraction.by_enemy})
|
||||
else
|
||||
entity.set_command(
|
||||
{
|
||||
type = defines.command.go_to_location,
|
||||
destination_entity = player.character,
|
||||
radius = 4,
|
||||
distraction = defines.distraction.by_damage
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_changed_position(event)
|
||||
local biter_pets = WPT.get('biter_pets')
|
||||
|
||||
if random(1, 100) ~= 1 then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
if not biter_pets[player.index] then
|
||||
return
|
||||
end
|
||||
if not biter_pets[player.index].entity then
|
||||
biter_pets[player.index] = nil
|
||||
return
|
||||
end
|
||||
if not biter_pets[player.index].entity.valid then
|
||||
biter_pets[player.index] = nil
|
||||
return
|
||||
end
|
||||
if not player.character then
|
||||
return
|
||||
end
|
||||
if biter_pets[player.index].last_command + 600 > game.tick then
|
||||
return
|
||||
end
|
||||
biter_pets[player.index].last_command = game.tick
|
||||
command_unit(biter_pets[player.index].entity, player)
|
||||
end
|
||||
|
||||
local function on_player_dropped_item(event)
|
||||
local player = game.players[event.player_index]
|
||||
if event.entity.stack.name ~= 'raw-fish' then
|
||||
return
|
||||
end
|
||||
local unit = find_unit(player, event.entity)
|
||||
if not unit then
|
||||
return
|
||||
end
|
||||
if Public.biter_pets_tame_unit(player, unit, false) then
|
||||
event.entity.destroy()
|
||||
return
|
||||
end
|
||||
if unit.force.index == player.force.index then
|
||||
feed_pet(unit)
|
||||
end
|
||||
end
|
||||
|
||||
local event = require 'utils.event'
|
||||
event.add(defines.events.on_player_dropped_item, on_player_dropped_item)
|
||||
event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
||||
|
||||
return Public
|
133
maps/amap/biters_yield_coins.lua
Normal file
133
maps/amap/biters_yield_coins.lua
Normal file
@ -0,0 +1,133 @@
|
||||
local Event = require 'utils.event'
|
||||
local RPG_Settings = require 'modules.rpg.table'
|
||||
local insert = table.insert
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
|
||||
local coin_yield = {
|
||||
['behemoth-biter'] = 5,
|
||||
['behemoth-spitter'] = 5,
|
||||
['behemoth-worm-turret'] = 20,
|
||||
['big-biter'] = 3,
|
||||
['big-spitter'] = 3,
|
||||
['big-worm-turret'] = 16,
|
||||
['biter-spawner'] = 32,
|
||||
['medium-biter'] = 2,
|
||||
['medium-spitter'] = 2,
|
||||
['medium-worm-turret'] = 12,
|
||||
['small-biter'] = 1,
|
||||
['small-spitter'] = 1,
|
||||
['small-worm-turret'] = 8,
|
||||
['spitter-spawner'] = 32
|
||||
}
|
||||
|
||||
local entities_that_earn_coins = {
|
||||
['artillery-turret'] = true,
|
||||
['gun-turret'] = true,
|
||||
['laser-turret'] = true,
|
||||
['flamethrower-turret'] = true
|
||||
}
|
||||
|
||||
--extra coins for "boss" biters from biter_health_booster.lua
|
||||
local function get_coin_count(entity)
|
||||
local coin_count = coin_yield[entity.name]
|
||||
if not coin_count then
|
||||
return
|
||||
end
|
||||
if not global.biter_health_boost_units then
|
||||
return coin_count
|
||||
end
|
||||
local unit_number = entity.unit_number
|
||||
if not unit_number then
|
||||
return coin_count
|
||||
end
|
||||
if not global.biter_health_boost_units[unit_number] then
|
||||
return coin_count
|
||||
end
|
||||
if not global.biter_health_boost_units[unit_number][3] then
|
||||
return coin_count
|
||||
end
|
||||
local m = 1 / global.biter_health_boost_units[unit_number][2]
|
||||
coin_count = floor(coin_count * m)
|
||||
if coin_count < 1 then
|
||||
return 1
|
||||
end
|
||||
return coin_count
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.force.index ~= 2 then
|
||||
return
|
||||
end
|
||||
|
||||
local cause = event.cause
|
||||
|
||||
local coin_count = get_coin_count(entity)
|
||||
if not coin_count then
|
||||
return
|
||||
end
|
||||
|
||||
local players_to_reward = {}
|
||||
local p
|
||||
local reward_has_been_given = false
|
||||
|
||||
if cause then
|
||||
if cause.valid then
|
||||
if (cause and cause.name == 'character' and cause.player) then
|
||||
p = cause.player
|
||||
end
|
||||
|
||||
if cause.name == 'character' then
|
||||
insert(players_to_reward, cause)
|
||||
reward_has_been_given = true
|
||||
end
|
||||
if cause.type == 'car' then
|
||||
local player = cause.get_driver()
|
||||
local passenger = cause.get_passenger()
|
||||
if player then
|
||||
insert(players_to_reward, player.player)
|
||||
end
|
||||
if passenger then
|
||||
insert(players_to_reward, passenger.player)
|
||||
end
|
||||
reward_has_been_given = true
|
||||
end
|
||||
if cause.type == 'locomotive' then
|
||||
local train_passengers = cause.train.passengers
|
||||
if train_passengers then
|
||||
for _, passenger in pairs(train_passengers) do
|
||||
insert(players_to_reward, passenger)
|
||||
end
|
||||
reward_has_been_given = true
|
||||
end
|
||||
end
|
||||
for _, player in pairs(players_to_reward) do
|
||||
local forest_zone
|
||||
if p then
|
||||
forest_zone = RPG_Settings.get_value_from_player(p.index, 'forest_zone')
|
||||
end
|
||||
if forest_zone then
|
||||
if random(1, 12) == 1 then
|
||||
player.insert({name = 'coin', count = coin_count})
|
||||
end
|
||||
else
|
||||
player.insert({name = 'coin', count = coin_count})
|
||||
end
|
||||
end
|
||||
end
|
||||
if entities_that_earn_coins[cause.name] then
|
||||
event.entity.surface.spill_item_stack(cause.position, {name = 'coin', count = coin_count}, true)
|
||||
reward_has_been_given = true
|
||||
end
|
||||
end
|
||||
|
||||
if reward_has_been_given == false then
|
||||
event.entity.surface.spill_item_stack(event.entity.position, {name = 'coin', count = coin_count}, true)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
66
maps/amap/burden.lua
Normal file
66
maps/amap/burden.lua
Normal file
@ -0,0 +1,66 @@
|
||||
local Event = require 'utils.event'
|
||||
local Modifier = require 'player_modifiers'
|
||||
local Color = require 'utils.color_presets'
|
||||
|
||||
local function validate_player(player)
|
||||
if not player then
|
||||
return false
|
||||
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.players[player.name] then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function compute_fullness(player)
|
||||
local inv = player.get_inventory(defines.inventory.character_main)
|
||||
local max_stacks = #inv
|
||||
local num_stacks = 0
|
||||
|
||||
local contents = inv.get_contents()
|
||||
for item, count in pairs(contents) do
|
||||
local stack_size = 1
|
||||
if game.item_prototypes[item].stackable then
|
||||
stack_size = game.item_prototypes[item].stack_size
|
||||
end
|
||||
|
||||
num_stacks = num_stacks + count / stack_size
|
||||
end
|
||||
|
||||
return num_stacks / max_stacks
|
||||
end
|
||||
|
||||
local function check_burden(event)
|
||||
local player_modifiers = Modifier.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
if not validate_player(player) then
|
||||
return
|
||||
end
|
||||
local fullness = compute_fullness(player)
|
||||
-- player_modifiers[player.index].character_running_speed_modifier['randomness'] = 0.3 - fullness
|
||||
--player_modifiers[player.index].character_mining_speed_modifier['randomess'] = 0.3 - fullness
|
||||
-- Modifier.update_player_modifiers(player)
|
||||
if fullness >= 0.9 and fullness <= 0.901 then
|
||||
player.print('Maybe you should drop some of that inventory to lessen the burden.', Color.red)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init(event)
|
||||
script.on_event(defines.events.on_player_main_inventory_changed, check_burden)
|
||||
end
|
||||
|
||||
local function on_load(event)
|
||||
script.on_event(defines.events.on_player_main_inventory_changed, check_burden)
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.on_load(on_load)
|
256
maps/amap/buried_enemies.lua
Normal file
256
maps/amap/buried_enemies.lua
Normal file
@ -0,0 +1,256 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local BiterRolls = require 'modules.wave_defense.biter_rolls'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local WPT = require 'maps.amap.table'
|
||||
|
||||
local traps = {}
|
||||
|
||||
Global.register(
|
||||
traps,
|
||||
function(t)
|
||||
traps = t
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
local sqrt = math.sqrt
|
||||
|
||||
local spawn_amount_rolls = {}
|
||||
for a = 48, 1, -1 do
|
||||
spawn_amount_rolls[#spawn_amount_rolls + 1] = floor(a ^ 5)
|
||||
end
|
||||
|
||||
local random_particles = {
|
||||
'dirt-2-stone-particle-medium',
|
||||
'dirt-4-dust-particle',
|
||||
'coal-particle'
|
||||
}
|
||||
|
||||
local s_random_particles = #random_particles
|
||||
|
||||
local function create_particles(data)
|
||||
local surface = data.surface
|
||||
local position = data.position
|
||||
local amount = data.amount
|
||||
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
for i = 1, amount, 1 do
|
||||
local m = random(6, 12)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle(
|
||||
{
|
||||
name = random_particles[random(1, s_random_particles)],
|
||||
position = position,
|
||||
frame_speed = 0.1,
|
||||
vertical_speed = 0.1,
|
||||
height = 0.1,
|
||||
movement = {m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01)}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_biters(data)
|
||||
local surface = data.surface
|
||||
if not (surface and surface.valid) then
|
||||
return
|
||||
end
|
||||
local position = data.position
|
||||
local h = floor(abs(position.y))
|
||||
local wave_number = WD.get('wave_number')
|
||||
local max_biters = WPT.get('biters')
|
||||
|
||||
|
||||
if max_biters.amount >= max_biters.limit then
|
||||
return
|
||||
end
|
||||
|
||||
if not position then
|
||||
position = surface.find_non_colliding_position('small-biter', position, 10, 1)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function trigger_health()
|
||||
local m = 0.0015
|
||||
|
||||
m = m * 1.05
|
||||
|
||||
local boosted_health = 1.25
|
||||
|
||||
if wave_number <= 10 then
|
||||
wave_number = 10
|
||||
end
|
||||
|
||||
boosted_health = boosted_health * (wave_number * 0.02)
|
||||
|
||||
local sum = boosted_health * 5
|
||||
|
||||
sum = sum + m
|
||||
|
||||
if sum >= 100 then
|
||||
sum = 100
|
||||
end
|
||||
|
||||
return sum
|
||||
end
|
||||
|
||||
BiterRolls.wave_defense_set_unit_raffle(h * 0.20)
|
||||
|
||||
local unit
|
||||
if random(1, 3) == 1 then
|
||||
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = position})
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
else
|
||||
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position})
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
end
|
||||
|
||||
if random(1, 32) == 1 then
|
||||
local sum = trigger_health()
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
BiterHealthBooster.add_boss_unit(unit, sum, 0.38)
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_worms(data)
|
||||
local max_biters = WPT.get('biters')
|
||||
|
||||
if max_biters.amount >= max_biters.limit then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = data.surface
|
||||
if not (surface and surface.valid) then
|
||||
return
|
||||
end
|
||||
local position = data.position
|
||||
BiterRolls.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
|
||||
surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = position})
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
end
|
||||
|
||||
function Public.buried_biter(surface, position, max)
|
||||
if not (surface and surface.valid) then
|
||||
return
|
||||
end
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
if not position.x then
|
||||
return
|
||||
end
|
||||
if not position.y then
|
||||
return
|
||||
end
|
||||
|
||||
local amount = 8
|
||||
local a = 0
|
||||
max = max or random(4, 6)
|
||||
|
||||
local ticks = amount * 30
|
||||
ticks = ticks + 90
|
||||
for t = 1, ticks, 1 do
|
||||
if not traps[game.tick + t] then
|
||||
traps[game.tick + t] = {}
|
||||
end
|
||||
|
||||
traps[game.tick + t][#traps[game.tick + t] + 1] = {
|
||||
callback = 'create_particles',
|
||||
data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4}
|
||||
}
|
||||
|
||||
if t > 90 then
|
||||
if t % 30 == 29 then
|
||||
a = a + 1
|
||||
traps[game.tick + t][#traps[game.tick + t] + 1] = {
|
||||
callback = 'spawn_biters',
|
||||
data = {surface = surface, position = {x = position.x, y = position.y}}
|
||||
}
|
||||
if a >= max then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.buried_worm(surface, position)
|
||||
if not (surface and surface.valid) then
|
||||
return
|
||||
end
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
if not position.x then
|
||||
return
|
||||
end
|
||||
if not position.y then
|
||||
return
|
||||
end
|
||||
|
||||
local amount = 8
|
||||
|
||||
local ticks = amount * 30
|
||||
ticks = ticks + 90
|
||||
local a = false
|
||||
for t = 1, ticks, 1 do
|
||||
if not traps[game.tick + t] then
|
||||
traps[game.tick + t] = {}
|
||||
end
|
||||
|
||||
traps[game.tick + t][#traps[game.tick + t] + 1] = {
|
||||
callback = 'create_particles',
|
||||
data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4}
|
||||
}
|
||||
|
||||
if not a then
|
||||
traps[game.tick + t][#traps[game.tick + t] + 1] = {
|
||||
callback = 'spawn_worms',
|
||||
data = {surface = surface, position = {x = position.x, y = position.y}}
|
||||
}
|
||||
a = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local callbacks = {
|
||||
['create_particles'] = create_particles,
|
||||
['spawn_biters'] = spawn_biters,
|
||||
['spawn_worms'] = spawn_worms
|
||||
}
|
||||
|
||||
local function on_tick()
|
||||
local t = game.tick
|
||||
if not traps[t] then
|
||||
return
|
||||
end
|
||||
for _, token in pairs(traps[t]) do
|
||||
local callback = token.callback
|
||||
local data = token.data
|
||||
local cbl = callbacks[callback]
|
||||
if callbacks[callback] then
|
||||
cbl(data)
|
||||
end
|
||||
end
|
||||
traps[t] = nil
|
||||
end
|
||||
|
||||
function Public.reset()
|
||||
for k, _ in pairs(traps) do
|
||||
traps[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
|
||||
return Public
|
297
maps/amap/caves.lua
Normal file
297
maps/amap/caves.lua
Normal file
@ -0,0 +1,297 @@
|
||||
--[[
|
||||
Exchange Strings
|
||||
|
||||
>>>eNp1UT1oFEEUfi/nkcsJonBNwMQrUtjsES/aHOFmTCMp1M5+b
|
||||
29OB/Z2ztldSLRwixQWQpo0pkmKNCZgJ2gXsVHQIGpjd5LGwiJBE
|
||||
AvhnNnd2VvX5IN5fPO9/xmAC3AbYuxTgKhdOeMI201vRMmk6ojBg
|
||||
ElLSJaXpxwZdpkluAqO6N7uLtGeKvNYf9Xq2D7TskqI5QqXwitWK
|
||||
PuB8P5VAsmYnyRGba2eDaXt8bCf5EZZJODOwZ3X0dos6DN6BPXRS
|
||||
B/Fhso/hBQqA5WWonTZEV4ghWv5LAi4d7dlhyutnmT3Q+Y5q61+6
|
||||
AZ84HImKwuN+RgzxYy+4H4QStbqcNufsuYbzWs6zjo17sTyVxoLM
|
||||
cqOy3s9gPp1dZb01oj4sPb8xrcHGwSTqRs0JUepst8xyrIht+ipr
|
||||
jlDrubqJN1/5kjSNFAt0qgKHZPEuaadiMf3Dh+/+P2ljX+eHX+62
|
||||
aEEj4yCOKkScCIzm081XplVwNQcktT1leCH9xo/CJZ1Rk2b7SfKR
|
||||
M0JwPPnzLV+EcxobVOmRrEX45fZ5NCQz6S4h3qIRV18Vpu32sQNs
|
||||
8kwoXSdIr1kvNPjEJXfhPwM3fGG70zbN7n+hUH+/4j8HgVljp7wD
|
||||
VXdsJuZ76VsGvWeHyfNjW7REoyhvvvAetn9CzJb1cQ=<<<
|
||||
]]
|
||||
|
||||
|
||||
--local List = require 'maps.chronosphere.production_list'
|
||||
--local Factories = require 'maps.chronosphere.production'
|
||||
local random = math.random
|
||||
local Alert = require 'utils.alert'
|
||||
require "player_modifiers"
|
||||
require "modules.rocks_broken_paint_tiles"
|
||||
require "modules.rocks_heal_over_time"
|
||||
require "modules.rocks_yield_ore_veins"
|
||||
local WPT = require 'maps.amap.table'
|
||||
require "modules.no_deconstruction_of_neutral_entities"
|
||||
local MT = require "maps.amap.basic_markets"
|
||||
local RPGtable = require 'modules.rpg.table'
|
||||
local Loot = require "maps.amap.loot"
|
||||
local get_noise = require "utils.get_noise"
|
||||
local Player_modifiers = require "player_modifiers"
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local math_abs = math.abs
|
||||
local Public = {}
|
||||
local BiterRolls = require 'modules.wave_defense.biter_rolls'
|
||||
local rock_raffle = {"sand-rock-big","sand-rock-big", "rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"}
|
||||
local size_of_rock_raffle = #rock_raffle
|
||||
local Pets = require 'maps.amap.biter_pets'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
|
||||
local function place_entity(surface, position)
|
||||
if math_random(1, 3) ~= 1 then
|
||||
surface.create_entity({name = rock_raffle[math_random(1, size_of_rock_raffle)], position = position, force = "neutral"})
|
||||
end
|
||||
end
|
||||
|
||||
local function is_scrap_area(noise)
|
||||
if noise > 0.67 then return end
|
||||
if noise < -0.67 then return end
|
||||
if noise > 0.33 then return true end
|
||||
if noise < -0.33 then return true end
|
||||
end
|
||||
|
||||
local function hidden_treasure(player, entity)
|
||||
|
||||
local rpg = RPGtable.get('rpg_t')
|
||||
|
||||
local magic = rpg[player.index].magicka
|
||||
|
||||
local msg = 'look,you find a treasure'
|
||||
|
||||
Alert.alert_player(player, 5, msg)
|
||||
|
||||
|
||||
Loot.add_rare(entity.surface, entity.position, 'wooden-chest', magic)
|
||||
|
||||
|
||||
end
|
||||
|
||||
local function register_spawner(spawner)
|
||||
local nests = WD.get('nests')
|
||||
if spawner.valid then
|
||||
nests[#nests + 1] = spawner
|
||||
end
|
||||
end
|
||||
|
||||
local function move_away_things(surface, area)
|
||||
for _, e in pairs(surface.find_entities_filtered({type = {"unit-spawner", "unit", "tree"}, area = area})) do
|
||||
local position = surface.find_non_colliding_position(e.name, e.position, 128, 4)
|
||||
if position then
|
||||
local entity = surface.create_entity({name = e.name, position = position, force = "enemy"})
|
||||
e.destroy()
|
||||
-- if (entity.name == "biter-spawner" or entity.name == "spitter-spawner") and entity.force.name == "enemy" then
|
||||
-- register_spawner(entity)
|
||||
-- end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vectors = {{0,0}, {1,0}, {-1,0}, {0,1}, {0,-1}}
|
||||
local function hidden_biter_pet(player, entity)
|
||||
|
||||
local pos = entity.position
|
||||
|
||||
BiterRolls.wave_defense_set_unit_raffle(math.sqrt(pos.x ^ 2 + pos.y ^ 2) * 0.25)
|
||||
local unit
|
||||
if random(1, 3) == 1 then
|
||||
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = pos})
|
||||
else
|
||||
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = pos})
|
||||
end
|
||||
Pets.biter_pets_tame_unit(game.players[player.index], unit, true)
|
||||
end
|
||||
local function hidden_biter(player, entity)
|
||||
|
||||
|
||||
local pos = entity.position
|
||||
BiterRolls.wave_defense_set_worm_raffle(math.sqrt(pos.x ^ 2 + pos.y ^ 2) * 0.19)
|
||||
BiterRolls.wave_defense_set_unit_raffle(math.sqrt(pos.x ^ 2 + pos.y ^ 2) * 0.25)
|
||||
local roll = math.random(1, 3)
|
||||
local unit
|
||||
if roll == 1 then
|
||||
|
||||
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = pos})
|
||||
elseif roll == 2 then
|
||||
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = pos})
|
||||
else
|
||||
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = pos})
|
||||
end
|
||||
end
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if entity.type ~= "simple-entity" then return end
|
||||
local surface = entity.surface
|
||||
for _, v in pairs(vectors) do
|
||||
local position = {entity.position.x + v[1], entity.position.y + v[2]}
|
||||
if not surface.get_tile(position).collides_with("resource-layer") then
|
||||
surface.set_tiles({{name = "landfill", position = position}}, true)
|
||||
end
|
||||
end
|
||||
if event.player_index then game.players[event.player_index].insert({name = "coin", count = 1}) end
|
||||
local player = game.players[event.player_index]
|
||||
--修复挖矿石路
|
||||
local rpg = RPGtable.get('rpg_t')
|
||||
local rpg_char = rpg[player.index]
|
||||
if rpg_char.stone_path then
|
||||
|
||||
entity.surface.set_tiles({{name = 'stone-path', position = entity.position}}, true)
|
||||
end
|
||||
|
||||
--挖出汽车
|
||||
if random(1,1024) < 2 then
|
||||
local position = {entity.position.x , entity.position.y }
|
||||
--local player = game.players[event.player_index]
|
||||
surface.create_entity({name = 'car', position = position, force = 'player'})
|
||||
Public.unstuck_player(player.index)
|
||||
local msg = ('you find a car!')
|
||||
Alert.alert_player(player, 15, msg)
|
||||
end
|
||||
--挖出虫巢
|
||||
|
||||
if random(1,200) < 2 then
|
||||
|
||||
local position = {entity.position.x , entity.position.y }
|
||||
local player = game.players[event.player_index]
|
||||
surface.create_entity({name = 'biter-spawner', position = position, force = 'enemy'})
|
||||
Public.unstuck_player(player.index)
|
||||
end
|
||||
--挖出宝藏
|
||||
if random(1,150) < 2 then
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
hidden_treasure(player,entity)
|
||||
|
||||
end
|
||||
--挖出宠物
|
||||
if random(1,170) < 3 then
|
||||
local player = game.players[event.player_index]
|
||||
hidden_biter_pet(player,entity)
|
||||
end
|
||||
--来挖个虫子
|
||||
if random(1,100) < 3 then
|
||||
local player = game.players[event.player_index]
|
||||
hidden_biter(player,entity)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--图块生成时
|
||||
local function on_chunk_generated(event)
|
||||
local surface = event.surface
|
||||
local this = WPT.get()
|
||||
if not(surface.index == game.surfaces[this.active_surface_index].index) then return end
|
||||
local seed = surface.map_gen_settings.seed
|
||||
local left_top_x = event.area.left_top.x
|
||||
local left_top_y = event.area.left_top.y
|
||||
local set_tiles = surface.set_tiles
|
||||
local get_tile = surface.get_tile
|
||||
local position
|
||||
local noise
|
||||
local tem_pos
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
position = {x = left_top_x + x, y = left_top_y + y}
|
||||
local q =position.x^2
|
||||
local w =position.y^2
|
||||
local maxs =math.sqrt(q + w)
|
||||
|
||||
if maxs <= 120 then
|
||||
if maxs > 117 then
|
||||
if surface.can_place_entity{name = "stone-wall", position = {x=position.x,y=position.y}, force=game.forces.player} then
|
||||
surface.create_entity{name = "stone-wall", position = {x=position.x,y=position.y}, force=game.forces.player}
|
||||
end
|
||||
end
|
||||
local h = math_abs(position.x)
|
||||
local k = math_abs(position.y)
|
||||
if maxs < 115 and maxs > 113 then
|
||||
if (1== h%7) or (1==k%7) then
|
||||
if surface.can_place_entity{name = "gun-turret", position = position, force=game.forces.player} then
|
||||
|
||||
local e = surface.create_entity{name = "gun-turret", position = position, force=game.forces.player}
|
||||
e.insert{name='firearm-magazine', count = 30}
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if not get_tile(position).collides_with("resource-layer") then
|
||||
noise = get_noise("scrapyard", position, seed)
|
||||
if is_scrap_area(noise) then
|
||||
set_tiles({{name = "dirt-" .. math_floor(math_abs(noise) * 12) % 4 + 3, position = position}}, true)
|
||||
|
||||
if maxs >= 3000 then
|
||||
local roll = math_random(1,1024)
|
||||
if roll <= 2 then
|
||||
BiterRolls.wave_defense_set_worm_raffle(math.sqrt(position.x ^ 2 + position.y ^ 2) * 0.19)
|
||||
surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = position, force = 'enemy'})
|
||||
end
|
||||
end
|
||||
if x+y > 33 and x+y < 40 then
|
||||
local b = math_random(1,200)
|
||||
--宝藏
|
||||
if b < 3 then
|
||||
local chest = 'iron-chest'
|
||||
Loot.add(surface, position, chest)
|
||||
end
|
||||
--中立建筑
|
||||
|
||||
--在我上面添加代码
|
||||
end
|
||||
--商店代码
|
||||
if y == 1 then
|
||||
if x == 1 then
|
||||
local a = math_random(1,8)
|
||||
if a == 1 then
|
||||
local q =math_abs(position.x)/80
|
||||
local w =math_abs(position.y)/80
|
||||
local maxs =math.floor(q+w)
|
||||
-- game.print(maxs)
|
||||
MT.mountain_market(surface,position,maxs)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
place_entity(surface, position)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
move_away_things(surface, event.area)
|
||||
end
|
||||
|
||||
|
||||
function Public.unstuck_player(index)
|
||||
local player = game.get_player(index)
|
||||
local surface = player.surface
|
||||
local position = surface.find_non_colliding_position('character', player.position, 32, 0.5)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
player.teleport(position, surface)
|
||||
end
|
||||
local function on_init()
|
||||
global.rocks_yield_ore_maximum_amount = 999
|
||||
global.rocks_yield_ore_base_amount = 100
|
||||
global.rocks_yield_ore_distance_modifier = 0.020
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
--Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
require "maps.amap.rocks_yield_ore"
|
187
maps/amap/diff.lua
Normal file
187
maps/amap/diff.lua
Normal file
@ -0,0 +1,187 @@
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local WPT = require 'maps.amap.table'
|
||||
local Difficulty = require 'modules.difficulty_vote_by_amount'
|
||||
local atry_talbe = require "maps.amap.enemy_arty"
|
||||
local function calc_players()
|
||||
local players = game.connected_players
|
||||
local check_afk_players = WPT.get('check_afk_players')
|
||||
if not check_afk_players then
|
||||
return #players
|
||||
end
|
||||
local total = 0
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
if player.afk_time < 36000 then
|
||||
total = total + 1
|
||||
end
|
||||
end
|
||||
if total <= 0 then
|
||||
total = 1
|
||||
end
|
||||
return total
|
||||
end
|
||||
|
||||
|
||||
local easy = function()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local player_count = calc_players()
|
||||
|
||||
wave_defense_table.max_active_biters = 768 + player_count * 180
|
||||
|
||||
if wave_defense_table.max_active_biters >= 4000 then
|
||||
wave_defense_table.max_active_biters = 4000
|
||||
end
|
||||
local wave_number = WD.get('wave_number')
|
||||
if wave_number >= 1500 then
|
||||
wave_number = 1500
|
||||
end
|
||||
-- threat gain / wave
|
||||
local max_threat = 1 + player_count * 0.1
|
||||
if max_threat >= 4 then
|
||||
max_threat = 4
|
||||
end
|
||||
|
||||
max_threat = max_threat + wave_number * 0.0013
|
||||
|
||||
WD.set_biter_health_boost(wave_number * 0.002+1)
|
||||
wave_defense_table.threat_gain_multiplier = max_threat
|
||||
|
||||
wave_defense_table.wave_interval = 4200 - player_count * 30
|
||||
if wave_defense_table.wave_interval < 1800 or wave_defense_table.threat <= 0 then
|
||||
wave_defense_table.wave_interval = 1800
|
||||
end
|
||||
local mintime = 7500 - player_count * 150
|
||||
if mintime <= 6000 then
|
||||
mintime = 6000
|
||||
end
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = mintime
|
||||
-- game.map_settings.enemy_expansion.max_expansion_cooldown = 104000
|
||||
|
||||
|
||||
end
|
||||
local med = function()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local player_count = calc_players()
|
||||
|
||||
wave_defense_table.max_active_biters = 768 + player_count * 220
|
||||
|
||||
if wave_defense_table.max_active_biters >= 4000 then
|
||||
wave_defense_table.max_active_biters = 4000
|
||||
end
|
||||
local wave_number = WD.get('wave_number')
|
||||
-- threat gain / wave
|
||||
if wave_number >= 1500 then
|
||||
wave_number = 1500
|
||||
end
|
||||
local max_threat = 1 + player_count * 0.1
|
||||
if max_threat >= 4 then
|
||||
max_threat = 4
|
||||
end
|
||||
|
||||
max_threat = max_threat + wave_number * 0.0013
|
||||
WD.set_biter_health_boost(wave_number * 0.002+1)
|
||||
wave_defense_table.threat_gain_multiplier = max_threat
|
||||
|
||||
wave_defense_table.wave_interval = 4200 - player_count * 45
|
||||
if wave_defense_table.wave_interval < 1800 or wave_defense_table.threat <= 0 then
|
||||
wave_defense_table.wave_interval = 1800
|
||||
end
|
||||
local mintime = 7500 - player_count * 240
|
||||
if mintime <= 3600 then
|
||||
mintime = 3600
|
||||
end
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = mintime
|
||||
-- game.map_settings.enemy_expansion.max_expansion_cooldown = 104000
|
||||
|
||||
end
|
||||
local hard = function()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local player_count = calc_players()
|
||||
|
||||
wave_defense_table.max_active_biters = 768 + player_count * 280
|
||||
|
||||
if wave_defense_table.max_active_biters >= 4000 then
|
||||
wave_defense_table.max_active_biters = 4000
|
||||
end
|
||||
|
||||
local wave_number = WD.get('wave_number')
|
||||
-- threat gain / wave
|
||||
if wave_number >= 1500 then
|
||||
wave_number = 1500
|
||||
end
|
||||
local max_threat = 1 + player_count * 0.1
|
||||
if max_threat >= 4 then
|
||||
max_threat = 4
|
||||
end
|
||||
|
||||
max_threat = max_threat + wave_number * 0.0013
|
||||
WD.set_biter_health_boost(wave_number * 0.002+1)
|
||||
wave_defense_table.threat_gain_multiplier = max_threat
|
||||
|
||||
wave_defense_table.wave_interval = 3900 - player_count * 60
|
||||
if wave_defense_table.wave_interval < 1800 or wave_defense_table.threat <= 0 then
|
||||
wave_defense_table.wave_interval = 1800
|
||||
end
|
||||
local mintime = 7500 - player_count * 300
|
||||
if mintime <= 3000 then
|
||||
mintime = 3000
|
||||
end
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = mintime
|
||||
-- game.map_settings.enemy_expansion.max_expansion_cooldown = 104000
|
||||
|
||||
end
|
||||
|
||||
local set_diff = function()
|
||||
|
||||
local game_lost = WPT.get('game_lost')
|
||||
if game_lost then
|
||||
return
|
||||
end
|
||||
|
||||
local diff= Difficulty.get()
|
||||
if diff.difficulty_vote_index == 1 then
|
||||
easy()
|
||||
end
|
||||
if diff.difficulty_vote_index == 2 then
|
||||
med()
|
||||
end
|
||||
if diff.difficulty_vote_index == 3 then
|
||||
hard()
|
||||
end
|
||||
|
||||
|
||||
--med()
|
||||
local wave_number = WD.get('wave_number')
|
||||
local damage_increase = 0
|
||||
-- local any=wave_number+150
|
||||
-- local k= math.floor(any/1000)
|
||||
-- if k <= 1 then
|
||||
-- k =1
|
||||
-- end
|
||||
-- if k >= 5 then
|
||||
-- k =5
|
||||
-- end
|
||||
local k = math.sqrt(diff.difficulty_vote_index)
|
||||
if k <= 1 then
|
||||
k =1
|
||||
end
|
||||
k=math.floor(k)
|
||||
damage_increase = wave_number * 0.001*k
|
||||
game.forces.enemy.set_ammo_damage_modifier("artillery-shell", damage_increase)
|
||||
game.forces.enemy.set_ammo_damage_modifier("rocket", damage_increase)
|
||||
game.forces.enemy.set_ammo_damage_modifier("melee", damage_increase)
|
||||
game.forces.enemy.set_ammo_damage_modifier("biological", damage_increase)
|
||||
|
||||
local table = atry_talbe.get()
|
||||
local radius=math.floor(wave_number*0.15)*k
|
||||
table.radius=350+radius
|
||||
local pace=wave_number*0.0002*k+1
|
||||
if pace >= 2 then
|
||||
pace = 2
|
||||
end
|
||||
table.pace=pace
|
||||
|
||||
end
|
||||
Event.on_nth_tick(600, set_diff)
|
247
maps/amap/enemy_arty.lua
Normal file
247
maps/amap/enemy_arty.lua
Normal file
@ -0,0 +1,247 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Task = require 'utils.task'
|
||||
local arty_count = {}
|
||||
local Public = {}
|
||||
local Token = require 'utils.token'
|
||||
local WPT = require 'maps.amap.table'
|
||||
local artillery_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'
|
||||
}
|
||||
|
||||
Global.register(
|
||||
arty_count,
|
||||
function(tbl)
|
||||
arty_count = tbl
|
||||
end
|
||||
)
|
||||
|
||||
function Public.reset_table()
|
||||
arty_count.max = 200
|
||||
arty_count.all = {}
|
||||
arty_count.count = 0
|
||||
arty_count.pace = 1
|
||||
arty_count.radius = 350
|
||||
arty_count.distance = 1400
|
||||
arty_count.surface = {}
|
||||
end
|
||||
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return arty_count[key]
|
||||
else
|
||||
return arty_count
|
||||
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
|
||||
|
||||
local on_init = function()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
||||
local function add_bullet ()
|
||||
for k, p in pairs(arty_count.all) do
|
||||
if arty_count.all[k].valid then
|
||||
arty_count.all[k].insert{name='artillery-shell', count = '5'}
|
||||
end
|
||||
end
|
||||
end
|
||||
local function on_chunk_generated(event)
|
||||
local surface = event.surface
|
||||
local left_top_x = event.area.left_top.x
|
||||
local left_top_y = event.area.left_top.y
|
||||
|
||||
local position
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
position = {x = left_top_x + x, y = left_top_y + y}
|
||||
local q =position.x*position.x
|
||||
local w =position.y*position.y
|
||||
local distance =math.sqrt(q+w)
|
||||
|
||||
if distance >= arty_count.distance then
|
||||
|
||||
if arty_count.count >= arty_count.max then
|
||||
return
|
||||
else
|
||||
local roll = math.random(1, 2024)
|
||||
if roll == 1 then
|
||||
local arty = surface.create_entity{name = "artillery-turret", position = position, force='enemy'}
|
||||
-- arty.insert{name='artillery-shell', count = '5'}
|
||||
--local k = #arty_count.all
|
||||
-- game.print(k)
|
||||
arty_count.all[arty.unit_number]=arty
|
||||
-- game.print(arty_count.all[1].name)
|
||||
arty_count.count = arty_count.count + 1
|
||||
-- game.print(arty_count.count)
|
||||
-- game.print(position)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
|
||||
|
||||
local entity = event.entity
|
||||
|
||||
if not entity or not entity.valid then return end
|
||||
|
||||
|
||||
if arty_count.all[entity.unit_number] then
|
||||
arty_count.all[entity.unit_number] = nil
|
||||
arty_count.count = arty_count.count - 1
|
||||
end
|
||||
-- local force = entity.force
|
||||
-- local name = entity.name
|
||||
-- if name == 'artillery-turret' and force.name == 'enemy' then
|
||||
-- arty_count.all[entity.unit_number] = nil
|
||||
-- arty_count.count = arty_count.count -1
|
||||
--
|
||||
-- if arty_count.count <= 0 then
|
||||
-- arty_count.count = 0
|
||||
-- end
|
||||
|
||||
end
|
||||
|
||||
function on_player_changed_position(event)
|
||||
local player = game.players[event.player_index]
|
||||
local surface = player.surface
|
||||
if not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local position = player.position
|
||||
|
||||
local q =position.x*position.x
|
||||
local w =position.y*position.y
|
||||
local distance =math.sqrt(q+w)
|
||||
--artillery-targeting-remote
|
||||
game.print("123")
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'artillery-targeting-remote',
|
||||
position = position,
|
||||
force = 'enemy',
|
||||
-- target = position,
|
||||
-- speed = 0.001
|
||||
}
|
||||
)
|
||||
game.print("logging")
|
||||
end
|
||||
local artillery_target_callback =
|
||||
Token.register(
|
||||
function(data)
|
||||
local position = data.position
|
||||
local entity = data.entity
|
||||
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local tx, ty = position.x, position.y
|
||||
local pos = entity.position
|
||||
local x, y = pos.x, pos.y
|
||||
local dx, dy = tx - x, ty - y
|
||||
local d = dx * dx + dy * dy
|
||||
-- if d >= 1024 and d <= 441398 then -- 704 in depth~
|
||||
if entity.name == 'character' then
|
||||
entity.surface.create_entity {
|
||||
name = 'artillery-projectile',
|
||||
position = position,
|
||||
target = entity,
|
||||
force = 'enemy',
|
||||
speed = arty_count.pace
|
||||
}
|
||||
elseif entity.name ~= 'character' then
|
||||
entity.surface.create_entity {
|
||||
name = 'rocket',
|
||||
position = position,
|
||||
target = entity,
|
||||
force = 'enemy',
|
||||
speed = arty_count.pace
|
||||
}
|
||||
end
|
||||
end
|
||||
-- end
|
||||
)
|
||||
|
||||
local function do_artillery_turrets_targets()
|
||||
--local surface = arty_count.surface
|
||||
local this = WPT.get()
|
||||
local surface = game.surfaces[this.active_surface_index]
|
||||
--选取重炮
|
||||
local roll_table = {}
|
||||
for index, arty in pairs(arty_count.all) do
|
||||
if arty.valid then
|
||||
roll_table[#roll_table + 1] = arty
|
||||
else
|
||||
arty_count.all[index] = nil -- <- if not valid, remove from table
|
||||
arty_count.count = arty_count.count - 1
|
||||
end
|
||||
end
|
||||
if #roll_table <= 0 then return end
|
||||
local roll = math.random(1, #roll_table)
|
||||
local position = roll_table[roll].position
|
||||
|
||||
--扫描区域
|
||||
-- local normal_area = {left_top = {-480, -480}, right_bottom = {480, 480}}
|
||||
-- game.print(123)
|
||||
-- normal_area= roll_table[roll].artillery_area
|
||||
-- game.print(12)
|
||||
local entities = surface.find_entities_filtered{position = position, radius = arty_count.radius, name = artillery_target_entities, force = game.forces.player}
|
||||
|
||||
-- local entities = surface.find_entities_filtered {area = normal_area, name = artillery_target_entities, force = 'player'}
|
||||
if #entities == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--开火
|
||||
for i = 1, arty_count.count do
|
||||
local entity = entities[math.random(#entities)]
|
||||
--game.print(entity.position)
|
||||
if entity and entity.valid then
|
||||
local data = {position = position, entity = entity}
|
||||
Task.set_timeout_in_ticks(i * 60, artillery_target_callback, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
--Event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
||||
--Event.on_nth_tick(600, add_bullet)
|
||||
Event.on_nth_tick(10, do_artillery_turrets_targets)
|
||||
Event.on_init(on_init)
|
||||
|
||||
|
||||
return Public
|
1382
maps/amap/entities.lua
Normal file
1382
maps/amap/entities.lua
Normal file
File diff suppressed because it is too large
Load Diff
890
maps/amap/functions.lua
Normal file
890
maps/amap/functions.lua
Normal file
@ -0,0 +1,890 @@
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Alert = require 'utils.alert'
|
||||
local WPT = require 'maps.amap.table'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local math2d = require 'math2d'
|
||||
local Commands = require 'commands.misc'
|
||||
local RPG = require 'modules.rpg.table'
|
||||
|
||||
local this = {
|
||||
power_sources = {index = 1},
|
||||
refill_turrets = {index = 1},
|
||||
magic_crafters = {index = 1},
|
||||
magic_fluid_crafters = {index = 1},
|
||||
art_table = {index = 1},
|
||||
surface_cleared = false
|
||||
}
|
||||
|
||||
local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['wood'] = 16}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(t)
|
||||
this = t
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local remove = table.remove
|
||||
local sqrt = math.sqrt
|
||||
local magic_crafters_per_tick = 3
|
||||
local magic_fluid_crafters_per_tick = 8
|
||||
local tile_damage = 50
|
||||
|
||||
local artillery_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'
|
||||
}
|
||||
|
||||
function Public.get_player_data(player, remove_user_data)
|
||||
local players = WPT.get('players')
|
||||
if remove_user_data then
|
||||
if players[player.index] then
|
||||
players[player.index] = nil
|
||||
end
|
||||
end
|
||||
if not players[player.index] then
|
||||
players[player.index] = {}
|
||||
end
|
||||
return players[player.index]
|
||||
end
|
||||
|
||||
local get_player_data = Public.get_player_data
|
||||
|
||||
local function debug_str(msg)
|
||||
local debug = WPT.get('debug')
|
||||
if not debug then
|
||||
return
|
||||
end
|
||||
print('Mtn: ' .. msg)
|
||||
end
|
||||
|
||||
local function show_text(msg, pos, color, surface)
|
||||
if color == nil then
|
||||
surface.create_entity({name = 'flying-text', position = pos, text = msg})
|
||||
else
|
||||
surface.create_entity({name = 'flying-text', position = pos, text = msg, color = color})
|
||||
end
|
||||
end
|
||||
|
||||
local function fast_remove(tbl, index)
|
||||
local count = #tbl
|
||||
if index > count then
|
||||
return
|
||||
elseif index < count then
|
||||
tbl[index] = tbl[count]
|
||||
end
|
||||
|
||||
tbl[count] = nil
|
||||
end
|
||||
|
||||
local function do_refill_turrets()
|
||||
local refill_turrets = this.refill_turrets
|
||||
local index = refill_turrets.index
|
||||
|
||||
if index > #refill_turrets then
|
||||
refill_turrets.index = 1
|
||||
return
|
||||
end
|
||||
|
||||
local turret_data = refill_turrets[index]
|
||||
local turret = turret_data.turret
|
||||
|
||||
if not turret.valid then
|
||||
fast_remove(refill_turrets, index)
|
||||
return
|
||||
end
|
||||
|
||||
refill_turrets.index = index + 1
|
||||
|
||||
local data = turret_data.data
|
||||
if data.liquid then
|
||||
turret.fluidbox[1] = data
|
||||
elseif data then
|
||||
turret.insert(data)
|
||||
end
|
||||
end
|
||||
|
||||
local function do_turret_energy()
|
||||
local power_sources = this.power_sources
|
||||
|
||||
for index = 1, #power_sources do
|
||||
local ps_data = power_sources[index]
|
||||
if not (ps_data and ps_data.valid) then
|
||||
fast_remove(power_sources, index)
|
||||
return
|
||||
end
|
||||
|
||||
ps_data.energy = 0xfffff
|
||||
end
|
||||
end
|
||||
|
||||
local function do_magic_crafters()
|
||||
local magic_crafters = this.magic_crafters
|
||||
local limit = #magic_crafters
|
||||
if limit == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local index = magic_crafters.index
|
||||
|
||||
for i = 1, magic_crafters_per_tick do
|
||||
if index > limit then
|
||||
index = 1
|
||||
end
|
||||
|
||||
local data = magic_crafters[index]
|
||||
|
||||
local entity = data.entity
|
||||
if not entity.valid then
|
||||
fast_remove(magic_crafters, index)
|
||||
limit = limit - 1
|
||||
if limit == 0 then
|
||||
return
|
||||
end
|
||||
else
|
||||
index = index + 1
|
||||
|
||||
local tick = game.tick
|
||||
local last_tick = data.last_tick
|
||||
local rate = data.rate
|
||||
|
||||
local count = (tick - last_tick) * rate
|
||||
|
||||
local fcount = floor(count)
|
||||
|
||||
if fcount > 1 then
|
||||
fcount = 1
|
||||
end
|
||||
|
||||
if fcount > 0 then
|
||||
entity.get_output_inventory().insert {name = data.item, count = fcount}
|
||||
data.last_tick = tick - (count - fcount) / rate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
magic_crafters.index = index
|
||||
end
|
||||
|
||||
local function do_magic_fluid_crafters()
|
||||
local magic_fluid_crafters = this.magic_fluid_crafters
|
||||
local limit = #magic_fluid_crafters
|
||||
|
||||
if limit == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local index = magic_fluid_crafters.index
|
||||
|
||||
for i = 1, magic_fluid_crafters_per_tick do
|
||||
if index > limit then
|
||||
index = 1
|
||||
end
|
||||
|
||||
local data = magic_fluid_crafters[index]
|
||||
|
||||
local entity = data.entity
|
||||
if not entity.valid then
|
||||
fast_remove(magic_fluid_crafters, index)
|
||||
limit = limit - 1
|
||||
if limit == 0 then
|
||||
return
|
||||
end
|
||||
else
|
||||
index = index + 1
|
||||
|
||||
local tick = game.tick
|
||||
local last_tick = data.last_tick
|
||||
local rate = data.rate
|
||||
|
||||
local count = (tick - last_tick) * rate
|
||||
|
||||
local fcount = floor(count)
|
||||
|
||||
if fcount > 0 then
|
||||
local fluidbox_index = data.fluidbox_index
|
||||
local fb = entity.fluidbox
|
||||
|
||||
local fb_data = fb[fluidbox_index] or {name = data.item, amount = 0}
|
||||
fb_data.amount = fb_data.amount + fcount
|
||||
fb[fluidbox_index] = fb_data
|
||||
|
||||
data.last_tick = tick - (count - fcount) / rate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
magic_fluid_crafters.index = index
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function tick()
|
||||
do_magic_crafters()
|
||||
do_magic_fluid_crafters()
|
||||
end
|
||||
|
||||
Public.deactivate_callback =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.active = false
|
||||
entity.operable = false
|
||||
entity.destructible = false
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.neutral_force =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.force = 'neutral'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.enemy_force =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.force = 'enemy'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.active_not_destructible_callback =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.active = true
|
||||
entity.operable = false
|
||||
entity.destructible = false
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.disable_minable_callback =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.minable = false
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.disable_minable_and_ICW_callback =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.minable = false
|
||||
ICW.register_wagon(entity, true)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.disable_destructible_callback =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.destructible = false
|
||||
entity.minable = false
|
||||
end
|
||||
end
|
||||
)
|
||||
Public.disable_active_callback =
|
||||
Token.register(
|
||||
function(entity)
|
||||
if entity and entity.valid then
|
||||
entity.active = false
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local disable_active_callback = Public.disable_active_callback
|
||||
|
||||
|
||||
Public.power_source_callback =
|
||||
Token.register(
|
||||
function(turret)
|
||||
local power_sources = this.power_sources
|
||||
power_sources[#power_sources + 1] = turret
|
||||
end
|
||||
)
|
||||
|
||||
Public.magic_item_crafting_callback =
|
||||
Token.register(
|
||||
function(entity, data)
|
||||
local callback_data = data.callback_data
|
||||
if not (entity and entity.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
entity.minable = false
|
||||
entity.destructible = false
|
||||
entity.operable = false
|
||||
|
||||
local force = game.forces.player
|
||||
|
||||
local tech = callback_data.tech
|
||||
if tech then
|
||||
if not force.technologies[tech].researched then
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local recipe = callback_data.recipe
|
||||
if recipe then
|
||||
entity.set_recipe(recipe)
|
||||
else
|
||||
local furance_item = callback_data.furance_item
|
||||
if furance_item then
|
||||
local inv = entity.get_inventory(defines.inventory.furnace_result)
|
||||
inv.insert(furance_item)
|
||||
end
|
||||
end
|
||||
|
||||
local p = entity.position
|
||||
local x, y = p.x, p.y
|
||||
local distance = sqrt(x * x + y * y)
|
||||
|
||||
local output = callback_data.output
|
||||
if #output == 0 then
|
||||
add_magic_crafter_output(entity, output, distance)
|
||||
else
|
||||
for i = 1, #output do
|
||||
local o = output[i]
|
||||
add_magic_crafter_output(entity, o, distance)
|
||||
end
|
||||
end
|
||||
|
||||
if not callback_data.keep_active then
|
||||
Task.set_timeout_in_ticks(2, disable_active_callback, entity) -- causes problems with refineries.
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.magic_item_crafting_callback_weighted =
|
||||
Token.register(
|
||||
function(entity, data)
|
||||
local callback_data = data.callback_data
|
||||
if not (entity and entity.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
entity.minable = false
|
||||
entity.destructible = false
|
||||
entity.operable = false
|
||||
|
||||
local weights = callback_data.weights
|
||||
local loot = callback_data.loot
|
||||
|
||||
local p = entity.position
|
||||
|
||||
local i = random() * weights.total
|
||||
|
||||
local index = table.binary_search(weights, i)
|
||||
if (index < 0) then
|
||||
index = bit32.bnot(index)
|
||||
end
|
||||
|
||||
local stack = loot[index].stack
|
||||
if not stack then
|
||||
return
|
||||
end
|
||||
|
||||
local force = game.forces.player
|
||||
|
||||
local tech = stack.tech
|
||||
if tech then
|
||||
if force.technologies[tech] then
|
||||
if not force.technologies[tech].researched then
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local recipe = stack.recipe
|
||||
if recipe then
|
||||
entity.set_recipe(recipe)
|
||||
else
|
||||
local furance_item = stack.furance_item
|
||||
if furance_item then
|
||||
local inv = entity.get_inventory(defines.inventory.furnace_result)
|
||||
inv.insert(furance_item)
|
||||
end
|
||||
end
|
||||
|
||||
local x, y = p.x, p.y
|
||||
local distance = sqrt(x * x + y * y)
|
||||
|
||||
local output = stack.output
|
||||
if #output == 0 then
|
||||
add_magic_crafter_output(entity, output, distance)
|
||||
else
|
||||
for o_i = 1, #output do
|
||||
local o = output[o_i]
|
||||
add_magic_crafter_output(entity, o, distance)
|
||||
end
|
||||
end
|
||||
|
||||
if not callback_data.keep_active then
|
||||
Task.set_timeout_in_ticks(2, disable_active_callback, entity) -- causes problems with refineries.
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function Public.prepare_weighted_loot(loot)
|
||||
local total = 0
|
||||
local weights = {}
|
||||
|
||||
for i = 1, #loot do
|
||||
local v = loot[i]
|
||||
total = total + v.weight
|
||||
weights[#weights + 1] = total
|
||||
end
|
||||
|
||||
weights.total = total
|
||||
|
||||
return weights
|
||||
end
|
||||
|
||||
function Public.do_random_loot(entity, weights, loot)
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
entity.operable = false
|
||||
--entity.destructible = false
|
||||
|
||||
local i = random() * weights.total
|
||||
|
||||
local index = table.binary_search(weights, i)
|
||||
if (index < 0) then
|
||||
index = bit32.bnot(index)
|
||||
end
|
||||
|
||||
local stack = loot[index].stack
|
||||
if not stack then
|
||||
return
|
||||
end
|
||||
|
||||
local df = stack.distance_factor
|
||||
local count
|
||||
if df then
|
||||
local p = entity.position
|
||||
local x, y = p.x, p.y
|
||||
local d = sqrt(x * x + y * y)
|
||||
|
||||
count = stack.count + d * df
|
||||
else
|
||||
count = stack.count
|
||||
end
|
||||
|
||||
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 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
|
||||
local later = {}
|
||||
for i = 1, #offline_players, 1 do
|
||||
if offline_players[i] and game.players[offline_players[i].index] and game.players[offline_players[i].index].connected then
|
||||
offline_players[i] = nil
|
||||
else
|
||||
if offline_players[i] and game.players[offline_players[i].index] and offline_players[i].tick < game.tick - 54000 then
|
||||
local name = offline_players[i].name
|
||||
player_inv[1] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_main)
|
||||
player_inv[2] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_armor)
|
||||
player_inv[3] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_guns)
|
||||
player_inv[4] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_ammo)
|
||||
player_inv[5] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_trash)
|
||||
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
|
||||
else
|
||||
later[#later + 1] = offline_players[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
for k, _ in pairs(offline_players) do
|
||||
offline_players[k] = nil
|
||||
end
|
||||
if #later > 0 then
|
||||
for i = 1, #later, 1 do
|
||||
offline_players[#offline_players + 1] = later[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function calc_players()
|
||||
local players = game.connected_players
|
||||
local check_afk_players = WPT.get('check_afk_players')
|
||||
if not check_afk_players then
|
||||
return #players
|
||||
end
|
||||
local total = 0
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
if player.afk_time < 36000 then
|
||||
total = total + 1
|
||||
end
|
||||
end
|
||||
if total <= 0 then
|
||||
total = 1
|
||||
end
|
||||
return total
|
||||
end
|
||||
|
||||
|
||||
function Public.on_player_joined_game(event)
|
||||
local active_surface_index = WPT.get('active_surface_index')
|
||||
local player = game.players[event.player_index]
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
|
||||
|
||||
local reward = require 'maps.amap.main'.reward
|
||||
local player_data = get_player_data(player)
|
||||
if not player_data.first_join then
|
||||
|
||||
for item, amount in pairs(starting_items) do
|
||||
player.insert({name = item, count = amount})
|
||||
end
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
local wave_number = WD.get('wave_number')
|
||||
local this = WPT.get()
|
||||
|
||||
for i=0,this.science do
|
||||
local point = math.floor(math.random(1,5))
|
||||
local money = math.floor(math.random(1,100))
|
||||
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+point
|
||||
player.insert{name='coin', count = money}
|
||||
player.print({'amap.science',point,money}, {r = 0.22, g = 0.88, b = 0.22})
|
||||
end
|
||||
|
||||
rpg_t[player.index].xp = rpg_t[player.index].xp + wave_number*10
|
||||
|
||||
|
||||
|
||||
player_data.first_join = true
|
||||
player.print({'amap.joingame'})
|
||||
end
|
||||
if player.surface.index ~= active_surface_index then
|
||||
--player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 20, 1, false) or {x=0,y=0}, surface)
|
||||
|
||||
player.teleport(surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 20, 1, false) or {x=0,y=0}, surface)
|
||||
else
|
||||
local p = {x = player.position.x, y = player.position.y}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
player.teleport(surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 20, 1, false) or {x=0,y=0}, surface)
|
||||
--player.teleport({x=0,y=0}, surface)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function Public.is_creativity_mode_on()
|
||||
local creative_enabled = Commands.get('creative_enabled')
|
||||
if creative_enabled then
|
||||
WD.set('next_wave', 1000)
|
||||
Collapse.start_now(true)
|
||||
Public.set_difficulty()
|
||||
end
|
||||
end
|
||||
local function on_player_mined_entity(event)
|
||||
local name = event.entity.name
|
||||
local entity = event.entity
|
||||
local this = WPT.get()
|
||||
if name == 'flamethrower-turret' then
|
||||
this.flame = this.flame - 1
|
||||
|
||||
if this.flame <= 0 then
|
||||
this.flame = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
function Public.disable_creative()
|
||||
local creative_enabled = Commands.get('creative_enabled')
|
||||
if creative_enabled then
|
||||
Commands.set('creative_enabled', false)
|
||||
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
|
||||
local on_player_or_robot_built_entity = function(event)
|
||||
--change_pos 改变位置
|
||||
local name = event.created_entity.name
|
||||
local entity = event.created_entity
|
||||
local this = WPT.get()
|
||||
if name == 'flamethrower-turret' then
|
||||
if this.flame >= 15 then
|
||||
game.print({'amap.too_many'})
|
||||
entity.destroy()
|
||||
else
|
||||
this.flame = this.flame + 1
|
||||
game.print({'amap.ok_many',this.flame})
|
||||
end
|
||||
end
|
||||
if name == "stone-wall" then
|
||||
local this = WPT.get()
|
||||
if not this.change then
|
||||
local wave_defense_table = WD.get_table()
|
||||
local dx = entity.position.x-this.pos.x
|
||||
local dy = entity.position.y-this.pos.y
|
||||
|
||||
if dx < 0 then
|
||||
dx=-dx
|
||||
end
|
||||
if dy < 0 then
|
||||
dy=-dy
|
||||
end
|
||||
local d = dx+dy
|
||||
if d < 100 then
|
||||
this.change = true
|
||||
end
|
||||
end
|
||||
|
||||
--game.print(dx)
|
||||
--game.print(dy)
|
||||
--game.print('差值为')
|
||||
--game.print(d)
|
||||
--game.print('出生地为')
|
||||
--game.print(this.pos)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function Public.on_player_respawned(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
local player_data = get_player_data(player)
|
||||
if player_data.died then
|
||||
player_data.died = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Public.on_player_died(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
local player_data = get_player_data(player)
|
||||
player_data.died = true
|
||||
end
|
||||
|
||||
function Public.on_player_changed_position(event)
|
||||
local active_surface_index = WPT.get('active_surface_index')
|
||||
if not active_surface_index then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
local map_name = 'amap'
|
||||
|
||||
if string.sub(player.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
local position = player.position
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
|
||||
local p = {x = player.position.x, y = player.position.y}
|
||||
local get_tile = surface.get_tile(p)
|
||||
local config_tile = WPT.get('void_or_tile')
|
||||
if config_tile == 'lab-dark-2' then
|
||||
if get_tile.valid and get_tile.name == 'lab-dark-2' then
|
||||
if random(1, 2) == 1 then
|
||||
if random(1, 2) == 1 then
|
||||
show_text('This path is not for players!', p, {r = 0.98, g = 0.66, b = 0.22}, surface)
|
||||
end
|
||||
player.surface.create_entity({name = 'fire-flame', position = player.position})
|
||||
player.character.health = player.character.health - tile_damage
|
||||
if player.character.health == 0 then
|
||||
player.character.die()
|
||||
local message = ({'main.death_message_' .. random(1, 7), player.name})
|
||||
game.print(message, {r = 0.98, g = 0.66, b = 0.22})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if position.y >= 74 then
|
||||
player.teleport({position.x, position.y - 1}, surface)
|
||||
player.print(({'main.forcefield'}), {r = 0.98, g = 0.66, b = 0.22})
|
||||
if player.character then
|
||||
player.character.health = player.character.health - 5
|
||||
player.character.surface.create_entity({name = 'water-splash', position = position})
|
||||
if player.character.health <= 0 then
|
||||
player.character.die('enemy')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local disable_recipes = function()
|
||||
local force = game.forces.player
|
||||
force.recipes['car'].enabled = false
|
||||
force.recipes['tank'].enabled = false
|
||||
force.recipes['pistol'].enabled = false
|
||||
force.recipes['land-mine'].enabled = false
|
||||
force.recipes['spidertron-remote'].enabled = false
|
||||
-- force.recipes['flamethrower-turret'].enabled = false
|
||||
end
|
||||
|
||||
function Public.disable_tech()
|
||||
game.forces.player.technologies['landfill'].enabled = false
|
||||
game.forces.player.technologies['spidertron'].enabled = false
|
||||
game.forces.player.technologies['spidertron'].researched = false
|
||||
disable_recipes()
|
||||
end
|
||||
|
||||
local disable_tech = Public.disable_tech
|
||||
function Public.on_research_finished(event)
|
||||
disable_tech()
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
|
||||
local name = event.entity.name
|
||||
|
||||
local entity = event.entity
|
||||
local this = WPT.get()
|
||||
if name == 'flamethrower-turret' then
|
||||
this.flame = this.flame - 1
|
||||
|
||||
if this.flame <= 0 then
|
||||
this.flame = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
Public.firearm_magazine_ammo = {name = 'firearm-magazine', count = 200}
|
||||
Public.piercing_rounds_magazine_ammo = {name = 'piercing-rounds-magazine', count = 200}
|
||||
Public.uranium_rounds_magazine_ammo = {name = 'uranium-rounds-magazine', count = 200}
|
||||
Public.light_oil_ammo = {name = 'light-oil', amount = 100}
|
||||
Public.artillery_shell_ammo = {name = 'artillery-shell', count = 15}
|
||||
Public.laser_turrent_power_source = {buffer_size = 2400000, power_production = 40000}
|
||||
|
||||
function Public.reset_table()
|
||||
this.power_sources = {index = 1}
|
||||
this.refill_turrets = {index = 1}
|
||||
this.magic_crafters = {index = 1}
|
||||
this.magic_fluid_crafters = {index = 1}
|
||||
end
|
||||
|
||||
local on_research_finished = Public.on_research_finished
|
||||
local on_player_joined_game = Public.on_player_joined_game
|
||||
local on_player_respawned = Public.on_player_respawned
|
||||
local on_player_died = Public.on_player_died
|
||||
local on_player_changed_position = Public.on_player_changed_position
|
||||
local on_pre_player_left_game = Public.on_pre_player_left_game
|
||||
|
||||
Event.add(defines.events.on_built_entity, on_player_or_robot_built_entity)
|
||||
Event.add(defines.events.on_robot_built_entity, on_player_or_robot_built_entity)
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.add(defines.events.on_player_died, on_player_died)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_robot_mined_entity, on_player_mined_entity)
|
||||
--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.on_nth_tick(10, tick)
|
||||
Event.on_nth_tick(5, do_turret_energy)
|
||||
|
||||
return Public
|
961
maps/amap/ic/functions.lua
Normal file
961
maps/amap/ic/functions.lua
Normal file
@ -0,0 +1,961 @@
|
||||
local Utils = require 'utils.core'
|
||||
local Color = require 'utils.color_presets'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local IC_Gui = require 'maps.amap.ic.gui'
|
||||
local WPT = require 'maps.amap.table'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Public = {}
|
||||
local main_tile_name = 'black-refined-concrete'
|
||||
local RPG = require 'modules.rpg.table'
|
||||
local Loot = require "maps.amap.loot"
|
||||
local function validate_entity(entity)
|
||||
if not (entity and entity.valid) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function log_err(ic, err)
|
||||
if ic.debug_mode then
|
||||
if type(err) == 'string' then
|
||||
log('IC: ' .. err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_trusted_system(this, player)
|
||||
if not this.trust_system[player.index] then
|
||||
this.trust_system[player.index] = {
|
||||
[player.name] = true
|
||||
}
|
||||
end
|
||||
|
||||
return this.trust_system[player.index]
|
||||
end
|
||||
|
||||
local function upperCase(str)
|
||||
return (str:gsub('^%l', string.upper))
|
||||
end
|
||||
|
||||
local function render_owner_text(renders, player, entity, new_owner)
|
||||
local color = {
|
||||
r = player.color.r * 0.6 + 0.25,
|
||||
g = player.color.g * 0.6 + 0.25,
|
||||
b = player.color.b * 0.6 + 0.25,
|
||||
a = 1
|
||||
}
|
||||
if renders[player.index] then
|
||||
rendering.destroy(renders[player.index])
|
||||
end
|
||||
if new_owner then
|
||||
renders[new_owner.index] =
|
||||
rendering.draw_text {
|
||||
text = '## - ' .. new_owner.name .. "'s " .. entity.name .. ' - ##',
|
||||
surface = entity.surface,
|
||||
target = entity,
|
||||
target_offset = {0, -2.6},
|
||||
color = color,
|
||||
scale = 1.05,
|
||||
font = 'default-large-semibold',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
else
|
||||
renders[player.index] =
|
||||
rendering.draw_text {
|
||||
text = '## - ' .. player.name .. "'s " .. entity.name .. ' - ##',
|
||||
surface = entity.surface,
|
||||
target = entity,
|
||||
target_offset = {0, -2.6},
|
||||
color = color,
|
||||
scale = 1.05,
|
||||
font = 'default-large-semibold',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
end
|
||||
entity.color = color
|
||||
end
|
||||
|
||||
local function kill_doors(ic, car)
|
||||
if not validate_entity(car.entity) then
|
||||
return
|
||||
end
|
||||
for k, e in pairs(car.doors) do
|
||||
ic.doors[e.unit_number] = nil
|
||||
e.destroy()
|
||||
car.doors[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function get_owner_car_object(cars, player)
|
||||
for k, car in pairs(cars) do
|
||||
if car.owner == player.index then
|
||||
return k
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function get_entity_from_player_surface(cars, player)
|
||||
for k, car in pairs(cars) do
|
||||
if validate_entity(car.entity) then
|
||||
if validate_entity(car.surface) then
|
||||
if car.surface.index == player.surface.index then
|
||||
return car.entity
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function get_owner_car_surface(cars, player, target)
|
||||
for k, car in pairs(cars) do
|
||||
if car.owner == player.index then
|
||||
if validate_entity(car.surface) then
|
||||
if car.surface.index == target.surface.index then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function get_player_surface(ic, player)
|
||||
local surfaces = ic.surfaces
|
||||
for _, surface in pairs(surfaces) do
|
||||
if validate_entity(surface) then
|
||||
if surface.index == player.surface.index then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function get_player_entity(ic, player)
|
||||
local cars = ic.cars
|
||||
for k, car in pairs(cars) do
|
||||
if car.owner == player.index and type(car.entity) == 'boolean' then
|
||||
return car.name, true
|
||||
elseif car.owner == player.index then
|
||||
return car.name, false
|
||||
end
|
||||
end
|
||||
return false, false
|
||||
end
|
||||
|
||||
local function get_owner_car_name(ic, player)
|
||||
local cars = ic.cars
|
||||
local saved_surfaces = ic.saved_surfaces
|
||||
local index = saved_surfaces[player.index]
|
||||
for k, car in pairs(cars) do
|
||||
if not index then
|
||||
return false
|
||||
end
|
||||
if car.owner == player.index then
|
||||
return car.name
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function get_saved_entity(entity, index)
|
||||
if index and index.name ~= entity.name then
|
||||
local msg =
|
||||
table.concat(
|
||||
{
|
||||
'The built entity is not the same as the saved one. ',
|
||||
'Saved entity is: ' .. upperCase(index.name) .. ' - Built entity is: ' .. upperCase(entity.name) .. '. '
|
||||
}
|
||||
)
|
||||
return false, msg
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function replace_entity(cars, entity, index)
|
||||
local unit_number = entity.unit_number
|
||||
for k, car in pairs(cars) do
|
||||
if car.saved_entity == index.saved_entity then
|
||||
local c = car
|
||||
cars[unit_number] = c
|
||||
cars[unit_number].entity = entity
|
||||
cars[unit_number].saved_entity = nil
|
||||
cars[unit_number].transfer_entities = car.transfer_entities
|
||||
cars[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function replace_doors(doors, entity, index)
|
||||
if not validate_entity(entity) then
|
||||
return
|
||||
end
|
||||
for k, door in pairs(doors) do
|
||||
local unit_number = entity.unit_number
|
||||
if index.saved_entity == door then
|
||||
doors[k] = unit_number
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function replace_surface(surfaces, entity, index)
|
||||
if not validate_entity(entity) then
|
||||
return
|
||||
end
|
||||
for k, surface in pairs(surfaces) do
|
||||
local unit_number = entity.unit_number
|
||||
if tostring(index.saved_entity) == surface.name then
|
||||
if validate_entity(surface) then
|
||||
surface.name = tostring(unit_number)
|
||||
surfaces[unit_number] = surface
|
||||
surfaces[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function replace_surface_entity(cars, entity, index)
|
||||
if not validate_entity(entity) then
|
||||
return
|
||||
end
|
||||
for _, car in pairs(cars) do
|
||||
local unit_number = entity.unit_number
|
||||
if index and index.saved_entity == car.saved_entity then
|
||||
if validate_entity(car.surface) then
|
||||
car.surface.name = tostring(unit_number)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_logistics(car)
|
||||
local chests = car.transfer_entities
|
||||
for k, chest in pairs(chests) do
|
||||
car.transfer_entities[k] = nil
|
||||
chest.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local function set_new_area(ic, car)
|
||||
local new_area = ic.car_areas
|
||||
local name = car.name
|
||||
local apply_area = new_area[name]
|
||||
car.area = apply_area
|
||||
end
|
||||
|
||||
local function upgrade_surface(ic, player, entity)
|
||||
local ce = entity
|
||||
local saved_surfaces = ic.saved_surfaces
|
||||
local cars = ic.cars
|
||||
local door = ic.doors
|
||||
local surfaces = ic.surfaces
|
||||
local index = saved_surfaces[player.index]
|
||||
if not index then
|
||||
return
|
||||
end
|
||||
|
||||
if saved_surfaces[player.index] then
|
||||
local c = get_owner_car_object(cars, player)
|
||||
local car = ic.cars[c]
|
||||
if ce.name == 'spidertron' then
|
||||
car.name = 'spidertron'
|
||||
elseif ce.name == 'tank' then
|
||||
car.name = 'tank'
|
||||
end
|
||||
set_new_area(ic, car)
|
||||
remove_logistics(car)
|
||||
replace_entity(cars, ce, index)
|
||||
replace_doors(door, ce, index)
|
||||
replace_surface(surfaces, ce, index)
|
||||
replace_surface_entity(cars, ce, index)
|
||||
kill_doors(ic, car)
|
||||
Public.create_car_room(ic, car)
|
||||
saved_surfaces[player.index] = nil
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function save_surface(ic, entity, player)
|
||||
local car = ic.cars[entity.unit_number]
|
||||
|
||||
car.entity = false
|
||||
car.saved_entity = entity.unit_number
|
||||
|
||||
ic.saved_surfaces[player.index] = {saved_entity = entity.unit_number, name = entity.name}
|
||||
end
|
||||
|
||||
local function kick_players_out_of_vehicles(car)
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local character = player.character
|
||||
if validate_entity(character) and character.driving then
|
||||
if car.surface == player.surface then
|
||||
character.driving = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function kick_players_from_surface(ic, car)
|
||||
if not validate_entity(car.surface) then
|
||||
return log_err('Car surface was not valid.')
|
||||
end
|
||||
if not car.entity or not car.entity.valid then
|
||||
local main_surface = game.surfaces[ic.allowed_surface]
|
||||
if validate_entity(main_surface) then
|
||||
for _, e in pairs(car.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)
|
||||
end
|
||||
end
|
||||
end
|
||||
return log_err('Car entity was not valid.')
|
||||
end
|
||||
|
||||
for _, e in pairs(car.surface.find_entities_filtered({area = car.area})) do
|
||||
if validate_entity(e) and e.name == 'character' and e.player then
|
||||
local p = car.entity.surface.find_non_colliding_position('character', car.entity.position, 128, 0.5)
|
||||
if p then
|
||||
e.player.teleport(p, car.entity.surface)
|
||||
else
|
||||
e.player.teleport(car.entity.position, car.entity.surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function kick_player_from_surface(ic, player, target)
|
||||
local cars = ic.cars
|
||||
|
||||
local main_surface = game.surfaces[ic.allowed_surface]
|
||||
if not validate_entity(main_surface) then
|
||||
return
|
||||
end
|
||||
|
||||
local c = get_owner_car_object(cars, player)
|
||||
local car = ic.cars[c]
|
||||
|
||||
if not validate_entity(car.entity) then
|
||||
return
|
||||
end
|
||||
|
||||
if validate_entity(player) then
|
||||
if validate_entity(target) then
|
||||
local locate = get_owner_car_surface(cars, player, target)
|
||||
if locate then
|
||||
local p = car.entity.surface.find_non_colliding_position('character', car.entity.position, 128, 0.5)
|
||||
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)
|
||||
end
|
||||
target.print('You were kicked out of ' .. player.name .. ' vehicle.', Color.warning)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function restore_surface(ic, player, entity)
|
||||
local ce = entity
|
||||
local saved_surfaces = ic.saved_surfaces
|
||||
local cars = ic.cars
|
||||
local door = ic.doors
|
||||
local renders = ic.renders
|
||||
local surfaces = ic.surfaces
|
||||
local index = saved_surfaces[player.index]
|
||||
if not index then
|
||||
return
|
||||
end
|
||||
|
||||
if saved_surfaces[player.index] then
|
||||
local success, msg = get_saved_entity(ce, index)
|
||||
if not success then
|
||||
player.print(msg, Color.warning)
|
||||
return true
|
||||
end
|
||||
replace_entity(cars, ce, index)
|
||||
replace_doors(door, ce, index)
|
||||
replace_surface(surfaces, ce, index)
|
||||
replace_surface_entity(cars, ce, index)
|
||||
saved_surfaces[player.index] = nil
|
||||
render_owner_text(renders, player, ce)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function input_filtered(car_inv, chest, chest_inv, free_slots)
|
||||
local request_stacks = {}
|
||||
|
||||
local prototypes = game.item_prototypes
|
||||
for slot_index = 1, 30, 1 do
|
||||
local stack = chest.get_request_slot(slot_index)
|
||||
if stack then
|
||||
request_stacks[stack.name] = 10 * prototypes[stack.name].stack_size
|
||||
end
|
||||
end
|
||||
for i = 1, #car_inv - 1, 1 do
|
||||
if free_slots <= 0 then
|
||||
return
|
||||
end
|
||||
local stack = car_inv[i]
|
||||
if stack.valid_for_read then
|
||||
local request_stack = request_stacks[stack.name]
|
||||
if request_stack and request_stack > chest_inv.get_item_count(stack.name) then
|
||||
chest_inv.insert(stack)
|
||||
stack.clear()
|
||||
free_slots = free_slots - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function input_cargo(car, chest)
|
||||
if not chest.request_from_buffers then
|
||||
return
|
||||
end
|
||||
|
||||
local car_entity = car.entity
|
||||
if not validate_entity(car_entity) then
|
||||
return
|
||||
end
|
||||
|
||||
local car_inventory = car_entity.get_inventory(defines.inventory.car_trunk)
|
||||
if car_inventory.is_empty() then
|
||||
return
|
||||
end
|
||||
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.chest)
|
||||
local free_slots = 0
|
||||
|
||||
for i = 1, chest_inventory.get_bar() - 1, 1 do
|
||||
if not chest_inventory[i].valid_for_read then
|
||||
free_slots = free_slots + 1
|
||||
end
|
||||
end
|
||||
|
||||
if chest.get_request_slot(1) then
|
||||
input_filtered(car_inventory, chest, chest_inventory, free_slots)
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, #car_inventory - 1, 1 do
|
||||
if free_slots <= 0 then
|
||||
return
|
||||
end
|
||||
if car_inventory[i].valid_for_read then
|
||||
chest_inventory.insert(car_inventory[i])
|
||||
car_inventory[i].clear()
|
||||
free_slots = free_slots - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function output_cargo(car, passive_chest)
|
||||
if not validate_entity(car.entity) then
|
||||
return
|
||||
end
|
||||
|
||||
if not passive_chest.valid then
|
||||
return
|
||||
end
|
||||
local chest1 = passive_chest.get_inventory(defines.inventory.chest)
|
||||
local chest2 = car.entity.get_inventory(defines.inventory.car_trunk)
|
||||
for k, v in pairs(chest1.get_contents()) do
|
||||
local t = {name = k, count = v}
|
||||
local c = chest2.insert(t)
|
||||
if (c > 0) then
|
||||
chest1.remove({name = k, count = c})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local transfer_functions = {
|
||||
['logistic-chest-requester'] = input_cargo,
|
||||
['logistic-chest-passive-provider'] = output_cargo
|
||||
}
|
||||
|
||||
local function construct_doors(ic, car)
|
||||
local area = car.area
|
||||
local surface = car.surface
|
||||
|
||||
for _, x in pairs({area.left_top.x - 1.5, area.right_bottom.x + 1.5}) do
|
||||
local p = {x = x, y = area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
|
||||
if p.x < 0 then
|
||||
surface.set_tiles({{name = main_tile_name, position = {x = p.x + 0.5, y = p.y}}}, true)
|
||||
else
|
||||
surface.set_tiles({{name = main_tile_name, position = {x = p.x - 1, y = p.y}}}, true)
|
||||
end
|
||||
local e =
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'car',
|
||||
position = {x, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)},
|
||||
force = 'neutral',
|
||||
create_build_effect_smoke = false
|
||||
}
|
||||
)
|
||||
e.destructible = false
|
||||
e.minable = false
|
||||
e.operable = false
|
||||
e.get_inventory(defines.inventory.fuel).insert({name = 'coal', count = 1})
|
||||
ic.doors[e.unit_number] = car.entity.unit_number
|
||||
car.doors[#car.doors + 1] = e
|
||||
end
|
||||
end
|
||||
|
||||
local function get_player_data(ic, player)
|
||||
local player_data = ic.players[player.index]
|
||||
if ic.players[player.index] then
|
||||
return player_data
|
||||
end
|
||||
local fallback = WPT.get('active_surface_index')
|
||||
if not fallback then
|
||||
fallback = 1
|
||||
end
|
||||
|
||||
ic.players[player.index] = {
|
||||
surface = 1,
|
||||
fallback_surface = tonumber(fallback),
|
||||
notified = false
|
||||
}
|
||||
return ic.players[player.index]
|
||||
end
|
||||
|
||||
local remove_car =
|
||||
Token.register(
|
||||
function(data)
|
||||
local player = data.player
|
||||
local car = data.car
|
||||
player.remove_item({name = car.name, count = 1})
|
||||
end
|
||||
)
|
||||
|
||||
function Public.save_car(ic, event)
|
||||
local entity = event.entity
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
local car = ic.cars[entity.unit_number]
|
||||
|
||||
if not car then
|
||||
log_err('Car was not valid.')
|
||||
return
|
||||
end
|
||||
|
||||
local position = entity.position
|
||||
local health = entity.health
|
||||
|
||||
kick_players_out_of_vehicles(car)
|
||||
kick_players_from_surface(ic, car)
|
||||
get_player_data(ic, player)
|
||||
|
||||
if car.owner == player.index then
|
||||
save_surface(ic, entity, player)
|
||||
if not ic.players[player.index].notified then
|
||||
player.print(player.name .. ', the ' .. car.name .. ' has been saved', Color.success)
|
||||
|
||||
ic.players[player.index].notified = true
|
||||
|
||||
local wave_number = WD.get('wave_number')
|
||||
--game.print(type(wave_number))
|
||||
local a = 100
|
||||
|
||||
if ( wave_number <= a ) then
|
||||
player.print({'amap.usecar'},Color.warning)
|
||||
|
||||
else
|
||||
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+50
|
||||
player.print({'amap.usecar2'},Color.success)
|
||||
end
|
||||
end
|
||||
else
|
||||
local p = game.players[car.owner]
|
||||
if not p then
|
||||
return
|
||||
end
|
||||
|
||||
log_err(ic, 'Owner of this vehicle is: ' .. p.name)
|
||||
save_surface(ic, entity, p)
|
||||
Utils.action_warning('{Car}', player.name .. ' has looted ' .. p.name .. '´s car.')
|
||||
player.print('This car was not yours to keep.', Color.warning)
|
||||
local params = {
|
||||
player = player,
|
||||
car = car
|
||||
}
|
||||
Task.set_timeout_in_ticks(10, remove_car, params)
|
||||
if ic.restore_on_theft then
|
||||
local e = player.surface.create_entity({name = car.name, position = position, force = player.force, create_build_effect_smoke = false})
|
||||
e.health = health
|
||||
restore_surface(ic, p, e)
|
||||
else
|
||||
p.insert({name = car.name, count = 1, health = health})
|
||||
p.print('Your car was stolen from you - the gods foresaw this and granted you a new one.', Color.info)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.kill_car(ic, entity)
|
||||
if not validate_entity(entity) then
|
||||
return
|
||||
end
|
||||
|
||||
local entity_type = ic.entity_type
|
||||
|
||||
if not entity_type[entity.type] then
|
||||
return
|
||||
end
|
||||
|
||||
local car = ic.cars[entity.unit_number]
|
||||
local surface = car.surface
|
||||
kick_players_out_of_vehicles(car)
|
||||
kill_doors(ic, car)
|
||||
kick_players_from_surface(ic, car)
|
||||
for _, tile in pairs(surface.find_tiles_filtered({area = car.area})) do
|
||||
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
|
||||
end
|
||||
for _, x in pairs({car.area.left_top.x - 1.5, car.area.right_bottom.x + 1.5}) do
|
||||
local p = {x = x, y = car.area.left_top.y + ((car.area.right_bottom.y - car.area.left_top.y) * 0.5)}
|
||||
surface.set_tiles({{name = 'out-of-map', position = {x = p.x + 0.5, y = p.y}}}, true)
|
||||
surface.set_tiles({{name = 'out-of-map', position = {x = p.x - 1, y = p.y}}}, true)
|
||||
end
|
||||
car.entity.force.chart(surface, car.area)
|
||||
game.delete_surface(surface)
|
||||
ic.surfaces[entity.unit_number] = nil
|
||||
ic.cars[entity.unit_number] = nil
|
||||
end
|
||||
|
||||
function Public.validate_owner(ic, player, entity)
|
||||
if validate_entity(entity) then
|
||||
local cars = ic.cars
|
||||
local unit_number = entity.unit_number
|
||||
local car = cars[unit_number]
|
||||
if not car then
|
||||
return
|
||||
end
|
||||
if validate_entity(car.entity) then
|
||||
local p = game.players[car.owner]
|
||||
local list = get_trusted_system(ic, p)
|
||||
if p and p.valid and p.connected then
|
||||
if list[player.name] then
|
||||
return
|
||||
end
|
||||
end
|
||||
if p then
|
||||
if car.owner ~= player.index and player.driving then
|
||||
player.driving = false
|
||||
if not player.admin then
|
||||
return Utils.print_to(nil, '{Car} ' .. player.name .. ' tried to drive ' .. p.name .. '´s car.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Public.create_room_surface(ic, unit_number)
|
||||
if game.surfaces[tostring(unit_number)] then
|
||||
return game.surfaces[tostring(unit_number)]
|
||||
end
|
||||
|
||||
local map_gen_settings = {
|
||||
['width'] = 2,
|
||||
['height'] = 2,
|
||||
['water'] = 0,
|
||||
['starting_area'] = 1,
|
||||
['cliff_settings'] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
|
||||
['default_enable_all_autoplace_controls'] = true,
|
||||
['autoplace_settings'] = {
|
||||
['entity'] = {treat_missing_as_default = false},
|
||||
['tile'] = {treat_missing_as_default = true},
|
||||
['decorative'] = {treat_missing_as_default = false}
|
||||
}
|
||||
}
|
||||
local surface = game.create_surface(tostring(unit_number), map_gen_settings)
|
||||
surface.freeze_daytime = true
|
||||
surface.daytime = 0.1
|
||||
surface.request_to_generate_chunks({16, 16}, 1)
|
||||
surface.force_generate_chunk_requests()
|
||||
for _, tile in pairs(surface.find_tiles_filtered({area = {{-2, -2}, {2, 2}}})) do
|
||||
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
|
||||
end
|
||||
ic.surfaces[unit_number] = surface
|
||||
return surface
|
||||
end
|
||||
|
||||
function Public.create_car_room(ic, car)
|
||||
local surface = car.surface
|
||||
local car_areas = ic.car_areas
|
||||
local entity_name = car.name
|
||||
local area = car_areas[entity_name]
|
||||
local tiles = {}
|
||||
|
||||
for x = area.left_top.x, area.right_bottom.x - 1, 1 do
|
||||
for y = area.left_top.y + 2, area.right_bottom.y - 3, 1 do
|
||||
tiles[#tiles + 1] = {name = main_tile_name, position = {x, y}}
|
||||
end
|
||||
end
|
||||
for x = -3, 2, 1 do
|
||||
for y = area.right_bottom.y - 4, area.right_bottom.y - 2, 1 do
|
||||
tiles[#tiles + 1] = {name = main_tile_name, position = {x, y}}
|
||||
end
|
||||
end
|
||||
|
||||
local fishes = {}
|
||||
|
||||
for x = area.left_top.x, area.right_bottom.x - 1, 1 do
|
||||
for y = -0, 1, 1 do
|
||||
tiles[#tiles + 1] = {name = 'water', position = {x, y}}
|
||||
fishes[#fishes + 1] = {name = 'fish', position = {x, y}}
|
||||
end
|
||||
end
|
||||
|
||||
surface.set_tiles(tiles, true)
|
||||
for _, fish in pairs(fishes) do
|
||||
surface.create_entity(fish)
|
||||
end
|
||||
|
||||
construct_doors(ic, car)
|
||||
local mgs = surface.map_gen_settings
|
||||
mgs.width = area.right_bottom.x * 2
|
||||
mgs.height = area.right_bottom.y * 2
|
||||
surface.map_gen_settings = mgs
|
||||
local lx, ly, rx, ry = 4, 1, 5, 1
|
||||
|
||||
local position1 = {area.left_top.x + lx, area.left_top.y + ly}
|
||||
local position2 = {area.right_bottom.x - rx, area.left_top.y + ry}
|
||||
|
||||
local e1 =
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'logistic-chest-requester',
|
||||
position = position1,
|
||||
force = 'neutral',
|
||||
create_build_effect_smoke = false
|
||||
}
|
||||
)
|
||||
e1.destructible = false
|
||||
e1.minable = false
|
||||
|
||||
local e2 =
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'logistic-chest-passive-provider',
|
||||
position = position2,
|
||||
force = 'neutral',
|
||||
create_build_effect_smoke = false
|
||||
}
|
||||
)
|
||||
e2.destructible = false
|
||||
e2.minable = false
|
||||
car.transfer_entities = {e1, e2}
|
||||
return
|
||||
end
|
||||
|
||||
function Public.create_car(ic, event)
|
||||
local ce = event.created_entity
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
|
||||
local map_name = ic.allowed_surface
|
||||
|
||||
local entity_type = ic.entity_type
|
||||
local un = ce.unit_number
|
||||
|
||||
if not un then
|
||||
return
|
||||
end
|
||||
|
||||
if not entity_type[ce.type] then
|
||||
return
|
||||
end
|
||||
|
||||
local name, mined = get_player_entity(ic, player)
|
||||
|
||||
if entity_type[name] and not mined then
|
||||
return player.print('Multiple vehicles are not supported at the moment.', Color.warning)
|
||||
end
|
||||
|
||||
if string.sub(ce.surface.name, 0, #map_name) ~= map_name then
|
||||
return player.print('Multi-surface is not supported at the moment.', Color.warning)
|
||||
end
|
||||
|
||||
if
|
||||
get_owner_car_name(ic, player) == 'car' and ce.name == 'tank' or get_owner_car_name(ic, player) == 'car' and ce.name == 'spidertron' or
|
||||
get_owner_car_name(ic, player) == 'tank' and ce.name == 'spidertron'
|
||||
then
|
||||
upgrade_surface(ic, player, ce)
|
||||
render_owner_text(ic.renders, player, ce)
|
||||
player.print('Your car-surface has been upgraded!', Color.success)
|
||||
return
|
||||
end
|
||||
|
||||
local saved_surface = restore_surface(ic, player, ce)
|
||||
if saved_surface then
|
||||
return
|
||||
end
|
||||
|
||||
local car_areas = ic.car_areas
|
||||
local car_area = car_areas[ce.name]
|
||||
|
||||
ic.cars[un] = {
|
||||
entity = ce,
|
||||
area = {
|
||||
left_top = {x = car_area.left_top.x, y = car_area.left_top.y},
|
||||
right_bottom = {x = car_area.right_bottom.x, y = car_area.right_bottom.y}
|
||||
},
|
||||
doors = {},
|
||||
owner = player.index,
|
||||
name = ce.name
|
||||
}
|
||||
|
||||
local car = ic.cars[un]
|
||||
|
||||
car.surface = Public.create_room_surface(ic, un)
|
||||
Public.create_car_room(ic, car)
|
||||
render_owner_text(ic.renders, player, ce)
|
||||
|
||||
return car
|
||||
end
|
||||
|
||||
function Public.remove_invalid_cars(ic)
|
||||
for k, car in pairs(ic.cars) do
|
||||
if type(car.entity) ~= 'boolean' then
|
||||
if not validate_entity(car.entity) then
|
||||
ic.cars[k] = nil
|
||||
for key, value in pairs(ic.doors) do
|
||||
if k == value then
|
||||
ic.doors[key] = nil
|
||||
end
|
||||
end
|
||||
kick_players_from_surface(ic, car)
|
||||
end
|
||||
end
|
||||
end
|
||||
for k, surface in pairs(ic.surfaces) do
|
||||
if not ic.cars[tonumber(surface.name)] then
|
||||
game.delete_surface(surface)
|
||||
ic.surfaces[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.use_door_with_entity(ic, player, door)
|
||||
local player_data = get_player_data(ic, player)
|
||||
if player_data.state then
|
||||
player_data.state = player_data.state - 1
|
||||
if player_data.state == 0 then
|
||||
player_data.state = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not validate_entity(door) then
|
||||
return
|
||||
end
|
||||
local doors = ic.doors
|
||||
local cars = ic.cars
|
||||
|
||||
local car = false
|
||||
if doors[door.unit_number] then
|
||||
car = cars[doors[door.unit_number]]
|
||||
end
|
||||
if cars[door.unit_number] then
|
||||
car = cars[door.unit_number]
|
||||
end
|
||||
if not car then
|
||||
return
|
||||
end
|
||||
|
||||
local owner = game.players[car.owner]
|
||||
local list = get_trusted_system(ic, owner)
|
||||
if owner and owner.valid and player.connected then
|
||||
if not list[player.name] and not player.admin then
|
||||
player.driving = false
|
||||
return player.print('You have not been approved by ' .. owner.name .. ' to enter their vehicle.', Color.warning)
|
||||
end
|
||||
end
|
||||
|
||||
player_data.fallback_surface = car.entity.surface.index
|
||||
player_data.fallback_position = {car.entity.position.x, car.entity.position.y}
|
||||
|
||||
if car.entity.surface.name == player.surface.name then
|
||||
local surface = car.surface
|
||||
if validate_entity(car.entity) and car.owner == player.index then
|
||||
IC_Gui.add_toolbar(player)
|
||||
car.entity.minable = false
|
||||
end
|
||||
|
||||
if not validate_entity(surface) then
|
||||
return
|
||||
end
|
||||
|
||||
local area = car.area
|
||||
local x_vector = door.position.x - player.position.x
|
||||
local position
|
||||
if x_vector > 0 then
|
||||
position = {area.left_top.x + 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
|
||||
else
|
||||
position = {area.right_bottom.x - 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
|
||||
end
|
||||
local p = surface.find_non_colliding_position('character', position, 128, 0.5)
|
||||
if p then
|
||||
player.teleport(p, surface)
|
||||
else
|
||||
player.teleport(position, surface)
|
||||
end
|
||||
player_data.surface = surface.index
|
||||
else
|
||||
if validate_entity(car.entity) and car.owner == player.index then
|
||||
IC_Gui.remove_toolbar(player)
|
||||
car.entity.minable = true
|
||||
end
|
||||
local surface = car.entity.surface
|
||||
local x_vector = (door.position.x / math.abs(door.position.x)) * 2
|
||||
local position = {car.entity.position.x + x_vector, car.entity.position.y}
|
||||
local surface_position = surface.find_non_colliding_position('character', position, 128, 0.5)
|
||||
if car.entity.type == 'car' or car.entity.name == 'spidertron' then
|
||||
player.teleport(surface_position, surface)
|
||||
player_data.state = 2
|
||||
player.driving = true
|
||||
else
|
||||
player.teleport(surface_position, surface)
|
||||
end
|
||||
player_data.surface = surface.index
|
||||
end
|
||||
end
|
||||
|
||||
function Public.item_transfer(ic)
|
||||
for _, car in pairs(ic.cars) do
|
||||
if validate_entity(car.entity) then
|
||||
if car.transfer_entities then
|
||||
for k, e in pairs(car.transfer_entities) do
|
||||
if validate_entity(e) then
|
||||
transfer_functions[e.name](car, e)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Public.kick_player_from_surface = kick_player_from_surface
|
||||
Public.get_player_surface = get_player_surface
|
||||
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
|
||||
|
||||
return Public
|
773
maps/amap/ic/gui.lua
Normal file
773
maps/amap/ic/gui.lua
Normal file
@ -0,0 +1,773 @@
|
||||
local ICT = require 'maps.amap.ic.table'
|
||||
local Color = require 'utils.color_presets'
|
||||
local Gui = require 'utils.gui'
|
||||
local Tabs = require 'comfy_panel.main'
|
||||
local Event = require 'utils.event'
|
||||
local rpgtable = require 'modules.rpg.table'
|
||||
local Loot = require'maps.amap.loot'
|
||||
local Public = {}
|
||||
local Alert = require 'utils.alert'
|
||||
--! Gui Frames
|
||||
local save_add_player_button_name = Gui.uid_name()
|
||||
local save_transfer_car_button_name = Gui.uid_name()
|
||||
local discard_add_player_button_name = Gui.uid_name()
|
||||
local discard_transfer_car_button_name = Gui.uid_name()
|
||||
local main_frame_name = Gui.uid_name()
|
||||
local draw_add_player_frame_name = Gui.uid_name()
|
||||
local draw_transfer_car_frame_name = Gui.uid_name()
|
||||
local main_toolbar_name = Gui.uid_name()
|
||||
local cool = Gui.uid_name()
|
||||
local gambel = Gui.uid_name()
|
||||
local buyxp = Gui.uid_name()
|
||||
local add_player_name = Gui.uid_name()
|
||||
local transfer_car_name = Gui.uid_name()
|
||||
local kick_player_name = Gui.uid_name()
|
||||
|
||||
local raise_event = script.raise_event
|
||||
local add_toolbar
|
||||
local remove_toolbar
|
||||
|
||||
local function increment(t, k)
|
||||
t[k] = true
|
||||
end
|
||||
|
||||
local function decrement(t, k)
|
||||
t[k] = nil
|
||||
end
|
||||
|
||||
local function create_player_table(player)
|
||||
local trust_system = ICT.get('trust_system')
|
||||
if not trust_system[player.index] then
|
||||
trust_system[player.index] = {
|
||||
[player.name] = true
|
||||
}
|
||||
end
|
||||
return trust_system[player.index]
|
||||
end
|
||||
|
||||
local function does_player_table_exist(player)
|
||||
local trust_system = ICT.get('trust_system')
|
||||
if not trust_system[player.index] then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function transfer_player_table(player, new_player)
|
||||
local trust_system = ICT.get('trust_system')
|
||||
if not trust_system[player.index] then
|
||||
return false
|
||||
end
|
||||
|
||||
if player.index == new_player.index then
|
||||
return false
|
||||
end
|
||||
|
||||
if not trust_system[new_player.index] then
|
||||
local Functions = require 'maps.amap.ic.functions'
|
||||
|
||||
trust_system[new_player.index] = trust_system[player.index]
|
||||
local name = new_player.name
|
||||
|
||||
if not trust_system[new_player.index][name] then
|
||||
increment(trust_system[new_player.index], name)
|
||||
end
|
||||
|
||||
local cars = ICT.get('cars')
|
||||
local renders = ICT.get('renders')
|
||||
local c = Functions.get_owner_car_object(cars, player)
|
||||
local car = cars[c]
|
||||
car.owner = new_player.index
|
||||
|
||||
Functions.render_owner_text(renders, player, car.entity, new_player)
|
||||
|
||||
remove_toolbar(player)
|
||||
add_toolbar(new_player)
|
||||
|
||||
trust_system[player.index] = nil
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
return trust_system[new_player.index]
|
||||
end
|
||||
|
||||
local function remove_main_frame(main_frame)
|
||||
Gui.remove_data_recursively(main_frame)
|
||||
main_frame.destroy()
|
||||
end
|
||||
|
||||
local function draw_add_player(frame)
|
||||
local main_frame =
|
||||
frame.add(
|
||||
{
|
||||
type = 'frame',
|
||||
name = draw_add_player_frame_name,
|
||||
caption = 'Add Player',
|
||||
direction = 'vertical'
|
||||
}
|
||||
)
|
||||
local main_frame_style = main_frame.style
|
||||
main_frame_style.width = 370
|
||||
main_frame_style.use_header_filler = true
|
||||
|
||||
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
|
||||
local inside_frame_style = inside_frame.style
|
||||
inside_frame_style.padding = 0
|
||||
local inside_table = inside_frame.add {type = 'table', column_count = 1}
|
||||
local inside_table_style = inside_table.style
|
||||
inside_table_style.vertical_spacing = 5
|
||||
inside_table_style.top_padding = 10
|
||||
inside_table_style.left_padding = 10
|
||||
inside_table_style.right_padding = 0
|
||||
inside_table_style.bottom_padding = 10
|
||||
inside_table_style.width = 325
|
||||
|
||||
local add_player_frame = main_frame.add({type = 'textfield', text = 'Name of the player.'})
|
||||
add_player_frame.style.width = 140
|
||||
|
||||
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
|
||||
|
||||
local left_flow = bottom_flow.add({type = 'flow'})
|
||||
left_flow.style.horizontal_align = 'left'
|
||||
left_flow.style.horizontally_stretchable = true
|
||||
|
||||
local close_button = left_flow.add({type = 'button', name = discard_add_player_button_name, caption = 'Discard'})
|
||||
close_button.style = 'back_button'
|
||||
close_button.style.maximal_width = 100
|
||||
|
||||
local right_flow = bottom_flow.add({type = 'flow'})
|
||||
right_flow.style.horizontal_align = 'right'
|
||||
|
||||
local save_button = right_flow.add({type = 'button', name = save_add_player_button_name, caption = 'Save'})
|
||||
save_button.style = 'confirm_button'
|
||||
save_button.style.maximal_width = 100
|
||||
|
||||
Gui.set_data(save_button, add_player_frame)
|
||||
end
|
||||
|
||||
local function draw_transfer_car(frame)
|
||||
local main_frame =
|
||||
frame.add(
|
||||
{
|
||||
type = 'frame',
|
||||
name = draw_transfer_car_frame_name,
|
||||
caption = 'Transfer Car',
|
||||
direction = 'vertical'
|
||||
}
|
||||
)
|
||||
local main_frame_style = main_frame.style
|
||||
main_frame_style.width = 370
|
||||
main_frame_style.use_header_filler = true
|
||||
|
||||
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
|
||||
local inside_frame_style = inside_frame.style
|
||||
inside_frame_style.padding = 0
|
||||
local inside_table = inside_frame.add {type = 'table', column_count = 1}
|
||||
local inside_table_style = inside_table.style
|
||||
inside_table_style.vertical_spacing = 5
|
||||
inside_table_style.top_padding = 10
|
||||
inside_table_style.left_padding = 10
|
||||
inside_table_style.right_padding = 0
|
||||
inside_table_style.bottom_padding = 10
|
||||
inside_table_style.width = 325
|
||||
|
||||
local transfer_car_alert_frame = main_frame.add({type = 'label', caption = "Warning, this action can't be undone!"})
|
||||
transfer_car_alert_frame.style.font_color = {r = 255, g = 0, b = 0}
|
||||
local transfer_car_frame = main_frame.add({type = 'textfield', text = 'Name of the player.'})
|
||||
transfer_car_frame.style.width = 140
|
||||
|
||||
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
|
||||
|
||||
local left_flow = bottom_flow.add({type = 'flow'})
|
||||
left_flow.style.horizontal_align = 'left'
|
||||
left_flow.style.horizontally_stretchable = true
|
||||
|
||||
local close_button = left_flow.add({type = 'button', name = discard_transfer_car_button_name, caption = 'Discard'})
|
||||
close_button.style = 'back_button'
|
||||
close_button.style.maximal_width = 100
|
||||
|
||||
local right_flow = bottom_flow.add({type = 'flow'})
|
||||
right_flow.style.horizontal_align = 'right'
|
||||
|
||||
local save_button = right_flow.add({type = 'button', name = save_transfer_car_button_name, caption = 'Save'})
|
||||
save_button.style = 'confirm_button'
|
||||
save_button.style.maximal_width = 100
|
||||
|
||||
Gui.set_data(save_button, transfer_car_frame)
|
||||
end
|
||||
|
||||
local function draw_players(data)
|
||||
local player_table = data.player_table
|
||||
local add_player_frame = data.add_player_frame
|
||||
local player = data.player
|
||||
local player_list = create_player_table(player)
|
||||
|
||||
for p, _ in pairs(player_list) do
|
||||
Gui.set_data(add_player_frame, p)
|
||||
local t_label =
|
||||
player_table.add(
|
||||
{
|
||||
type = 'label',
|
||||
caption = p
|
||||
}
|
||||
)
|
||||
t_label.style.minimal_width = 75
|
||||
t_label.style.horizontal_align = 'center'
|
||||
|
||||
local a_label =
|
||||
player_table.add(
|
||||
{
|
||||
type = 'label',
|
||||
caption = '✔️'
|
||||
}
|
||||
)
|
||||
a_label.style.minimal_width = 75
|
||||
a_label.style.horizontal_align = 'center'
|
||||
a_label.style.font = 'default-large-bold'
|
||||
|
||||
local kick_flow = player_table.add {type = 'flow'}
|
||||
local kick_player_button =
|
||||
kick_flow.add(
|
||||
{
|
||||
type = 'button',
|
||||
caption = 'Kick ' .. p,
|
||||
name = kick_player_name
|
||||
}
|
||||
)
|
||||
if player.name == t_label.caption then
|
||||
kick_player_button.enabled = false
|
||||
end
|
||||
kick_player_button.style.minimal_width = 75
|
||||
Gui.set_data(kick_player_button, p)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_main_frame(player)
|
||||
local main_frame =
|
||||
player.gui.screen.add(
|
||||
{
|
||||
type = 'frame',
|
||||
name = main_frame_name,
|
||||
caption = 'Car Settings',
|
||||
direction = 'vertical',
|
||||
style = 'inner_frame_in_outer_frame'
|
||||
}
|
||||
)
|
||||
|
||||
main_frame.auto_center = true
|
||||
local main_frame_style = main_frame.style
|
||||
main_frame_style.width = 400
|
||||
main_frame_style.use_header_filler = true
|
||||
|
||||
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
|
||||
local inside_frame_style = inside_frame.style
|
||||
inside_frame_style.padding = 0
|
||||
|
||||
local inside_table = inside_frame.add {type = 'table', column_count = 1}
|
||||
local inside_table_style = inside_table.style
|
||||
inside_table_style.vertical_spacing = 5
|
||||
inside_table_style.top_padding = 10
|
||||
inside_table_style.left_padding = 10
|
||||
inside_table_style.right_padding = 0
|
||||
inside_table_style.bottom_padding = 10
|
||||
inside_table_style.width = 350
|
||||
|
||||
local add_player_frame = inside_table.add({type = 'button', caption = 'Add Player', name = add_player_name})
|
||||
local transfer_car_frame = inside_table.add({type = 'button', caption = 'Transfer Car', name = transfer_car_name})
|
||||
|
||||
local player_table =
|
||||
inside_table.add {
|
||||
type = 'table',
|
||||
column_count = 3,
|
||||
draw_horizontal_lines = true,
|
||||
draw_vertical_lines = true,
|
||||
vertical_centering = true
|
||||
}
|
||||
local player_table_style = player_table.style
|
||||
player_table_style.vertical_spacing = 10
|
||||
player_table_style.width = 350
|
||||
player_table_style.horizontal_spacing = 30
|
||||
|
||||
local name_label =
|
||||
player_table.add(
|
||||
{
|
||||
type = 'label',
|
||||
caption = 'Name',
|
||||
tooltip = ''
|
||||
}
|
||||
)
|
||||
name_label.style.minimal_width = 75
|
||||
name_label.style.horizontal_align = 'center'
|
||||
|
||||
local trusted_label =
|
||||
player_table.add(
|
||||
{
|
||||
type = 'label',
|
||||
caption = 'Allowed',
|
||||
tooltip = ''
|
||||
}
|
||||
)
|
||||
trusted_label.style.minimal_width = 75
|
||||
trusted_label.style.horizontal_align = 'center'
|
||||
|
||||
local operations_label =
|
||||
player_table.add(
|
||||
{
|
||||
type = 'label',
|
||||
caption = 'Operations',
|
||||
tooltip = ''
|
||||
}
|
||||
)
|
||||
operations_label.style.minimal_width = 75
|
||||
operations_label.style.horizontal_align = 'center'
|
||||
|
||||
local data = {
|
||||
player_table = player_table,
|
||||
add_player_frame = add_player_frame,
|
||||
transfer_car_frame = transfer_car_frame,
|
||||
player = player
|
||||
}
|
||||
draw_players(data)
|
||||
|
||||
player.opened = main_frame
|
||||
end
|
||||
|
||||
local function toggle(player, recreate)
|
||||
local screen = player.gui.screen
|
||||
local main_frame = screen[main_frame_name]
|
||||
|
||||
if recreate and main_frame then
|
||||
local location = main_frame.location
|
||||
remove_main_frame(main_frame)
|
||||
draw_main_frame(player, location)
|
||||
return
|
||||
end
|
||||
if main_frame then
|
||||
remove_main_frame(main_frame)
|
||||
Tabs.comfy_panel_restore_left_gui(player)
|
||||
else
|
||||
Tabs.comfy_panel_clear_left_gui(player)
|
||||
draw_main_frame(player)
|
||||
end
|
||||
end
|
||||
|
||||
add_toolbar = function(player, remove)
|
||||
if remove then
|
||||
if player.gui.top[main_toolbar_name] then
|
||||
player.gui.top[cool].destroy()
|
||||
player.gui.top[buyxp].destroy()
|
||||
player.gui.top[gambel].destroy()
|
||||
player.gui.top[main_toolbar_name].destroy()
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
if player.gui.top[main_toolbar_name] then
|
||||
return
|
||||
end
|
||||
|
||||
local tooltip = 'contorl who can enter your car.'
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/spidertron',
|
||||
name = main_toolbar_name,
|
||||
tooltip = tooltip
|
||||
}
|
||||
)
|
||||
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/logistic-chest-storage',
|
||||
name = cool,
|
||||
tooltip = {'amap.openchest'}
|
||||
}
|
||||
)
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/coin',
|
||||
name = gambel,
|
||||
tooltip = {'amap.gambel'}
|
||||
}
|
||||
)
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/rocket-part',
|
||||
name = buyxp,
|
||||
tooltip = {'amap.buyxp'}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
remove_toolbar = function(player)
|
||||
local screen = player.gui.screen
|
||||
local main_frame = screen[main_frame_name]
|
||||
|
||||
if main_frame and main_frame.valid then
|
||||
remove_main_frame(main_frame)
|
||||
end
|
||||
|
||||
if player.gui.top[main_toolbar_name] then
|
||||
player.gui.top[main_toolbar_name].destroy()
|
||||
player.gui.top[cool].destroy()
|
||||
player.gui.top[buyxp].destroy()
|
||||
player.gui.top[gambel].destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Gui.on_click(
|
||||
add_player_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
if not frame or not frame.valid then
|
||||
return
|
||||
end
|
||||
local player_frame = frame[draw_add_player_frame_name]
|
||||
if not player_frame or not player_frame.valid then
|
||||
draw_add_player(frame)
|
||||
else
|
||||
player_frame.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
transfer_car_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
if not frame or not frame.valid then
|
||||
return
|
||||
end
|
||||
local player_frame = frame[draw_transfer_car_frame_name]
|
||||
if not player_frame or not player_frame.valid then
|
||||
draw_transfer_car(frame)
|
||||
else
|
||||
player_frame.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
Gui.on_click(
|
||||
gambel ,
|
||||
function(event)
|
||||
local player = event.player
|
||||
local something = player.get_inventory(defines.inventory.chest)
|
||||
for k, v in pairs(something.get_contents()) do
|
||||
local t = {name = k, count = v}
|
||||
if t.name == 'coin' then
|
||||
if v > 999 then
|
||||
player.remove_item{name='coin', count = '1000'}
|
||||
local roll = math.random(1,100)
|
||||
if roll <= 36 then
|
||||
player.insert{name='coin', count = '2500'}
|
||||
player.print({'amap.gambel1'})
|
||||
return
|
||||
else
|
||||
player.print({'amap.gambel2'})
|
||||
return
|
||||
end
|
||||
else
|
||||
player.print({'amap.noenough'})
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
cool ,
|
||||
function(event)
|
||||
local player = event.player
|
||||
local something = player.get_inventory(defines.inventory.chest)
|
||||
for k, v in pairs(something.get_contents()) do
|
||||
local t = {name = k, count = v}
|
||||
if t.name == 'coin' then
|
||||
if v > 2999 then
|
||||
player.remove_item{name='coin', count = '3000'}
|
||||
local luck = math.floor(math.random(1,130))
|
||||
player.print({'amap.lucknb'})
|
||||
player.print(luck)
|
||||
local magic = luck*5+100
|
||||
local msg = {'amap.whatopen'}
|
||||
Loot.cool(player.surface, player.surface.find_non_colliding_position("steel-chest", player.position, 20, 1, true) or player.position, 'steel-chest', magic)
|
||||
Alert.alert_player(player, 5, msg)
|
||||
return
|
||||
else
|
||||
player.print({'amap.noenough'})
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
Gui.on_click(
|
||||
buyxp ,
|
||||
function(event)
|
||||
local player = event.player
|
||||
local something = player.get_inventory(defines.inventory.chest)
|
||||
for k, v in pairs(something.get_contents()) do
|
||||
local t = {name = k, count = v}
|
||||
if t.name == 'coin' then
|
||||
if v > 4999 then
|
||||
player.remove_item{name='coin', count = '5000'}
|
||||
local rpg_t = rpgtable.get('rpg_t')
|
||||
|
||||
rpg_t[player.index].xp = rpg_t[player.index].xp +1000
|
||||
local msg = {'amap.buyover'}
|
||||
Alert.alert_player(player, 5, msg)
|
||||
return
|
||||
else
|
||||
player.print({'amap.noenough'})
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
Gui.on_click(
|
||||
save_add_player_button_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local player_list = create_player_table(player)
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
local add_player_frame = Gui.get_data(event.element)
|
||||
|
||||
if frame and frame.valid then
|
||||
if add_player_frame and add_player_frame.valid and add_player_frame.text then
|
||||
local text = add_player_frame.text
|
||||
if not text then
|
||||
return
|
||||
end
|
||||
local player_to_add = game.get_player(text)
|
||||
if not player_to_add or not player_to_add.valid then
|
||||
return player.print('Target player was not valid.', Color.warning)
|
||||
end
|
||||
|
||||
local name = player_to_add.name
|
||||
|
||||
if not player_list[name] then
|
||||
player.print(name .. ' was added to your vehicle.', Color.info)
|
||||
player_to_add.print(player.name .. ' added you to their vehicle. You may now enter it.', Color.info)
|
||||
increment(player_list, name)
|
||||
else
|
||||
return player.print('Target player is already trusted.', Color.warning)
|
||||
end
|
||||
|
||||
remove_main_frame(event.element)
|
||||
|
||||
if player.gui.screen[main_frame_name] then
|
||||
toggle(player, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
save_transfer_car_button_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
local transfer_car_frame = Gui.get_data(event.element)
|
||||
|
||||
if frame and frame.valid then
|
||||
if transfer_car_frame and transfer_car_frame.valid and transfer_car_frame.text then
|
||||
local text = transfer_car_frame.text
|
||||
if not text then
|
||||
return
|
||||
end
|
||||
local player_to_add = game.get_player(text)
|
||||
if not player_to_add or not player_to_add.valid then
|
||||
return player.print('Target player was not valid.', Color.warning)
|
||||
end
|
||||
|
||||
local name = player_to_add.name
|
||||
local does_player_have_a_car = does_player_table_exist(name)
|
||||
if does_player_have_a_car then
|
||||
return player.print(name .. ' already has a vehicle.', Color.warning)
|
||||
end
|
||||
|
||||
local to_add = game.get_player(name)
|
||||
if not (to_add and to_add.valid) then
|
||||
return player.print(name .. ' does not exist.', Color.warning)
|
||||
end
|
||||
|
||||
local success = transfer_player_table(player, to_add)
|
||||
if not success then
|
||||
player.print('Please try again.', Color.warning)
|
||||
else
|
||||
player.print('You have successfully transferred your car to ' .. name, Color.success)
|
||||
to_add.print('You have become the rightfully owner of ' .. player.name .. "'s car!", Color.success)
|
||||
end
|
||||
|
||||
remove_main_frame(event.element)
|
||||
|
||||
if player.gui.screen[main_frame_name] then
|
||||
player.gui.screen[main_frame_name].destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
kick_player_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local player_list = create_player_table(player)
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
local player_name = Gui.get_data(event.element)
|
||||
local this = ICT.get()
|
||||
|
||||
if frame and frame.valid then
|
||||
if not player_name then
|
||||
return
|
||||
end
|
||||
local target = game.get_player(player_name)
|
||||
if not target or not target.valid then
|
||||
player.print('Target player was not valid.', Color.warning)
|
||||
return
|
||||
end
|
||||
local name = target.name
|
||||
|
||||
if player_list[name] then
|
||||
player.print(name .. ' was removed from your vehicle.', Color.info)
|
||||
decrement(player_list, name)
|
||||
raise_event(
|
||||
ICT.events.on_player_kicked_from_surface,
|
||||
{
|
||||
player = player,
|
||||
target = target,
|
||||
this = this
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
remove_main_frame(event.element)
|
||||
|
||||
if player.gui.screen[main_frame_name] then
|
||||
toggle(player, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
discard_add_player_button_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
if not frame or not frame.valid then
|
||||
return
|
||||
end
|
||||
local player_frame = frame[draw_add_player_frame_name]
|
||||
|
||||
if player_frame and player_frame.valid then
|
||||
player_frame.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
discard_transfer_car_button_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
if not frame or not frame.valid then
|
||||
return
|
||||
end
|
||||
local player_frame = frame[draw_transfer_car_frame_name]
|
||||
|
||||
if player_frame and player_frame.valid then
|
||||
player_frame.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
main_toolbar_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
|
||||
if frame and frame.valid then
|
||||
frame.destroy()
|
||||
else
|
||||
draw_main_frame(player)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Public.draw_main_frame = draw_main_frame
|
||||
Public.toggle = toggle
|
||||
Public.add_toolbar = add_toolbar
|
||||
Public.remove_toolbar = remove_toolbar
|
||||
|
||||
Event.add(
|
||||
defines.events.on_gui_closed,
|
||||
function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
|
||||
if frame and frame.valid then
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
187
maps/amap/ic/main.lua
Normal file
187
maps/amap/ic/main.lua
Normal file
@ -0,0 +1,187 @@
|
||||
require 'modules.check_fullness'
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local Functions = require 'maps.amap.ic.functions'
|
||||
local IC = require 'maps.amap.ic.table'
|
||||
local Minimap = require 'maps.amap.ic.minimap'
|
||||
local Public = {}
|
||||
|
||||
Public.reset = IC.reset
|
||||
Public.get_table = IC.get
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local ic = IC.get()
|
||||
|
||||
if entity.type == 'car' or entity.name == 'spidertron' then
|
||||
Minimap.kill_minimap(game.players[event.player_index])
|
||||
Functions.kill_car(ic, entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local ic = IC.get()
|
||||
|
||||
--Minimap.kill_minimap(game.players[event.player_index])
|
||||
|
||||
if entity.type == 'car' or entity.name == 'spidertron' then
|
||||
Functions.save_car(ic, event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_robot_mined_entity(event)
|
||||
local entity = event.entity
|
||||
|
||||
if not entity and not entity.valid then
|
||||
return
|
||||
end
|
||||
local ic = IC.get()
|
||||
|
||||
if entity.type == 'car' or entity.name == 'spidertron' then
|
||||
Functions.kill_car(ic, entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_built_entity(event)
|
||||
local ce = event.created_entity
|
||||
|
||||
if not ce or not ce.valid then
|
||||
return
|
||||
end
|
||||
if (ce.type == 'car' or ce.name == 'spidertron') ~= true then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local ic = IC.get()
|
||||
Functions.create_car(ic, event)
|
||||
end
|
||||
|
||||
local function on_player_driving_changed_state(event)
|
||||
local ic = IC.get()
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
Functions.use_door_with_entity(ic, player, event.entity)
|
||||
Functions.validate_owner(ic, player, event.entity)
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
local ic = IC.get()
|
||||
local tick = game.tick
|
||||
|
||||
if tick % 10 == 1 then
|
||||
Functions.item_transfer(ic)
|
||||
end
|
||||
|
||||
if tick % 240 == 0 then
|
||||
Minimap.update_minimap()
|
||||
end
|
||||
|
||||
if tick % 400 == 0 then
|
||||
Functions.remove_invalid_cars(ic)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_closed(event)
|
||||
local entity = event.entity
|
||||
if not entity then
|
||||
return
|
||||
end
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
if not entity.unit_number then
|
||||
return
|
||||
end
|
||||
local ic = IC.get()
|
||||
if not ic.cars[entity.unit_number] then
|
||||
return
|
||||
end
|
||||
|
||||
Minimap.kill_minimap(game.players[event.player_index])
|
||||
end
|
||||
|
||||
local function on_gui_opened(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not entity.unit_number then
|
||||
return
|
||||
end
|
||||
local ic = IC.get()
|
||||
local car = ic.cars[entity.unit_number]
|
||||
if not car then
|
||||
return
|
||||
end
|
||||
|
||||
Minimap.minimap(
|
||||
game.players[event.player_index],
|
||||
car.surface,
|
||||
{
|
||||
car.area.left_top.x + (car.area.right_bottom.x - car.area.left_top.x) * 0.5,
|
||||
car.area.left_top.y + (car.area.right_bottom.y - car.area.left_top.y) * 0.5
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
local element = event.element
|
||||
if not element or not element.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if event.element.name == 'minimap_button' then
|
||||
Minimap.minimap(player, false)
|
||||
elseif event.element.name == 'minimap_frame' or event.element.name == 'minimap_toggle_frame' then
|
||||
Minimap.toggle_minimap(event)
|
||||
elseif event.element.name == 'switch_auto_map' then
|
||||
Minimap.toggle_auto(player)
|
||||
end
|
||||
end
|
||||
|
||||
local function trigger_on_player_kicked_from_surface(data)
|
||||
local player = data.player
|
||||
local target = data.target
|
||||
local this = data.this
|
||||
Functions.kick_player_from_surface(this, player, target)
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
Public.reset()
|
||||
end
|
||||
|
||||
local changed_surface = Minimap.changed_surface
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
||||
Event.add(defines.events.on_gui_closed, on_gui_closed)
|
||||
Event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity)
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
Event.add(defines.events.on_player_changed_surface, changed_surface)
|
||||
Event.add(IC.events.on_player_kicked_from_surface, trigger_on_player_kicked_from_surface)
|
||||
return Public
|
258
maps/amap/ic/minimap.lua
Normal file
258
maps/amap/ic/minimap.lua
Normal file
@ -0,0 +1,258 @@
|
||||
local Public = {}
|
||||
|
||||
local ICT = require 'maps.amap.ic.table'
|
||||
local Functions = require 'maps.amap.ic.functions'
|
||||
local Gui = require 'maps.amap.ic.gui'
|
||||
|
||||
local function validate_player(player)
|
||||
if not player then
|
||||
return false
|
||||
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.players[player.name] then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function create_button(player)
|
||||
local button =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = 'minimap_button',
|
||||
sprite = 'utility/map',
|
||||
tooltip = 'Open or close minimap.'
|
||||
}
|
||||
)
|
||||
button.visible = false
|
||||
end
|
||||
|
||||
function Public.toggle_button(player)
|
||||
if not player.gui.top['minimap_button'] then
|
||||
create_button(player)
|
||||
end
|
||||
local ic = ICT.get()
|
||||
local button = player.gui.top['minimap_button']
|
||||
if Functions.get_player_surface(ic, player) then
|
||||
button.visible = true
|
||||
else
|
||||
button.visible = false
|
||||
end
|
||||
end
|
||||
|
||||
local function get_player_data(player)
|
||||
local ic = ICT.get()
|
||||
local player_data = ic.minimap[player.index]
|
||||
if ic.minimap[player.index] then
|
||||
return player_data
|
||||
end
|
||||
|
||||
ic.minimap[player.index] = {
|
||||
surface = ic.allowed_surface,
|
||||
zoom = 0.30,
|
||||
map_size = 360,
|
||||
auto_map = true
|
||||
}
|
||||
return ic.minimap[player.index]
|
||||
end
|
||||
|
||||
function Public.toggle_auto(player)
|
||||
local ic = ICT.get()
|
||||
local switch = player.gui.left.minimap_toggle_frame['switch_auto_map']
|
||||
if not switch or not switch.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if switch.switch_state == 'left' then
|
||||
ic.minimap[player.index].auto_map = true
|
||||
elseif switch.switch_state == 'right' then
|
||||
ic.minimap[player.index].auto_map = false
|
||||
end
|
||||
end
|
||||
|
||||
local function kill_minimap(player)
|
||||
local frame = player.gui.left.minimap_toggle_frame
|
||||
if not frame or not frame.valid then
|
||||
return
|
||||
end
|
||||
if frame.visible then
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function kill_frame(player)
|
||||
if player.gui.left.minimap_toggle_frame then
|
||||
local element = player.gui.left.minimap_toggle_frame.minimap_frame
|
||||
if not element or not element.valid then
|
||||
return
|
||||
end
|
||||
element.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_minimap(player, surface, position)
|
||||
local ic = ICT.get()
|
||||
surface = surface or game.surfaces[ic.allowed_surface]
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
local cars = ic.cars
|
||||
|
||||
local entity = Functions.get_entity_from_player_surface(cars, player)
|
||||
if not position then
|
||||
if not entity or not entity.valid then
|
||||
kill_minimap(player)
|
||||
kill_frame(player)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
position = position or entity.position
|
||||
local player_data = get_player_data(player)
|
||||
local frame = player.gui.left.minimap_toggle_frame
|
||||
if not frame then
|
||||
frame =
|
||||
player.gui.left.add(
|
||||
{type = 'frame', direction = 'vertical', name = 'minimap_toggle_frame', caption = 'Minimap'}
|
||||
)
|
||||
end
|
||||
frame.visible = true
|
||||
local element = frame['minimap_frame']
|
||||
if not element then
|
||||
element =
|
||||
player.gui.left.minimap_toggle_frame.add(
|
||||
{
|
||||
type = 'camera',
|
||||
name = 'minimap_frame',
|
||||
position = position,
|
||||
surface_index = surface.index,
|
||||
zoom = player_data.zoom,
|
||||
tooltip = 'LMB: Increase zoom level.\nRMB: Decrease zoom level.\nMMB: Toggle camera size.'
|
||||
}
|
||||
)
|
||||
element.style.margin = 1
|
||||
element.style.minimal_height = player_data.map_size
|
||||
element.style.minimal_width = player_data.map_size
|
||||
return
|
||||
end
|
||||
element.position = position
|
||||
end
|
||||
|
||||
function Public.minimap(player, surface, position)
|
||||
local frame = player.gui.left['minimap_toggle_frame']
|
||||
local ic = ICT.get()
|
||||
if frame and frame.visible then
|
||||
kill_minimap(player)
|
||||
else
|
||||
if Functions.get_player_surface(ic, player) and not surface and not position then
|
||||
draw_minimap(player)
|
||||
else
|
||||
draw_minimap(player, surface, position)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.update_minimap()
|
||||
local ic = ICT.get()
|
||||
for k, player in pairs(game.connected_players) do
|
||||
if Functions.get_player_surface(ic, player) and player.gui.left.minimap_toggle_frame then
|
||||
kill_frame(player)
|
||||
draw_minimap(player)
|
||||
else
|
||||
kill_minimap(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.toggle_minimap(event)
|
||||
local element = event.element
|
||||
if not element then
|
||||
return
|
||||
end
|
||||
if not element.valid then
|
||||
return
|
||||
end
|
||||
if element.name ~= 'minimap_frame' then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
local player_data = get_player_data(player)
|
||||
if event.button == defines.mouse_button_type.right then
|
||||
player_data.zoom = player_data.zoom - 0.07
|
||||
if player_data.zoom < 0.07 then
|
||||
player_data.zoom = 0.07
|
||||
end
|
||||
element.zoom = player_data.zoom
|
||||
return
|
||||
end
|
||||
if event.button == defines.mouse_button_type.left then
|
||||
player_data.zoom = player_data.zoom + 0.07
|
||||
if player_data.zoom > 2 then
|
||||
player_data.zoom = 2
|
||||
end
|
||||
element.zoom = player_data.zoom
|
||||
return
|
||||
end
|
||||
if event.button == defines.mouse_button_type.middle then
|
||||
player_data.map_size = player_data.map_size + 50
|
||||
if player_data.map_size > 650 then
|
||||
player_data.map_size = 250
|
||||
end
|
||||
element.style.minimal_height = player_data.map_size
|
||||
element.style.minimal_width = player_data.map_size
|
||||
element.style.maximal_height = player_data.map_size
|
||||
element.style.maximal_width = player_data.map_size
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function Public.changed_surface(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not validate_player(player) then
|
||||
return
|
||||
end
|
||||
|
||||
local ic = ICT.get()
|
||||
local surface = game.surfaces[ic.allowed_surface]
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
local wd = player.gui.top['wave_defense']
|
||||
local diff = player.gui.top['difficulty_gui']
|
||||
|
||||
if Functions.get_player_surface(ic, player) then
|
||||
Public.toggle_button(player)
|
||||
Public.minimap(player, surface)
|
||||
if wd and wd.visible then
|
||||
wd.visible = false
|
||||
end
|
||||
if diff and diff.visible then
|
||||
diff.visible = false
|
||||
end
|
||||
elseif player.surface.index == surface.index then
|
||||
Gui.remove_toolbar(player)
|
||||
Public.toggle_button(player)
|
||||
kill_minimap(player)
|
||||
if wd and not wd.visible then
|
||||
wd.visible = true
|
||||
end
|
||||
if diff and not diff.visible then
|
||||
diff.visible = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Public.kill_minimap = kill_minimap
|
||||
|
||||
return Public
|
87
maps/amap/ic/table.lua
Normal file
87
maps/amap/ic/table.lua
Normal file
@ -0,0 +1,87 @@
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local this = {}
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {
|
||||
events = {
|
||||
on_player_kicked_from_surface = Event.generate_event_name('on_player_kicked_from_surface')
|
||||
}
|
||||
}
|
||||
|
||||
function Public.reset()
|
||||
if this.surfaces then
|
||||
for k, surface in pairs(this.surfaces) do
|
||||
if surface and surface.valid then
|
||||
game.delete_surface(surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
for k, _ in pairs(this) do
|
||||
this[k] = nil
|
||||
end
|
||||
this.debug_mode = false
|
||||
this.restore_on_theft = false
|
||||
this.doors = {}
|
||||
this.cars = {}
|
||||
this.current_car_index = nil
|
||||
this.renders = {}
|
||||
this.saved_surfaces = {}
|
||||
this.allowed_surface = 'nauvis'
|
||||
this.trust_system = {}
|
||||
this.players = {}
|
||||
this.surfaces = {}
|
||||
this.minimap = {}
|
||||
this.entity_type = {
|
||||
['car'] = true,
|
||||
['tank'] = true,
|
||||
['spidertron'] = true,
|
||||
['spider-vehicle'] = true
|
||||
}
|
||||
this.car_areas = {
|
||||
['car'] = {left_top = {x = -20, y = 0}, right_bottom = {x = 20, y = 20}},
|
||||
['tank'] = {left_top = {x = -30, y = 0}, right_bottom = {x = 30, y = 40}},
|
||||
['spidertron'] = {left_top = {x = -40, y = 0}, right_bottom = {x = 40, y = 60}},
|
||||
['spider-vehicle'] = {left_top = {x = -40, y = 0}, right_bottom = {x = 40, y = 60}}
|
||||
}
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
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
|
||||
function Public.set_car_area(tbl)
|
||||
if not tbl then
|
||||
return
|
||||
end
|
||||
|
||||
this.car_areas = tbl
|
||||
end
|
||||
|
||||
function Public.allowed_surface(value)
|
||||
if value then
|
||||
this.allowed_surface = value
|
||||
end
|
||||
return this.allowed_surface
|
||||
end
|
||||
|
||||
return Public
|
157
maps/amap/loot.lua
Normal file
157
maps/amap/loot.lua
Normal file
@ -0,0 +1,157 @@
|
||||
local LootRaffle = require 'functions.loot_raffle'
|
||||
|
||||
local Public = {}
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
local floor = math.floor
|
||||
local sqrt = math.sqrt
|
||||
|
||||
local blacklist = {
|
||||
['atomic-bomb'] = true,
|
||||
['cargo-wagon'] = true,
|
||||
['car'] = true,
|
||||
['tank'] = true,
|
||||
['spidertron'] = true,
|
||||
['locomotive'] = true,
|
||||
['artillery-wagon'] = true,
|
||||
['artillery-turret'] = true,
|
||||
['landfill'] = true,
|
||||
['discharge-defense-equipment'] = true,
|
||||
['discharge-defense-remote'] = true,
|
||||
['fluid-wagon'] = true,
|
||||
['pistol'] = true
|
||||
}
|
||||
|
||||
function Public.get_distance(position)
|
||||
local difficulty = sqrt(position.x ^ 2 + position.y ^ 2) * 0.0001
|
||||
return difficulty
|
||||
end
|
||||
|
||||
function Public.add(surface, position, chest)
|
||||
local budget = 48 + abs(position.y) * 1.75
|
||||
budget = budget * random(25, 175) * 0.01
|
||||
|
||||
if random(1, 128) == 1 then
|
||||
budget = budget * 4
|
||||
chest = 'crash-site-chest-' .. random(1, 2)
|
||||
end
|
||||
if random(1, 256) == 1 then
|
||||
budget = budget * 4
|
||||
chest = 'crash-site-chest-' .. random(1, 2)
|
||||
end
|
||||
|
||||
budget = floor(budget) + 1
|
||||
|
||||
local amount = random(1, 5)
|
||||
local base_amount = 12 * amount
|
||||
local distance_mod = Public.get_distance(position)
|
||||
|
||||
local result = base_amount + budget + distance_mod
|
||||
|
||||
local c = game.entity_prototypes[chest]
|
||||
local slots = c.get_inventory_size(defines.inventory.chest)
|
||||
|
||||
local item_stacks = LootRaffle.roll(result, slots, blacklist)
|
||||
local container = surface.create_entity({name = chest, position = position, force = 'neutral'})
|
||||
for _, item_stack in pairs(item_stacks) do
|
||||
container.insert(item_stack)
|
||||
end
|
||||
container.minable = false
|
||||
|
||||
if random(1, 8) == 1 then
|
||||
container.insert({name = 'coin', count = random(1, 32)})
|
||||
elseif random(1, 32) == 1 then
|
||||
container.insert({name = 'coin', count = random(1, 128)})
|
||||
elseif random(1, 128) == 1 then
|
||||
container.insert({name = 'coin', count = random(1, 256)})
|
||||
end
|
||||
|
||||
for _ = 1, 3, 1 do
|
||||
if random(1, 8) == 1 then
|
||||
container.insert({name = 'explosives', count = random(25, 50)})
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_rare(surface, position, chest, magic)
|
||||
local budget = magic * 48 + abs(position.y) * 1.75
|
||||
budget = budget * random(25, 175) * 0.01
|
||||
|
||||
if random(1, 128) == 1 then
|
||||
budget = budget * 6
|
||||
chest = 'crash-site-chest-' .. random(1, 2)
|
||||
end
|
||||
if random(1, 128) == 1 then
|
||||
budget = budget * 6
|
||||
chest = 'crash-site-chest-' .. random(1, 2)
|
||||
end
|
||||
|
||||
local amount = random(1, 5)
|
||||
local base_amount = 12 * amount
|
||||
local distance_mod = Public.get_distance(position)
|
||||
|
||||
budget = floor(budget) + 1
|
||||
|
||||
local result = base_amount + budget + distance_mod
|
||||
|
||||
local c = game.entity_prototypes[chest]
|
||||
local slots = c.get_inventory_size(defines.inventory.chest)
|
||||
|
||||
local item_stacks = LootRaffle.roll(result, slots, blacklist)
|
||||
local container = surface.create_entity({name = chest, position = position, force = 'neutral'})
|
||||
for _, item_stack in pairs(item_stacks) do
|
||||
container.insert(item_stack)
|
||||
end
|
||||
container.minable = false
|
||||
|
||||
for _ = 1, 3, 1 do
|
||||
if random(1, 8) == 1 then
|
||||
container.insert({name = 'explosives', count = random(25, 50)})
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.cool(surface, position, chest, magic)
|
||||
local budget = magic * 48 + abs(position.y) * 1.75
|
||||
budget = budget * random(25, 175) * 0.01
|
||||
|
||||
if random(1, 128) == 1 then
|
||||
budget = budget * 6
|
||||
chest = 'crash-site-chest-' .. random(1, 2)
|
||||
end
|
||||
if random(1, 128) == 1 then
|
||||
budget = budget * 6
|
||||
chest = 'crash-site-chest-' .. random(1, 2)
|
||||
end
|
||||
|
||||
local amount = random(1, 5)
|
||||
local base_amount = 12 * amount
|
||||
local distance_mod = Public.get_distance(position)
|
||||
|
||||
budget = floor(budget) + 1
|
||||
|
||||
local result = base_amount + budget + distance_mod
|
||||
|
||||
local c = game.entity_prototypes[chest]
|
||||
local slots = c.get_inventory_size(defines.inventory.chest)
|
||||
|
||||
local item_stacks = LootRaffle.roll(result, slots, blacklist)
|
||||
local container = surface.create_entity({name = chest, position = position, force = 'neutral'})
|
||||
for _, item_stack in pairs(item_stacks) do
|
||||
container.insert(item_stack)
|
||||
end
|
||||
|
||||
|
||||
for _ = 1, 3, 1 do
|
||||
if random(1, 8) == 1 then
|
||||
container.insert({name = 'explosives', count = random(25, 50)})
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return Public
|
686
maps/amap/main.lua
Normal file
686
maps/amap/main.lua
Normal file
@ -0,0 +1,686 @@
|
||||
require 'modules.rpg.main'
|
||||
require 'maps.amap.relax'
|
||||
require 'maps.amap.diff'
|
||||
local Functions = require 'maps.amap.functions'
|
||||
local IC = require 'maps.amap.ic.table'
|
||||
local CS = require 'maps.amap.surface'
|
||||
local Event = require 'utils.event'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local wall_health = require 'maps.amap.wall_health_booster'.set_health_modifier
|
||||
|
||||
local spider_health =require 'maps.amap.spider_health_booster'.set_health_modifier
|
||||
|
||||
local Map = require 'modules.map_info'
|
||||
local AntiGrief = require 'antigrief'
|
||||
--local Explosives = require 'modules.explosives'
|
||||
local WPT = require 'maps.amap.table'
|
||||
local Autostash = require 'modules.autostash'
|
||||
local BuriedEnemies = require 'maps.amap.buried_enemies'
|
||||
local RPG_Settings = require 'modules.rpg.table'
|
||||
local RPG_Func = require 'modules.rpg.functions'
|
||||
local Commands = require 'commands.misc'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local Alert = require 'utils.alert'
|
||||
local rock = require 'maps.amap.rock'
|
||||
local Loot = require'maps.amap.loot'
|
||||
local RPG = require 'modules.rpg.table'
|
||||
local Difficulty = require 'modules.difficulty_vote_by_amount'
|
||||
--local arty = require "maps.amap.enemy_arty"
|
||||
--require 'maps.amap.burden'
|
||||
require "modules.spawners_contain_biters"
|
||||
require 'maps.amap.biters_yield_coins'
|
||||
--require 'maps.amap.sort'
|
||||
local Public = {}
|
||||
local floor = math.floor
|
||||
local remove = table.remove
|
||||
--require 'modules.flamethrower_nerf'
|
||||
--加载地形
|
||||
require 'maps.amap.caves'
|
||||
require 'modules.surrounded_by_worms'
|
||||
require 'maps.amap.ic.main'
|
||||
require 'modules.shotgun_buff'
|
||||
require 'modules.no_deconstruction_of_neutral_entities'
|
||||
require 'modules.wave_defense.main'
|
||||
require 'modules.charging_station'
|
||||
|
||||
local init_new_force = function()
|
||||
local new_force = game.forces.protectors
|
||||
local enemy = game.forces.enemy
|
||||
if not new_force then
|
||||
new_force = game.create_force('protectors')
|
||||
end
|
||||
new_force.set_friend('enemy', true)
|
||||
enemy.set_friend('protectors', true)
|
||||
end
|
||||
local setting = function()
|
||||
--game.map_settings.enemy_evolution.destroy_factor = 0.004
|
||||
-- game.map_settings.enemy_evolution.pollution_factor = 0.000003
|
||||
game.map_settings.enemy_expansion.enabled = true
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = 6000
|
||||
game.map_settings.enemy_expansion.max_expansion_cooldown = 104000
|
||||
--game.map_settings.enemy_evolution.time_factor = 0.00004
|
||||
game.map_settings.enemy_expansion.max_expansion_distance = 20
|
||||
game.map_settings.enemy_expansion.settler_group_min_size = 5
|
||||
game.map_settings.enemy_expansion.settler_group_max_size = 50
|
||||
|
||||
global.biter_health_boost_forces[game.forces.player.index] = 1
|
||||
game.forces.player.set_ammo_damage_modifier("artillery-shell", 0)
|
||||
game.forces.player.set_ammo_damage_modifier("melee", 0)
|
||||
game.forces.player.set_ammo_damage_modifier("biological", 0)
|
||||
local index = game.forces.player.index
|
||||
wall_health(index,1)
|
||||
spider_health(index,1)
|
||||
end
|
||||
|
||||
function Public.reset_map()
|
||||
|
||||
local this = WPT.get()
|
||||
local wave_defense_table = WD.get_table()
|
||||
|
||||
--创建一个地表
|
||||
this.active_surface_index = CS.create_surface()
|
||||
|
||||
Autostash.insert_into_furnace(true)
|
||||
Autostash.bottom_button(true)
|
||||
BuriedEnemies.reset()
|
||||
Commands.reset()
|
||||
Commands.activate_custom_buttons(true)
|
||||
Commands.bottom_right(false)
|
||||
|
||||
IC.reset()
|
||||
IC.allowed_surface('amap')
|
||||
|
||||
game.reset_time_played()
|
||||
WPT.reset_table()
|
||||
|
||||
--记得后面改为失去一半经验!并且修订技能!
|
||||
local xp = {}
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
xp[player.index]={}
|
||||
xp[player.index] = rpg_t[player.index].xp / 3
|
||||
|
||||
if xp[player.index] > 5000 then
|
||||
xp[player.index] = 5000
|
||||
end
|
||||
end
|
||||
|
||||
RPG_Func.rpg_reset_all_players()
|
||||
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
rpg_t[player.index].xp = xp[player.index]
|
||||
xp[player.index]={}
|
||||
end
|
||||
|
||||
RPG_Settings.set_surface_name('amap')
|
||||
RPG_Settings.enable_health_and_mana_bars(true)
|
||||
RPG_Settings.enable_wave_defense(true)
|
||||
RPG_Settings.enable_mana(true)
|
||||
RPG_Settings.enable_flame_boots(true)
|
||||
RPG_Settings.enable_stone_path(true)
|
||||
RPG_Settings.enable_one_punch(true)
|
||||
RPG_Settings.enable_one_punch_globally(false)
|
||||
RPG_Settings.enable_auto_allocate(true)
|
||||
RPG_Settings.disable_cooldowns_on_spells()
|
||||
|
||||
--初始化部队
|
||||
init_new_force()
|
||||
--难度设置
|
||||
local Diff = Difficulty.get()
|
||||
Difficulty.reset_difficulty_poll({difficulty_poll_closing_timeout = game.tick + 36000})
|
||||
Diff.gui_width = 20
|
||||
|
||||
local surface = game.surfaces[this.active_surface_index]
|
||||
--Explosives.set_surface_whitelist({[surface.name] = true})
|
||||
game.forces.player.set_spawn_position({0, 0}, surface)
|
||||
|
||||
|
||||
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
Commands.insert_all_items(player)
|
||||
end
|
||||
|
||||
--生产火箭发射井
|
||||
rock.spawn(surface,{x=0,y=10})
|
||||
rock.market(surface)
|
||||
|
||||
WD.reset_wave_defense()
|
||||
wave_defense_table.surface_index = this.active_surface_index
|
||||
--记得修改目标!
|
||||
wave_defense_table.target = this.rock
|
||||
wave_defense_table.nest_building_density = 32
|
||||
wave_defense_table.game_lost = false
|
||||
-- wave_defense_table.set_evolution_time = true
|
||||
--生成随机位置!
|
||||
local positions = {x = 200, y = 200}
|
||||
positions.x = math.random(-200,200)
|
||||
positions.y = math.random(-200,200)
|
||||
|
||||
if positions.y < 75 and positions.y > -75 then
|
||||
|
||||
if positions.y < 0 then
|
||||
positions.y = positions.y - 100
|
||||
else
|
||||
positions.y = positions.y + 100
|
||||
end
|
||||
end
|
||||
if positions.x < 75 and positions.x > -75 then
|
||||
if positions.x < 0 then
|
||||
positions.x = positions.x - 100
|
||||
else
|
||||
positions.x = positions.x + 100
|
||||
end
|
||||
end
|
||||
|
||||
wave_defense_table.spawn_position = positions
|
||||
this.pos = positions
|
||||
this.change = false
|
||||
this.science = 0
|
||||
--game.print(positions)
|
||||
WD.alert_boss_wave(true)
|
||||
WD.clear_corpses(false)
|
||||
WD.remove_entities(true)
|
||||
WD.enable_threat_log(true)
|
||||
WD.set_disable_threat_below_zero(true)
|
||||
WD.set_biter_health_boost(1.4)
|
||||
-- WD.set().wave_interval = 3300
|
||||
-- WD.set().threat_gain_multiplier = 4
|
||||
WD.set().next_wave = game.tick + 7200* 15
|
||||
--初始化虫子科技
|
||||
|
||||
Functions.disable_tech()
|
||||
game.forces.player.set_spawn_position({0, 0}, surface)
|
||||
|
||||
Task.start_queue()
|
||||
Task.set_queue_speed(16)
|
||||
|
||||
this.chunk_load_tick = game.tick + 1200
|
||||
this.game_lost = false
|
||||
this.last = 0
|
||||
|
||||
global.worm_distance = 210
|
||||
global.average_worm_amount_per_chunk = 5
|
||||
|
||||
setting()
|
||||
end
|
||||
|
||||
|
||||
|
||||
local on_init = function()
|
||||
|
||||
Public.reset_map()
|
||||
|
||||
local tooltip = {
|
||||
[1] = ({'amap.easy'}),
|
||||
[2] = ({'amap.med'}),
|
||||
[3] = ({'amap.hard'})
|
||||
}
|
||||
|
||||
Difficulty.set_tooltip(tooltip)
|
||||
|
||||
game.forces.player.research_queue_enabled = true
|
||||
local T = Map.Pop_info()
|
||||
T.localised_category = 'amap'
|
||||
T.main_caption_color = {r = 150, g = 150, b = 0}
|
||||
T.sub_caption_color = {r = 0, g = 150, b = 0}
|
||||
|
||||
|
||||
|
||||
--Explosives.set_whitelist_entity('character')
|
||||
--Explosives.set_whitelist_entity('spidertron')
|
||||
--Explosives.set_whitelist_entity('car')
|
||||
--Explosives.set_whitelist_entity('tank')
|
||||
--地图设置
|
||||
|
||||
--setting()
|
||||
end
|
||||
local is_player_valid = function()
|
||||
local players = game.connected_players
|
||||
for _, player in pairs(players) do
|
||||
if player.connected and not player.character or not player.character.valid then
|
||||
if not player.admin then
|
||||
local player_data = Functions.get_player_data(player)
|
||||
if player_data.died then
|
||||
return
|
||||
end
|
||||
player.set_controller {type = defines.controllers.god}
|
||||
player.create_character()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local has_the_game_ended = function()
|
||||
local game_reset_tick = WPT.get('game_reset_tick')
|
||||
if game_reset_tick then
|
||||
if game_reset_tick < 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local this = WPT.get()
|
||||
|
||||
this.game_reset_tick = this.game_reset_tick - 30
|
||||
if this.game_reset_tick % 1800 == 0 then
|
||||
if this.game_reset_tick > 0 then
|
||||
local cause_msg
|
||||
if this.restart then
|
||||
cause_msg = 'restart'
|
||||
|
||||
end
|
||||
|
||||
game.print(({'main.reset_in', cause_msg, this.game_reset_tick / 60}), {r = 0.22, g = 0.88, b = 0.22})
|
||||
end
|
||||
|
||||
if this.soft_reset and this.game_reset_tick == 0 then
|
||||
this.game_reset_tick = nil
|
||||
Public.reset_map()
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local chunk_load = function()
|
||||
local chunk_load_tick = WPT.get('chunk_load_tick')
|
||||
if chunk_load_tick then
|
||||
if chunk_load_tick < game.tick then
|
||||
WPT.get().chunk_load_tick = nil
|
||||
Task.set_queue_speed(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local rondom = function(player,many)
|
||||
if not player.character or not player.character.valid then return end
|
||||
if many >= 500 then
|
||||
many = 500
|
||||
end
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
local q = math.random(0,19)
|
||||
local k = math.floor(many/100)
|
||||
local get_point = k*5+5
|
||||
if get_point >= 25 then
|
||||
get_point = 25
|
||||
end
|
||||
if q == 16 then
|
||||
if rpg_t[player.index].magicka < (get_point+10) then
|
||||
q = 17
|
||||
-- player.print({'amap.nopoint'})
|
||||
-- player.remove_item{name='coin', count = '1000'}
|
||||
else
|
||||
|
||||
rpg_t[player.index].magicka =rpg_t[player.index].magicka -get_point
|
||||
player.print({'amap.nb16',get_point+10})
|
||||
return
|
||||
end
|
||||
end
|
||||
if q == 17 then
|
||||
if rpg_t[player.index].dexterity < (get_point+10) then
|
||||
q = 18
|
||||
-- player.print({'amap.nopoint'})
|
||||
-- player.remove_item{name='coin', count = '1000'}
|
||||
else
|
||||
rpg_t[player.index].dexterity = rpg_t[player.index].dexterity - get_point
|
||||
player.print({'amap.nb17',get_point})
|
||||
return
|
||||
end
|
||||
end
|
||||
if q == 18 then
|
||||
if rpg_t[player.index].vitality < (get_point+10) then
|
||||
q = 15
|
||||
-- player.print({'amap.nopoint'})
|
||||
-- player.remove_item{name='coin', count = '1000'}
|
||||
else
|
||||
rpg_t[player.index].vitality = rpg_t[player.index].vitality -get_point
|
||||
player.print({'amap.nb18',get_point})
|
||||
return
|
||||
end
|
||||
end
|
||||
if q == 15 then
|
||||
if rpg_t[player.index].strength < (get_point+10) then
|
||||
local money = 1000+1000*k
|
||||
player.print({'amap.nopoint',money})
|
||||
player.remove_item{name='coin', count = money}
|
||||
return
|
||||
else
|
||||
rpg_t[player.index].strength = rpg_t[player.index].strength -get_point
|
||||
player.print({'amap.nb15',get_point})
|
||||
return
|
||||
end
|
||||
end
|
||||
if q == 14 then
|
||||
local luck = 50*k+50
|
||||
if luck >= 400 then
|
||||
luck = 400
|
||||
end
|
||||
Loot.cool(player.surface, player.surface.find_non_colliding_position("steel-chest", player.position, 20, 1, true) or player.position, 'steel-chest', luck)
|
||||
player.print({'amap.nb14',luck})
|
||||
return
|
||||
elseif q == 13 then
|
||||
local money = 10000+1000*k
|
||||
player.insert{name='coin', count =money}
|
||||
player.print({'amap.nb13',money})
|
||||
return
|
||||
elseif q == 12 then
|
||||
local get_xp = 100+k*50
|
||||
rpg_t[player.index].xp = rpg_t[player.index].xp +get_xp
|
||||
player.print({'amap.nb12',get_xp})
|
||||
return
|
||||
elseif q == 11 then
|
||||
local amount = 10+10*k
|
||||
player.insert{name='distractor-capsule', count = amount}
|
||||
player.print({'amap.nb11',amount})
|
||||
return
|
||||
elseif q == 10 then
|
||||
local amount = 100+100*k
|
||||
player.insert{name='raw-fish', count = amount}
|
||||
player.print({'amap.nb10',amount})
|
||||
return
|
||||
elseif q == 9 then
|
||||
player.insert{name='raw-fish', count = '1'}
|
||||
player.print({'amap.nb9'})
|
||||
return
|
||||
elseif q == 8 then
|
||||
local lost_xp = 2000+k*200
|
||||
if rpg_t[player.index].xp < lost_xp then
|
||||
rpg_t[player.index].xp = 0
|
||||
return
|
||||
else
|
||||
rpg_t[player.index].xp = rpg_t[player.index].xp - lost_xp
|
||||
player.print({'amap.nb8',lost_xp})
|
||||
return
|
||||
end
|
||||
elseif q == 7 then
|
||||
player.print({'amap.nb7'})
|
||||
return
|
||||
elseif q == 6 then
|
||||
rpg_t[player.index].strength = rpg_t[player.index].strength + get_point
|
||||
player.print({'amap.nb6',get_point})
|
||||
return
|
||||
elseif q == 5 then
|
||||
player.print({'amap.nb5',get_point})
|
||||
rpg_t[player.index].magicka =rpg_t[player.index].magicka +get_point
|
||||
return
|
||||
elseif q == 4 then
|
||||
player.print({'amap.nb4',get_point})
|
||||
rpg_t[player.index].dexterity = rpg_t[player.index].dexterity+get_point
|
||||
return
|
||||
elseif q == 3 then
|
||||
player.print({'amap.nb3',get_point})
|
||||
rpg_t[player.index].vitality = rpg_t[player.index].vitality+get_point
|
||||
return
|
||||
elseif q == 2 then
|
||||
player.print({'amap.nb2',get_point})
|
||||
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+get_point
|
||||
return
|
||||
elseif q == 1 then
|
||||
local money = 1000+1000*k
|
||||
player.print({'amap.nbone',money})
|
||||
player.insert{name='coin', count = money}
|
||||
return
|
||||
elseif q == 0 then
|
||||
local money = 1000+1000*k
|
||||
player.print({'amap.sorry',money})
|
||||
player.remove_item{name='coin', count = money}
|
||||
return
|
||||
elseif q == 19 then
|
||||
player.print({'amap.what'})
|
||||
return
|
||||
end
|
||||
end
|
||||
local timereward = function()
|
||||
local game_lost = WPT.get('game_lost')
|
||||
if game_lost then
|
||||
return
|
||||
end
|
||||
local this = WPT.get()
|
||||
local last = this.last
|
||||
local wave_number = WD.get('wave_number')
|
||||
if last < wave_number then
|
||||
if wave_number % 25 == 0 then
|
||||
game.print({'amap.roll'},{r = 0.22, g = 0.88, b = 0.22})
|
||||
--biterbuff()
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
rondom(player,wave_number)
|
||||
k=k+1
|
||||
end
|
||||
this.last = wave_number
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local getrawrad = function()
|
||||
local game_lost = WPT.get('game_lost')
|
||||
if game_lost then
|
||||
return
|
||||
end
|
||||
local this = WPT.get()
|
||||
local wave_number = WD.get('wave_number')
|
||||
if wave_number > this.number then
|
||||
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
rpg_t[player.index].xp = rpg_t[player.index].xp + 10
|
||||
end
|
||||
this.number = wave_number
|
||||
-- game.print({'amap.getxpfromwave'})
|
||||
end
|
||||
end
|
||||
local function calc_players()
|
||||
local players = game.connected_players
|
||||
local check_afk_players = WPT.get('check_afk_players')
|
||||
if not check_afk_players then
|
||||
return #players
|
||||
end
|
||||
local total = 0
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
if player.afk_time < 36000 then
|
||||
total = total + 1
|
||||
end
|
||||
end
|
||||
if total <= 0 then
|
||||
total = 1
|
||||
end
|
||||
return total
|
||||
end
|
||||
local change = function()
|
||||
local this = WPT.get()
|
||||
local roll = this.roll
|
||||
if this.change then
|
||||
this.change = false
|
||||
this.change_dist = false
|
||||
if roll == 1 then
|
||||
if this.pos.x < 0 then
|
||||
this.pos.x = this.pos.x - 75
|
||||
else
|
||||
this.pos.x = this.pos.x + 75
|
||||
end
|
||||
elseif roll == 2 then
|
||||
if this.pos.y < 0 then
|
||||
this.pos.y = this.pos.y - 75
|
||||
else
|
||||
this.pos.y = this.pos.y + 75
|
||||
end
|
||||
elseif roll == 3 then
|
||||
if this.pos.y < 0 then
|
||||
this.pos.y = -this.pos.y + 75
|
||||
else
|
||||
this.pos.y = -this.pos.y - 75
|
||||
end
|
||||
elseif roll == 4 then
|
||||
if this.pos.x < 0 then
|
||||
this.pos.x = -this.pos.x + 75
|
||||
else
|
||||
this.pos.x = -this.pos.x - 75
|
||||
end
|
||||
elseif roll == 5 then
|
||||
if this.pos.x < 0 then
|
||||
this.pos.x = this.pos.x - 75
|
||||
else
|
||||
this.pos.x = this.pos.x + 75
|
||||
end
|
||||
if this.pos.y < 0 then
|
||||
this.pos.y = this.pos.y - 75
|
||||
else
|
||||
this.pos.y = this.pos.y + 75
|
||||
end
|
||||
elseif roll == 6 then
|
||||
if this.pos.y < 0 then
|
||||
this.pos.y = -this.pos.y + 75
|
||||
else
|
||||
this.pos.y = -this.pos.y - 75
|
||||
end
|
||||
|
||||
if this.pos.x < 0 then
|
||||
this.pos.x = -this.pos.x + 75
|
||||
else
|
||||
this.pos.x = -this.pos.x - 75
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
if this.change_dist then
|
||||
this.change_dist = false
|
||||
local k = roll
|
||||
if k == 1 then
|
||||
this.pos.y = -this.pos.y
|
||||
this.pos.x = -this.pos.x
|
||||
elseif k == 2 then
|
||||
this.pos.y = -this.pos.y
|
||||
elseif k == 3 then
|
||||
this.pos.x = -this.pos.x
|
||||
elseif k == 4 then
|
||||
this.pos.y = -this.pos.y
|
||||
elseif k == 5 then
|
||||
this.pos.y = -this.pos.y
|
||||
this.pos.x = -this.pos.x
|
||||
elseif k == 6 then
|
||||
this.pos.x = -this.pos.x
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
local single_rewrad = function()
|
||||
local game_lost = WPT.get('game_lost')
|
||||
if game_lost then
|
||||
return
|
||||
end
|
||||
local wave_number = WD.get('wave_number')
|
||||
if wave_number >= 10 then
|
||||
return
|
||||
end
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
|
||||
local this = WPT.get()
|
||||
local player_count = calc_players()
|
||||
if this.single and player_count <= 2 and not this.first then
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute + 200
|
||||
rpg_t[player.index].xp= rpg_t[player.index].xp+5000
|
||||
player.insert{name='coin', count = 10000}
|
||||
player.insert{name='tank', count = 1}
|
||||
game.print({'amap.single'})
|
||||
this.single = false
|
||||
|
||||
end
|
||||
end
|
||||
this.first = false
|
||||
end
|
||||
|
||||
|
||||
|
||||
local on_tick = function()
|
||||
local tick = game.tick
|
||||
|
||||
if tick % 40 == 0 then
|
||||
-- pos()
|
||||
|
||||
--bigermap()
|
||||
|
||||
|
||||
-- has_the_game_ended()
|
||||
is_player_valid()
|
||||
chunk_load()
|
||||
timereward()
|
||||
getrawrad()
|
||||
-- biterup()
|
||||
end
|
||||
if tick % 500 == 0 then
|
||||
change()
|
||||
end
|
||||
|
||||
if tick % 600 == 0 then
|
||||
local this = WPT.get()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local roll = this.roll
|
||||
wave_defense_table.spawn_position = this.pos
|
||||
if this.roll == 6 then
|
||||
this.roll = 1
|
||||
end
|
||||
this.roll=this.roll+1
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function on_research_finished(Event)
|
||||
local this = WPT.get()
|
||||
this.science=this.science+1
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
local point = math.floor(math.random(1,5))
|
||||
local money = math.floor(math.random(1,100))
|
||||
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+point
|
||||
player.insert{name='coin', count = money}
|
||||
-- player.print({'amap.science',point,money}, {r = 0.22, g = 0.88, b = 0.22})
|
||||
Alert.alert_player(player, 5, {'amap.science',point,money})
|
||||
k=k+1
|
||||
end
|
||||
end
|
||||
|
||||
local on_player_joined_game = function()
|
||||
local player_count = calc_players()
|
||||
if player_count <= 4 then
|
||||
RPG_Settings.points_per_level = 10
|
||||
else
|
||||
RPG_Settings.points_per_level = 5
|
||||
end
|
||||
end
|
||||
|
||||
local on_player_left_game = function()
|
||||
local player_count = calc_players()
|
||||
if player_count <= 4 then
|
||||
RPG_Settings.points_per_level = 10
|
||||
else
|
||||
RPG_Settings.points_per_level = 5
|
||||
end
|
||||
end
|
||||
|
||||
local change_dis = function()
|
||||
local this = WPT.get()
|
||||
this.change_dist=true
|
||||
end
|
||||
Event.add_event_filter(defines.events.on_entity_damaged, {filter = 'final-damage-amount', comparison = '>', value = 0})
|
||||
Event.on_init(on_init)
|
||||
Event.on_nth_tick(10, on_tick)
|
||||
Event.on_nth_tick(7200, single_rewrad)
|
||||
Event.on_nth_tick(60, change_dis)
|
||||
--Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
--Event.add(defines.events.on_pre_player_left_game, on_player_left_game)
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
return Public
|
31
maps/amap/relax.lua
Normal file
31
maps/amap/relax.lua
Normal file
@ -0,0 +1,31 @@
|
||||
local Event = require 'utils.event'
|
||||
local msg = {
|
||||
[1] = {'amap.relax1'},
|
||||
[2] = {'amap.relax2'},
|
||||
[3] = {'amap.relax3'},
|
||||
[4] = {'amap.relax4'},
|
||||
[5] = {'amap.relax5'},
|
||||
[6] = {'amap.relax6'},
|
||||
[7] = {'amap.relax7'},
|
||||
[8] = {'amap.relax8'},
|
||||
[9] = {'amap.relax9'},
|
||||
[10] = {'amap.relax10'},
|
||||
[11] = {'amap.relax11'},
|
||||
[12] = {'amap.relax12'},
|
||||
[13] = {'amap.relax13'},
|
||||
[14] = {'amap.relax14'},
|
||||
[15] = {'amap.relax15'},
|
||||
[16] = {'amap.relax16'},
|
||||
[17] = {'amap.relax17'},
|
||||
[18] = {'amap.relax18'},
|
||||
[19] = {'amap.relax19'},
|
||||
[20] = {'amap.relax20'},
|
||||
|
||||
}
|
||||
|
||||
local on_tick = function()
|
||||
local roll = math.random(1, #msg)
|
||||
game.print(msg[roll],{r = 0.22, g = 0.88, b = 0.22})
|
||||
end
|
||||
|
||||
Event.on_nth_tick(108000, on_tick)
|
270
maps/amap/rock.lua
Normal file
270
maps/amap/rock.lua
Normal file
@ -0,0 +1,270 @@
|
||||
local WPT = require 'maps.amap.table'
|
||||
local Event = require 'utils.event'
|
||||
local Public = {}
|
||||
local Alert = require 'utils.alert'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local RPG = require 'modules.rpg.table'
|
||||
local wave_defense_table = WD.get_table()
|
||||
local Task = require 'utils.task'
|
||||
local Server = require 'utils.server'
|
||||
local wall_health = require 'maps.amap.wall_health_booster'.set_health_modifier
|
||||
local spider_health =require 'maps.amap.spider_health_booster'.set_health_modifier
|
||||
local urgrade_item = function(market)
|
||||
local this = WPT.get()
|
||||
local pirce_wall=this.health*1000 + 10000
|
||||
local pirce_arty=this.arty*1000 +10000
|
||||
local biter_health=this.biter_health*1000 + 7000
|
||||
local spider_health=this.spider_health*1000 + 10000
|
||||
local pirce_biter_dam=this.biter_dam*1000 +7000
|
||||
if pirce_arty >= 50000 then
|
||||
pirce_arty = 50000
|
||||
end
|
||||
|
||||
|
||||
if pirce_wall >= 50000 then
|
||||
pirce_wall = 50000
|
||||
end
|
||||
|
||||
|
||||
if biter_health >= 50000 then
|
||||
biter_health = 50000
|
||||
end
|
||||
if spider_health >= 50000 then
|
||||
spider_health = 50000
|
||||
end
|
||||
if pirce_biter_dam >= 50000 then
|
||||
pirce_biter_dam = 50000
|
||||
end
|
||||
local health_wall = {price = {{"coin", pirce_wall}}, offer = {type = 'nothing', effect_description = {'amap.buy_health_wall'}}}
|
||||
local arty_dam = {price = {{"coin", pirce_arty}}, offer = {type = 'nothing', effect_description = {'amap.buy_arty_dam'}}}
|
||||
local player_biter_health={price = {{"coin", biter_health}}, offer = {type = 'nothing', effect_description = {'amap.player_biter_health'}}}
|
||||
local spider_buy={price = {{"coin", spider_health}}, offer = {type = 'nothing', effect_description = {'amap.player_spider_health'}}}
|
||||
local biter_dam={price = {{"coin", pirce_biter_dam}}, offer = {type = 'nothing', effect_description = {'amap.player_biter_dam'}}}
|
||||
local buy_cap={price = {{"coin", 50000}}, offer = {type = 'nothing', effect_description = {'amap.buy_cap'}}}
|
||||
market.add_market_item(health_wall)
|
||||
market.add_market_item(arty_dam)
|
||||
market.add_market_item(player_biter_health)
|
||||
market.add_market_item(spider_buy)
|
||||
market.add_market_item(biter_dam)
|
||||
market.add_market_item(buy_cap)
|
||||
end
|
||||
|
||||
local market_items = {
|
||||
|
||||
{price = {{"coin", 5}}, offer = {type = 'give-item', item = "raw-fish", count = 1}},
|
||||
{price = {{"coin", 2000}}, offer = {type = 'give-item', item = 'car', count = 1}},
|
||||
{price = {{"coin", 15000}}, offer = {type = 'give-item', item = 'tank', count = 1}},
|
||||
{price = {{"coin", 60000}}, offer = {type = 'give-item', item = 'spidertron', count = 1}},
|
||||
{price = {{"coin", 500}}, offer = {type = 'give-item', item = 'spidertron-remote', count = 1}},
|
||||
--{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'locomotive', count = 1}},
|
||||
--{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'cargo-wagon', count = 1}},
|
||||
--{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'fluid-wagon', count = 1}}
|
||||
{price = {{"coin", 25000}}, offer = {type = 'give-item', item = 'tank-cannon', count = 1}},
|
||||
{price = {{"coin", 128}}, offer = {type = 'give-item', item = 'loader', count = 1}},
|
||||
{price = {{"coin", 512}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
|
||||
{price = {{"coin", 4096}}, offer = {type = 'give-item', item = 'express-loader', count = 1}},
|
||||
{price = {{"raw-fish", 1}}, offer = {type = 'give-item', item = 'coin', count = 5}},
|
||||
{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'flamethrower-turret', count = 1}},
|
||||
|
||||
}
|
||||
|
||||
function Public.spawn(surface, position)
|
||||
local this = WPT.get()
|
||||
this.rock = surface.create_entity{name = "rocket-silo", position = position, force=game.forces.player}
|
||||
|
||||
this.rock.minable = false
|
||||
game.forces.player.set_spawn_position({0,0}, surface)
|
||||
end
|
||||
|
||||
function Public.market(surface)
|
||||
local this = WPT.get()
|
||||
local market = surface.create_entity{name = "market", position = {x=0, y=-10}, force=game.forces.player}
|
||||
|
||||
market.last_user = nil
|
||||
if market ~= nil then
|
||||
market.destructible = false
|
||||
if market ~= nil then
|
||||
game.print(1)
|
||||
urgrade_item(market)
|
||||
for _, item in pairs(market_items) do
|
||||
market.add_market_item(item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function on_rocket_launched(Event)
|
||||
local this = WPT.get()
|
||||
--game.print({'amap.times',this.times})
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
--local money = 1000 + this.times*1000
|
||||
local money = 10000
|
||||
local point = 1
|
||||
-- if money >= 50000 then
|
||||
-- money = 50000
|
||||
-- end
|
||||
-- if point >= 100 then
|
||||
-- point = 100
|
||||
-- end
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
|
||||
rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+point
|
||||
player.insert{name='coin', count = money}
|
||||
player.print({'amap.reward',this.times,point,money}, {r = 0.22, g = 0.88, b = 0.22})
|
||||
|
||||
end
|
||||
if not this.pass then
|
||||
local wave_number = WD.get('wave_number')
|
||||
local msg = {'amap.pass',wave_number}
|
||||
for k, p in pairs(game.connected_players) do
|
||||
local player = game.connected_players[k]
|
||||
Alert.alert_player(player, 25, msg)
|
||||
end
|
||||
Server.to_discord_embed(table.concat({'** we win the game ! Record is ', wave_number}))
|
||||
this.pass = true
|
||||
end
|
||||
this.times=this.times+1
|
||||
end
|
||||
|
||||
local function on_entity_died(Event)
|
||||
local this = WPT.get()
|
||||
if Event.entity == this.rock then
|
||||
for _, player in pairs(game.connected_players) do
|
||||
player.play_sound {path = 'utility/game_lost', volume_modifier = 0.75}
|
||||
end
|
||||
--game.print({'amap.lost',wave_number}),{r = 1, g = 0, b = 0, a = 0.5})
|
||||
local wave_number = WD.get('wave_number')
|
||||
local msg = {'amap.lost',wave_number}
|
||||
for _, p in pairs(game.connected_players) do
|
||||
|
||||
Alert.alert_player(p, 25, msg)
|
||||
|
||||
end
|
||||
Server.to_discord_embed(table.concat({'** we lost the game ! Record is ', wave_number}))
|
||||
local Reset_map = require 'maps.amap.main'.reset_map
|
||||
wave_defense_table.game_lost = true
|
||||
wave_defense_table.target = nil
|
||||
-- game.forces.enemy.set_friend('player', true)
|
||||
--game.print('设置右军友好')
|
||||
-- game.forces.player.set_friend('enemy', true)
|
||||
--game.print('设置敌军友好')
|
||||
--local game_reset_tick = WPT.get('game_reset_tick')
|
||||
-- game.print('GG,游戏结束,稍后自动重启',{r = 0.99, g = 0.00, b = 0.22})
|
||||
-- this.game_reset_tick = 5400
|
||||
|
||||
Reset_map()
|
||||
|
||||
--abc()
|
||||
end
|
||||
end
|
||||
|
||||
local function on_market_item_purchased(event)
|
||||
local player = game.players[event.player_index]
|
||||
local market = event.market
|
||||
local offer_index = event.offer_index
|
||||
local count = event.count
|
||||
local offers = market.get_market_items()
|
||||
local bought_offer = offers[offer_index].offer
|
||||
local this = WPT.get()
|
||||
local index = game.forces.player.index
|
||||
if bought_offer.type ~= "nothing" then return end
|
||||
|
||||
if offer_index == 1 then
|
||||
local wave_number = WD.get('wave_number')
|
||||
local times = math.floor(wave_number/100)+this.cap
|
||||
if this.health >= times then
|
||||
player.print({'amap.cap_upgrad'})
|
||||
local pirce_wall=this.health*1000 + 10000
|
||||
if pirce_wall >= 50000 then
|
||||
pirce_wall = 50000
|
||||
end
|
||||
player.insert{name='coin',count = pirce_wall}
|
||||
return
|
||||
end
|
||||
this.health=this.health+1
|
||||
wall_health(index,this.health*0.1+1.1)
|
||||
game.print({'amap.buy_wall_over',player.name,this.health*0.1+1})
|
||||
|
||||
end
|
||||
|
||||
if offer_index == 2 then
|
||||
|
||||
this.arty=this.arty+1
|
||||
game.forces.player.set_ammo_damage_modifier("artillery-shell", this.arty*0.1)
|
||||
game.print({'amap.buy_arty_over',player.name,this.arty*0.1+1})
|
||||
end
|
||||
if offer_index == 3 then
|
||||
local wave_number = WD.get('wave_number')
|
||||
local times = math.floor(wave_number/50)+this.cap
|
||||
if this.biter_health >= times then
|
||||
player.print({'amap.cap_upgrad'})
|
||||
local pirce_biter_dam=this.biter_health*1000 +7000
|
||||
if pirce_biter_dam >= 50000 then
|
||||
pirce_biter_dam = 50000
|
||||
end
|
||||
player.insert{name='coin',count = pirce_biter_dam}
|
||||
return
|
||||
end
|
||||
this.biter_health=this.biter_health+1
|
||||
global.biter_health_boost_forces[game.forces.player.index] = this.biter_health*0.1+1
|
||||
game.print({'amap.buy_player_biter_over',player.name,this.biter_health*0.1+1})
|
||||
end
|
||||
if offer_index == 4 then
|
||||
|
||||
local wave_number = WD.get('wave_number')
|
||||
local times = math.floor(wave_number/100)+this.cap
|
||||
if this.spider_health >= times then
|
||||
player.print({'amap.cap_upgrad'})
|
||||
local spider_health=this.spider_health*1000 + 10000
|
||||
if spider_health >= 50000 then
|
||||
spider_health = 50000
|
||||
end
|
||||
player.insert{name='coin',count = spider_health}
|
||||
return
|
||||
end
|
||||
this.spider_health=this.spider_health+1
|
||||
spider_health(index,this.spider_health*0.1+1.1)
|
||||
game.print({'amap.buy_spider_health_over',player.name,this.spider_health*0.1+1})
|
||||
end
|
||||
if offer_index == 5 then
|
||||
local wave_number = WD.get('wave_number')
|
||||
local times = math.floor(wave_number/100)+this.cap+1
|
||||
if times >= 30 then
|
||||
times = 30
|
||||
end
|
||||
if this.biter_dam >= times then
|
||||
player.print({'amap.cap_upgrad'})
|
||||
local pirce_biter_dam=this.biter_dam*1000 +7000
|
||||
if pirce_biter_dam >= 50000 then
|
||||
pirce_biter_dam = 50000
|
||||
end
|
||||
player.insert{name='coin',count = pirce_biter_dam}
|
||||
return
|
||||
end
|
||||
this.biter_dam=this.biter_dam+1
|
||||
local damage_increase = this.biter_dam*0.1
|
||||
game.forces.player.set_ammo_damage_modifier("melee", damage_increase)
|
||||
game.forces.player.set_ammo_damage_modifier("biological", damage_increase)
|
||||
game.print({'amap.buy_biter_dam',player.name,this.biter_dam*0.1+1})
|
||||
end
|
||||
|
||||
if offer_index == 6 then
|
||||
|
||||
this.cap=this.cap+1
|
||||
game.print({'amap.buy_cap_over',player.name,this.cap})
|
||||
end
|
||||
market.force.play_sound({path = 'utility/new_objective', volume_modifier = 0.75})
|
||||
market.clear_market_items()
|
||||
urgrade_item(market)
|
||||
for k, item in pairs(market_items) do
|
||||
market.add_market_item(item)
|
||||
end
|
||||
|
||||
end
|
||||
Event.add(defines.events.on_rocket_launched, on_rocket_launched)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_market_item_purchased,on_market_item_purchased)
|
||||
return Public
|
177
maps/amap/rocks_yield_ore.lua
Normal file
177
maps/amap/rocks_yield_ore.lua
Normal file
@ -0,0 +1,177 @@
|
||||
--destroying and mining rocks yields ore -- load as last module
|
||||
local max_spill = 60
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local math_sqrt = math.sqrt
|
||||
|
||||
local rock_yield = {
|
||||
["rock-big"] = 1,
|
||||
["rock-huge"] = 2,
|
||||
["sand-rock-big"] = 1
|
||||
}
|
||||
|
||||
local particles = {
|
||||
["iron-ore"] = "iron-ore-particle",
|
||||
["copper-ore"] = "copper-ore-particle",
|
||||
["uranium-ore"] = "coal-particle",
|
||||
["coal"] = "coal-particle",
|
||||
["stone"] = "stone-particle",
|
||||
["angels-ore1"] = "iron-ore-particle",
|
||||
["angels-ore2"] = "copper-ore-particle",
|
||||
["angels-ore3"] = "coal-particle",
|
||||
["angels-ore4"] = "iron-ore-particle",
|
||||
["angels-ore5"] = "iron-ore-particle",
|
||||
["angels-ore6"] = "iron-ore-particle",
|
||||
}
|
||||
|
||||
local function get_chances()
|
||||
local chances = {}
|
||||
|
||||
if game.entity_prototypes["angels-ore1"] then
|
||||
for i = 1, 6, 1 do
|
||||
table.insert(chances, {"angels-ore" .. i, 1})
|
||||
end
|
||||
table.insert(chances, {"coal", 2})
|
||||
return chances
|
||||
end
|
||||
|
||||
table.insert(chances, {"iron-ore", 25})
|
||||
table.insert(chances, {"copper-ore",17})
|
||||
table.insert(chances, {"coal",13})
|
||||
table.insert(chances, {"uranium-ore",2})
|
||||
table.insert(chances, {"stone",7})
|
||||
return chances
|
||||
end
|
||||
|
||||
local function set_raffle()
|
||||
global.rocks_yield_ore["raffle"] = {}
|
||||
for _, t in pairs(get_chances()) do
|
||||
for x = 1, t[2], 1 do
|
||||
table.insert(global.rocks_yield_ore["raffle"], t[1])
|
||||
end
|
||||
end
|
||||
global.rocks_yield_ore["size_of_raffle"] = #global.rocks_yield_ore["raffle"]
|
||||
end
|
||||
|
||||
local function create_particles(surface, name, position, amount, cause_position)
|
||||
local direction_mod = (-100 + math_random(0,200)) * 0.0004
|
||||
local direction_mod_2 = (-100 + math_random(0,200)) * 0.0004
|
||||
|
||||
if cause_position then
|
||||
direction_mod = (cause_position.x - position.x) * 0.025
|
||||
direction_mod_2 = (cause_position.y - position.y) * 0.025
|
||||
end
|
||||
|
||||
for i = 1, amount, 1 do
|
||||
local m = math_random(4, 10)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle({
|
||||
name = name,
|
||||
position = position,
|
||||
frame_speed = 1,
|
||||
vertical_speed = 0.130,
|
||||
height = 0,
|
||||
movement = {
|
||||
(m2 - (math_random(0, m) * 0.01)) + direction_mod,
|
||||
(m2 - (math_random(0, m) * 0.01)) + direction_mod_2
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function get_amount(entity)
|
||||
local distance_to_center = math_floor(math_sqrt(entity.position.x ^ 2 + entity.position.y ^ 2))
|
||||
|
||||
local amount = global.rocks_yield_ore_base_amount + (distance_to_center * global.rocks_yield_ore_distance_modifier)
|
||||
if amount > global.rocks_yield_ore_maximum_amount then amount = global.rocks_yield_ore_maximum_amount end
|
||||
|
||||
local m = (70 + math_random(0, 60)) * 0.01
|
||||
|
||||
amount = math_floor(amount * rock_yield[entity.name] * m)
|
||||
if amount < 1 then amount = 1 end
|
||||
|
||||
return amount
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if not rock_yield[entity.name] then return end
|
||||
local player = game.players[event.player_index]
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
event.buffer.clear()
|
||||
|
||||
local ore = global.rocks_yield_ore["raffle"][math_random(1, global.rocks_yield_ore["size_of_raffle"])]
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
local count = get_amount(entity)
|
||||
count = math_floor(count * (1 + player.force.mining_drill_productivity_bonus))
|
||||
|
||||
global.rocks_yield_ore["ores_mined"] = global.rocks_yield_ore["ores_mined"] + count
|
||||
global.rocks_yield_ore["rocks_broken"] = global.rocks_yield_ore["rocks_broken"] + 1
|
||||
|
||||
local position = {x = entity.position.x, y = entity.position.y}
|
||||
|
||||
local ore_amount = math_floor(count * 0.85) + 1
|
||||
local stone_amount = math_floor(count * 0.15) + 1
|
||||
|
||||
player.surface.create_entity({name = "flying-text", position = position, text = "+" .. ore_amount .. " [img=item/" .. ore .. "]", color = {r = 200, g = 160, b = 30}})
|
||||
create_particles(player.surface, particles[ore], position, 64, {x = player.position.x, y = player.position.y})
|
||||
|
||||
entity.destroy()
|
||||
|
||||
if ore_amount > max_spill then
|
||||
local k = player.insert({name = ore, count = ore_amount})
|
||||
ore_amount = ore_amount - k
|
||||
if ore_amount > 0 then
|
||||
-- player.surface.spill_item_stack(position,{name = ore, count = ore_amount}, true)
|
||||
player.character.health = player.character.health - player.character.health*0.2 - 100
|
||||
player.print({'amap.bag_isfull'},{r = 200, g = 0, b = 30})
|
||||
end
|
||||
else
|
||||
player.surface.spill_item_stack(position,{name = ore, count = ore_amount}, true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if not rock_yield[entity.name] then return end
|
||||
|
||||
local surface = entity.surface
|
||||
local ore = global.rocks_yield_ore["raffle"][math_random(1, global.rocks_yield_ore["size_of_raffle"])]
|
||||
local pos = {entity.position.x, entity.position.y}
|
||||
create_particles(surface, particles[ore], pos, 16, false)
|
||||
|
||||
if event.cause then
|
||||
if event.cause.valid then
|
||||
if event.cause.force.index == 2 or event.cause.force.index == 3 then
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
global.rocks_yield_ore = {}
|
||||
global.rocks_yield_ore["rocks_broken"] = 0
|
||||
global.rocks_yield_ore["ores_mined"] = 0
|
||||
set_raffle()
|
||||
|
||||
if not global.rocks_yield_ore_distance_modifier then global.rocks_yield_ore_distance_modifier = 0.25 end
|
||||
if not global.rocks_yield_ore_base_amount then global.rocks_yield_ore_base_amount = 35 end
|
||||
if not global.rocks_yield_ore_maximum_amount then global.rocks_yield_ore_maximum_amount = 150 end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
114
maps/amap/soft_reset.lua
Normal file
114
maps/amap/soft_reset.lua
Normal file
@ -0,0 +1,114 @@
|
||||
local Server = require 'utils.server'
|
||||
local Session = require 'utils.datastore.session_data'
|
||||
local Modifers = require 'player_modifiers'
|
||||
local WPT = require 'maps.amap.table'
|
||||
|
||||
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
|
||||
|
||||
local Public = {}
|
||||
|
||||
local function reset_forces(new_surface, old_surface)
|
||||
for _, f in pairs(game.forces) do
|
||||
local spawn = {
|
||||
x = game.forces.player.get_spawn_position(old_surface).x,
|
||||
y = game.forces.player.get_spawn_position(old_surface).y
|
||||
}
|
||||
f.reset()
|
||||
f.reset_evolution()
|
||||
f.set_spawn_position(spawn, new_surface)
|
||||
end
|
||||
for _, tech in pairs(game.forces.player.technologies) do
|
||||
tech.researched = false
|
||||
game.forces.player.set_saved_technology_progress(tech, 0)
|
||||
end
|
||||
end
|
||||
|
||||
local function teleport_players(surface)
|
||||
game.forces.player.set_spawn_position({-27, 25}, surface)
|
||||
|
||||
for _, player in pairs(game.connected_players) do
|
||||
player.teleport(
|
||||
surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5),
|
||||
surface
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function equip_players(player_starting_items, data)
|
||||
for k, player in pairs(game.players) do
|
||||
if player.character and player.character.valid then
|
||||
player.character.destroy()
|
||||
end
|
||||
if player.connected then
|
||||
if not player.character then
|
||||
player.set_controller({type = defines.controllers.god})
|
||||
player.create_character()
|
||||
end
|
||||
player.clear_items_inside()
|
||||
Modifers.update_player_modifiers(player)
|
||||
for item, amount in pairs(player_starting_items) do
|
||||
player.insert({name = item, count = amount})
|
||||
end
|
||||
else
|
||||
data.players[player.index] = nil
|
||||
Session.clear_player(player)
|
||||
game.remove_offline_players({player.index})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.soft_reset_map(old_surface, map_gen_settings, player_starting_items)
|
||||
local this = WPT.get()
|
||||
|
||||
if not this.soft_reset_counter then
|
||||
this.soft_reset_counter = 0
|
||||
end
|
||||
if not this.original_surface_name then
|
||||
this.original_surface_name = old_surface.name
|
||||
end
|
||||
this.soft_reset_counter = this.soft_reset_counter + 1
|
||||
|
||||
local new_surface =
|
||||
game.create_surface(this.original_surface_name .. '_' .. tostring(this.soft_reset_counter), map_gen_settings)
|
||||
new_surface.request_to_generate_chunks({0, 0}, 0.5)
|
||||
new_surface.force_generate_chunk_requests()
|
||||
|
||||
reset_forces(new_surface, old_surface)
|
||||
teleport_players(new_surface)
|
||||
equip_players(player_starting_items, this)
|
||||
|
||||
game.delete_surface(old_surface)
|
||||
|
||||
local radius = 512
|
||||
local area = {{x = -radius, y = -radius}, {x = radius, y = radius}}
|
||||
for _, entity in pairs(new_surface.find_entities_filtered {area = area, type = 'logistic-robot'}) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
for _, entity in pairs(new_surface.find_entities_filtered {area = area, type = 'construction-robot'}) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local message = table.concat({mapkeeper .. ' Welcome to ', this.original_surface_name, '!'})
|
||||
local message_to_discord = table.concat({'** Welcome to ', this.original_surface_name, '! **'})
|
||||
|
||||
if this.soft_reset_counter > 1 then
|
||||
message =
|
||||
table.concat(
|
||||
{
|
||||
mapkeeper,
|
||||
' The world has been reshaped, welcome to ',
|
||||
this.original_surface_name,
|
||||
' number ',
|
||||
tostring(this.soft_reset_counter),
|
||||
'!'
|
||||
}
|
||||
)
|
||||
end
|
||||
game.print(message, {r = 0.98, g = 0.66, b = 0.22})
|
||||
Server.to_discord_embed(message_to_discord)
|
||||
|
||||
return new_surface
|
||||
end
|
||||
|
||||
return Public
|
482
maps/amap/sort.lua
Normal file
482
maps/amap/sort.lua
Normal file
@ -0,0 +1,482 @@
|
||||
--this adds a button that stashes/sorts your inventory into nearby chests in some kind of intelligent way - mewmew
|
||||
-- modified by gerkiz
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local math_floor = math.floor
|
||||
local print_color = {r = 120, g = 255, b = 0}
|
||||
|
||||
local autostash = {
|
||||
floating_text_y_offsets = {},
|
||||
whitelist = {},
|
||||
insert_into_wagon = false
|
||||
}
|
||||
|
||||
local Public = {}
|
||||
|
||||
Global.register(
|
||||
autostash,
|
||||
function(t)
|
||||
autostash = t
|
||||
end
|
||||
)
|
||||
|
||||
local function create_floaty_text(surface, position, name, count)
|
||||
if autostash.floating_text_y_offsets[position.x .. '_' .. position.y] then
|
||||
autostash.floating_text_y_offsets[position.x .. '_' .. position.y] =
|
||||
autostash.floating_text_y_offsets[position.x .. '_' .. position.y] - 0.5
|
||||
else
|
||||
autostash.floating_text_y_offsets[position.x .. '_' .. position.y] = 0
|
||||
end
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = {
|
||||
position.x,
|
||||
position.y + autostash.floating_text_y_offsets[position.x .. '_' .. position.y]
|
||||
},
|
||||
text = {'', '-', count, ' ', game.item_prototypes[name].localised_name},
|
||||
color = {r = 255, g = 255, b = 255}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local function chest_is_valid(chest)
|
||||
if chest.type == 'cargo-wagon' then
|
||||
local t = {}
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.cargo_wagon)
|
||||
for index = 1, 40 do
|
||||
if chest_inventory.get_filter(index) ~= nil then
|
||||
local n = chest_inventory.get_filter(index)
|
||||
t[n] = true
|
||||
end
|
||||
end
|
||||
|
||||
if not next(t) then
|
||||
return false, {}
|
||||
end
|
||||
|
||||
return true, t
|
||||
end
|
||||
|
||||
for _, e in pairs(
|
||||
chest.surface.find_entities_filtered(
|
||||
{
|
||||
type = {'inserter', 'loader'},
|
||||
area = {{chest.position.x - 1, chest.position.y - 1}, {chest.position.x + 1, chest.position.y + 1}}
|
||||
}
|
||||
)
|
||||
) do
|
||||
if e.name ~= 'long-handed-inserter' then
|
||||
if e.position.x == chest.position.x then
|
||||
if e.direction == 0 or e.direction == 4 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
if e.position.y == chest.position.y then
|
||||
if e.direction == 2 or e.direction == 6 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local i1 = chest.surface.find_entity('long-handed-inserter', {chest.position.x - 2, chest.position.y})
|
||||
if i1 then
|
||||
if i1.direction == 2 or i1.direction == 6 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
local i2 = chest.surface.find_entity('long-handed-inserter', {chest.position.x + 2, chest.position.y})
|
||||
if i2 then
|
||||
if i2.direction == 2 or i2.direction == 6 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local i3 = chest.surface.find_entity('long-handed-inserter', {chest.position.x, chest.position.y - 2})
|
||||
if i3 then
|
||||
if i3.direction == 0 or i3.direction == 4 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
local i4 = chest.surface.find_entity('long-handed-inserter', {chest.position.x, chest.position.y + 2})
|
||||
if i4 then
|
||||
if i4.direction == 0 or i4.direction == 4 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function sort_entities_by_distance(position, entities)
|
||||
local t = {}
|
||||
local distance
|
||||
local index
|
||||
local size_of_entities = #entities
|
||||
if size_of_entities < 2 then
|
||||
return
|
||||
end
|
||||
|
||||
for _, entity in pairs(entities) do
|
||||
distance = (entity.position.x - position.x) ^ 2 + (entity.position.y - position.y) ^ 2
|
||||
index = math_floor(distance) + 1
|
||||
if not t[index] then
|
||||
t[index] = {}
|
||||
end
|
||||
table.insert(t[index], entity)
|
||||
end
|
||||
|
||||
local i = 0
|
||||
for _, range in pairs(t) do
|
||||
for _, entity in pairs(range) do
|
||||
i = i + 1
|
||||
entities[i] = entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_nearby_chests(player, a)
|
||||
local r = player.force.character_reach_distance_bonus + 10
|
||||
local r_square = r * r
|
||||
local chests = {}
|
||||
local size_of_chests = 0
|
||||
local area = {{player.position.x - r, player.position.y - r}, {player.position.x + r, player.position.y + r}}
|
||||
|
||||
area = a or area
|
||||
|
||||
local container_type = {'container', 'logistic-container', 'furnace'}
|
||||
local containers = {}
|
||||
local i = 0
|
||||
|
||||
if autostash.insert_into_wagon then
|
||||
table.insert(container_type, 'cargo-wagon')
|
||||
end
|
||||
|
||||
for _, e in pairs(player.surface.find_entities_filtered({type = container_type, area = area, force = 'player'})) do
|
||||
if ((player.position.x - e.position.x) ^ 2 + (player.position.y - e.position.y) ^ 2) <= r_square then
|
||||
i = i + 1
|
||||
containers[i] = e
|
||||
end
|
||||
end
|
||||
sort_entities_by_distance(player.position, containers)
|
||||
for _, entity in pairs(containers) do
|
||||
size_of_chests = size_of_chests + 1
|
||||
chests[size_of_chests] = entity
|
||||
end
|
||||
|
||||
return chests
|
||||
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_item_into_chest(player_inventory, chests, filtered_chests, name, count, wagon)
|
||||
local container = {
|
||||
['container'] = true,
|
||||
['logistic-container'] = true
|
||||
}
|
||||
|
||||
local to_insert = math.floor(count / #chests)
|
||||
local variator = count % #chests
|
||||
|
||||
if wagon then
|
||||
-- Attempt to load filtered cargo wagon
|
||||
for _, chest in pairs(chests) do
|
||||
if chest.type == 'cargo-wagon' then
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.cargo_wagon)
|
||||
if chest_inventory.can_insert({name = name, count = count}) then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = count})
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
count = count - inserted_count
|
||||
if count <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Attempt to store into furnaces.
|
||||
for _, chest in pairs(chests) do
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.furnace_source)
|
||||
if chest_inventory and chest.type == 'furnace' then
|
||||
if chest_inventory.can_insert({name = name, count = count}) then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = count})
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
count = count - inserted_count
|
||||
if count <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, chest in pairs(chests) do
|
||||
if chest.type == 'furnace' then
|
||||
local amount = to_insert
|
||||
if variator > 0 then
|
||||
amount = amount + 1
|
||||
variator = variator - 1
|
||||
end
|
||||
if amount <= 0 then
|
||||
return
|
||||
end
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.chest)
|
||||
if chest_inventory.can_insert({name = name, count = amount}) then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = amount})
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Attempt to store in chests that already have the same item.
|
||||
for _, chest in pairs(chests) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.chest)
|
||||
if chest_inventory.can_insert({name = name, count = count}) then
|
||||
if chest_inventory.find_item_stack(name) then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = count})
|
||||
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
count = count - inserted_count
|
||||
if count <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Attempt to store in empty chests.
|
||||
for _, chest in pairs(filtered_chests) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.chest)
|
||||
if chest_inventory.can_insert({name = name, count = count}) then
|
||||
if chest_inventory.is_empty() then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = count})
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
count = count - inserted_count
|
||||
if count <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Attempt to store in chests with same item subgroup.
|
||||
local item_subgroup = game.item_prototypes[name].subgroup.name
|
||||
if item_subgroup then
|
||||
for _, chest in pairs(filtered_chests) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.chest)
|
||||
if chest_inventory.can_insert({name = name, count = count}) then
|
||||
if does_inventory_contain_item_type(chest_inventory, item_subgroup) then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = count})
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
count = count - inserted_count
|
||||
if count <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Attempt to store in mixed chests.
|
||||
for _, chest in pairs(filtered_chests) do
|
||||
if container[chest.type] then
|
||||
local chest_inventory = chest.get_inventory(defines.inventory.chest)
|
||||
if chest_inventory.can_insert({name = name, count = count}) then
|
||||
local inserted_count = chest_inventory.insert({name = name, count = count})
|
||||
player_inventory.remove({name = name, count = inserted_count})
|
||||
create_floaty_text(chest.surface, chest.position, name, inserted_count)
|
||||
count = count - inserted_count
|
||||
if count <= 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function auto_stash(player, event)
|
||||
local button = event.button
|
||||
local shift = event.shift
|
||||
if not player.character then
|
||||
player.print('It seems that you are not in the realm of the living.', print_color)
|
||||
return
|
||||
end
|
||||
if not player.character.valid then
|
||||
player.print('It seems that you are not in the realm of the living.', print_color)
|
||||
return
|
||||
end
|
||||
local inventory = player.get_inventory(defines.inventory.character_main)
|
||||
if inventory.is_empty() then
|
||||
player.print('Inventory is empty.', print_color)
|
||||
return
|
||||
end
|
||||
local chests
|
||||
local r = 1
|
||||
local area = {{player.position.x - r, player.position.y - r}, {player.position.x + r, player.position.y + r}}
|
||||
if shift then
|
||||
if
|
||||
button == defines.mouse_button_type.right or
|
||||
button == defines.mouse_button_type.left and autostash.insert_into_wagon
|
||||
then
|
||||
chests = get_nearby_chests(player, area)
|
||||
end
|
||||
else
|
||||
chests = get_nearby_chests(player)
|
||||
end
|
||||
|
||||
if not chests[1] then
|
||||
player.print('No valid nearby containers found.', print_color)
|
||||
return
|
||||
end
|
||||
|
||||
local filtered_chests = {}
|
||||
local filtered_allowed
|
||||
for _, e in pairs(chests) do
|
||||
local is_valid, t = chest_is_valid(e)
|
||||
filtered_allowed = t
|
||||
if is_valid then
|
||||
filtered_chests[#filtered_chests + 1] = e
|
||||
end
|
||||
end
|
||||
|
||||
autostash.floating_text_y_offsets = {}
|
||||
|
||||
local hotbar_items = {}
|
||||
for i = 1, 100, 1 do
|
||||
local prototype = player.get_quick_bar_slot(i)
|
||||
if prototype then
|
||||
hotbar_items[prototype.name] = true
|
||||
end
|
||||
end
|
||||
|
||||
for name, count in pairs(inventory.get_contents()) do
|
||||
local is_resource = autostash.whitelist[name]
|
||||
|
||||
if not inventory.find_item_stack(name).grid and not hotbar_items[name] then
|
||||
if shift and autostash.insert_into_wagon then
|
||||
if button == defines.mouse_button_type.left then
|
||||
if is_resource then
|
||||
insert_item_into_chest(inventory, chests, filtered_chests, name, count, true)
|
||||
end
|
||||
end
|
||||
if button == defines.mouse_button_type.right then
|
||||
if filtered_allowed and is_resource and filtered_allowed[name] then
|
||||
insert_item_into_chest(inventory, chests, filtered_chests, name, count, true)
|
||||
end
|
||||
end
|
||||
elseif button == defines.mouse_button_type.right then
|
||||
if is_resource then
|
||||
insert_item_into_chest(inventory, chests, filtered_chests, name, count)
|
||||
end
|
||||
elseif button == defines.mouse_button_type.left then
|
||||
insert_item_into_chest(inventory, chests, filtered_chests, name, count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local c = autostash.floating_text_y_offsets
|
||||
for k, _ in pairs(c) do
|
||||
autostash.floating_text_y_offsets[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function create_gui_button(player)
|
||||
if player.gui.top.auto_stash then
|
||||
return
|
||||
end
|
||||
local tooltip
|
||||
if autostash.insert_into_wagon then
|
||||
tooltip =
|
||||
'Sort your inventory into nearby chests.\nLMB: Everything, excluding quickbar items.\nRMB: Only ores.\nSHIFT+LMB: Only ores to wagon\nSHIFT+RMB: Only ores onto filtered slots to wagon.'
|
||||
else
|
||||
tooltip = 'Sort your inventory into nearby chests.\nLMB: Everything, excluding quickbar items.\nRMB: Only ores.'
|
||||
end
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/wooden-chest',
|
||||
name = 'auto_stash',
|
||||
tooltip = tooltip
|
||||
}
|
||||
)
|
||||
b.style.font_color = {r = 0.11, g = 0.8, b = 0.44}
|
||||
b.style.font = 'heading-1'
|
||||
b.style.minimal_height = 38
|
||||
b.style.minimal_width = 38
|
||||
b.style.maximal_height = 38
|
||||
b.style.maximal_width = 38
|
||||
b.style.padding = 1
|
||||
b.style.margin = 0
|
||||
end
|
||||
|
||||
local function do_whitelist()
|
||||
local resources = game.entity_prototypes
|
||||
autostash.whitelist = {}
|
||||
for k, _ in pairs(resources) do
|
||||
if resources[k] and resources[k].type == 'resource' and resources[k].mineable_properties then
|
||||
if resources[k].mineable_properties.products[1] then
|
||||
local r = resources[k].mineable_properties.products[1].name
|
||||
autostash.whitelist[r] = true
|
||||
elseif resources[k].mineable_properties.products[2] then
|
||||
local r = resources[k].mineable_properties.products[2].name
|
||||
autostash.whitelist[r] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
if event.element.name == 'auto_stash' then
|
||||
auto_stash(game.players[event.player_index], event)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.insert_into_wagon(value)
|
||||
if value then
|
||||
autostash.insert_into_wagon = value or false
|
||||
end
|
||||
end
|
||||
|
||||
Event.on_configuration_changed = function()
|
||||
do_whitelist()
|
||||
log('[Autostash] on_configuration_changed was called, rebuilding resource whitelist.')
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
return Public
|
99
maps/amap/spider_health_booster.lua
Normal file
99
maps/amap/spider_health_booster.lua
Normal file
@ -0,0 +1,99 @@
|
||||
-- All entities that own a unit_number of a chosen force gain damage resistance.
|
||||
-- ignores entity health regeneration
|
||||
|
||||
-- Use Public.set_health_modifier(force_index, modifier) to modify health.
|
||||
-- 1 = original health, 2 = 200% total health, 4 = 400% total health,..
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Public = {}
|
||||
|
||||
local math_round = math.round
|
||||
|
||||
local fhb = {}
|
||||
Global.register(
|
||||
fhb,
|
||||
function(tbl)
|
||||
fhb = tbl
|
||||
end
|
||||
)
|
||||
|
||||
function Public.set_health_modifier(force_index, modifier)
|
||||
if not game.forces[force_index] then return end
|
||||
if not modifier then return end
|
||||
if not fhb[force_index] then fhb[force_index] = {} end
|
||||
fhb[force_index].m = math_round(1 / modifier, 4)
|
||||
end
|
||||
|
||||
function Public.reset_tables()
|
||||
for k, v in pairs(fhb) do fhb[k] = nil end
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
|
||||
if not entity then return end
|
||||
if not entity.valid then return end
|
||||
|
||||
if not (entity.name == 'spidertron') then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
if not unit_number then return end
|
||||
|
||||
local boost = fhb[entity.force.index]
|
||||
if not boost then return end
|
||||
if not boost[unit_number] then boost[unit_number] = entity.prototype.max_health end
|
||||
|
||||
local new_health = boost[unit_number] - event.final_damage_amount * boost.m
|
||||
boost[unit_number] = new_health
|
||||
entity.health = new_health
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity then return end
|
||||
if not entity.valid then return end
|
||||
|
||||
if not (entity.name == 'spidertron') then
|
||||
return
|
||||
end
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
if not unit_number then return end
|
||||
local boost = fhb[entity.force.index]
|
||||
if not boost then return end
|
||||
boost[unit_number] = nil
|
||||
|
||||
end
|
||||
|
||||
local function on_player_repaired_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity then return end
|
||||
if not entity.valid then return end
|
||||
if not (entity.name == 'spidertron') then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
local boost = fhb[entity.force.index]
|
||||
|
||||
if not unit_number then return end
|
||||
if not boost then return end
|
||||
boost[unit_number] = entity.health
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
Public.reset_tables()
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
|
||||
|
||||
return Public
|
80
maps/amap/surface.lua
Normal file
80
maps/amap/surface.lua
Normal file
@ -0,0 +1,80 @@
|
||||
local Global = require 'utils.global'
|
||||
local surface_name = 'amap'
|
||||
local WPT = require 'maps.amap.table'
|
||||
local Reset = require 'maps.amap.soft_reset'
|
||||
|
||||
local Public = {}
|
||||
|
||||
local this = {
|
||||
active_surface_index = nil,
|
||||
surface_name = surface_name,
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['wood'] = 16}
|
||||
|
||||
function Public.create_surface()
|
||||
local map_gen_settings = {
|
||||
['seed'] = math.random(10000, 99999),
|
||||
['starting_area'] = 1.2,
|
||||
['default_enable_all_autoplace_controls'] = true,
|
||||
['water'] = 0.65
|
||||
|
||||
}
|
||||
map_gen_settings.autoplace_controls = {
|
||||
["coal"] = {frequency = "1", size = "1", richness = "1"},
|
||||
["stone"] = {frequency = "1", size = "1", richness = "1"},
|
||||
["copper-ore"] = {frequency = "1", size = "2", richness = "1"},
|
||||
["iron-ore"] = {frequency = "1", size = "2", richness = "1"},
|
||||
["crude-oil"] = {frequency = "2", size = "2", richness = "1"},
|
||||
["trees"] = {frequency = "1", size = "0.5", richness = "0.7"},
|
||||
["enemy-base"] = {frequency = "4", size = "2", richness = "1"},
|
||||
--["starting_area"] = 1.2,
|
||||
}
|
||||
if not this.active_surface_index then
|
||||
this.active_surface_index = game.create_surface(surface_name, map_gen_settings).index
|
||||
else
|
||||
this.active_surface_index = Reset.soft_reset_map(game.surfaces[this.active_surface_index], map_gen_settings, starting_items).index
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
if not this.cleared_nauvis then
|
||||
local mgs = game.surfaces['nauvis'].map_gen_settings
|
||||
mgs.width = 16
|
||||
mgs.height = 16
|
||||
game.surfaces['nauvis'].map_gen_settings = mgs
|
||||
game.surfaces['nauvis'].clear()
|
||||
this.cleared_nauvis = true
|
||||
end
|
||||
--local size = game.surfaces[this.active_surface_index].map_gen_settings
|
||||
-- size.width = 512
|
||||
-- size.height = 512
|
||||
--game.surfaces[this.active_surface_index].map_gen_settings = size
|
||||
return this.active_surface_index
|
||||
end
|
||||
|
||||
function Public.get_active_surface()
|
||||
return this.active_surface
|
||||
end
|
||||
|
||||
function Public.get_surface_name()
|
||||
return this.surface_name
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
190
maps/amap/table.lua
Normal file
190
maps/amap/table.lua
Normal file
@ -0,0 +1,190 @@
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local this = {
|
||||
players = {},
|
||||
traps = {}
|
||||
}
|
||||
local Public = {}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
Public.level_depth = 512
|
||||
Public.level_width = 512
|
||||
function Public.reset_table()
|
||||
-- @start
|
||||
-- these 3 are in case of stop/start/reloading the instance
|
||||
this.biter_dam=0
|
||||
this.cap=2
|
||||
this.biter_health=0
|
||||
this.change_dist=false
|
||||
this.spider_health=0
|
||||
this.arty=0
|
||||
this.health = 0
|
||||
this.flame = 0
|
||||
this.roll = 0
|
||||
this.pass = false
|
||||
this.single = true
|
||||
this.science = 0
|
||||
this.number = 0
|
||||
this.first = true
|
||||
this.times = 1
|
||||
this.change = false
|
||||
this.pos = {x=0,y=0}
|
||||
this.last = 0
|
||||
this.rock = nil
|
||||
this.soft_reset = true
|
||||
this.restart = false
|
||||
this.shutdown = false
|
||||
this.announced_message = false
|
||||
this.game_saved = false
|
||||
-- @end
|
||||
this.icw_locomotive = nil
|
||||
this.debug = false
|
||||
this.game_lost = false
|
||||
this.fullness_enabled = true
|
||||
this.locomotive_health = 10000
|
||||
this.locomotive_max_health = 10000
|
||||
this.gap_between_zones = {
|
||||
set = false,
|
||||
gap = 900,
|
||||
neg_gap = -500,
|
||||
highest_pos = 0
|
||||
}
|
||||
this.force_chunk = false
|
||||
this.train_upgrades = 0
|
||||
this.biter_pets = {}
|
||||
this.flamethrower_damage = {}
|
||||
this.mined_scrap = 0
|
||||
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
|
||||
this.poison_deployed = false
|
||||
this.upgrades = {
|
||||
showed_text = false,
|
||||
landmine = {
|
||||
limit = 25,
|
||||
bought = 0,
|
||||
built = 0
|
||||
},
|
||||
flame_turret = {
|
||||
limit = 6,
|
||||
bought = 0,
|
||||
built = 0
|
||||
},
|
||||
unit_number = {
|
||||
landmine = {},
|
||||
flame_turret = {}
|
||||
}
|
||||
}
|
||||
this.aura_upgrades = 0
|
||||
this.pickaxe_tier = 1
|
||||
this.pickaxe_speed_per_purchase = 0.10
|
||||
this.health_upgrades = 0
|
||||
this.breached_wall = 1
|
||||
this.left_top = {
|
||||
x = 0,
|
||||
y = 0
|
||||
}
|
||||
this.biters = {
|
||||
amount = 0,
|
||||
limit = 512
|
||||
}
|
||||
this.traps = {}
|
||||
this.munch_time = true
|
||||
this.coin_amount = 1
|
||||
this.difficulty_set = false
|
||||
this.bonus_xp_on_join = 250
|
||||
this.main_market_items = {}
|
||||
this.spill_items_to_surface = false
|
||||
this.outside_chests = {}
|
||||
this.chests_linked_to = {}
|
||||
this.chest_limit_outside_upgrades = 1
|
||||
this.placed_trains_in_zone = {
|
||||
placed = 0,
|
||||
positions = {},
|
||||
limit = 2,
|
||||
randomized = false
|
||||
}
|
||||
this.marked_fixed_prices = {
|
||||
chest_limit_cost = 3000,
|
||||
health_cost = 10000,
|
||||
pickaxe_cost = 3000,
|
||||
aura_cost = 4000,
|
||||
xp_point_boost_cost = 5000,
|
||||
explosive_bullets_cost = 20000,
|
||||
flamethrower_turrets_cost = 3000,
|
||||
land_mine_cost = 2,
|
||||
skill_reset_cost = 100000
|
||||
}
|
||||
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.collapse_amount = false
|
||||
this.collapse_speed = false
|
||||
this.spawn_near_collapse = {
|
||||
active = true,
|
||||
total_pos = 35,
|
||||
compare = -150,
|
||||
compare_next = 200,
|
||||
distance_from = 2
|
||||
}
|
||||
this.spidertron_unlocked_at_wave = 11
|
||||
-- this.void_or_tile = 'lab-dark-2'
|
||||
this.void_or_tile = 'out-of-map'
|
||||
this.validate_spider = {}
|
||||
this.check_afk_players = true
|
||||
this.winter_mode = false
|
||||
this.sent_to_discord = false
|
||||
this.difficulty = {
|
||||
multiply = 0.25,
|
||||
highest = 10
|
||||
}
|
||||
|
||||
--!reset player tables
|
||||
for _, player in pairs(this.players) do
|
||||
player.died = false
|
||||
end
|
||||
|
||||
end
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
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
|
||||
|
||||
local on_init = function()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
|
||||
return Public
|
2448
maps/amap/terrain.lua
Normal file
2448
maps/amap/terrain.lua
Normal file
File diff suppressed because it is too large
Load Diff
116
maps/amap/wall_health_booster.lua
Normal file
116
maps/amap/wall_health_booster.lua
Normal file
@ -0,0 +1,116 @@
|
||||
-- All entities that own a unit_number of a chosen force gain damage resistance.
|
||||
-- ignores entity health regeneration
|
||||
|
||||
-- Use Public.set_health_modifier(force_index, modifier) to modify health.
|
||||
-- 1 = original health, 2 = 200% total health, 4 = 400% total health,..
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Public = {}
|
||||
|
||||
local math_round = math.round
|
||||
|
||||
local fhb = {}
|
||||
Global.register(
|
||||
fhb,
|
||||
function(tbl)
|
||||
fhb = tbl
|
||||
end
|
||||
)
|
||||
|
||||
function Public.set_health_modifier(force_index, modifier)
|
||||
if not game.forces[force_index] then return end
|
||||
if not modifier then return end
|
||||
if not fhb[force_index] then fhb[force_index] = {} end
|
||||
fhb[force_index].m = math_round(1 / modifier, 4)
|
||||
end
|
||||
|
||||
function Public.reset_tables()
|
||||
for k, v in pairs(fhb) do fhb[k] = nil end
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
|
||||
if not entity then return end
|
||||
if not entity.valid then return end
|
||||
|
||||
if not (entity.name == 'stone-wall') then
|
||||
if not (entity.name == 'gun-turret') then
|
||||
if not (entity.name == 'laser-turret') then
|
||||
-- if not (entity.name == 'flamethrower-turret') then
|
||||
return
|
||||
--end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
if not unit_number then return end
|
||||
|
||||
local boost = fhb[entity.force.index]
|
||||
if not boost then return end
|
||||
if not boost[unit_number] then boost[unit_number] = entity.prototype.max_health end
|
||||
|
||||
local new_health = boost[unit_number] - event.final_damage_amount * boost.m
|
||||
boost[unit_number] = new_health
|
||||
entity.health = new_health
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity then return end
|
||||
if not entity.valid then return end
|
||||
|
||||
if not (entity.name == 'stone-wall') then
|
||||
if not (entity.name == 'gun-turret') then
|
||||
if not (entity.name == 'laser-turret') then
|
||||
-- if not (entity.name == 'flamethrower-turret') then
|
||||
return
|
||||
--end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
if not unit_number then return end
|
||||
local boost = fhb[entity.force.index]
|
||||
if not boost then return end
|
||||
boost[unit_number] = nil
|
||||
|
||||
end
|
||||
|
||||
local function on_player_repaired_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity then return end
|
||||
if not entity.valid then return end
|
||||
if not (entity.name == 'stone-wall') then
|
||||
if not (entity.name == 'gun-turret') then
|
||||
if not (entity.name == 'laser-turret') then
|
||||
-- if not (entity.name == 'flamethrower-turret') then
|
||||
return
|
||||
--end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local unit_number = entity.unit_number
|
||||
local boost = fhb[entity.force.index]
|
||||
|
||||
if not unit_number then return end
|
||||
if not boost then return end
|
||||
boost[unit_number] = entity.health
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
Public.reset_tables()
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
|
||||
|
||||
return Public
|
@ -1257,24 +1257,31 @@ function Public.reset_game()
|
||||
|
||||
local difficulties = {
|
||||
[1] = {
|
||||
name = 'Easy',
|
||||
value = 0.75,
|
||||
color = {r = 0.00, g = 0.25, b = 0.00},
|
||||
print_color = {r = 0.00, g = 0.4, b = 0.00},
|
||||
enabled = true
|
||||
},
|
||||
[2] = {
|
||||
name = 'Normal',
|
||||
value = 1,
|
||||
color = {r = 0.00, g = 0.00, b = 0.25},
|
||||
print_color = {r = 0.0, g = 0.0, b = 0.5}
|
||||
},
|
||||
[2] = {
|
||||
[3] = {
|
||||
name = 'Hard',
|
||||
value = 1.5,
|
||||
color = {r = 0.25, g = 0.00, b = 0.00},
|
||||
print_color = {r = 0.4, g = 0.0, b = 0.00}
|
||||
},
|
||||
[3] = {
|
||||
[4] = {
|
||||
name = 'Nightmare',
|
||||
value = 3,
|
||||
color = {r = 0.35, g = 0.00, b = 0.00},
|
||||
print_color = {r = 0.6, g = 0.0, b = 0.00}
|
||||
},
|
||||
[4] = {
|
||||
[5] = {
|
||||
name = 'Impossible',
|
||||
value = 5,
|
||||
color = {r = 0.45, g = 0.00, b = 0.00},
|
||||
|
@ -1,5 +1,6 @@
|
||||
local Event = require 'utils.event'
|
||||
local RPG_Settings = require 'modules.rpg.table'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local insert = table.insert
|
||||
local floor = math.floor
|
||||
local random = math.random
|
||||
@ -34,20 +35,22 @@ local function get_coin_count(entity)
|
||||
if not coin_count then
|
||||
return
|
||||
end
|
||||
if not global.biter_health_boost_units then
|
||||
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
|
||||
|
||||
if not biter_health_boost_units then
|
||||
return coin_count
|
||||
end
|
||||
local unit_number = entity.unit_number
|
||||
if not unit_number then
|
||||
return coin_count
|
||||
end
|
||||
if not global.biter_health_boost_units[unit_number] then
|
||||
if not biter_health_boost_units[unit_number] then
|
||||
return coin_count
|
||||
end
|
||||
if not global.biter_health_boost_units[unit_number][3] then
|
||||
if not biter_health_boost_units[unit_number][3] then
|
||||
return coin_count
|
||||
end
|
||||
local m = 1 / global.biter_health_boost_units[unit_number][2]
|
||||
local m = 1 / biter_health_boost_units[unit_number][2]
|
||||
coin_count = floor(coin_count * m)
|
||||
if coin_count < 1 then
|
||||
return 1
|
||||
|
@ -183,7 +183,6 @@ local function distance(player)
|
||||
WPT.set().placed_trains_in_zone.randomized = false
|
||||
WPT.set().placed_trains_in_zone.positions = {}
|
||||
raise_event(Balance.events.breached_wall, {})
|
||||
--[[ global.biter_health_boost = calculate_hp(breached_wall) ]]
|
||||
if WPT.get('breached_wall') == WPT.get('spidertron_unlocked_at_wave') then
|
||||
local main_market_items = WPT.get('main_market_items')
|
||||
if not main_market_items['spidertron'] then
|
||||
@ -241,8 +240,6 @@ local function distance(player)
|
||||
|
||||
RPG_Settings.set_value_to_player(index, 'bonus', bonus + 1)
|
||||
|
||||
local b = RPG_Settings.get_value_from_player(index, 'bonus')
|
||||
|
||||
Functions.gain_xp(player, bonus_xp_on_join * bonus)
|
||||
local message = ({'breached_wall.wall_breached', bonus})
|
||||
Alert.alert_player_warning(player, 10, message)
|
||||
|
@ -1,7 +1,7 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local BiterRolls = require 'modules.wave_defense.biter_rolls'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local Diff = require 'modules.difficulty_vote_by_amount'
|
||||
@ -121,7 +121,7 @@ local function spawn_biters(data)
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
end
|
||||
|
||||
if random(1, 32) == 1 then
|
||||
if random(1, 45) == 1 then
|
||||
local sum = trigger_health()
|
||||
max_biters.amount = max_biters.amount + 1
|
||||
BiterHealthBooster.add_boss_unit(unit, sum, 0.38)
|
||||
|
@ -285,8 +285,12 @@ local function protect_entities(event)
|
||||
return
|
||||
end
|
||||
|
||||
if entity.type == 'simple-entity' and dmg >= 300 then
|
||||
entity.health = entity.health + dmg
|
||||
local check_heavy_damage = WPT.get('check_heavy_damage')
|
||||
|
||||
if check_heavy_damage then
|
||||
if entity.type == 'simple-entity' and dmg >= 500 then
|
||||
entity.health = entity.health + dmg
|
||||
end
|
||||
end
|
||||
|
||||
if entity.force.index ~= 1 then
|
||||
|
@ -1281,6 +1281,8 @@ function Public.disable_tech()
|
||||
game.forces.player.technologies['landfill'].enabled = false
|
||||
game.forces.player.technologies['spidertron'].enabled = false
|
||||
game.forces.player.technologies['spidertron'].researched = false
|
||||
game.forces.player.technologies['atomic-bomb'].enabled = false
|
||||
game.forces.player.technologies['atomic-bomb'].researched = false
|
||||
game.forces.player.technologies['optics'].researched = true
|
||||
game.forces.player.technologies['railway'].researched = true
|
||||
game.forces.player.technologies['land-mine'].enabled = false
|
||||
|
@ -1,12 +1,16 @@
|
||||
local Event = require 'utils.event'
|
||||
local RPG_Settings = require 'modules.rpg.table'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local IC_Gui = require 'maps.mountain_fortress_v3.ic.gui'
|
||||
local IC_Minimap = require 'maps.mountain_fortress_v3.ic.minimap'
|
||||
local Gui = require 'utils.gui'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
|
||||
local format_number = require 'util'.format_number
|
||||
|
||||
local Public = {}
|
||||
Public.events = {reset_map = Event.generate_event_name('reset_map')}
|
||||
|
||||
local main_button_name = Gui.uid_name()
|
||||
local main_frame_name = Gui.uid_name()
|
||||
local floor = math.floor
|
||||
@ -334,6 +338,50 @@ local function on_player_changed_surface(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function enable_guis(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not validate_player(player) then
|
||||
return
|
||||
end
|
||||
|
||||
local rpg_button = RPG_Settings.draw_main_frame_name
|
||||
local info = player.gui.top[main_button_name]
|
||||
local wd = player.gui.top['wave_defense']
|
||||
local rpg_b = player.gui.top[rpg_button]
|
||||
local diff = player.gui.top['difficulty_gui']
|
||||
local charging = player.gui.top['charging_station']
|
||||
|
||||
IC_Gui.remove_toolbar(player)
|
||||
IC_Minimap.toggle_button(player)
|
||||
|
||||
if info then
|
||||
info.tooltip = ({'gui.info_tooltip'})
|
||||
info.sprite = 'item/dummy-steel-axe'
|
||||
end
|
||||
|
||||
local minimap = player.gui.left.icw_main_frame
|
||||
if minimap and minimap.visible then
|
||||
minimap.visible = false
|
||||
end
|
||||
if rpg_b and not rpg_b.visible then
|
||||
rpg_b.visible = true
|
||||
end
|
||||
if diff and not diff.visible then
|
||||
diff.visible = true
|
||||
end
|
||||
if wd and not wd.visible then
|
||||
wd.visible = true
|
||||
end
|
||||
if charging and not charging.visible then
|
||||
charging.visible = true
|
||||
end
|
||||
if info then
|
||||
info.tooltip = ({'gui.info_tooltip'})
|
||||
info.sprite = 'item/dummy-steel-axe'
|
||||
info.visible = true
|
||||
end
|
||||
end
|
||||
|
||||
function Public.update_gui(player)
|
||||
if not validate_player(player) then
|
||||
return
|
||||
@ -394,5 +442,6 @@ end
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
Event.add(Public.events.reset_map, enable_guis)
|
||||
|
||||
return Public
|
||||
|
@ -27,7 +27,10 @@ end
|
||||
local function get_trusted_system(this, player)
|
||||
if not this.trust_system[player.index] then
|
||||
this.trust_system[player.index] = {
|
||||
[player.name] = true
|
||||
players = {
|
||||
[player.name] = true
|
||||
},
|
||||
allow_anyone = 'right'
|
||||
}
|
||||
end
|
||||
|
||||
@ -644,7 +647,7 @@ function Public.validate_owner(ic, player, entity)
|
||||
local p = game.players[car.owner]
|
||||
local list = get_trusted_system(ic, p)
|
||||
if p and p.valid and p.connected then
|
||||
if list[player.name] then
|
||||
if list.players[player.name] then
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -879,10 +882,12 @@ function Public.use_door_with_entity(ic, player, door)
|
||||
|
||||
local owner = game.players[car.owner]
|
||||
local list = get_trusted_system(ic, owner)
|
||||
if owner and owner.valid and player.connected then
|
||||
if not list[player.name] and not player.admin then
|
||||
player.driving = false
|
||||
return player.print('You have not been approved by ' .. owner.name .. ' to enter their vehicle.', Color.warning)
|
||||
if owner and owner.valid and owner.index ~= player.index and player.connected then
|
||||
if list.allow_anyone == 'right' then
|
||||
if not list.players[player.name] and not player.admin then
|
||||
player.driving = false
|
||||
return player.print('You have not been approved by ' .. owner.name .. ' to enter their vehicle.', Color.warning)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -17,6 +17,7 @@ local draw_transfer_car_frame_name = Gui.uid_name()
|
||||
local main_toolbar_name = Gui.uid_name()
|
||||
local add_player_name = Gui.uid_name()
|
||||
local transfer_car_name = Gui.uid_name()
|
||||
local allow_anyone_to_enter_name = Gui.uid_name()
|
||||
local kick_player_name = Gui.uid_name()
|
||||
|
||||
local raise_event = script.raise_event
|
||||
@ -35,7 +36,10 @@ local function create_player_table(player)
|
||||
local trust_system = ICT.get('trust_system')
|
||||
if not trust_system[player.index] then
|
||||
trust_system[player.index] = {
|
||||
[player.name] = true
|
||||
players = {
|
||||
[player.name] = true
|
||||
},
|
||||
allow_anyone = 'right'
|
||||
}
|
||||
end
|
||||
return trust_system[player.index]
|
||||
@ -61,7 +65,7 @@ local function transfer_player_table(player, new_player)
|
||||
end
|
||||
|
||||
if not trust_system[new_player.index] then
|
||||
local Functions = require 'maps.mountain_fortress_v3.ic.functions'
|
||||
local Functions = is_loaded('maps.mountain_fortress_v3.ic.functions')
|
||||
|
||||
trust_system[new_player.index] = trust_system[player.index]
|
||||
local name = new_player.name
|
||||
@ -200,7 +204,7 @@ local function draw_players(data)
|
||||
local player = data.player
|
||||
local player_list = create_player_table(player)
|
||||
|
||||
for p, _ in pairs(player_list) do
|
||||
for p, _ in pairs(player_list.players) do
|
||||
Gui.set_data(add_player_frame, p)
|
||||
local t_label =
|
||||
player_table.add(
|
||||
@ -270,8 +274,21 @@ local function draw_main_frame(player)
|
||||
inside_table_style.bottom_padding = 10
|
||||
inside_table_style.width = 350
|
||||
|
||||
local player_list = create_player_table(player)
|
||||
|
||||
local add_player_frame = inside_table.add({type = 'button', caption = 'Add Player', name = add_player_name})
|
||||
local transfer_car_frame = inside_table.add({type = 'button', caption = 'Transfer Car', name = transfer_car_name})
|
||||
local allow_anyone_to_enter =
|
||||
inside_table.add(
|
||||
{
|
||||
type = 'switch',
|
||||
name = allow_anyone_to_enter_name,
|
||||
switch_state = player_list.allow_anyone,
|
||||
allow_none_state = false,
|
||||
left_label_caption = 'Allow everyone to enter: ON',
|
||||
right_label_caption = 'OFF'
|
||||
}
|
||||
)
|
||||
|
||||
local player_table =
|
||||
inside_table.add {
|
||||
@ -323,6 +340,7 @@ local function draw_main_frame(player)
|
||||
player_table = player_table,
|
||||
add_player_frame = add_player_frame,
|
||||
transfer_car_frame = transfer_car_frame,
|
||||
allow_anyone_to_enter = allow_anyone_to_enter,
|
||||
player = player
|
||||
}
|
||||
draw_players(data)
|
||||
@ -429,6 +447,35 @@ Gui.on_click(
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
allow_anyone_to_enter_name,
|
||||
function(event)
|
||||
local player = event.player
|
||||
if not player or not player.valid or not player.character then
|
||||
return
|
||||
end
|
||||
|
||||
local player_list = create_player_table(player)
|
||||
|
||||
local screen = player.gui.screen
|
||||
local frame = screen[main_frame_name]
|
||||
|
||||
if frame and frame.valid then
|
||||
if player_list.allow_anyone == 'right' then
|
||||
player_list.allow_anyone = 'left'
|
||||
player.print('Everyone is allowed to enter your car!', Color.warning)
|
||||
else
|
||||
player_list.allow_anyone = 'right'
|
||||
player.print('Everyone is disallowed to enter your car except your trusted list!', Color.warning)
|
||||
end
|
||||
|
||||
if player.gui.screen[main_frame_name] then
|
||||
toggle(player, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
save_add_player_button_name,
|
||||
function(event)
|
||||
@ -456,10 +503,10 @@ Gui.on_click(
|
||||
|
||||
local name = player_to_add.name
|
||||
|
||||
if not player_list[name] then
|
||||
if not player_list.players[name] then
|
||||
player.print(name .. ' was added to your vehicle.', Color.info)
|
||||
player_to_add.print(player.name .. ' added you to their vehicle. You may now enter it.', Color.info)
|
||||
increment(player_list, name)
|
||||
increment(player_list.players, name)
|
||||
else
|
||||
return player.print('Target player is already trusted.', Color.warning)
|
||||
end
|
||||
@ -552,9 +599,9 @@ Gui.on_click(
|
||||
end
|
||||
local name = target.name
|
||||
|
||||
if player_list[name] then
|
||||
if player_list.players[name] then
|
||||
player.print(name .. ' was removed from your vehicle.', Color.info)
|
||||
decrement(player_list, name)
|
||||
decrement(player_list.players, name)
|
||||
raise_event(
|
||||
ICT.events.on_player_kicked_from_surface,
|
||||
{
|
||||
|
@ -347,8 +347,8 @@ local function property_boost(data)
|
||||
}
|
||||
rpg[player.index].xp_since_last_floaty_text = 0
|
||||
rpg[player.index].last_floaty_text = game.tick + visuals_delay
|
||||
if player.gui.left[rpg_main_frame] then
|
||||
local f = player.gui.left[rpg_main_frame]
|
||||
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
|
||||
d.exp_gui.caption = floor(rpg[player.index].xp)
|
||||
@ -1650,8 +1650,8 @@ local function place_market()
|
||||
end
|
||||
|
||||
local function on_research_finished()
|
||||
local game_lost = WPT.get('game_lost')
|
||||
if game_lost then
|
||||
local market_announce = WPT.get('market_announce')
|
||||
if market_announce > game.tick then
|
||||
return
|
||||
end
|
||||
|
||||
@ -1749,18 +1749,42 @@ local function on_player_driving_changed_state(event)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local trusted = Session.get_trusted_table()
|
||||
if #trusted == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local locomotive = WPT.get('locomotive')
|
||||
if not locomotive or not locomotive.valid then
|
||||
return
|
||||
end
|
||||
if not trusted[player.name] then
|
||||
if player.character and player.character.valid and player.character.driving then
|
||||
player.character.driving = false
|
||||
|
||||
if entity.unit_number == locomotive.unit_number then
|
||||
if not trusted[player.name] then
|
||||
if player.character and player.character.valid and player.character.driving then
|
||||
player.character.driving = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_left_game(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local trusted = Session.get_trusted_table()
|
||||
if trusted[player.name] then
|
||||
trusted[player.name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Public.close_gui_player(frame)
|
||||
if not frame then
|
||||
return
|
||||
@ -2405,5 +2429,6 @@ Event.add(defines.events.on_robot_mined_entity, on_player_and_robot_mined_entity
|
||||
Event.add(defines.events.on_console_chat, on_console_chat)
|
||||
Event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
|
||||
Event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
|
||||
Event.add(defines.events.on_player_left_game, on_player_left_game)
|
||||
|
||||
return Public
|
||||
|
@ -33,6 +33,8 @@ local Alert = require 'utils.alert'
|
||||
local AntiGrief = require 'antigrief'
|
||||
local Commands = require 'commands.misc'
|
||||
local Modifiers = require 'player_modifiers'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
|
||||
require 'maps.mountain_fortress_v3.rocks_yield_ore_veins'
|
||||
|
||||
require 'maps.mountain_fortress_v3.generate'
|
||||
@ -48,6 +50,7 @@ require 'modules.wave_defense.main'
|
||||
require 'modules.charging_station'
|
||||
|
||||
local Public = {}
|
||||
local raise_event = script.raise_event
|
||||
local floor = math.floor
|
||||
local remove = table.remove
|
||||
|
||||
@ -148,6 +151,8 @@ function Public.reset_map()
|
||||
game.forces.player.set_spawn_position({-27, 25}, surface)
|
||||
game.forces.player.manual_mining_speed_modifier = 0
|
||||
|
||||
BiterHealthBooster.set_active_surface(tostring(surface.name))
|
||||
|
||||
Balance.init_enemy_weapon_damage()
|
||||
|
||||
AntiGrief.log_tree_harvest(true)
|
||||
@ -172,6 +177,7 @@ function Public.reset_map()
|
||||
player.gui.left['mvps'].destroy()
|
||||
end
|
||||
ICMinimap.kill_minimap(player)
|
||||
raise_event(Gui_mf.events.reset_map, {player_index = player.index})
|
||||
end
|
||||
|
||||
Difficulty.reset_difficulty_poll({difficulty_poll_closing_timeout = game.tick + 36000})
|
||||
@ -206,7 +212,9 @@ function Public.reset_map()
|
||||
WD.enable_threat_log(true)
|
||||
WD.check_collapse_position(true)
|
||||
WD.set_disable_threat_below_zero(true)
|
||||
WD.increase_boss_health_per_wave(true)
|
||||
WD.increase_damage_per_wave(false)
|
||||
WD.increase_health_per_wave(true)
|
||||
|
||||
Functions.set_difficulty()
|
||||
Functions.disable_creative()
|
||||
@ -224,6 +232,7 @@ function Public.reset_map()
|
||||
HS.get_scores()
|
||||
|
||||
this.chunk_load_tick = game.tick + 1200
|
||||
this.market_announce = game.tick + 1200
|
||||
this.game_lost = false
|
||||
end
|
||||
|
||||
|
@ -200,6 +200,8 @@ function Public.reset_table()
|
||||
multiply = 0.25,
|
||||
highest = 10
|
||||
}
|
||||
this.market_announce = game.tick + 1200
|
||||
this.check_heavy_damage = true
|
||||
|
||||
--!reset player tables
|
||||
for _, player in pairs(this.players) do
|
||||
|
139
maps/scrap_towny_ffa/main.lua
Normal file
139
maps/scrap_towny_ffa/main.lua
Normal file
@ -0,0 +1,139 @@
|
||||
require "modules.custom_death_messages"
|
||||
require "modules.flashlight_toggle_button"
|
||||
require "modules.global_chat_toggle"
|
||||
require "modules.worms_create_oil_patches"
|
||||
require "modules.biters_yield_coins"
|
||||
require "modules.scrap_towny_ffa.mining"
|
||||
require "modules.scrap_towny_ffa.on_tick_schedule"
|
||||
require "modules.scrap_towny_ffa.building"
|
||||
require "modules.scrap_towny_ffa.town_center"
|
||||
require "modules.scrap_towny_ffa.market"
|
||||
require "modules.scrap_towny_ffa.slots"
|
||||
require "modules.scrap_towny_ffa.wreckage_yields_scrap"
|
||||
require "modules.scrap_towny_ffa.rocks_yield_ore_veins"
|
||||
require "modules.scrap_towny_ffa.spawners_contain_biters"
|
||||
require "modules.scrap_towny_ffa.explosives_are_explosive"
|
||||
require "modules.scrap_towny_ffa.fluids_are_explosive"
|
||||
require "modules.scrap_towny_ffa.trap"
|
||||
require "modules.scrap_towny_ffa.turrets_drop_ammo"
|
||||
require "modules.scrap_towny_ffa.combat_balance"
|
||||
|
||||
local Table = require "modules.scrap_towny_ffa.table"
|
||||
local Nauvis = require "modules.scrap_towny_ffa.nauvis"
|
||||
local Biters = require "modules.scrap_towny_ffa.biters"
|
||||
local Pollution = require "modules.scrap_towny_ffa.pollution"
|
||||
local Fish = require "modules.scrap_towny_ffa.fish_reproduction"
|
||||
local Info = require "modules.scrap_towny_ffa.info"
|
||||
local Team = require "modules.scrap_towny_ffa.team"
|
||||
local Spawn = require "modules.scrap_towny_ffa.spawn"
|
||||
local Radar = require "modules.scrap_towny_ffa.limited_radar"
|
||||
|
||||
local default_surface = "nauvis"
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local surface = game.surfaces[default_surface]
|
||||
|
||||
player.game_view_settings.show_minimap = false
|
||||
player.game_view_settings.show_map_view_options = false
|
||||
player.game_view_settings.show_entity_info = true
|
||||
--player.game_view_settings.show_side_menu = false
|
||||
|
||||
Info.toggle_button(player)
|
||||
Info.show(player)
|
||||
Team.set_player_color(player)
|
||||
if player.force ~= game.forces.player then return end
|
||||
|
||||
-- setup outlanders
|
||||
Team.set_player_to_outlander(player)
|
||||
|
||||
if player.online_time == 0 then
|
||||
player.teleport({ 0, 0 }, game.surfaces["limbo"])
|
||||
Team.give_outlander_items(player)
|
||||
Team.give_key(player)
|
||||
-- first time spawn point
|
||||
local spawn_point = Spawn.get_spawn_point(player, surface)
|
||||
Spawn.clear_spawn_point(spawn_point, surface)
|
||||
player.teleport(spawn_point, surface)
|
||||
return
|
||||
end
|
||||
|
||||
if not ffatable.requests[player.index] then return end
|
||||
if ffatable.requests[player.index] ~= "kill-character" then return end
|
||||
if player.character then
|
||||
if player.character.valid then
|
||||
player.character.die()
|
||||
end
|
||||
end
|
||||
ffatable.requests[player.index] = nil
|
||||
end
|
||||
|
||||
local function on_player_respawned(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local surface = player.surface
|
||||
if player.force == game.forces["rogue"] then Team.set_player_to_outlander(player) end
|
||||
if player.force == game.forces["player"] then Team.give_key(player) end
|
||||
|
||||
-- TODO: this needs fixing!
|
||||
-- 5 second cooldown
|
||||
--local last_respawn = ffatable.cooldowns_last_respawn[player.name]
|
||||
--if last_respawn == nil then last_respawn = 0 end
|
||||
local spawn_point = Spawn.get_spawn_point(player, surface)
|
||||
-- reset cooldown
|
||||
ffatable.cooldowns_last_respawn[player.name] = game.tick
|
||||
|
||||
player.teleport(surface.find_non_colliding_position("character", spawn_point, 0, 0.5, false), surface)
|
||||
end
|
||||
|
||||
local function on_player_died(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
ffatable.cooldowns_last_death[player.name] = game.tick
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local ffatable = Table.get_table()
|
||||
--log("on_init")
|
||||
game.enemy_has_vision_on_land_mines = false
|
||||
game.draw_resource_selection = true
|
||||
game.disable_tutorial_triggers()
|
||||
|
||||
ffatable.cooldowns_last_respawn = {}
|
||||
ffatable.cooldowns_last_death = {}
|
||||
|
||||
Nauvis.initialize()
|
||||
Team.initialize()
|
||||
|
||||
end
|
||||
|
||||
local tick_actions = {
|
||||
[60 * 0] = Radar.reset, -- each minute, at 00 seconds
|
||||
[60 * 5] = Team.update_town_chart_tags, -- each minute, at 05 seconds
|
||||
[60 * 10] = Team.set_all_player_colors, -- each minute, at 10 seconds
|
||||
[60 * 15] = Fish.reproduce, -- each minute, at 15 seconds
|
||||
[60 * 25] = Biters.unit_groups_start_moving, -- each minute, at 25 seconds
|
||||
[60 * 30] = Radar.reset, -- each minute, at 30 seconds
|
||||
[60 * 45] = Biters.validate_swarms, -- each minute, at 45 seconds
|
||||
[60 * 50] = Biters.swarm, -- each minute, at 50 seconds
|
||||
[60 * 55] = Pollution.market_scent -- each minute, at 55 seconds
|
||||
}
|
||||
|
||||
local function on_nth_tick(event)
|
||||
-- run each second
|
||||
local tick = event.tick
|
||||
local seconds = tick % 3600 -- tick will recycle minute
|
||||
if not tick_actions[seconds] then return end
|
||||
tick_actions[seconds]()
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.on_nth_tick(60, on_nth_tick) -- once every second
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.add(defines.events.on_player_died, on_player_died)
|
||||
|
||||
|
247
modules/biter_health_booster_v2.lua
Normal file
247
modules/biter_health_booster_v2.lua
Normal file
@ -0,0 +1,247 @@
|
||||
-- Biters, Spawners and Worms gain additional health / resistance -- mewmew
|
||||
-- modified by Gerkiz
|
||||
-- Use this.biter_health_boost or this.biter_health_boost_forces to modify their health.
|
||||
-- 1 = vanilla health, 2 = 200% vanilla health
|
||||
-- do not use values below 1
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local floor = math.floor
|
||||
local insert = table.insert
|
||||
local round = math.round
|
||||
local Public = {}
|
||||
|
||||
local this = {
|
||||
biter_health_boost = 1,
|
||||
biter_health_boost_forces = {},
|
||||
biter_health_boost_units = {},
|
||||
biter_health_boost_count = 0,
|
||||
active_surface = 'nauvis'
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(t)
|
||||
this = t
|
||||
end
|
||||
)
|
||||
|
||||
function Public.reset_table()
|
||||
this.biter_health_boost = 1
|
||||
this.biter_health_boost_forces = {}
|
||||
this.biter_health_boost_units = {}
|
||||
this.biter_health_boost_count = 0
|
||||
this.active_surface = 'nauvis'
|
||||
this.check_on_entity_died = false
|
||||
end
|
||||
|
||||
local entity_types = {
|
||||
['unit'] = true,
|
||||
['turret'] = true,
|
||||
['unit-spawner'] = true
|
||||
}
|
||||
|
||||
if is_loaded('maps.biter_hatchery.terrain') then
|
||||
entity_types['unit-spawner'] = nil
|
||||
end
|
||||
|
||||
local function clean_table()
|
||||
--Perform a table cleanup every 500 boosts
|
||||
this.biter_health_boost_count = this.biter_health_boost_count + 1
|
||||
if this.biter_health_boost_count % 500 ~= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local units_to_delete = {}
|
||||
|
||||
--Mark all health boost entries for deletion
|
||||
for key, _ in pairs(this.biter_health_boost_units) do
|
||||
units_to_delete[key] = true
|
||||
end
|
||||
|
||||
--Remove valid health boost entries from deletion
|
||||
local validTypes = {}
|
||||
for k, v in pairs(entity_types) do
|
||||
if v then
|
||||
insert(validTypes, k)
|
||||
end
|
||||
end
|
||||
|
||||
local surface = game.surfaces[this.active_surface]
|
||||
|
||||
for _, unit in pairs(surface.find_entities_filtered({type = validTypes})) do
|
||||
units_to_delete[unit.unit_number] = nil
|
||||
end
|
||||
|
||||
--Remove abandoned health boost entries
|
||||
for key, _ in pairs(units_to_delete) do
|
||||
this.biter_health_boost_units[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function create_boss_healthbar(entity, size)
|
||||
return rendering.draw_sprite(
|
||||
{
|
||||
sprite = 'virtual-signal/signal-white',
|
||||
tint = {0, 200, 0},
|
||||
x_scale = size * 15,
|
||||
y_scale = size,
|
||||
render_layer = 'light-effect',
|
||||
target = entity,
|
||||
target_offset = {0, -2.5},
|
||||
surface = entity.surface
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local function set_boss_healthbar(health, max_health, healthbar_id)
|
||||
local m = health / max_health
|
||||
local x_scale = rendering.get_y_scale(healthbar_id) * 15
|
||||
rendering.set_x_scale(healthbar_id, x_scale * m)
|
||||
rendering.set_color(healthbar_id, {floor(255 - 255 * m), floor(200 * m), 0})
|
||||
end
|
||||
|
||||
function Public.add_unit(unit, health_multiplier)
|
||||
if not health_multiplier then
|
||||
health_multiplier = this.biter_health_boost
|
||||
end
|
||||
this.biter_health_boost_units[unit.unit_number] = {
|
||||
floor(unit.prototype.max_health * health_multiplier),
|
||||
round(1 / health_multiplier, 5)
|
||||
}
|
||||
clean_table()
|
||||
end
|
||||
|
||||
function Public.add_boss_unit(unit, health_multiplier, health_bar_size)
|
||||
if not health_multiplier then
|
||||
health_multiplier = this.biter_health_boost
|
||||
end
|
||||
if not health_bar_size then
|
||||
health_bar_size = 0.5
|
||||
end
|
||||
local health = floor(unit.prototype.max_health * health_multiplier)
|
||||
this.biter_health_boost_units[unit.unit_number] = {
|
||||
health,
|
||||
round(1 / health_multiplier, 5),
|
||||
{max_health = health, healthbar_id = create_boss_healthbar(unit, health_bar_size), last_update = game.tick}
|
||||
}
|
||||
clean_table()
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local biter = event.entity
|
||||
if not (biter and biter.valid) then
|
||||
return
|
||||
end
|
||||
if not entity_types[biter.type] then
|
||||
return
|
||||
end
|
||||
|
||||
local biter_health_boost_units = this.biter_health_boost_units
|
||||
|
||||
local unit_number = biter.unit_number
|
||||
|
||||
--Create new health pool
|
||||
local health_pool = biter_health_boost_units[unit_number]
|
||||
if not health_pool then
|
||||
if this.biter_health_boost_forces[biter.force.index] then
|
||||
Public.add_unit(biter, this.biter_health_boost_forces[biter.force.index])
|
||||
else
|
||||
Public.add_unit(biter, this.biter_health_boost)
|
||||
end
|
||||
health_pool = this.biter_health_boost_units[unit_number]
|
||||
end
|
||||
|
||||
--Process boss unit health bars
|
||||
local boss = health_pool[3]
|
||||
if boss then
|
||||
if boss.last_update + 10 < game.tick then
|
||||
set_boss_healthbar(health_pool[1], boss.max_health, boss.healthbar_id)
|
||||
boss.last_update = game.tick
|
||||
end
|
||||
end
|
||||
|
||||
--Reduce health pool
|
||||
health_pool[1] = health_pool[1] - event.final_damage_amount
|
||||
|
||||
--Set entity health relative to health pool
|
||||
biter.health = health_pool[1] * health_pool[2]
|
||||
|
||||
--Proceed to kill entity if health is 0
|
||||
if biter.health > 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if event.cause then
|
||||
if event.cause.valid then
|
||||
event.entity.die(event.cause.force, event.cause)
|
||||
return
|
||||
end
|
||||
end
|
||||
biter.die(biter.force)
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
if not this.check_on_entity_died then
|
||||
return
|
||||
end
|
||||
|
||||
local biter = event.entity
|
||||
if not (biter and biter.valid) then
|
||||
return
|
||||
end
|
||||
if not entity_types[biter.type] then
|
||||
return
|
||||
end
|
||||
|
||||
local biter_health_boost_units = this.biter_health_boost_units
|
||||
|
||||
local unit_number = biter.unit_number
|
||||
|
||||
local health_pool = biter_health_boost_units[unit_number]
|
||||
if health_pool then
|
||||
biter_health_boost_units[unit_number] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
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
|
||||
|
||||
function Public.set_active_surface(str)
|
||||
if str and type(str) == 'string' then
|
||||
this.active_surface = str
|
||||
end
|
||||
return this.active_surface
|
||||
end
|
||||
|
||||
function Public.check_on_entity_died(boolean)
|
||||
this.check_on_entity_died = boolean or false
|
||||
|
||||
return this.check_on_entity_died
|
||||
end
|
||||
|
||||
local on_init = function()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
|
||||
return Public
|
@ -32,6 +32,9 @@ local function is_player_warned(player, reset)
|
||||
end
|
||||
|
||||
local function compute_fullness(player)
|
||||
if not player.mining_state.mining then
|
||||
return false
|
||||
end
|
||||
local warn_player = is_player_warned(player)
|
||||
local free_slots = player.get_main_inventory().count_empty_stacks()
|
||||
if free_slots == 0 or free_slots == 1 then
|
||||
|
@ -479,6 +479,13 @@ function Public.get_one_punch_chance(player)
|
||||
return chance
|
||||
end
|
||||
|
||||
function Public.get_extra_following_robots(player)
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
local strength = rpg_t[player.index].strength
|
||||
local count = math.round(strength / 2 * 0.03, 3)
|
||||
return count
|
||||
end
|
||||
|
||||
function Public.get_magicka(player)
|
||||
local rpg_t = RPG.get('rpg_t')
|
||||
return (rpg_t[player.index].magicka - 10) * 0.10
|
||||
@ -641,6 +648,14 @@ function Public.gain_xp(player, amount, added_to_pool, text)
|
||||
return
|
||||
end
|
||||
|
||||
local f = player.gui.screen[main_frame_name]
|
||||
if f and f.valid then
|
||||
local d = Gui.get_data(f)
|
||||
if d.exp_gui and d.exp_gui.valid then
|
||||
d.exp_gui.caption = math.floor(rpg_t[player.index].xp)
|
||||
end
|
||||
end
|
||||
|
||||
if rpg_t[player.index].xp >= experience_levels[rpg_t[player.index].level + 1] then
|
||||
level_up(player)
|
||||
end
|
||||
|
@ -359,7 +359,8 @@ local function draw_main_frame(player, location)
|
||||
melee_damage_tooltip = ({
|
||||
'rpg_gui.one_punch_chance',
|
||||
Functions.get_life_on_hit(player),
|
||||
Functions.get_one_punch_chance(player)
|
||||
Functions.get_one_punch_chance(player),
|
||||
Functions.get_extra_following_robots(player)
|
||||
})
|
||||
else
|
||||
melee_damage_tooltip = ({'rpg_gui.one_punch_disabled'})
|
||||
|
@ -3,6 +3,7 @@ local Event = require 'utils.event'
|
||||
local AntiGrief = require 'antigrief'
|
||||
local Color = require 'utils.color_presets'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Math2D = require 'math2d'
|
||||
@ -214,6 +215,9 @@ local function on_entity_died(event)
|
||||
end
|
||||
end
|
||||
|
||||
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
|
||||
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
|
||||
|
||||
if not event.cause then
|
||||
return
|
||||
end
|
||||
@ -232,8 +236,8 @@ local function on_entity_died(event)
|
||||
if rpg_extra.rpg_xp_yield[event.entity.name] then
|
||||
local amount = rpg_extra.rpg_xp_yield[event.entity.name]
|
||||
amount = amount / 5
|
||||
if global.biter_health_boost then
|
||||
local health_pool = global.biter_health_boost_units[event.entity.unit_number]
|
||||
if biter_health_boost then
|
||||
local health_pool = biter_health_boost_units[event.entity.unit_number]
|
||||
if health_pool then
|
||||
amount = amount * (1 / health_pool[2])
|
||||
end
|
||||
@ -268,9 +272,9 @@ local function on_entity_died(event)
|
||||
end
|
||||
|
||||
--Grant modified XP for health boosted units
|
||||
if global.biter_health_boost then
|
||||
if biter_health_boost then
|
||||
if enemy_types[event.entity.type] then
|
||||
local health_pool = global.biter_health_boost_units[event.entity.unit_number]
|
||||
local health_pool = biter_health_boost_units[event.entity.unit_number]
|
||||
if health_pool then
|
||||
for _, player in pairs(players) do
|
||||
if rpg_extra.rpg_xp_yield[event.entity.name] then
|
||||
@ -553,6 +557,14 @@ local function on_entity_damaged(event)
|
||||
return
|
||||
end
|
||||
|
||||
local item = p.cursor_stack
|
||||
|
||||
if item and item.valid_for_read then
|
||||
if item.name == 'discharge-defense-remote' then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Functions.reward_mana(cause.player, 2)
|
||||
|
||||
--Grant the player life-on-hit.
|
||||
@ -612,9 +624,12 @@ local function on_entity_damaged(event)
|
||||
)
|
||||
end
|
||||
|
||||
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
|
||||
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
|
||||
|
||||
--Handle the custom health pool of the biter health booster, if it is used in the map.
|
||||
if global.biter_health_boost then
|
||||
local health_pool = global.biter_health_boost_units[entity.unit_number]
|
||||
if biter_health_boost then
|
||||
local health_pool = biter_health_boost_units[entity.unit_number]
|
||||
if health_pool then
|
||||
health_pool[1] = health_pool[1] + event.final_damage_amount
|
||||
health_pool[1] = health_pool[1] - damage
|
||||
@ -625,7 +640,10 @@ local function on_entity_damaged(event)
|
||||
if health_pool[1] <= 0 then
|
||||
local entity_number = entity.unit_number
|
||||
entity.die(entity.force.name, cause)
|
||||
global.biter_health_boost_units[entity_number] = nil
|
||||
|
||||
if biter_health_boost_units[entity_number] then
|
||||
biter_health_boost_units[entity_number] = nil
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
210
modules/scrap_towny_ffa/biters.lua
Normal file
210
modules/scrap_towny_ffa/biters.lua
Normal file
@ -0,0 +1,210 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local math_sqrt = math.sqrt
|
||||
local math_round = math.round
|
||||
local table_size = table.size
|
||||
local table_insert = table.insert
|
||||
local table_remove = table.remove
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local tick_schedule = {}
|
||||
Global.register(
|
||||
tick_schedule,
|
||||
function(t)
|
||||
tick_schedule = t
|
||||
end
|
||||
)
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
|
||||
local function get_commmands(target, group)
|
||||
local commands = {}
|
||||
local group_position = { x = group.position.x, y = group.position.y }
|
||||
local step_length = 128
|
||||
|
||||
local target_position = target.position
|
||||
local distance_to_target = math_floor(math_sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2))
|
||||
local steps = math_floor(distance_to_target / step_length) + 1
|
||||
local vector = { math_round((target_position.x - group_position.x) / steps, 3), math_round((target_position.y - group_position.y) / steps, 3) }
|
||||
|
||||
for _ = 1, steps, 1 do
|
||||
group_position.x = group_position.x + vector[1]
|
||||
group_position.y = group_position.y + vector[2]
|
||||
local position = group.surface.find_non_colliding_position("small-biter", group_position, step_length, 2)
|
||||
if position then
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack_area,
|
||||
destination = { x = position.x, y = position.y },
|
||||
radius = 16,
|
||||
distraction = defines.distraction.by_damage
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack_area,
|
||||
destination = target.position,
|
||||
radius = 12,
|
||||
distraction = defines.distraction.by_enemy,
|
||||
}
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack,
|
||||
target = target,
|
||||
distraction = defines.distraction.by_anything,
|
||||
}
|
||||
|
||||
return commands
|
||||
end
|
||||
|
||||
local function roll_market()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
if town_centers == nil or table_size(town_centers) == 0 then return end
|
||||
local keyset = {}
|
||||
for town_name, _ in pairs(town_centers) do
|
||||
table_insert(keyset, town_name)
|
||||
end
|
||||
local tc = math_random(1, #keyset)
|
||||
return town_centers[keyset[tc]]
|
||||
end
|
||||
|
||||
local function get_random_close_spawner(surface, market, radius)
|
||||
local units = surface.find_enemy_units(market.position, radius, market.force)
|
||||
if units ~= nil and #units > 0 then
|
||||
-- found units, shuffle the list
|
||||
table_shuffle(units)
|
||||
while units[1] do
|
||||
local unit = units[1]
|
||||
if unit.spawner then return unit.spawner end
|
||||
table_remove(units, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function is_swarm_valid(swarm)
|
||||
local group = swarm.group
|
||||
if not group then return end
|
||||
if not group.valid then return end
|
||||
if game.tick >= swarm.timeout then
|
||||
group.destroy()
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.validate_swarms()
|
||||
local ffatable = Table.get_table()
|
||||
for k, swarm in pairs(ffatable.swarms) do
|
||||
if not is_swarm_valid(swarm) then
|
||||
table_remove(ffatable.swarms, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.unit_groups_start_moving()
|
||||
local ffatable = Table.get_table()
|
||||
for _, swarm in pairs(ffatable.swarms) do
|
||||
if swarm.group then
|
||||
if swarm.group.valid then
|
||||
swarm.group.start_moving()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.swarm(town_center, radius)
|
||||
if town_center == nil then return end
|
||||
local ffatable = Table.get_table()
|
||||
local r = radius or 32
|
||||
local tc = town_center or roll_market()
|
||||
if not tc or r > 512 then return end
|
||||
|
||||
-- skip if town evolution < 0.25
|
||||
if town_center.get_biter_evolution < 0.25 then return end
|
||||
|
||||
-- skip if we have to many swarms already
|
||||
local count = table_size(ffatable.swarms)
|
||||
local towns = table_size(ffatable.town_centers)
|
||||
if count > 3 * towns then return end
|
||||
|
||||
local market = tc.market
|
||||
local surface = market.surface
|
||||
|
||||
-- find a spawner
|
||||
local spawner = get_random_close_spawner(surface, market, r)
|
||||
if not spawner then
|
||||
r = r + 16
|
||||
local future = game.tick + 1
|
||||
-- schedule to run this method again with a higher radius on next tick
|
||||
if not tick_schedule[future] then tick_schedule[future] = {} end
|
||||
tick_schedule[future][#tick_schedule[future] + 1] = {
|
||||
callback = 'swarm',
|
||||
params = { tc, r }
|
||||
}
|
||||
return
|
||||
end
|
||||
|
||||
-- get our evolution
|
||||
local evolution = 0
|
||||
if spawner.name == "spitter-spawner" then
|
||||
evolution = Evolution.get_biter_evolution(spawner)
|
||||
else
|
||||
evolution = Evolution.get_spitter_evolution(spawner)
|
||||
end
|
||||
|
||||
-- get our target amount of enemies
|
||||
local count2 = (evolution * 124) + 4
|
||||
|
||||
local units = spawner.surface.find_enemy_units(spawner.position, 16, market.force)
|
||||
if #units < count2 then
|
||||
units = spawner.surface.find_enemy_units(spawner.position, 32, market.force)
|
||||
end
|
||||
if #units < count2 then
|
||||
units = spawner.surface.find_enemy_units(spawner.position, 64, market.force)
|
||||
end
|
||||
if #units < count2 then
|
||||
units = spawner.surface.find_enemy_units(spawner.position, 128, market.force)
|
||||
end
|
||||
if not units[1] then return end
|
||||
|
||||
local unit_group_position = surface.find_non_colliding_position("biter-spawner", units[1].position, 256, 1)
|
||||
if not unit_group_position then return end
|
||||
local unit_group = surface.create_unit_group({ position = unit_group_position, force = units[1].force })
|
||||
|
||||
for key, unit in pairs(units) do
|
||||
if key > count2 then break end
|
||||
unit_group.add_member(unit)
|
||||
end
|
||||
|
||||
unit_group.set_command({
|
||||
type = defines.command.compound,
|
||||
structure_type = defines.compound_command.return_last,
|
||||
commands = get_commmands(market, unit_group)
|
||||
})
|
||||
table_insert(ffatable.swarms, { group = unit_group, timeout = game.tick + 36000 })
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if not tick_schedule[game.tick] then return end
|
||||
for _, token in pairs(tick_schedule[game.tick]) do
|
||||
local callback = token.callback
|
||||
local params = token.params
|
||||
if callback == 'swarm' then Public.swarm(params[1], params[2]) end
|
||||
end
|
||||
tick_schedule[game.tick] = nil
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.swarms = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
|
||||
return Public
|
269
modules/scrap_towny_ffa/building.lua
Normal file
269
modules/scrap_towny_ffa/building.lua
Normal file
@ -0,0 +1,269 @@
|
||||
local Public = {}
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local town_radius = 27
|
||||
local connection_radius = 7
|
||||
|
||||
local neutral_whitelist = {
|
||||
["wooden-chest"] = true,
|
||||
["iron-chest"] = true,
|
||||
["steel-chest"] = true,
|
||||
["raw-fish"] = true,
|
||||
}
|
||||
|
||||
local entity_type_whitelist = {
|
||||
["accumulator"] = true,
|
||||
["ammo-turret"] = true,
|
||||
["arithmetic-combinator"] = true,
|
||||
["artillery-turret"] = true,
|
||||
["assembling-machine"] = true,
|
||||
["boiler"] = true,
|
||||
["constant-combinator"] = true,
|
||||
["container"] = true,
|
||||
["curved-rail"] = true,
|
||||
["decider-combinator"] = true,
|
||||
["electric-pole"] = true,
|
||||
["electric-turret"] = true,
|
||||
["fluid-turret"] = true,
|
||||
["furnace"] = true,
|
||||
["gate"] = true,
|
||||
["generator"] = true,
|
||||
["heat-interface"] = true,
|
||||
["heat-pipe"] = true,
|
||||
["infinity-container"] = true,
|
||||
["infinity-pipe"] = true,
|
||||
["inserter"] = true,
|
||||
["lab"] = true,
|
||||
["lamp"] = true,
|
||||
["land-mine"] = true,
|
||||
["loader"] = true,
|
||||
["logistic-container"] = true,
|
||||
["market"] = true,
|
||||
["mining-drill"] = true,
|
||||
["offshore-pump"] = true,
|
||||
["pipe"] = true,
|
||||
["pipe-to-ground"] = true,
|
||||
["programmable-speaker"] = true,
|
||||
["pump"] = true,
|
||||
["radar"] = true,
|
||||
["rail-chain-signal"] = true,
|
||||
["rail-signal"] = true,
|
||||
["reactor"] = true,
|
||||
["roboport"] = true,
|
||||
["rocket-silo"] = true,
|
||||
["solar-panel"] = true,
|
||||
["splitter"] = true,
|
||||
["storage-tank"] = true,
|
||||
["straight-rail"] = true,
|
||||
["train-stop"] = true,
|
||||
["transport-belt"] = true,
|
||||
["underground-belt"] = true,
|
||||
["wall"] = true,
|
||||
}
|
||||
|
||||
local function isolated(surface, force, position)
|
||||
local position_x = position.x
|
||||
local position_y = position.y
|
||||
local area = { { position_x - connection_radius, position_y - connection_radius }, { position_x + connection_radius, position_y + connection_radius } }
|
||||
local count = 0
|
||||
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = area, force = force.name })) do
|
||||
if entity_type_whitelist[e.type] then
|
||||
count = count + 1
|
||||
if count > 1 then return false end -- are there more than one team entities in the area?
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function refund_item(event, item_name)
|
||||
if item_name == "blueprint" then return end
|
||||
if event.player_index then
|
||||
game.players[event.player_index].insert({ name = item_name, count = 1 })
|
||||
return
|
||||
end
|
||||
|
||||
if event.robot then
|
||||
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
||||
inventory.insert({ name = item_name, count = 1 })
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function error_floaty(surface, position, msg)
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = msg,
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
end
|
||||
|
||||
local function in_range(pos1, pos2, radius)
|
||||
if pos1 == nil then return false end
|
||||
if pos2 == nil then return false end
|
||||
if radius < 1 then return true end
|
||||
local dx = pos1.x - pos2.x
|
||||
local dy = pos1.y - pos2.y
|
||||
if dx ^ 2 + dy ^ 2 < radius ^ 2 then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- is the position near a town?
|
||||
function Public.near_town(position, surface, radius)
|
||||
local ffatable = Table.get_table()
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
if town_center ~= nil then
|
||||
local market = town_center.market
|
||||
if in_range(position, market.position, radius) and market.surface == surface then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function in_town(force, position)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if town_center ~= nil then
|
||||
local center = town_center.market.position
|
||||
if position.x >= center.x - town_radius and position.x <= center.x + town_radius then
|
||||
if position.y >= center.y - town_radius and position.y <= center.y + town_radius then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function prevent_isolation_entity(event, player)
|
||||
local p = player or nil
|
||||
local entity = event.created_entity
|
||||
local position = entity.position
|
||||
if not entity.valid then return end
|
||||
local entity_name = entity.name
|
||||
local item = event.item
|
||||
if item == nil then return end
|
||||
local item_name = item.name
|
||||
local force = entity.force
|
||||
if force == game.forces.player then return end
|
||||
if force == game.forces["rogue"] then return end
|
||||
local surface = entity.surface
|
||||
local error = false
|
||||
if not in_town(force, position) and isolated(surface, force, position) then
|
||||
error = true
|
||||
entity.destroy()
|
||||
if entity_name ~= "entity-ghost" and entity_name ~= "tile-ghost" then
|
||||
refund_item(event, item_name)
|
||||
end
|
||||
--return true
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({ path = "utility/cannot_build", position = p.position, volume_modifier = 0.75 })
|
||||
end
|
||||
error_floaty(surface, position, "Building is not connected to town!")
|
||||
end
|
||||
end
|
||||
|
||||
local function prevent_isolation_tile(event, player)
|
||||
local p = player or nil
|
||||
local tile = event.tile
|
||||
if not tile.valid then return end
|
||||
local tile_name = tile.name
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local tiles = event.tiles
|
||||
local force
|
||||
if event.player_index then
|
||||
force = game.players[event.player_index].force
|
||||
else
|
||||
force = event.robot.force
|
||||
end
|
||||
local error = false
|
||||
local position
|
||||
for _, t in pairs(tiles) do
|
||||
local old_tile = t.old_tile
|
||||
position = t.position
|
||||
if not in_town(force, position) and isolated(surface, force, position) then
|
||||
error = true
|
||||
surface.set_tiles({ { name = old_tile.name, position = position } }, true)
|
||||
if tile_name ~= "tile-ghost" then
|
||||
if tile_name == "stone-path" then tile_name = "stone-brick" end
|
||||
refund_item(event, tile_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({ path = "utility/cannot_build", position = p.position, volume_modifier = 0.75 })
|
||||
end
|
||||
error_floaty(surface, position, "Tile is not connected to town!")
|
||||
end
|
||||
end
|
||||
|
||||
local function restrictions(event, player)
|
||||
local p = player or nil
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then return end
|
||||
local entity_name = entity.name
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local error = false
|
||||
if entity.force == game.forces["player"] or entity.force == game.forces["rogue"] then
|
||||
if Public.near_town(position, surface, 32) then
|
||||
error = true
|
||||
entity.destroy()
|
||||
if entity_name ~= "entity-ghost" then
|
||||
refund_item(event, event.stack.name)
|
||||
end
|
||||
else
|
||||
entity.force = game.forces["neutral"]
|
||||
end
|
||||
return
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({ path = "utility/cannot_build", position = p.position, volume_modifier = 0.75 })
|
||||
end
|
||||
error_floaty(surface, position, "Can't build near town!")
|
||||
end
|
||||
|
||||
if not neutral_whitelist[entity.type] then return end
|
||||
entity.force = game.forces["neutral"]
|
||||
|
||||
end
|
||||
|
||||
-- called when a player places an item, or a ghost
|
||||
local function on_built_entity(event)
|
||||
local player = game.players[event.player_index]
|
||||
if prevent_isolation_entity(event, player) then return end
|
||||
restrictions(event, player)
|
||||
end
|
||||
|
||||
local function on_robot_built_entity(event)
|
||||
if prevent_isolation_entity(event) then return end
|
||||
restrictions(event)
|
||||
end
|
||||
|
||||
-- called when a player places landfill
|
||||
local function on_player_built_tile(event)
|
||||
local player = game.players[event.player_index]
|
||||
prevent_isolation_tile(event, player)
|
||||
end
|
||||
|
||||
local function on_robot_built_tile(event)
|
||||
prevent_isolation_tile(event)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_player_built_tile, on_player_built_tile)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_robot_built_tile, on_robot_built_tile)
|
||||
|
||||
return Public
|
50
modules/scrap_towny_ffa/combat_balance.lua
Normal file
50
modules/scrap_towny_ffa/combat_balance.lua
Normal file
@ -0,0 +1,50 @@
|
||||
local string_sub = string.sub
|
||||
local string_len = string.len
|
||||
|
||||
-- ammo damage modifiers are static values that increase with research
|
||||
-- modifier is multiplied by base damage and then added to damage, so a negative value will reduce base damage and a positive value will increase damage
|
||||
local balance_functions = {
|
||||
["land-mine"] = function(force_name)
|
||||
-- landmines normally have a modifier of 0, so have them start at 25% of normal
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("landmine", -0.75)
|
||||
end
|
||||
end,
|
||||
["military-2"] = function(force_name)
|
||||
-- grenades normally have a modifier of 0, so have them start at 50% of normal
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
end,
|
||||
["military-4"] = function(force_name)
|
||||
-- cluster-grenades normally have a modifier of 0, so have them start at 50% of normal
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
end,
|
||||
["stronger-explosives"] = function(force_name)
|
||||
-- landmines should never increase in damage with stronger explosives
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("landmine", -0.75)
|
||||
-- allow grenades to increase by 10%
|
||||
game.forces[force_name].set_ammo_damage_modifier("grenade", game.forces[force_name].get_ammo_damage_modifier("grenade") + 0.1)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local function on_research_finished(event)
|
||||
local research_name = event.research.name
|
||||
local force_name = event.research.force.name
|
||||
local key
|
||||
for b = 1, string_len(research_name), 1 do
|
||||
key = string_sub(research_name, 0, b)
|
||||
if balance_functions[key] then
|
||||
balance_functions[key](force_name)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
|
63
modules/scrap_towny_ffa/enemy.lua
Normal file
63
modules/scrap_towny_ffa/enemy.lua
Normal file
@ -0,0 +1,63 @@
|
||||
local Public = {}
|
||||
|
||||
function Public.clear_enemies(position, surface, radius)
|
||||
--log("clear_enemies {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear enemies
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "unit-spawner", "unit", "turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
-- clear gun turrets
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "gun-turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_units(position, surface, radius)
|
||||
--log("clear_units {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear units
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "unit" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_biters(position, surface, radius)
|
||||
--log("clear_units {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear biters
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "small-biter", "medium-biter", "big-biter", "behemoth-biter" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_spitters(position, surface, radius)
|
||||
--log("clear_units {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear spitters
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "small-spitter", "medium-spitter", "big-spitter", "behemoth-spitter" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_nests(position, surface, radius)
|
||||
--log("clear_unit_spawners {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear enemies
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "unit-spawner" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_worms(position, surface, radius)
|
||||
--log("clear_turrets {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear enemies
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_gun_turrets(position, surface, radius)
|
||||
--log("clear_gun_turrets {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear gun turrets
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "gun-turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
585
modules/scrap_towny_ffa/evolution.lua
Normal file
585
modules/scrap_towny_ffa/evolution.lua
Normal file
@ -0,0 +1,585 @@
|
||||
local Public = {}
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local biters = {
|
||||
[1] = "small-biter",
|
||||
[2] = "medium-biter",
|
||||
[3] = "big-biter",
|
||||
[4] = "behemoth-biter"
|
||||
}
|
||||
|
||||
local spitters = {
|
||||
[1] = "small-spitter",
|
||||
[2] = "medium-spitter",
|
||||
[3] = "big-spitter",
|
||||
[4] = "behemoth-spitter"
|
||||
}
|
||||
|
||||
local worms = {
|
||||
[1] = "small-worm-turret",
|
||||
[2] = "medium-worm-turret",
|
||||
[3] = "big-worm-turret",
|
||||
[4] = "behemoth-worm-turret"
|
||||
}
|
||||
|
||||
-- evolution max distance in tiles
|
||||
local max_evolution_distance = 1024
|
||||
local max_pollution_behemoth = 256
|
||||
local max_pollution_big = 64
|
||||
local max_pollution_medium = 16
|
||||
local max_factor = 0.8
|
||||
|
||||
-- technology weights (biter, spitter, worm)
|
||||
local technology_weights = {
|
||||
['advanced-electronics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-electronics-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-material-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-material-processing-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-oil-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['artillery']={biter=1, spitter=1, worm=1},
|
||||
['artillery-shell-range-1']={biter=1, spitter=1, worm=1},
|
||||
['artillery-shell-speed-1']={biter=1, spitter=1, worm=1},
|
||||
['atomic-bomb']={biter=1, spitter=1, worm=1},
|
||||
['automated-rail-transportation'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automation'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automation-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automation-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automobilism'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['battery'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['battery-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['battery-mk2-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['belt-immunity-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-7'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['chemical-science-pack'] = { biter = 125, spitter = 125, worm = 125 },
|
||||
['circuit-network'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['cliff-explosives'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['coal-liquefaction'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['concrete'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['construction-robotics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['defender'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['destroyer'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['discharge-defense-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['distractor'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effect-transmission'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effectivity-module'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effectivity-module-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effectivity-module-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-energy-accumulators'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-energy-distribution-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-energy-distribution-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-engine'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electronics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['energy-shield-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-shield-mk2-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-7'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['engine'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['exoskeleton-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['explosive-rocketry']={biter=1, spitter=1, worm=1},
|
||||
['explosives'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['fast-inserter'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['flamethrower'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['flammables'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['fluid-handling'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['fluid-wagon'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-7'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['fusion-reactor-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['gate'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['gun-turret'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['heavy-armor'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['improved-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-7'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['kovarex-enrichment-process'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['land-mine'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['landfill'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['laser'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret-speed-7'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['laser-turret'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['logistic-robotics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistic-science-pack'] = { biter = 25, spitter = 25, worm = 25 },
|
||||
['logistic-system'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistics-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistics-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['low-density-structure'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['lubricant'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['military'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['military-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['military-3'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['military-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['military-science-pack'] = { biter = 50, spitter = 50, worm = 50 },
|
||||
['mining-productivity-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['mining-productivity-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['mining-productivity-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['mining-productivity-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['modular-armor'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['modules'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['night-vision-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['nuclear-fuel-reprocessing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['nuclear-power'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['oil-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['optics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['personal-laser-defense-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['personal-roboport-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['personal-roboport-mk2-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['physical-projectile-damage-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-7'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['plastics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['power-armor'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['power-armor-mk2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['production-science-pack'] = { biter = 250, spitter = 250, worm = 250 },
|
||||
['productivity-module'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['productivity-module-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['productivity-module-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rail-signals'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['railway'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['refined-flammables-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-2'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['refined-flammables-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-7'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['research-speed-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['robotics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocket-control-unit'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocket-fuel'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocket-silo'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocketry']={biter=1, spitter=1, worm=1},
|
||||
['solar-energy'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['solar-panel-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['space-science-pack'] = { biter = 1000, spitter = 1000, worm = 1000 },
|
||||
['speed-module'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['speed-module-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['speed-module-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['spidertron'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['stack-inserter'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['steel-axe'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['steel-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['stone-wall'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['stronger-explosives-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-7'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['sulfur-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['tank'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['toolbelt'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['uranium-ammo'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['uranium-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['utility-science-pack'] = { biter = 500, spitter = 500, worm = 500 },
|
||||
['weapon-shooting-speed-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['worker-robots-speed-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-storage-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-storage-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-storage-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
}
|
||||
|
||||
local max_biter_weight = 0
|
||||
local max_spitter_weight = 0
|
||||
local max_worm_weight = 0
|
||||
for _, weight in pairs(technology_weights) do
|
||||
max_biter_weight = max_biter_weight + weight.biter
|
||||
max_spitter_weight = max_spitter_weight + weight.spitter
|
||||
max_worm_weight = max_worm_weight + weight.worm
|
||||
end
|
||||
max_biter_weight = max_biter_weight * max_factor
|
||||
max_spitter_weight = max_spitter_weight * max_factor
|
||||
max_worm_weight = max_worm_weight * max_factor
|
||||
|
||||
local function get_unit_size(evolution)
|
||||
-- returns a value 0-3 that represents the unit size
|
||||
|
||||
-- basically evo values of: 0%, 10%, 30%, 60%, 80%, 100%
|
||||
-- small unit chances are 100%, 100%, 50%, 25%, 12.5%, 0%
|
||||
-- medium unit chances are 0%, 0%, 50%, 25%, 12.5%, 0%
|
||||
-- big unit chances are 0%, 0%, 0%, 50%, 25%, 0%
|
||||
-- behemoth unit chances are 0%, 0%, 0%, 0%, 50%, 100%
|
||||
-- and curve accordingly in between evo values
|
||||
|
||||
-- magic stuff happens here
|
||||
if (evolution < 0.10) then return 1 end
|
||||
if (evolution >= 0.10 and evolution < 0.40) then
|
||||
local r = (evolution - 0.10) * 5
|
||||
if math.random() < 0.5 then return 1 end
|
||||
if math.random() < r then return 1 end
|
||||
return 2
|
||||
end
|
||||
if (evolution >= 0.30 and evolution < 0.60) then
|
||||
local r = (evolution - 0.30) * 3.3333
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < 0.5 then
|
||||
return 1
|
||||
else
|
||||
if math.random() < r then return 1 else return 2 end
|
||||
end
|
||||
else
|
||||
if math.random() < r then return 2 else return 3 end
|
||||
end
|
||||
end
|
||||
if (evolution >= 0.60 and evolution < 0.80) then
|
||||
local r = (evolution - 0.60) * 5
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < r then return 1 else return 2 end
|
||||
else
|
||||
if math.random() < r then return 2 else return 3 end
|
||||
end
|
||||
else
|
||||
if math.random() < r then return 3 else return 4 end
|
||||
end
|
||||
end
|
||||
if (evolution >= 0.80 and evolution < 1.0) then
|
||||
local r = (evolution - 0.80) * 5
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < r then
|
||||
if math.random() < r then
|
||||
return 1
|
||||
else return 2 end
|
||||
else return 3 end
|
||||
else return 4 end
|
||||
end
|
||||
if (evolution >= 1.0) then return 4 end
|
||||
end
|
||||
|
||||
local function distance_squared(pos1, pos2)
|
||||
-- calculate the distance squared
|
||||
local dx = pos1.x - pos2.x
|
||||
local dy = pos1.y - pos2.y
|
||||
local d2 = dx * dx + dy * dy
|
||||
return d2
|
||||
end
|
||||
|
||||
local function get_relative_biter_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
local max_d2 = max_evolution_distance * max_evolution_distance
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
-- calculate the distance squared
|
||||
local d2 = distance_squared(position, market_position)
|
||||
if d2 < max_d2 then
|
||||
-- get the distance factor (0.0-1.0)
|
||||
local distance_factor = 1.0 - d2 / max_d2;
|
||||
-- get the evolution factor (0.0-1.0)
|
||||
if not town_center.evolution then town_center.evolution = {} end
|
||||
if town_center.evolution.biters == nil then town_center.evolution.biters = 0.0 end
|
||||
local evolution_factor = town_center.evolution.biters
|
||||
local evo = distance_factor * evolution_factor
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
return relative_evolution
|
||||
end
|
||||
|
||||
local function get_relative_spitter_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
local max_d2 = max_evolution_distance * max_evolution_distance
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
-- calculate the distance squared
|
||||
local d2 = distance_squared(position, market_position)
|
||||
if d2 < max_d2 then
|
||||
-- get the distance factor (0.0-1.0)
|
||||
local distance_factor = 1.0 - d2 / max_d2;
|
||||
-- get the evolution factor (0.0-1.0)
|
||||
if not town_center.evolution then town_center.evolution = {} end
|
||||
if town_center.evolution.spitters == nil then town_center.evolution.spitters = 0.0 end
|
||||
local evolution_factor = town_center.evolution.spitters
|
||||
local evo = distance_factor * evolution_factor
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
return relative_evolution
|
||||
end
|
||||
|
||||
local function get_relative_worm_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
local max_d2 = max_evolution_distance * max_evolution_distance
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
-- calculate the distance squared
|
||||
local d2 = distance_squared(position, market_position)
|
||||
if d2 < max_d2 then
|
||||
-- get the distance factor (0.0-1.0)
|
||||
local distance_factor = 1.0 - d2 / max_d2;
|
||||
-- get the evolution factor (0.0-1.0)
|
||||
if not town_center.evolution then town_center.evolution = {} end
|
||||
if town_center.evolution.worms == nil then town_center.evolution.worms = 0.0 end
|
||||
local evolution_factor = town_center.evolution.worms
|
||||
local evo = distance_factor * evolution_factor
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
return relative_evolution
|
||||
end
|
||||
|
||||
function Public.get_evolution(position)
|
||||
return get_relative_biter_evolution(position)
|
||||
end
|
||||
|
||||
function Public.get_biter_evolution(entity)
|
||||
return get_relative_biter_evolution(entity.position)
|
||||
end
|
||||
|
||||
function Public.get_spitter_evolution(entity)
|
||||
return get_relative_spitter_evolution(entity.position)
|
||||
end
|
||||
|
||||
function Public.get_worm_evolution(entity)
|
||||
return get_relative_worm_evolution(entity.position)
|
||||
end
|
||||
|
||||
local function get_nearby_location(position, surface, radius, entity_name)
|
||||
return surface.find_non_colliding_position(entity_name, position, radius, 0.5, false)
|
||||
end
|
||||
|
||||
local function set_biter_type(entity)
|
||||
-- checks nearby evolution levels for bases and returns an appropriately leveled type
|
||||
local position = entity.position
|
||||
local evo = get_relative_biter_evolution(position)
|
||||
local unit_size = get_unit_size(evo)
|
||||
local entity_name = biters[unit_size]
|
||||
if entity.name == entity_name then return end
|
||||
local surface = entity.surface
|
||||
local pollution = surface.get_pollution(position)
|
||||
local behemoth = math_floor(pollution / max_pollution_behemoth)
|
||||
local big = math_floor((pollution - (behemoth * max_pollution_behemoth)) / max_pollution_big)
|
||||
local medium = math_floor((pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big)) / max_pollution_medium)
|
||||
local small = pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big) - (medium * max_pollution_medium) + 1
|
||||
|
||||
if entity.valid then
|
||||
for _ = 1, behemoth do
|
||||
local e = surface.create_entity({ name = biters[4], position = get_nearby_location(position, surface, 5, biters[4]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, big do
|
||||
local e = surface.create_entity({ name = biters[3], position = get_nearby_location(position, surface, 5, biters[3]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, medium do
|
||||
local e = surface.create_entity({ name = biters[2], position = get_nearby_location(position, surface, 5, biters[2]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, small do
|
||||
local e = surface.create_entity({ name = biters[1], position = get_nearby_location(position, surface, 5, biters[1]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
local e = surface.create_entity({ name = entity_name, position = get_nearby_location(position, surface, 5, entity_name) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
entity.destroy()
|
||||
--log("spawned " .. entity_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function set_spitter_type(entity)
|
||||
-- checks nearby evolution levels for bases and returns an appropriately leveled type
|
||||
local position = entity.position
|
||||
local evo = get_relative_spitter_evolution(position)
|
||||
local unit_size = get_unit_size(evo)
|
||||
local entity_name = spitters[unit_size]
|
||||
if entity.name == entity_name then return end
|
||||
local surface = entity.surface
|
||||
local pollution = surface.get_pollution(position)
|
||||
local behemoth = math_floor(pollution / max_pollution_behemoth)
|
||||
local big = math_floor((pollution - (behemoth * max_pollution_behemoth)) / max_pollution_big)
|
||||
local medium = math_floor((pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big)) / max_pollution_medium)
|
||||
local small = pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big) - (medium * max_pollution_medium) + 1
|
||||
|
||||
if entity.valid then
|
||||
for _ = 1, behemoth do
|
||||
local e = surface.create_entity({ name = spitters[4], position = get_nearby_location(position, surface, 5, spitters[4]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, big do
|
||||
local e = surface.create_entity({ name = spitters[3], position = get_nearby_location(position, surface, 5, spitters[3]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, medium do
|
||||
local e = surface.create_entity({ name = spitters[2], position = get_nearby_location(position, surface, 5, spitters[2]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, small do
|
||||
local e = surface.create_entity({ name = spitters[1], position = get_nearby_location(position, surface, 5, spitters[1]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
local e = surface.create_entity({ name = entity_name, position = get_nearby_location(position, surface, 5, entity_name) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
entity.destroy()
|
||||
--log("spawned " .. entity_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function set_worm_type(entity)
|
||||
-- checks nearby evolution levels for bases and returns an appropriately leveled type
|
||||
local position = entity.position
|
||||
local evo = get_relative_worm_evolution(position)
|
||||
local unit_size = get_unit_size(evo)
|
||||
local entity_name = worms[unit_size]
|
||||
if entity.name == entity_name then return end
|
||||
local surface = entity.surface
|
||||
if entity.valid then
|
||||
entity.destroy()
|
||||
surface.create_entity({ name = entity_name, position = position })
|
||||
--log("spawned " .. entity_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function is_biter(entity)
|
||||
if entity == nil or not entity.valid then return false end
|
||||
if entity.name == 'small-biter' or entity.name == 'medium-biter' or entity.name == 'big-biter' or entity.name == 'behemoth-biter' then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_spitter(entity)
|
||||
if entity == nil or not entity.valid then return false end
|
||||
if entity.name == 'small-spitter' or entity.name == 'medium-spitter' or entity.name == 'big-spitter' or entity.name == 'behemoth-spitter' then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_worm(entity)
|
||||
if entity == nil or not entity.valid then return false end
|
||||
if entity.name == 'small-worm-turret' or entity.name == 'medium-worm-turret' or entity.name == 'big-worm-turret' or entity.name == 'behemoth-worm-turret' then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function update_evolution(force_name, technology)
|
||||
if technology == nil then return end
|
||||
local ffatable = Table.get_table()
|
||||
-- update evolution based on research completed (weighted)
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
-- town_center is a reference to a global table
|
||||
if not town_center then return end
|
||||
-- initialize if not already
|
||||
local evo = town_center.evolution
|
||||
-- get the weights for this technology
|
||||
local weight = technology_weights[technology]
|
||||
if weight == nil then
|
||||
log("no technology_weights for " .. technology)
|
||||
return
|
||||
end
|
||||
local biter_weight = weight.biter
|
||||
local spitter_weight = weight.spitter
|
||||
local worm_weight = weight.worm
|
||||
-- update the evolution values (0.0 to 1.0)
|
||||
local b = (biter_weight / max_biter_weight)
|
||||
local s = (spitter_weight / max_spitter_weight)
|
||||
local w = (worm_weight / max_worm_weight)
|
||||
b = b + evo.biters
|
||||
s = s + evo.spitters
|
||||
w = w + evo.worms
|
||||
evo.biters = b
|
||||
evo.spitters = s
|
||||
evo.worms = w
|
||||
end
|
||||
|
||||
local function on_research_finished(event)
|
||||
local research = event.research
|
||||
local force_name = research.force.name
|
||||
local technology = research.name
|
||||
update_evolution(force_name, technology)
|
||||
end
|
||||
|
||||
local function on_entity_spawned(event)
|
||||
local entity = event.entity
|
||||
-- check the unit type and handle appropriately
|
||||
if is_biter(entity) then
|
||||
set_biter_type(entity)
|
||||
end
|
||||
if is_spitter(entity) then
|
||||
set_spitter_type(entity)
|
||||
end
|
||||
if is_worm(entity) then
|
||||
set_worm_type(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_biter_base_built(event)
|
||||
local entity = event.entity
|
||||
if is_worm(entity) then
|
||||
set_worm_type(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_entity_spawned, on_entity_spawned)
|
||||
Event.add(defines.events.on_biter_base_built, on_biter_base_built)
|
||||
|
||||
return Public
|
228
modules/scrap_towny_ffa/explosives_are_explosive.lua
Normal file
228
modules/scrap_towny_ffa/explosives_are_explosive.lua
Normal file
@ -0,0 +1,228 @@
|
||||
--This will add a new game mechanic so that containers with explosives actually go boom when they get damaged.
|
||||
--Made by MewMew
|
||||
local math_min = math.min
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Pollution = require "modules.scrap_towny_ffa.pollution"
|
||||
|
||||
--local damage_per_explosive = 100
|
||||
local damage_per_explosive = 50
|
||||
local empty_tile_damage_decay = 100
|
||||
local out_of_map_tile_health = 1500
|
||||
local max_volatility = 20
|
||||
|
||||
local explosive_items = {
|
||||
["explosives"] = 1,
|
||||
["land-mine"] = 1,
|
||||
["grenade"] = 1,
|
||||
["cluster-grenade"] = 3,
|
||||
["artillery-shell"] = 5,
|
||||
["cannon-shell"] = 3,
|
||||
["explosive-cannon-shell"] = 5,
|
||||
["explosive-uranium-cannon-shell"] = 5,
|
||||
["uranium-cannon-shell"] = 5,
|
||||
-- ["atomic-bomb"] = 100,
|
||||
["explosive-rocket"] = 5,
|
||||
["rocket"] = 2,
|
||||
["flamethrower-ammo"] = 2,
|
||||
["petroleum-gas-barrel"] = 2,
|
||||
-- ["crude-oil-barrel"] = 2,
|
||||
-- ["light-oil-barrel"] = 2,
|
||||
-- ["heavy-oil-barrel"] = 2,
|
||||
-- ["lubricant-barrel"] = 1,
|
||||
-- ["shotgun-shell"] = 1,
|
||||
-- ["piercing-shotgun-shell"] = 1,
|
||||
-- ["firearm-magazine"] = 1,
|
||||
-- ["piercing-rounds-magazine"] = 1,
|
||||
-- ["uranium-rounds-magazine"] = 1,
|
||||
["cliff-explosives"] = 2,
|
||||
-- ["solid-fuel"] = 1
|
||||
}
|
||||
|
||||
local circle_coordinates = {
|
||||
[1] = { { x = 0, y = 0 } },
|
||||
[2] = { { x = -1, y = -1 }, { x = 1, y = -1 }, { x = 0, y = -1 }, { x = -1, y = 0 }, { x = -1, y = 1 }, { x = 0, y = 1 }, { x = 1, y = 1 }, { x = 1, y = 0 } },
|
||||
[3] = { { x = -2, y = -1 }, { x = -1, y = -2 }, { x = 1, y = -2 }, { x = 0, y = -2 }, { x = 2, y = -1 }, { x = -2, y = 1 }, { x = -2, y = 0 }, { x = 2, y = 1 }, { x = 2, y = 0 }, { x = -1, y = 2 }, { x = 1, y = 2 }, { x = 0, y = 2 } },
|
||||
[4] = { { x = -1, y = -3 }, { x = 1, y = -3 }, { x = 0, y = -3 }, { x = -3, y = -1 }, { x = -2, y = -2 }, { x = 3, y = -1 }, { x = 2, y = -2 }, { x = -3, y = 0 }, { x = -3, y = 1 }, { x = 3, y = 1 }, { x = 3, y = 0 }, { x = -2, y = 2 }, { x = -1, y = 3 }, { x = 0, y = 3 }, { x = 1, y = 3 }, { x = 2, y = 2 } },
|
||||
[5] = { { x = -3, y = -3 }, { x = -2, y = -3 }, { x = -1, y = -4 }, { x = -2, y = -4 }, { x = 1, y = -4 }, { x = 0, y = -4 }, { x = 2, y = -3 }, { x = 3, y = -3 }, { x = 2, y = -4 }, { x = -3, y = -2 }, { x = -4, y = -1 }, { x = -4, y = -2 }, { x = 3, y = -2 }, { x = 4, y = -1 }, { x = 4, y = -2 }, { x = -4, y = 1 }, { x = -4, y = 0 }, { x = 4, y = 1 }, { x = 4, y = 0 }, { x = -3, y = 3 }, { x = -3, y = 2 }, { x = -4, y = 2 }, { x = -2, y = 3 }, { x = 2, y = 3 }, { x = 3, y = 3 }, { x = 3, y = 2 }, { x = 4, y = 2 }, { x = -2, y = 4 }, { x = -1, y = 4 }, { x = 0, y = 4 }, { x = 1, y = 4 }, { x = 2, y = 4 } },
|
||||
[6] = { { x = -1, y = -5 }, { x = -2, y = -5 }, { x = 1, y = -5 }, { x = 0, y = -5 }, { x = 2, y = -5 }, { x = -3, y = -4 }, { x = -4, y = -3 }, { x = 3, y = -4 }, { x = 4, y = -3 }, { x = -5, y = -1 }, { x = -5, y = -2 }, { x = 5, y = -1 }, { x = 5, y = -2 }, { x = -5, y = 1 }, { x = -5, y = 0 }, { x = 5, y = 1 }, { x = 5, y = 0 }, { x = -5, y = 2 }, { x = -4, y = 3 }, { x = 4, y = 3 }, { x = 5, y = 2 }, { x = -3, y = 4 }, { x = -2, y = 5 }, { x = -1, y = 5 }, { x = 0, y = 5 }, { x = 1, y = 5 }, { x = 3, y = 4 }, { x = 2, y = 5 } },
|
||||
[7] = { { x = -4, y = -5 }, { x = -3, y = -5 }, { x = -2, y = -6 }, { x = -1, y = -6 }, { x = 0, y = -6 }, { x = 1, y = -6 }, { x = 3, y = -5 }, { x = 2, y = -6 }, { x = 4, y = -5 }, { x = -5, y = -4 }, { x = -5, y = -3 }, { x = -4, y = -4 }, { x = 4, y = -4 }, { x = 5, y = -4 }, { x = 5, y = -3 }, { x = -6, y = -1 }, { x = -6, y = -2 }, { x = 6, y = -1 }, { x = 6, y = -2 }, { x = -6, y = 1 }, { x = -6, y = 0 }, { x = 6, y = 1 }, { x = 6, y = 0 }, { x = -5, y = 3 }, { x = -6, y = 2 }, { x = 5, y = 3 }, { x = 6, y = 2 }, { x = -5, y = 4 }, { x = -4, y = 4 }, { x = -4, y = 5 }, { x = -3, y = 5 }, { x = 3, y = 5 }, { x = 4, y = 4 }, { x = 5, y = 4 }, { x = 4, y = 5 }, { x = -1, y = 6 }, { x = -2, y = 6 }, { x = 1, y = 6 }, { x = 0, y = 6 }, { x = 2, y = 6 } },
|
||||
[8] = { { x = -1, y = -7 }, { x = -2, y = -7 }, { x = 1, y = -7 }, { x = 0, y = -7 }, { x = 2, y = -7 }, { x = -5, y = -5 }, { x = -4, y = -6 }, { x = -3, y = -6 }, { x = 3, y = -6 }, { x = 4, y = -6 }, { x = 5, y = -5 }, { x = -6, y = -3 }, { x = -6, y = -4 }, { x = 6, y = -4 }, { x = 6, y = -3 }, { x = -7, y = -1 }, { x = -7, y = -2 }, { x = 7, y = -1 }, { x = 7, y = -2 }, { x = -7, y = 1 }, { x = -7, y = 0 }, { x = 7, y = 1 }, { x = 7, y = 0 }, { x = -7, y = 2 }, { x = -6, y = 3 }, { x = 6, y = 3 }, { x = 7, y = 2 }, { x = -5, y = 5 }, { x = -6, y = 4 }, { x = 5, y = 5 }, { x = 6, y = 4 }, { x = -3, y = 6 }, { x = -4, y = 6 }, { x = -2, y = 7 }, { x = -1, y = 7 }, { x = 0, y = 7 }, { x = 1, y = 7 }, { x = 3, y = 6 }, { x = 2, y = 7 }, { x = 4, y = 6 } },
|
||||
[9] = { { x = -4, y = -7 }, { x = -3, y = -7 }, { x = -2, y = -8 }, { x = -1, y = -8 }, { x = 0, y = -8 }, { x = 1, y = -8 }, { x = 3, y = -7 }, { x = 2, y = -8 }, { x = 4, y = -7 }, { x = -5, y = -6 }, { x = -6, y = -6 }, { x = -6, y = -5 }, { x = 5, y = -6 }, { x = 6, y = -5 }, { x = 6, y = -6 }, { x = -7, y = -4 }, { x = -7, y = -3 }, { x = 7, y = -4 }, { x = 7, y = -3 }, { x = -8, y = -2 }, { x = -8, y = -1 }, { x = 8, y = -1 }, { x = 8, y = -2 }, { x = -8, y = 0 }, { x = -8, y = 1 }, { x = 8, y = 1 }, { x = 8, y = 0 }, { x = -7, y = 3 }, { x = -8, y = 2 }, { x = 7, y = 3 }, { x = 8, y = 2 }, { x = -7, y = 4 }, { x = -6, y = 5 }, { x = 6, y = 5 }, { x = 7, y = 4 }, { x = -5, y = 6 }, { x = -6, y = 6 }, { x = -4, y = 7 }, { x = -3, y = 7 }, { x = 3, y = 7 }, { x = 5, y = 6 }, { x = 4, y = 7 }, { x = 6, y = 6 }, { x = -2, y = 8 }, { x = -1, y = 8 }, { x = 0, y = 8 }, { x = 1, y = 8 }, { x = 2, y = 8 } },
|
||||
[10] = { { x = -3, y = -9 }, { x = -1, y = -9 }, { x = -2, y = -9 }, { x = 1, y = -9 }, { x = 0, y = -9 }, { x = 3, y = -9 }, { x = 2, y = -9 }, { x = -5, y = -7 }, { x = -6, y = -7 }, { x = -5, y = -8 }, { x = -4, y = -8 }, { x = -3, y = -8 }, { x = 3, y = -8 }, { x = 5, y = -7 }, { x = 5, y = -8 }, { x = 4, y = -8 }, { x = 6, y = -7 }, { x = -7, y = -5 }, { x = -7, y = -6 }, { x = -8, y = -5 }, { x = 7, y = -5 }, { x = 7, y = -6 }, { x = 8, y = -5 }, { x = -9, y = -3 }, { x = -8, y = -4 }, { x = -8, y = -3 }, { x = 8, y = -4 }, { x = 8, y = -3 }, { x = 9, y = -3 }, { x = -9, y = -1 }, { x = -9, y = -2 }, { x = 9, y = -1 }, { x = 9, y = -2 }, { x = -9, y = 1 }, { x = -9, y = 0 }, { x = 9, y = 1 }, { x = 9, y = 0 }, { x = -9, y = 3 }, { x = -9, y = 2 }, { x = -8, y = 3 }, { x = 8, y = 3 }, { x = 9, y = 3 }, { x = 9, y = 2 }, { x = -7, y = 5 }, { x = -8, y = 5 }, { x = -8, y = 4 }, { x = 7, y = 5 }, { x = 8, y = 5 }, { x = 8, y = 4 }, { x = -7, y = 6 }, { x = -6, y = 7 }, { x = -5, y = 7 }, { x = 5, y = 7 }, { x = 7, y = 6 }, { x = 6, y = 7 }, { x = -5, y = 8 }, { x = -4, y = 8 }, { x = -3, y = 8 }, { x = -3, y = 9 }, { x = -2, y = 9 }, { x = -1, y = 9 }, { x = 0, y = 9 }, { x = 1, y = 9 }, { x = 3, y = 8 }, { x = 2, y = 9 }, { x = 3, y = 9 }, { x = 5, y = 8 }, { x = 4, y = 8 } },
|
||||
[11] = { { x = -5, y = -9 }, { x = -4, y = -9 }, { x = -3, y = -10 }, { x = -1, y = -10 }, { x = -2, y = -10 }, { x = 1, y = -10 }, { x = 0, y = -10 }, { x = 3, y = -10 }, { x = 2, y = -10 }, { x = 5, y = -9 }, { x = 4, y = -9 }, { x = -7, y = -7 }, { x = -6, y = -8 }, { x = 7, y = -7 }, { x = 6, y = -8 }, { x = -9, y = -5 }, { x = -8, y = -6 }, { x = 9, y = -5 }, { x = 8, y = -6 }, { x = -9, y = -4 }, { x = -10, y = -3 }, { x = 9, y = -4 }, { x = 10, y = -3 }, { x = -10, y = -2 }, { x = -10, y = -1 }, { x = 10, y = -1 }, { x = 10, y = -2 }, { x = -10, y = 0 }, { x = -10, y = 1 }, { x = 10, y = 1 }, { x = 10, y = 0 }, { x = -10, y = 2 }, { x = -10, y = 3 }, { x = 10, y = 3 }, { x = 10, y = 2 }, { x = -9, y = 4 }, { x = -9, y = 5 }, { x = 9, y = 5 }, { x = 9, y = 4 }, { x = -8, y = 6 }, { x = -7, y = 7 }, { x = 7, y = 7 }, { x = 8, y = 6 }, { x = -6, y = 8 }, { x = -5, y = 9 }, { x = -4, y = 9 }, { x = 4, y = 9 }, { x = 5, y = 9 }, { x = 6, y = 8 }, { x = -3, y = 10 }, { x = -2, y = 10 }, { x = -1, y = 10 }, { x = 0, y = 10 }, { x = 1, y = 10 }, { x = 2, y = 10 }, { x = 3, y = 10 } },
|
||||
[12] = { { x = -3, y = -11 }, { x = -2, y = -11 }, { x = -1, y = -11 }, { x = 0, y = -11 }, { x = 1, y = -11 }, { x = 2, y = -11 }, { x = 3, y = -11 }, { x = -7, y = -9 }, { x = -6, y = -9 }, { x = -5, y = -10 }, { x = -4, y = -10 }, { x = 5, y = -10 }, { x = 4, y = -10 }, { x = 7, y = -9 }, { x = 6, y = -9 }, { x = -9, y = -7 }, { x = -7, y = -8 }, { x = -8, y = -8 }, { x = -8, y = -7 }, { x = 7, y = -8 }, { x = 8, y = -7 }, { x = 8, y = -8 }, { x = 9, y = -7 }, { x = -9, y = -6 }, { x = -10, y = -5 }, { x = 9, y = -6 }, { x = 10, y = -5 }, { x = -11, y = -3 }, { x = -10, y = -4 }, { x = 10, y = -4 }, { x = 11, y = -3 }, { x = -11, y = -2 }, { x = -11, y = -1 }, { x = 11, y = -1 }, { x = 11, y = -2 }, { x = -11, y = 0 }, { x = -11, y = 1 }, { x = 11, y = 1 }, { x = 11, y = 0 }, { x = -11, y = 2 }, { x = -11, y = 3 }, { x = 11, y = 3 }, { x = 11, y = 2 }, { x = -10, y = 5 }, { x = -10, y = 4 }, { x = 10, y = 5 }, { x = 10, y = 4 }, { x = -9, y = 7 }, { x = -9, y = 6 }, { x = -8, y = 7 }, { x = 8, y = 7 }, { x = 9, y = 7 }, { x = 9, y = 6 }, { x = -8, y = 8 }, { x = -7, y = 8 }, { x = -7, y = 9 }, { x = -6, y = 9 }, { x = 7, y = 8 }, { x = 7, y = 9 }, { x = 6, y = 9 }, { x = 8, y = 8 }, { x = -5, y = 10 }, { x = -4, y = 10 }, { x = -3, y = 11 }, { x = -2, y = 11 }, { x = -1, y = 11 }, { x = 0, y = 11 }, { x = 1, y = 11 }, { x = 2, y = 11 }, { x = 3, y = 11 }, { x = 4, y = 10 }, { x = 5, y = 10 } },
|
||||
[13] = { { x = -5, y = -11 }, { x = -4, y = -11 }, { x = -3, y = -12 }, { x = -1, y = -12 }, { x = -2, y = -12 }, { x = 1, y = -12 }, { x = 0, y = -12 }, { x = 3, y = -12 }, { x = 2, y = -12 }, { x = 4, y = -11 }, { x = 5, y = -11 }, { x = -8, y = -9 }, { x = -7, y = -10 }, { x = -6, y = -10 }, { x = 6, y = -10 }, { x = 7, y = -10 }, { x = 8, y = -9 }, { x = -10, y = -7 }, { x = -9, y = -8 }, { x = 9, y = -8 }, { x = 10, y = -7 }, { x = -11, y = -5 }, { x = -10, y = -6 }, { x = 10, y = -6 }, { x = 11, y = -5 }, { x = -11, y = -4 }, { x = -12, y = -3 }, { x = 11, y = -4 }, { x = 12, y = -3 }, { x = -12, y = -1 }, { x = -12, y = -2 }, { x = 12, y = -1 }, { x = 12, y = -2 }, { x = -12, y = 1 }, { x = -12, y = 0 }, { x = 12, y = 1 }, { x = 12, y = 0 }, { x = -12, y = 3 }, { x = -12, y = 2 }, { x = 12, y = 3 }, { x = 12, y = 2 }, { x = -11, y = 5 }, { x = -11, y = 4 }, { x = 11, y = 4 }, { x = 11, y = 5 }, { x = -10, y = 7 }, { x = -10, y = 6 }, { x = 10, y = 6 }, { x = 10, y = 7 }, { x = -9, y = 8 }, { x = -8, y = 9 }, { x = 9, y = 8 }, { x = 8, y = 9 }, { x = -7, y = 10 }, { x = -5, y = 11 }, { x = -6, y = 10 }, { x = -4, y = 11 }, { x = 5, y = 11 }, { x = 4, y = 11 }, { x = 7, y = 10 }, { x = 6, y = 10 }, { x = -3, y = 12 }, { x = -2, y = 12 }, { x = -1, y = 12 }, { x = 0, y = 12 }, { x = 1, y = 12 }, { x = 2, y = 12 }, { x = 3, y = 12 } },
|
||||
[14] = { { x = -3, y = -13 }, { x = -1, y = -13 }, { x = -2, y = -13 }, { x = 1, y = -13 }, { x = 0, y = -13 }, { x = 3, y = -13 }, { x = 2, y = -13 }, { x = -7, y = -11 }, { x = -6, y = -11 }, { x = -5, y = -12 }, { x = -6, y = -12 }, { x = -4, y = -12 }, { x = 5, y = -12 }, { x = 4, y = -12 }, { x = 7, y = -11 }, { x = 6, y = -11 }, { x = 6, y = -12 }, { x = -10, y = -9 }, { x = -9, y = -9 }, { x = -9, y = -10 }, { x = -8, y = -10 }, { x = 9, y = -9 }, { x = 9, y = -10 }, { x = 8, y = -10 }, { x = 10, y = -9 }, { x = -11, y = -7 }, { x = -10, y = -8 }, { x = 11, y = -7 }, { x = 10, y = -8 }, { x = -11, y = -6 }, { x = -12, y = -6 }, { x = -12, y = -5 }, { x = 11, y = -6 }, { x = 12, y = -6 }, { x = 12, y = -5 }, { x = -13, y = -3 }, { x = -12, y = -4 }, { x = 12, y = -4 }, { x = 13, y = -3 }, { x = -13, y = -2 }, { x = -13, y = -1 }, { x = 13, y = -1 }, { x = 13, y = -2 }, { x = -13, y = 0 }, { x = -13, y = 1 }, { x = 13, y = 1 }, { x = 13, y = 0 }, { x = -13, y = 2 }, { x = -13, y = 3 }, { x = 13, y = 3 }, { x = 13, y = 2 }, { x = -12, y = 5 }, { x = -12, y = 4 }, { x = 12, y = 5 }, { x = 12, y = 4 }, { x = -11, y = 6 }, { x = -11, y = 7 }, { x = -12, y = 6 }, { x = 11, y = 7 }, { x = 11, y = 6 }, { x = 12, y = 6 }, { x = -10, y = 8 }, { x = -10, y = 9 }, { x = -9, y = 9 }, { x = 9, y = 9 }, { x = 10, y = 9 }, { x = 10, y = 8 }, { x = -9, y = 10 }, { x = -8, y = 10 }, { x = -7, y = 11 }, { x = -6, y = 11 }, { x = 7, y = 11 }, { x = 6, y = 11 }, { x = 8, y = 10 }, { x = 9, y = 10 }, { x = -6, y = 12 }, { x = -5, y = 12 }, { x = -4, y = 12 }, { x = -3, y = 13 }, { x = -2, y = 13 }, { x = -1, y = 13 }, { x = 0, y = 13 }, { x = 1, y = 13 }, { x = 2, y = 13 }, { x = 3, y = 13 }, { x = 5, y = 12 }, { x = 4, y = 12 }, { x = 6, y = 12 } },
|
||||
[15] = { { x = -5, y = -13 }, { x = -6, y = -13 }, { x = -4, y = -13 }, { x = -3, y = -14 }, { x = -1, y = -14 }, { x = -2, y = -14 }, { x = 1, y = -14 }, { x = 0, y = -14 }, { x = 3, y = -14 }, { x = 2, y = -14 }, { x = 5, y = -13 }, { x = 4, y = -13 }, { x = 6, y = -13 }, { x = -9, y = -11 }, { x = -8, y = -11 }, { x = -8, y = -12 }, { x = -7, y = -12 }, { x = 7, y = -12 }, { x = 8, y = -12 }, { x = 8, y = -11 }, { x = 9, y = -11 }, { x = -11, y = -9 }, { x = -10, y = -10 }, { x = 10, y = -10 }, { x = 11, y = -9 }, { x = -12, y = -7 }, { x = -11, y = -8 }, { x = -12, y = -8 }, { x = 11, y = -8 }, { x = 12, y = -8 }, { x = 12, y = -7 }, { x = -13, y = -5 }, { x = -13, y = -6 }, { x = 13, y = -5 }, { x = 13, y = -6 }, { x = -13, y = -4 }, { x = -14, y = -3 }, { x = 13, y = -4 }, { x = 14, y = -3 }, { x = -14, y = -2 }, { x = -14, y = -1 }, { x = 14, y = -1 }, { x = 14, y = -2 }, { x = -14, y = 0 }, { x = -14, y = 1 }, { x = 14, y = 1 }, { x = 14, y = 0 }, { x = -14, y = 2 }, { x = -14, y = 3 }, { x = 14, y = 3 }, { x = 14, y = 2 }, { x = -13, y = 4 }, { x = -13, y = 5 }, { x = 13, y = 5 }, { x = 13, y = 4 }, { x = -13, y = 6 }, { x = -12, y = 7 }, { x = 12, y = 7 }, { x = 13, y = 6 }, { x = -11, y = 9 }, { x = -11, y = 8 }, { x = -12, y = 8 }, { x = 11, y = 8 }, { x = 11, y = 9 }, { x = 12, y = 8 }, { x = -9, y = 11 }, { x = -10, y = 10 }, { x = -8, y = 11 }, { x = 9, y = 11 }, { x = 8, y = 11 }, { x = 10, y = 10 }, { x = -7, y = 12 }, { x = -8, y = 12 }, { x = -6, y = 13 }, { x = -5, y = 13 }, { x = -4, y = 13 }, { x = 5, y = 13 }, { x = 4, y = 13 }, { x = 7, y = 12 }, { x = 6, y = 13 }, { x = 8, y = 12 }, { x = -3, y = 14 }, { x = -2, y = 14 }, { x = -1, y = 14 }, { x = 0, y = 14 }, { x = 1, y = 14 }, { x = 2, y = 14 }, { x = 3, y = 14 } },
|
||||
[16] = { { x = -3, y = -15 }, { x = -1, y = -15 }, { x = -2, y = -15 }, { x = 1, y = -15 }, { x = 0, y = -15 }, { x = 3, y = -15 }, { x = 2, y = -15 }, { x = -7, y = -13 }, { x = -8, y = -13 }, { x = -5, y = -14 }, { x = -6, y = -14 }, { x = -4, y = -14 }, { x = 5, y = -14 }, { x = 4, y = -14 }, { x = 7, y = -13 }, { x = 6, y = -14 }, { x = 8, y = -13 }, { x = -9, y = -12 }, { x = -10, y = -11 }, { x = 9, y = -12 }, { x = 10, y = -11 }, { x = -11, y = -10 }, { x = -12, y = -9 }, { x = 11, y = -10 }, { x = 12, y = -9 }, { x = -13, y = -7 }, { x = -13, y = -8 }, { x = 13, y = -7 }, { x = 13, y = -8 }, { x = -14, y = -6 }, { x = -14, y = -5 }, { x = 14, y = -5 }, { x = 14, y = -6 }, { x = -15, y = -3 }, { x = -14, y = -4 }, { x = 15, y = -3 }, { x = 14, y = -4 }, { x = -15, y = -2 }, { x = -15, y = -1 }, { x = 15, y = -1 }, { x = 15, y = -2 }, { x = -15, y = 0 }, { x = -15, y = 1 }, { x = 15, y = 1 }, { x = 15, y = 0 }, { x = -15, y = 2 }, { x = -15, y = 3 }, { x = 15, y = 3 }, { x = 15, y = 2 }, { x = -14, y = 5 }, { x = -14, y = 4 }, { x = 14, y = 5 }, { x = 14, y = 4 }, { x = -13, y = 7 }, { x = -14, y = 6 }, { x = 13, y = 7 }, { x = 14, y = 6 }, { x = -13, y = 8 }, { x = -12, y = 9 }, { x = 12, y = 9 }, { x = 13, y = 8 }, { x = -11, y = 10 }, { x = -10, y = 11 }, { x = 10, y = 11 }, { x = 11, y = 10 }, { x = -9, y = 12 }, { x = -8, y = 13 }, { x = -7, y = 13 }, { x = 7, y = 13 }, { x = 8, y = 13 }, { x = 9, y = 12 }, { x = -6, y = 14 }, { x = -5, y = 14 }, { x = -4, y = 14 }, { x = -3, y = 15 }, { x = -2, y = 15 }, { x = -1, y = 15 }, { x = 0, y = 15 }, { x = 1, y = 15 }, { x = 2, y = 15 }, { x = 3, y = 15 }, { x = 4, y = 14 }, { x = 5, y = 14 }, { x = 6, y = 14 } },
|
||||
[17] = { { x = -5, y = -15 }, { x = -6, y = -15 }, { x = -3, y = -16 }, { x = -4, y = -16 }, { x = -4, y = -15 }, { x = -1, y = -16 }, { x = -2, y = -16 }, { x = 1, y = -16 }, { x = 0, y = -16 }, { x = 3, y = -16 }, { x = 2, y = -16 }, { x = 5, y = -15 }, { x = 4, y = -15 }, { x = 4, y = -16 }, { x = 6, y = -15 }, { x = -9, y = -13 }, { x = -10, y = -13 }, { x = -8, y = -14 }, { x = -7, y = -14 }, { x = 7, y = -14 }, { x = 9, y = -13 }, { x = 8, y = -14 }, { x = 10, y = -13 }, { x = -11, y = -12 }, { x = -11, y = -11 }, { x = -12, y = -11 }, { x = -10, y = -12 }, { x = 11, y = -11 }, { x = 11, y = -12 }, { x = 10, y = -12 }, { x = 12, y = -11 }, { x = -13, y = -10 }, { x = -13, y = -9 }, { x = -12, y = -10 }, { x = 13, y = -9 }, { x = 13, y = -10 }, { x = 12, y = -10 }, { x = -14, y = -7 }, { x = -14, y = -8 }, { x = 14, y = -7 }, { x = 14, y = -8 }, { x = -15, y = -6 }, { x = -15, y = -5 }, { x = 15, y = -5 }, { x = 15, y = -6 }, { x = -15, y = -4 }, { x = -16, y = -4 }, { x = -16, y = -3 }, { x = 15, y = -4 }, { x = 16, y = -3 }, { x = 16, y = -4 }, { x = -16, y = -2 }, { x = -16, y = -1 }, { x = 16, y = -1 }, { x = 16, y = -2 }, { x = -16, y = 0 }, { x = -16, y = 1 }, { x = 16, y = 1 }, { x = 16, y = 0 }, { x = -16, y = 2 }, { x = -16, y = 3 }, { x = 16, y = 3 }, { x = 16, y = 2 }, { x = -16, y = 4 }, { x = -15, y = 4 }, { x = -15, y = 5 }, { x = 15, y = 5 }, { x = 15, y = 4 }, { x = 16, y = 4 }, { x = -15, y = 6 }, { x = -14, y = 7 }, { x = 14, y = 7 }, { x = 15, y = 6 }, { x = -13, y = 9 }, { x = -14, y = 8 }, { x = 13, y = 9 }, { x = 14, y = 8 }, { x = -13, y = 10 }, { x = -12, y = 10 }, { x = -12, y = 11 }, { x = -11, y = 11 }, { x = 11, y = 11 }, { x = 12, y = 11 }, { x = 12, y = 10 }, { x = 13, y = 10 }, { x = -11, y = 12 }, { x = -10, y = 12 }, { x = -10, y = 13 }, { x = -9, y = 13 }, { x = 9, y = 13 }, { x = 10, y = 13 }, { x = 10, y = 12 }, { x = 11, y = 12 }, { x = -8, y = 14 }, { x = -7, y = 14 }, { x = -6, y = 15 }, { x = -5, y = 15 }, { x = -4, y = 15 }, { x = 4, y = 15 }, { x = 5, y = 15 }, { x = 7, y = 14 }, { x = 6, y = 15 }, { x = 8, y = 14 }, { x = -4, y = 16 }, { x = -3, y = 16 }, { x = -2, y = 16 }, { x = -1, y = 16 }, { x = 0, y = 16 }, { x = 1, y = 16 }, { x = 2, y = 16 }, { x = 3, y = 16 }, { x = 4, y = 16 } },
|
||||
[18] = { { x = -3, y = -17 }, { x = -4, y = -17 }, { x = -1, y = -17 }, { x = -2, y = -17 }, { x = 1, y = -17 }, { x = 0, y = -17 }, { x = 3, y = -17 }, { x = 2, y = -17 }, { x = 4, y = -17 }, { x = -9, y = -15 }, { x = -8, y = -15 }, { x = -7, y = -15 }, { x = -7, y = -16 }, { x = -6, y = -16 }, { x = -5, y = -16 }, { x = 5, y = -16 }, { x = 7, y = -15 }, { x = 7, y = -16 }, { x = 6, y = -16 }, { x = 9, y = -15 }, { x = 8, y = -15 }, { x = -11, y = -13 }, { x = -10, y = -14 }, { x = -9, y = -14 }, { x = 9, y = -14 }, { x = 11, y = -13 }, { x = 10, y = -14 }, { x = -13, y = -11 }, { x = -12, y = -12 }, { x = 13, y = -11 }, { x = 12, y = -12 }, { x = -15, y = -9 }, { x = -14, y = -10 }, { x = -14, y = -9 }, { x = 14, y = -10 }, { x = 14, y = -9 }, { x = 15, y = -9 }, { x = -15, y = -8 }, { x = -15, y = -7 }, { x = -16, y = -7 }, { x = 15, y = -8 }, { x = 15, y = -7 }, { x = 16, y = -7 }, { x = -16, y = -6 }, { x = -16, y = -5 }, { x = 16, y = -5 }, { x = 16, y = -6 }, { x = -17, y = -3 }, { x = -17, y = -4 }, { x = 17, y = -3 }, { x = 17, y = -4 }, { x = -17, y = -1 }, { x = -17, y = -2 }, { x = 17, y = -1 }, { x = 17, y = -2 }, { x = -17, y = 1 }, { x = -17, y = 0 }, { x = 17, y = 1 }, { x = 17, y = 0 }, { x = -17, y = 3 }, { x = -17, y = 2 }, { x = 17, y = 3 }, { x = 17, y = 2 }, { x = -17, y = 4 }, { x = -16, y = 5 }, { x = 16, y = 5 }, { x = 17, y = 4 }, { x = -15, y = 7 }, { x = -16, y = 7 }, { x = -16, y = 6 }, { x = 15, y = 7 }, { x = 16, y = 7 }, { x = 16, y = 6 }, { x = -15, y = 9 }, { x = -15, y = 8 }, { x = -14, y = 9 }, { x = 14, y = 9 }, { x = 15, y = 9 }, { x = 15, y = 8 }, { x = -14, y = 10 }, { x = -13, y = 11 }, { x = 13, y = 11 }, { x = 14, y = 10 }, { x = -12, y = 12 }, { x = -11, y = 13 }, { x = 11, y = 13 }, { x = 12, y = 12 }, { x = -10, y = 14 }, { x = -9, y = 14 }, { x = -9, y = 15 }, { x = -8, y = 15 }, { x = -7, y = 15 }, { x = 7, y = 15 }, { x = 9, y = 14 }, { x = 9, y = 15 }, { x = 8, y = 15 }, { x = 10, y = 14 }, { x = -7, y = 16 }, { x = -6, y = 16 }, { x = -5, y = 16 }, { x = -4, y = 17 }, { x = -3, y = 17 }, { x = -2, y = 17 }, { x = -1, y = 17 }, { x = 0, y = 17 }, { x = 1, y = 17 }, { x = 2, y = 17 }, { x = 3, y = 17 }, { x = 4, y = 17 }, { x = 5, y = 16 }, { x = 6, y = 16 }, { x = 7, y = 16 } },
|
||||
[19] = { { x = -7, y = -17 }, { x = -6, y = -17 }, { x = -5, y = -17 }, { x = -3, y = -18 }, { x = -4, y = -18 }, { x = -1, y = -18 }, { x = -2, y = -18 }, { x = 1, y = -18 }, { x = 0, y = -18 }, { x = 3, y = -18 }, { x = 2, y = -18 }, { x = 5, y = -17 }, { x = 4, y = -18 }, { x = 7, y = -17 }, { x = 6, y = -17 }, { x = -10, y = -15 }, { x = -9, y = -16 }, { x = -8, y = -16 }, { x = 9, y = -16 }, { x = 8, y = -16 }, { x = 10, y = -15 }, { x = -13, y = -13 }, { x = -11, y = -14 }, { x = -12, y = -14 }, { x = -12, y = -13 }, { x = 11, y = -14 }, { x = 13, y = -13 }, { x = 12, y = -13 }, { x = 12, y = -14 }, { x = -13, y = -12 }, { x = -14, y = -12 }, { x = -14, y = -11 }, { x = 13, y = -12 }, { x = 14, y = -11 }, { x = 14, y = -12 }, { x = -15, y = -10 }, { x = -16, y = -9 }, { x = 15, y = -10 }, { x = 16, y = -9 }, { x = -17, y = -7 }, { x = -16, y = -8 }, { x = 16, y = -8 }, { x = 17, y = -7 }, { x = -17, y = -5 }, { x = -17, y = -6 }, { x = 17, y = -6 }, { x = 17, y = -5 }, { x = -18, y = -3 }, { x = -18, y = -4 }, { x = 18, y = -4 }, { x = 18, y = -3 }, { x = -18, y = -1 }, { x = -18, y = -2 }, { x = 18, y = -2 }, { x = 18, y = -1 }, { x = -18, y = 1 }, { x = -18, y = 0 }, { x = 18, y = 0 }, { x = 18, y = 1 }, { x = -18, y = 3 }, { x = -18, y = 2 }, { x = 18, y = 2 }, { x = 18, y = 3 }, { x = -17, y = 5 }, { x = -18, y = 4 }, { x = 17, y = 5 }, { x = 18, y = 4 }, { x = -17, y = 7 }, { x = -17, y = 6 }, { x = 17, y = 7 }, { x = 17, y = 6 }, { x = -16, y = 9 }, { x = -16, y = 8 }, { x = 16, y = 9 }, { x = 16, y = 8 }, { x = -15, y = 10 }, { x = -14, y = 11 }, { x = 14, y = 11 }, { x = 15, y = 10 }, { x = -14, y = 12 }, { x = -13, y = 12 }, { x = -13, y = 13 }, { x = -12, y = 13 }, { x = 12, y = 13 }, { x = 13, y = 13 }, { x = 13, y = 12 }, { x = 14, y = 12 }, { x = -12, y = 14 }, { x = -11, y = 14 }, { x = -10, y = 15 }, { x = 10, y = 15 }, { x = 11, y = 14 }, { x = 12, y = 14 }, { x = -9, y = 16 }, { x = -7, y = 17 }, { x = -8, y = 16 }, { x = -5, y = 17 }, { x = -6, y = 17 }, { x = 5, y = 17 }, { x = 7, y = 17 }, { x = 6, y = 17 }, { x = 8, y = 16 }, { x = 9, y = 16 }, { x = -3, y = 18 }, { x = -4, y = 18 }, { x = -1, y = 18 }, { x = -2, y = 18 }, { x = 1, y = 18 }, { x = 0, y = 18 }, { x = 3, y = 18 }, { x = 2, y = 18 }, { x = 4, y = 18 } },
|
||||
[20] = { { x = -3, y = -19 }, { x = -4, y = -19 }, { x = -1, y = -19 }, { x = -2, y = -19 }, { x = 1, y = -19 }, { x = 0, y = -19 }, { x = 3, y = -19 }, { x = 2, y = -19 }, { x = 4, y = -19 }, { x = -9, y = -17 }, { x = -7, y = -18 }, { x = -8, y = -17 }, { x = -5, y = -18 }, { x = -6, y = -18 }, { x = 5, y = -18 }, { x = 7, y = -18 }, { x = 6, y = -18 }, { x = 9, y = -17 }, { x = 8, y = -17 }, { x = -11, y = -16 }, { x = -11, y = -15 }, { x = -12, y = -15 }, { x = -10, y = -16 }, { x = 11, y = -15 }, { x = 11, y = -16 }, { x = 10, y = -16 }, { x = 12, y = -15 }, { x = -13, y = -14 }, { x = -14, y = -13 }, { x = 13, y = -14 }, { x = 14, y = -13 }, { x = -15, y = -12 }, { x = -15, y = -11 }, { x = -16, y = -11 }, { x = 15, y = -11 }, { x = 15, y = -12 }, { x = 16, y = -11 }, { x = -17, y = -9 }, { x = -16, y = -10 }, { x = 16, y = -10 }, { x = 17, y = -9 }, { x = -17, y = -8 }, { x = -18, y = -7 }, { x = 17, y = -8 }, { x = 18, y = -7 }, { x = -18, y = -6 }, { x = -18, y = -5 }, { x = 18, y = -5 }, { x = 18, y = -6 }, { x = -19, y = -4 }, { x = -19, y = -3 }, { x = 19, y = -3 }, { x = 19, y = -4 }, { x = -19, y = -2 }, { x = -19, y = -1 }, { x = 19, y = -1 }, { x = 19, y = -2 }, { x = -19, y = 0 }, { x = -19, y = 1 }, { x = 19, y = 1 }, { x = 19, y = 0 }, { x = -19, y = 2 }, { x = -19, y = 3 }, { x = 19, y = 3 }, { x = 19, y = 2 }, { x = -19, y = 4 }, { x = -18, y = 5 }, { x = 18, y = 5 }, { x = 19, y = 4 }, { x = -18, y = 7 }, { x = -18, y = 6 }, { x = 18, y = 7 }, { x = 18, y = 6 }, { x = -17, y = 9 }, { x = -17, y = 8 }, { x = 17, y = 9 }, { x = 17, y = 8 }, { x = -16, y = 10 }, { x = -16, y = 11 }, { x = -15, y = 11 }, { x = 15, y = 11 }, { x = 16, y = 11 }, { x = 16, y = 10 }, { x = -15, y = 12 }, { x = -14, y = 13 }, { x = 14, y = 13 }, { x = 15, y = 12 }, { x = -13, y = 14 }, { x = -12, y = 15 }, { x = -11, y = 15 }, { x = 11, y = 15 }, { x = 12, y = 15 }, { x = 13, y = 14 }, { x = -11, y = 16 }, { x = -10, y = 16 }, { x = -9, y = 17 }, { x = -8, y = 17 }, { x = 9, y = 17 }, { x = 8, y = 17 }, { x = 10, y = 16 }, { x = 11, y = 16 }, { x = -7, y = 18 }, { x = -5, y = 18 }, { x = -6, y = 18 }, { x = -4, y = 19 }, { x = -3, y = 19 }, { x = -2, y = 19 }, { x = -1, y = 19 }, { x = 0, y = 19 }, { x = 1, y = 19 }, { x = 2, y = 19 }, { x = 3, y = 19 }, { x = 4, y = 19 }, { x = 5, y = 18 }, { x = 7, y = 18 }, { x = 6, y = 18 } },
|
||||
[21] = { { x = -7, y = -19 }, { x = -5, y = -19 }, { x = -6, y = -19 }, { x = -3, y = -20 }, { x = -4, y = -20 }, { x = -1, y = -20 }, { x = -2, y = -20 }, { x = 1, y = -20 }, { x = 0, y = -20 }, { x = 3, y = -20 }, { x = 2, y = -20 }, { x = 5, y = -19 }, { x = 4, y = -20 }, { x = 7, y = -19 }, { x = 6, y = -19 }, { x = -11, y = -17 }, { x = -10, y = -17 }, { x = -9, y = -18 }, { x = -8, y = -18 }, { x = 9, y = -18 }, { x = 8, y = -18 }, { x = 10, y = -17 }, { x = 11, y = -17 }, { x = -13, y = -15 }, { x = -14, y = -15 }, { x = -12, y = -16 }, { x = 13, y = -15 }, { x = 12, y = -16 }, { x = 14, y = -15 }, { x = -15, y = -14 }, { x = -15, y = -13 }, { x = -14, y = -14 }, { x = 15, y = -13 }, { x = 15, y = -14 }, { x = 14, y = -14 }, { x = -17, y = -11 }, { x = -16, y = -12 }, { x = 16, y = -12 }, { x = 17, y = -11 }, { x = -17, y = -10 }, { x = -18, y = -9 }, { x = 17, y = -10 }, { x = 18, y = -9 }, { x = -19, y = -7 }, { x = -18, y = -8 }, { x = 18, y = -8 }, { x = 19, y = -7 }, { x = -19, y = -6 }, { x = -19, y = -5 }, { x = 19, y = -6 }, { x = 19, y = -5 }, { x = -20, y = -4 }, { x = -20, y = -3 }, { x = 20, y = -3 }, { x = 20, y = -4 }, { x = -20, y = -2 }, { x = -20, y = -1 }, { x = 20, y = -1 }, { x = 20, y = -2 }, { x = -20, y = 0 }, { x = -20, y = 1 }, { x = 20, y = 1 }, { x = 20, y = 0 }, { x = -20, y = 2 }, { x = -20, y = 3 }, { x = 20, y = 3 }, { x = 20, y = 2 }, { x = -20, y = 4 }, { x = -19, y = 5 }, { x = 19, y = 5 }, { x = 20, y = 4 }, { x = -19, y = 7 }, { x = -19, y = 6 }, { x = 19, y = 7 }, { x = 19, y = 6 }, { x = -18, y = 9 }, { x = -18, y = 8 }, { x = 18, y = 9 }, { x = 18, y = 8 }, { x = -17, y = 11 }, { x = -17, y = 10 }, { x = 17, y = 11 }, { x = 17, y = 10 }, { x = -16, y = 12 }, { x = -15, y = 13 }, { x = 15, y = 13 }, { x = 16, y = 12 }, { x = -15, y = 14 }, { x = -14, y = 14 }, { x = -14, y = 15 }, { x = -13, y = 15 }, { x = 13, y = 15 }, { x = 14, y = 15 }, { x = 14, y = 14 }, { x = 15, y = 14 }, { x = -12, y = 16 }, { x = -11, y = 17 }, { x = -10, y = 17 }, { x = 11, y = 17 }, { x = 10, y = 17 }, { x = 12, y = 16 }, { x = -9, y = 18 }, { x = -8, y = 18 }, { x = -7, y = 19 }, { x = -5, y = 19 }, { x = -6, y = 19 }, { x = 5, y = 19 }, { x = 6, y = 19 }, { x = 7, y = 19 }, { x = 9, y = 18 }, { x = 8, y = 18 }, { x = -4, y = 20 }, { x = -3, y = 20 }, { x = -2, y = 20 }, { x = -1, y = 20 }, { x = 0, y = 20 }, { x = 1, y = 20 }, { x = 2, y = 20 }, { x = 3, y = 20 }, { x = 4, y = 20 } },
|
||||
[22] = { { x = -3, y = -21 }, { x = -4, y = -21 }, { x = -1, y = -21 }, { x = -2, y = -21 }, { x = 1, y = -21 }, { x = 0, y = -21 }, { x = 3, y = -21 }, { x = 2, y = -21 }, { x = 4, y = -21 }, { x = -10, y = -19 }, { x = -9, y = -19 }, { x = -8, y = -19 }, { x = -7, y = -20 }, { x = -5, y = -20 }, { x = -6, y = -20 }, { x = 5, y = -20 }, { x = 7, y = -20 }, { x = 6, y = -20 }, { x = 9, y = -19 }, { x = 8, y = -19 }, { x = 10, y = -19 }, { x = -13, y = -17 }, { x = -12, y = -17 }, { x = -11, y = -18 }, { x = -10, y = -18 }, { x = 11, y = -18 }, { x = 10, y = -18 }, { x = 13, y = -17 }, { x = 12, y = -17 }, { x = -15, y = -15 }, { x = -13, y = -16 }, { x = -14, y = -16 }, { x = 13, y = -16 }, { x = 15, y = -15 }, { x = 14, y = -16 }, { x = -17, y = -13 }, { x = -16, y = -14 }, { x = -16, y = -13 }, { x = 17, y = -13 }, { x = 16, y = -13 }, { x = 16, y = -14 }, { x = -17, y = -12 }, { x = -18, y = -11 }, { x = 17, y = -12 }, { x = 18, y = -11 }, { x = -19, y = -10 }, { x = -19, y = -9 }, { x = -18, y = -10 }, { x = 18, y = -10 }, { x = 19, y = -10 }, { x = 19, y = -9 }, { x = -19, y = -8 }, { x = -20, y = -7 }, { x = 19, y = -8 }, { x = 20, y = -7 }, { x = -20, y = -6 }, { x = -20, y = -5 }, { x = 20, y = -6 }, { x = 20, y = -5 }, { x = -21, y = -4 }, { x = -21, y = -3 }, { x = 21, y = -3 }, { x = 21, y = -4 }, { x = -21, y = -2 }, { x = -21, y = -1 }, { x = 21, y = -1 }, { x = 21, y = -2 }, { x = -21, y = 0 }, { x = -21, y = 1 }, { x = 21, y = 1 }, { x = 21, y = 0 }, { x = -21, y = 2 }, { x = -21, y = 3 }, { x = 21, y = 3 }, { x = 21, y = 2 }, { x = -21, y = 4 }, { x = -20, y = 5 }, { x = 20, y = 5 }, { x = 21, y = 4 }, { x = -20, y = 7 }, { x = -20, y = 6 }, { x = 20, y = 7 }, { x = 20, y = 6 }, { x = -19, y = 9 }, { x = -19, y = 8 }, { x = 19, y = 9 }, { x = 19, y = 8 }, { x = -19, y = 10 }, { x = -18, y = 11 }, { x = -18, y = 10 }, { x = 18, y = 11 }, { x = 18, y = 10 }, { x = 19, y = 10 }, { x = -17, y = 13 }, { x = -17, y = 12 }, { x = -16, y = 13 }, { x = 16, y = 13 }, { x = 17, y = 13 }, { x = 17, y = 12 }, { x = -16, y = 14 }, { x = -15, y = 15 }, { x = 15, y = 15 }, { x = 16, y = 14 }, { x = -14, y = 16 }, { x = -13, y = 16 }, { x = -13, y = 17 }, { x = -12, y = 17 }, { x = 13, y = 16 }, { x = 13, y = 17 }, { x = 12, y = 17 }, { x = 14, y = 16 }, { x = -11, y = 18 }, { x = -10, y = 18 }, { x = -10, y = 19 }, { x = -9, y = 19 }, { x = -8, y = 19 }, { x = 9, y = 19 }, { x = 8, y = 19 }, { x = 11, y = 18 }, { x = 10, y = 18 }, { x = 10, y = 19 }, { x = -7, y = 20 }, { x = -6, y = 20 }, { x = -5, y = 20 }, { x = -3, y = 21 }, { x = -4, y = 21 }, { x = -1, y = 21 }, { x = -2, y = 21 }, { x = 1, y = 21 }, { x = 0, y = 21 }, { x = 3, y = 21 }, { x = 2, y = 21 }, { x = 4, y = 21 }, { x = 5, y = 20 }, { x = 7, y = 20 }, { x = 6, y = 20 } },
|
||||
[23] = { { x = -8, y = -21 }, { x = -7, y = -21 }, { x = -6, y = -21 }, { x = -5, y = -21 }, { x = -3, y = -22 }, { x = -4, y = -22 }, { x = -1, y = -22 }, { x = -2, y = -22 }, { x = 1, y = -22 }, { x = 0, y = -22 }, { x = 3, y = -22 }, { x = 2, y = -22 }, { x = 5, y = -21 }, { x = 4, y = -22 }, { x = 7, y = -21 }, { x = 6, y = -21 }, { x = 8, y = -21 }, { x = -12, y = -19 }, { x = -11, y = -19 }, { x = -10, y = -20 }, { x = -9, y = -20 }, { x = -8, y = -20 }, { x = 9, y = -20 }, { x = 8, y = -20 }, { x = 11, y = -19 }, { x = 10, y = -20 }, { x = 12, y = -19 }, { x = -14, y = -17 }, { x = -13, y = -18 }, { x = -12, y = -18 }, { x = 13, y = -18 }, { x = 12, y = -18 }, { x = 14, y = -17 }, { x = -15, y = -16 }, { x = -16, y = -15 }, { x = 15, y = -16 }, { x = 16, y = -15 }, { x = -17, y = -14 }, { x = -18, y = -13 }, { x = 17, y = -14 }, { x = 18, y = -13 }, { x = -19, y = -12 }, { x = -19, y = -11 }, { x = -18, y = -12 }, { x = 18, y = -12 }, { x = 19, y = -12 }, { x = 19, y = -11 }, { x = -20, y = -10 }, { x = -20, y = -9 }, { x = 20, y = -10 }, { x = 20, y = -9 }, { x = -21, y = -8 }, { x = -21, y = -7 }, { x = -20, y = -8 }, { x = 20, y = -8 }, { x = 21, y = -8 }, { x = 21, y = -7 }, { x = -21, y = -6 }, { x = -21, y = -5 }, { x = 21, y = -6 }, { x = 21, y = -5 }, { x = -22, y = -4 }, { x = -22, y = -3 }, { x = 22, y = -3 }, { x = 22, y = -4 }, { x = -22, y = -2 }, { x = -22, y = -1 }, { x = 22, y = -1 }, { x = 22, y = -2 }, { x = -22, y = 0 }, { x = -22, y = 1 }, { x = 22, y = 1 }, { x = 22, y = 0 }, { x = -22, y = 2 }, { x = -22, y = 3 }, { x = 22, y = 3 }, { x = 22, y = 2 }, { x = -22, y = 4 }, { x = -21, y = 5 }, { x = 21, y = 5 }, { x = 22, y = 4 }, { x = -21, y = 7 }, { x = -21, y = 6 }, { x = 21, y = 7 }, { x = 21, y = 6 }, { x = -21, y = 8 }, { x = -20, y = 9 }, { x = -20, y = 8 }, { x = 20, y = 8 }, { x = 20, y = 9 }, { x = 21, y = 8 }, { x = -19, y = 11 }, { x = -20, y = 10 }, { x = 19, y = 11 }, { x = 20, y = 10 }, { x = -19, y = 12 }, { x = -18, y = 13 }, { x = -18, y = 12 }, { x = 18, y = 13 }, { x = 18, y = 12 }, { x = 19, y = 12 }, { x = -17, y = 14 }, { x = -16, y = 15 }, { x = 16, y = 15 }, { x = 17, y = 14 }, { x = -15, y = 16 }, { x = -14, y = 17 }, { x = 14, y = 17 }, { x = 15, y = 16 }, { x = -13, y = 18 }, { x = -12, y = 18 }, { x = -12, y = 19 }, { x = -11, y = 19 }, { x = 11, y = 19 }, { x = 13, y = 18 }, { x = 12, y = 18 }, { x = 12, y = 19 }, { x = -10, y = 20 }, { x = -9, y = 20 }, { x = -8, y = 20 }, { x = -8, y = 21 }, { x = -7, y = 21 }, { x = -6, y = 21 }, { x = -5, y = 21 }, { x = 5, y = 21 }, { x = 7, y = 21 }, { x = 6, y = 21 }, { x = 8, y = 20 }, { x = 9, y = 20 }, { x = 8, y = 21 }, { x = 10, y = 20 }, { x = -4, y = 22 }, { x = -3, y = 22 }, { x = -2, y = 22 }, { x = -1, y = 22 }, { x = 0, y = 22 }, { x = 1, y = 22 }, { x = 2, y = 22 }, { x = 3, y = 22 }, { x = 4, y = 22 } }
|
||||
}
|
||||
|
||||
local function process_explosion_tile(pos, explosion_index, current_radius)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = game.surfaces[ffatable.explosion_schedule[explosion_index].surface]
|
||||
local target_entities = surface.find_entities_filtered({ area = { { pos.x - 0.5, pos.y - 0.5 }, { pos.x + 0.499, pos.y + 0.499 } } })
|
||||
local explosion_animation = "explosion"
|
||||
|
||||
local tile = surface.get_tile(pos)
|
||||
if tile.name == "out-of-map" then
|
||||
if ffatable.explosion_schedule[explosion_index].damage_remaining >= out_of_map_tile_health then
|
||||
explosion_animation = "big-explosion"
|
||||
surface.set_tiles({ { name = "dirt-5", position = pos } }, true)
|
||||
end
|
||||
ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - out_of_map_tile_health
|
||||
else
|
||||
local decay_explosion = true
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.health then
|
||||
decay_explosion = false
|
||||
end
|
||||
end
|
||||
if decay_explosion then ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - empty_tile_damage_decay end
|
||||
end
|
||||
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.valid then
|
||||
if entity.health then
|
||||
if entity.health < ffatable.explosion_schedule[explosion_index].damage_remaining then
|
||||
explosion_animation = "big-explosion"
|
||||
if entity.health > 500 then explosion_animation = "big-artillery-explosion" end
|
||||
ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - entity.health
|
||||
if entity.name ~= "character" then
|
||||
entity.damage(2097152, "player", "explosion")
|
||||
else
|
||||
entity.die("player")
|
||||
end
|
||||
else
|
||||
entity.damage(ffatable.explosion_schedule[explosion_index].damage_remaining, "player", "explosion")
|
||||
if entity.valid then
|
||||
ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - entity.health
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.explosion_schedule[explosion_index].damage_remaining > 5000 and current_radius < 2 then
|
||||
if math_random(1, 2) == 1 then
|
||||
explosion_animation = "big-explosion"
|
||||
else
|
||||
explosion_animation = "big-artillery-explosion"
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity({ name = explosion_animation, position = pos })
|
||||
Pollution.explosion(pos, surface, explosion_animation)
|
||||
|
||||
if ffatable.explosion_schedule[explosion_index].damage_remaining <= 0 then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function volatility(inventory)
|
||||
local result = 0
|
||||
for item, v in pairs(explosive_items) do
|
||||
local c = inventory.get_item_count(item)
|
||||
result = result + (c * v)
|
||||
end
|
||||
return math_min(max_volatility, result)
|
||||
end
|
||||
|
||||
local function create_explosion_schedule(entity)
|
||||
local ffatable = Table.get_table()
|
||||
local inventory = defines.inventory.chest
|
||||
if entity.type == "car" then inventory = defines.inventory.car_trunk end
|
||||
local i = entity.get_inventory(inventory)
|
||||
local explosives_amount = volatility(i)
|
||||
if explosives_amount < 1 then return end
|
||||
local center_position = entity.position
|
||||
|
||||
if not ffatable.explosion_schedule then ffatable.explosion_schedule = {} end
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule + 1] = {}
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule].surface = entity.surface.name
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule].damage_remaining = damage_per_explosive * explosives_amount
|
||||
|
||||
for current_radius = 1, 23, 1 do
|
||||
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule][current_radius] = {}
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule][current_radius].trigger_tick = game.tick + (current_radius * 8)
|
||||
|
||||
local circle_coords = circle_coordinates[current_radius]
|
||||
|
||||
for index, tile_position in pairs(circle_coords) do
|
||||
local pos = { x = center_position.x + tile_position.x, y = center_position.y + tile_position.y }
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule][current_radius][index] = { x = pos.x, y = pos.y }
|
||||
end
|
||||
|
||||
end
|
||||
entity.die("player")
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if not entity.health then return end
|
||||
if entity.health > entity.prototype.max_health * 0.75 then return end
|
||||
|
||||
if entity.type == "container" or entity.type == "logistic-container" then
|
||||
if math_random(1, 3) == 1 or entity.health <= 0 then
|
||||
create_explosion_schedule(event.entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
if entity.type == "cargo-wagon" or entity.type == "car" then
|
||||
if entity.health <= 0 then
|
||||
create_explosion_schedule(entity)
|
||||
return
|
||||
end
|
||||
if entity.health < 150 and math_random(1, 3) == 1 then
|
||||
create_explosion_schedule(entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick(event)
|
||||
local ffatable = Table.get_table()
|
||||
local tick = event.tick
|
||||
if ffatable.explosion_schedule then
|
||||
local explosion_schedule_is_alive = false
|
||||
for explosion_index = 1, #ffatable.explosion_schedule, 1 do
|
||||
if #ffatable.explosion_schedule[explosion_index] > 0 then
|
||||
explosion_schedule_is_alive = true
|
||||
for radius = 1, #ffatable.explosion_schedule[explosion_index], 1 do
|
||||
if ffatable.explosion_schedule[explosion_index][radius].trigger_tick == tick then
|
||||
for tile_index = 1, #ffatable.explosion_schedule[explosion_index][radius], 1 do
|
||||
local continue_explosion = process_explosion_tile(ffatable.explosion_schedule[explosion_index][radius][tile_index], explosion_index, radius)
|
||||
if not continue_explosion then
|
||||
ffatable.explosion_schedule[explosion_index] = {}
|
||||
break
|
||||
end
|
||||
end
|
||||
if radius == #ffatable.explosion_schedule[explosion_index] then ffatable.explosion_schedule[explosion_index] = {} end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not explosion_schedule_is_alive then ffatable.explosion_schedule = nil end
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.explosion_schedule = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
67
modules/scrap_towny_ffa/fish_reproduction.lua
Normal file
67
modules/scrap_towny_ffa/fish_reproduction.lua
Normal file
@ -0,0 +1,67 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
function Public.reproduce()
|
||||
local ffatable = Table.get_table()
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local surface = town_center.market.surface
|
||||
local position = town_center.market.position
|
||||
local fishes = surface.find_entities_filtered({ name = "fish", position = position, radius = 27 })
|
||||
if #fishes == 0 then return end
|
||||
if #fishes >= 100 then return end
|
||||
-- pick a random fish
|
||||
local t = math_random(1, #fishes)
|
||||
local fish = fishes[t]
|
||||
-- test against all other fishes
|
||||
local guppy = false
|
||||
for i, f in pairs(fishes) do
|
||||
if i ~= t then
|
||||
if math_floor(fish.position.x) == math_floor(f.position.x) and math_floor(fish.position.y) == math_floor(f.position.y) then
|
||||
guppy = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if guppy == true then
|
||||
--log("fish spawn {" .. fish.position.x .. "," .. fish.position.y .. "}")
|
||||
surface.create_entity({ name = "water-splash", position = fish.position })
|
||||
surface.create_entity({ name = "fish", position = fish.position })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_used_capsule(event)
|
||||
if event.item.name ~= "raw-fish" then return end
|
||||
local player = game.players[event.player_index]
|
||||
local surface = player.surface
|
||||
local position = event.position
|
||||
local tile = player.surface.get_tile(position.x, position.y)
|
||||
|
||||
-- return back some of the health if not healthy
|
||||
if player.character.health < 250 then
|
||||
player.surface.play_sound({ path = "utility/armor_insert", position = player.position, volume_modifier = 1 })
|
||||
return
|
||||
end
|
||||
|
||||
-- if using fish on water
|
||||
if tile.name == "water" and tile.name == "water-green" and tile.name == "deepwater" and tile.name == "deepwater-green" then
|
||||
-- get the count of fish in the water nearby and test if can be repopulated
|
||||
local fishes = surface.find_entities_filtered({ name = "fish", position = position, radius = 27 })
|
||||
if #fishes < 12 then
|
||||
surface.create_entity({ name = "water-splash", position = position })
|
||||
surface.create_entity({ name = "fish", position = position })
|
||||
surface.play_sound({ path = "utility/achievement_unlocked", position = player.position, volume_modifier = 1 })
|
||||
return
|
||||
end
|
||||
end
|
||||
-- otherwise return the fish and make no sound
|
||||
player.insert({ name = "raw-fish", count = 1 })
|
||||
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
|
||||
|
||||
return Public
|
194
modules/scrap_towny_ffa/fluids_are_explosive.lua
Normal file
194
modules/scrap_towny_ffa/fluids_are_explosive.lua
Normal file
@ -0,0 +1,194 @@
|
||||
--This will add a new game mechanic so that containers with certain fluids explode when they get damaged or are destroyed.
|
||||
--Made by MewMew
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Pollution = require "modules.scrap_towny_ffa.pollution"
|
||||
|
||||
local empty_tile_damage_decay = 50
|
||||
local out_of_map_tile_health = 1500
|
||||
|
||||
local container_types = {
|
||||
["storage-tank"] = true,
|
||||
["pipe"] = true,
|
||||
["pipe-to-ground"] = true
|
||||
}
|
||||
|
||||
local fluid_damages = { -- Fluid Whitelist -- add fluid and a damage value to enable
|
||||
["lubricant"] = 5,
|
||||
["crude-oil"] = 5,
|
||||
["gasoline"] = 8,
|
||||
["heavy-oil"] = 6,
|
||||
["light-oil"] = 7,
|
||||
["petroleum-gas"] = 8,
|
||||
}
|
||||
|
||||
local function shuffle(tbl)
|
||||
local size = #tbl
|
||||
for i = size, 1, -1 do
|
||||
local rand = math_random(size)
|
||||
tbl[i], tbl[rand] = tbl[rand], tbl[i]
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function process_explosion_tile(pos, explosion_index, current_radius)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = game.surfaces[ffatable.fluid_explosion_schedule[explosion_index].surface]
|
||||
local target_entities = surface.find_entities_filtered({ area = { { pos.x - 0.5, pos.y - 0.5 }, { pos.x + 0.499, pos.y + 0.499 } } })
|
||||
local explosion_animation = "explosion"
|
||||
|
||||
local tile = surface.get_tile(pos)
|
||||
if tile.name == "out-of-map" then
|
||||
if ffatable.fluid_explosion_schedule[explosion_index].damage_remaining >= out_of_map_tile_health then
|
||||
explosion_animation = "big-explosion"
|
||||
surface.set_tiles({ { name = "dirt-5", position = pos } }, true)
|
||||
end
|
||||
ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = ffatable.fluid_explosion_schedule[explosion_index].damage_remaining - out_of_map_tile_health
|
||||
else
|
||||
local decay_explosion = true
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.health then
|
||||
decay_explosion = false
|
||||
end
|
||||
end
|
||||
if decay_explosion then ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = ffatable.fluid_explosion_schedule[explosion_index].damage_remaining - empty_tile_damage_decay end
|
||||
end
|
||||
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.valid then
|
||||
if entity.health then
|
||||
if entity.health <= ffatable.fluid_explosion_schedule[explosion_index].damage_remaining then
|
||||
explosion_animation = "big-explosion"
|
||||
if entity.health > 500 then explosion_animation = "big-artillery-explosion" end
|
||||
ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = ffatable.fluid_explosion_schedule[explosion_index].damage_remaining - entity.health
|
||||
if entity.name ~= "character" then
|
||||
entity.damage(2097152, "player", "explosion")
|
||||
else
|
||||
entity.die("player")
|
||||
end
|
||||
else
|
||||
entity.damage(ffatable.fluid_explosion_schedule[explosion_index].damage_remaining, "player", "explosion")
|
||||
ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.fluid_explosion_schedule[explosion_index].damage_remaining > 5000 and current_radius < 2 then
|
||||
if math_random(1, 2) == 1 then
|
||||
explosion_animation = "big-explosion"
|
||||
else
|
||||
explosion_animation = "big-artillery-explosion"
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity({ name = explosion_animation, position = pos })
|
||||
Pollution.explosion(pos, surface, explosion_animation)
|
||||
|
||||
if ffatable.fluid_explosion_schedule[explosion_index].damage_remaining <= 0 then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function create_explosion_schedule(entity)
|
||||
local ffatable = Table.get_table()
|
||||
local explosives_amount = math_floor(entity.fluidbox[1].amount)
|
||||
|
||||
if explosives_amount < 1 then return end
|
||||
local center_position = entity.position
|
||||
|
||||
if not ffatable.fluid_explosion_schedule then ffatable.fluid_explosion_schedule = {} end
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule + 1] = {}
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule].surface = entity.surface.name
|
||||
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule].damage_remaining = fluid_damages[entity.fluidbox[1].name] * explosives_amount
|
||||
|
||||
local circle_coordinates = {
|
||||
[1] = { { x = 0, y = 0 } },
|
||||
[2] = { { x = -1, y = -1 }, { x = 1, y = -1 }, { x = 0, y = -1 }, { x = -1, y = 0 }, { x = -1, y = 1 }, { x = 0, y = 1 }, { x = 1, y = 1 }, { x = 1, y = 0 } },
|
||||
[3] = { { x = -2, y = -1 }, { x = -1, y = -2 }, { x = 1, y = -2 }, { x = 0, y = -2 }, { x = 2, y = -1 }, { x = -2, y = 1 }, { x = -2, y = 0 }, { x = 2, y = 1 }, { x = 2, y = 0 }, { x = -1, y = 2 }, { x = 1, y = 2 }, { x = 0, y = 2 } },
|
||||
[4] = { { x = -1, y = -3 }, { x = 1, y = -3 }, { x = 0, y = -3 }, { x = -3, y = -1 }, { x = -2, y = -2 }, { x = 3, y = -1 }, { x = 2, y = -2 }, { x = -3, y = 0 }, { x = -3, y = 1 }, { x = 3, y = 1 }, { x = 3, y = 0 }, { x = -2, y = 2 }, { x = -1, y = 3 }, { x = 0, y = 3 }, { x = 1, y = 3 }, { x = 2, y = 2 } },
|
||||
[5] = { { x = -3, y = -3 }, { x = -2, y = -3 }, { x = -1, y = -4 }, { x = -2, y = -4 }, { x = 1, y = -4 }, { x = 0, y = -4 }, { x = 2, y = -3 }, { x = 3, y = -3 }, { x = 2, y = -4 }, { x = -3, y = -2 }, { x = -4, y = -1 }, { x = -4, y = -2 }, { x = 3, y = -2 }, { x = 4, y = -1 }, { x = 4, y = -2 }, { x = -4, y = 1 }, { x = -4, y = 0 }, { x = 4, y = 1 }, { x = 4, y = 0 }, { x = -3, y = 3 }, { x = -3, y = 2 }, { x = -4, y = 2 }, { x = -2, y = 3 }, { x = 2, y = 3 }, { x = 3, y = 3 }, { x = 3, y = 2 }, { x = 4, y = 2 }, { x = -2, y = 4 }, { x = -1, y = 4 }, { x = 0, y = 4 }, { x = 1, y = 4 }, { x = 2, y = 4 } },
|
||||
[6] = { { x = -1, y = -5 }, { x = -2, y = -5 }, { x = 1, y = -5 }, { x = 0, y = -5 }, { x = 2, y = -5 }, { x = -3, y = -4 }, { x = -4, y = -3 }, { x = 3, y = -4 }, { x = 4, y = -3 }, { x = -5, y = -1 }, { x = -5, y = -2 }, { x = 5, y = -1 }, { x = 5, y = -2 }, { x = -5, y = 1 }, { x = -5, y = 0 }, { x = 5, y = 1 }, { x = 5, y = 0 }, { x = -5, y = 2 }, { x = -4, y = 3 }, { x = 4, y = 3 }, { x = 5, y = 2 }, { x = -3, y = 4 }, { x = -2, y = 5 }, { x = -1, y = 5 }, { x = 0, y = 5 }, { x = 1, y = 5 }, { x = 3, y = 4 }, { x = 2, y = 5 } },
|
||||
[7] = { { x = -4, y = -5 }, { x = -3, y = -5 }, { x = -2, y = -6 }, { x = -1, y = -6 }, { x = 0, y = -6 }, { x = 1, y = -6 }, { x = 3, y = -5 }, { x = 2, y = -6 }, { x = 4, y = -5 }, { x = -5, y = -4 }, { x = -5, y = -3 }, { x = -4, y = -4 }, { x = 4, y = -4 }, { x = 5, y = -4 }, { x = 5, y = -3 }, { x = -6, y = -1 }, { x = -6, y = -2 }, { x = 6, y = -1 }, { x = 6, y = -2 }, { x = -6, y = 1 }, { x = -6, y = 0 }, { x = 6, y = 1 }, { x = 6, y = 0 }, { x = -5, y = 3 }, { x = -6, y = 2 }, { x = 5, y = 3 }, { x = 6, y = 2 }, { x = -5, y = 4 }, { x = -4, y = 4 }, { x = -4, y = 5 }, { x = -3, y = 5 }, { x = 3, y = 5 }, { x = 4, y = 4 }, { x = 5, y = 4 }, { x = 4, y = 5 }, { x = -1, y = 6 }, { x = -2, y = 6 }, { x = 1, y = 6 }, { x = 0, y = 6 }, { x = 2, y = 6 } },
|
||||
[8] = { { x = -1, y = -7 }, { x = -2, y = -7 }, { x = 1, y = -7 }, { x = 0, y = -7 }, { x = 2, y = -7 }, { x = -5, y = -5 }, { x = -4, y = -6 }, { x = -3, y = -6 }, { x = 3, y = -6 }, { x = 4, y = -6 }, { x = 5, y = -5 }, { x = -6, y = -3 }, { x = -6, y = -4 }, { x = 6, y = -4 }, { x = 6, y = -3 }, { x = -7, y = -1 }, { x = -7, y = -2 }, { x = 7, y = -1 }, { x = 7, y = -2 }, { x = -7, y = 1 }, { x = -7, y = 0 }, { x = 7, y = 1 }, { x = 7, y = 0 }, { x = -7, y = 2 }, { x = -6, y = 3 }, { x = 6, y = 3 }, { x = 7, y = 2 }, { x = -5, y = 5 }, { x = -6, y = 4 }, { x = 5, y = 5 }, { x = 6, y = 4 }, { x = -3, y = 6 }, { x = -4, y = 6 }, { x = -2, y = 7 }, { x = -1, y = 7 }, { x = 0, y = 7 }, { x = 1, y = 7 }, { x = 3, y = 6 }, { x = 2, y = 7 }, { x = 4, y = 6 } },
|
||||
[9] = { { x = -4, y = -7 }, { x = -3, y = -7 }, { x = -2, y = -8 }, { x = -1, y = -8 }, { x = 0, y = -8 }, { x = 1, y = -8 }, { x = 3, y = -7 }, { x = 2, y = -8 }, { x = 4, y = -7 }, { x = -5, y = -6 }, { x = -6, y = -6 }, { x = -6, y = -5 }, { x = 5, y = -6 }, { x = 6, y = -5 }, { x = 6, y = -6 }, { x = -7, y = -4 }, { x = -7, y = -3 }, { x = 7, y = -4 }, { x = 7, y = -3 }, { x = -8, y = -2 }, { x = -8, y = -1 }, { x = 8, y = -1 }, { x = 8, y = -2 }, { x = -8, y = 0 }, { x = -8, y = 1 }, { x = 8, y = 1 }, { x = 8, y = 0 }, { x = -7, y = 3 }, { x = -8, y = 2 }, { x = 7, y = 3 }, { x = 8, y = 2 }, { x = -7, y = 4 }, { x = -6, y = 5 }, { x = 6, y = 5 }, { x = 7, y = 4 }, { x = -5, y = 6 }, { x = -6, y = 6 }, { x = -4, y = 7 }, { x = -3, y = 7 }, { x = 3, y = 7 }, { x = 5, y = 6 }, { x = 4, y = 7 }, { x = 6, y = 6 }, { x = -2, y = 8 }, { x = -1, y = 8 }, { x = 0, y = 8 }, { x = 1, y = 8 }, { x = 2, y = 8 } },
|
||||
[10] = { { x = -3, y = -9 }, { x = -1, y = -9 }, { x = -2, y = -9 }, { x = 1, y = -9 }, { x = 0, y = -9 }, { x = 3, y = -9 }, { x = 2, y = -9 }, { x = -5, y = -7 }, { x = -6, y = -7 }, { x = -5, y = -8 }, { x = -4, y = -8 }, { x = -3, y = -8 }, { x = 3, y = -8 }, { x = 5, y = -7 }, { x = 5, y = -8 }, { x = 4, y = -8 }, { x = 6, y = -7 }, { x = -7, y = -5 }, { x = -7, y = -6 }, { x = -8, y = -5 }, { x = 7, y = -5 }, { x = 7, y = -6 }, { x = 8, y = -5 }, { x = -9, y = -3 }, { x = -8, y = -4 }, { x = -8, y = -3 }, { x = 8, y = -4 }, { x = 8, y = -3 }, { x = 9, y = -3 }, { x = -9, y = -1 }, { x = -9, y = -2 }, { x = 9, y = -1 }, { x = 9, y = -2 }, { x = -9, y = 1 }, { x = -9, y = 0 }, { x = 9, y = 1 }, { x = 9, y = 0 }, { x = -9, y = 3 }, { x = -9, y = 2 }, { x = -8, y = 3 }, { x = 8, y = 3 }, { x = 9, y = 3 }, { x = 9, y = 2 }, { x = -7, y = 5 }, { x = -8, y = 5 }, { x = -8, y = 4 }, { x = 7, y = 5 }, { x = 8, y = 5 }, { x = 8, y = 4 }, { x = -7, y = 6 }, { x = -6, y = 7 }, { x = -5, y = 7 }, { x = 5, y = 7 }, { x = 7, y = 6 }, { x = 6, y = 7 }, { x = -5, y = 8 }, { x = -4, y = 8 }, { x = -3, y = 8 }, { x = -3, y = 9 }, { x = -2, y = 9 }, { x = -1, y = 9 }, { x = 0, y = 9 }, { x = 1, y = 9 }, { x = 3, y = 8 }, { x = 2, y = 9 }, { x = 3, y = 9 }, { x = 5, y = 8 }, { x = 4, y = 8 } },
|
||||
[11] = { { x = -5, y = -9 }, { x = -4, y = -9 }, { x = -3, y = -10 }, { x = -1, y = -10 }, { x = -2, y = -10 }, { x = 1, y = -10 }, { x = 0, y = -10 }, { x = 3, y = -10 }, { x = 2, y = -10 }, { x = 5, y = -9 }, { x = 4, y = -9 }, { x = -7, y = -7 }, { x = -6, y = -8 }, { x = 7, y = -7 }, { x = 6, y = -8 }, { x = -9, y = -5 }, { x = -8, y = -6 }, { x = 9, y = -5 }, { x = 8, y = -6 }, { x = -9, y = -4 }, { x = -10, y = -3 }, { x = 9, y = -4 }, { x = 10, y = -3 }, { x = -10, y = -2 }, { x = -10, y = -1 }, { x = 10, y = -1 }, { x = 10, y = -2 }, { x = -10, y = 0 }, { x = -10, y = 1 }, { x = 10, y = 1 }, { x = 10, y = 0 }, { x = -10, y = 2 }, { x = -10, y = 3 }, { x = 10, y = 3 }, { x = 10, y = 2 }, { x = -9, y = 4 }, { x = -9, y = 5 }, { x = 9, y = 5 }, { x = 9, y = 4 }, { x = -8, y = 6 }, { x = -7, y = 7 }, { x = 7, y = 7 }, { x = 8, y = 6 }, { x = -6, y = 8 }, { x = -5, y = 9 }, { x = -4, y = 9 }, { x = 4, y = 9 }, { x = 5, y = 9 }, { x = 6, y = 8 }, { x = -3, y = 10 }, { x = -2, y = 10 }, { x = -1, y = 10 }, { x = 0, y = 10 }, { x = 1, y = 10 }, { x = 2, y = 10 }, { x = 3, y = 10 } },
|
||||
[12] = { { x = -3, y = -11 }, { x = -2, y = -11 }, { x = -1, y = -11 }, { x = 0, y = -11 }, { x = 1, y = -11 }, { x = 2, y = -11 }, { x = 3, y = -11 }, { x = -7, y = -9 }, { x = -6, y = -9 }, { x = -5, y = -10 }, { x = -4, y = -10 }, { x = 5, y = -10 }, { x = 4, y = -10 }, { x = 7, y = -9 }, { x = 6, y = -9 }, { x = -9, y = -7 }, { x = -7, y = -8 }, { x = -8, y = -8 }, { x = -8, y = -7 }, { x = 7, y = -8 }, { x = 8, y = -7 }, { x = 8, y = -8 }, { x = 9, y = -7 }, { x = -9, y = -6 }, { x = -10, y = -5 }, { x = 9, y = -6 }, { x = 10, y = -5 }, { x = -11, y = -3 }, { x = -10, y = -4 }, { x = 10, y = -4 }, { x = 11, y = -3 }, { x = -11, y = -2 }, { x = -11, y = -1 }, { x = 11, y = -1 }, { x = 11, y = -2 }, { x = -11, y = 0 }, { x = -11, y = 1 }, { x = 11, y = 1 }, { x = 11, y = 0 }, { x = -11, y = 2 }, { x = -11, y = 3 }, { x = 11, y = 3 }, { x = 11, y = 2 }, { x = -10, y = 5 }, { x = -10, y = 4 }, { x = 10, y = 5 }, { x = 10, y = 4 }, { x = -9, y = 7 }, { x = -9, y = 6 }, { x = -8, y = 7 }, { x = 8, y = 7 }, { x = 9, y = 7 }, { x = 9, y = 6 }, { x = -8, y = 8 }, { x = -7, y = 8 }, { x = -7, y = 9 }, { x = -6, y = 9 }, { x = 7, y = 8 }, { x = 7, y = 9 }, { x = 6, y = 9 }, { x = 8, y = 8 }, { x = -5, y = 10 }, { x = -4, y = 10 }, { x = -3, y = 11 }, { x = -2, y = 11 }, { x = -1, y = 11 }, { x = 0, y = 11 }, { x = 1, y = 11 }, { x = 2, y = 11 }, { x = 3, y = 11 }, { x = 4, y = 10 }, { x = 5, y = 10 } },
|
||||
[13] = { { x = -5, y = -11 }, { x = -4, y = -11 }, { x = -3, y = -12 }, { x = -1, y = -12 }, { x = -2, y = -12 }, { x = 1, y = -12 }, { x = 0, y = -12 }, { x = 3, y = -12 }, { x = 2, y = -12 }, { x = 4, y = -11 }, { x = 5, y = -11 }, { x = -8, y = -9 }, { x = -7, y = -10 }, { x = -6, y = -10 }, { x = 6, y = -10 }, { x = 7, y = -10 }, { x = 8, y = -9 }, { x = -10, y = -7 }, { x = -9, y = -8 }, { x = 9, y = -8 }, { x = 10, y = -7 }, { x = -11, y = -5 }, { x = -10, y = -6 }, { x = 10, y = -6 }, { x = 11, y = -5 }, { x = -11, y = -4 }, { x = -12, y = -3 }, { x = 11, y = -4 }, { x = 12, y = -3 }, { x = -12, y = -1 }, { x = -12, y = -2 }, { x = 12, y = -1 }, { x = 12, y = -2 }, { x = -12, y = 1 }, { x = -12, y = 0 }, { x = 12, y = 1 }, { x = 12, y = 0 }, { x = -12, y = 3 }, { x = -12, y = 2 }, { x = 12, y = 3 }, { x = 12, y = 2 }, { x = -11, y = 5 }, { x = -11, y = 4 }, { x = 11, y = 4 }, { x = 11, y = 5 }, { x = -10, y = 7 }, { x = -10, y = 6 }, { x = 10, y = 6 }, { x = 10, y = 7 }, { x = -9, y = 8 }, { x = -8, y = 9 }, { x = 9, y = 8 }, { x = 8, y = 9 }, { x = -7, y = 10 }, { x = -5, y = 11 }, { x = -6, y = 10 }, { x = -4, y = 11 }, { x = 5, y = 11 }, { x = 4, y = 11 }, { x = 7, y = 10 }, { x = 6, y = 10 }, { x = -3, y = 12 }, { x = -2, y = 12 }, { x = -1, y = 12 }, { x = 0, y = 12 }, { x = 1, y = 12 }, { x = 2, y = 12 }, { x = 3, y = 12 } },
|
||||
[14] = { { x = -3, y = -13 }, { x = -1, y = -13 }, { x = -2, y = -13 }, { x = 1, y = -13 }, { x = 0, y = -13 }, { x = 3, y = -13 }, { x = 2, y = -13 }, { x = -7, y = -11 }, { x = -6, y = -11 }, { x = -5, y = -12 }, { x = -6, y = -12 }, { x = -4, y = -12 }, { x = 5, y = -12 }, { x = 4, y = -12 }, { x = 7, y = -11 }, { x = 6, y = -11 }, { x = 6, y = -12 }, { x = -10, y = -9 }, { x = -9, y = -9 }, { x = -9, y = -10 }, { x = -8, y = -10 }, { x = 9, y = -9 }, { x = 9, y = -10 }, { x = 8, y = -10 }, { x = 10, y = -9 }, { x = -11, y = -7 }, { x = -10, y = -8 }, { x = 11, y = -7 }, { x = 10, y = -8 }, { x = -11, y = -6 }, { x = -12, y = -6 }, { x = -12, y = -5 }, { x = 11, y = -6 }, { x = 12, y = -6 }, { x = 12, y = -5 }, { x = -13, y = -3 }, { x = -12, y = -4 }, { x = 12, y = -4 }, { x = 13, y = -3 }, { x = -13, y = -2 }, { x = -13, y = -1 }, { x = 13, y = -1 }, { x = 13, y = -2 }, { x = -13, y = 0 }, { x = -13, y = 1 }, { x = 13, y = 1 }, { x = 13, y = 0 }, { x = -13, y = 2 }, { x = -13, y = 3 }, { x = 13, y = 3 }, { x = 13, y = 2 }, { x = -12, y = 5 }, { x = -12, y = 4 }, { x = 12, y = 5 }, { x = 12, y = 4 }, { x = -11, y = 6 }, { x = -11, y = 7 }, { x = -12, y = 6 }, { x = 11, y = 7 }, { x = 11, y = 6 }, { x = 12, y = 6 }, { x = -10, y = 8 }, { x = -10, y = 9 }, { x = -9, y = 9 }, { x = 9, y = 9 }, { x = 10, y = 9 }, { x = 10, y = 8 }, { x = -9, y = 10 }, { x = -8, y = 10 }, { x = -7, y = 11 }, { x = -6, y = 11 }, { x = 7, y = 11 }, { x = 6, y = 11 }, { x = 8, y = 10 }, { x = 9, y = 10 }, { x = -6, y = 12 }, { x = -5, y = 12 }, { x = -4, y = 12 }, { x = -3, y = 13 }, { x = -2, y = 13 }, { x = -1, y = 13 }, { x = 0, y = 13 }, { x = 1, y = 13 }, { x = 2, y = 13 }, { x = 3, y = 13 }, { x = 5, y = 12 }, { x = 4, y = 12 }, { x = 6, y = 12 } },
|
||||
[15] = { { x = -5, y = -13 }, { x = -6, y = -13 }, { x = -4, y = -13 }, { x = -3, y = -14 }, { x = -1, y = -14 }, { x = -2, y = -14 }, { x = 1, y = -14 }, { x = 0, y = -14 }, { x = 3, y = -14 }, { x = 2, y = -14 }, { x = 5, y = -13 }, { x = 4, y = -13 }, { x = 6, y = -13 }, { x = -9, y = -11 }, { x = -8, y = -11 }, { x = -8, y = -12 }, { x = -7, y = -12 }, { x = 7, y = -12 }, { x = 8, y = -12 }, { x = 8, y = -11 }, { x = 9, y = -11 }, { x = -11, y = -9 }, { x = -10, y = -10 }, { x = 10, y = -10 }, { x = 11, y = -9 }, { x = -12, y = -7 }, { x = -11, y = -8 }, { x = -12, y = -8 }, { x = 11, y = -8 }, { x = 12, y = -8 }, { x = 12, y = -7 }, { x = -13, y = -5 }, { x = -13, y = -6 }, { x = 13, y = -5 }, { x = 13, y = -6 }, { x = -13, y = -4 }, { x = -14, y = -3 }, { x = 13, y = -4 }, { x = 14, y = -3 }, { x = -14, y = -2 }, { x = -14, y = -1 }, { x = 14, y = -1 }, { x = 14, y = -2 }, { x = -14, y = 0 }, { x = -14, y = 1 }, { x = 14, y = 1 }, { x = 14, y = 0 }, { x = -14, y = 2 }, { x = -14, y = 3 }, { x = 14, y = 3 }, { x = 14, y = 2 }, { x = -13, y = 4 }, { x = -13, y = 5 }, { x = 13, y = 5 }, { x = 13, y = 4 }, { x = -13, y = 6 }, { x = -12, y = 7 }, { x = 12, y = 7 }, { x = 13, y = 6 }, { x = -11, y = 9 }, { x = -11, y = 8 }, { x = -12, y = 8 }, { x = 11, y = 8 }, { x = 11, y = 9 }, { x = 12, y = 8 }, { x = -9, y = 11 }, { x = -10, y = 10 }, { x = -8, y = 11 }, { x = 9, y = 11 }, { x = 8, y = 11 }, { x = 10, y = 10 }, { x = -7, y = 12 }, { x = -8, y = 12 }, { x = -6, y = 13 }, { x = -5, y = 13 }, { x = -4, y = 13 }, { x = 5, y = 13 }, { x = 4, y = 13 }, { x = 7, y = 12 }, { x = 6, y = 13 }, { x = 8, y = 12 }, { x = -3, y = 14 }, { x = -2, y = 14 }, { x = -1, y = 14 }, { x = 0, y = 14 }, { x = 1, y = 14 }, { x = 2, y = 14 }, { x = 3, y = 14 } },
|
||||
[16] = { { x = -3, y = -15 }, { x = -1, y = -15 }, { x = -2, y = -15 }, { x = 1, y = -15 }, { x = 0, y = -15 }, { x = 3, y = -15 }, { x = 2, y = -15 }, { x = -7, y = -13 }, { x = -8, y = -13 }, { x = -5, y = -14 }, { x = -6, y = -14 }, { x = -4, y = -14 }, { x = 5, y = -14 }, { x = 4, y = -14 }, { x = 7, y = -13 }, { x = 6, y = -14 }, { x = 8, y = -13 }, { x = -9, y = -12 }, { x = -10, y = -11 }, { x = 9, y = -12 }, { x = 10, y = -11 }, { x = -11, y = -10 }, { x = -12, y = -9 }, { x = 11, y = -10 }, { x = 12, y = -9 }, { x = -13, y = -7 }, { x = -13, y = -8 }, { x = 13, y = -7 }, { x = 13, y = -8 }, { x = -14, y = -6 }, { x = -14, y = -5 }, { x = 14, y = -5 }, { x = 14, y = -6 }, { x = -15, y = -3 }, { x = -14, y = -4 }, { x = 15, y = -3 }, { x = 14, y = -4 }, { x = -15, y = -2 }, { x = -15, y = -1 }, { x = 15, y = -1 }, { x = 15, y = -2 }, { x = -15, y = 0 }, { x = -15, y = 1 }, { x = 15, y = 1 }, { x = 15, y = 0 }, { x = -15, y = 2 }, { x = -15, y = 3 }, { x = 15, y = 3 }, { x = 15, y = 2 }, { x = -14, y = 5 }, { x = -14, y = 4 }, { x = 14, y = 5 }, { x = 14, y = 4 }, { x = -13, y = 7 }, { x = -14, y = 6 }, { x = 13, y = 7 }, { x = 14, y = 6 }, { x = -13, y = 8 }, { x = -12, y = 9 }, { x = 12, y = 9 }, { x = 13, y = 8 }, { x = -11, y = 10 }, { x = -10, y = 11 }, { x = 10, y = 11 }, { x = 11, y = 10 }, { x = -9, y = 12 }, { x = -8, y = 13 }, { x = -7, y = 13 }, { x = 7, y = 13 }, { x = 8, y = 13 }, { x = 9, y = 12 }, { x = -6, y = 14 }, { x = -5, y = 14 }, { x = -4, y = 14 }, { x = -3, y = 15 }, { x = -2, y = 15 }, { x = -1, y = 15 }, { x = 0, y = 15 }, { x = 1, y = 15 }, { x = 2, y = 15 }, { x = 3, y = 15 }, { x = 4, y = 14 }, { x = 5, y = 14 }, { x = 6, y = 14 } }
|
||||
}
|
||||
|
||||
for current_radius = 1, 16, 1 do
|
||||
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule][current_radius] = {}
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule][current_radius].trigger_tick = game.tick + (current_radius * 8)
|
||||
|
||||
local circle_coords = circle_coordinates[current_radius]
|
||||
circle_coords = shuffle(circle_coords)
|
||||
|
||||
for index, tile_position in pairs(circle_coords) do
|
||||
local pos = { x = center_position.x + tile_position.x, y = center_position.y + tile_position.y }
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule][current_radius][index] = { x = pos.x, y = pos.y }
|
||||
end
|
||||
|
||||
end
|
||||
entity.die("player")
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if not entity.health then return end
|
||||
if not container_types[entity.type] then return end
|
||||
if not entity.fluidbox[1] then return end
|
||||
if not fluid_damages[entity.fluidbox[1].name] then return end
|
||||
if entity.health > entity.prototype.max_health * 0.75 then return end
|
||||
|
||||
if math.random(1, 3) == 1 or entity.health <= 0 then
|
||||
create_explosion_schedule(entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick(event)
|
||||
local ffatable = Table.get_table()
|
||||
local tick = event.tick
|
||||
if ffatable.fluid_explosion_schedule then
|
||||
local explosion_schedule_is_alive = false
|
||||
for explosion_index = 1, #ffatable.fluid_explosion_schedule, 1 do
|
||||
if #ffatable.fluid_explosion_schedule[explosion_index] > 0 then
|
||||
explosion_schedule_is_alive = true
|
||||
for radius = 1, #ffatable.fluid_explosion_schedule[explosion_index], 1 do
|
||||
if ffatable.fluid_explosion_schedule[explosion_index][radius].trigger_tick == tick then
|
||||
for tile_index = 1, #ffatable.fluid_explosion_schedule[explosion_index][radius], 1 do
|
||||
local continue_explosion = process_explosion_tile(ffatable.fluid_explosion_schedule[explosion_index][radius][tile_index], explosion_index, radius)
|
||||
if not continue_explosion then
|
||||
ffatable.fluid_explosion_schedule[explosion_index] = {}
|
||||
break
|
||||
end
|
||||
end
|
||||
if radius == #ffatable.fluid_explosion_schedule[explosion_index] then ffatable.fluid_explosion_schedule[explosion_index] = {} end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not explosion_schedule_is_alive then ffatable.fluid_explosion_schedule = nil end
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.fluid_explosion_schedule = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
125
modules/scrap_towny_ffa/info.lua
Normal file
125
modules/scrap_towny_ffa/info.lua
Normal file
@ -0,0 +1,125 @@
|
||||
local Public = {}
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local info = [[You are an "outlander" stuck on this god-forsaken planet with a bunch of other desolate fools. You can choose to join
|
||||
an existing town if accepted, or go at it alone, building your own outpost or living as an "outlander".
|
||||
|
||||
The local inhabitants are indifferent to you at first, so long as you don't build or pollute, but become increasingly aggressive
|
||||
by foreign technology. In fact, they get quite aggressive at the scent of it. If you were to hurt any of the natives you will be
|
||||
brandished a rogue until your untimely death or until you find better digs.
|
||||
|
||||
To create a new town or outpost simply place a furnace down in a suitable spot that is not near any other towns or obstructed.
|
||||
The world seems to be limited in size with uninhabitable zones on four sides. News towns can only be built within these
|
||||
borders and you must leave room for the town's size (radius of 27) when placing a new town.
|
||||
TIP: It's best to find a spot far from existing towns and pollution, as enemies will become aggressive once you form a town.
|
||||
|
||||
Once a town is formed, members may invite other players and teams using a raw fish. To invite another player, drop a fish
|
||||
on that player (with the Z key). To accept an invite, offer a fish in return to the member. To leave a town, simply drop coal
|
||||
on the market. As a member of a town, your respawn point will change to that of the town.
|
||||
|
||||
To form any alliance with another town, drop a fish on a member or their market. If they agree they can reciprocate with a
|
||||
fish offering.
|
||||
|
||||
The town market is the heart of your town. If it is destroyed, your town is destroyed and you will lose all research. So
|
||||
protect it well, repair it whenever possible, and if you can afford, increase its health by purchasing upgrades. If your
|
||||
town falls, members will be disbanded, and all buildings will become neutral and lootable.
|
||||
|
||||
When building your town, note that you may only build nearby existing structures such as your town market and walls and
|
||||
any other structure you have placed. Beware that biters and spitters become more aggressive towards towns that are
|
||||
advanced in research. Their evolution will scale around technology progress in any nearby towns and pollution levels.
|
||||
|
||||
This is a FFA ("Free-For-All") world. Short of bullying and derogatory remarks, anything goes. Griefing is encouraged,
|
||||
so best to setup proper defenses for your town or outpost to fend off enemies when you are there and away.
|
||||
|
||||
Have fun and be comfy ^.^]]
|
||||
|
||||
function Public.toggle_button(player)
|
||||
if player.gui.top["towny_map_intro_button"] then return end
|
||||
local b = player.gui.top.add({ type = "sprite-button", caption = "Towny", name = "towny_map_intro_button", tooltip = "Show Info" })
|
||||
b.style.font_color = { r = 0.5, g = 0.3, b = 0.99 }
|
||||
b.style.font = "heading-1"
|
||||
b.style.minimal_height = 38
|
||||
b.style.minimal_width = 80
|
||||
b.style.top_padding = 1
|
||||
b.style.left_padding = 1
|
||||
b.style.right_padding = 1
|
||||
b.style.bottom_padding = 1
|
||||
end
|
||||
|
||||
function Public.show(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player.gui.center["towny_map_intro_frame"] then player.gui.center["towny_map_intro_frame"].destroy() end
|
||||
local frame = player.gui.center.add { type = "frame", name = "towny_map_intro_frame" }
|
||||
frame = frame.add { type = "frame", direction = "vertical" }
|
||||
|
||||
local t = frame.add { type = "table", column_count = 2 }
|
||||
|
||||
local label = t.add { type = "label", caption = "Active Factions:" }
|
||||
label.style.font = "heading-1"
|
||||
label.style.font_color = { r = 0.85, g = 0.85, b = 0.85 }
|
||||
label.style.right_padding = 8
|
||||
|
||||
t = t.add { type = "table", column_count = 4 }
|
||||
|
||||
local label2 = t.add { type = "label", caption = "Outlander" .. "(" .. #game.forces.player.connected_players .. ")" }
|
||||
label2.style.font_color = { 170, 170, 170 }
|
||||
label2.style.font = "heading-3"
|
||||
label2.style.minimal_width = 80
|
||||
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local force = town_center.market.force
|
||||
local label3 = t.add { type = "label", caption = force.name .. "(" .. #force.connected_players .. ")" }
|
||||
label3.style.font = "heading-3"
|
||||
label3.style.minimal_width = 80
|
||||
label3.style.font_color = town_center.color
|
||||
end
|
||||
|
||||
frame.add { type = "line" }
|
||||
|
||||
local l = frame.add { type = "label", caption = "Instructions:" }
|
||||
l.style.font = "heading-1"
|
||||
l.style.font_color = { r = 0.85, g = 0.85, b = 0.85 }
|
||||
|
||||
local l2 = frame.add { type = "label", caption = info }
|
||||
l2.style.single_line = false
|
||||
l2.style.font = "heading-2"
|
||||
l2.style.font_color = { r = 0.8, g = 0.7, b = 0.99 }
|
||||
end
|
||||
|
||||
function Public.close(event)
|
||||
if not event.element then return end
|
||||
if not event.element.valid then return end
|
||||
local parent = event.element.parent
|
||||
for _ = 1, 4, 1 do
|
||||
if not parent then return end
|
||||
if parent.name == "towny_map_intro_frame" then
|
||||
parent.destroy()
|
||||
return
|
||||
end
|
||||
parent = parent.parent
|
||||
end
|
||||
end
|
||||
|
||||
function Public.toggle(event)
|
||||
if not event.element then return end
|
||||
if not event.element.valid then return end
|
||||
if event.element.name == "towny_map_intro_button" then
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.center["towny_map_intro_frame"] then
|
||||
player.gui.center["towny_map_intro_frame"].destroy()
|
||||
else
|
||||
Public.show(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
Public.close(event)
|
||||
Public.toggle(event)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
|
||||
return Public
|
15
modules/scrap_towny_ffa/limited_radar.lua
Normal file
15
modules/scrap_towny_ffa/limited_radar.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local Public = {}
|
||||
|
||||
function Public.reset()
|
||||
for index = 1, table.size(game.forces), 1 do
|
||||
local force = game.forces[index]
|
||||
if force ~= nil then
|
||||
force.clear_chart("nauvis")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--local Event = require 'utils.event'
|
||||
--Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
|
||||
return Public
|
295
modules/scrap_towny_ffa/market.lua
Normal file
295
modules/scrap_towny_ffa/market.lua
Normal file
@ -0,0 +1,295 @@
|
||||
local table_insert = table.insert
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Town_center = require 'modules.scrap_towny_ffa.town_center'
|
||||
|
||||
local upgrade_functions = {
|
||||
-- Upgrade Town Center Health
|
||||
[1] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local surface = market.surface
|
||||
if town_center.max_health > 500000 then return end
|
||||
town_center.health = town_center.health + town_center.max_health
|
||||
town_center.max_health = town_center.max_health * 2
|
||||
Town_center.set_market_health(market, 0)
|
||||
surface.play_sound({ path = "utility/achievement_unlocked", position = player.position, volume_modifier = 1 })
|
||||
end,
|
||||
-- Upgrade Backpack
|
||||
[2] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
if force.character_inventory_slots_bonus > 100 then return end
|
||||
force.character_inventory_slots_bonus = force.character_inventory_slots_bonus + 5
|
||||
surface.play_sound({ path = "utility/achievement_unlocked", position = player.position, volume_modifier = 1 })
|
||||
end,
|
||||
-- Upgrade Mining Productivity
|
||||
[3] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
if town_center.upgrades.mining_prod >= 10 then return end
|
||||
town_center.upgrades.mining_prod = town_center.upgrades.mining_prod + 1
|
||||
force.mining_drill_productivity_bonus = force.mining_drill_productivity_bonus + 0.1
|
||||
surface.play_sound({ path = "utility/achievement_unlocked", position = player.position, volume_modifier = 1 })
|
||||
end,
|
||||
-- Laser Turret Slot
|
||||
[4] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local surface = market.surface
|
||||
town_center.upgrades.laser_turret.slots = town_center.upgrades.laser_turret.slots + 1
|
||||
surface.play_sound({ path = "utility/new_objective", position = player.position, volume_modifier = 1 })
|
||||
end,
|
||||
-- Set Spawn Point
|
||||
[5] = function(town_center, player)
|
||||
local ffatable = Table.get_table()
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
local spawn_point = force.get_spawn_position(surface)
|
||||
ffatable.spawn_point[player.name] = spawn_point
|
||||
surface.play_sound({ path = "utility/scenario_message", position = player.position, volume_modifier = 1 })
|
||||
end,
|
||||
}
|
||||
|
||||
local function clear_offers(market)
|
||||
for _ = 1, 256, 1 do
|
||||
local a = market.remove_market_item(1)
|
||||
if a == false then return end
|
||||
end
|
||||
end
|
||||
|
||||
local function set_offers(town_center)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
|
||||
local special_offers = {}
|
||||
|
||||
if town_center.max_health < 500000 then
|
||||
special_offers[1] = { { { "coin", town_center.max_health * 0.1 } }, "Upgrade Town Center Health" }
|
||||
else
|
||||
special_offers[1] = { { { "coin", 1 } }, "Maximum Health upgrades reached!" }
|
||||
end
|
||||
if force.character_inventory_slots_bonus <= 100 then
|
||||
special_offers[2] = { { { "coin", (force.character_inventory_slots_bonus / 5 + 1) * 50 } }, "Upgrade Backpack +5 Slot" }
|
||||
else
|
||||
special_offers[2] = { { { "coin", 1 } }, "Maximum Backpack upgrades reached!" }
|
||||
end
|
||||
if town_center.upgrades.mining_prod < 10 then
|
||||
special_offers[3] = { { { "coin", (town_center.upgrades.mining_prod + 1) * 400 } }, "Upgrade Mining Productivity +10%" }
|
||||
else
|
||||
special_offers[3] = { { { "coin", 1 } }, "Maximum Mining upgrades reached!" }
|
||||
end
|
||||
local laser_turret = "Laser Turret Slot [#" .. tostring(town_center.upgrades.laser_turret.slots + 1) .. "]"
|
||||
special_offers[4] = { { { "coin", 1000 + (town_center.upgrades.laser_turret.slots * 50) } }, laser_turret }
|
||||
local spawn_point = "Set Spawn Point"
|
||||
special_offers[5] = { { { "coin", 1 } }, spawn_point }
|
||||
|
||||
local market_items = {}
|
||||
|
||||
for _, v in pairs(special_offers) do
|
||||
table_insert(market_items, { price = v[1], offer = { type = 'nothing', effect_description = v[2] } })
|
||||
end
|
||||
|
||||
-- coin purchases
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'raw-fish', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'wood', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'iron-ore', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'copper-ore', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'stone', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'coal', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'uranium-ore', count = 4 } })
|
||||
table_insert(market_items, { price = { { 'coin', 300 } }, offer = { type = 'give-item', item = 'loader', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'coin', 600 } }, offer = { type = 'give-item', item = 'fast-loader', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'coin', 900 } }, offer = { type = 'give-item', item = 'express-loader', count = 1 } })
|
||||
-- scrap selling
|
||||
table_insert(market_items, { price = { { 'wood', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'iron-ore', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'copper-ore', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'stone', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'coal', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'uranium-ore', 5 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'copper-cable', 12 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'iron-gear-wheel', 3 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'iron-stick', 12 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'empty-barrel', 1 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
|
||||
for _, item in pairs(market_items) do
|
||||
market.add_market_item(item)
|
||||
end
|
||||
end
|
||||
|
||||
local function refresh_offers(event)
|
||||
local ffatable = Table.get_table()
|
||||
local market = event.entity or event.market
|
||||
if not market then return end
|
||||
if not market.valid then return end
|
||||
if market.name ~= "market" then return end
|
||||
local town_center = ffatable.town_centers[market.force.name]
|
||||
if not town_center then return end
|
||||
clear_offers(market)
|
||||
set_offers(town_center)
|
||||
end
|
||||
|
||||
local function offer_purchased(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local market = event.market
|
||||
local offer_index = event.offer_index
|
||||
local count = event.count
|
||||
if not upgrade_functions[offer_index] then return end
|
||||
|
||||
local town_center = ffatable.town_centers[market.force.name]
|
||||
if not town_center then return end
|
||||
|
||||
upgrade_functions[offer_index](town_center, player)
|
||||
|
||||
if count > 1 then
|
||||
local offers = market.get_market_items()
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({ name = "coin", count = price * (count - 1) })
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_opened(event)
|
||||
local gui_type = event.gui_type
|
||||
if gui_type ~= defines.gui_type.entity then return end
|
||||
local entity = event.entity
|
||||
if entity == nil or not entity.valid then return end
|
||||
if entity.type == "market" then refresh_offers(event) end
|
||||
end
|
||||
|
||||
local function on_market_item_purchased(event)
|
||||
offer_purchased(event)
|
||||
refresh_offers(event)
|
||||
end
|
||||
|
||||
local function inside(pos, area)
|
||||
return pos.x >= area.left_top.x and pos.x <= area.right_bottom.x and pos.y >= area.left_top.y and pos.y <= area.right_bottom.y
|
||||
end
|
||||
|
||||
local function on_tick(_)
|
||||
local ffatable = Table.get_table()
|
||||
if not ffatable.town_centers then return end
|
||||
local items = { "burner-inserter", "inserter", "long-handed-inserter", "fast-inserter",
|
||||
"filter-inserter", "stack-inserter", "stack-filter-inserter",
|
||||
"loader", "fast-loader", "express-loader" }
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local market = town_center.market
|
||||
local offers = market.get_market_items()
|
||||
if offers == nil then set_offers(town_center) end
|
||||
local s = market.surface
|
||||
local force = market.force
|
||||
-- get the bounding box for the market
|
||||
local bb = market.bounding_box
|
||||
local area = { left_top = { bb.left_top.x - 2, bb.left_top.y - 2 }, right_bottom = { bb.right_bottom.x + 2, bb.right_bottom.y + 2 } }
|
||||
local entities = s.find_entities_filtered({ area = area, name = items })
|
||||
for _, e in pairs(entities) do
|
||||
if e.name ~= "loader" and e.name ~= "fast-loader" and e.name ~= "express-loader" then
|
||||
local ppos = e.pickup_position
|
||||
local dpos = e.drop_position
|
||||
-- pulling an item from the market
|
||||
if inside(ppos, bb) and e.drop_target then
|
||||
local stack = e.held_stack
|
||||
local spos = e.held_stack_position
|
||||
if inside(spos, bb) then
|
||||
local filter
|
||||
local filter_mode = e.inserter_filter_mode
|
||||
if filter_mode ~= nil then
|
||||
for i = 1, e.filter_slot_count do
|
||||
if e.get_filter(i) ~= nil then
|
||||
filter = e.get_filter(i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if (filter_mode == "whitelist" and filter == "coin") or (filter_mode == "blacklist" and filter == nil) or (filter_mode == nil) then
|
||||
if stack.valid and town_center.coin_balance > 0 then
|
||||
-- pull coins
|
||||
stack.set_stack({ name = "coin", count = 1 })
|
||||
town_center.coin_balance = town_center.coin_balance - 1
|
||||
Town_center.update_coin_balance(force)
|
||||
end
|
||||
else
|
||||
if filter_mode == "whitelist" and filter ~= nil and stack.valid then
|
||||
-- purchased and pull items if output buffer is empty
|
||||
-- buffer the output in a item buffer since the stack might be too small
|
||||
-- output items are shared among the output
|
||||
for _, trade in ipairs(offers) do
|
||||
local type = trade.offer.type
|
||||
local item = trade.offer.item
|
||||
local count = trade.offer.count or 1
|
||||
local cost = trade.price[1].amount
|
||||
if type == "give-item" and item == filter then
|
||||
if town_center.output_buffer[item] == nil then town_center.output_buffer[item] = 0 end
|
||||
if town_center.output_buffer[item] == 0 then
|
||||
-- fill buffer
|
||||
if town_center.coin_balance >= cost then
|
||||
town_center.coin_balance = town_center.coin_balance - cost
|
||||
Town_center.update_coin_balance(force)
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] + count
|
||||
--log("output_buffer[" .. item .. "] = " .. town_center.output_buffer[item])
|
||||
end
|
||||
end
|
||||
if town_center.output_buffer[item] > 0 and not stack.valid_for_read then
|
||||
-- output the item
|
||||
local amount = 1
|
||||
if stack.can_set_stack({ name = item, count = amount }) then
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] - amount
|
||||
stack.set_stack({ name = item, count = amount })
|
||||
--log("output_buffer[" .. item .. "] = " .. town_center.output_buffer[item])
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- pushing an item to the market (coins or scrap)
|
||||
if e.pickup_target and inside(dpos, bb) then
|
||||
local stack = e.held_stack
|
||||
local spos = e.held_stack_position
|
||||
if stack.valid_for_read and inside(spos, bb) then
|
||||
local name = stack.name
|
||||
local amount = stack.count
|
||||
if name == "coin" then
|
||||
-- push coins
|
||||
e.remove_item(stack)
|
||||
town_center.coin_balance = town_center.coin_balance + amount
|
||||
Town_center.update_coin_balance(force)
|
||||
else
|
||||
-- push items to turn into coin
|
||||
for _, trade in ipairs(offers) do
|
||||
local type = trade.offer.type
|
||||
local item = trade.price[1].name
|
||||
local count = trade.price[1].amount
|
||||
local cost = trade.offer.count
|
||||
if type == "give-item" and name == item and item ~= "coin" then
|
||||
e.remove_item(stack)
|
||||
-- buffer the input in an item buffer that can be sold
|
||||
if town_center.input_buffer[item] == nil then town_center.input_buffer[item] = 0 end
|
||||
town_center.input_buffer[item] = town_center.input_buffer[item] + amount
|
||||
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
|
||||
if town_center.input_buffer[item] >= count then
|
||||
town_center.input_buffer[item] = town_center.input_buffer[item] - count
|
||||
town_center.coin_balance = town_center.coin_balance + cost
|
||||
Town_center.update_coin_balance(force)
|
||||
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
|
98
modules/scrap_towny_ffa/mining.lua
Normal file
98
modules/scrap_towny_ffa/mining.lua
Normal file
@ -0,0 +1,98 @@
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local crash_site = {
|
||||
-- simple entity with owner
|
||||
"crash-site-spaceship-wreck-small-1",
|
||||
"crash-site-spaceship-wreck-small-2",
|
||||
"crash-site-spaceship-wreck-small-3",
|
||||
"crash-site-spaceship-wreck-small-4",
|
||||
"crash-site-spaceship-wreck-small-5",
|
||||
"crash-site-spaceship-wreck-small-6",
|
||||
-- containers
|
||||
"big-ship-wreck-1",
|
||||
"big-ship-wreck-2",
|
||||
"big-ship-wreck-3",
|
||||
"crash-site-chest-1",
|
||||
"crash-site-chest-2",
|
||||
"crash-site-spaceship-wreck-medium-1",
|
||||
"crash-site-spaceship-wreck-medium-2",
|
||||
"crash-site-spaceship-wreck-medium-3",
|
||||
"crash-site-spaceship-wreck-big-1",
|
||||
"crash-site-spaceship-wreck-big-2",
|
||||
"crash-site-spaceship"
|
||||
}
|
||||
|
||||
local function is_crash_site(entity)
|
||||
if not entity.valid then return false end
|
||||
local f = false
|
||||
for i = 1, #crash_site, 1 do
|
||||
if entity.name == crash_site[i] then f = true end
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
local function mining_sound(player)
|
||||
if game.tick % 15 ~= 0 then return end
|
||||
local target = player.selected
|
||||
if target == nil or not target.valid then return end
|
||||
local surface = target.surface
|
||||
local position = target.position
|
||||
local path = "entity-mining/" .. target.name
|
||||
surface.play_sound({path = path, position = position, volume_modifier = 1, override_sound_type = "game-effect" })
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
local ffatable = Table.get_table()
|
||||
for index, player in pairs(game.players) do
|
||||
if player.character ~= nil then
|
||||
local mining = player.mining_state.mining
|
||||
if ffatable.mining[index] ~= mining then
|
||||
ffatable.mining[index] = mining
|
||||
-- state change
|
||||
if mining == true then
|
||||
--log(player.name .. " started mining")
|
||||
local target = player.selected
|
||||
if target ~= nil and target.valid then
|
||||
--log("target name = " .. target.prototype.name)
|
||||
--log("position = " .. serpent.block(target.position))
|
||||
--log("mineable_properties = " .. serpent.block(target.prototype.mineable_properties))
|
||||
if is_crash_site(target) then
|
||||
-- mining crash site
|
||||
mining_sound(player)
|
||||
ffatable.mining_target[index] = target
|
||||
end
|
||||
end
|
||||
else
|
||||
--log(player.name .. " stopped mining")
|
||||
local target = ffatable.mining_target[index]
|
||||
if target ~= nil then
|
||||
ffatable.mining_target[index] = nil
|
||||
end
|
||||
end
|
||||
else
|
||||
if mining == true then
|
||||
local target = player.selected
|
||||
if target ~= nil and target.valid then
|
||||
--local progress = player.character_mining_progress
|
||||
--log("progress = " .. progress)
|
||||
if is_crash_site(target) then
|
||||
-- mining crash site
|
||||
mining_sound(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.mining = {}
|
||||
ffatable.mining_entity = {}
|
||||
ffatable.mining_target = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
203
modules/scrap_towny_ffa/nauvis.lua
Normal file
203
modules/scrap_towny_ffa/nauvis.lua
Normal file
@ -0,0 +1,203 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
|
||||
local function create_limbo()
|
||||
game.create_surface("limbo")
|
||||
end
|
||||
|
||||
local function initialize_nauvis()
|
||||
local surface = game.surfaces["nauvis"]
|
||||
|
||||
-- this overrides what is in the map_gen_settings.json file
|
||||
local mgs = surface.map_gen_settings
|
||||
mgs.default_enable_all_autoplace_controls = true -- don't mess with this!
|
||||
mgs.autoplace_controls = {
|
||||
coal = { frequency = "none", size = 1, richness = "normal" },
|
||||
stone = { frequency = "none", size = 1, richness = "normal" },
|
||||
["copper-ore"] = { frequency = "none", size = 1, richness = "normal" },
|
||||
["iron-ore"] = { frequency = "none", size = 1, richness = "normal" },
|
||||
["uranium-ore"] = { frequency = "none", size = 1, richness = "normal" },
|
||||
["crude-oil"] = { frequency = "none", size = 1, richness = "normal" },
|
||||
trees = { frequency = 2, size = "normal", richness = "normal" },
|
||||
["enemy-base"] = { frequency = 8, size = 1, richness = "normal" }
|
||||
}
|
||||
mgs.autoplace_settings = {
|
||||
entity = {
|
||||
settings = {
|
||||
["rock-huge"] = { frequency = 3, size = 12, richness = "very-high" },
|
||||
["rock-big"] = { frequency = 3, size = 12, richness = "very-high" },
|
||||
["sand-rock-big"] = { frequency = 3, size = 12, richness = 1, "very-high" },
|
||||
}
|
||||
},
|
||||
decorative = {
|
||||
settings = {
|
||||
["rock-tiny"] = { frequency = 10, size = "normal", richness = "normal" },
|
||||
["rock-small"] = { frequency = 5, size = "normal", richness = "normal" },
|
||||
["rock-medium"] = { frequency = 2, size = "normal", richness = "normal" },
|
||||
["sand-rock-small"] = { frequency = 10, size = "normal", richness = "normal" },
|
||||
["sand-rock-medium"] = { frequency = 5, size = "normal", richness = "normal" }
|
||||
}
|
||||
}
|
||||
}
|
||||
mgs.cliff_settings = {
|
||||
name = "cliff",
|
||||
cliff_elevation_0 = 5,
|
||||
cliff_elevation_interval = 10,
|
||||
richness = 0.4
|
||||
}
|
||||
-- water = 0 means no water allowed
|
||||
-- water = 1 means elevation is not reduced when calculating water tiles (elevation < 0)
|
||||
-- water = 2 means elevation is reduced by 10 when calculating water tiles (elevation < 0)
|
||||
-- or rather, the water table is 10 above the normal elevation
|
||||
mgs.water = 0.5
|
||||
mgs.peaceful_mode = false
|
||||
mgs.starting_area = "none"
|
||||
mgs.terrain_segmentation = 8
|
||||
mgs.width = 2048
|
||||
mgs.height = 2048
|
||||
--mgs.starting_points = {
|
||||
-- {x = 0, y = 0}
|
||||
--}
|
||||
mgs.research_queue_from_the_start = "always"
|
||||
-- here we put the named noise expressions for the specific noise-layer if we want to override them
|
||||
mgs.property_expression_names = {
|
||||
-- here we are overriding the moisture noise-layer with a fixed value of 0 to keep moisture consistently dry across the map
|
||||
-- it allows to free up the moisture noise expression
|
||||
-- low moisture
|
||||
--moisture = 0,
|
||||
|
||||
-- here we are overriding the aux noise-layer with a fixed value to keep aux consistent across the map
|
||||
-- it allows to free up the aux noise expression
|
||||
-- aux should be not sand, nor red sand
|
||||
--aux = 0.5,
|
||||
|
||||
-- here we are overriding the temperature noise-layer with a fixed value to keep temperature consistent across the map
|
||||
-- it allows to free up the temperature noise expression
|
||||
-- temperature should be 20C or 68F
|
||||
--temperature = 20,
|
||||
|
||||
-- here we are overriding the cliffiness noise-layer with a fixed value of 0 to disable cliffs
|
||||
-- it allows to free up the cliffiness noise expression (which may or may not be useful)
|
||||
-- disable cliffs
|
||||
--cliffiness = 0,
|
||||
|
||||
-- we can disable starting lakes two ways, one by setting starting-lake-noise-amplitude = 0
|
||||
-- or by making the elevation a very large number
|
||||
-- make sure starting lake amplitude is 0 to disable starting lakes
|
||||
["starting-lake-noise-amplitude"] = 0,
|
||||
|
||||
-- allow enemies to get up close on spawn
|
||||
["starting-area"] = 0,
|
||||
|
||||
-- this accepts a string representing a named noise expression
|
||||
-- or number to determine the elevation based on x, y and distance from starting points
|
||||
-- we can not add a named noise expression at this point, we can only reference existing ones
|
||||
-- if we have any custom noise expressions defined from a mod, we will be able to use them here
|
||||
-- setting it to a fixed number would mean a flat map
|
||||
-- elevation < 0 means there is water unless the water table has been changed
|
||||
--elevation = -1,
|
||||
--elevation = 0,
|
||||
--elevation-persistence = 0,
|
||||
|
||||
-- testing
|
||||
--["control-setting:moisture:bias"] = 0.5,
|
||||
--["control-setting:moisture:frequency:multiplier"] = 0,
|
||||
--["control-setting:aux:bias"] = 0.5,
|
||||
--["control-setting:aux:frequency:multiplier"] = 1,
|
||||
--["control-setting:temperature:bias"] = 0.01,
|
||||
--["control-setting:temperature:frequency:multiplier"] = 100,
|
||||
|
||||
--["tile:water:probability"] = -1000,
|
||||
--["tile:deep-water:probability"] = -1000,
|
||||
|
||||
-- a constant intensity means base distribution will be consistent with regard to distance
|
||||
["enemy-base-intensity"] = 1,
|
||||
|
||||
-- adjust this value to set how many nests spawn per tile
|
||||
["enemy-base-frequency"] = 0.2,
|
||||
|
||||
-- this will make and average base radius around 12 tiles
|
||||
["enemy-base-radius"] = 12
|
||||
}
|
||||
mgs.seed = math_random(10000, 99999)
|
||||
surface.map_gen_settings = mgs
|
||||
surface.peaceful_mode = false
|
||||
surface.always_day = false
|
||||
surface.freeze_daytime = false
|
||||
surface.clear(true)
|
||||
surface.regenerate_entity({ "rock-huge", "rock-big", "sand-rock-big" })
|
||||
surface.regenerate_decorative()
|
||||
end
|
||||
|
||||
function Public.initialize()
|
||||
-- difficulty settings
|
||||
game.difficulty_settings.recipe_difficulty = defines.difficulty_settings.recipe_difficulty.normal
|
||||
game.difficulty_settings.technology_difficulty = defines.difficulty_settings.technology_difficulty.normal
|
||||
game.difficulty_settings.technology_price_multiplier = 0.50
|
||||
|
||||
-- pollution settings
|
||||
game.map_settings.pollution.enabled = true
|
||||
game.map_settings.pollution.diffusion_ratio = 0.02 -- amount that is diffused to neighboring chunk each second
|
||||
game.map_settings.pollution.min_to_diffuse = 15 -- minimum number of pollution units on the chunk to start diffusing
|
||||
game.map_settings.pollution.ageing = 1 -- percent of pollution eaten by a chunk's tiles per second
|
||||
game.map_settings.pollution.expected_max_per_chunk = 150 -- anything greater than this number of pollution units is visualized similarly
|
||||
game.map_settings.pollution.min_to_show_per_chunk = 50
|
||||
game.map_settings.pollution.min_pollution_to_damage_trees = 60
|
||||
game.map_settings.pollution.pollution_with_max_forest_damage = 150
|
||||
game.map_settings.pollution.pollution_per_tree_damage = 50
|
||||
game.map_settings.pollution.pollution_restored_per_tree_damage = 10
|
||||
game.map_settings.pollution.max_pollution_to_restore_trees = 20
|
||||
game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = 1
|
||||
|
||||
-- enemy evolution settings
|
||||
game.map_settings.enemy_evolution.enabled = true
|
||||
game.map_settings.enemy_evolution.time_factor = 0.0 -- percent increase in the evolution factor per second
|
||||
game.map_settings.enemy_evolution.destroy_factor = 0.0 -- percent increase in the evolution factor for each spawner destroyed
|
||||
game.map_settings.enemy_evolution.pollution_factor = 0.0 -- percent increase in the evolution factor for each pollution unit
|
||||
|
||||
-- enemy expansion settings
|
||||
game.map_settings.enemy_expansion.enabled = true
|
||||
game.map_settings.enemy_expansion.max_expansion_distance = 7 -- maximum distance in chunks from the nearest base (4 = 128 tiles)
|
||||
game.map_settings.enemy_expansion.friendly_base_influence_radius = 4 -- consider other nests within radius number of chunks (2 = 64 tiles)
|
||||
game.map_settings.enemy_expansion.other_base_coefficient = 2.0 -- multiply by coefficient for friendly bases
|
||||
game.map_settings.enemy_expansion.neighbouring_base_chunk_coefficient = 0.4 -- multiply by coefficient for friendly bases (^distance)
|
||||
game.map_settings.enemy_expansion.enemy_building_influence_radius = 4 -- consider player buildings within radius number of chunks
|
||||
game.map_settings.enemy_expansion.building_coefficient = 1.0 -- multiply by coefficient for player buildings
|
||||
game.map_settings.enemy_expansion.neighbouring_chunk_coefficient = 0.5 -- multiply by coefficient for player buildings (^distance)
|
||||
game.map_settings.enemy_expansion.max_colliding_tiles_coefficient = 0.9 -- percent of unbuildable tiles to not be considered a candidate
|
||||
game.map_settings.enemy_expansion.settler_group_min_size = 4 -- min size of group for building a base (multiplied by evo factor, so need evo > 0)
|
||||
game.map_settings.enemy_expansion.settler_group_max_size = 12 -- max size of group for building a base (multiplied by evo factor, so need evo > 0)
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = 1200 -- minimum time before next expansion
|
||||
game.map_settings.enemy_expansion.max_expansion_cooldown = 3600 -- maximum time before next expansion
|
||||
|
||||
-- unit group settings
|
||||
game.map_settings.unit_group.min_group_gathering_time = 600
|
||||
game.map_settings.unit_group.max_group_gathering_time = 3600
|
||||
game.map_settings.unit_group.max_wait_time_for_late_members = 3600
|
||||
game.map_settings.unit_group.max_group_radius = 30.0
|
||||
game.map_settings.unit_group.min_group_radius = 5.0
|
||||
game.map_settings.unit_group.max_member_speedup_when_behind = 1.4
|
||||
game.map_settings.unit_group.max_member_slowdown_when_ahead = 0.6
|
||||
game.map_settings.unit_group.max_group_slowdown_factor = 0.3
|
||||
game.map_settings.unit_group.max_group_member_fallback_factor = 3
|
||||
game.map_settings.unit_group.member_disown_distance = 10
|
||||
game.map_settings.unit_group.tick_tolerance_when_member_arrives = 60
|
||||
game.map_settings.unit_group.max_gathering_unit_groups = 30
|
||||
game.map_settings.unit_group.max_unit_group_size = 200
|
||||
|
||||
---- steering settings
|
||||
--game.map_settings.steering.default.radius = 1.2
|
||||
--game.map_settings.steering.default.separation_force = 0.005
|
||||
--game.map_settings.steering.default.separation_factor = 1.2
|
||||
--game.map_settings.steering.default.force_unit_fuzzy_goto_behavior = false
|
||||
--game.map_settings.steering.moving.radius = 3
|
||||
--game.map_settings.steering.moving.separation_force = 0.01
|
||||
--game.map_settings.steering.moving.separation_factor = 3
|
||||
--game.map_settings.steering.moving.force_unit_fuzzy_goto_behavior = false
|
||||
|
||||
create_limbo()
|
||||
initialize_nauvis()
|
||||
|
||||
end
|
||||
|
||||
return Public
|
19
modules/scrap_towny_ffa/on_tick_schedule.lua
Normal file
19
modules/scrap_towny_ffa/on_tick_schedule.lua
Normal file
@ -0,0 +1,19 @@
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local function on_tick()
|
||||
local ffatable = Table.get_table()
|
||||
if not ffatable.on_tick_schedule[game.tick] then return end
|
||||
for _, schedule in pairs(ffatable.on_tick_schedule[game.tick]) do
|
||||
schedule.func(unpack(schedule.args))
|
||||
end
|
||||
ffatable.on_tick_schedule[game.tick] = nil
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.on_tick_schedule = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
99
modules/scrap_towny_ffa/pollution.lua
Normal file
99
modules/scrap_towny_ffa/pollution.lua
Normal file
@ -0,0 +1,99 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
|
||||
local pollution_index = {
|
||||
["small-biter"] = { min = 0.1, max = 0.1 },
|
||||
["medium-biter"] = { min = 0.1, max = 0.2 },
|
||||
["big-biter"] = { min = 0.1, max = 0.3 },
|
||||
["behemoth-biter"] = { min = 0.1, max = 0.4 },
|
||||
["small-spitter"] = { min = 0.1, max = 0.1 },
|
||||
["medium-spitter"] = { min = 0.1, max = 0.2 },
|
||||
["big-spitter"] = { min = 0.1, max = 0.3 },
|
||||
["behemoth-spitter"] = { min = 0.2, max = 0.4 },
|
||||
["small-worm-turret"] = { min = 0.1, max = 0.1 },
|
||||
["medium-worm-turret"] = { min = 0.1, max = 0.2 },
|
||||
["big-worm-turret"] = { min = 0.1, max = 0.3 },
|
||||
["behemoth-worm-turret"] = { min = 0.2, max = 0.4 },
|
||||
["biter-spawner"] = { min = 0.5, max = 2.5 },
|
||||
["spitter-spawner"] = { min = 0.5, max = 2.5 },
|
||||
["mineable-wreckage"] = { min = 0.1, max = 0.1 },
|
||||
["small-ship-wreck"] = { min = 0.1, max = 0.1 },
|
||||
["medium-ship-wreck"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-1"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-2"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-3"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-4"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-5"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-6"] = { min = 0.1, max = 0.1 },
|
||||
["big-ship-wreck-1"] = { min = 0.2, max = 0.4 },
|
||||
["big-ship-wreck-2"] = { min = 0.2, max = 0.4 },
|
||||
["big-ship-wreck-3"] = { min = 0.2, max = 0.4 },
|
||||
["crash-site-chest-1"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-chest-2"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-medium-1"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-medium-2"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-medium-3"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-big-1"] = { min = 0.2, max = 0.4 },
|
||||
["crash-site-spaceship-wreck-big-2"] = { min = 0.2, max = 0.4 },
|
||||
["crash-site-spaceship"] = { min = 0.5, max = 2.5 },
|
||||
["explosion"] = { min = 0.1, max = 0.1 },
|
||||
["big-explosion"] = { min = 0.2, max = 0.2 },
|
||||
["big-artillery-explosion"] = { min = 0.5, max = 0.5 },
|
||||
["market"] = { min = 10, max = 50 },
|
||||
}
|
||||
|
||||
function Public.market_scent()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
if town_centers == nil then return end
|
||||
for _, town_center in pairs(town_centers) do
|
||||
local market = town_center.market
|
||||
local pollution = pollution_index["market"]
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
market.surface.pollute(market.position, amount)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.explosion(position, surface, animation)
|
||||
local pollution = pollution_index[animation]
|
||||
if pollution == nil then return end
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
surface.pollute(position, amount)
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if Scrap.is_scrap(entity) == true then
|
||||
local pollution = pollution_index[entity.name]
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
entity.surface.pollute(entity.position, amount)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local pollution = pollution_index[entity.name]
|
||||
if pollution == nil then return end
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
entity.surface.pollute(entity.position, amount)
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local pollution = pollution_index[entity.name]
|
||||
if pollution == nil then return end
|
||||
local amount = math_random(pollution.min, pollution.max) * 10
|
||||
entity.surface.pollute(entity.position, amount)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
|
||||
return Public
|
173
modules/scrap_towny_ffa/rocks_yield_ore_veins.lua
Normal file
173
modules/scrap_towny_ffa/rocks_yield_ore_veins.lua
Normal file
@ -0,0 +1,173 @@
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local table_insert = table.insert
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
|
||||
local valid_entities = {
|
||||
["rock-big"] = true,
|
||||
["rock-huge"] = true,
|
||||
["sand-rock-big"] = true
|
||||
}
|
||||
|
||||
local size_raffle = {
|
||||
{ "giant", 128, 256 },
|
||||
{ "huge", 64, 128 },
|
||||
{ "big", 32, 64 },
|
||||
{ "small", 16, 32 },
|
||||
{ "tiny", 8, 16 },
|
||||
}
|
||||
|
||||
local function get_chances()
|
||||
local chances = {}
|
||||
table_insert(chances, { "iron-ore", 25 })
|
||||
table_insert(chances, { "copper-ore", 18 })
|
||||
table_insert(chances, { "mixed", 15 })
|
||||
table_insert(chances, { "coal", 14 })
|
||||
table_insert(chances, { "stone", 8 })
|
||||
table_insert(chances, { "uranium-ore", 3 })
|
||||
return chances
|
||||
end
|
||||
|
||||
local function set_raffle()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.rocks_yield_ore_veins.raffle = {}
|
||||
for _, t in pairs(get_chances()) do
|
||||
for _ = 1, t[2], 1 do
|
||||
table_insert(ffatable.rocks_yield_ore_veins.raffle, t[1])
|
||||
end
|
||||
end
|
||||
ffatable.rocks_yield_ore_veins.mixed_ores = { "iron-ore", "copper-ore", "stone", "coal" }
|
||||
end
|
||||
|
||||
local function get_amount(position)
|
||||
local base = 256
|
||||
local relative_evolution = Evolution.get_evolution(position)
|
||||
local tier = 4 + math_floor(relative_evolution * 16)
|
||||
return (math_random(1, base) + math_random(1, 2 ^ tier))
|
||||
end
|
||||
|
||||
local function draw_chain(surface, count, ore, ore_entities, ore_positions)
|
||||
local ffatable = Table.get_table()
|
||||
local vectors = { { 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 } }
|
||||
local r = math_random(1, #ore_entities)
|
||||
local position = { x = ore_entities[r].position.x, y = ore_entities[r].position.y }
|
||||
for _ = 1, count, 1 do
|
||||
table_shuffle(vectors)
|
||||
for i = 1, 4, 1 do
|
||||
local p = { x = position.x + vectors[i][1], y = position.y + vectors[i][2] }
|
||||
local name = ore
|
||||
if ore == "mixed" then name = ffatable.rocks_yield_ore_veins.mixed_ores[math_random(1, #ffatable.rocks_yield_ore_veins.mixed_ores)] end
|
||||
if surface.can_place_entity({ name = name, position = p, amount = 1 }) then
|
||||
if not ore_positions[p.x .. "_" .. p.y] then
|
||||
position.x = p.x
|
||||
position.y = p.y
|
||||
ore_positions[p.x .. "_" .. p.y] = true
|
||||
ore_entities[#ore_entities + 1] = { name = name, position = p, amount = get_amount(p) }
|
||||
break
|
||||
end
|
||||
else
|
||||
if surface.can_fast_replace({ name = name, position = p }) then
|
||||
if math_random(1, 2) == 1 then
|
||||
if not ore_positions[p.x .. "_" .. p.y] then
|
||||
position.x = p.x
|
||||
position.y = p.y
|
||||
ore_positions[p.x .. "_" .. p.y] = true
|
||||
ore_entities[#ore_entities + 1] = { name = name, position = p, amount = get_amount(p), fast_replace = true }
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ore_vein(event)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = event.entity.surface
|
||||
local size = size_raffle[math_random(1, #size_raffle)]
|
||||
local ore = ffatable.rocks_yield_ore_veins.raffle[math_random(1, #ffatable.rocks_yield_ore_veins.raffle)]
|
||||
local icon
|
||||
if game.entity_prototypes[ore] then
|
||||
icon = "[img=entity/" .. ore .. "]"
|
||||
else
|
||||
icon = " "
|
||||
end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
for _, p in pairs(game.connected_players) do
|
||||
if p.index == player.index then
|
||||
p.print(
|
||||
{ "rocks_yield_ore_veins.player_print",
|
||||
{ "rocks_yield_ore_veins_colors." .. ore },
|
||||
{ "rocks_yield_ore_veins." .. size[1] },
|
||||
{ "rocks_yield_ore_veins." .. ore },
|
||||
icon
|
||||
},
|
||||
{ r = 0.80, g = 0.80, b = 0.80 }
|
||||
)
|
||||
else
|
||||
if p.force == player.force then
|
||||
game.print(
|
||||
{ "rocks_yield_ore_veins.game_print",
|
||||
"[color=" .. player.chat_color.r .. "," .. player.chat_color.g .. "," .. player.chat_color.b .. "]" .. player.name .. "[/color]",
|
||||
{ "rocks_yield_ore_veins." .. size[1] },
|
||||
{ "rocks_yield_ore_veins." .. ore },
|
||||
icon
|
||||
},
|
||||
{ r = 0.80, g = 0.80, b = 0.80 }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local position = event.entity.position
|
||||
local ore_entities = { { name = ore, position = { x = position.x, y = position.y }, amount = get_amount(position) } }
|
||||
if ore == "mixed" then
|
||||
ore_entities = { { name = ffatable.rocks_yield_ore_veins.mixed_ores[math_random(1, #ffatable.rocks_yield_ore_veins.mixed_ores)], position = { x = position.x, y = position.y }, amount = get_amount(position) } }
|
||||
end
|
||||
|
||||
local ore_positions = { [event.entity.position.x .. "_" .. event.entity.position.y] = true }
|
||||
local count = math_random(size[2], size[3])
|
||||
|
||||
for _ = 1, 128, 1 do
|
||||
local c = math_random(math_floor(size[2] * 0.25) + 1, size[2])
|
||||
if count < c then c = count end
|
||||
|
||||
local placed_ore_count = #ore_entities
|
||||
|
||||
draw_chain(surface, c, ore, ore_entities, ore_positions)
|
||||
|
||||
count = count - (#ore_entities - placed_ore_count)
|
||||
|
||||
if count <= 0 then break end
|
||||
end
|
||||
|
||||
for _, e in pairs(ore_entities) do
|
||||
surface.create_entity(e)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
if not event.entity.valid then return end
|
||||
if not valid_entities[event.entity.name] then return end
|
||||
if math_random(1, ffatable.rocks_yield_ore_veins.chance) ~= 1 then return end
|
||||
ore_vein(event)
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.rocks_yield_ore_veins = {}
|
||||
ffatable.rocks_yield_ore_veins.raffle = {}
|
||||
ffatable.rocks_yield_ore_veins.mixed_ores = {}
|
||||
ffatable.rocks_yield_ore_veins.chance = 4
|
||||
set_raffle()
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
36
modules/scrap_towny_ffa/scrap.lua
Normal file
36
modules/scrap_towny_ffa/scrap.lua
Normal file
@ -0,0 +1,36 @@
|
||||
local Public = {}
|
||||
|
||||
local scrapable = {
|
||||
-- simple entity
|
||||
"small-ship-wreck",
|
||||
"medium-ship-wreck",
|
||||
-- simple entity with owner
|
||||
"crash-site-spaceship-wreck-small-1",
|
||||
"crash-site-spaceship-wreck-small-2",
|
||||
"crash-site-spaceship-wreck-small-3",
|
||||
"crash-site-spaceship-wreck-small-4",
|
||||
"crash-site-spaceship-wreck-small-5",
|
||||
"crash-site-spaceship-wreck-small-6",
|
||||
"big-ship-wreck-1",
|
||||
"big-ship-wreck-2",
|
||||
"big-ship-wreck-3",
|
||||
"crash-site-chest-1",
|
||||
"crash-site-chest-2",
|
||||
"crash-site-spaceship-wreck-medium-1",
|
||||
"crash-site-spaceship-wreck-medium-2",
|
||||
"crash-site-spaceship-wreck-medium-3",
|
||||
"crash-site-spaceship-wreck-big-1",
|
||||
"crash-site-spaceship-wreck-big-2",
|
||||
"crash-site-spaceship"
|
||||
}
|
||||
|
||||
function Public.is_scrap(entity)
|
||||
if not entity.valid then return false end
|
||||
local f = false
|
||||
for i = 1, #scrapable, 1 do
|
||||
if entity.name == scrapable[i] then f = true end
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
return Public
|
103
modules/scrap_towny_ffa/slots.lua
Normal file
103
modules/scrap_towny_ffa/slots.lua
Normal file
@ -0,0 +1,103 @@
|
||||
local table_size = table.size
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
-- called whenever a player places an item
|
||||
local function on_built_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then return end
|
||||
if entity.name ~= "laser-turret" then return end
|
||||
local player = game.players[event.player_index]
|
||||
local force = player.force
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
local surface = entity.surface
|
||||
if force == game.forces["player"] or force == game.forces["rogue"] or town_center == nil then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "You are not acclimated to this technology!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
player.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local slots = town_center.upgrades.laser_turret.slots
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
if table_size(locations) >= slots then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "You do not have enough slots!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
player.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local position = entity.position
|
||||
local key = tostring("{" .. position.x .. "," .. position.y .. "}")
|
||||
locations[key] = true
|
||||
end
|
||||
|
||||
-- called whenever a player places an item
|
||||
local function on_robot_built_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then return end
|
||||
if entity.name ~= "laser-turret" then return end
|
||||
local robot = event.robot
|
||||
local force = robot.force
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
local surface = entity.surface
|
||||
if force == game.forces["player"] or force == game.forces["rogue"] or town_center == nil then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "Robot not acclimated to this technology!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
robot.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local slots = town_center.upgrades.laser_turret.slots
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
if table_size(locations) >= slots then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "Town does not have enough slots!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
robot.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local position = entity.position
|
||||
local key = tostring("{" .. position.x .. "," .. position.y .. "}")
|
||||
locations[key] = true
|
||||
end
|
||||
|
||||
-- called whenever a player mines an entity but before it is removed from the map
|
||||
-- will have the contents of the drops
|
||||
local function on_player_mined_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local force = player.force
|
||||
local entity = event.entity
|
||||
if entity.name == "laser-turret" then
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if force == game.forces["player"] or force == game.forces["rogue"] or town_center == nil then return end
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
local position = entity.position
|
||||
local key = tostring("{" .. position.x .. "," .. position.y .. "}")
|
||||
locations[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
183
modules/scrap_towny_ffa/spawn.lua
Normal file
183
modules/scrap_towny_ffa/spawn.lua
Normal file
@ -0,0 +1,183 @@
|
||||
local Public = {}
|
||||
|
||||
local table_size = table.size
|
||||
local table_insert = table.insert
|
||||
local math_random = math.random
|
||||
local math_rad = math.rad
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Enemy = require "modules.scrap_towny_ffa.enemy"
|
||||
local Building = require "modules.scrap_towny_ffa.building"
|
||||
|
||||
-- don't spawn if town is within this range
|
||||
local spawn_point_town_buffer = 256
|
||||
-- clear enemies within this distance from spawn
|
||||
local spawn_point_safety = 16
|
||||
-- incremental spawn distance from existing town
|
||||
-- this is how much each attempt is incremented by for checking a pollution free area
|
||||
local spawn_point_incremental_distance = 16
|
||||
|
||||
local function force_load(position, surface, radius)
|
||||
--log("is_chunk_generated = " .. tostring(surface.is_chunk_generated(position)))
|
||||
surface.request_to_generate_chunks(position, radius)
|
||||
--log("force load position = {" .. position.x .. "," .. position.y .. "}")
|
||||
surface.force_generate_chunk_requests()
|
||||
end
|
||||
|
||||
-- gets an area (might not be even amount)
|
||||
local function get_area(position, w, h)
|
||||
local x1 = math_floor(w / 2)
|
||||
local x2 = w - x1
|
||||
local y1 = math_floor(h / 2)
|
||||
local y2 = h - y1
|
||||
return { { position.x - x1, position.y - y1 }, { position.x + x2, position.y + y2 } }
|
||||
end
|
||||
|
||||
local function clear_spawn(position, surface, w, h)
|
||||
--log("clear_spawn {" .. position.x .. "," .. position.y .. "}")
|
||||
local area = get_area(position, w, h)
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = area })) do
|
||||
if e.type ~= "character" then
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- does the position have any pollution
|
||||
local function has_pollution(position, surface)
|
||||
local result = surface.get_pollution(position) > 0.0
|
||||
--log("has_pollution = " .. tostring(result))
|
||||
return result
|
||||
end
|
||||
|
||||
-- is the position already used
|
||||
local function in_use(position)
|
||||
local ffatable = Table.get_table()
|
||||
local result = false
|
||||
for _, v in pairs(ffatable.spawn_point) do
|
||||
if v == position then result = true end
|
||||
end
|
||||
--log("in_use = " .. tostring(result))
|
||||
return result
|
||||
end
|
||||
|
||||
-- is the position empty
|
||||
local function is_empty(position, surface)
|
||||
local entity_radius = 1
|
||||
local tile_radius = 1
|
||||
local entities = surface.count_entities_filtered({ position = position, radius = entity_radius, collision_mask = { "object-layer", "player-layer" } })
|
||||
--log("entities = " .. entities)
|
||||
if entities > 0 then return false end
|
||||
local tiles = surface.count_tiles_filtered({ position = position, radius = tile_radius, collision_mask = "water-tile" })
|
||||
--log("water-tiles = " .. tiles)
|
||||
if tiles > 0 then return false end
|
||||
local result = surface.can_place_entity({ name = "character", position = position })
|
||||
--log("is_empty = " .. tostring(result))
|
||||
return result
|
||||
end
|
||||
|
||||
-- finds a valid spawn point that is not near a town and not in a polluted area
|
||||
local function find_valid_spawn_point(surface)
|
||||
local ffatable = Table.get_table()
|
||||
-- check center of map first if valid
|
||||
local position = { x = 0, y = 0 }
|
||||
--log("testing {" .. position.x .. "," .. position.y .. "}")
|
||||
force_load(position, surface, 1)
|
||||
if in_use(position) == false then
|
||||
if Building.near_town(position, surface, spawn_point_town_buffer) == false then
|
||||
-- force load the position
|
||||
if is_empty(position, surface) == true then
|
||||
--log("found valid spawn point at {" .. position.x .. "," .. position.y .. "}")
|
||||
return position
|
||||
end
|
||||
end
|
||||
end
|
||||
-- otherwise find a nearby town
|
||||
local keyset = {}
|
||||
for town_name, _ in pairs(ffatable.town_centers) do
|
||||
table_insert(keyset, town_name)
|
||||
end
|
||||
local count = table_size(keyset)
|
||||
if count > 0 then
|
||||
local town_name = keyset[math_random(1, count)]
|
||||
local town_center = ffatable.town_centers[town_name]
|
||||
if town_center ~= nil then
|
||||
position = town_center.market.position
|
||||
end
|
||||
--log("town center is {" .. position.x .. "," .. position.y .. "}")
|
||||
end
|
||||
-- and start checking around it for a suitable spawn position
|
||||
local tries = 0
|
||||
local radius = spawn_point_town_buffer
|
||||
local angle
|
||||
while (tries < 100) do
|
||||
-- 8 attempts each position
|
||||
for _ = 1, 8 do
|
||||
-- position on the circle radius
|
||||
angle = math_random(0, 360)
|
||||
local t = math_rad(angle)
|
||||
local x = math_floor(position.x + math_cos(t) * radius)
|
||||
local y = math_floor(position.y + math_sin(t) * radius)
|
||||
local target = { x = x, y = y }
|
||||
--log("testing {" .. target.x .. "," .. target.y .. "}")
|
||||
force_load(position, surface, 1)
|
||||
if in_use(target) == false then
|
||||
if has_pollution(target, surface) == false then
|
||||
if Building.near_town(target, surface, spawn_point_town_buffer) == false then
|
||||
if is_empty(target, surface) == true then
|
||||
--log("found valid spawn point at {" .. target.x .. "," .. target.y .. "}")
|
||||
position = target
|
||||
return position
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- near a town, increment the radius and select another angle
|
||||
radius = radius + math_random(1, spawn_point_incremental_distance)
|
||||
angle = math_random(0, 360)
|
||||
tries = tries + 1
|
||||
end
|
||||
return { x = 0, y = 0 }
|
||||
end
|
||||
|
||||
function Public.get_new_spawn_point(player, surface)
|
||||
local ffatable = Table.get_table()
|
||||
-- get a new spawn point
|
||||
local position = find_valid_spawn_point(surface)
|
||||
-- should never be invalid or blocked
|
||||
ffatable.spawn_point[player.name] = position
|
||||
--log("player " .. player.name .. " assigned new spawn point at {" .. position.x .. "," .. position.y .. "}")
|
||||
return position
|
||||
end
|
||||
|
||||
-- gets a new or existing spawn point for the player
|
||||
function Public.get_spawn_point(player, surface)
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.spawn_point == nil then ffatable.spawn_point = {} end
|
||||
-- test the existing spawn point
|
||||
local position = ffatable.spawn_point[player.name]
|
||||
if position ~= nil then
|
||||
-- check that the spawn point is not blocked
|
||||
if surface.can_place_entity({ name = "character", position = position }) then
|
||||
--log("player " .. player.name .. "using existing spawn point at {" .. position.x .. "," .. position.y .. "}")
|
||||
return position
|
||||
else
|
||||
position = surface.find_non_colliding_position("character", position, 16, 0.25)
|
||||
if (position ~= nil) then return position end
|
||||
end
|
||||
end
|
||||
-- otherwise get a new spawn point
|
||||
return Public.get_new_spawn_point(player, surface)
|
||||
end
|
||||
|
||||
function Public.clear_spawn_point(position, surface)
|
||||
Enemy.clear_worms(position, surface, spawn_point_safety) -- behemoth worms can attack from a range of 48, clear first time only
|
||||
Enemy.clear_enemies(position, surface, spawn_point_safety) -- behemoth worms can attack from a range of 48
|
||||
clear_spawn(position, surface, 7, 9)
|
||||
end
|
||||
|
||||
return Public
|
33
modules/scrap_towny_ffa/spawners_contain_biters.lua
Normal file
33
modules/scrap_towny_ffa/spawners_contain_biters.lua
Normal file
@ -0,0 +1,33 @@
|
||||
-- spawners release biters on death -- by mewmew
|
||||
local math_random = math.random
|
||||
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
|
||||
local biter_building_inhabitants = {
|
||||
[1] = { { "small-biter", 8, 16 } },
|
||||
[2] = { { "small-biter", 12, 24 } },
|
||||
[3] = { { "small-biter", 8, 16 }, { "medium-biter", 1, 2 } },
|
||||
[4] = { { "small-biter", 4, 8 }, { "medium-biter", 4, 8 } },
|
||||
[5] = { { "small-biter", 3, 5 }, { "medium-biter", 8, 12 } },
|
||||
[6] = { { "small-biter", 3, 5 }, { "medium-biter", 5, 7 }, { "big-biter", 1, 2 } },
|
||||
[7] = { { "medium-biter", 6, 8 }, { "big-biter", 3, 5 } },
|
||||
[8] = { { "medium-biter", 2, 4 }, { "big-biter", 6, 8 } },
|
||||
[9] = { { "medium-biter", 2, 3 }, { "big-biter", 7, 9 } },
|
||||
[10] = { { "big-biter", 4, 8 }, { "behemoth-biter", 3, 4 } }
|
||||
}
|
||||
|
||||
local function on_entity_died(event)
|
||||
if not event.entity.valid then return end
|
||||
if event.entity.type ~= "unit-spawner" then return end
|
||||
local e = math.ceil(Evolution.get_biter_evolution(event.entity) * 10)
|
||||
if e < 1 then e = 1 end
|
||||
for _, t in pairs(biter_building_inhabitants[e]) do
|
||||
for _ = 1, math_random(t[2], t[3]), 1 do
|
||||
local p = event.entity.surface.find_non_colliding_position(t[1], event.entity.position, 6, 1)
|
||||
if p then event.entity.surface.create_entity { name = t[1], position = p, force = event.entity.force.name } end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
30
modules/scrap_towny_ffa/table.lua
Normal file
30
modules/scrap_towny_ffa/table.lua
Normal file
@ -0,0 +1,30 @@
|
||||
local Public = {}
|
||||
|
||||
-- one table to rule them all!
|
||||
local Global = require 'utils.global'
|
||||
local ffatable = {}
|
||||
Global.register(
|
||||
ffatable,
|
||||
function(tbl)
|
||||
ffatable = tbl
|
||||
end
|
||||
)
|
||||
|
||||
function Public.reset_table()
|
||||
for k, _ in pairs(ffatable) do
|
||||
ffatable[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Public.get_table()
|
||||
return ffatable
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
|
||||
return Public
|
681
modules/scrap_towny_ffa/team.lua
Normal file
681
modules/scrap_towny_ffa/team.lua
Normal file
@ -0,0 +1,681 @@
|
||||
local Public = {}
|
||||
|
||||
local table_size = table.size
|
||||
local string_match = string.match
|
||||
local string_lower = string.lower
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local outlander_color = { 150, 150, 150 }
|
||||
local outlander_chat_color = { 170, 170, 170 }
|
||||
local rogue_color = { 150, 150, 150 }
|
||||
local rogue_chat_color = { 170, 170, 170 }
|
||||
local item_drop_radius = 1.65
|
||||
|
||||
local function can_force_accept_member(force)
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local size_of_town_centers = ffatable.size_of_town_centers
|
||||
local member_limit = 0
|
||||
|
||||
if size_of_town_centers <= 1 then return true end
|
||||
|
||||
for _, town in pairs(town_centers) do
|
||||
member_limit = member_limit + table_size(town.market.force.connected_players)
|
||||
end
|
||||
member_limit = math.floor(member_limit / size_of_town_centers) + 4
|
||||
|
||||
if #force.connected_players >= member_limit then
|
||||
game.print(">> Town " .. force.name .. " has too many settlers! Current limit (" .. member_limit .. ")", { 255, 255, 0 })
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function is_towny(force)
|
||||
if force == game.forces["player"] or force == game.forces["rogue"] then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.has_key(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player == nil then return false end
|
||||
return ffatable.key[player]
|
||||
end
|
||||
|
||||
function Public.give_key(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player == nil then return end
|
||||
ffatable.key[player] = true
|
||||
end
|
||||
|
||||
function Public.remove_key(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player == nil then return end
|
||||
ffatable.key[player] = false
|
||||
end
|
||||
|
||||
function Public.set_player_color(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player.force == game.forces["player"] then
|
||||
player.color = outlander_color
|
||||
player.chat_color = outlander_chat_color
|
||||
return
|
||||
end
|
||||
if player.force == game.forces["rogue"] then
|
||||
player.color = rogue_color
|
||||
player.chat_color = rogue_chat_color
|
||||
return
|
||||
end
|
||||
local town_center = ffatable.town_centers[player.force.name]
|
||||
if not town_center then return end
|
||||
player.color = town_center.color
|
||||
player.chat_color = town_center.color
|
||||
end
|
||||
|
||||
local function set_town_color(event)
|
||||
local ffatable = Table.get_table()
|
||||
if event.command ~= "color" then return end
|
||||
local player = game.players[event.player_index]
|
||||
local force = player.force
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if not town_center then
|
||||
Public.set_player_color(player)
|
||||
return
|
||||
end
|
||||
town_center.color = { player.color.r, player.color.g, player.color.b }
|
||||
rendering.set_color(town_center.town_caption, town_center.color)
|
||||
for _, p in pairs(force.players) do
|
||||
Public.set_player_color(p)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set_all_player_colors()
|
||||
for _, p in pairs(game.connected_players) do
|
||||
Public.set_player_color(p)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_player_to_town(player, town_center)
|
||||
local ffatable = Table.get_table()
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
player.force = market.force
|
||||
Public.remove_key(player)
|
||||
ffatable.spawn_point[player.name] = force.get_spawn_position(surface)
|
||||
game.permissions.get_group(force.name).add_player(player)
|
||||
player.tag = ""
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
|
||||
function Public.give_outlander_items(player)
|
||||
player.insert({ name = "stone-furnace", count = 1 })
|
||||
player.insert({ name = "raw-fish", count = 3 })
|
||||
player.insert({ name = "coal", count = 3 })
|
||||
end
|
||||
|
||||
function Public.set_player_to_outlander(player)
|
||||
local ffatable = Table.get_table()
|
||||
player.force = game.forces.player
|
||||
if ffatable.spawn_point[player.name] then
|
||||
ffatable.spawn_point[player.name] = nil
|
||||
end
|
||||
if game.permissions.get_group("outlander") == nil then game.permissions.create_group("outlander") end
|
||||
game.permissions.get_group("outlander").add_player(player)
|
||||
player.tag = "[Outlander]"
|
||||
Public.set_player_color(player)
|
||||
Public.give_key(player)
|
||||
end
|
||||
|
||||
local function set_player_to_rogue(player)
|
||||
local ffatable = Table.get_table()
|
||||
player.force = game.forces["rogue"]
|
||||
if ffatable.spawn_point[player.name] then
|
||||
ffatable.spawn_point[player.name] = nil
|
||||
end
|
||||
if game.permissions.get_group("rogue") == nil then game.permissions.create_group("rogue") end
|
||||
game.permissions.get_group("rogue").add_player(player)
|
||||
player.tag = "[Rogue]"
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
|
||||
local function ally_outlander(player, target)
|
||||
local ffatable = Table.get_table()
|
||||
local requesting_force = player.force
|
||||
local target_force = target.force
|
||||
|
||||
-- don't handle request if target is not a town
|
||||
if not is_towny(requesting_force) and not is_towny(target_force) then return false end
|
||||
|
||||
-- don't handle request to another town if already in a town
|
||||
if is_towny(requesting_force) and is_towny(target_force) then return false end
|
||||
|
||||
-- handle the request
|
||||
if not is_towny(requesting_force) and is_towny(target_force) then
|
||||
ffatable.requests[player.index] = target_force.name
|
||||
|
||||
local target_player = false
|
||||
if target.type == "character" then
|
||||
target_player = target.player
|
||||
else
|
||||
target_player = game.players[target_force.name]
|
||||
end
|
||||
|
||||
if target_player then
|
||||
if ffatable.requests[target_player.index] then
|
||||
if ffatable.requests[target_player.index] == player.name then
|
||||
if ffatable.town_centers[target_force.name] then
|
||||
if not can_force_accept_member(target_force) then return true end
|
||||
game.print(">> " .. player.name .. " has settled in " .. target_force.name .. "'s Town!", { 255, 255, 0 })
|
||||
Public.add_player_to_town(player, ffatable.town_centers[target_force.name])
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
game.print(">> " .. player.name .. " wants to settle in " .. target_force.name .. " Town!", { 255, 255, 0 })
|
||||
return true
|
||||
end
|
||||
|
||||
-- handle the approval
|
||||
if is_towny(requesting_force) and not is_towny(target_force) then
|
||||
if target.type ~= "character" then return true end
|
||||
local target_player = target.player
|
||||
if not target_player then return true end
|
||||
ffatable.requests[player.index] = target_player.name
|
||||
|
||||
if ffatable.requests[target_player.index] then
|
||||
if ffatable.requests[target_player.index] == player.force.name then
|
||||
if not can_force_accept_member(player.force) then return true end
|
||||
if player.force.name == player.name then
|
||||
game.print(">> " .. player.name .. " has accepted " .. target_player.name .. " into their Town!", { 255, 255, 0 })
|
||||
else
|
||||
game.print(">> " .. player.name .. " has accepted " .. target_player.name .. " into" .. player.force.name .. "'s Town!", { 255, 255, 0 })
|
||||
end
|
||||
Public.add_player_to_town(target_player, ffatable.town_centers[player.force.name])
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if player.force.name == player.name then
|
||||
game.print(">> " .. player.name .. " is inviting " .. target_player.name .. " into their Town!", { 255, 255, 0 })
|
||||
else
|
||||
game.print(">> " .. player.name .. " is inviting " .. target_player.name .. " into " .. player.force.name .. "'s Town!", { 255, 255, 0 })
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ally_neighbour_towns(player, target)
|
||||
local requesting_force = player.force
|
||||
local target_force = target.force
|
||||
|
||||
if target_force.get_friend(requesting_force) and requesting_force.get_friend(target_force) then return end
|
||||
|
||||
requesting_force.set_friend(target_force, true)
|
||||
game.print(">> Town " .. requesting_force.name .. " has set " .. target_force.name .. " as their friend!", { 255, 255, 0 })
|
||||
|
||||
if target_force.get_friend(requesting_force) then
|
||||
game.print(">> The towns " .. requesting_force.name .. " and " .. target_force.name .. " have formed an alliance!", { 255, 255, 0 })
|
||||
end
|
||||
end
|
||||
|
||||
local function ally_town(player, item)
|
||||
local position = item.position
|
||||
local surface = player.surface
|
||||
local area = { { position.x - item_drop_radius, position.y - item_drop_radius }, { position.x + item_drop_radius, position.y + item_drop_radius } }
|
||||
local requesting_force = player.force
|
||||
local target = false
|
||||
|
||||
for _, e in pairs(surface.find_entities_filtered({ type = { "character", "market" }, area = area })) do
|
||||
if e.force.name ~= requesting_force.name then
|
||||
target = e
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not target then return end
|
||||
if target.force == game.forces["enemy"] or target.force == game.forces["neutral"] then return end
|
||||
|
||||
if ally_outlander(player, target) then return end
|
||||
ally_neighbour_towns(player, target)
|
||||
end
|
||||
|
||||
local function declare_war(player, item)
|
||||
local ffatable = Table.get_table()
|
||||
local position = item.position
|
||||
local surface = player.surface
|
||||
local area = { { position.x - item_drop_radius, position.y - item_drop_radius }, { position.x + item_drop_radius, position.y + item_drop_radius } }
|
||||
|
||||
local requesting_force = player.force
|
||||
local target = surface.find_entities_filtered({ type = { "character", "market" }, area = area })[1]
|
||||
|
||||
if not target then return end
|
||||
local target_force = target.force
|
||||
if not is_towny(target_force) then return end
|
||||
|
||||
if requesting_force.name == target_force.name then
|
||||
if player.name ~= target.force.name then
|
||||
Public.set_player_to_outlander(player)
|
||||
game.print(">> " .. player.name .. " has abandoned " .. target_force.name .. "'s Town!", { 255, 255, 0 })
|
||||
ffatable.requests[player.index] = nil
|
||||
end
|
||||
if player.name == target.force.name then
|
||||
if target.type ~= "character" then return end
|
||||
local target_player = target.player
|
||||
if not target_player then return end
|
||||
if target_player.index == player.index then return end
|
||||
Public.set_player_to_outlander(target_player)
|
||||
game.print(">> " .. player.name .. " has banished " .. target_player.name .. " from their Town!", { 255, 255, 0 })
|
||||
ffatable.requests[player.index] = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not is_towny(requesting_force) then return end
|
||||
|
||||
requesting_force.set_friend(target_force, false)
|
||||
target_force.set_friend(requesting_force, false)
|
||||
|
||||
game.print(">> " .. player.name .. " has dropped the coal! Town " .. target_force.name .. " and " .. requesting_force.name .. " are now at war!", { 255, 255, 0 })
|
||||
end
|
||||
|
||||
local function delete_chart_tag_for_all_forces(market)
|
||||
local forces = game.forces
|
||||
local position = market.position
|
||||
local surface = market.surface
|
||||
for _, force in pairs(forces) do
|
||||
local tags = force.find_chart_tags(surface, { { position.x - 0.1, position.y - 0.1 }, { position.x + 0.1, position.y + 0.1 } })
|
||||
local tag = tags[1]
|
||||
if tag then
|
||||
if tag.icon.name == "stone-furnace" then
|
||||
tag.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_chart_tag(force, market)
|
||||
local position = market.position
|
||||
local tags = force.find_chart_tags(market.surface, { { position.x - 0.1, position.y - 0.1 }, { position.x + 0.1, position.y + 0.1 } })
|
||||
if tags[1] then return end
|
||||
force.add_chart_tag(market.surface, { icon = { type = 'item', name = 'stone-furnace' }, position = position, text = market.force.name .. "'s Town" })
|
||||
end
|
||||
|
||||
function Public.update_town_chart_tags()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local forces = game.forces
|
||||
for _, town_center in pairs(town_centers) do
|
||||
local market = town_center.market
|
||||
for _, force in pairs(forces) do
|
||||
if force.is_chunk_visible(market.surface, town_center.chunk_position) then
|
||||
Public.add_chart_tag(force, market)
|
||||
end
|
||||
end
|
||||
end
|
||||
if game.forces["player"] ~= nil then game.forces["player"].clear_chart(game.surfaces["nauvis"]) end
|
||||
if game.forces["rogue"] ~= nil then game.forces["rogue"].clear_chart(game.surfaces["nauvis"]) end
|
||||
end
|
||||
|
||||
local function reset_permissions(permission_group)
|
||||
for action_name, _ in pairs(defines.input_action) do
|
||||
permission_group.set_allows_action(defines.input_action[action_name], true)
|
||||
end
|
||||
end
|
||||
|
||||
local function disable_blueprints(permission_group)
|
||||
local defs = {
|
||||
defines.input_action.alt_select_blueprint_entities,
|
||||
defines.input_action.cancel_new_blueprint,
|
||||
defines.input_action.change_blueprint_record_label,
|
||||
defines.input_action.clear_selected_blueprint,
|
||||
defines.input_action.create_blueprint_like,
|
||||
defines.input_action.cycle_blueprint_backwards,
|
||||
defines.input_action.cycle_blueprint_forwards,
|
||||
defines.input_action.delete_blueprint_library,
|
||||
defines.input_action.delete_blueprint_record,
|
||||
defines.input_action.drop_blueprint_record,
|
||||
defines.input_action.drop_to_blueprint_book,
|
||||
defines.input_action.export_blueprint,
|
||||
defines.input_action.grab_blueprint_record,
|
||||
defines.input_action.import_blueprint,
|
||||
defines.input_action.import_blueprint_string,
|
||||
defines.input_action.open_blueprint_library_gui,
|
||||
defines.input_action.open_blueprint_record,
|
||||
defines.input_action.select_blueprint_entities,
|
||||
defines.input_action.setup_blueprint,
|
||||
defines.input_action.setup_single_blueprint_record,
|
||||
defines.input_action.upgrade_open_blueprint,
|
||||
defines.input_action.deconstruct,
|
||||
defines.input_action.clear_selected_deconstruction_item,
|
||||
defines.input_action.cancel_deconstruct,
|
||||
defines.input_action.toggle_deconstruction_item_entity_filter_mode,
|
||||
defines.input_action.toggle_deconstruction_item_tile_filter_mode,
|
||||
defines.input_action.set_deconstruction_item_tile_selection_mode,
|
||||
defines.input_action.set_deconstruction_item_trees_and_rocks_only,
|
||||
}
|
||||
for _, d in pairs(defs) do permission_group.set_allows_action(d, false) end
|
||||
end
|
||||
|
||||
local function enable_artillery(force, permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.use_artillery_remote, true)
|
||||
force.technologies["artillery"].enabled = true
|
||||
force.technologies["artillery-shell-range-1"].enabled = false
|
||||
force.technologies["artillery-shell-speed-1"].enabled = false
|
||||
force.recipes["artillery-turret"].enabled = true
|
||||
force.recipes["artillery-wagon"].enabled = true
|
||||
force.recipes["artillery-targeting-remote"].enabled = true
|
||||
force.recipes["artillery-shell"].enabled = true
|
||||
end
|
||||
|
||||
local function disable_artillery(force, permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.use_artillery_remote, false)
|
||||
force.technologies["artillery"].enabled = false
|
||||
force.technologies["artillery-shell-range-1"].enabled = false
|
||||
force.technologies["artillery-shell-speed-1"].enabled = false
|
||||
force.recipes["artillery-turret"].enabled = false
|
||||
force.recipes["artillery-wagon"].enabled = false
|
||||
force.recipes["artillery-targeting-remote"].enabled = false
|
||||
force.recipes["artillery-shell"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_spidertron(force, permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.send_spidertron, false)
|
||||
force.technologies["spidertron"].enabled = false
|
||||
force.recipes["spidertron"].enabled = false
|
||||
force.recipes["spidertron-remote"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_rockets(force)
|
||||
force.technologies["rocketry"].enabled = false
|
||||
force.technologies["explosive-rocketry"].enabled = false
|
||||
force.recipes["rocket-launcher"].enabled = false
|
||||
force.recipes["rocket"].enabled = false
|
||||
force.recipes["explosive-rocket"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_nukes(force)
|
||||
force.technologies["atomic-bomb"].enabled = false
|
||||
force.recipes["atomic-bomb"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_cluster_grenades(force)
|
||||
force.recipes["cluster-grenade"].enabled = false
|
||||
end
|
||||
|
||||
local function enable_radar(force)
|
||||
force.recipes["radar"].enabled = true
|
||||
force.share_chart = true
|
||||
force.clear_chart("nauvis")
|
||||
end
|
||||
|
||||
local function disable_radar(force)
|
||||
force.recipes["radar"].enabled = false
|
||||
force.share_chart = false
|
||||
force.clear_chart("nauvis")
|
||||
end
|
||||
|
||||
local function disable_achievements(permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.open_achievements_gui, false)
|
||||
end
|
||||
|
||||
local function disable_tips_and_tricks(permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.open_tips_and_tricks_gui, false)
|
||||
end
|
||||
|
||||
-- setup a team force
|
||||
function Public.add_new_force(force_name)
|
||||
-- disable permissions
|
||||
local force = game.create_force(force_name)
|
||||
local permission_group = game.permissions.create_group(force_name)
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
enable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
disable_nukes(force)
|
||||
disable_cluster_grenades(force)
|
||||
enable_radar(force)
|
||||
disable_achievements(permission_group)
|
||||
disable_tips_and_tricks(permission_group)
|
||||
-- friendly fire
|
||||
force.friendly_fire = true
|
||||
-- disable technologies
|
||||
force.research_queue_enabled = true
|
||||
-- balance initial combat
|
||||
force.set_ammo_damage_modifier("landmine", -0.75)
|
||||
force.set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
|
||||
local function kill_force(force_name)
|
||||
local ffatable = Table.get_table()
|
||||
local force = game.forces[force_name]
|
||||
local market = ffatable.town_centers[force_name].market
|
||||
local surface = market.surface
|
||||
surface.create_entity({ name = "big-artillery-explosion", position = market.position })
|
||||
for _, player in pairs(force.players) do
|
||||
if player.character then
|
||||
player.character.die()
|
||||
else
|
||||
ffatable.requests[player.index] = "kill-character"
|
||||
end
|
||||
player.force = game.forces.player
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = force_name })) do
|
||||
if e.valid then
|
||||
if e.type == "wall" or e.type == "gate" then
|
||||
e.die()
|
||||
end
|
||||
end
|
||||
end
|
||||
game.merge_forces(force_name, "neutral")
|
||||
ffatable.town_centers[force_name] = nil
|
||||
ffatable.size_of_town_centers = ffatable.size_of_town_centers - 1
|
||||
delete_chart_tag_for_all_forces(market)
|
||||
game.print(">> " .. force_name .. "'s town has fallen! [gps=" .. math.floor(market.position.x) .. "," .. math.floor(market.position.y) .. "]", { 255, 255, 0 })
|
||||
end
|
||||
|
||||
local player_force_disabled_recipes = { "lab", "automation-science-pack", "stone-brick", "radar" }
|
||||
local player_force_enabled_recipes = { "submachine-gun", "assembling-machine-1", "small-lamp", "shotgun", "shotgun-shell", "underground-belt", "splitter", "steel-plate", "car", "cargo-wagon", "constant-combinator", "engine-unit", "green-wire", "locomotive", "rail", "train-stop", "arithmetic-combinator", "decider-combinator" }
|
||||
|
||||
-- setup the player force (this is the default for Outlanders)
|
||||
local function setup_player_force()
|
||||
local force = game.forces.player
|
||||
local permission_group = game.permissions.create_group("outlander")
|
||||
-- disable permissions
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
disable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
disable_nukes(force)
|
||||
disable_cluster_grenades(force)
|
||||
disable_radar(force)
|
||||
disable_achievements(permission_group)
|
||||
disable_tips_and_tricks(permission_group)
|
||||
-- disable research
|
||||
force.disable_research()
|
||||
force.research_queue_enabled = false
|
||||
-- friendly fire
|
||||
force.friendly_fire = true
|
||||
-- disable recipes
|
||||
local recipes = force.recipes
|
||||
for _, recipe_name in pairs(player_force_disabled_recipes) do
|
||||
recipes[recipe_name].enabled = false
|
||||
end
|
||||
for _, recipe_name in pairs(player_force_enabled_recipes) do
|
||||
recipes[recipe_name].enabled = true
|
||||
end
|
||||
force.set_ammo_damage_modifier("landmine", -0.75)
|
||||
force.set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
|
||||
local function setup_rogue_force()
|
||||
local force_name = "rogue"
|
||||
local force = game.create_force(force_name)
|
||||
local permission_group = game.permissions.create_group(force_name)
|
||||
-- disable permissions
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
disable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
disable_nukes(force)
|
||||
disable_cluster_grenades(force)
|
||||
disable_radar(force)
|
||||
disable_achievements(permission_group)
|
||||
disable_tips_and_tricks(permission_group)
|
||||
-- disable research
|
||||
force.disable_research()
|
||||
force.research_queue_enabled = false
|
||||
-- friendly fire
|
||||
force.friendly_fire = true
|
||||
-- disable recipes
|
||||
local recipes = force.recipes
|
||||
for _, recipe_name in pairs(player_force_disabled_recipes) do
|
||||
recipes[recipe_name].enabled = false
|
||||
end
|
||||
for _, recipe_name in pairs(player_force_enabled_recipes) do
|
||||
recipes[recipe_name].enabled = true
|
||||
end
|
||||
force.set_ammo_damage_modifier("landmine", -0.75)
|
||||
force.set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
|
||||
local function setup_enemy_force()
|
||||
local e_force = game.forces["enemy"]
|
||||
e_force.evolution_factor = 1 -- this should never change since we are changing biter types on spawn
|
||||
e_force.set_friend(game.forces.player, true) -- outlander force (player) should not be attacked by turrets
|
||||
e_force.set_cease_fire(game.forces.player, true) -- outlander force (player) should not be attacked by units
|
||||
e_force.set_friend(game.forces["rogue"], false) -- rogue force (rogue) should be attacked by turrets
|
||||
e_force.set_cease_fire(game.forces["rogue"], false) -- rogue force (rogue) should be attacked by units
|
||||
-- note, these don't prevent an outlander or rogue from attacking a unit or spawner, we need to handle separately
|
||||
end
|
||||
|
||||
local function on_player_dropped_item(event)
|
||||
local player = game.players[event.player_index]
|
||||
local entity = event.entity
|
||||
if entity.stack.name == "raw-fish" then
|
||||
ally_town(player, entity)
|
||||
return
|
||||
end
|
||||
if entity.stack.name == "coal" then
|
||||
declare_war(player, entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
---- when a player dies, reveal their base to everyone
|
||||
--local function on_player_died(event)
|
||||
-- local player = game.players[event.player_index]
|
||||
-- if not player.character then return end
|
||||
-- if not player.character.valid then return end
|
||||
-- reveal_entity_to_all(player.character)
|
||||
--end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local cause = event.cause
|
||||
local force = event.force
|
||||
|
||||
-- special case to handle enemies attacked by outlanders
|
||||
if entity.force == game.forces["enemy"] then
|
||||
if cause ~= nil then
|
||||
if cause.type == "character" and force == game.forces["player"] then
|
||||
local player = cause.player
|
||||
if force == game.forces["player"] then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(player)
|
||||
end
|
||||
end
|
||||
-- cars and tanks
|
||||
if cause.type == "car" or cause.type == "tank" then
|
||||
local driver = cause.get_driver()
|
||||
if driver ~= nil and driver.force == game.forces["player"] then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(driver)
|
||||
end
|
||||
local passenger = cause.get_passenger()
|
||||
if passenger ~= nil and passenger.force == game.forces["player"] then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(passenger)
|
||||
end
|
||||
end
|
||||
-- trains
|
||||
if cause.type == "locomotive" or cause.type == "cargo-wagon" or cause.type == "fluid-wagon" or cause.type == "artillery-wagon" then
|
||||
local train = cause.train
|
||||
for _, passenger in pairs(train.passengers) do
|
||||
if passenger ~= nil and passenger.force == game.forces["player"] then
|
||||
set_player_to_rogue(passenger)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- combat robots
|
||||
if cause.type == "combat-robot" and force == game.forces["player"] then
|
||||
local owner = cause.last_user
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(owner)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if entity.name == "market" then
|
||||
kill_force(entity.force.name)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_post_entity_died(event)
|
||||
local prototype = event.prototype.type
|
||||
if prototype ~= "character" then return end
|
||||
local entities = game.surfaces[event.surface_index].find_entities_filtered({ position = event.position, radius = 1 })
|
||||
for _, e in pairs(entities) do
|
||||
if e.type == "character-corpse" then
|
||||
Public.remove_key(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_console_command(event)
|
||||
set_town_color(event)
|
||||
end
|
||||
|
||||
local function on_console_chat(event)
|
||||
local player = game.players[event.player_index]
|
||||
if string_match(string_lower(event.message), "%[armor%=") then
|
||||
player.clear_console()
|
||||
game.print(">> " .. player.name .. " is trying to gain an unfair advantage!")
|
||||
end
|
||||
end
|
||||
|
||||
function Public.initialize()
|
||||
setup_player_force()
|
||||
setup_rogue_force()
|
||||
setup_enemy_force()
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.key = {}
|
||||
ffatable.spawn_point = {}
|
||||
ffatable.requests = {}
|
||||
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_player_dropped_item, on_player_dropped_item)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_post_entity_died, on_post_entity_died)
|
||||
Event.add(defines.events.on_console_command, on_console_command)
|
||||
Event.add(defines.events.on_console_chat, on_console_chat)
|
||||
|
||||
return Public
|
92
modules/scrap_towny_ffa/tick_tack_trap.lua
Normal file
92
modules/scrap_towny_ffa/tick_tack_trap.lua
Normal file
@ -0,0 +1,92 @@
|
||||
-- timer traps -- by mewmew
|
||||
local table_insert = table.insert
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local tick_tacks = { "*tick*", "*tick*", "*tack*", "*tak*", "*tik*", "*tok*" }
|
||||
|
||||
local kaboom_weights = {
|
||||
{ name = "grenade", chance = 7 },
|
||||
{ name = "cluster-grenade", chance = 1 },
|
||||
{ name = "destroyer-capsule", chance = 1 },
|
||||
{ name = "defender-capsule", chance = 4 },
|
||||
{ name = "distractor-capsule", chance = 3 },
|
||||
{ name = "poison-capsule", chance = 2 },
|
||||
{ name = "explosive-uranium-cannon-projectile", chance = 3 },
|
||||
{ name = "explosive-cannon-projectile", chance = 5 },
|
||||
}
|
||||
|
||||
local kabooms = {}
|
||||
for _, t in pairs(kaboom_weights) do
|
||||
for _ = 1, t.chance, 1 do
|
||||
table_insert(kabooms, t.name)
|
||||
end
|
||||
end
|
||||
|
||||
local function create_flying_text(surface, position, text)
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = text,
|
||||
color = { r = 0.75, g = 0.75, b = 0.75 }
|
||||
})
|
||||
if text == "..." then return end
|
||||
surface.play_sound({ path = "utility/armor_insert", position = position, volume_modifier = 0.75 })
|
||||
end
|
||||
|
||||
local function create_kaboom(surface, position, name)
|
||||
local target = position
|
||||
local speed = 0.5
|
||||
if name == "defender-capsule" or name == "destroyer-capsule" or name == "distractor-capsule" then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "(((Sentries Engaging Target)))",
|
||||
color = { r = 0.8, g = 0.0, b = 0.0 }
|
||||
})
|
||||
local nearest_player_unit = surface.find_nearest_enemy({ position = position, max_distance = 128, force = "enemy" })
|
||||
if nearest_player_unit then target = nearest_player_unit.position end
|
||||
speed = 0.001
|
||||
end
|
||||
surface.create_entity({
|
||||
name = name,
|
||||
position = position,
|
||||
force = "enemy",
|
||||
target = target,
|
||||
speed = speed
|
||||
})
|
||||
end
|
||||
|
||||
local function tick_tack_trap(surface, position)
|
||||
local ffatable = Table.get_table()
|
||||
if not surface then return end
|
||||
if not position then return end
|
||||
if not position.x then return end
|
||||
if not position.y then return end
|
||||
local tick_tack_count = math_random(5, 9)
|
||||
for t = 60, tick_tack_count * 60, 60 do
|
||||
if not ffatable.on_tick_schedule[game.tick + t] then ffatable.on_tick_schedule[game.tick + t] = {} end
|
||||
|
||||
if t < tick_tack_count * 60 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_flying_text,
|
||||
args = { surface, { x = position.x, y = position.y }, tick_tacks[math_random(1, #tick_tacks)] }
|
||||
}
|
||||
else
|
||||
if math_random(1, 10) == 1 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_flying_text,
|
||||
args = { surface, { x = position.x, y = position.y }, "..." }
|
||||
}
|
||||
else
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_kaboom,
|
||||
args = { surface, { x = position.x, y = position.y }, kabooms[math_random(1, #kabooms)] }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return tick_tack_trap
|
523
modules/scrap_towny_ffa/town_center.lua
Normal file
523
modules/scrap_towny_ffa/town_center.lua
Normal file
@ -0,0 +1,523 @@
|
||||
local Public = {}
|
||||
|
||||
local math_random = math.random
|
||||
local table_insert = table.insert
|
||||
local math_floor = math.floor
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Team = require "modules.scrap_towny_ffa.team"
|
||||
local Building = require "modules.scrap_towny_ffa.building"
|
||||
|
||||
local town_radius = 27
|
||||
local radius_between_towns = 160
|
||||
local ore_amount = 250
|
||||
|
||||
local colors = {}
|
||||
local c1 = 250
|
||||
local c2 = 210
|
||||
local c3 = -40
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { 0, 0, v })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { 0, v, 0 })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { v, 0, 0 })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { 0, v, v })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { v, v, 0 })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { v, 0, v })
|
||||
end
|
||||
|
||||
local town_wall_vectors = {}
|
||||
for x = 2, town_radius, 1 do
|
||||
table_insert(town_wall_vectors, { x, town_radius })
|
||||
table_insert(town_wall_vectors, { x * -1, town_radius })
|
||||
table_insert(town_wall_vectors, { x, town_radius * -1 })
|
||||
table_insert(town_wall_vectors, { x * -1, town_radius * -1 })
|
||||
end
|
||||
for y = 2, town_radius - 1, 1 do
|
||||
table_insert(town_wall_vectors, { town_radius, y })
|
||||
table_insert(town_wall_vectors, { town_radius, y * -1 })
|
||||
table_insert(town_wall_vectors, { town_radius * -1, y })
|
||||
table_insert(town_wall_vectors, { town_radius * -1, y * -1 })
|
||||
end
|
||||
|
||||
local gate_vectors_horizontal = {}
|
||||
for x = -1, 1, 1 do
|
||||
table_insert(gate_vectors_horizontal, { x, town_radius })
|
||||
table_insert(gate_vectors_horizontal, { x, town_radius * -1 })
|
||||
end
|
||||
local gate_vectors_vertical = {}
|
||||
for y = -1, 1, 1 do
|
||||
table_insert(gate_vectors_vertical, { town_radius, y })
|
||||
table_insert(gate_vectors_vertical, { town_radius * -1, y })
|
||||
end
|
||||
|
||||
local resource_vectors = {}
|
||||
resource_vectors[1] = {}
|
||||
for x = 7, 24, 1 do
|
||||
for y = 7, 24, 1 do
|
||||
table_insert(resource_vectors[1], { x, y })
|
||||
end
|
||||
end
|
||||
resource_vectors[2] = {}
|
||||
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[2], { vector[1] * -1, vector[2] }) end
|
||||
resource_vectors[3] = {}
|
||||
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[3], { vector[1] * -1, vector[2] * -1 }) end
|
||||
resource_vectors[4] = {}
|
||||
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[4], { vector[1], vector[2] * -1 }) end
|
||||
|
||||
local additional_resource_vectors = {}
|
||||
additional_resource_vectors[1] = {}
|
||||
for x = 10, 22, 1 do
|
||||
for y = -4, 4, 1 do
|
||||
table_insert(additional_resource_vectors[1], { x, y })
|
||||
end
|
||||
end
|
||||
additional_resource_vectors[2] = {}
|
||||
for _, vector in pairs(additional_resource_vectors[1]) do table_insert(additional_resource_vectors[2], { vector[1] * -1, vector[2] }) end
|
||||
additional_resource_vectors[3] = {}
|
||||
for y = 10, 22, 1 do
|
||||
for x = -4, 4, 1 do
|
||||
table_insert(additional_resource_vectors[3], { x, y })
|
||||
end
|
||||
end
|
||||
additional_resource_vectors[4] = {}
|
||||
for _, vector in pairs(additional_resource_vectors[3]) do table_insert(additional_resource_vectors[4], { vector[1], vector[2] * -1 }) end
|
||||
|
||||
local clear_whitelist_types = {
|
||||
["simple-entity"] = true,
|
||||
["resource"] = true,
|
||||
["cliff"] = true,
|
||||
["tree"] = true,
|
||||
}
|
||||
|
||||
local starter_supplies = {
|
||||
{ name = "raw-fish", count = 3 },
|
||||
{ name = "grenade", count = 3 },
|
||||
{ name = "stone", count = 32 },
|
||||
{ name = "land-mine", count = 4 },
|
||||
{ name = "iron-gear-wheel", count = 16 },
|
||||
{ name = "iron-plate", count = 32 },
|
||||
{ name = "copper-plate", count = 16 },
|
||||
{ name = "shotgun", count = 1 },
|
||||
{ name = "shotgun-shell", count = 8 },
|
||||
{ name = "firearm-magazine", count = 16 },
|
||||
{ name = "firearm-magazine", count = 16 },
|
||||
{ name = "gun-turret", count = 2 },
|
||||
}
|
||||
|
||||
local function count_nearby_ore(surface, position, ore_name)
|
||||
local count = 0
|
||||
local r = town_radius + 8
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = { { position.x - r, position.y - r }, { position.x + r, position.y + r } }, force = "neutral", name = ore_name })) do
|
||||
count = count + e.amount
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
local function draw_town_spawn(player_name)
|
||||
local ffatable = Table.get_table()
|
||||
local market = ffatable.town_centers[player_name].market
|
||||
local position = market.position
|
||||
local surface = market.surface
|
||||
|
||||
local area = { { position.x - (town_radius + 1), position.y - (town_radius + 1) }, { position.x + (town_radius + 1), position.y + (town_radius + 1) } }
|
||||
|
||||
-- remove other than cliffs, rocks and ores and trees
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = area, force = "neutral" })) do
|
||||
if not clear_whitelist_types[e.type] then
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
-- create walls
|
||||
for _, vector in pairs(gate_vectors_horizontal) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
--p = surface.find_non_colliding_position("gate", p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = "gate", position = p, force = player_name, direction = 2 })
|
||||
end
|
||||
end
|
||||
for _, vector in pairs(gate_vectors_vertical) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
--p = surface.find_non_colliding_position("gate", p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = "gate", position = p, force = player_name, direction = 0 })
|
||||
end
|
||||
end
|
||||
|
||||
for _, vector in pairs(town_wall_vectors) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
--p = surface.find_non_colliding_position("stone-wall", p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = "stone-wall", position = p, force = player_name })
|
||||
end
|
||||
end
|
||||
|
||||
-- ore patches
|
||||
local ores = { "iron-ore", "copper-ore", "stone", "coal" }
|
||||
table_shuffle(ores)
|
||||
|
||||
for i = 1, 4, 1 do
|
||||
if count_nearby_ore(surface, position, ores[i]) < 200000 then
|
||||
for _, vector in pairs(resource_vectors[i]) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
p = surface.find_non_colliding_position(ores[i], p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = ores[i], position = p, amount = ore_amount })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- starter chests
|
||||
for _, item_stack in pairs(starter_supplies) do
|
||||
local m1 = -8 + math_random(0, 16)
|
||||
local m2 = -8 + math_random(0, 16)
|
||||
local p = { position.x + m1, position.y + m2 }
|
||||
p = surface.find_non_colliding_position("wooden-chest", p, 64, 1)
|
||||
if p then
|
||||
local e = surface.create_entity({ name = "wooden-chest", position = p, force = player_name })
|
||||
local inventory = e.get_inventory(defines.inventory.chest)
|
||||
inventory.insert(item_stack)
|
||||
end
|
||||
end
|
||||
|
||||
local vector_indexes = { 1, 2, 3, 4 }
|
||||
table_shuffle(vector_indexes)
|
||||
|
||||
-- trees
|
||||
--local tree = "tree-0" .. math_random(1, 9)
|
||||
--for _, vector in pairs(additional_resource_vectors[vector_indexes[1]]) do
|
||||
-- if math_random(1, 6) == 1 then
|
||||
-- local p = {position.x + vector[1], position.y + vector[2]}
|
||||
-- p = surface.find_non_colliding_position(tree, p, 64, 1)
|
||||
-- if p then
|
||||
-- surface.create_entity({name = tree, position = p})
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
|
||||
--local area = {{position.x - town_radius * 1.5, position.y - town_radius * 1.5}, {position.x + town_radius * 1.5, position.y + town_radius * 1.5}}
|
||||
|
||||
-- pond
|
||||
for _, vector in pairs(additional_resource_vectors[vector_indexes[2]]) do
|
||||
local x = position.x + vector[1]
|
||||
local y = position.y + vector[2]
|
||||
local p = { x = x, y = y }
|
||||
if surface.get_tile(p).name ~= "out-of-map" then
|
||||
surface.set_tiles({ { name = "water-green", position = p } })
|
||||
end
|
||||
end
|
||||
|
||||
-- fish
|
||||
for _, vector in pairs(additional_resource_vectors[vector_indexes[2]]) do
|
||||
local x = position.x + vector[1] + 0.5
|
||||
local y = position.y + vector[2] + 0.5
|
||||
local p = { x = x, y = y }
|
||||
if math_random(1, 5) == 1 then
|
||||
if surface.can_place_entity({ name = "fish", position = p }) then
|
||||
surface.create_entity({ name = "water-splash", position = p })
|
||||
surface.create_entity({ name = "fish", position = p })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- uranium ore
|
||||
--if count_nearby_ore(surface, position, "uranium-ore") < 100000 then
|
||||
-- for _, vector in pairs(additional_resource_vectors[vector_indexes[3]]) do
|
||||
-- local p = {position.x + vector[1], position.y + vector[2]}
|
||||
-- p = surface.find_non_colliding_position("uranium-ore", p, 64, 1)
|
||||
-- if p then
|
||||
-- surface.create_entity({name = "uranium-ore", position = p, amount = ore_amount * 2})
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
|
||||
-- oil patches
|
||||
--local vectors = additional_resource_vectors[vector_indexes[4]]
|
||||
--for _ = 1, 3, 1 do
|
||||
-- local vector = vectors[math_random(1, #vectors)]
|
||||
-- local p = {position.x + vector[1], position.y + vector[2]}
|
||||
-- p = surface.find_non_colliding_position("crude-oil", p, 64, 1)
|
||||
-- if p then
|
||||
-- surface.create_entity({name = "crude-oil", position = p, amount = 500000})
|
||||
-- end
|
||||
--end
|
||||
end
|
||||
|
||||
local function is_valid_location(surface, position)
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
if not surface.can_place_entity({ name = "market", position = position }) then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Position is obstructed - no room for market!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
return false
|
||||
end
|
||||
|
||||
for _, vector in pairs(town_wall_vectors) do
|
||||
local p = { x = math_floor(position.x + vector[1]), y = math_floor(position.y + vector[2]) }
|
||||
local tile = surface.get_tile(p.x, p.y)
|
||||
if tile.name == "out-of-map" then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Town would be off-map!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.size_of_town_centers > 48 then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Too many town centers on the map!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
return false
|
||||
end
|
||||
|
||||
if Building.near_town(position, surface, radius_between_towns) then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Town location is too close to another town center!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
return false
|
||||
end
|
||||
|
||||
local area = { { position.x - town_radius, position.y - town_radius }, { position.x + town_radius, position.y + town_radius } }
|
||||
local count = 0
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = area })) do
|
||||
if e.force.name == "enemy" then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if count > 1 then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "I got a bad feeling about this! There are enemies nearby.",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.set_market_health(entity, final_damage_amount)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[entity.force.name]
|
||||
town_center.health = math_floor(town_center.health - final_damage_amount)
|
||||
if town_center.health > town_center.max_health then town_center.health = town_center.max_health end
|
||||
local m = town_center.health / town_center.max_health
|
||||
entity.health = 150 * m
|
||||
rendering.set_text(town_center.health_text, "HP: " .. town_center.health .. " / " .. town_center.max_health)
|
||||
end
|
||||
|
||||
function Public.update_coin_balance(force)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
rendering.set_text(town_center.coins_text, "Coins: " .. town_center.coin_balance)
|
||||
end
|
||||
|
||||
local function is_color_used(color, town_centers)
|
||||
for _, center in pairs(town_centers) do
|
||||
if center.color then
|
||||
if center.color.r == color.r and center.color.g == color.g and center.color.b == color.b then return true end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_color()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local c
|
||||
|
||||
local shuffle_index = {}
|
||||
for i = 1, #colors, 1 do shuffle_index[i] = i end
|
||||
table_shuffle(shuffle_index)
|
||||
|
||||
for i = 1, #colors, 1 do
|
||||
c = { r = colors[shuffle_index[i]][1], g = colors[shuffle_index[i]][2], b = colors[shuffle_index[i]][3], }
|
||||
if not is_color_used(c, town_centers) then return c end
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
local function found_town(event)
|
||||
local entity = event.created_entity
|
||||
if entity == nil or not entity.valid then return true end -- cancel, not a valid entity placed
|
||||
if entity.name ~= "stone-furnace" then return false end -- cancel, player did not place a stone-furnace
|
||||
local player = game.players[event.player_index]
|
||||
if player.force ~= game.forces.player and player.force ~= game.forces["rogue"] then return false end -- cancel, player is in a team already
|
||||
local force_name = tostring(player.name)
|
||||
if game.forces[force_name] then return end -- cancel, player is mayor of town
|
||||
if Team.has_key(player) == false then return false end -- cancel, player has already placed a town
|
||||
|
||||
local surface = entity.surface
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
if ffatable.cooldowns_town_placement[player.index] then
|
||||
if game.tick < ffatable.cooldowns_town_placement[player.index] then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "Town founding is on cooldown for " .. math.ceil((ffatable.cooldowns_town_placement[player.index] - game.tick) / 3600) .. " minutes.",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
player.insert({ name = "stone-furnace", count = 1 })
|
||||
entity.destroy()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local position = entity.position
|
||||
entity.destroy()
|
||||
|
||||
if not is_valid_location(surface, position) then
|
||||
player.insert({ name = "stone-furnace", count = 1 })
|
||||
return true
|
||||
end
|
||||
|
||||
Team.add_new_force(force_name)
|
||||
|
||||
ffatable.town_centers[force_name] = {}
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
town_center.market = surface.create_entity({ name = "market", position = position, force = force_name })
|
||||
town_center.chunk_position = { math.floor(town_center.market.position.x / 32), math.floor(town_center.market.position.y / 32) }
|
||||
town_center.max_health = 1000
|
||||
town_center.coin_balance = 0
|
||||
town_center.input_buffer = {}
|
||||
town_center.output_buffer = {}
|
||||
town_center.health = town_center.max_health
|
||||
town_center.color = get_color()
|
||||
town_center.research_counter = 1
|
||||
town_center.upgrades = {}
|
||||
town_center.upgrades.mining_prod = 0
|
||||
town_center.upgrades.laser_turret = {}
|
||||
town_center.upgrades.laser_turret.slots = 0
|
||||
town_center.upgrades.laser_turret.locations = {}
|
||||
town_center.evolution = {}
|
||||
town_center.evolution.biters = 0
|
||||
town_center.evolution.spitters = 0
|
||||
town_center.evolution.worms = 0
|
||||
|
||||
town_center.coins_text = rendering.draw_text {
|
||||
text = "Coins: " .. town_center.coin_balance,
|
||||
surface = surface,
|
||||
target = town_center.market,
|
||||
target_offset = { 0, -2.75 },
|
||||
color = { 200, 200, 200 },
|
||||
scale = 1.00,
|
||||
font = "default-game",
|
||||
alignment = "center",
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
town_center.health_text = rendering.draw_text {
|
||||
text = "HP: " .. town_center.health .. " / " .. town_center.max_health,
|
||||
surface = surface,
|
||||
target = town_center.market,
|
||||
target_offset = { 0, -3.25 },
|
||||
color = { 200, 200, 200 },
|
||||
scale = 1.00,
|
||||
font = "default-game",
|
||||
alignment = "center",
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
town_center.town_caption = rendering.draw_text {
|
||||
text = player.name .. "'s Town",
|
||||
surface = surface,
|
||||
target = town_center.market,
|
||||
target_offset = { 0, -4.25 },
|
||||
color = town_center.color,
|
||||
scale = 1.30,
|
||||
font = "default-game",
|
||||
alignment = "center",
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
ffatable.size_of_town_centers = ffatable.size_of_town_centers + 1
|
||||
|
||||
draw_town_spawn(force_name)
|
||||
|
||||
Team.add_player_to_town(player, town_center)
|
||||
Team.add_chart_tag(game.forces.player, town_center.market)
|
||||
|
||||
local force = player.force
|
||||
|
||||
-- set the spawn point
|
||||
local pos = { x = town_center.market.position.x, y = town_center.market.position.y + 4 }
|
||||
--log("setting spawn point = {" .. spawn_point.x .. "," .. spawn_point.y .. "}")
|
||||
force.set_spawn_position(pos, surface)
|
||||
ffatable.spawn_point[player.name] = pos
|
||||
|
||||
ffatable.cooldowns_town_placement[player.index] = game.tick + 3600 * 15
|
||||
|
||||
Team.remove_key(player)
|
||||
|
||||
game.print(">> " .. player.name .. " has founded a new town!", { 255, 255, 0 })
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_built_entity(event)
|
||||
found_town(event)
|
||||
end
|
||||
|
||||
local function on_player_repaired_entity(event)
|
||||
local entity = event.entity
|
||||
if entity.name == "market" then
|
||||
Public.set_market_health(entity, -4)
|
||||
end
|
||||
end
|
||||
|
||||
--local function on_robot_repaired_entity(event)
|
||||
-- local entity = event.entity
|
||||
-- if entity.name == "market" then
|
||||
-- Public.set_market_health(entity, -4)
|
||||
-- end
|
||||
--end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if entity.name == "market" then
|
||||
Public.set_market_health(entity, event.final_damage_amount)
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.town_centers = {}
|
||||
ffatable.size_of_town_centers = 0
|
||||
ffatable.cooldowns_town_placement = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
|
||||
--Event.add(defines.events.on_robot_repaired_entity, on_robot_repaired_entity)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
|
||||
return Public
|
176
modules/scrap_towny_ffa/towny_balance.lua
Normal file
176
modules/scrap_towny_ffa/towny_balance.lua
Normal file
@ -0,0 +1,176 @@
|
||||
--Towny balance things by Gerkiz --
|
||||
|
||||
local player_ammo_starting_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.25,
|
||||
['cannon-shell'] = -0.75,
|
||||
['capsule'] = -0.5,
|
||||
['combat-robot-beam'] = -0.5,
|
||||
['combat-robot-laser'] = -0.5,
|
||||
['electric'] = -0.5,
|
||||
['flamethrower'] = -0.75,
|
||||
['grenade'] = -0.5,
|
||||
['landmine'] = -0.33,
|
||||
['laser-turret'] = -0.75,
|
||||
['melee'] = 2,
|
||||
['railgun'] = 1,
|
||||
['rocket'] = -0.75,
|
||||
['shotgun-shell'] = -0.20
|
||||
}
|
||||
|
||||
local player_gun_speed_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.55,
|
||||
['cannon-shell'] = -0.75,
|
||||
['capsule'] = -0.5,
|
||||
['combat-robot-beam'] = -0.5,
|
||||
['combat-robot-laser'] = -0.5,
|
||||
['electric'] = -0.5,
|
||||
['flamethrower'] = -0.75,
|
||||
['grenade'] = -0.5,
|
||||
['landmine'] = -0.33,
|
||||
['laser-turret'] = -0.75,
|
||||
['melee'] = 1,
|
||||
['railgun'] = 0,
|
||||
['rocket'] = -0.75,
|
||||
['shotgun-shell'] = -0.50
|
||||
}
|
||||
|
||||
local player_ammo_research_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.5,
|
||||
['cannon-shell'] = -0.85,
|
||||
['capsule'] = -0.5,
|
||||
['combat-robot-beam'] = -0.5,
|
||||
['combat-robot-laser'] = -0.5,
|
||||
['electric'] = -0.6,
|
||||
['flamethrower'] = -0.75,
|
||||
['grenade'] = -0.5,
|
||||
['landmine'] = -0.5,
|
||||
['laser-turret'] = -0.75,
|
||||
['melee'] = -0.5,
|
||||
['railgun'] = -0.5,
|
||||
['rocket'] = -0.5,
|
||||
['shotgun-shell'] = -0.20
|
||||
}
|
||||
|
||||
local player_turrets_research_modifiers = {
|
||||
['gun-turret'] = -0.75,
|
||||
['laser-turret'] = -0.75,
|
||||
['flamethrower-turret'] = -0.75
|
||||
}
|
||||
|
||||
local enemy_ammo_starting_modifiers = {
|
||||
['artillery-shell'] = 0,
|
||||
['biological'] = 0,
|
||||
['bullet'] = 0,
|
||||
['cannon-shell'] = 0,
|
||||
['capsule'] = 0,
|
||||
['combat-robot-beam'] = 0,
|
||||
['combat-robot-laser'] = 0,
|
||||
['electric'] = 0,
|
||||
['flamethrower'] = 0,
|
||||
['grenade'] = 0,
|
||||
['landmine'] = 0,
|
||||
['laser-turret'] = 0,
|
||||
['melee'] = 0,
|
||||
['railgun'] = 0,
|
||||
['rocket'] = 0,
|
||||
['shotgun-shell'] = 0
|
||||
}
|
||||
|
||||
local enemy_ammo_evolution_modifiers = {
|
||||
['artillery-shell'] = 1,
|
||||
['biological'] = 2,
|
||||
['bullet'] = 1,
|
||||
--['cannon-shell'] = 1,
|
||||
--['capsule'] = 1,
|
||||
--['combat-robot-beam'] = 1,
|
||||
--['combat-robot-laser'] = 1,
|
||||
--['electric'] = 1,
|
||||
['flamethrower'] = 2,
|
||||
--['grenade'] = 1,
|
||||
--['landmine'] = 1,
|
||||
['laser-turret'] = 2,
|
||||
['melee'] = 2
|
||||
--['railgun'] = 1,
|
||||
--['rocket'] = 1,
|
||||
--['shotgun-shell'] = 1
|
||||
}
|
||||
|
||||
function init_player_weapon_damage(force)
|
||||
for k, v in pairs(player_ammo_starting_modifiers) do
|
||||
force.set_ammo_damage_modifier(k, v)
|
||||
end
|
||||
|
||||
for k, v in pairs(player_gun_speed_modifiers) do
|
||||
force.set_gun_speed_modifier(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
function init_enemy_weapon_damage()
|
||||
local e_force = game.forces["enemy"]
|
||||
|
||||
for k, v in pairs(enemy_ammo_starting_modifiers) do
|
||||
e_force.set_ammo_damage_modifier(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
local function enemy_weapon_damage()
|
||||
local f = game.forces.enemy
|
||||
|
||||
local ef = f.evolution_factor
|
||||
|
||||
for k, v in pairs(enemy_ammo_evolution_modifiers) do
|
||||
local base = enemy_ammo_starting_modifiers[k]
|
||||
|
||||
local new = base + v * ef
|
||||
f.set_ammo_damage_modifier(k, new)
|
||||
end
|
||||
end
|
||||
|
||||
local function research_finished(event)
|
||||
local r = event.research
|
||||
local p_force = r.force
|
||||
|
||||
for _, e in ipairs(r.effects) do
|
||||
local t = e.type
|
||||
|
||||
if t == 'ammo-damage' then
|
||||
local category = e.ammo_category
|
||||
local factor = player_ammo_research_modifiers[category]
|
||||
|
||||
if factor then
|
||||
local current_m = p_force.get_ammo_damage_modifier(category)
|
||||
local m = e.modifier
|
||||
p_force.set_ammo_damage_modifier(category, current_m + factor * m)
|
||||
end
|
||||
elseif t == 'turret-attack' then
|
||||
local category = e.turret_id
|
||||
local factor = player_turrets_research_modifiers[category]
|
||||
|
||||
if factor then
|
||||
local current_m = p_force.get_turret_attack_modifier(category)
|
||||
local m = e.modifier
|
||||
p_force.set_turret_attack_modifier(category, current_m + factor * m)
|
||||
end
|
||||
elseif t == 'gun-speed' then
|
||||
local category = e.ammo_category
|
||||
local factor = player_gun_speed_modifiers[category]
|
||||
|
||||
if factor then
|
||||
local current_m = p_force.get_gun_speed_modifier(category)
|
||||
local m = e.modifier
|
||||
p_force.set_gun_speed_modifier(category, current_m + factor * m)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(init_enemy_weapon_damage)
|
||||
Event.on_nth_tick(18000, enemy_weapon_damage)
|
||||
Event.add(defines.events.on_research_finished, research_finished)
|
37
modules/scrap_towny_ffa/trap.lua
Normal file
37
modules/scrap_towny_ffa/trap.lua
Normal file
@ -0,0 +1,37 @@
|
||||
local math_random = math.random
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
local Building = require "modules.scrap_towny_ffa.building"
|
||||
local Scrap = require "modules.scrap_towny_ffa.scrap"
|
||||
local unearthing_worm = require "modules.scrap_towny_ffa.unearthing_worm"
|
||||
local unearthing_biters = require "modules.scrap_towny_ffa.unearthing_biters"
|
||||
local tick_tack_trap = require "modules.scrap_towny_ffa.tick_tack_trap"
|
||||
|
||||
local function trap(entity)
|
||||
-- check if within 32 blocks of market
|
||||
if entity.type == "tree" or Scrap.is_scrap(entity) then
|
||||
if math_random(1, 1024) == 1 then
|
||||
if not Building.near_town(entity.position, entity.surface, 32) then
|
||||
tick_tack_trap(entity.surface, entity.position)
|
||||
return
|
||||
end
|
||||
end
|
||||
if math_random(1, 256) == 1 then
|
||||
if not Building.near_town(entity.position, entity.surface, 32) then
|
||||
unearthing_worm(entity.surface, entity.position, Evolution.get_worm_evolution(entity))
|
||||
end
|
||||
end
|
||||
if math_random(1, 128) == 1 then
|
||||
if not Building.near_town(entity.position, entity.surface, 32) then
|
||||
unearthing_biters(entity.surface, entity.position, math_random(4, 8), Evolution.get_biter_evolution(entity))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
trap(entity)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
17
modules/scrap_towny_ffa/turrets_drop_ammo.lua
Normal file
17
modules/scrap_towny_ffa/turrets_drop_ammo.lua
Normal file
@ -0,0 +1,17 @@
|
||||
local math_random = math.random
|
||||
local math_min = math.min
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
local surface = entity.surface
|
||||
if entity.type == "ammo-turret" and entity.force.name == "enemy" then
|
||||
local min = math_min(entity.get_item_count("piercing-rounds-magazine"), 20)
|
||||
if min > 0 then
|
||||
surface.spill_item_stack(entity.position, { name = "piercing-rounds-magazine", count = math_random(1, min) }, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
|
84
modules/scrap_towny_ffa/unearthing_biters.lua
Normal file
84
modules/scrap_towny_ffa/unearthing_biters.lua
Normal file
@ -0,0 +1,84 @@
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local function create_particles(surface, position, amount)
|
||||
if not surface.valid then return end
|
||||
for _ = 1, amount, 1 do
|
||||
local m = math_random(6, 12)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle({
|
||||
name = "stone-particle",
|
||||
position = position,
|
||||
frame_speed = 0.1,
|
||||
vertical_speed = 0.1,
|
||||
height = 0.1,
|
||||
movement = { m2 - (math_random(0, m) * 0.01), m2 - (math_random(0, m) * 0.01) }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_biter(surface, position, evolution)
|
||||
if not surface.valid then return end
|
||||
local evo = math.floor(evolution * 1000)
|
||||
|
||||
local biter_chances = {
|
||||
{ name = "small-biter", chance = math.floor(1000 - (evo * 1.6)) },
|
||||
{ name = "small-spitter", chance = math.floor(500 - evo * 0.8) },
|
||||
{ name = "medium-biter", chance = -150 + evo },
|
||||
{ name = "medium-spitter", chance = -75 + math.floor(evo * 0.5) },
|
||||
{ name = "big-biter", chance = math.floor((evo - 500) * 3) },
|
||||
{ name = "big-spitter", chance = math.floor((evo - 500) * 2) },
|
||||
{ name = "behemoth-biter", chance = math.floor((evo - 800) * 6) },
|
||||
{ name = "behemoth-spitter", chance = math.floor((evo - 800) * 4) }
|
||||
}
|
||||
|
||||
local max_chance = 0
|
||||
for i = 1, 8, 1 do
|
||||
if biter_chances[i].chance < 0 then biter_chances[i].chance = 0 end
|
||||
max_chance = max_chance + biter_chances[i].chance
|
||||
end
|
||||
local r = math_random(1, max_chance)
|
||||
local current_chance = 0
|
||||
for i = 1, 8, 1 do
|
||||
current_chance = current_chance + biter_chances[i].chance
|
||||
if r <= current_chance then
|
||||
local biter_name = biter_chances[i].name
|
||||
local p = surface.find_non_colliding_position(biter_name, position, 10, 1)
|
||||
if not p then return end
|
||||
surface.create_entity({ name = biter_name, position = p, force = "enemy" })
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function unearthing_biters(surface, position, amount, relative_evolution)
|
||||
local ffatable = Table.get_table()
|
||||
if not surface then return end
|
||||
if not position then return end
|
||||
if not position.x then return end
|
||||
if not position.y then return end
|
||||
|
||||
local ticks = amount * 30
|
||||
ticks = ticks + 90
|
||||
for t = 1, ticks, 1 do
|
||||
if not ffatable.on_tick_schedule[game.tick + t] then ffatable.on_tick_schedule[game.tick + t] = {} end
|
||||
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_particles,
|
||||
args = { surface, { x = position.x, y = position.y }, 4 }
|
||||
}
|
||||
|
||||
if t > 90 then
|
||||
if t % 30 == 29 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = spawn_biter,
|
||||
args = { surface, { x = position.x, y = position.y }, relative_evolution }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unearthing_biters
|
69
modules/scrap_towny_ffa/unearthing_worm.lua
Normal file
69
modules/scrap_towny_ffa/unearthing_worm.lua
Normal file
@ -0,0 +1,69 @@
|
||||
local math_random = math.random
|
||||
local math_ceil = math.ceil
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local function create_particles(surface, position, amount)
|
||||
if not surface.valid then return end
|
||||
for _ = 1, amount, 1 do
|
||||
local m = math_random(8, 24)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle({
|
||||
name = "stone-particle",
|
||||
position = position,
|
||||
frame_speed = 0.1,
|
||||
vertical_speed = 0.1,
|
||||
height = 0.1,
|
||||
movement = { m2 - (math_random(0, m) * 0.01), m2 - (math_random(0, m) * 0.01) }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_worm(surface, position, evolution_index)
|
||||
if not surface.valid then return end
|
||||
local worm_raffle_table = {
|
||||
[1] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret" },
|
||||
[2] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret" },
|
||||
[3] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret" },
|
||||
[4] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret" },
|
||||
[5] = { "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret" },
|
||||
[6] = { "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret" },
|
||||
[7] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret" },
|
||||
[8] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret" },
|
||||
[9] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret" },
|
||||
[10] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret" }
|
||||
}
|
||||
local raffle = worm_raffle_table[evolution_index]
|
||||
local worm_name = raffle[math_random(1, #raffle)]
|
||||
surface.create_entity({ name = worm_name, position = position })
|
||||
end
|
||||
|
||||
local function unearthing_worm(surface, position, relative_evolution)
|
||||
local ffatable = Table.get_table()
|
||||
if not surface then return end
|
||||
if not position then return end
|
||||
if not position.x then return end
|
||||
if not position.y then return end
|
||||
|
||||
local evolution_index = math.ceil(relative_evolution * 10)
|
||||
if evolution_index < 1 then evolution_index = 1 end
|
||||
|
||||
for t = 1, 330, 1 do
|
||||
if not ffatable.on_tick_schedule[game.tick + t] then ffatable.on_tick_schedule[game.tick + t] = {} end
|
||||
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_particles,
|
||||
args = { surface, { x = position.x, y = position.y }, math_ceil(t * 0.05) }
|
||||
}
|
||||
|
||||
if t == 330 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = spawn_worm,
|
||||
args = { surface, { x = position.x, y = position.y }, evolution_index }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unearthing_worm
|
159
modules/scrap_towny_ffa/wreckage_yields_scrap.lua
Normal file
159
modules/scrap_towny_ffa/wreckage_yields_scrap.lua
Normal file
@ -0,0 +1,159 @@
|
||||
--wreckage yields scrap
|
||||
local table_insert = table.insert
|
||||
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
|
||||
-- loot chances and amounts for scrap entities
|
||||
|
||||
local entity_loot_chance = {
|
||||
{name = "advanced-circuit", chance = 5},
|
||||
--{name = "artillery-shell", chance = 1},
|
||||
{name = "battery", chance = 20},
|
||||
{name = "cannon-shell", chance = 2},
|
||||
--{name = "cluster-grenade", chance = 2},
|
||||
{name = "construction-robot", chance = 1},
|
||||
{name = "copper-cable", chance = 250},
|
||||
{name = "copper-plate", chance = 500},
|
||||
{name = "crude-oil-barrel", chance = 30},
|
||||
{name = "defender-capsule", chance = 5},
|
||||
{name = "destroyer-capsule", chance = 1},
|
||||
{name = "distractor-capsule", chance = 2},
|
||||
{name = "electric-engine-unit", chance = 2},
|
||||
{name = "electronic-circuit", chance = 200},
|
||||
{name = "empty-barrel", chance = 10},
|
||||
{name = "engine-unit", chance = 4},
|
||||
{name = "explosive-cannon-shell", chance = 2},
|
||||
--{name = "explosive-rocket", chance = 3},
|
||||
--{name = "explosive-uranium-cannon-shell", chance = 1},
|
||||
{name = "explosives", chance = 5},
|
||||
{name = "green-wire", chance = 10},
|
||||
{name = "grenade", chance = 10},
|
||||
{name = "heat-pipe", chance = 1},
|
||||
{name = "heavy-oil-barrel", chance = 15},
|
||||
{name = "iron-gear-wheel", chance = 500},
|
||||
{name = "iron-plate", chance = 750},
|
||||
{name = "iron-stick", chance = 50},
|
||||
{name = "land-mine", chance = 3},
|
||||
{name = "light-oil-barrel", chance = 15},
|
||||
{name = "logistic-robot", chance = 1},
|
||||
{name = "low-density-structure", chance = 1},
|
||||
{name = "lubricant-barrel", chance = 20},
|
||||
--{name = "nuclear-fuel", chance = 1},
|
||||
{name = "petroleum-gas-barrel", chance = 15},
|
||||
{name = "pipe", chance = 100},
|
||||
{name = "pipe-to-ground", chance = 10},
|
||||
{name = "plastic-bar", chance = 5},
|
||||
{name = "processing-unit", chance = 2},
|
||||
{name = "red-wire", chance = 10},
|
||||
--{name = "rocket", chance = 3},
|
||||
--{name = "rocket-control-unit", chance = 1},
|
||||
--{name = "rocket-fuel", chance = 3},
|
||||
{name = "solid-fuel", chance = 100},
|
||||
{name = "steel-plate", chance = 150},
|
||||
{name = "sulfuric-acid-barrel", chance = 15},
|
||||
--{name = "uranium-cannon-shell", chance = 1},
|
||||
--{name = "uranium-fuel-cell", chance = 1},
|
||||
--{name = "used-up-uranium-fuel-cell", chance = 1},
|
||||
{name = "water-barrel", chance = 10},
|
||||
{name = "tank", chance = 1},
|
||||
{name = "car", chance = 1}
|
||||
}
|
||||
|
||||
local entity_loot_amounts = {
|
||||
["advanced-circuit"] = 2,
|
||||
--["artillery-shell"] = 0.3,
|
||||
["battery"] = 2,
|
||||
["cannon-shell"] = 2,
|
||||
--["cluster-grenade"] = 0.3,
|
||||
["construction-robot"] = 0.3,
|
||||
["copper-cable"] = 24,
|
||||
["copper-plate"] = 16,
|
||||
["crude-oil-barrel"] = 3,
|
||||
["defender-capsule"] = 2,
|
||||
["destroyer-capsule"] = 0.3,
|
||||
["distractor-capsule"] = 0.3,
|
||||
["electric-engine-unit"] = 2,
|
||||
["electronic-circuit"] = 8,
|
||||
["empty-barrel"] = 3,
|
||||
["engine-unit"] = 2,
|
||||
["explosive-cannon-shell"] = 2,
|
||||
--["explosive-rocket"] = 2,
|
||||
--["explosive-uranium-cannon-shell"] = 2,
|
||||
["explosives"] = 4,
|
||||
["green-wire"] = 8,
|
||||
["grenade"] = 2,
|
||||
["heat-pipe"] = 1,
|
||||
["heavy-oil-barrel"] = 3,
|
||||
["iron-gear-wheel"] = 8,
|
||||
["iron-plate"] = 16,
|
||||
["iron-stick"] = 16,
|
||||
["land-mine"] = 1,
|
||||
["light-oil-barrel"] = 3,
|
||||
["logistic-robot"] = 0.3,
|
||||
["low-density-structure"] = 0.3,
|
||||
["lubricant-barrel"] = 3,
|
||||
--["nuclear-fuel"] = 0.1,
|
||||
["petroleum-gas-barrel"] = 3,
|
||||
["pipe"] = 8,
|
||||
["pipe-to-ground"] = 1,
|
||||
["plastic-bar"] = 4,
|
||||
["processing-unit"] = 1,
|
||||
["red-wire"] = 8,
|
||||
--["rocket"] = 2,
|
||||
--["rocket-control-unit"] = 0.3,
|
||||
--["rocket-fuel"] = 0.3,
|
||||
["solid-fuel"] = 4,
|
||||
["steel-plate"] = 4,
|
||||
["sulfuric-acid-barrel"] = 3,
|
||||
--["uranium-cannon-shell"] = 2,
|
||||
--["uranium-fuel-cell"] = 0.3,
|
||||
--["used-up-uranium-fuel-cell"] = 1,
|
||||
["water-barrel"] = 3,
|
||||
["tank"] = 1,
|
||||
["car"] = 1,
|
||||
}
|
||||
|
||||
local scrap_raffle = {}
|
||||
for _, t in pairs (entity_loot_chance) do
|
||||
for _ = 1, t.chance, 1 do
|
||||
table_insert(scrap_raffle, t.name)
|
||||
end
|
||||
end
|
||||
|
||||
local size_of_scrap_raffle = #scrap_raffle
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local position = entity.position
|
||||
if Scrap.is_scrap(entity) == false then return end
|
||||
if entity.name == 'crash-site-chest-1' or entity.name == 'crash-site-chest-2' then return end
|
||||
|
||||
-- scrap entities drop loot
|
||||
event.buffer.clear()
|
||||
|
||||
local scrap = scrap_raffle[math.random(1, size_of_scrap_raffle)]
|
||||
|
||||
local amount_bonus = (game.forces.enemy.evolution_factor * 2) + (game.forces.player.mining_drill_productivity_bonus * 2)
|
||||
local r1 = math.ceil(entity_loot_amounts[scrap] * (0.3 + (amount_bonus * 0.3)))
|
||||
local r2 = math.ceil(entity_loot_amounts[scrap] * (1.7 + (amount_bonus * 1.7)))
|
||||
local amount = math.random(r1, r2)
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
local inserted_count = player.insert({name = scrap, count = amount})
|
||||
|
||||
if inserted_count ~= amount then
|
||||
local amount_to_spill = amount - inserted_count
|
||||
entity.surface.spill_item_stack(position, {name = scrap, count = amount_to_spill}, true)
|
||||
end
|
||||
|
||||
entity.surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "+" .. amount .. " [img=item/" .. scrap .. "]",
|
||||
color = {r=0.98, g=0.66, b=0.22}
|
||||
})
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
@ -1,4 +1,5 @@
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
|
||||
local function create_gui(player)
|
||||
local frame = player.gui.top.add({type = 'frame', name = 'wave_defense'})
|
||||
@ -68,8 +69,9 @@ local function update_gui(player)
|
||||
end
|
||||
local gui = player.gui.top.wave_defense
|
||||
local biter_health_boost = 1
|
||||
if global.biter_health_boost then
|
||||
biter_health_boost = global.biter_health_boost
|
||||
local biter_health_boosts = BiterHealthBooster.get('biter_health_boost')
|
||||
if biter_health_boost then
|
||||
biter_health_boost = biter_health_boosts
|
||||
end
|
||||
|
||||
local wave_number = WD.get('wave_number')
|
||||
|
@ -1,5 +1,5 @@
|
||||
local Event = require 'utils.event'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local BiterRolls = require 'modules.wave_defense.biter_rolls'
|
||||
local SideTargets = require 'modules.wave_defense.side_targets'
|
||||
local ThreatEvent = require 'modules.wave_defense.threat_events'
|
||||
@ -238,7 +238,8 @@ local function refresh_active_unit_threat()
|
||||
active_biters[k] = nil
|
||||
end
|
||||
end
|
||||
WD.set('active_biter_threat', math_round(biter_threat * global.biter_health_boost, 2))
|
||||
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
|
||||
WD.set('active_biter_threat', math_round(biter_threat * biter_health_boost, 2))
|
||||
debug_print('refresh_active_unit_threat - new value ' .. active_biter_threat)
|
||||
end
|
||||
|
||||
@ -251,12 +252,14 @@ local function time_out_biters()
|
||||
WD.set('active_biter_count', 50)
|
||||
end
|
||||
|
||||
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
|
||||
|
||||
for k, biter in pairs(active_biters) do
|
||||
if not is_unit_valid(biter) then
|
||||
WD.set('active_biter_count', active_biter_count - 1)
|
||||
if biter.entity then
|
||||
if biter.entity.valid then
|
||||
WD.set('active_biter_threat', active_biter_threat - math_round(threat_values[biter.entity.name] * global.biter_health_boost, 2))
|
||||
WD.set('active_biter_threat', active_biter_threat - math_round(threat_values[biter.entity.name] * biter_health_boost, 2))
|
||||
if biter.entity.force.index == 2 then
|
||||
biter.entity.destroy()
|
||||
end
|
||||
@ -373,7 +376,7 @@ local function set_enemy_evolution()
|
||||
end
|
||||
--damage_increase = math_round(damage_increase + threat * 0.0000025, 3)
|
||||
|
||||
global.biter_health_boost = biter_h_boost
|
||||
BiterHealthBooster.set('biter_health_boost', biter_h_boost)
|
||||
--game.forces.enemy.set_ammo_damage_modifier("melee", damage_increase)
|
||||
--game.forces.enemy.set_ammo_damage_modifier("biological", damage_increase)
|
||||
game.forces.enemy.evolution_factor = evolution_factor
|
||||
@ -440,7 +443,7 @@ local function spawn_biter(surface, is_boss_biter)
|
||||
end
|
||||
end
|
||||
|
||||
local boosted_health = global.biter_health_boost
|
||||
local boosted_health = BiterHealthBooster.get('biter_health_boost')
|
||||
|
||||
local name
|
||||
if math_random(1, 100) > 73 then
|
||||
@ -455,26 +458,25 @@ local function spawn_biter(surface, is_boss_biter)
|
||||
biter.ai_settings.allow_try_return_to_spawner = true
|
||||
biter.ai_settings.do_separation = true
|
||||
|
||||
local increase_health_per_wave = WD.get('increase_health_per_wave')
|
||||
|
||||
if increase_health_per_wave and not is_boss_biter then
|
||||
local modified_unit_health = WD.get('modified_unit_health')
|
||||
BiterHealthBooster.add_unit(biter, modified_unit_health)
|
||||
end
|
||||
|
||||
if is_boss_biter then
|
||||
local modified_boss_health = WD.get('modified_boss_health')
|
||||
if modified_boss_health then
|
||||
local wave_number = WD.get('wave_number')
|
||||
if boosted_health == 1 then
|
||||
boosted_health = 1.25
|
||||
end
|
||||
boosted_health = boosted_health * (wave_number * 0.04)
|
||||
local sum = boosted_health * 5
|
||||
debug_print('Boss Health Boosted: ' .. sum)
|
||||
if sum >= 150 then
|
||||
sum = 150
|
||||
end
|
||||
BiterHealthBooster.add_boss_unit(biter, sum, 0.55)
|
||||
local increase_boss_health_per_wave = WD.get('increase_boss_health_per_wave')
|
||||
if increase_boss_health_per_wave then
|
||||
local modified_boss_unit_health = WD.get('modified_boss_unit_health')
|
||||
BiterHealthBooster.add_boss_unit(biter, modified_boss_unit_health, 0.55)
|
||||
else
|
||||
local sum = boosted_health * 5
|
||||
debug_print('Boss Health Boosted: ' .. sum)
|
||||
BiterHealthBooster.add_boss_unit(biter, sum, 0.55)
|
||||
end
|
||||
end
|
||||
|
||||
WD.set('active_biters')[biter.unit_number] = {entity = biter, spawn_tick = game.tick}
|
||||
local active_biter_count = WD.get('active_biter_count')
|
||||
WD.set('active_biter_count', active_biter_count + 1)
|
||||
@ -509,6 +511,37 @@ local function increase_biter_damage()
|
||||
e.set_ammo_damage_modifier('biological', new + e_old_biological)
|
||||
end
|
||||
|
||||
local function increase_biters_health()
|
||||
local increase_health_per_wave = WD.get('increase_health_per_wave')
|
||||
if not increase_health_per_wave then
|
||||
return
|
||||
end
|
||||
|
||||
local boosted_health = BiterHealthBooster.get('biter_health_boost')
|
||||
local wave_number = WD.get('wave_number')
|
||||
|
||||
-- this sets normal units health
|
||||
local modified_unit_health = WD.get('modified_unit_health')
|
||||
if modified_unit_health > 30 then
|
||||
modified_unit_health = 30
|
||||
end
|
||||
debug_print('[HEALTHBOOSTER] > Normal Units Health Boosted: ' .. modified_unit_health)
|
||||
WD.set('modified_unit_health', modified_unit_health + 0.02)
|
||||
|
||||
-- this sets boss units health
|
||||
if boosted_health == 1 then
|
||||
boosted_health = 1.20
|
||||
end
|
||||
boosted_health = boosted_health * (wave_number * 0.03)
|
||||
local sum = boosted_health * 4
|
||||
debug_print('[HEALTHBOOSTER] > Boss Health Boosted: ' .. sum)
|
||||
if sum >= 100 then
|
||||
sum = 100
|
||||
end
|
||||
|
||||
WD.set('modified_boss_unit_health', sum)
|
||||
end
|
||||
|
||||
local function set_next_wave()
|
||||
local wave_number = WD.get('wave_number')
|
||||
WD.set('wave_number', wave_number + 1)
|
||||
@ -521,6 +554,7 @@ local function set_next_wave()
|
||||
end
|
||||
if wave_number % 25 == 0 then
|
||||
increase_biter_damage()
|
||||
increase_biters_health()
|
||||
WD.set('boss_wave', true)
|
||||
WD.set('boss_wave_warning', true)
|
||||
local alert_boss_wave = WD.get('alert_boss_wave')
|
||||
|
@ -15,6 +15,7 @@ function Public.debug_module()
|
||||
this.next_wave = 1000
|
||||
this.wave_interval = 500
|
||||
this.wave_enforced = true
|
||||
this.debug = true
|
||||
end
|
||||
|
||||
function Public.reset_wave_defense()
|
||||
@ -70,10 +71,12 @@ function Public.reset_wave_defense()
|
||||
this.enable_threat_log = true
|
||||
this.disable_threat_below_zero = false
|
||||
this.check_collapse_position = true
|
||||
this.modified_boss_health = true
|
||||
this.resolve_pathing = true
|
||||
this.increase_damage_per_wave = false
|
||||
this.increase_boss_health_per_wave = true
|
||||
this.increase_health_per_wave = false
|
||||
this.fill_tiles_so_biter_can_path = true
|
||||
this.modified_unit_health = 1.02
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
@ -150,6 +153,13 @@ function Public.remove_entities(boolean)
|
||||
return this.remove_entities
|
||||
end
|
||||
|
||||
function Public.increase_health_per_wave(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.increase_health_per_wave = boolean
|
||||
end
|
||||
return this.increase_health_per_wave
|
||||
end
|
||||
|
||||
function Public.enable_threat_log(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.enable_threat_log = boolean
|
||||
@ -171,11 +181,11 @@ function Public.enable_side_target(boolean)
|
||||
return this.enable_side_target
|
||||
end
|
||||
|
||||
function Public.modified_boss_health(boolean)
|
||||
function Public.increase_boss_health_per_wave(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.modified_boss_health = boolean
|
||||
this.increase_boss_health_per_wave = boolean
|
||||
end
|
||||
return this.modified_boss_health
|
||||
return this.increase_boss_health_per_wave
|
||||
end
|
||||
|
||||
function Public.resolve_pathing(boolean)
|
||||
|
@ -2,6 +2,7 @@ local WD = require 'modules.wave_defense.table'
|
||||
local threat_values = require 'modules.wave_defense.threat_values'
|
||||
local Event = require 'utils.event'
|
||||
local BiterRolls = require 'modules.wave_defense.biter_rolls'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
local math_random = math.random
|
||||
|
||||
local Public = {}
|
||||
@ -13,8 +14,9 @@ local function remove_unit(entity)
|
||||
return
|
||||
end
|
||||
local m = 1
|
||||
if global.biter_health_boost_units[unit_number] then
|
||||
m = 1 / global.biter_health_boost_units[unit_number][2]
|
||||
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
|
||||
if biter_health_boost_units[unit_number] then
|
||||
m = 1 / biter_health_boost_units[unit_number][2]
|
||||
end
|
||||
local active_threat_loss = math.round(threat_values[entity.name] * m, 2)
|
||||
local active_biter_threat = WD.get('active_biter_threat')
|
||||
@ -230,6 +232,8 @@ local function on_entity_died(event)
|
||||
end
|
||||
|
||||
local disable_threat_below_zero = WD.get('disable_threat_below_zero')
|
||||
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
|
||||
|
||||
if entity.type == 'unit' then
|
||||
--acid_nova(entity)
|
||||
if not threat_values[entity.name] then
|
||||
@ -241,11 +245,11 @@ local function on_entity_died(event)
|
||||
WD.set('threat', 0)
|
||||
threat = WD.get('threat')
|
||||
end
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * global.biter_health_boost, 2))
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * biter_health_boost, 2))
|
||||
remove_unit(entity)
|
||||
else
|
||||
local threat = WD.get('threat')
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * global.biter_health_boost, 2))
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * biter_health_boost, 2))
|
||||
remove_unit(entity)
|
||||
end
|
||||
else
|
||||
@ -253,7 +257,7 @@ local function on_entity_died(event)
|
||||
if entity.health then
|
||||
if threat_values[entity.name] then
|
||||
local threat = WD.get('threat')
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * global.biter_health_boost, 2))
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * biter_health_boost, 2))
|
||||
end
|
||||
spawn_unit_spawner_inhabitants(entity)
|
||||
end
|
||||
|
104
modules/worms_create_oil_patches.lua
Normal file
104
modules/worms_create_oil_patches.lua
Normal file
@ -0,0 +1,104 @@
|
||||
local math_random = math.random
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local tick_schedule = {}
|
||||
Global.register(
|
||||
tick_schedule,
|
||||
function(t)
|
||||
tick_schedule = t
|
||||
end
|
||||
)
|
||||
|
||||
local death_animation_ticks = 120
|
||||
local decay_ticks = 2
|
||||
|
||||
local worms = {
|
||||
["small-worm-turret"] = { corpse="small-worm-corpse", patch_size = { min=30000, max=90000} },
|
||||
["medium-worm-turret"] = { corpse="medium-worm-corpse", patch_size = { min=60000, max=120000 } },
|
||||
["big-worm-turret"] = { corpse="big-worm-corpse", patch_size = { min=90000, max=300000 } },
|
||||
["behemoth-worm-turret"] = { corpse="behemoth-worm-corpse", patch_size = { min=120000, max=600000 } }
|
||||
}
|
||||
|
||||
local function destroy_worm(name, position, surface)
|
||||
local entity = surface.find_entity(name, position)
|
||||
if entity ~= nil and entity.valid then entity.destroy() end
|
||||
local corpse = worms[name].corpse
|
||||
local remains = surface.find_entity(corpse, position)
|
||||
if remains ~= nil and remains.valid then
|
||||
-- show an animation
|
||||
if math_random(1,40) == 1 then surface.create_entity({name = "explosion", position = {x = position.x + (3 - (math_random(1,60) * 0.1)), y = position.y + (3 - (math_random(1,60) * 0.1))}}) end
|
||||
if math_random(1,32) == 1 then surface.create_entity({name = "blood-explosion-huge", position = position}) end
|
||||
if math_random(1,16) == 1 then surface.create_entity({name = "blood-explosion-big", position = position}) end
|
||||
if math_random(1,8) == 1 then surface.create_entity({name = "blood-explosion-small", position = position}) end
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_corpse(name, position, surface)
|
||||
local corpse = worms[name].corpse
|
||||
local remains = surface.find_entity(corpse, position)
|
||||
if remains ~= nil and remains.valid then remains.destroy() end
|
||||
end
|
||||
|
||||
-- place an oil patch at the worm location
|
||||
local function create_oil_patch(name, position, surface)
|
||||
local min = worms[name].patch_size.min
|
||||
local max = worms[name].patch_size.max
|
||||
surface.create_entity({name="crude-oil", position=position, amount=math_random(min,max)})
|
||||
end
|
||||
|
||||
-- worms create oil patches when killed
|
||||
local function process_worm(entity)
|
||||
local name = entity.name
|
||||
local position = entity.position
|
||||
local surface = entity.surface
|
||||
|
||||
local tick1 = game.tick + death_animation_ticks
|
||||
if not tick_schedule[tick1] then tick_schedule[tick1] = {} end
|
||||
tick_schedule[tick1][#tick_schedule[tick1] + 1] = {
|
||||
callback = 'destroy_worm',
|
||||
params = {name, position, surface}
|
||||
}
|
||||
local tick2 = game.tick + death_animation_ticks + decay_ticks
|
||||
if not tick_schedule[tick2] then tick_schedule[tick2] = {} end
|
||||
tick_schedule[tick2][#tick_schedule[tick2] + 1] = {
|
||||
callback = 'remove_corpse',
|
||||
params = {name, position, surface}
|
||||
}
|
||||
if math_random(1,4) == 1 then
|
||||
local tick3 = game.tick + death_animation_ticks + decay_ticks + 1
|
||||
if not tick_schedule[tick3] then tick_schedule[tick3] = {} end
|
||||
tick_schedule[tick3][#tick_schedule[tick3] + 1] = {
|
||||
callback = 'create_oil_patch',
|
||||
params = {name, position, surface}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
local test = {
|
||||
["small-worm-turret"] = true,
|
||||
["medium-worm-turret"] = true,
|
||||
["big-worm-turret"] = true,
|
||||
["behemoth-worm-turret"] = true
|
||||
}
|
||||
if test[entity.name] ~= nil then
|
||||
process_worm(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if not tick_schedule[game.tick] then return end
|
||||
for _, token in pairs(tick_schedule[game.tick]) do
|
||||
local callback = token.callback
|
||||
local params = token.params
|
||||
if callback == 'destroy_worm' then destroy_worm(params[1], params[2], params[3]) end
|
||||
if callback == 'remove_corpse' then remove_corpse(params[1], params[2], params[3]) end
|
||||
if callback == 'create_oil_patch' then create_oil_patch(params[1], params[2], params[3]) end
|
||||
end
|
||||
tick_schedule[game.tick] = nil
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
330
terrain_layouts/scrap_towny_ffa.lua
Normal file
330
terrain_layouts/scrap_towny_ffa.lua
Normal file
@ -0,0 +1,330 @@
|
||||
local table_insert = table.insert
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local math_abs = math.abs
|
||||
|
||||
local get_noise = require 'utils.get_noise'
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
require 'modules.no_deconstruction_of_neutral_entities'
|
||||
|
||||
local scrap_entities = {
|
||||
-- simple entity
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
-- simple entity with owner
|
||||
{name = "crash-site-spaceship-wreck-small-1"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-1"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-2"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-3"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-4"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-5"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-6"} -- these do not have mining animation
|
||||
}
|
||||
|
||||
local scrap_entities_index = table.size(scrap_entities)
|
||||
|
||||
local scrap_containers = {
|
||||
-- containers
|
||||
{name = "big-ship-wreck-1", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-1", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-1", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-2", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-2", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-2", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-3", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-3", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-3", size = 3}, -- these are not mineable normally
|
||||
{name = "crash-site-chest-1", size = 8}, -- these do not have mining animation
|
||||
{name = "crash-site-chest-2", size = 8}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-1", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-1", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-1", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-2", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-2", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-2", size = 2}, -- these do not have mining animation
|
||||
}
|
||||
local scrap_containers_index = table.size(scrap_containers)
|
||||
|
||||
-- loot chances and amounts for scrap containers
|
||||
|
||||
local container_loot_chance = {
|
||||
{name = "advanced-circuit", chance = 5},
|
||||
{name = "artillery-shell", chance = 1},
|
||||
{name = "cannon-shell", chance = 2},
|
||||
{name = "cliff-explosives", chance = 5},
|
||||
--{name = "cluster-grenade", chance = 2},
|
||||
{name = "construction-robot", chance = 1},
|
||||
{name = "copper-cable", chance = 250},
|
||||
{name = "copper-plate", chance = 500},
|
||||
{name = "crude-oil-barrel", chance = 30},
|
||||
{name = "defender-capsule", chance = 5},
|
||||
{name = "destroyer-capsule", chance = 1},
|
||||
{name = "distractor-capsule", chance = 2},
|
||||
{name = "electric-engine-unit", chance = 2},
|
||||
{name = "electronic-circuit", chance = 200},
|
||||
{name = "empty-barrel", chance = 10},
|
||||
{name = "engine-unit", chance = 7},
|
||||
{name = "explosive-cannon-shell", chance = 2},
|
||||
--{name = "explosive-rocket", chance = 3},
|
||||
{name = "explosive-uranium-cannon-shell", chance = 1},
|
||||
{name = "explosives", chance = 5},
|
||||
{name = "green-wire", chance = 10},
|
||||
{name = "grenade", chance = 10},
|
||||
{name = "heat-pipe", chance = 1},
|
||||
{name = "heavy-oil-barrel", chance = 15},
|
||||
{name = "iron-gear-wheel", chance = 500},
|
||||
{name = "iron-plate", chance = 750},
|
||||
{name = "iron-stick", chance = 50},
|
||||
{name = "land-mine", chance = 3},
|
||||
{name = "light-oil-barrel", chance = 15},
|
||||
{name = "logistic-robot", chance = 1},
|
||||
{name = "low-density-structure", chance = 1},
|
||||
{name = "lubricant-barrel", chance = 20},
|
||||
{name = "nuclear-fuel", chance = 1},
|
||||
{name = "petroleum-gas-barrel", chance = 15},
|
||||
{name = "pipe", chance = 100},
|
||||
{name = "pipe-to-ground", chance = 10},
|
||||
{name = "plastic-bar", chance = 5},
|
||||
{name = "processing-unit", chance = 2},
|
||||
{name = "red-wire", chance = 10},
|
||||
--{name = "rocket", chance = 3}, {name = "battery", chance = 20},
|
||||
{name = "rocket-control-unit", chance = 1},
|
||||
{name = "rocket-fuel", chance = 3},
|
||||
{name = "solid-fuel", chance = 100},
|
||||
{name = "steel-plate", chance = 150},
|
||||
{name = "sulfuric-acid-barrel", chance = 15},
|
||||
{name = "uranium-cannon-shell", chance = 1},
|
||||
{name = "uranium-fuel-cell", chance = 1},
|
||||
{name = "used-up-uranium-fuel-cell", chance = 1},
|
||||
{name = "water-barrel", chance = 10}
|
||||
}
|
||||
|
||||
local container_loot_amounts = {
|
||||
["advanced-circuit"] = 2,
|
||||
["artillery-shell"] = 0.3,
|
||||
["battery"] = 2,
|
||||
["cannon-shell"] = 2,
|
||||
["cliff-explosives"] = 2,
|
||||
--["cluster-grenade"] = 0.3,
|
||||
["construction-robot"] = 0.3,
|
||||
["copper-cable"] = 24,
|
||||
["copper-plate"] = 16,
|
||||
["crude-oil-barrel"] = 3,
|
||||
["defender-capsule"] = 2,
|
||||
["destroyer-capsule"] = 0.3,
|
||||
["distractor-capsule"] = 0.3,
|
||||
["electric-engine-unit"] = 2,
|
||||
["electronic-circuit"] = 8,
|
||||
["empty-barrel"] = 3,
|
||||
["engine-unit"] = 2,
|
||||
["explosive-cannon-shell"] = 2,
|
||||
--["explosive-rocket"] = 2,
|
||||
["explosive-uranium-cannon-shell"] = 2,
|
||||
["explosives"] = 4,
|
||||
["green-wire"] = 8,
|
||||
["grenade"] = 2,
|
||||
["heat-pipe"] = 1,
|
||||
["heavy-oil-barrel"] = 3,
|
||||
["iron-gear-wheel"] = 8,
|
||||
["iron-plate"] = 16,
|
||||
["iron-stick"] = 16,
|
||||
["land-mine"] = 1,
|
||||
["light-oil-barrel"] = 3,
|
||||
["logistic-robot"] = 0.3,
|
||||
["low-density-structure"] = 0.3,
|
||||
["lubricant-barrel"] = 3,
|
||||
["nuclear-fuel"] = 0.1,
|
||||
["petroleum-gas-barrel"] = 3,
|
||||
["pipe"] = 8,
|
||||
["pipe-to-ground"] = 1,
|
||||
["plastic-bar"] = 4,
|
||||
["processing-unit"] = 1,
|
||||
["red-wire"] = 8,
|
||||
--["rocket"] = 2,
|
||||
["rocket-control-unit"] = 0.3,
|
||||
["rocket-fuel"] = 0.3,
|
||||
["solid-fuel"] = 4,
|
||||
["steel-plate"] = 4,
|
||||
["sulfuric-acid-barrel"] = 3,
|
||||
["uranium-cannon-shell"] = 2,
|
||||
["uranium-fuel-cell"] = 0.3,
|
||||
["used-up-uranium-fuel-cell"] = 1,
|
||||
["water-barrel"] = 3
|
||||
}
|
||||
|
||||
local scrap_raffle = {}
|
||||
for _, t in pairs(container_loot_chance) do
|
||||
for _ = 1, t.chance, 1 do
|
||||
table_insert(scrap_raffle, t.name)
|
||||
end
|
||||
end
|
||||
|
||||
local size_of_scrap_raffle = #scrap_raffle
|
||||
|
||||
local function place_scrap(surface, position)
|
||||
-- place turrets
|
||||
if math_random(1, 700) == 1 then
|
||||
if position.x ^ 2 + position.x ^ 2 > 4096 then
|
||||
local e = surface.create_entity({name = "gun-turret", position = position, force = "enemy"})
|
||||
e.minable = false
|
||||
e.operable = false
|
||||
e.insert({name = "piercing-rounds-magazine", count = 100})
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- place spaceship with loot
|
||||
if math_random(1, 8192) == 1 then
|
||||
local e = surface.create_entity({name = 'crash-site-spaceship', position = position, force = "neutral"})
|
||||
e.minable = true
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
if i then
|
||||
for _ = 1, math_random(1, 5), 1 do
|
||||
local loot = scrap_raffle[math_random(1, size_of_scrap_raffle)]
|
||||
local amount = container_loot_amounts[loot]
|
||||
local count = math_floor(amount * math_random(5, 35) * 0.1) + 1
|
||||
i.insert({name = loot, count = count})
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- place scrap containers with loot
|
||||
if math_random(1, 128) == 1 then
|
||||
local scrap = scrap_containers[math_random(1, scrap_containers_index)]
|
||||
local e = surface.create_entity({name = scrap.name, position = position, force = "neutral"})
|
||||
e.minable = true
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
if i then
|
||||
local size = scrap.size
|
||||
for _ = 1, math_random(1, size), 1 do
|
||||
local loot = scrap_raffle[math_random(1, size_of_scrap_raffle)]
|
||||
local amount = container_loot_amounts[loot]
|
||||
local count = math_floor(amount * math_random(5, 35) * 0.1) + 1
|
||||
i.insert({name = loot, count = count})
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- place scrap entities with loot
|
||||
local scrap = scrap_entities[math_random(1, scrap_entities_index)]
|
||||
local e = surface.create_entity({name = scrap.name, position = position, force = "neutral"})
|
||||
e.minable = true
|
||||
end
|
||||
|
||||
local function is_scrap_area(n)
|
||||
if n > 0.5 then return true end
|
||||
if n < -0.5 then return true end
|
||||
end
|
||||
|
||||
local function move_away_biteys(surface, area)
|
||||
for _, e in pairs(surface.find_entities_filtered({type = {"unit-spawner", "turret", "unit"}, area = area})) do
|
||||
local position = surface.find_non_colliding_position(e.name, e.position, 96, 4)
|
||||
if position then
|
||||
surface.create_entity({name = e.name, position = position, force = "enemy"})
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vectors = {{0,0}, {1,0}, {-1,0}, {0,1}, {0,-1}}
|
||||
|
||||
local function landfill_under(entity)
|
||||
-- landfill the area under the entity
|
||||
local surface = entity.surface
|
||||
for _, v in pairs(vectors) do
|
||||
local position = {entity.position.x + v[1], entity.position.y + v[2]}
|
||||
if not surface.get_tile(position).collides_with("resource-layer") then
|
||||
surface.set_tiles({{name = "landfill", position = position}}, true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if Scrap.is_scrap(entity) then landfill_under(entity) end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if Scrap.is_scrap(entity) then landfill_under(entity) end
|
||||
end
|
||||
|
||||
--local function on_init(event)
|
||||
--
|
||||
--end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
--log("scrap_towny_ffa::on_chunk_generated")
|
||||
local surface = event.surface
|
||||
local seed = surface.map_gen_settings.seed
|
||||
local left_top_x = event.area.left_top.x
|
||||
local left_top_y = event.area.left_top.y
|
||||
--log(" chunk = {" .. left_top_x/32 .. ", " .. left_top_y/32 .. "}")
|
||||
local position
|
||||
local noise
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
if math_random(1, 3) > 1 then
|
||||
position = {x = left_top_x + x, y = left_top_y + y}
|
||||
if not surface.get_tile(position).collides_with("resource-layer") then
|
||||
noise = get_noise("scrap_towny_ffa", position, seed)
|
||||
if is_scrap_area(noise) then
|
||||
surface.set_tiles({{name = "dirt-" .. math_floor(math_abs(noise) * 6) % 6 + 2, position = position}}, true)
|
||||
place_scrap(surface, position)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
move_away_biteys(surface, event.area)
|
||||
--ffatable.chunk_generated[key] = true
|
||||
end
|
||||
|
||||
local function on_chunk_charted(event)
|
||||
local force = event.force
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
if force.valid then
|
||||
if force == game.forces["player"] or force == game.forces["rogue"] then
|
||||
force.clear_chart(surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- local on_init = function ()
|
||||
-- local ffatable = Table.get_table()
|
||||
-- ffatable.chunk_generated = {}
|
||||
-- end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
-- Event.on_init(on_init)
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
@ -156,9 +156,11 @@ local function handler_factory(event_id)
|
||||
return
|
||||
end
|
||||
|
||||
local is_spamming = SpamProtection.is_spamming(player, nil, 'UtilsGUI Handler')
|
||||
if is_spamming and player.name ~= 'Gerkiz' then
|
||||
return
|
||||
if not event.text then
|
||||
local is_spamming = SpamProtection.is_spamming(player, nil, 'UtilsGUI Handler')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
event.player = player
|
||||
|
@ -4,7 +4,7 @@ local Public = {}
|
||||
|
||||
local this = {
|
||||
prevent_spam = {}, -- the default table where all player indexes will be stored
|
||||
default_tick = 15, -- this defines the default tick to check weather or not a user is spamming a button.
|
||||
default_tick = 10, -- this defines the default tick to check weather or not a user is spamming a button.
|
||||
_DEBUG = false
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user