mirror of
https://github.com/veden/Rampant.git
synced 2025-01-14 02:23:01 +02:00
checked settler movement and working on new temperament
This commit is contained in:
parent
66b193c097
commit
05ca2126e9
206
LICENSE.md
206
LICENSE.md
@ -1,201 +1,7 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License.
|
||||
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ or send a letter to Creative Commons
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
PO Box 1866,
|
||||
Mountain View,
|
||||
CA 94042,
|
||||
USA.
|
||||
|
16
Upgrade.lua
16
Upgrade.lua
@ -43,7 +43,7 @@ function upgrade.attempt(natives, setNewSurface)
|
||||
end
|
||||
if (global.version < constants.VERSION_11) then
|
||||
natives.state = constants.AI_STATE_AGGRESSIVE
|
||||
natives.temperament = 0
|
||||
-- natives.temperament = 0
|
||||
|
||||
global.version = constants.VERSION_11
|
||||
end
|
||||
@ -304,6 +304,20 @@ function upgrade.attempt(natives, setNewSurface)
|
||||
natives.pendingAttack.len = #natives.pendingAttack
|
||||
natives.squads.len = #natives.squads
|
||||
|
||||
natives.activeRaidNests = 0
|
||||
natives.activeNests = 0
|
||||
natives.destroyPlayerBuildings = 0
|
||||
natives.lostEnemyUnits = 0
|
||||
natives.lostEnemyBuilding = 0
|
||||
natives.rocketLaunched = 0
|
||||
natives.builtEnemyBuilding = 0
|
||||
natives.ionCannonBlasts = 0
|
||||
natives.artilleryBlasts = 0
|
||||
|
||||
natives.temperament = 0
|
||||
natives.temperamentScore = 0
|
||||
natives.stateTick = 0
|
||||
|
||||
if not setNewSurface then
|
||||
game.surfaces[natives.activeSurface].print("Rampant - Version 0.17.29")
|
||||
end
|
||||
|
@ -11,6 +11,7 @@ Date: 07. 12. 2019
|
||||
- Better tracking of squads on chunks to accommodate the two step path finding
|
||||
- Collision checker for squads and squad movement from a container to a unit
|
||||
- Attack waves should generate more localized squad formations, so that biters appear to attack from all sides less
|
||||
- New AI temperament system
|
||||
Tweaks:
|
||||
- Increased minimum unit count for a retreat from 3 to 6
|
||||
- Biters and Spitters now are affected by tile modifiers
|
||||
@ -59,6 +60,8 @@ Date: 07. 12. 2019
|
||||
- Dropped support for 5 tier new enemy configuration
|
||||
- Changed default blood particle removal optimization to off
|
||||
- Added interop function that allows other mods to set the active surface for the AI processing
|
||||
License:
|
||||
- License change from Apache2 to CC BY-NC 4.0
|
||||
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Version: 0.17.28
|
||||
|
25
control.lua
25
control.lua
@ -31,6 +31,7 @@ local INTERVAL_SCAN = constants.INTERVAL_SCAN
|
||||
local INTERVAL_SQUAD = constants.INTERVAL_SQUAD
|
||||
local INTERVAL_RESQUAD = constants.INTERVAL_RESQUAD
|
||||
local INTERVAL_BUILDERS = constants.INTERVAL_BUILDERS
|
||||
local INTERVAL_TEMPERAMENT = constants.INTERVAL_TEMPERAMENT
|
||||
|
||||
local HIVE_BUILDINGS = constants.HIVE_BUILDINGS
|
||||
|
||||
@ -86,6 +87,8 @@ local squadsDispatch = squadAttack.squadsDispatch
|
||||
|
||||
local positionToChunkXY = mapUtils.positionToChunkXY
|
||||
|
||||
local temperamentPlanner = aiPlanning.temperamentPlanner
|
||||
|
||||
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
|
||||
|
||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
@ -148,6 +151,7 @@ local function onIonCannonFired(event)
|
||||
--]]
|
||||
local surface = event.surface
|
||||
if (surface.index == natives.activeSurface) then
|
||||
natives.ionCannonBlasts = natives.ionCannonBlasts + 1
|
||||
natives.points = natives.points + 3000
|
||||
local chunk = getChunkByPosition(map, event.position)
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
@ -615,6 +619,12 @@ script.on_nth_tick(INTERVAL_LOGIC,
|
||||
end
|
||||
end)
|
||||
|
||||
script.on_nth_tick(-- INTERVAL_TEMPERAMENT
|
||||
61,
|
||||
function (event)
|
||||
temperamentPlanner(natives)
|
||||
end)
|
||||
|
||||
script.on_nth_tick(INTERVAL_SQUAD,
|
||||
function ()
|
||||
squadsDispatch(map,
|
||||
@ -677,6 +687,10 @@ local function onDeath(event)
|
||||
|
||||
local artilleryBlast = (cause and ((cause.type == "artillery-wagon") or (cause.type == "artillery-turret")))
|
||||
|
||||
if artilleryBlast then
|
||||
natives.artilleryBlasts = natives.artilleryBlasts + 1
|
||||
end
|
||||
|
||||
if (entityType == "unit") then
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
-- drop death pheromone where unit died
|
||||
@ -684,6 +698,8 @@ local function onDeath(event)
|
||||
|
||||
if event.force and (event.force.name ~= "enemy") and (chunk[MOVEMENT_PHEROMONE] < -natives.retreatThreshold) then
|
||||
|
||||
natives.lostEnemyUnits = natives.lostEnemyUnits + 1
|
||||
|
||||
retreatUnits(chunk,
|
||||
entityPosition,
|
||||
convertUnitGroupToSquad(natives, entity.unit_group),
|
||||
@ -893,6 +909,7 @@ end
|
||||
local function onRocketLaunch(event)
|
||||
local entity = event.rocket_silo or event.rocket
|
||||
if entity and entity.valid and (entity.surface.index == natives.activeSurface) then
|
||||
natives.rocketLaunched = natives.rocketLaunched + 1
|
||||
natives.points = natives.points + 2000
|
||||
end
|
||||
end
|
||||
@ -954,6 +971,13 @@ local function onEntitySpawned(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function onUnitGroupCreated(event)
|
||||
local group = event.group
|
||||
if (group.force.name ~= "enemy") then
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local function onCommandDebugger(event)
|
||||
for i=1,natives.squads.len do
|
||||
if (natives.squads[i].group.valid) and (natives.squads[i].group.group_number == event.unit_number) then
|
||||
@ -1017,6 +1041,7 @@ script.on_event(defines.events.on_entity_spawned, onEntitySpawned)
|
||||
script.on_event(defines.events.on_rocket_launched, onRocketLaunch)
|
||||
script.on_event(defines.events.on_entity_died, onDeath)
|
||||
script.on_event(defines.events.on_chunk_generated, onChunkGenerated)
|
||||
-- script.on_event(defines.events.on_unit_group_created, onUnitGroupCreated)
|
||||
script.on_event(defines.events.on_force_created, onForceCreated)
|
||||
script.on_event(defines.events.on_forces_merged, onForceMerged)
|
||||
|
||||
|
@ -51,16 +51,15 @@ local mFloor = math.floor
|
||||
local mRandom = math.random
|
||||
|
||||
local mMax = math.max
|
||||
local mMin = math.min
|
||||
|
||||
-- module code
|
||||
|
||||
function aiPlanning.planning(natives, evolution_factor, tick)
|
||||
natives.evolutionLevel = evolution_factor
|
||||
|
||||
local maxPoints = AI_MAX_POINTS * evolution_factor
|
||||
|
||||
if natives.aiNocturnalMode then
|
||||
maxPoints = maxPoints * 0.85
|
||||
end
|
||||
|
||||
if not natives.ranIncompatibleMessage and natives.newEnemies and (game.active_mods["bobenemies"] or game.active_mods["Natural_Evolution_Enemies"]) then
|
||||
natives.ranIncompatibleMessage = true
|
||||
for i,p in ipairs(game.connected_players) do
|
||||
@ -68,8 +67,6 @@ function aiPlanning.planning(natives, evolution_factor, tick)
|
||||
end
|
||||
end
|
||||
|
||||
natives.evolutionLevel = evolution_factor
|
||||
|
||||
local maxOverflowPoints = maxPoints * 3
|
||||
|
||||
local attackWaveMaxSize = natives.attackWaveMaxSize
|
||||
@ -102,45 +99,208 @@ function aiPlanning.planning(natives, evolution_factor, tick)
|
||||
if (currentPoints < maxPoints) then
|
||||
natives.points = currentPoints + points
|
||||
end
|
||||
|
||||
|
||||
if (currentPoints > maxOverflowPoints) then
|
||||
natives.points = maxOverflowPoints
|
||||
end
|
||||
|
||||
if (natives.temperamentTick <= tick) then
|
||||
natives.temperament = mRandom()
|
||||
natives.temperamentTick = randomTickEvent(tick, AI_MIN_TEMPERAMENT_DURATION, AI_MAX_TEMPERAMENT_DURATION)
|
||||
end
|
||||
-- if (natives.temperamentTick <= tick) then
|
||||
-- natives.temperament = mRandom()
|
||||
-- natives.temperamentTick = randomTickEvent(tick, AI_MIN_TEMPERAMENT_DURATION, AI_MAX_TEMPERAMENT_DURATION)
|
||||
-- end
|
||||
|
||||
if (natives.stateTick <= tick) then
|
||||
local roll = mRandom() * mMax(1 - evolution_factor, 0.15) * natives.aiAggressiveness
|
||||
if (roll > natives.temperament) then
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
else
|
||||
roll = mRandom()
|
||||
if (roll < 0.65) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
natives.canAttackTick = randomTickEvent(tick,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
elseif ((natives.enabledMigration) and (natives.expansion) and (roll < 0.75)) then
|
||||
natives.state = AI_STATE_MIGRATING
|
||||
elseif ((natives.siegeAIToggle) and (natives.expansion) and (roll < 0.80)) then
|
||||
natives.state = AI_STATE_SIEGE
|
||||
elseif ((natives.onslaughtAIToggle) and (roll < 0.85)) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
elseif ((natives.raidAIToggle) and (evolution_factor >= 0.04)) then
|
||||
natives.state = AI_STATE_RAIDING
|
||||
-- local roll = mRandom() * mMax(1 - evolution_factor, 0.15) * natives.aiAggressiveness
|
||||
-- if (roll > natives.temperament) then
|
||||
-- natives.state = AI_STATE_PEACEFUL
|
||||
-- else
|
||||
-- roll = mRandom()
|
||||
-- if (roll < 0.65) then
|
||||
-- natives.state = AI_STATE_AGGRESSIVE
|
||||
-- natives.canAttackTick = randomTickEvent(tick,
|
||||
-- AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
|
||||
-- AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
|
||||
-- elseif ((natives.enabledMigration) and (natives.expansion) and (roll < 0.75)) then
|
||||
-- natives.state = AI_STATE_MIGRATING
|
||||
-- elseif ((natives.siegeAIToggle) and (natives.expansion) and (roll < 0.80)) then
|
||||
-- natives.state = AI_STATE_SIEGE
|
||||
-- elseif ((natives.onslaughtAIToggle) and (roll < 0.85)) then
|
||||
-- natives.state = AI_STATE_ONSLAUGHT
|
||||
-- elseif ((natives.raidAIToggle) and (evolution_factor >= 0.04)) then
|
||||
-- natives.state = AI_STATE_RAIDING
|
||||
|
||||
natives.points = natives.points + 1000
|
||||
-- natives.points = natives.points + 1000
|
||||
-- else
|
||||
-- natives.state = AI_STATE_AGGRESSIVE
|
||||
-- end
|
||||
-- end
|
||||
|
||||
local roll = mRandom()
|
||||
if (natives.temperament < 1) then -- 0 - 0.05
|
||||
if natives.expansion then
|
||||
natives.state = AI_STATE_SIEGE
|
||||
else
|
||||
if natives.raidAIToggle then
|
||||
natives.state = AI_STATE_RAIDING
|
||||
else
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
end
|
||||
end
|
||||
elseif (natives.temperament < 0.20) then -- 0.05 - 0.2
|
||||
if (roll < 0.2) then
|
||||
natives.state = AI_STATE_SIEGE
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_MIGRATING
|
||||
end
|
||||
elseif (natives.temperament < 0.4) then -- 0.2 - 0.4
|
||||
if (roll < 0.2) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_MIGRATING
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
elseif (natives.temperament < 0.6) then -- 0.4 - 0.6
|
||||
if (roll < 0.6) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
elseif (natives.temperament < 0.8) then -- 0.6 - 0.8
|
||||
if (roll < 0.6) then
|
||||
natives.state = AI_STATE_AGGRESSIVE
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
else
|
||||
natives.state = AI_STATE_PEACEFUL
|
||||
end
|
||||
else -- 0.8 - 1
|
||||
if (roll < 0.2) then
|
||||
natives.state = AI_STATE_SIEGE
|
||||
elseif (roll < 0.8) then
|
||||
natives.state = AI_STATE_ONSLAUGHT
|
||||
elseif (roll < 0.9) then
|
||||
natives.state = AI_STATE_RAIDING
|
||||
end
|
||||
end
|
||||
|
||||
print("changing state", natives.state)
|
||||
|
||||
natives.stateTick = randomTickEvent(tick, AI_MIN_STATE_DURATION, AI_MAX_STATE_DURATION)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function aiPlanning.temperamentPlanner(natives)
|
||||
local destroyPlayerBuildings = natives.destroyPlayerBuildings
|
||||
local lostEnemyUnits = natives.lostEnemyUnits
|
||||
local lostEnemyBuilding = natives.lostEnemyBuilding
|
||||
local rocketLaunched = natives.rocketLaunched
|
||||
local builtEnemyBuilding = natives.builtEnemyBuilding
|
||||
local ionCannonBlasts = natives.ionCannonBlasts
|
||||
local artilleryBlasts = natives.artilleryBlasts
|
||||
local activeNests = natives.activeNests
|
||||
local activeRaidNests = natives.activeRaidNests
|
||||
|
||||
local currentTemperament = natives.temperamentScore
|
||||
local delta = 0
|
||||
|
||||
if activeNests > 0 then
|
||||
local val = (1 * activeNests)
|
||||
delta = delta + val
|
||||
|
||||
if destroyPlayerBuildings > 0 then
|
||||
delta = delta - (1 * destroyPlayerBuildings)
|
||||
else
|
||||
delta = delta + val
|
||||
end
|
||||
|
||||
else
|
||||
delta = delta - 1
|
||||
|
||||
if destroyPlayerBuildings > 0 then
|
||||
delta = delta - (1 * destroyPlayerBuildings)
|
||||
else
|
||||
delta = delta - 1
|
||||
end
|
||||
end
|
||||
|
||||
if activeRaidNests > 0 then
|
||||
local val = (0.01 * activeRaidNests)
|
||||
delta = delta - val
|
||||
else
|
||||
delta = delta - 1
|
||||
end
|
||||
|
||||
if lostEnemyUnits > 0 then
|
||||
local val = (0.001 * lostEnemyUnits)
|
||||
if (currentTemperament > 0) then
|
||||
delta = delta - val
|
||||
else
|
||||
delta = delta + val
|
||||
end
|
||||
else
|
||||
if (currentTemperament < 0) then
|
||||
delta = delta - 1
|
||||
else
|
||||
delta = delta + 1
|
||||
end
|
||||
end
|
||||
|
||||
if lostEnemyBuilding > 0 then
|
||||
delta = delta + (1 * lostEnemyBuilding)
|
||||
else
|
||||
if (currentTemperament < 0) then
|
||||
delta = delta - 1
|
||||
else
|
||||
delta = delta + 1
|
||||
end
|
||||
end
|
||||
|
||||
if (builtEnemyBuilding > 0) then
|
||||
local val = (1 * builtEnemyBuilding)
|
||||
if (currentTemperament > 0) then
|
||||
delta = delta - val
|
||||
else
|
||||
delta = delta + val
|
||||
end
|
||||
else
|
||||
delta = delta - 1
|
||||
end
|
||||
|
||||
if (rocketLaunched > 0) then
|
||||
local val = (1 * rocketLaunched)
|
||||
delta = delta + val
|
||||
end
|
||||
|
||||
if (ionCannonBlasts > 0) then
|
||||
local val = (1 * ionCannonBlasts)
|
||||
delta = delta + val
|
||||
end
|
||||
|
||||
if (artilleryBlasts > 0) then
|
||||
local val = (1 * artilleryBlasts)
|
||||
delta = delta + val
|
||||
end
|
||||
|
||||
print(natives.activeNests, natives.activeRaidNests, natives.destroyPlayerBuildings, natives.lostEnemyUnits,
|
||||
natives.lostEnemyBuilding, natives.rocketLaunched, natives.builtEnemyBuilding, natives.ionCannonBlasts,
|
||||
natives.artilleryBlasts)
|
||||
|
||||
natives.destroyPlayerBuildings = 0
|
||||
natives.lostEnemyUnits = 0
|
||||
natives.lostEnemyBuilding = 0
|
||||
natives.rocketLaunched = 0
|
||||
natives.builtEnemyBuilding = 0
|
||||
natives.ionCannonBlasts = 0
|
||||
natives.artilleryBlasts = 0
|
||||
|
||||
natives.temperamentScore = mMin(1000, mMax(-1000, currentTemperament + delta))
|
||||
natives.temperament = (natives.temperamentScore + 1000) * 0.0005
|
||||
print(natives.temperament, natives.temperamentScore)
|
||||
print("--")
|
||||
end
|
||||
|
||||
aiPlanningG = aiPlanning
|
||||
return aiPlanning
|
||||
|
@ -150,8 +150,14 @@ end
|
||||
|
||||
function chunkPropertyUtils.setRaidNestActiveness(map, chunk, value)
|
||||
if (value <= 0) then
|
||||
if (map.chunkToActiveRaidNest[chunk] ~= nil) then
|
||||
map.natives.activeRaidNests = map.natives.activeRaidNests - 1
|
||||
end
|
||||
map.chunkToActiveRaidNest[chunk] = nil
|
||||
else
|
||||
if (map.chunkToActiveRaidNest[chunk] == nil) then
|
||||
map.natives.activeRaidNests = map.natives.activeRaidNests + 1
|
||||
end
|
||||
map.chunkToActiveRaidNest[chunk] = value
|
||||
end
|
||||
end
|
||||
@ -162,8 +168,14 @@ end
|
||||
|
||||
function chunkPropertyUtils.setNestActiveness(map, chunk, value)
|
||||
if (value <= 0) then
|
||||
if (map.chunkToActiveNest[chunk] ~= nil) then
|
||||
map.natives.activeNests = map.natives.activeNests - 1
|
||||
end
|
||||
map.chunkToActiveNest[chunk] = nil
|
||||
else
|
||||
if (map.chunkToActiveNest[chunk] == nil) then
|
||||
map.natives.activeNests = map.natives.activeNests + 1
|
||||
end
|
||||
map.chunkToActiveNest[chunk] = value
|
||||
end
|
||||
end
|
||||
@ -222,7 +234,7 @@ function chunkPropertyUtils.addSquadToChunk(map, chunk, squad)
|
||||
squads[#squads+1] = squad
|
||||
|
||||
squad.chunk = chunk
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.removeSquadFromChunk(map, squad)
|
||||
|
@ -214,7 +214,7 @@ function chunkUtils.initialScan(chunk, surface, map, tick, rebuilding)
|
||||
if (pass ~= CHUNK_IMPASSABLE) then
|
||||
local worms = surface.find_entities_filtered(map.filteredEntitiesWormQuery)
|
||||
local resources = surface.count_entities_filtered(map.countResourcesQuery) * RESOURCE_NORMALIZER
|
||||
|
||||
|
||||
local buildingHiveTypeLookup = natives.buildingHiveTypeLookup
|
||||
local counts = map.chunkScanCounts
|
||||
for i=1,#HIVE_BUILDINGS_TYPES do
|
||||
@ -354,7 +354,7 @@ function chunkUtils.mapScanChunk(chunk, surface, map)
|
||||
local counts = map.chunkScanCounts
|
||||
for i=1,#HIVE_BUILDINGS_TYPES do
|
||||
counts[HIVE_BUILDINGS_TYPES[i]] = 0
|
||||
end
|
||||
end
|
||||
for i=1,#nests do
|
||||
local hiveType = buildingHiveTypeLookup[nests[i].name] or "biter-spawner"
|
||||
counts[hiveType] = counts[hiveType] + 1
|
||||
@ -369,7 +369,7 @@ function chunkUtils.mapScanChunk(chunk, surface, map)
|
||||
setUtilityCount(map, chunk, counts["utility"])
|
||||
setHiveCount(map, chunk, counts["hive"])
|
||||
setTrapCount(map, chunk, counts["trap"])
|
||||
setTurretCount(map, chunk, counts["turret"])
|
||||
setTurretCount(map, chunk, counts["turret"])
|
||||
end
|
||||
|
||||
function chunkUtils.entityForPassScan(map, entity)
|
||||
@ -414,32 +414,39 @@ function chunkUtils.registerEnemyBaseStructure(map, entity, base)
|
||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||
local overlapArray = getEntityOverlapChunks(map, entity)
|
||||
|
||||
local natives = map.natives
|
||||
local getFunc
|
||||
local setFunc
|
||||
local hiveTypeLookup = map.natives.buildingHiveTypeLookup
|
||||
local hiveTypeLookup = natives.buildingHiveTypeLookup
|
||||
local hiveType = hiveTypeLookup[entity.name]
|
||||
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
elseif (hiveType == "turret") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (hiveType == "trap") then
|
||||
getFunc = getTrapCount
|
||||
setFunc = setTrapCount
|
||||
elseif (hiveType == "utility") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
getFunc = getUtilityCount
|
||||
setFunc = setUtilityCount
|
||||
setFunc = setUtilityCount
|
||||
elseif (hiveType == "hive") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
getFunc = getHiveCount
|
||||
setFunc = setHiveCount
|
||||
else
|
||||
if (entityType == "turret") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (entityType == "unit-spawner") then
|
||||
natives.builtEnemyBuilding = natives.builtEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
setFunc = setNestCount
|
||||
end
|
||||
end
|
||||
|
||||
@ -460,32 +467,39 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
|
||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||
local overlapArray = getEntityOverlapChunks(map, entity)
|
||||
|
||||
local natives = map.natives
|
||||
local getFunc
|
||||
local setFunc
|
||||
local hiveTypeLookup = map.natives.buildingHiveTypeLookup
|
||||
local hiveType = hiveTypeLookup[entity.name]
|
||||
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
elseif (hiveType == "turret") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (hiveType == "trap") then
|
||||
getFunc = getTrapCount
|
||||
setFunc = setTrapCount
|
||||
elseif (hiveType == "utility") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
getFunc = getUtilityCount
|
||||
setFunc = setUtilityCount
|
||||
setFunc = setUtilityCount
|
||||
elseif (hiveType == "hive") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
getFunc = getHiveCount
|
||||
setFunc = setHiveCount
|
||||
else
|
||||
if (entityType == "turret") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
getFunc = getTurretCount
|
||||
setFunc = setTurretCount
|
||||
elseif (entityType == "unit-spawner") then
|
||||
natives.lostEnemyBuilding = natives.lostEnemyBuilding + 1
|
||||
getFunc = getNestCount
|
||||
setFunc = setNestCount
|
||||
setFunc = setNestCount
|
||||
end
|
||||
end
|
||||
|
||||
@ -514,7 +528,6 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
|
||||
end
|
||||
|
||||
function chunkUtils.accountPlayerEntity(entity, natives, addObject, creditNatives)
|
||||
|
||||
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name ~= "enemy") then
|
||||
local map = natives.map
|
||||
local entityValue = BUILDING_PHEROMONES[entity.type]
|
||||
@ -522,6 +535,7 @@ function chunkUtils.accountPlayerEntity(entity, natives, addObject, creditNative
|
||||
local overlapArray = getEntityOverlapChunks(map, entity)
|
||||
if not addObject then
|
||||
if creditNatives then
|
||||
natives.destroyPlayerBuildings = natives.destroyPlayerBuildings + 1
|
||||
if (natives.state == AI_STATE_ONSLAUGHT) then
|
||||
natives.points = natives.points + entityValue
|
||||
else
|
||||
|
@ -59,7 +59,8 @@ constants.INTERVAL_PLAYER_PROCESS = (settings.startup["rampant-liteMode"].value
|
||||
constants.INTERVAL_MAP_PROCESS = (settings.startup["rampant-liteMode"].value and 8) or 5
|
||||
constants.INTERVAL_SCAN = (settings.startup["rampant-liteMode"].value and 42) or 21
|
||||
constants.INTERVAL_CHUNK = 17
|
||||
constants.INTERVAL_LOGIC = 61
|
||||
constants.INTERVAL_LOGIC = 60
|
||||
constants.INTERVAL_TEMPERAMENT = 60 * 360
|
||||
constants.INTERVAL_SQUAD = 41
|
||||
constants.INTERVAL_RESQUAD = 101
|
||||
constants.INTERVAL_BUILDERS = 300
|
||||
@ -122,7 +123,7 @@ constants.AI_SQUAD_MERGE_THRESHOLD = constants.AI_MAX_BITER_GROUP_SIZE * 0.75
|
||||
|
||||
constants.AI_STATE_PEACEFUL = 1
|
||||
constants.AI_STATE_AGGRESSIVE = 2
|
||||
constants.AI_STATE_NOCTURNAL = 3
|
||||
-- constants.AI_STATE_NOCTURNAL = 3
|
||||
constants.AI_STATE_RAIDING = 4
|
||||
constants.AI_STATE_MIGRATING = 5
|
||||
constants.AI_STATE_SIEGE = 6
|
||||
@ -139,8 +140,11 @@ constants.BASE_AI_STATE_MUTATE = 3
|
||||
constants.AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION = 0.5
|
||||
constants.AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION = 3
|
||||
|
||||
constants.AI_MIN_STATE_DURATION = 7
|
||||
constants.AI_MAX_STATE_DURATION = 17
|
||||
-- constants.AI_MIN_STATE_DURATION = 7
|
||||
-- constants.AI_MAX_STATE_DURATION = 17
|
||||
constants.AI_MIN_STATE_DURATION = 0.2
|
||||
constants.AI_MAX_STATE_DURATION = 0.2
|
||||
|
||||
constants.AI_MIN_TEMPERAMENT_DURATION = 25
|
||||
constants.AI_MAX_TEMPERAMENT_DURATION = 32
|
||||
|
||||
@ -444,7 +448,7 @@ constants.FACTION_SET[#constants.FACTION_SET+1] = {
|
||||
type = "spitter-spawner",
|
||||
name = "spitter-spawner",
|
||||
majorResistances = {},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
minorResistances = {},
|
||||
attributes = {},
|
||||
drops = {"nilArtifact"},
|
||||
@ -456,7 +460,7 @@ constants.FACTION_SET[#constants.FACTION_SET+1] = {
|
||||
type = "biter-spawner",
|
||||
name = "biter-spawner",
|
||||
majorResistances = {},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
minorResistances = {},
|
||||
attributes = {},
|
||||
drops = {"nilArtifact"},
|
||||
@ -525,7 +529,7 @@ if settings.startup["rampant-acidEnemy"].value then
|
||||
name = "spitter-spawner",
|
||||
majorResistances = {"acid"},
|
||||
minorResistances = {"poison"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"greenArtifact"},
|
||||
buildSets = {
|
||||
@ -537,7 +541,7 @@ if settings.startup["rampant-acidEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"acid"},
|
||||
minorResistances = {"poison"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"greenArtifact"},
|
||||
buildSets = {
|
||||
@ -603,7 +607,7 @@ if settings.startup["rampant-laserEnemy"].value then
|
||||
type = "spitter-spawner",
|
||||
name = "spitter-spawner",
|
||||
majorResistances = {"laser", "electric"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"blueArtifact"},
|
||||
buildSets = {
|
||||
@ -614,7 +618,7 @@ if settings.startup["rampant-laserEnemy"].value then
|
||||
type = "biter-spawner",
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"laser", "electric"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"blueArtifact"},
|
||||
buildSets = {
|
||||
@ -681,7 +685,7 @@ if settings.startup["rampant-fireEnemy"].value then
|
||||
name = "spitter-spawner",
|
||||
majorResistances = {"fire", "acid"},
|
||||
minorResistances = {},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"redArtifact"},
|
||||
buildSets = {
|
||||
@ -692,7 +696,7 @@ if settings.startup["rampant-fireEnemy"].value then
|
||||
type = "biter-spawner",
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"fire", "acid"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
minorResistances = {},
|
||||
attributes = {},
|
||||
drops = {"redArtifact"},
|
||||
@ -753,7 +757,7 @@ if settings.startup["rampant-infernoEnemy"].value then
|
||||
name = "spitter-spawner",
|
||||
majorResistances = {"acid", "fire"},
|
||||
minorWeaknesses = {"poison"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"orangeArtifact"},
|
||||
buildSets = {
|
||||
@ -823,7 +827,7 @@ if settings.startup["rampant-waspEnemy"].value then
|
||||
type = "spitter-spawner",
|
||||
name = "spitter-spawner",
|
||||
attributes = {},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
drops = {"purpleArtifact"},
|
||||
buildSets = {
|
||||
{"spitter", 1, 10}
|
||||
@ -896,7 +900,7 @@ if settings.startup["rampant-spawnerEnemy"].value then
|
||||
name = "spitter-spawner",
|
||||
attributes = {},
|
||||
drops = {"orangeArtifact"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
buildSets = {
|
||||
{"spitter", 1, 10}
|
||||
}
|
||||
@ -949,7 +953,7 @@ if settings.startup["rampant-electricEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"electric"},
|
||||
minorResistances = {"laser"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"blueArtifact"},
|
||||
buildSets = {
|
||||
@ -998,7 +1002,7 @@ if settings.startup["rampant-physicalEnemy"].value then
|
||||
name = "biter",
|
||||
majorResistances = {"physical", "explosion"},
|
||||
minorWeaknesses = {"laser", "electric"},
|
||||
attributes = {"highHealth", "longReach", "big", "highRegen", "slowMovement", "altBiterArmored"},
|
||||
attributes = {"highHealth", "longReach", "big", "slowMovement", "altBiterArmored"},
|
||||
drops = {"redArtifact"}
|
||||
}
|
||||
},
|
||||
@ -1008,8 +1012,8 @@ if settings.startup["rampant-physicalEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"physical", "explosion"},
|
||||
minorWeaknesses = {"laser", "electric"},
|
||||
attributes = {"highHealth", "bigger", "highRegen"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
attributes = {"highHealth", "bigger"},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
drops = {"redArtifact"},
|
||||
buildSets = {
|
||||
{"biter", 1, 10}
|
||||
@ -1022,7 +1026,7 @@ if settings.startup["rampant-physicalEnemy"].value then
|
||||
minorWeaknesses = {"laser", "electric"},
|
||||
attackAttributes = {"spit", "physical"},
|
||||
acceptRate = {1, 10, 0.8, 0.6},
|
||||
attributes = {"highHealth", "bigger", "highRegen"},
|
||||
attributes = {"highHealth", "bigger"},
|
||||
drops = {"redArtifact"}
|
||||
},
|
||||
{
|
||||
@ -1067,7 +1071,7 @@ if settings.startup["rampant-trollEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
minorResistances = {"physical", "explosion"},
|
||||
majorWeaknesses = {"fire"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {"highestHealth", "bigger", "highestRegen"},
|
||||
drops = {"greenArtifact"},
|
||||
buildSets = {
|
||||
@ -1129,7 +1133,7 @@ if settings.startup["rampant-poisonEnemy"].value then
|
||||
majorResistances = {"poison"},
|
||||
minorWeaknesses = {"electric", "explosion", "laser"},
|
||||
attributes = {"poisonDeathCloud"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
drops = {"greenArtifact"},
|
||||
buildSets = {
|
||||
{"biter", 1, 10}
|
||||
@ -1189,7 +1193,7 @@ if settings.startup["rampant-suicideEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"explosion"},
|
||||
minorResistances = {"poison"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"yellowArtifact", "quickSpawning", "lowUnits"},
|
||||
buildSets = {
|
||||
@ -1247,7 +1251,7 @@ if settings.startup["rampant-nuclearEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"explosion"},
|
||||
minorResistances = {"fire"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"yellowArtifact", "quickSpawning", "lowUnits"},
|
||||
buildSets = {
|
||||
@ -1306,7 +1310,7 @@ if settings.startup["rampant-energyThiefEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {"electric", "laser"},
|
||||
minorResistances = {},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {},
|
||||
drops = {"blueArtifact"},
|
||||
buildSets = {
|
||||
@ -1374,7 +1378,7 @@ if settings.startup["rampant-fastEnemy"].value then
|
||||
majorResistances = {},
|
||||
minorResistances = {"explosion"},
|
||||
attributes = {"quickSpawning"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
drops = {"purpleArtifact"},
|
||||
buildSets = {
|
||||
{"spitter", 1, 10}
|
||||
@ -1385,7 +1389,7 @@ if settings.startup["rampant-fastEnemy"].value then
|
||||
name = "biter-spawner",
|
||||
majorResistances = {},
|
||||
minorResistances = {"explosion"},
|
||||
acceptRate = {1, 10, 0.1, 0.2},
|
||||
acceptRate = {1, 10, 0.3, 0.5},
|
||||
attributes = {"quickSpawning"},
|
||||
drops = {"purpleArtifact"},
|
||||
buildSets = {
|
||||
|
@ -161,6 +161,34 @@ function mapProcessor.processMap(map, surface, tick)
|
||||
end
|
||||
end
|
||||
|
||||
local function processNestActiveness(map, chunk, natives, surface)
|
||||
local nests = getNestCount(map, chunk)
|
||||
if (nests > 0) then
|
||||
local activeness = getNestActiveness(map, chunk)
|
||||
local raidActiveness = getRaidNestActiveness(map, chunk)
|
||||
if natives.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > natives.attackPlayerThreshold) then
|
||||
setNestActiveness(map, chunk, mMin(activeness + 5, 20))
|
||||
elseif (chunk[BASE_PHEROMONE] > 0) then
|
||||
if (surface.get_pollution(chunk) > 0) then
|
||||
setNestActiveness(map, chunk, mMin(activeness + 5, 20))
|
||||
else
|
||||
setNestActiveness(map, chunk, activeness - 2)
|
||||
if (chunk[BASE_PHEROMONE] > RAIDING_MINIMUM_BASE_THRESHOLD) then
|
||||
setRaidNestActiveness(map, chunk, mMin(raidActiveness + 3, 20))
|
||||
else
|
||||
setRaidNestActiveness(map, chunk, raidActiveness - 1)
|
||||
end
|
||||
end
|
||||
else
|
||||
setNestActiveness(map, chunk, activeness - 5)
|
||||
setRaidNestActiveness(map, chunk, raidActiveness - 5)
|
||||
end
|
||||
else
|
||||
setNestActiveness(map, chunk, 0)
|
||||
setRaidNestActiveness(map, chunk, 0)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Localized player radius were processing takes place in realtime, doesn't store state
|
||||
between calls.
|
||||
@ -199,31 +227,7 @@ function mapProcessor.processPlayers(players, map, surface, tick)
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) and (chunk[CHUNK_TICK] ~= tick) then
|
||||
processPheromone(map, chunk, scentStaging[i])
|
||||
|
||||
local nests = getNestCount(map, chunk)
|
||||
if (nests > 0) then
|
||||
local activeness = getNestActiveness(map, chunk)
|
||||
local raidActiveness = getRaidNestActiveness(map, chunk)
|
||||
if natives.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > natives.attackPlayerThreshold) then
|
||||
setNestActiveness(map, chunk, mMin((activeness or 0) + 5, 20))
|
||||
elseif (chunk[BASE_PHEROMONE] > 0) then
|
||||
if (surface.get_pollution(chunk) > 0) then
|
||||
setNestActiveness(map, chunk, mMin((activeness or 0) + 5, 20))
|
||||
else
|
||||
setNestActiveness(map, chunk, activeness - 2)
|
||||
if (chunk[BASE_PHEROMONE] > RAIDING_MINIMUM_BASE_THRESHOLD) then
|
||||
setRaidNestActiveness(map, chunk, mMin((raidActiveness or 0) + 3, 20))
|
||||
else
|
||||
setRaidNestActiveness(map, chunk, raidActiveness - 1)
|
||||
end
|
||||
end
|
||||
else
|
||||
setNestActiveness(map, chunk, activeness - 5)
|
||||
setRaidNestActiveness(map, chunk, raidActiveness - 5)
|
||||
end
|
||||
else
|
||||
setNestActiveness(map, chunk, 0)
|
||||
setRaidNestActiveness(map, chunk, 0)
|
||||
end
|
||||
processNestActiveness(map, chunk, natives, surface)
|
||||
|
||||
if vengence and (getNestCount(map, chunk) > 0) then
|
||||
vengence = formVengenceSquad(map, surface, chunk)
|
||||
@ -324,33 +328,8 @@ function mapProcessor.scanMap(map, surface, tick)
|
||||
if isFullMapScan then
|
||||
mapScanChunk(chunk, surface, map)
|
||||
end
|
||||
|
||||
local nests = getNestCount(map, chunk)
|
||||
if (nests > 0) then
|
||||
local activeness = getNestActiveness(map, chunk)
|
||||
local raidActiveness = getRaidNestActiveness(map, chunk)
|
||||
if natives.attackUsePlayer and (chunk[PLAYER_PHEROMONE] > natives.attackPlayerThreshold) then
|
||||
setNestActiveness(map, chunk, mMin((activeness or 0) + 5, 20))
|
||||
elseif (chunk[BASE_PHEROMONE] > 0) then
|
||||
if (surface.get_pollution(chunk) > 0) then
|
||||
setNestActiveness(map, chunk, mMin((activeness or 0) + 5, 20))
|
||||
else
|
||||
setNestActiveness(map, chunk, activeness - 2)
|
||||
if (chunk[BASE_PHEROMONE] > RAIDING_MINIMUM_BASE_THRESHOLD) then
|
||||
setRaidNestActiveness(map, chunk, mMin((raidActiveness or 0) + 3, 20))
|
||||
else
|
||||
setRaidNestActiveness(map, chunk, raidActiveness - 1)
|
||||
end
|
||||
end
|
||||
else
|
||||
setNestActiveness(map, chunk, activeness - 5)
|
||||
setRaidNestActiveness(map, chunk, raidActiveness - 5)
|
||||
end
|
||||
else
|
||||
setNestActiveness(map, chunk, 0)
|
||||
setRaidNestActiveness(map, chunk, 0)
|
||||
end
|
||||
|
||||
processNestActiveness(map, chunk, natives, surface)
|
||||
end
|
||||
|
||||
if (endIndex == #processQueue) then
|
||||
|
@ -142,7 +142,7 @@ end
|
||||
function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction, squad)
|
||||
local highestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
||||
local highestDirection
|
||||
local highestDirection = 0
|
||||
|
||||
for x=1,8 do
|
||||
local neighborChunk = neighborDirectionChunks[x]
|
||||
@ -162,7 +162,7 @@ function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionCh
|
||||
|
||||
local nextHighestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||
local nextHighestScore = -MAGIC_MAXIMUM_NUMBER
|
||||
local nextHighestDirection
|
||||
local nextHighestDirection = 0
|
||||
|
||||
if (highestChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
|
||||
@ -181,10 +181,6 @@ function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionCh
|
||||
end
|
||||
end
|
||||
|
||||
if (nextHighestChunk == nil) then
|
||||
nextHighestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||
end
|
||||
|
||||
return highestChunk, highestDirection, nextHighestChunk, nextHighestDirection
|
||||
end
|
||||
|
||||
|
@ -11,6 +11,7 @@ local unitGroupUtils = require("UnitGroupUtils")
|
||||
local movementUtils = require("MovementUtils")
|
||||
local mathUtils = require("MathUtils")
|
||||
local chunkPropertyUtils = require("ChunkPropertyUtils")
|
||||
local chunkUtils = require("ChunkUtils")
|
||||
|
||||
-- constants
|
||||
|
||||
@ -144,7 +145,7 @@ local function settleMove(map, squad, surface)
|
||||
local cmd
|
||||
local position
|
||||
local position2
|
||||
|
||||
|
||||
if (distance >= squad.maxDistance) or ((getResourceGenerator(map, chunk) ~= 0) and (getNestCount(map, chunk) == 0))
|
||||
then
|
||||
if not ((groupState == DEFINES_GROUP_FINISHED) or ((groupState == DEFINES_GROUP_GATHERING) and (squad.cycles <= 0))) then
|
||||
@ -157,6 +158,9 @@ local function settleMove(map, squad, surface)
|
||||
position = groupPosition
|
||||
end
|
||||
|
||||
targetPosition.x = position.x
|
||||
targetPosition.y = position.y
|
||||
|
||||
cmd = map.settleCommand
|
||||
if squad.kamikaze then
|
||||
cmd.distraction = DEFINES_DISTRACTION_NONE
|
||||
@ -179,7 +183,7 @@ local function settleMove(map, squad, surface)
|
||||
end
|
||||
end
|
||||
|
||||
squad.cycles = 400
|
||||
squad.cycles = 40
|
||||
group.set_command(cmd)
|
||||
else
|
||||
local attackChunk, attackDirection, nextAttackChunk, nextAttackDirection = scoreNeighborsForSettling(map,
|
||||
@ -207,7 +211,7 @@ local function settleMove(map, squad, surface)
|
||||
else
|
||||
targetPosition.x = position.x
|
||||
targetPosition.y = position.y
|
||||
|
||||
|
||||
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) or
|
||||
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
|
||||
then
|
||||
@ -228,7 +232,7 @@ local function settleMove(map, squad, surface)
|
||||
end
|
||||
end
|
||||
|
||||
if (nextAttackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
if (nextAttackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
positionFromDirectionAndFlat(nextAttackDirection, targetPosition, targetPosition2)
|
||||
|
||||
position2 = findMovementPosition(surface, targetPosition2)
|
||||
@ -263,10 +267,10 @@ local function settleMove(map, squad, surface)
|
||||
|
||||
squad.status = SQUAD_BUILDING
|
||||
|
||||
map.buildPositionTop.x = position.x - BASE_CLEAN_DISTANCE
|
||||
map.buildPositionTop.y = position.y - BASE_CLEAN_DISTANCE
|
||||
map.buildPositionBottom.x = position.x + BASE_CLEAN_DISTANCE
|
||||
map.buildPositionBottom.y = position.y + BASE_CLEAN_DISTANCE
|
||||
map.buildPositionTop.x = targetPosition.x - BASE_CLEAN_DISTANCE
|
||||
map.buildPositionTop.y = targetPosition.y - BASE_CLEAN_DISTANCE
|
||||
map.buildPositionBottom.x = targetPosition.x + BASE_CLEAN_DISTANCE
|
||||
map.buildPositionBottom.y = targetPosition.y + BASE_CLEAN_DISTANCE
|
||||
|
||||
local entities = surface.find_entities_filtered(map.filteredEntitiesClearBuildingQuery)
|
||||
for i=1,#entities do
|
||||
@ -276,7 +280,7 @@ local function settleMove(map, squad, surface)
|
||||
end
|
||||
end
|
||||
|
||||
squad.cycles = 400
|
||||
squad.cycles = 40
|
||||
group.set_command(cmd)
|
||||
else
|
||||
squad.cycles = 23
|
||||
|
@ -202,10 +202,9 @@ function unitGroupUtils.cleanBuilders(natives, surface)
|
||||
position.x = groupPosition.x
|
||||
position.y = groupPosition.y
|
||||
|
||||
squad.cycles = 400
|
||||
squad.cycles = 40
|
||||
|
||||
group.set_command(cmd)
|
||||
group.start_moving()
|
||||
else
|
||||
tRemove(squads, i)
|
||||
group.destroy()
|
||||
|
@ -15440,7 +15440,7 @@ rampant-safeBuildings-railSignals=Make rail signals safe from biters
|
||||
rampant-safeBuildings-lamps=Make lamps safe from biters
|
||||
rampant-safeBuildings-trainStops=Make train stops safe from biters
|
||||
rampant-attackPlayerThreshold=The score that a chunk must reach for it to contribute to the attack threshold. Increasing reduces player pheromone cloud impact.
|
||||
rampant-permanentNocturnal=Toggling this will cause Rampant attack waves to spawn at night. DOES NOT turn off vanilla attack groups yet. Works better with Day/Night extender mod.
|
||||
rampant-permanentNocturnal=Toggling this will cause Rampant attack waves to spawn at night. DOES NOT turn off vanilla attack groups yet. Works better with the clockwork mod.
|
||||
rampant-aiPointsScaler=Between 0.0 and 5.0. This scales how many action points the ai gets per logic cycle to perform actions like making attack waves. 0.3 - very easy, 0.75 - easy, 1.0 - medium, 1.25+ - hard
|
||||
rampant-addWallResistanceAcid=Toggling this will cause a %60 acid resistance to be added to all wall entities to reduce the damage done by spitters to walls back to vanilla levels.
|
||||
rampant-removeBloodParticles=The blood particles that are created when biters are being killed can cause UPS spikes, this removes them.
|
||||
|
Loading…
Reference in New Issue
Block a user