Skip to content

Commit

Permalink
Major fixes for ancient expansion logic #464
Browse files Browse the repository at this point in the history
Additionally distance optimised as was still too close to creeps in some cases.

Disabled special racial militia, ancient expand, tower rush in team games as hardcoded targets still break these special attacks.

Fixed a bug where all special racial expansions could not run on the first expansion.
  • Loading branch information
SMUnlimited committed Dec 18, 2024
1 parent 20bd84c commit 8341b0a
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 348 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Deprecated
- (DevTools) 'race_ancient_expansion_strength' setting does not do anything anymore as it uses actual strength to determine feasability of attack.

### Fixed
- Fixed edge cases where retreat location could not be the home town as expected.
- Disabled special racial militia, ancient expand, tower rush in team games as hardcoded targets still break these special attacks.
- Fixed a bug where all special racial expansions could not run on the first expansion.
- Lots of fixes to ancient expansion logic improving overall reliability.
- Fixed bug where ancient attacks didn't take account of ancient strength in retreat calculations.
- (DevTools) Removed use of hardcoded ids in expansion tracking for custom mod support.

## [3.4.1] - 2024-12-07
Expand Down
385 changes: 151 additions & 234 deletions Jobs/ANCIENT_EXPANSION.eai

Large diffs are not rendered by default.

51 changes: 23 additions & 28 deletions Jobs/ANCIENT_EXPANSION_CHECK.eai
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,30 @@
#ELSE

// ######################## Ancient Expansion Check #################
// # Created by Strategy Master 13/07/05. Conditions that check that
// # an ancient expansion can start.
// ##################################################################

// Job only exists to run the pathing code outside the expansion builder code to not cause a delay to build processes
// TODO once we can do pathing requests in the pathing thread can be reworked.
function AncientExpansionCheck takes nothing returns nothing
local unit u = null
local integer i = 0
call DisplayToAllJobDebug("ANCIENT_EXPANSION_CHECK JOB START")
if not ancient_expanding then
if current_expansion != null and take_exp and not CheckExpansionTaken(current_expansion) then
set u = GetExpFoe(u)
call Trace("expansion free")
if u != null then
call Trace("Ancient expansion - Begin Job")
if ancient_exp_loc == null then
set ancient_exp_loc = GetBuildLocationInDistanceFromLoc_d(old_id[racial_expansion], GetUnitLoc(current_expansion), ver_creeps_attack_buildings_dist + 500, true)
endif
set ancient_expanding = true
call TQAddJob(1, ANCIENT_EXPANSION, 0)
set u = null
elseif i < race_ancient_expansion_hero_rush_level then
call Trace("Ancient Expansion not possible with hero")
set u = null
endif
set u = null
else
call Trace("Ancient expansion - No expansion available")
endif
endif
local unit u = null
call TraceAll("ANCIENT_EXPANSION_CHECK JOB START")
if not ancient_expanding then
if current_expansion != null and take_exp and not CheckExpansionTaken(current_expansion) then
set u = GetExpFoe(u)
if u != null then
call TraceAll("Ancient expansion - Begin Job")
if ancient_exp_loc == null then
set ancient_exp_loc = GetBuildLocationInDistanceFromLoc_d(old_id[racial_expansion], GetUnitLoc(u), ver_creeps_attack_buildings_dist, true)
endif
set ancient_exp_mine = current_expansion
set ancient_exp_creep = u
set ancient_expanding = true
call TQAddJob(1, ANCIENT_EXPANSION, 0)
set u = null
endif
set u = null
else
call Trace("Ancient expansion - No expansion available")
endif
endif
endfunction

#ENDIF
98 changes: 49 additions & 49 deletions Jobs/RESET_ANCIENT.eai
Original file line number Diff line number Diff line change
@@ -1,66 +1,66 @@
#IFDEF GLOBAL
real lastancientx = -1
real lastancienty = -1
real lastbuildx = 0
real lastbuildy = 0
integer retry = 0
real lastancientx = -1
real lastancienty = -1
real lastbuildx = 0
real lastbuildy = 0
integer retry = 0

#ELSE

//Only 1 ancient reset can run at a time
function ResetAncient takes unit u returns nothing
local unit buildu = null
local real buildx = 0
local real buildy = 0
local integer i = 0
local unit buildu = null
local real buildx = 0
local real buildy = 0
local integer i = 0

if not UnitAlive(u) then
return
endif

if UnitAlive(u) and GetUnitCurrentOrder(u) != OrderId("root") and retry < 2 then
set i = Max(GetRandomInt(0, front_loc_num - 1),0)
if front_locs_computed and front_loc[i] != null then
set buildu = CreatePathingUnitFull(buildu, ai_player, GetUnitTypeId(u), GetLocationX(front_loc[i]) + ISign() * GetRandomReal(0, 300), GetLocationY(front_loc[i]) + ISign() * GetRandomReal(0, 300))
else
set buildu = CreatePathingUnitFull(buildu, ai_player, GetUnitTypeId(u), GetLocationX(home_location) + ISign() * GetRandomReal(500, 750), GetLocationY(home_location) + ISign() * GetRandomReal(500, 750))
if not UnitAlive(u) then
return
endif
set lastbuildx = GetUnitX(buildu)
set lastbuildy = GetUnitY(buildu)
call RemoveUnit(buildu)
set buildu = null
call IssuePointOrder( u, "root", lastbuildx, lastbuildy)
set retry = retry + 1
elseif GetUnitCurrentOrder(u) != OrderId("root") and retry >= 2 and (GetUnitX(u) != lastancientx or GetUnitY(u) != lastancienty) then
// if moving then not rooted
set retry = 1
elseif GetUnitCurrentOrder(u) != OrderId("root") and retry >= 2 and (GetUnitX(u) == lastancientx and GetUnitY(u) == lastancienty) then
// Root done as not moved
call RecycleGuardPosition(u)
elseif retry > 0 and GetUnitX(u) != lastancientx or GetUnitY(u) != lastancienty then
// moving so all good
set retry = 1
if DistanceBetweenPoints_dd(Location(lastbuildx, lastbuildy), GetUnitLoc(u)) > 400 then
// Rather than get to location and we can't build there re-evaluate and make sure no one built there early.
set buildu = CreatePathingUnitFull(buildu, ai_player, GetUnitTypeId(u), lastbuildx, lastbuildy)
set buildx = GetUnitX(buildu)
set buildy = GetUnitY(buildu)
if lastbuildx != buildx or lastbuildy != buildy then
set lastbuildx = GetUnitX(buildu)
set lastbuildy = GetUnitY(buildu)
call RemoveUnit(buildu)
set buildu = null
call IssuePointOrder( u, "root", lastbuildx, lastbuildy)

if UnitAlive(u) and GetUnitCurrentOrder(u) != OrderId("root") and retry < 2 then
set i = Max(GetRandomInt(0, front_loc_num - 1),0)
if front_locs_computed and front_loc[i] != null then
set buildu = CreatePathingUnitFull(buildu, ai_player, GetUnitTypeId(u), GetLocationX(front_loc[i]) + ISign() * GetRandomReal(0, 300), GetLocationY(front_loc[i]) + ISign() * GetRandomReal(0, 300))
else
set buildu = CreatePathingUnitFull(buildu, ai_player, GetUnitTypeId(u), GetLocationX(home_location) + ISign() * GetRandomReal(500, 750), GetLocationY(home_location) + ISign() * GetRandomReal(500, 750))
endif
set lastbuildx = GetUnitX(buildu)
set lastbuildy = GetUnitY(buildu)
call RemoveUnit(buildu)
set buildu = null
call IssuePointOrder( u, "root", lastbuildx, lastbuildy)
set retry = retry + 1
elseif GetUnitCurrentOrder(u) != OrderId("root") and retry >= 2 and (GetUnitX(u) != lastancientx or GetUnitY(u) != lastancienty) then
// if moving then not rooted
set retry = 1
elseif GetUnitCurrentOrder(u) != OrderId("root") and retry >= 2 and (GetUnitX(u) == lastancientx and GetUnitY(u) == lastancienty) then
// Root done as not moved
call RecycleGuardPosition(u)
elseif retry > 0 and GetUnitX(u) != lastancientx or GetUnitY(u) != lastancienty then
// moving so all good
set retry = 1
if DistanceBetweenPoints_dd(Location(lastbuildx, lastbuildy), GetUnitLoc(u)) > 400 then
// Rather than get to location and we can't build there re-evaluate and make sure no one built there early.
set buildu = CreatePathingUnitFull(buildu, ai_player, GetUnitTypeId(u), lastbuildx, lastbuildy)
set buildx = GetUnitX(buildu)
set buildy = GetUnitY(buildu)
if lastbuildx != buildx or lastbuildy != buildy then
set lastbuildx = GetUnitX(buildu)
set lastbuildy = GetUnitY(buildu)
call RemoveUnit(buildu)
set buildu = null
call IssuePointOrder( u, "root", lastbuildx, lastbuildy)
endif
call RemoveUnit(buildu)
set buildu = null
endif
endif
endif

set lastancientx = GetUnitX(u)
set lastancienty = GetUnitY(u)
set lastancientx = GetUnitX(u)
set lastancienty = GetUnitY(u)

call TQAddUnitJob(10, RESET_ANCIENT, 0, u)
call TQAddUnitJob(10, RESET_ANCIENT, 0, u)

endfunction

Expand Down
9 changes: 9 additions & 0 deletions Jobs/RETREAT_CONTROL.eai
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,15 @@ if attack_running then
endloop
call DestroyGroup(g)
set g = null

// Ancient tree army bonuses
if ancient_expanding and ancient_attack_running then
set ally_sum = ally_sum + 7
endif

if br_rush_attacked then
set ally_sum = ally_sum + 5
endif

set xe = xe / I2R(Max(enemy_count, 1))
set ye = ye / I2R(Max(enemy_count, 1))
Expand Down
4 changes: 2 additions & 2 deletions REFORGED/Elf/Settings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ race_militiaworker_unitstring "" what is the string of the unit that can be turn
use_militia_only_on_bigger_threats false shall the computer only use militias against larger threats ?
race_ancient_expansion_available true can the race expand with an uprooted building that also helps fighting the creeps ?
race_ancient_expansion_probability 43 how high (in percent) is the probability of doing an ancient expansion when possible ?
race_ancient_expansion_strength 18 up to how much expansion strength is an ancient expansion allowed ?
race_ancient_expansion_strength 18 up to how much expansion strength is an ancient expansion allowed (DEPRECATED) ?
race_ancient_expansion_help_id 'earc' the unit id of the unit that should help in ancient expansion
race_item_expansion_available false can expand with item building ?
race_item_expansion_probability 35 how high (in percent) is the probability of doing a item expansion ?
Expand All @@ -72,7 +72,7 @@ race_farms_at_mine 0 the first that many farms will be built at the mine
race_max_expa_mine_distance 850 the maximum distance between the mine and the expansion building
race_has_moonwells true Racial farms have healing properties
race_towerrush_hero_rush_level 1 the bonus strength value hero must have to be able to do the tower rush
race_ancient_expansion_hero_rush_level 2 the bonus strength value hero must have to be able to do the ancient expansion
race_ancient_expansion_hero_rush_level 1 the bonus strength value hero must have to be able to do the ancient expansion
ghoul_prio 250 priority for ghoul building
race_min_ghouls 2 smallest number of ghouls to build at all times
race_max_ghouls 5 maximum number of ghouls to build in low lumber situations
Expand Down
2 changes: 1 addition & 1 deletion REFORGED/GlobalSettings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ expansion_taken_radius 1300 how near a mine a enemy building must be to make ama
ver_hero_base_value 4 what is the base strength of a hero (the level number is added to get the actual strength) ?
ver_hero_ultimate_level 6 at what level do the heroes get their ultimates ?
ver_hero_ultimate_value 6 how much extra strength does the ultimate give to the hero ?
ver_creeps_attack_buildings_dist 1600 how far away do creeps attack buildings ?
ver_creeps_attack_buildings_dist 1850 how far away do creeps attack buildings ?
ver_mercs_night_buy false can mercs be bought at night without waking up creeps ?
ver_tower_check_radius 2000 check for towers in this radius around a target
ver_harass_tower_check_radius 2200 check for towers in this radius during harassing
Expand Down
Loading

0 comments on commit 8341b0a

Please sign in to comment.