Jump to content


Photo

Reverse Engineering Thread


  • Please log in to reply
49 replies to this topic

#21 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 22 June 2005 - 01:53 PM

No need - it is already set to 'true' in the file cpumanager.ai. What difference did you think it would make?

I have already done a second version of the code with some additional lines printing the output of prereq:PrerequisitesFulfilled(), prereq:CannotFulfillPrereqs(), prereq:GetNumUnfulfilledPrerequisites() and prereq:UnfulfilledOwnership().

prereq:UnfulfilledOwnership() is a boolean value which seems to track whether the squad has requirement for ownership of a relic, nothing more.

prereq:GetNumUnfulfilledPrerequisites() simply returns a numeric value.

prereq:PrerequisitesFulfilled() return TRUE if all prereqs are fulfilled.

Lastly, prereq:CannotFulfillPrereqs() returns FALSE for everything at gamestart (well, for everything Space Marine that is - I have not tried version 2 of my script with the other races yet). This means that my previous thoughts on the purpose of prereq:CannotFulfillPrereqs() are a pile of cack.

I will make a version 3 which runs during the game and not just at gamestart. I am very keen to see how prereq:CannotFulfillPrereqs() changes as the game progresses. If every squad starts off with prereq:CannotFulfillPrereqs() = FALSE, what could conceivably make it turn TRUE?

Flenser

Edited by Flenser, 22 June 2005 - 02:00 PM.


#22 Polaris

Polaris
  • Members
  • 49 posts

Posted 22 June 2005 - 02:22 PM

No need - it is already set to 'true' in the file cpumanager.ai. What difference did you think it would make?


I did not knew that... I was just trying to force the game to emit the highest amount of output in order to better track its inner workings (and in fact, I found the "debug = true" command inside the game code).

Also, it seems that I have landed into some AI-relevant code, that is responsible of loading the default AI code...

.text:0F20D996 sub_F20D996     proc near              ; CODE XREF: sub_F20DB6F+135p
.text:0F20D996                 mov     eax, offset unknown_libname_185; MFC 3.1/4.0/4.2/7.1 32bit
.text:0F20D99B                 call    __EH_prolog
.text:0F20D99B
.text:0F20D9A0                 sub     esp, 1Ch
.text:0F20D9A3                 push    ebx
.text:0F20D9A4                 push    esi
.text:0F20D9A5                 push    edi
.text:0F20D9A6                 push    4
.text:0F20D9A8                 mov     esi, ecx
.text:0F20D9AA                 call    operator new(uint)
.text:0F20D9AA
.text:0F20D9AF                 pop     ecx
.text:0F20D9B0                 mov     ecx, eax
.text:0F20D9B2                 mov     [ebp-10h], ecx
.text:0F20D9B5                 xor     ebx, ebx
.text:0F20D9B7                 cmp     ecx, ebx
.text:0F20D9B9                 mov     [ebp-4], ebx
.text:0F20D9BC                 jz      short loc_F20D9CB
.text:0F20D9BC
.text:0F20D9BE                 push    offset aAi     ; "AI"
.text:0F20D9C3                 call    ds:LuaConfig::LuaConfig(char const *)
.text:0F20D9C3
.text:0F20D9C9                 jmp     short loc_F20D9CD
.text:0F20D9C9
.text:0F20D9CB; ---------------------------------------------------------------------------
.text:0F20D9CB
.text:0F20D9CB loc_F20D9CB:                           ; CODE XREF: sub_F20D996+26j
.text:0F20D9CB                 xor     eax, eax
.text:0F20D9CD
.text:0F20D9CD loc_F20D9CD:                           ; CODE XREF: sub_F20D996+33j
.text:0F20D9CD                 mov     ecx, [esi+8]
.text:0F20D9D0                 push    8
.text:0F20D9D2                 mov     [ecx+1Ch], eax
.text:0F20D9D5                 mov     eax, [esi+8]
.text:0F20D9D8                 push    offset dword_F383538
.text:0F20D9DD                 push    dword ptr [eax+1Ch]
.text:0F20D9E0                 or      edi, 0FFFFFFFFh
.text:0F20D9E3                 mov     [ebp-4], edi
.text:0F20D9E6                 call    sub_F20B4B3
.text:0F20D9E6
.text:0F20D9EB                 push    offset aProfileai; "profileai"
.text:0F20D9F0                 call    ds:Plat::Options::Exist(char const *)
.text:0F20D9F0
.text:0F20D9F6                 test    al, al
.text:0F20D9F8                 jz      short loc_F20DA0C
.text:0F20D9F8
.text:0F20D9FA                 mov     eax, [esi+8]
.text:0F20D9FD                 mov     ecx, [eax+1Ch]
.text:0F20DA00                 push    ebx
.text:0F20DA01                 push    offset aG_profileTrue; "g_profile = true"
.text:0F20DA06                 call    ds:LuaConfig::RunString(char const *,bool)
.text:0F20DA06
.text:0F20DA0C
.text:0F20DA0C loc_F20DA0C:                           ; CODE XREF: sub_F20D996+62j
.text:0F20DA0C                 push    esi
.text:0F20DA0D                 call    sub_F20E28C
.text:0F20DA0D
.text:0F20DA12                 mov     eax, [esi+8]
.text:0F20DA15                 xor     edx, edx
.text:0F20DA17                 push    edx
.text:0F20DA18                 mov     ecx, offset loc_F20B7B8
.text:0F20DA1D                 push    ecx
.text:0F20DA1E                 push    esi
.text:0F20DA1F                 push    offset aAi_getplayerid; "AI_GetPlayerID"
.text:0F20DA24                 push    dword ptr [eax+1Ch]
.text:0F20DA27                 lea     eax, [ebp-10h]
.text:0F20DA2A                 push    eax
.text:0F20DA2B                 call    near ptr byte_F20D84E
.text:0F20DA2B
.text:0F20DA30                 mov     ecx, [esi+8]
.text:0F20DA33                 push    eax
.text:0F20DA34                 add     ecx, 4Ch
.text:0F20DA37                 mov     dword ptr [ebp-4], 1
.text:0F20DA3E                 call    sub_F20D534
.text:0F20DA3E
.text:0F20DA43                 lea     ecx, [ebp-10h]
.text:0F20DA46                 mov     [ebp-4], edi
.text:0F20DA49                 call    ds:LuaBinding::Obj::~Obj(void)
.text:0F20DA49
.text:0F20DA4F                 mov     eax, [esi+8]
.text:0F20DA52                 push    dword ptr [eax+1Ch]
.text:0F20DA55                 lea     ecx, [eax+20h]
.text:0F20DA58                 call    ds:LuaRuleSystem::Init(LuaConfig *)
.text:0F20DA58
.text:0F20DA5E                 push    offset sub_F20B512
.text:0F20DA63                 lea     ecx, [ebp-1Ch]
.text:0F20DA66                 mov     [ebp-1Ch], ebx
.text:0F20DA69                 mov     [ebp-18h], ebx
.text:0F20DA6C                 mov     [ebp-14h], ebx
.text:0F20DA6F                 call    sub_F2E90CC
.text:0F20DA6F
.text:0F20DA74                 mov     eax, [esi+8]
.text:0F20DA77                 lea     ecx, [ebp-1Ch]
.text:0F20DA7A                 push    ecx
.text:0F20DA7B                 mov     ecx, [eax+1Ch]
.text:0F20DA7E                 mov     dword ptr [ebp-4], 2
.text:0F20DA85                 call    ds:LuaConfig::SetOnImport(boost::function1<LuaConfig::Importer *,char const *,_STL::allocator<boost::function_base>> const &)
.text:0F20DA85
.text:0F20DA8B                 lea     ecx, [ebp-1Ch]
.text:0F20DA8E                 mov     [ebp-4], edi
.text:0F20DA91                 call    sub_F28865E
.text:0F20DA91
.text:0F20DA96                 push    offset loc_F20B4D8
.text:0F20DA9B                 lea     ecx, [ebp-1Ch]
.text:0F20DA9E                 mov     [ebp-1Ch], ebx
.text:0F20DAA1                 mov     [ebp-18h], ebx
.text:0F20DAA4                 mov     [ebp-14h], ebx
.text:0F20DAA7                 call    sub_F2F37C9
.text:0F20DAA7
.text:0F20DAAC                 mov     eax, [esi+8]
.text:0F20DAAF                 lea     ecx, [ebp-1Ch]
.text:0F20DAB2                 push    ecx
.text:0F20DAB3                 mov     ecx, [eax+1Ch]
.text:0F20DAB6                 mov     dword ptr [ebp-4], 3
.text:0F20DABD                 call    ds:LuaConfig::SetOnPrint(boost::function1<void,char const *,_STL::allocator<boost::function_base>> const &)
.text:0F20DABD
.text:0F20DAC3                 lea     ecx, [ebp-1Ch]
.text:0F20DAC6                 mov     [ebp-4], edi
.text:0F20DAC9                 call    sub_F28865E
.text:0F20DAC9
.text:0F20DACE                 push    offset loc_F20B4F2
.text:0F20DAD3                 lea     ecx, [ebp-28h]
.text:0F20DAD6                 mov     [ebp-28h], ebx
.text:0F20DAD9                 mov     [ebp-24h], ebx
.text:0F20DADC                 mov     [ebp-20h], ebx
.text:0F20DADF                 call    sub_F2F37C9
.text:0F20DADF
.text:0F20DAE4                 mov     eax, [esi+8]
.text:0F20DAE7                 lea     ecx, [ebp-28h]
.text:0F20DAEA                 push    ecx
.text:0F20DAEB                 mov     ecx, [eax+1Ch]
.text:0F20DAEE                 mov     dword ptr [ebp-4], 4
.text:0F20DAF5                 call    ds:LuaConfig::SetOnAlert(boost::function1<void,char const *,_STL::allocator<boost::function_base>> const &)
.text:0F20DAF5
.text:0F20DAFB                 lea     ecx, [ebp-28h]
.text:0F20DAFE                 mov     [ebp-4], edi
.text:0F20DB01                 call    sub_F28865E
.text:0F20DB01
.text:0F20DB06                 mov     ecx, esi
.text:0F20DB08                 call    sub_F20B8D9
.text:0F20DB08
.text:0F20DB0D                 test    al, al
.text:0F20DB0F                 jz      short loc_F20DB4B
.text:0F20DB0F
.text:0F20DB11                 mov     edi, [ebp+8]
.text:0F20DB14                 push    edi
.text:0F20DB15                 call    ds:FilePath::GetFileType(char const *)
.text:0F20DB15
.text:0F20DB1B                 test    eax, eax
.text:0F20DB1D                 push    edi
.text:0F20DB1E                 jnz     short loc_F20DB27
.text:0F20DB1E
.text:0F20DB20                 push    offset aAiScriptFileDo; "AI Script File Does Not Exist (%s)"
.text:0F20DB25                 jmp     short loc_F20DB3D
.text:0F20DB25
.text:0F20DB27; ---------------------------------------------------------------------------
.text:0F20DB27
.text:0F20DB27 loc_F20DB27:                           ; CODE XREF: sub_F20D996+188j
.text:0F20DB27                 mov     eax, [esi+8]
.text:0F20DB2A                 push    dword ptr [eax+1Ch]
.text:0F20DB2D                 call    ds:LuaConfigSave::LoadLua(LuaConfig &,char const *)
.text:0F20DB2D
.text:0F20DB33                 test    al, al
.text:0F20DB35                 push    edi
.text:0F20DB36                 jnz     short loc_F20DB53
.text:0F20DB36
.text:0F20DB38                 push    offset aErrorLoadingSc; "Error loading script file (%s).  Check "...
.text:0F20DB3D
.text:0F20DB3D loc_F20DB3D:                           ; CODE XREF: sub_F20D996+18Fj
.text:0F20DB3D                 push    4149h
.text:0F20DB42                 call    ds:dbWarningfAux(ulong,char const *,...)
.text:0F20DB42
.text:0F20DB48                 add     esp, 0Ch
.text:0F20DB4B
.text:0F20DB4B loc_F20DB4B:                           ; CODE XREF: sub_F20D996+179j
.text:0F20DB4B                 mov     eax, [esi+8]
.text:0F20DB4E                 mov     [eax+3Ch], bl
.text:0F20DB51                 jmp     short loc_F20DB5E
.text:0F20DB51
.text:0F20DB53; ---------------------------------------------------------------------------
.text:0F20DB53
.text:0F20DB53 loc_F20DB53:                           ; CODE XREF: sub_F20D996+1A0j
.text:0F20DB53                 mov     ecx, [esi+8]
.text:0F20DB56                 add     ecx, 0Ch
.text:0F20DB59                 call    sub_F20425A
.text:0F20DB59
.text:0F20DB5E
.text:0F20DB5E loc_F20DB5E:                           ; CODE XREF: sub_F20D996+1BBj
.text:0F20DB5E                 mov     ecx, [ebp-0Ch]
.text:0F20DB61                 pop     edi
.text:0F20DB62                 pop     esi
.text:0F20DB63                 pop     ebx
.text:0F20DB64                 mov     large fs:0, ecx
.text:0F20DB6B                 leave
.text:0F20DB6C                 retn    4
.text:0F20DB6C
.text:0F20DB6C sub_F20D996     endp; sp =  4

I suppose that here inside we will find something interesting to solve the problem... ;)
Stay tuned...

#23 Polaris

Polaris
  • Members
  • 49 posts

Posted 22 June 2005 - 02:53 PM

Finally, I succeeded... I succesfully located the code responsible for AI registering and command binding. There is a huge set of commands, I'll post later a human-comprehensible update with the list of them ;)

#24 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 22 June 2005 - 03:19 PM

Finally, I succeeded... I succesfully located the code responsible for AI registering and command binding. There is a huge set of commands, I'll post later a human-comprehensible update with the list of them ;)

<{POST_SNAPBACK}>

Excellent - this could be very illuminating ;)

Flenser

#25 Polaris

Polaris
  • Members
  • 49 posts

Posted 22 June 2005 - 04:35 PM

Ok, here is the list of the AI-Objects and relative methods.

Before listing them, let me briefly explain HOW the whole systems behaves.

At startup, a specific LUA script file dedicated to AI is loaded.
If such file is correct with regard of LUA specifics, the AI behaviour is registered into the game.
In this registering process, the AI objects used by the script are created and initialized. It is in this moment that the CpuPrerequisites object is created and various methods (for example CannotFulfillPrereqs) are bound to it.

Here follows the list of objects with methods for DOW AI.... Feedback wanted! ;)

CpuTerrainAnalyzer
   FindClosestFreePosition
   GetMarkerPositionByID
   GetMarkerProximityByID
   GetChokepointMarkerIDs
   GetClosestChokepointID
   GetThreatAtPos
   GetSafePointBeforeDest
   HasThreatOnPath
   GetPathingDistance
   GetMajorityClassType
   Update
   HasThreat

AIStats
   Update
   LoadUnitStats
   GetUnitStatsFromBPID
   GetUnitStats
   GetPlayerStats
   GetPlayerStatsFromID
   GetSquadName
   GetSquadID
   GetBuildingName
   GetBuildingID
   GetResearchName
   GetResearchID
   GetAbilityID
   GetAddOnName
   GetAddOnID

CpuPlayer
   FindFirstCommanderEnemy
   FindFirstInfantryEnemy
   FindFirstVehicleEnemy
   FindFirstEnemy
   FindFirstSquadInCombat
   FindFirstHurtSquad
   GetDifficultyLevel
   GetStartingPosition
   DoUpdate
   NetSay
   GetTerrainAnalyzer
   IsResearchComplete
   GetGameTime
   GetStats
   GetResourceManager
   GetMilitaryManager
   GetBuildManager
   GetPlayerTeam
   Enable


BuildManager
   Update
   CanBuildSquad
   SetSquadLimit
   GetSquadLimit
   ClearSquadLimits
   GetSupportCapLeft
   GetSquadCapLeft
   GetSquadCapCurrentMax
   GetSupportCapCurrentMax
   GetSquadCapTotalMax
   GetSupportCapTotalMax
   GetNumBuildableBuildings
   GetBuildableBuildingAt
   GetNumSquadsWithBPID
   IsGarrisonBuilding
   IsPowerGenerator
   FindUnfinishedBuilding
   FindAnyUnfinishedBuildings
   CancelBuilding
   GetBuildChannelAIs
   GetUnlockedBuildChannelAIs

MilitaryManager
   Update
   GetSquads
   GetNumEngineers
   GetUnlockedSquads

ResourceManager
   Update
   UpdateFreeSlagHeaps
   GetResourceAmount
   GetResourceRate
   GetTotalNumStrategicPoints
   GetTotalNumStrategicObjectives
   GetNumOwnedStrategicPoints
   GetNumOwnedStrategicObjectives
   GetNumOwnedPowerGenerators
   SearchForFlagToDisown
   GetSlagHeaps
   GetStrategicPointAIs
   GetUnlockedStrategicPointAIs

CpuPrerequisites
   GetUnfulfilledPrerequisites
   PrerequisitesFulfilled
   GetNumUnfulfilledPrerequisites
   UnfulfilledOwnership
   CannotFulfillPrereqs

CpuBuildType
   // Attributes only


PlayerStatsAI
   IsPlayerDead
   GetPlayerID
   GetPlayerTeam
   GetPlayerRaceName
   GetPlayerRace
   GetEffectivenessRating
   GetClassRating
   GetMajorityClassType
   GetStartingPosition
   GetNumSquads
   GetArmyCost
   IsEnemy
   GetArmyCostAt
   GetBuildingsWithGuns
   GetBases
   GetSquads

BuildChannelAI
   GetBlueprintID
   GetEntity
   GetNumberOfItems
   BuildSquad
   IsBuilding
   GetItemNameAt
   GetItemIDAt
   GetItemIndexFromID
   GetItemCostAt
   GetItemRequiredTicksAt
   CanAddToQueue
   ConstructionDone
   BuildResearch
   BuildAddOn
   SetRallyPoint
   CanDeepStrike
   CanOnlyDeepStrikeToEntity
   DoDeepStrikeToPos
   DoDeepStrikeToSquad

UnitStatsAI
   GetID
   GetSquadName
   GetSquadCapReq
   GetSupportCapReq
   GetSupportCapReq
   GetClassRating
   GetBaseEffectiveness
   GetAverageEffectiveness
   GetCost
   GetTicksToBuild
   IsEngineer

ResourceAmount
   Set
   Get

BaseAI
   HasAddOn
   GetThreatRating
   GetPosition
   IsStrategicObjective

SquadAI
   IsValid
   GetTactic
   GetSquad
   GetStateName
   GetNumTroopers
   GetProRatedCost
   GetStance
   GetMeleeStance
   CanSummon
   CanCapture
   DoCapture
   DoPossess
   DoDefault
   DoFinishBuilding
   DoRepair
   DoReinforce
   DoMove
   DoStop
   DoAttackMove
   DoSpecialAbility
   DoSpecialAbilityPos
   DoSpecialAbilitySquad
   DoMoveToClosestCover
   DoBestUpgrade
   DoMoveToClosestSafePoint
   DoDetachSquad
   DoAttachSquad
   DoSetStance
   DoSetMeleeStance
   DoSetDefaultMeleeStance
   DoJump
   CanReceiveAttachment
   HasSquadAttached
   IsAttached
   GetAttachedHealthPercentage
   CanAttachTo
   CanJumpToPosition
   CanJump
   CanDoAbility
   CanPossess
   CanBuild
   CanBuildAt
   CanReinforce
   GetJumpDistance
   GetPosition
   GetAbilityRange
   GetMoralePercentage
   GetHealthPercentage
   GetTargetPos
   HasLeader
   HasUpgradableTrooper
   HasSetupTime
   WasAttackedSince
   IsInCombat
   WasRecentlyHurt
   IsEngineer
   IsBroken
   IsRanged
   IsCapturing
   DoBuildBuilding
   GetBuildingEntityID
   BaseAI__IsBuilding
   IsBuildProgressing
   IsIdle
   IsUsingAbility
   IsInStateMove
   IsInStateAttackMove
   IsReinforcing
   GetStats

StrategicPointAI
   GetEntity
   IsStrategicObjective
   HasListeningPost
   HasWeapons
   FinishedCapturing
   IsBeingCaptured
   ShouldDisown
   IsTagged
   TagFlagForEngineer
   Owner
   GetCaptureProgress

SigmaPlayer
   GetRace

Entity
   GetPosition
   GetSquad(void)


Squad
   GetPosition(void)
   GetAllEntities(void)
   GetTightPackedSize(void)

AIResource
   GetID
   IsValid
   GetType
   IsLocked
   DesignerLock
   Lock
   Unlock

Edited by Polaris, 22 June 2005 - 04:37 PM.


#26 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,166 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 22 June 2005 - 06:29 PM

Hmm that list above is nothing new as its mostly contained here:

http://www.relic.com/rdn/rdn_login.php

You need to be a member to access it so register up and the AI list of functions is there.

Still.. glad to hear there is movement.
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#27 Polaris

Polaris
  • Members
  • 49 posts

Posted 22 June 2005 - 06:35 PM

Hmm that list above is nothing new as its mostly contained here:

http://www.relic.com/rdn/rdn_login.php

You need to be a member to access it so register up and the AI list of functions is there.

Still.. glad to hear there is movement.

<{POST_SNAPBACK}>


This is nothing new, BUT that comes from the W40KBinary... I know location for the code of **every** method inside the above list... Allowing me to make fast check and comparisons. ;)

#28 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 22 June 2005 - 07:26 PM

I know location for the code of **every** method inside the above list... Allowing me to make fast check and comparisons

So that means you can now begin comparing the code for the CpuPrequisite methods between v1.2 and v1.3??? ;)

Flenser

#29 Polaris

Polaris
  • Members
  • 49 posts

Posted 22 June 2005 - 07:47 PM

Comparison is done... The two functions are unchanged! :(
This is reasonable, however: in fact this function scans the content of an object and returns true or false... No real AI inside it.

From version 1.3:

.text:0F20EA6D CannotFulfillPrereqs proc near        ; DATA XREF: BindAICommands+A04o
.text:0F20EA6D                 mov     eax, [ecx]
.text:0F20EA6F                 mov     ecx, [ecx+4]
.text:0F20EA72                 cmp     eax, ecx
.text:0F20EA74                 jz      short loc_F20EA86
.text:0F20EA74
.text:0F20EA76
.text:0F20EA76 loc_F20EA76:                          ; CODE XREF: CannotFulfillPrereqs+14j
.text:0F20EA76                 cmp     byte ptr [eax+10h], 0
.text:0F20EA7A                 jnz     short loc_F20EA86
.text:0F20EA7A
.text:0F20EA7C                 add     eax, 14h
.text:0F20EA7F                 cmp     eax, ecx
.text:0F20EA81                 jnz     short loc_F20EA76
.text:0F20EA81
.text:0F20EA83                 mov     al, 1
.text:0F20EA85                 retn
.text:0F20EA85
.text:0F20EA86; ---------------------------------------------------------------------------
.text:0F20EA86
.text:0F20EA86 loc_F20EA86:                          ; CODE XREF: CannotFulfillPrereqs+7j
.text:0F20EA86                                       ; CannotFulfillPrereqs+Dj
.text:0F20EA86                 xor     al, al
.text:0F20EA88                 retn
.text:0F20EA88
.text:0F20EA88 CannotFulfillPrereqs endp

and from 1.2:

.text:0F20ED63 sub_F20ED63     proc near             ; DATA XREF: sub_F22A86F+9FEo
.text:0F20ED63                 mov     eax, [ecx]
.text:0F20ED65                 mov     ecx, [ecx+4]
.text:0F20ED68                 cmp     eax, ecx
.text:0F20ED6A                 jz      short loc_F20ED7C
.text:0F20ED6A
.text:0F20ED6C
.text:0F20ED6C loc_F20ED6C:                          ; CODE XREF: sub_F20ED63+14j
.text:0F20ED6C                 cmp     byte ptr [eax+10h], 0
.text:0F20ED70                 jnz     short loc_F20ED7C
.text:0F20ED70
.text:0F20ED72                 add     eax, 14h
.text:0F20ED75                 cmp     eax, ecx
.text:0F20ED77                 jnz     short loc_F20ED6C
.text:0F20ED77
.text:0F20ED79                 mov     al, 1
.text:0F20ED7B                 retn
.text:0F20ED7B
.text:0F20ED7C; ---------------------------------------------------------------------------
.text:0F20ED7C
.text:0F20ED7C loc_F20ED7C:                          ; CODE XREF: sub_F20ED63+7j
.text:0F20ED7C                                       ; sub_F20ED63+Dj
.text:0F20ED7C                 xor     al, al
.text:0F20ED7E                 retn
.text:0F20ED7E
.text:0F20ED7E sub_F20ED63     endp

Now, I can easily scan and compare each of the above listed AI functions... So, it's up to you to tell me where to head now... ;)

Want me to proceed investigating the CpuPrerequisites object?

Edited by Polaris, 22 June 2005 - 07:49 PM.


#30 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 23 June 2005 - 08:56 AM

They do not look the same to me, but then I do not know what I am looking at :) Eg. v1.3 has "CannotFulfillPrereqs" but v1.2 has "sub F20ED63". Are they the same thing?

Please check the CpuPrerequisites object.

Flenser

#31 Polaris

Polaris
  • Members
  • 49 posts

Posted 23 June 2005 - 10:32 AM

They do not look the same to me, but then I do not know what I am looking at :) Eg. v1.3 has "CannotFulfillPrereqs" but v1.2 has "sub F20ED63". Are they the same thing?

Please check the CpuPrerequisites object.

Flenser

<{POST_SNAPBACK}>


LOL :p

They are the same... You see the name difference because the 1.3 version comes from my fully enhanced disassembly (with names added, comments, local variables and more) while the 1.2 version was just cutted-and-pasted without hand modifications.

Also, the addresses are different because the binaries are different

Trust me, the code is the same... ;)

Also, the WHOLE CPUPREREQUISITE object is unchanged... As you can clearly see from the code snippets posted below, the CPUPREREQUISITE is comprised only of methods that retrieve values/iterators that are stored in the object.

The real prerequisite operations are done elsewhere...

GetUnfulfilledPrerequisites

1.3:

.text:0F20605B GetUnfulfilledPrerequisites proc near 
.text:0F20605B                 mov     eax, ecx
.text:0F20605D                 retn
.text:0F20605D
.text:0F20605D GetUnfulfilledPrerequisites endp

1.2:

.text:0F2E53C4 sub_F2E53C4     proc near  
.text:0F2E53C4                 mov     eax, ecx
.text:0F2E53C6                 retn
.text:0F2E53C6
.text:0F2E53C6 sub_F2E53C4     endp

PrerequisitesFulfilled

1.3:

.text:0F20EA89 PrerequisitesFulfilled proc near 
.text:0F20EA89                 mov     eax, [ecx]
.text:0F20EA8B                 sub     eax, [ecx+4]
.text:0F20EA8E                 neg     eax
.text:0F20EA90                 sbb     eax, eax
.text:0F20EA92                 inc     eax
.text:0F20EA93                 retn
.text:0F20EA93
.text:0F20EA93 PrerequisitesFulfilled endp

1.2:

.text:0F20ED7F sub_F20ED7F     proc near             
.text:0F20ED7F                 mov     eax, [ecx]
.text:0F20ED81                 sub     eax, [ecx+4]
.text:0F20ED84                 neg     eax
.text:0F20ED86                 sbb     eax, eax
.text:0F20ED88                 inc     eax
.text:0F20ED89                 retn
.text:0F20ED89
.text:0F20ED89 sub_F20ED7F     endp

GetNumUnfulfilledPrerequisites

1.3:

.text:0F20EA94 GetNumUnfulfilledPrerequisites proc near 
.text:0F20EA94                 mov     eax, [ecx+4]
.text:0F20EA97                 sub     eax, [ecx]
.text:0F20EA99                 push    14h
.text:0F20EA9B                 cdq
.text:0F20EA9C                 pop     ecx
.text:0F20EA9D                 idiv    ecx
.text:0F20EA9F                 retn
.text:0F20EA9F
.text:0F20EA9F GetNumUnfulfilledPrerequisites endp

1.2:

.text:0F20ED8A sub_F20ED8A     proc near               
.text:0F20ED8A                 mov     eax, [ecx+4]
.text:0F20ED8D                 sub     eax, [ecx]
.text:0F20ED8F                 push    14h
.text:0F20ED91                 cdq
.text:0F20ED92                 pop     ecx
.text:0F20ED93                 idiv    ecx
.text:0F20ED95                 retn
.text:0F20ED95
.text:0F20ED95 sub_F20ED8A     endp

UnfulfilledOwnership

1.3:

.text:0F20E8F8 UnfulfilledOwnership proc near
.text:0F20E8F8                 mov     al, [ecx+10h]
.text:0F20E8FB                 retn
.text:0F20E8FB
.text:0F20E8FB UnfulfilledOwnership endp

1.2:

.text:0F20EC1B sub_F20EC1B     proc near  
.text:0F20EC1B                 mov     al, [ecx+10h]
.text:0F20EC1E                 retn
.text:0F20EC1E
.text:0F20EC1E sub_F20EC1B     endp

CannotFulfillPrereqs

1.3:

.text:0F20EA6D CannotFulfillPrereqs proc near  
.text:0F20EA6D                 mov     eax, [ecx]
.text:0F20EA6F                 mov     ecx, [ecx+4]
.text:0F20EA72                 cmp     eax, ecx
.text:0F20EA74                 jz      short loc_F20EA86
.text:0F20EA74
.text:0F20EA76
.text:0F20EA76 loc_F20EA76:                          ; CODE XREF: CannotFulfillPrereqs+14j
.text:0F20EA76                 cmp     byte ptr [eax+10h], 0
.text:0F20EA7A                 jnz     short loc_F20EA86
.text:0F20EA7A
.text:0F20EA7C                 add     eax, 14h
.text:0F20EA7F                 cmp     eax, ecx
.text:0F20EA81                 jnz     short loc_F20EA76
.text:0F20EA81
.text:0F20EA83                 mov     al, 1
.text:0F20EA85                 retn
.text:0F20EA85
.text:0F20EA86; ---------------------------------------------------------------------------
.text:0F20EA86
.text:0F20EA86 loc_F20EA86:                          ; CODE XREF: CannotFulfillPrereqs+7j
.text:0F20EA86                                       ; CannotFulfillPrereqs+Dj
.text:0F20EA86                 xor     al, al
.text:0F20EA88                 retn
.text:0F20EA88
.text:0F20EA88 CannotFulfillPrereqs endp

1.2:

.text:0F20ED63 sub_F20ED63     proc near  
.text:0F20ED63                 mov     eax, [ecx]
.text:0F20ED65                 mov     ecx, [ecx+4]
.text:0F20ED68                 cmp     eax, ecx
.text:0F20ED6A                 jz      short loc_F20ED7C
.text:0F20ED6A
.text:0F20ED6C
.text:0F20ED6C loc_F20ED6C:                          ; CODE XREF: sub_F20ED63+14j
.text:0F20ED6C                 cmp     byte ptr [eax+10h], 0
.text:0F20ED70                 jnz     short loc_F20ED7C
.text:0F20ED70
.text:0F20ED72                 add     eax, 14h
.text:0F20ED75                 cmp     eax, ecx
.text:0F20ED77                 jnz     short loc_F20ED6C
.text:0F20ED77
.text:0F20ED79                 mov     al, 1
.text:0F20ED7B                 retn
.text:0F20ED7B
.text:0F20ED7C; ---------------------------------------------------------------------------
.text:0F20ED7C
.text:0F20ED7C loc_F20ED7C:                          ; CODE XREF: sub_F20ED63+7j
.text:0F20ED7C                                       ; sub_F20ED63+Dj
.text:0F20ED7C                 xor     al, al
.text:0F20ED7E                 retn
.text:0F20ED7E
.text:0F20ED7E sub_F20ED63     endp

Edited by Polaris, 23 June 2005 - 10:33 AM.


#32 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 23 June 2005 - 10:57 AM

Trust me, the code is the same... :p

Never afraid to flaunt my ignorance in the hope of learning something new :)

Let us know what you find.

Cheers,

Flenser

#33 Polaris

Polaris
  • Members
  • 49 posts

Posted 23 June 2005 - 12:38 PM

Trust me, the code is the same... :p

Never afraid to flaunt my ignorance in the hope of learning something new :)

Let us know what you find.

Cheers,

Flenser

<{POST_SNAPBACK}>


Flenser, I was just joking... I really know that this is not standard stuff, and even experienced user/programmers may be unaware of what is going on under the hood....

But do not worry, we will manage to fix that... I have an increasingly clear view of the whole DLL, and intervention becomes every hour more feasible.

Now, since the prereq object is NOT what we are looking for, since it just retrieves informations, my idea is: let's look for something that actually WRITES prerequisites.

For example: maybe prerequisites are estabilished when we create an object?? For example, when we build the Daemon Pit, its prereq are initialized and then modified as soon as we add more stuff around... So that, as soon as the Desecrated Stronghold is upgraded to tier 2, the Daemon Pit prereqs get updated and the user can build the Sorceror.

Am I right?

#34 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 23 June 2005 - 01:08 PM

That is something I am trying to establish at the moment (I wonder if our two little projects will wind up meeting somewhere in the middle!?!) with some scripts that monitor the output of GetUnfulfilledPrerequisites() in the LUA files as the game progresses.

Here is the code I am testing:-

function Strategy:Prereq()

	local race = cpu_manager.cpu_player:GetPlayerRace()

 local get_prereq

	local get_prereq = function( prereq )

  local unfulfilled == prereq:GetUnfulfilledPrerequisites() 

  if unfulfilled == nil then

   --this never seems to get executed, so unfulfilled is never == nil
  	aipushtrace("")
  	aitrace("This has no unfulfilled prerequisites")
  	aitrace(" ")
  	aipoptrace("")
  	return

  end
  
  for i in unfulfilled do

  	aipushtrace("")
  	aitrace("Type of data: "..type (i) )
  	aitrace("Name: "..i.name )
  	aitrace("Build Type: "..i.btype )
  	aitrace("Prereq Fulfilled?: "..tostring( i.prereq_fulfilled ) )

  	if i.btype == 1 then

    aitrace("This prerequisite is a squad")
    local prereq_1 = CpuPrerequisites( cpu_manager.cpu_player, i.name, CpuPrerequisites.BT_Squad )
    get_prereq( prereq_1 )
    aitrace(" ")

  	elseif i.btype == 2 then

    aitrace("This prerequisite is a building")
    local prereq_2 = CpuPrerequisites( cpu_manager.cpu_player, i.name, CpuPrerequisites.BT_Building )
    get_prereq( prereq_2 )
    aitrace(" ")

  	elseifi.btype == 3 then

    aitrace("This prerequisite is research")
    local prereq_3 = CpuPrerequisites( cpu_manager.cpu_player, i.name, CpuPrerequisites.BT_Research )
    get_prereq( prereq_3 )
    aitrace(" ")

  	elseifi.btype == 4 then

    aitrace("This prerequisite is an addon")
    local prereq_4 = CpuPrerequisites( cpu_manager.cpu_player, i.name, CpuPrerequisites.BT_Addon )
    get_prereq( prereq_4 )
    aitrace(" ")

  	end

  	aipoptrace("")
  
  end

  return

	end
  
	for unit_stats in cpu_manager.stats:GetUnitStats(race) do

  local prereq = CpuPrerequisites( cpu_manager.cpu_player, unit_stats:GetSquadName(), CpuPrerequisites.BT_Squad )
  aitrace("Unfulfilled Prerequisites for "..unit_stats:GetSquadName() )
  aitrace("Are all prerequisites fulfilled?: "..tostring( prereq:PrerequisitesFulfilled() ) )
  aitrace("Number of unfulfilled prerequisites: "..prereq:GetNumUnfulfilledPrerequisites() )      	aitrace("Is the prerequisite unfulfillable?: "..tostring( prereq:CannotFulfillPrereqs() ) )
  aitrace("Is ownership unfulfilled?: "..tostring( prereq:UnfulfilledOwnership() ) )
  aitrace(" ")

  get_prereq( prereq )

  aitrace(" ")
  
	end

end
I will call this about once every 10 secs and see where that gets us.

Hopefully this code will not just reveal the prereqs, but the prereqs for the prereqs, and the prereqs for the prereqs for the prereqs etc etc.

The CpuPrerequisites object is clearly populated from the LUA files. The squad files only have some prereq information, and I think the code assembles the prereq information from squad, building, addon and research LUA files. We will see.

I will post here once I have tested (and then fixed and tested again, natch) the above code and considered the output.

(I knew you were joking, as was I :) )

EDIT: Bloody LUA recursion - need to define the local variable before I define the local function.

Flenser

Edited by Flenser, 24 June 2005 - 02:59 PM.


#35 Polaris

Polaris
  • Members
  • 49 posts

Posted 23 June 2005 - 03:01 PM

Ok, I will continue deepening my knowledge of the whole DOW LUA implementation, unless someone (Thudo, Larkin, Corsix ?) comes up with some suggestion...

Pleeez, keep me aware of the result of your experiments! :)

#36 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,166 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 23 June 2005 - 05:26 PM

One thing of note that may/may not be anything but under v1.30, when you increase the AI skill level to INSANE or toggle resource gathering to HIGH (rather than Standard/Normal) the AI will much more reliably build all units its supposed to (similiar to v1.20 HARDER w/Standard Resources). So does giving the AI a faster economy suggest something broken in v1.30? Hmmmmm...

Edited by thudo, 23 June 2005 - 05:27 PM.

Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#37 Polaris

Polaris
  • Members
  • 49 posts

Posted 23 June 2005 - 06:28 PM

I'll add the AI skill level to the research plan :)

#38 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,166 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 25 June 2005 - 06:03 PM

Thanks Polaris.. keep us abreast of the situation. :p
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#39 Polaris

Polaris
  • Members
  • 49 posts

Posted 28 June 2005 - 02:44 PM

I have finally decided to compare every function listed in the DOW RDN AI Wiki for 1.2 and 1.3 in order to find the responsibles of the bad AI behaviour...

I have just started, and some difference have been detected.

CpuTerrainAnalyzer:
FindClosestFreePosition: NO MATCH
GetMarkerPositionByID: MATCH
GetMarkerProximityByID: MATCH
GetChokepointMarkerIDs: MATCH
GetClosestChokepointID: NO MATCH
GetThreatAtPos: MATCH
GetSafePointBeforeDest: MATCH
HasThreatOnPath: MATCH
GetPathingDistance: MATCH
GetMajorityClassType: NO MATCH

where MATCH and NO MATCH means that the CFG graph of the functions are extremely different.

I will add more as soon as the analysis proceeds... :ninja: In the meanwhile, you should start thinking if the mismatching functions listed above as NO MATCH could be the source of the error...

#40 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 30 June 2005 - 01:21 PM

I have repeated the prereq traces for v1.3 - there are certainly differences. Again, the logs are too large to post but PM me and I will email them to you if you are interested.

Polaris - I will email them to you tonight.

Flenser




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users