Skip to content
This repository was archived by the owner on Jul 19, 2024. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
63ef267
Add lua bindings for GVars.dbf
VladimirMakeev Mar 7, 2024
ad61a9c
Add lua bindings for GlobalData
VladimirMakeev Mar 7, 2024
81a61a6
Fix typo
VladimirMakeev Mar 7, 2024
37b42a8
Add lua bindings for game rules and user settings
VladimirMakeev Mar 7, 2024
9dac629
Support id types in lua api
VladimirMakeev Mar 7, 2024
c1d7913
Update group lua api
VladimirMakeev Mar 8, 2024
b9bbfd9
Update stack and unitimpl lua api
VladimirMakeev Mar 8, 2024
103f7b3
Add missing include
VladimirMakeev Mar 9, 2024
2600ade
Fix const
VladimirMakeev Mar 9, 2024
c26944a
Update lua bindings for scenario
VladimirMakeev Mar 9, 2024
0258c9d
Add CMidCrystal structure
VladimirMakeev Mar 10, 2024
3ff437b
Add lua bindings for crystals
VladimirMakeev Mar 10, 2024
284ec69
Return capital protection when calling prot(6)
VladimirMakeev Mar 10, 2024
d604227
Add CMidSiteMerchant structure
VladimirMakeev Mar 13, 2024
25a92be
Add CMidSiteMage structure
VladimirMakeev Mar 13, 2024
3555317
Add CMidSiteMercs structure
VladimirMakeev Mar 13, 2024
13fc865
Add CMidSiteTrainer structure
VladimirMakeev Mar 13, 2024
4d1ba2f
Add lua bindings for sites
VladimirMakeev Mar 13, 2024
89b6847
Add lua bindings for merchant
VladimirMakeev Mar 13, 2024
f9413d0
Add lua bindings for mercenary camps
VladimirMakeev Mar 13, 2024
37cadd5
Add lua bindings for trainer
VladimirMakeev Mar 13, 2024
1c85244
Allow access to sites from scenario in lua api
VladimirMakeev Mar 13, 2024
3c35aeb
Place ai attitude categories separately
VladimirMakeev Mar 16, 2024
3fbe668
Add CAiAttitudesTable structure and its api
VladimirMakeev Mar 16, 2024
1149a5a
Add visitor to change player attitude
VladimirMakeev Mar 16, 2024
aab0d6e
Add CScenPropInterf structure and its api
VladimirMakeev Mar 16, 2024
c6cda88
Allow changing Netrals attitude from scenario properties menu
VladimirMakeev Mar 16, 2024
41cff10
Add function to get unit group owner
VladimirMakeev Mar 20, 2024
8700e77
Add new functions to BattleMsgData api
VladimirMakeev Mar 22, 2024
dddd7db
Add lua bindings for mutable BattleMsgData
VladimirMakeev Mar 22, 2024
2d96577
Load custom battle action scripts for AI
VladimirMakeev Mar 22, 2024
67d43b4
Support custom scripts for AI battle actions
VladimirMakeev Mar 22, 2024
f89913d
Update lua api docs
VladimirMakeev Mar 22, 2024
97e5919
Fix typos
VladimirMakeev Mar 22, 2024
292d826
Add entrance method to fort binding
VladimirMakeev Mar 23, 2024
54fe046
Add AI battle action script example
VladimirMakeev Mar 23, 2024
13d3441
Add fast battle to battle api
VladimirMakeev Mar 24, 2024
bab0bcb
Support battle turns order in lua api
VladimirMakeev Mar 24, 2024
dacd6b7
Update battle api
VladimirMakeev Mar 24, 2024
57f14a0
Update scenario api
VladimirMakeev Mar 25, 2024
498dd3a
Add method to check unit wait status in battle
VladimirMakeev Mar 27, 2024
3fc9168
Check attack existence before accessing it
VladimirMakeev Mar 28, 2024
902a200
Event system optimization
VladimirMakeev Apr 14, 2024
56a1aea
'Kill stack' event condition optimization
VladimirMakeev Apr 17, 2024
a39a12c
'Own item' event condition optimization
VladimirMakeev Apr 18, 2024
72b357f
Describe CMidgardPlan implementation
VladimirMakeev Apr 18, 2024
3bd0f83
Implement cache for stack templates
VladimirMakeev Apr 23, 2024
7094af0
'Leader own item' event condition optimization
VladimirMakeev Apr 23, 2024
8a76434
'Stack exists' event condition optimization
VladimirMakeev Apr 23, 2024
7f33b5a
Add Lua api documentation in LaTeX
VladimirMakeev May 5, 2024
8386ec0
Fix battle actions script
VladimirMakeev May 5, 2024
f846931
Update gitignore for LaTeX
VladimirMakeev May 5, 2024
8b679c7
Implement resource market site
VladimirMakeev May 9, 2024
d32a99d
Update resource market
VladimirMakeev May 23, 2024
72d5e32
Add missing hooks
VladimirMakeev May 23, 2024
868d943
Define CMidClientData fields
VladimirMakeev May 26, 2024
69a810b
Add location name to lua api
VladimirMakeev Jun 1, 2024
1e83e1a
Add editor check to Lua api
VladimirMakeev Jun 5, 2024
17e5625
Code review fixes
VladimirMakeev Jun 5, 2024
2081130
Move entrance computation to utility function
VladimirMakeev Jun 5, 2024
6f953de
Code review fixes
VladimirMakeev Jun 5, 2024
1104959
Add player buildings to Lua api
VladimirMakeev Jun 28, 2024
35b8868
Fix edit box input
VladimirMakeev Jun 28, 2024
b5dfffc
Add examples to documentation
VladimirMakeev Jun 29, 2024
329faee
Define noble action categories
VladimirMakeev Jul 3, 2024
89596ef
Read custom noble action categories
VladimirMakeev Jul 3, 2024
021b859
Properly define GlobalVariables and support custom values
VladimirMakeev Jul 3, 2024
922dbbf
Define CEventEffectBase
VladimirMakeev Jul 3, 2024
d34380f
Implement CEffectStealMarket
VladimirMakeev Jul 3, 2024
ddb11e9
Implement CEffectGiveResources
VladimirMakeev Jul 3, 2024
365f9d7
Define INobleActionResult and its vftable
VladimirMakeev Jul 3, 2024
2aac69a
Implement noble action result 'steal from market'
VladimirMakeev Jul 3, 2024
1524028
Implement custom noble action 'steal from resource market'
VladimirMakeev Jul 3, 2024
d12ec2d
Add missing include
VladimirMakeev Jul 3, 2024
7b77b37
Update documentation
VladimirMakeev Jul 5, 2024
5ae5522
Minor fixes
VladimirMakeev Jul 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
48 changes: 48 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,51 @@ ASALocalRun/

# MFractors (Xamarin productivity tool) working folder
.mfractor/

# LaTeX
*.acn
*.acr
*.alg
*.aux
*.bak
*.bbl
*.bcf
*.blg
*.brf
*.bst
*.dvi
*.fdb_latexmk
*.fls
*.glg
*.glo
*.gls
*.idx
*.ilg
*.ind
*.ist
*.lof
*.log
*.lol
*.lot
*.maf
*.mtc
*.mtc1
*.nav
*.nlo
*.nls
*.out
*.pdf
*.pyg
*.run.xml
*.snm
*.synctex.gz
*.tex.backup
*.tex~
*.thm
*.toc
*.vrb
*.xdy
*.xml
*blx.bib
.bak
.mtc
7 changes: 7 additions & 0 deletions ApiDocs/en/apiReference.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
\section{API reference}

\input{standaloneFuncs.tex}
\newpage
\input{enumerations.tex}
\newpage
\input{types.tex}
49 changes: 49 additions & 0 deletions ApiDocs/en/attack.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
\subsection{Attack}
\label{Attack}
Represents attack of \hyperref[UnitImpl]{unit implementation}.
\subsubsection{Properties}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
\textbf{Name} & \textbf{Description} \\
\hline
id & Returns attack \hyperref[Id]{id}. This is different for every \hyperref[DynamicUpgrade]{dynamic upgrade} unit gets\\
\hline
type & Returns attack \hyperref[AttackCategory]{type}\\
\hline
source & Returns attack \hyperref[SourceCategory]{source}\\
\hline
reach & Returns attack \hyperref[ReachCategory]{reach}\\
\hline
initiative & Returns attack initiative value\\
\hline
power & Returns attack power (accuracy)\\
\hline
damage & Returns damage the attack can inflict. Damage depends on attack type\\
\hline
heal & Returns healing the attack can apply. Healing depends on attack type\\
\hline
infinite & Returns true if attack has long effect duration. Effect depends on attack type\\
\hline
crit & Returns true if attack can inflict critical damage\\
\hline
level & Returns level for boost damage, lower damage and lower initiative attacks\\
\hline
melee & Returns true if attack is melee (\texttt{L\_ADJACENT} or custom reach marked as \texttt{MELEE} in \texttt{LAttR.dbf})\\
\hline
maxTargets & Returns maximum number of targets (1, 6 or \texttt{MAX\_TARGTS} value for custom reach in \texttt{LAttR.dbf})\\
\hline
critDamage & Returns critical damage percent \texttt{[0 : 255]}\\
\hline
critPower & Returns critical damage chance \texttt{[0 : 100]}\\
\hline
damageRatio & Returns damage ratio \texttt{[0 : 255]} for additional targets\\
\hline
damageRatioPerTarget & Returns true if damage ratio reapplied for each consecutive target\\
\hline
damageSplit & Returns true if damage is split among targets\\
\hline
wards & Returns array of \hyperref[Modifier]{modifiers} applied by bestow wards attack\\
\hline
\end{tabularx}
\end{center}
87 changes: 87 additions & 0 deletions ApiDocs/en/battle.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
\subsection{Battle}
\label{Battle}
Represents battle state.
\subsubsection{Properties}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
currentRound & Returns current round in battle. Round counting starts from 1, but there is a special round 0 when units with `Doppelganger' \hyperref[Attack]{attacks} present\\
\hline
autoBattle & Returns \texttt{true} if autobattle mode is turned on\\
\hline
fastBattle & Returns \texttt{true} if fast battle is turned on. When fast battle is active, auto battle is active too\\
\hline
attackerPlayer & Returns \hyperref[Player]{player} that started battle or \texttt{nil} if not found\\
\hline
defenderPlayer & Returns \hyperref[Player]{player} that was attacked or \texttt{nil} if not found\\
\hline
attacker & Returns \hyperref[Stack]{stack} that started battle. Only stacks can initiate battles\\
\hline
defender & Returns \hyperref[Group]{group} that was attacked. Defender group can represent units of a \hyperref[Stack]{stack}, \hyperref[Fort]{fort} or \hyperref[Ruin]{ruin}. Use \texttt{group.id.type} to get an actual type of a group\\
\hline
decidedToRetreat & Returns \texttt{true} if decision about groups retreat was made and should not be reconsidered\\
\hline
afterBattle & Returns \texttt{true} if battle is over but healers can make one more turn to heal allies\\
\hline
duel & Returns \texttt{true} if battle is a duel between thief and a stack leader. All units except leaders are marked with \texttt{Hidden} \hyperref[BattleStatus]{battle status}\\
\hline
turnsOrder & Returns list of \hyperref[BattleTurn]{battle turns} remaining in the current round of battle. Position of elements in the list corresponds to order of remaining turns in current round. In other words, at the start of a round, battle turns in the list are sorted according to units initiative, including an additional random initiative\\
\hline
\end{tabularx}
\end{center}

\subsubsection{Methods}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
getUnitStatus(id, BattleStatus.Defend) & Returns \texttt{true} if a unit with a specified \hyperref[Id]{id} has a specified \hyperref[BattleStatus]{battle status}\\
\hline
isUnitAttacker(unit) & Returns \texttt{true} if \hyperref[Unit]{unit} belongs to attacker group.\\
isUnitAttacker(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitActions(unit) & Returns possible actions and attack options for specified \hyperref[Unit]{unit}.\\
getUnitActions(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getRetreatStatus(true) & Returns retreat status of attacker (\texttt{true}) or defender (\texttt{false}) group\\
getRetreatStatus(false) &\\
\hline
isUnitRevived(unit) & Returns \texttt{true} if specified \hyperref[Unit]{unit} was revived during battle.\\
isUnitRevived(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
isUnitWaiting(unit) & Returns \texttt{true} if specified \hyperref[Unit]{unit} skipped its turn and waiting.\\
isUnitWaiting(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitShatteredArmor(unit) & Returns amount of \hyperref[Unit]{unit} armor shattered in battle so far.\\
getUnitShatteredArmor(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitFortificationArmor(unit) & Returns armor that is granted to \hyperref[Unit]{unit} by fortification, if any.\\
getUnitFortificationArmor(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
isUnitResistantToClass(unit, attackClass) & Returns true if specified \hyperref[Unit]{unit} is resistant to \hyperref[AttackCategory]{attack class}.\\
isUnitResistantToClass(id, attackClass) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
isUnitResistantToSource(unit, attackSource) & Returns true if specified \hyperref[Unit]{unit} is resistant to \hyperref[SourceCategory]{attack source}.\\
isUnitResistantToSource(id, attackSource) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitDisableRound(unit) & Returns round when paralyze, petrify or fear was applied to \hyperref[Unit]{unit}. Returns 0 if unit is not disabled.\\
getUnitDisableRound(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitPoisonRound(unit) & Returns round when long poison was applied to \hyperref[Unit]{unit}. Returns 0 if unit is not poisoned.\\
getUnitPoisonRound(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitFrostbiteRound(unit) & Returns round when long frostbite was applied to \hyperref[Unit]{unit}. Returns 0 if unit is not frozen.\\
getUnitFrostbiteRound(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitBlisterRound(unit) & Returns round when long blister was applied to \hyperref[Unit]{unit}. Returns 0 if unit is not burning.\\
getUnitBlisterRound(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
getUnitTransformRound(unit) & Returns round when long transform was applied to \hyperref[Unit]{unit}. Returns 0 if unit is not transformed.\\
getUnitTransformRound(id) & Method also accepts unit \hyperref[Id]{ids}\\
\hline
setRetreatStatus(true, Retreat.FullRetreat) & Sets \hyperref[Retreat]{retreat status} of attacker (\texttt{true}) or defender (\texttt{false}) group. This method can be only used in AI battle action script\\
setRetreatStatus(false, Retreat.NoRetreat) &\\
\hline
setDecidedToRetreat() & Notifies battle state that the decision about groups retreat was made and it is final. This method can be only used in AI battle action script\\
\hline
\end{tabularx}
\end{center}
15 changes: 15 additions & 0 deletions ApiDocs/en/battleturn.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
\subsection{Battle turn}
\label{BattleTurn}
Represents \hyperref[Unit]{unit} action inside battle round\\
\subsubsection{Properties}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
\textbf{Name} & \textbf{Description} \\
\hline
unit & Returns \hyperref[Unit]{unit} that performs the turn\\
\hline
attackCount & Returns number of attacks unit can perform in its turn. Units with double attack (\texttt{turn.unit.impl.attacksTwice}) will have 2 in attackCount\\
\hline
\end{tabularx}
\end{center}
18 changes: 18 additions & 0 deletions ApiDocs/en/building.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
\subsection{Building}
\label{Building}
Represents building in \hyperref[Player]{player's} capital.
\subsubsection{Properties}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
\textbf{Name} & \textbf{Description} \\
\hline
id & Returns building \hyperref[Id]{id}. \texttt{BUILD\_ID} value from \texttt{GBuild.dbf}\\
cost & Returns building \hyperref[Currency]{cost}. \texttt{COST} value from \texttt{GBuild.dbf}\\
type & Returns building \hyperref[BuildingCategory]{type}. \texttt{CATEGORY} value from \texttt{GBuild.dbf}\\
requiredBuilding & Returns \hyperref[Building]{building} that is required to build this one or \texttt{nil} if building has no requirements. \texttt{REQUIRED} value from \texttt{GBuild.dbf}\\
branch & Returns unit \hyperref[UnitBranch]{branch} or -1 if building type is not \texttt{Unit}\\
level & Returns building level or 0 if building type is not \texttt{Unit}\\
\hline
\end{tabularx}
\end{center}
17 changes: 17 additions & 0 deletions ApiDocs/en/crystal.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
\subsection{Crystal}
\label{Crystal}
Represents gold mine or mana source on a map.
\subsubsection{Properties}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
\textbf{Name} & \textbf{Description} \\
\hline
id & Returns crystal \hyperref[Id]{id}. The value is unique for every crystal on scenario map\\
\hline
position & Returns crystal position as a \hyperref[Point]{point}\\
\hline
resource & Returns crystal \hyperref[Resource]{resource type}\\
\hline
\end{tabularx}
\end{center}
34 changes: 34 additions & 0 deletions ApiDocs/en/currency.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
\subsection{Currency}
\label{Currency}
Represents game currency, mana and gold united.
\subsubsection{Properties}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
\textbf{Name} & \textbf{Description} \\
\hline
gold & Returns or sets amount of gold\\
\hline
infernalMana & Returns or sets amount of infernal mana\\
\hline
lifeMana & Returns or sets amount of life mana\\
\hline
deathMana & Returns or sets amount of death mana\\
\hline
runicMana & Returns or sets amount of runic mana\\
\hline
groveMana & Returns or sets amount of grove mana\\
\hline
\end{tabularx}
\end{center}

\subsubsection{Methods}
\begin{center}
\begin{tabularx}{\linewidth}{| l | X |}
\hline
\textbf{Name} & \textbf{Description} \\
\hline
Currency.new(existing) & Creates new currency from existing object\\
\hline
\end{tabularx}
\end{center}
88 changes: 88 additions & 0 deletions ApiDocs/en/customModifiersExample.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
\subsection{Custom modifiers}
Modifiers in the game stack on top of each other, making ordered modifiers chain.
First modifier takes base values from the unit it modifies, next - values modified by the first modifier and so on.
Custom modifiers allow you to modify every stat of unit and its attacks in a single script file with a number of uniform functions.\\
Most of the custom modifier functions have the following form:
\begin{center}
\begin{lstlisting}[language=Lua]
function getSomething(unit, prev)
if someCondition then
return modifiedValue
end

return prev
end
\end{lstlisting}
\end{center}
\begin{itemize}
\item \texttt{unit} has type \hyperref[Unit]{Unit}. The unit is presented in a state before the current modifier is applied.
\item \texttt{prev} is a previous value of the stat. It is either a base value or a value modified by the previous modifier.
\end{itemize}
Check \href{https://github.com/VladimirMakeev/D2ModdingToolset/tree/master/Scripts/Modifiers}{Scripts/Modifiers} for script examples.\\
\href{https://github.com/VladimirMakeev/D2ModdingToolset/blob/master/Scripts/Modifiers/template.lua}{template.lua} contains a complete list of available functions.\\

\textbf{Due to how modifiers chain work, you have no direct access to final unit stats}\\
For example:
\begin{itemize}
\item Lets say we have a unit with base of 50 initiative;
\item Then we give it a potion that increases damage by 50\% \textbf{if unit initiative} \texttt{> 60};
\item Then we give it another potion that increases initiative to 70.
\end{itemize}
The damage bonus \textbf{will not work} in this case, even though a final unit initiative is 70 that is \texttt{> 60}. This is because \textbf{damage modifier applied earlier than initiative modifier}.
If we get \texttt{unit.impl.attack1.initiative} from the damage modifier script it will be 50, because \textbf{initiative modifier is not applied yet}.\\

\textbf{Dangerous way around to get final unit stats}\\
The limitation described above \textbf{can be avoided} by getting unit instance via \texttt{getScenario:getUnit(unit.id)}.\\
But you have to be \textbf{very careful} using this approach, as you can easily fall into a deadloop.\\

Lets see a \textbf{bad example} where we created a modifier that grants bonus armor and regen depending on each other:
\begin{center}
\begin{lstlisting}[language=Lua]
function getArmor(unit, prev)
local finalUnit = getScenario():getUnit(unit.id)
return prev + finalUnit.impl.regen / 5
end

function getRegen(unit, prev)
local finalUnit = getScenario():getUnit(unit.id)
return prev + finalUnit.impl.armor / 10
end
\end{lstlisting}
\end{center}
Or it can be two different modifiers, does not matter:
\begin{center}
\begin{lstlisting}[language=Lua]
-- MyBonusArmorMod.lua
function getArmor(unit, prev)
local finalUnit = getScenario():getUnit(unit.id)
return prev + finalUnit.impl.regen / 5
end
\end{lstlisting}
\end{center}
When this modifier(s) applied to a unit, we are getting circular dependence here: \textbf{final armor depends on final regen while final regen depends on final armor}.\\
Imagine what happens when the game tries to get unit armor:\\
It calls \texttt{getArmor} that calls \texttt{getRegen} that calls \texttt{getArmor} that calls \texttt{getRegen} that calls \texttt{getArmor} that calls \texttt{getRegen} that calls \texttt{getArmor}... and so on until your \textbf{game hang or crash to desktop}.\\

As a \textbf{good example}, you could refer to a third stat, thus avoiding deadloop condition:
\begin{center}
\begin{lstlisting}[language=Lua]
-- MyBonusArmorMod.lua
function getArmor(unit, prev)
local finalUnit = getScenario():getUnit(unit.id)
return prev + finalUnit.impl.regen / 5
end
\end{lstlisting}
\end{center}
and
\begin{center}
\begin{lstlisting}[language=Lua]
-- MyBonusRegenMod.lua
function getRegen(unit, prev)
local finalUnit = getScenario():getUnit(unit.id)
return prev + finalUnit.impl.level / 10
end
\end{lstlisting}
\end{center}
This way, regen depends on level, and armor depends on regen and there is no circular dependence in this case.\\

\textbf{Remember that this is subject for all modifiers that can potentially happen to be applied to the same unit}.
Loading