Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

VladimirMakeev/D2ModdingToolset

Repository files navigation

Modding toolset for Disciples 2 License: GPL v3

Features:

General

  • Can be used on vanilla version or with other mods installed;

  • Allows players to search and create PvP matches without external software using custom lobby server. Currently only for Motlin's mod;

  • Adds random scenario map generator;
    • Add generatorSettings.lua into Scripts forlder;
    • Create Templates folder inside game folder and place template files here;
    • Add buttons BTN_RANDOM_MAP to DLG_CHOOSE_SKIRMISH, DLG_HOST and DLG_HOTSEAT_NEW in Interf.dlg:
    BUTTON	BTN_RANDOM_MAP,27,541,336,592,BTN_GENERATE_N,BTN_GENERATE_H,BTN_GENERATE_C,BTN_GENERATE_D,"",0
    TEXT	TXT_RANDOM_MAP,27,541,336,592,\hC;\vC;\fMenu;,"X015TA0022","X015TA0023"
    
    • Add two new menu screens: for random multiplayer maps and local play (singleplayer or hotseat) maps. Add DLG_RANDOM_SCENARIO_SINGLE and DLG_RANDOM_SCENARIO_MULTI in Interf.dlg;
    • Add popup menu that will be displayed during scenario map generation process, add DLG_WAIT_GENERATION in Interf.dlg;
    • Add popup menu that will show zones placement preview after map generation, add DLG_GENERATION_RESULT in Interf.dlg;
    • Add transition animations for new menu screens in MenuAnim.ff:
      • TRANS_HOST2RNDMULTI.BIK - transition from multiplayer host to generator menu;
      • TRANS_NEWQUEST2RNDSINGLE.BIK - transition from local game to generator menu;
      • TRANS_RND2HSLOBBY.BIK - transition from generator menu to hotseat lobby;
      • TRANS_RNDSINGLE2GOD.BIK - transition from generator menu to race selection menu;
    • Add race preview images as well as 'random race' to Interf.ff. Images should be named as GOD_EMPIRE, GOD_CLANS, GOD_UNDEAD, GOD_LEGIONS, GOD_ELVES, GOD_RANDOM;
    • Add ZONE_BORDER image for zones placement preview to Interf.ff;
    • Add translated text ids to TApp.dbf and into generator section of Scripts/textids.lua.
  • Increases maximum game turn to 9999;

  • Allows to load and create scenarios with no magic (maximum spell level set to 0);

  • Buildings up to tier 10 are supported in editor and game;

  • Adds new custom building category for unit hire;
    • Place new buildings on the 'Other buildings' tab using game resources;
    • Create custom category by adding L_CUSTOM record to LBuild.dbf.
  • Allows sideshow buildings (Ruined Temple, Snow Den and such) to have no required prerequisite building;

    Demo video

    • Create custom category records L_FIGHTER, L_MAGE, L_ARCHER, L_SPECIAL and L_CUSTOM ('Other buildings') in Lbuild.dbf;
    • Set corresponding category number in CATEGORY field and empty id g000000000 in REQUIRED field for desired sideshow buildings in Gbuild.dbf. Note that you only need to change the first building in a tree: for example, in case of the 'Elven Alliance', you only need these changes for 'Aviary' building that enlists 'Griffins', while 'Volary' should be left unchanged.
  • Allows each race to hire up to 10 new tier-1 units in cities and capital;
    • For each new unit, add a new column SOLDIER_N to Grace.dbf, where N starts from 6;
    • You can specify either an unit id from GUnits.dbf, or the empty id g000000000 as the column value;
    • Add scroll buttons BTN_PG_DN, BTN_PG_UP, BTN_LIST_UP and BTN_LIST_DN to unit hire dialog DLG_HIRE_LEADER_2 in Interf.dlg:
    DIALOG	DLG_HIRE_LEADER_2,0,0,533,600,DLG_HIRE_LEADER_2_PHIRELEADER,_CUDEFAUL,0,0,77,3,455,551,0
    BEGIN
    	BUTTON	BTN_PG_DN,0,0,10,10,,,,,"",0,34
    	BUTTON	BTN_PG_UP,10,0,20,10,,,,,"",0,33
    	BUTTON	BTN_LIST_UP,415,30,441,56,DLG_UPGRADE_LEADER_ARROW_UP_N,DLG_UPGRADE_LEADER_ARROW_UP_H,DLG_UPGRADE_LEADER_ARROW_UP_C,DLG_UPGRADE_LEADER_ARROW_UP_N,"",1,38
    	BUTTON	BTN_LIST_DN,415,480,441,506,DLG_UPGRADE_LEADER_ARROW_DOWN_N,DLG_UPGRADE_LEADER_ARROW_DOWN_H,DLG_UPGRADE_LEADER_ARROW_DOWN_C,DLG_UPGRADE_LEADER_ARROW_DOWN_N,"",1,40
    	BUTTON	BTN_CLOSE,399,506,448,600,DLG_HIRE_LEADER_2_SEAL_X_N,DLG_HIRE_LEADER_2_SEAL_X_H,DLG_HIRE_LEADER_2_SEAL_X_C,DLG_HIRE_LEADER_2_SEAL_X_N,"X100TA0020",0,27
    	BUTTON	BTN_HIRE_LEADER,352,506,401,600,DLG_HIRE_LEADER_2_SEAL_OK_N,DLG_HIRE_LEADER_2_SEAL_OK_H,DLG_HIRE_LEADER_2_SEAL_OK_C,DLG_HIRE_LEADER_2_SEAL_OK_N,"X100TA0101",0,13
    	IMAGE	IMG_GOLD,222,517,258,546,DLG_HIRE_LEADER_2_GOLD,"X100TA0082"
    	LBOX	LBOX_LEADER,125,43,410,503,285,85,0,7,BTN_LIST_UP,BTN_LIST_DN,,,BTN_PG_UP,BTN_PG_DN,BTN_HIRE_LEADER,,,0,"",0
    	TEXT	TXT_GOLD,264,525,304,541,\hL;\vC;,"",""
    	TEXT	TXT_LEGENDE,144,13,394,43,\fLarge;\hC;\vC;,"",""
    END
    
  • Allows foreign race units (including neutral) to be upgraded using capital buildings;

    Demo video

    • Use existing or create a new unit to be used as upgrade in GUnits.dbf;
    • Specify a building to upgrade in UPGRADE_B (the game does not allow to do free upgrades without a building);
    • Refer to the previous unit in PREV_ID (if you want different previous units to be upgraded into one single unit, you will have to make copies of the latter using BASE_UNIT);
    • The LEVEL of the upgrade unit must be equal to the level of the previous unit + 1;
  • Allows scenarios with prebuilt capital cities;
    • Enable preserveCapitalBuildings in settings.lua;
    • Start a scenario;
    • Build desired buildings in a capital;
    • Save the scenario;
    • Move the saved game from 'SaveGame' folder to 'Exports';
    • Restart the scenario.
  • Allows to set a maximum number of items the player is allowed to transfer between campaign scenarios;

    Specify carryOverItemsMax in settings.lua.

  • Allows to add new music tracks for battle and capital cities;

    New music tracks name format follows original game naming convention.
    WAV tracks in Music folder containing 'battle' as part of their names will be played during battle.
    WAV tracks in Music folder containing '<humn/dwrf/unde/here/elf>trk' as part of their names will be played in capital city window with accordance to race.

    Examples:

    • battle10.wav - new music track for battle
    • humntrk4.wav - new music track for Empire
    • heretrk15.wav - new music track for Legions of the Damned
  • Provides debug log files to help mod makers;

    Enable debugHooks in settings.lua.
    Don't forget to turn it off in release package of your mod to avoid cluttering and improve performance.

  • Provides recommended game settings: add contents of Disciple.ini to Disciple.ini;

User interface

  • Allows banners, resources panel and converted land percentage to be displayed by default;

    Use the following settings in settings.lua:

    • showBanners
    • showResources
    • showLandConverted
  • Buttons for bulk item transfer: transfer all items, potions, scrolls/wands or valuables between inventories with single click;

    Add buttons with predefined names to DLG_CITY_STACK, DLG_EXCHANGE or DLG_PICKUP_DROP dialogs in Interf.dlg file.
    Every button is optional and can be ignored.
    Buttons and their meaning:

    • Transfer all items to the left inventory: BTN_TRANSF_L_ALL;
    • Transfer all items to the right inventory: BTN_TRANSF_R_ALL;
    • Transfer all potions to the left: BTN_TRANSF_L_POTIONS;
    • Transfer all potions to the right: BTN_TRANSF_R_POTIONS;
    • Transfer all scrolls and wands to the left: BTN_TRANSF_L_SPELLS;
    • Transfer all scrolls and wands to the right: BTN_TRANSF_R_SPELLS;
    • Transfer all valuables to the left: BTN_TRANSF_L_VALUABLES;
    • Transfer all valuables to the right: BTN_TRANSF_R_VALUABLES;

    Example of button description in Interf.dlg:

    BUTTON    BTN_TRANSF_L_ALL,342,424,385,459,DLG_EXCHANGE_RETURN_D,DLG_EXCHANGE_RETURN_H,DLG_EXCHANGE_RETURN_C,DLG_EXCHANGE_RETURN_D,"Transfer all items to left",0
    
  • Button to sell all valuables with a single click;
    • Add sell confirmation text to TApp.dbf. The text must contain %PRICE% keyword in it;
    • Specify id of the text in sellAllValuables field inside textids.lua (default id is X015TA0001);
    • Add button with name BTN_SELL_ALL_VALUABLES to DLG_MERCHANT in Interf.dlg file.

    In case of missing text, the following default message will be shown:

    Do you want to sell all valuables? Revenue will be:\n%PRICE%
    

    Example of button description in Interf.dlg:

    BUTTON	BTN_SELL_ALL_VALUABLES,417,425,460,460,DLG_CITY_STACK_RETURN_D,DLG_CITY_STACK_RETURN_H,DLG_CITY_STACK_RETURN_C,DLG_CITY_STACK_RETURN_D,"Sell all valuables",0
    
  • Button to sell all items with a single click;
    • Add sell confirmation text to TApp.dbf. The text must contain %PRICE% keyword in it;
    • Specify id of the text in sellAllItems field inside textids.lua.
    • Add button with name BTN_SELL_ALL to DLG_MERCHANT in Interf.dlg file.

    In case of missing text, the following default message will be shown:

    Do you want to sell all items? Revenue will be:\n%PRICE%
    

    Example of button description in Interf.dlg:

    BUTTON	BTN_SELL_ALL,417,425,460,460,DLG_CITY_STACK_RETURN_D,DLG_CITY_STACK_RETURN_H,DLG_CITY_STACK_RETURN_C,DLG_CITY_STACK_RETURN_D,"Sell all items",0
    
  • Button to show grid in game;

    Add toggle button with name TOG_GRID to DLG_ISO_LAND in Interf.dlg.

    Example of button description in Interf.dlg:

    TOGGLE  TOG_GRID,128,63,160,92,DLG_ISO_GRID_N,DLG_ISO_GRID_H,DLG_ISO_GRID_C,DLG_ISO_GRID_D,DLG_ISO_GRID_H,DLG_ISO_GRID_H,DLG_ISO_GRID_H,"",71
    
  • Adds missing information to unit encyclopedia;
    • Enable detailedUnitDescription under unitEncyclopedia category in settings.lua to add the following:

      • Modifier values for 'HP', 'Immunities' and 'Wards';
      • Custom unit modifiers.
    • Enable or disable displayBonusHp and displayBonusXp depending on whether you want to display corresponding bonuses or just total values;

    • Enable detailedAttackDescription under unitEncyclopedia category in settings.lua to add the following:

      • Damage of secondary attack if its not either poison, blister or frostbite;
      • Power (if applicable) and source (if it matters) of alternative attack;
      • Value of boost/lower damage if its secondary attack;
      • Value of lower initiative;
      • Critical hit indication;
      • Effect duration;
      • Infinite effect indication (alternative to effect duration);
      • Broken (removed) wards indication;
      • Drain attack description;
      • Custom attack sources;
      • Custom attack reaches;
      • Custom attack damage ratios;
      • Custom unit modifiers.
    • Specify the following interface text ids in textids.lua:

      • critHitAttack
      • critHitDamage
      • durationDescription
      • durationText
      • instantDurationText
      • randomDurationText
      • singleTurnDurationText
      • wholeBattleDurationText
      • infiniteAttack
      • infiniteText
      • ratedDamage
      • ratedDamageEqual
      • ratedDamageSeparator
      • splitDamage
      • modifiedValue
      • modifiedNumber
      • modifiedNumberTotal
      • positiveBonusNumber
      • negativeBonusNumber
      • drainDescription
      • drainEffect
      • overflowAttack
      • overflowText
      • dynamicUpgradeLevel
      • dynamicUpgradeValues
      • removedAttackWard
    • Add the specified interface text to TApp.dbf and TAppEdit.dbf;

    • (Optional) Add drain attack description:

      • Find text constants with ids X005TA0787 and X005TA0788 in TApp.dbf and TAppEdit.dbf;
      • Add %DRAIN% keyword where you like to put the description (propose to place it after damage field like ...%DAMAGE%\n%DRAIN%...);
      • The keyword is replaced with empty string if attack has no drain effect;
      • Note that you can freely move content between X005TA0787 and X005TA0788 if you run out of length limit (because the two strings simply merged together in X005TA0424).
    • (Optional) Add effect duration description:

      • Find text constants with ids X005TA0787 and X005TA0788 in TApp.dbf and TAppEdit.dbf;
      • Add %DURATION% keyword where you like to put the description (propose to place it after attack-name field like ...%ATTACK%%SECOND%\p0;\n%DURATION%...);
      • The keyword is replaced with empty string if attack has instant effect;
      • Note that you can freely move content between X005TA0787 and X005TA0788 if you run out of length limit (because the two strings simply merged together in X005TA0424).
    • (Optional) Add infinite effect indication (alternative to effect duration): enable setting 'unitEncyclopedia.displayInfiniteAttackIndicator';

    • (Optional) Add extra stats panel:

      • Add interface text to TApp.dbf and TAppEdit.dbf that contains %XPKILL%, %EFFHP% and %REGEN% (every keyword is optional), for example:
        \s50;\n\fMedbold;Bounty:\t\fNormal;%XPKILL%\n\fMedbold;Eff. HP:\t\fNormal;%EFFHP%\n\fMedbold;Regen:\t\fNormal;%REGEN%
        
      • Add text box with name TXT_STATS_2 to DLG_R_C_UNIT in Interf.dlg and ScenEdit.dlg. Specify added interface text id. For example:
        TEXT	TXT_STATS_2,554,75,664,231,,"X015TA0003",""
        
      • Try extending the dialog bounds or otherwise rearrange its elements to properly accomodate the panel with its contents;
      • Displayed regeneration value includes all the factors:
        • Unit regeneration including modifiers;
        • Warrior lord bonus;
        • Race terrain bonus;
        • Ruins bonus;
        • Capital / village bonus;
        • Rioting village penalty.
    • (Optional) Adds dynamic upgrade values to unit encyclopedia:

      • Enable displayDynamicUpgradeValues under unitEncyclopedia category in settings.lua;
      • Enable detailedUnitDescription and/or detailedAttackDescription to show upgrade values for corresponding stats;
      • The values are only shown for unit types to avoid clutter:
        • While browsing unit buildings in capital;
        • While hiring from capital, villages or mencenaries;
        • While adding units to groups (specific to Scenario Editor).

      image image

  • Shows effective HP in unit encyclopedia;
    • Add text box with name TXT_EFFECTIVE_HP to DLG_R_C_UNIT in Interf.dlg and ScenEdit.dlg files, for example:
      TEXT	TXT_EFFECTIVE_HP,468,95,663,231,,"X015TA0002",""
      
    • Specify text id from TApp.dbf and TAppEdit.dbf that contains key %HP%.
  • Shows total XP for killing in stack/city/ruin encyclopedia;
    • Add interface text to TApp.dbf and TAppEdit.dbf that contains %XPKILL% keyword, for example: X015TA0011 Bounty: %XPKILL%;
    • Add text box with name TXT_XP_KILLED to DLG_R_C_STACK in Interf.dlg and ScenEdit.dlg files, for example:
      TEXT	TXT_XP_KILLED,161,527,396,549,\hC;,"X015TA0011",""
      
    • Add text boxes with names TXT_XP_KILLED and TXT_XP_KILLED_STACK to DLG_R_C_CITY in Interf.dlg and ScenEdit.dlg files, for example:
      TEXT	TXT_XP_KILLED,444,531,619,553,\hC;,"X015TA0011",""
      TEXT	TXT_XP_KILLED_STACK,165,531,339,553,\hC;,"X015TA0011",""
      
    • Add text box with name TXT_XP_KILLED to DLG_R_C_RUIN in Interf.dlg and ScenEdit.dlg files, for example:
      TEXT	TXT_XP_KILLED,130,486,360,508,\hC;,"X015TA0011",""
      

    image image image

Strategic map

  • Allows to display movement cost for each individual step of parties;

    See movementCost category in settings.lua:

    • Enable show to display movement cost;
    • textColor can be used to specify a color (RGB) of the text;
    • outlineColor can be used to specify a color (RGB) of the text outline.
  • Allows to specify a maximum allowed scout range for parties;

    Specify stackMaxScoutRange in settings.lua.

  • Allows unit regeneration modifiers to stack;

    Enable cumulativeUnitRegeneration under modifiers category in settings.lua.
    By default, the game picks single highest value, then sums it with lord, terrain and city bonuses;

  • Adds new event conditions;
    • Replace LEvCond.dbf with LEvCond.dbf;
    • Add contents of ScenEdit.dlg to ScenEdit.dlg;
    • Translate menus and buttons if needed. Also, add translated text ids to textids.lua;
    • Add translations for brief (BRIEF) and full (DESCR) event condition descriptions to TAppEdit.dbf;
    • Set ids of these translations to corresponding columns in LEvCond.dbf;
    • Text strings in INFO column must contain predefined keys for game to show actual game data.

    Examples:

    • TEXT is L_OWN_RESOURCE, INFO refers to Own %COND% %GOLD% gold, %INFERNAL% infernal, %LIFE% life, %DEATH% death, %RUNIC% runic, %GROVE% grove;
    • TEXT is L_GAME_MODE, INFO refers to Game mode: %MODE%;
    • TEXT is L_PLAYER_TYPE, INFO refers to Player is controlled by %TYPE%;
    • TEXT is L_SCRIPT, INFO refers to Script: %DESC%;
    • TEXT is L_VARIABLE_CMP does not use text id from INFO column, so it can be set as 'g0000000000'.
  • Cities can generate daily income depending on scenario variables with predefined names;

    Scenario variables with predefined names are checked each turn and affect income, excluding neutrals race. Variables can be changed by events as any others.

    Variables that affect all races:

    - TIER_0_CITY_INCOME - income from capital city;
    - TIER_N_CITY_INCOME - income from tier N city, N = [1 : 5];
    

    Variables that affect specific race:

    - EMPIRE_TIER_0_CITY_INCOME - income from capital city for Empire only;
    - EMPIRE_TIER_N_CITY_INCOME - income from tier N city for Empire only, N = [1 : 5];
    - LEGIONS .. - income for Legions of the Damned only;
    - CLANS .. - Mountain Clans;
    - HORDES .. - Undead Hordes;
    - ELVES .. - Elven Alliance;
    
  • Neutral cities can use race-specific graphics;

    Add cities graphics with names G000FT0000NE<tier><race> to isoAnim.ff and isoStill.ff.
    tier is a city tier, values from 1 to 5.
    race is a race suffix:

    • DW for Mountain Clans;
    • EL for Elven Alliance;
    • HE for Legions of the Damned;
    • HU for Empire;
    • UN for Undead Hordes;
  • Allows Scenario Editor to place merchants, mages, trainers and mercenaries on water tiles;

  • Allows Scenario Editor to place more than 200 stacks on a map;

Battle mechanics

  • Allows to set maximum unit damage and armor;

    Specify unitMaxDamage and unitMaxArmor in settings.lua.

  • Allows to set critical hit damage and chance;

    Specify criticalHitDamage and criticalHitChance in settings.lua.

    Aside from that, these numbers can be customized for each particular attack:

    • Add CRIT_DAM (Numeric, size 3) and CRIT_POWER (Numeric, size 3) columns to Gattacks.dbf;
    • Check CRIT_HIT column to enable critical hit for attacks that you wish to customize;
    • CRIT_DAM specifies a critical hit damage (0-255%). Falls back to criticalHitDamage if empty;
    • CRIT_POWER specifies a critical hit chance (0-100%). Falls back to criticalHitChance if empty;
    • Specify the following interface text ids in textids.lua:
      • critHitAttack
      • critHitDamage
    • Add the specified interface text to TApp.dbf and TAppEdit.dbf.

    image

  • Allows to set AI accuracy bonuses for different game difficulty modes;

    See aiAccuracyBonus category in settings.lua:

    • Specify easy, average, hard and veryHard according to difficulty modes;
    • absolute determines how accuracy bonuses are treated - as absolute or percentage values.
  • Allows to set accuracy reduction for mage leaders per each additional target;

    Specify mageLeaderAccuracyReduction in settings.lua.

  • Allows to set a number of battle round after which paralyze and petrify attacks will constantly miss;

    Specify disableAllowedRoundMax in settings.lua.

  • Allows to switch attacks miss check to a single random value roll instead of check against arithmetic mean of two random numbers;

    Enable missChanceSingleRoll in settings.lua.

  • Allows alchemists to give additional attacks to retreating allies;

  • Allows to set vampiric attacks heal ratio;

    Specify drainAttackHeal and drainOverflowHeal in settings.lua.

  • Allows vampiric attacks to deal critical damage;

  • Allows to customize shatter attacks: maximum damage per hit, maximum armor that can be shattered, whether attack can miss or not, and its upgrade ratio;

    Use the following settings in settings.lua:

    • shatteredArmorMax
    • shatterDamageMax
    • shatterDamageUpgradeRatio
    • allowShatterAttackToMiss
  • Allows doppelganger, transform-self, transform-other, drain-level and summon attacks to produce leveled versions of units;

    Demo video

    Use the following settings in settings.lua:

    • leveledDoppelgangerAttack
    • leveledTransformSelfAttack
    • leveledTransformOtherAttack
    • leveledDrainLevelAttack
    • leveledSummonAttack
  • Allows doppelganger attacks to respect enemy and ally wards and immunities to the attack class and source;

    Enable doppelgangerRespectsEnemyImmunity and doppelgangerRespectsAllyImmunity in settings.lua.

  • Allows transform-self attack to not consume a unit turn for transformation;

    Demo video

    • Enable freeTransformSelfAttack in settings.lua;
    • freeTransformSelfAttackInfinite allows the attack to be used infinite number of times per single turn;
    • Logic can be customized using getFreeAttackNumber function in transformSelf.lua.
  • Allows transformed leaders (doppelganger, drain-level, transform-self/other attacks) to use battle items (potions, orbs and talismans);

    See allowBattleItems category in settings.lua:

    • onTransformOther
    • onTransformSelf
    • onDrainLevel
    • onDoppelganger
  • Increases total ward limit for bestow-wards attack from 8 to 48;

    Demo video

    Up to 8 modifiers can be applied to each unit (8 x 6 = 48 total):

    • Enable unrestrictedBestowWards in settings.lua;
    • If needed, set QTY_WARDS to 5 (6, 7 or 8) and create additional WARD5 (6, 7, 8) columns in GAttacks.dbf.
  • Allows attack class immunity modifiers to be applied (e.g. Banner of Fear Warding);

    Demo video

    • Add IMMUNITYC and IMMUNECATC columns to GmodifL.dbf (similar to IMMUNITY and IMMUNECAT);
    • Add a new record with TYPE 14, and fill the columns accordingly to attack class and immunity.

    Note that this also works in pure vanilla version.

  • Allows to carry extra XP received over unit's upgrade (limited to value required for the next upgrade minus 1);

    Demo video

  • Allows units to receive multiple upgrades per single battle;

    Demo video

  • Supports custom attack sources; **Note** that the total number of attack sources (including the base 8) cannot exceed 32 due to game limitations.
    • Add a name for a custom source to TApp.dbf and TAppEdit.dbf;
    • Add NAME_TXT (Character, size 10) and IMMU_AI_R (Numeric, size 2) columns to LattS.dbf;
    • Add a new entry in LattS.dbf;
    • Specify the custom source ID and TEXT accordingly;
    • Specify the id of the source name from TApp.dbf in NAME_TXT ('X005TA0153' for instance);
    • Specify IMMU_AI_R: AI rating of the source immunity - used to determine how powerful a unit with such ward or immunity is. The greater - the better. For example, elemental immunities have average rating of 5, while weapon immunity has 57. Can be omitted - 5 is the default;
    • Consider adding vertical align to unit encyclopedia fields to properly accommodate custom attack source text:
      • Find text constants with ids X005TA0787 and X005TA0788 in TApp.dbf and TAppEdit.dbf;
      • Note how attack name fields %TWICE%%ALTATTACK%%ATTACK%%SECOND% are enclosed in vertical align \p110; and \p0;;
      • Use the same technique to enclose %SOURCE%%SOURCE2% field in X005TA0788 (like \p110;%SOURCE%%SOURCE2%\p0;);
      • Note that you can freely move content between X005TA0787 and X005TA0788 if you run out of length limit (because the two strings simply merged together in X005TA0424).

    image

    Note that the SOURCE column is limited to 1 digit in GAttacks.dbf.
    This means that only 2 additional sources (with id 8 and 9) can be added by default.
    The limit can be lifted by extending the SOURCE column size to 2 digits (similar to CLASS).
    For example, using Sdbf: go to main manu Table > Change structure, set SOURCE size to 2 and hit save: image

  • Supports custom attack reaches;

    Demo video. Customizable via Lua scripting and additional columns in LAttR.dbf.
    Scripts includes example targeting scripts demonstrated in the video above.
    Examples includes an example of LAttR.dbf.
    luaApi contains a complete script Api reference to help you create your own scripts.

    Additional columns of LAttR.dbf:

    • REACH_TXT (Character, size 10) specifies an id for 'Reach' encyclopedia description from TApp.dbf and TAppEdit.dbf. For example 'X005TA0201' is the standard 'Adjacent units';
    • TARGET_TXT (Character, size 10) is similar to REACH_TXT but for 'Targets' entry (either '1' or '6' in vanilla);
    • SEL_SCRIPT (Character, size 48) contains a file name of a targeting script from Scripts. The script determines which units allowed to be selected for attack;
    • ATT_SCRIPT (Character, size 48) is similar to SEL_SCRIPT, but determines which units will be affected by attack;
    • MRK_TARGTS (Logical) determines whether ATT_SCRIPT should be used to also mark targets with circle animation on battlefield. Usually should be true, except when the attack affects random targets (L_CHAIN for instance);
    • MAX_TARGTS (Numeric, size 1) specifies maximum number of targets that can be affected by attack. Used for AI rating calculations, and for damage ratio display formatting in unit encyclopedia;
    • MELEE (Logical) determines whether the attack considered as melee. Used by AI for unit hiring, positioning and targeting;
    • Consider adding vertical align to unit encyclopedia fields to properly accommodate custom attack reach text:
      • Find text constants with ids X005TA0787 and X005TA0788 in TApp.dbf and TAppEdit.dbf;
      • Note how attack name fields %TWICE%%ALTATTACK%%ATTACK%%SECOND% are enclosed in vertical align \p110; and \p0;;
      • Use the same technique to enclose %REACH% and %TARGETS% fields in X005TA0788 (like \p110;%REACH%\p0;);
      • Note that you can freely move content between X005TA0787 and X005TA0788 if you run out of length limit (because the two strings simply merged together in X005TA0424).

    Example descriptions for TARGET_TXT:

    X005TA1000 All adjacent units
    X005TA1001 The target and all units adjacent to it
    X005TA1002 The target and one unit adjacent to it
    X005TA1003 All units in the adjacent line
    X005TA1004 The target and the unit behind it
    X005TA1005 The target and the unit behind it
    X005TA1006 All units in the target line
    X005TA1007 All units in the target column
    X005TA1008 All units in 2x2 area
    X005TA1009 Randomly bounces to 2 additional targets
    X005TA1010 The target and one random unit
    

    Note that the REACH column is limited to 1 digit in GAttacks.dbf.
    This means that only 6 additional reaches (id 4-9) can be added by default.
    The limit can be lifted by extending the REACH column size to 2 digits (similar to CLASS).
    For example, using Sdbf: go to main manu Table > Change structure, set REACH size to 2 and hit save: image

  • Supports custom attack damage ratios for additional targets;

    The main purpose is to complement custom attack reaches.
    Allows to reduce or increase incoming damage for additional attack targets:

    • Add DAM_RATIO (Numeric, size 3), DR_REPEAT (Logical) and DAM_SPLIT (Logical) columns to Gattacks.dbf;
    • DAM_RATIO specifies a portion of the attack damage received by additional targets (0-255%). 100 or empty is the vanilla behavior;
    • DR_REPEAT specifies whether the DAM_RATIO should be applied for every consequent target;
    • DAM_SPLIT specifies whether the attack damage (QTY_DAM) is split between all the affected targets;
    • splitDamageMultiplier in settings.lua specifies multiplier for DAM_SPLIT damage for better late-game scaling (default of 300 max damage split among 6 targets is miserable);
    • Specify the following interface text ids in textids.lua:
      • ratedDamage
      • ratedDamageEqual
      • ratedDamageSeparator
      • splitDamage
    • Add the specified interface text to TApp.dbf and TAppEdit.dbf;
    • Consider adding vertical align to unit encyclopedia fields to properly accommodate damage ratio text:
      • Find text constants with ids X005TA0787 and X005TA0788 in TApp.dbf and TAppEdit.dbf;
      • Note how attack name fields %TWICE%%ALTATTACK%%ATTACK%%SECOND% are enclosed in vertical align \p110; and \p0;;
      • Use the same technique to enclose %DAMAGE% field in X005TA0788 (like \p110;%DAMAGE%\p0;);
      • Note that you can freely move content between X005TA0787 and X005TA0788 if you run out of length limit (because the two strings simply merged together in X005TA0424).

    image

    How DR_REPEAT works:

    • For instance, if QTY_DAM = 50 and DAM_RATIO = 20, then the first target receives 50, second - 10 (50 * 0,2), third - 2 (10 * 0,2) and so on.

    How DAM_SPLIT works:

    • For instance, if QTY_DAM = 100 and there are 3 affected targets, then every target will receive 33 damage;
    • DAM_RATIO and DR_REPEAT also apply, but determine a ratio between additional and first target damage. For instance, if QTY_DAM = 100, DAM_RATIO = 25 and there are 3 affected targets then the damage distribution will be 67-17-17 (67 * 0,25 ~ 17; 67 + 17 + 17 ~ 100).

    How splitDamageMultiplier works:

    • For instance, if the multiplier is 6 and unit attack damage is 300, then its final damage will be 300 * 6 = 1800;
    • Take the multiplier into account when picking base values for QTY_DAM in Gattacks.dbf along with DAMAGE in GDynUpgr.dbf;
    • The multiplied damage is correctly displayed in unit encyclopedia.
  • Supports custom unit modifiers;

    Demo video. Customizable via Lua scripting.
    Scripts/Modifiers includes example modifier scripts.
    template.lua contains a complete list of available functions.
    luaApi contains a complete script Api reference to help you create your own scripts.
    Note that Bestow Wards attack does not reset wards granted by custom modifiers (because the attack cannot predict the behavior of your custom script). Use standard modifiers for this purpose.

    • Add L_CUSTOM category to LModifS.dbf or simply copy the file from Examples;
    • Add SCRIPT (Character, size 40) column to Gmodif.dbf;
    • Add DESC_TXT (Character, size 10) column to Gmodif.dbf;
    • Add DISPLAY (Logical) column to Gmodif.dbf;
    • (Optional) Setup modifiers panel for Unit Encyclopedia:
      • Include LBOX_MODIFIERS and TXT_MODIFIERS elements to Interf.dlg and ScenEdit.dlg. Interf.dlg and ScenEdit.dlg contain examples of modified DLG_R_C_UNIT dialog of Unit Encyclopedia;
      • Note that the examples intentionally hide or reposition some native elements: 'Leader abilities', 'Leadership', 'Battles won', locked-unit / upgrade-needed indicators;
      • Try extending the dialog bounds or otherwise rearrange its elements to properly accomodate all the available elements as you like;
      • Specify the following interface text ids in textids.lua:
        • modifiersCaption
        • modifiersEmpty
        • modifierDescription
        • nativeModifierDescription
      • Add the specified interface text to TApp.dbf and TAppEdit.dbf.
    • (Optional) Add a new modifier description and icon (it will be displayed in Scenario Editor and Unit Encyclopedia):
      • Create a description in Tglobal.dbf. You can use rich formatting like \fMedBold;Born Leader\n\fSmall;+1 leadership every 3 levels.\fNormal;;
      • Create 31x36px icon in Icons.ff (using special software like D2ResExplorer). Its name should correspond to modifier id to be linked with it (similar to spell icons and other game resources), like G000UM9048;
    • Add a new modifier entry in Gmodif.dbf (see example Gmodif.dbf):
      • Specify new MODIF_ID (use format gXXXum9XXX if you want it to be available as Scenario Editor modifier);
      • Specify SOURCE id that corresponds to L_CUSTOM category added earlier (example LModifS.dbf uses 4 as the id);
      • Specify SCRIPT file name that will be used for this modifier (omit file path, for example berserk.lua);
      • (Optional) Specify DESC_TXT id that corresponds to Tglobal.dbf entry added earlier (defaults to the standard stub x000tg6000);
      • (Optional) Specify DISPLAY that controls whether the modifier should appear in modifiers panel for Unit Encyclopedia (defaults to false);
    • Refer to Scripts/Modifiers examples and luaApi to create your modifier script;
    • (Optional) Define dynamic display functions inside your modifier script to control its appearance on modifiers panel depending on a current unit:
      • Specify getModifierDisplay(unit, prev) function to enable or disable modifier display (defaults to DISPLAY in Gmodif.dbf);
      • Specify getModifierDescTxt(unit, prev) function to redefine modifier description (defaults to DESC_TXT in Gmodif.dbf);
      • Specify getModifierIconName(unit, prev) function to redefine modifier icon (defaults to MODIF_ID in Gmodif.dbf);
      • See template.lua for examples.
    • Try assigning the created modifier to item, potion or spell, or simply use it as Scenario Editor modifier;
    • Consider adding vertical align to unit encyclopedia fields to properly accommodate custom modifier bonuses text:
      • Find text constants with ids X005TA0787 and X005TA0788 in TApp.dbf and TAppEdit.dbf;
      • Note how attack name fields %TWICE%%ALTATTACK%%ATTACK%%SECOND% are enclosed in vertical align \p110; and \p0;;
      • Use the same technique to enclose %HIT%%HIT2% and %DAMAGE% fields (like \p110;%DAMAGE%\p0;);
      • Note that you can freely move content between X005TA0787 and X005TA0788 if you run out of length limit (because the two strings simply merged together in X005TA0424).

    image image image image image

  • Supports native unit modifiers;

    Allows to assign 'native' modifiers to unit types.
    That is, a modifier will be permanently applied to all units of the specified type - existing in a scenario or newly created / hired.
    When unit changes its type (transforms or upgrades), modifiers native to its previous type are automatically removed, and new modifiers that are native to the new type are applied.
    Native modifiers are not stored in scenario file, thus you can freely manipulate it without scenario file being affected in any way.

    • Copy GUmodif.dbf to 'Globals' directory;
    • UNIT_ID specifies id of a unit from GUnits.dbf. Use empty id (g000000000) if you want a modifier to be applied to every single unit, note it impacts performance so try to avoid this if its not necessary;
    • MODIF_1, MODIF_2, ..., MODIF_N specifies modifier id from Gmodif.dbf. In can be either standard or custom modifier.

Bug fixes:

  • Fixes game crash in battles with summoners involved;

  • Fixes game crash when AI controlled unit with transform self attack uses alternative attack with 'adjacent' attack range;

  • Fixes game crash on 144x144 maps that occurs if there is a party standing on a lower-left or lower-right edge of the map;

  • Fixes game crash in unit encyclopedia showing doppelganger info when it copied stack leader;

  • Fixes AI unit placement logic for melee units with vampiric attacks;

  • Fixes AI targeting for single lower-damage and lower-initiative attacks;

  • Fixes AI targeting for shatter attacks where it tends to pick a most armored target ignoring general prioritization;

  • Fixes AI targeting for shatter attacks where it assumes that armored targets always stay armored, even if their armor is already shattered;

  • Fixes AI targeting where it incorrectly calculates effective HP of armored targets, getting significantly lower values than intended;

    Enable fixEffectiveHpFormula in settings.lua.

  • Fixes incorrect function of transform-self attack in cases where its alternative attack targets allies (heal, summon, etc.);

  • Fixes an issue with transform-other attack where it selects melee vs ranged transform based on attacker position rather than on target position;

  • Removes persistent target highlighting for transform-self attack (circle animations for all possible targets on the ground), so it no longer interferes with highlighting for targets that are actually going to be affected by the attack;

  • Fixes missing modifiers of alternative attacks (demo video);

  • Fixes unit transformation (doppelganger, drain-level, transform-self/other attacks) to include HP modifiers into current hp recalculation, thus unit is not getting "damaged" upon transforming (demo video);

  • Fixes unit transformation (drain-level, transform-self/other and untransform-effect attacks) to update unit attack count for current battle round (for example, Holy Avenger transformed into Imp before its turn will no longer attack twice);

  • Fixes incorrect function of doppelganger attack where it uses alternative attack if the doppelganger is already transformed in any way (by doppelganger, drain-level or transform-self/other attacks);

  • Fixes bestow-wards attack bugs and restrictions;
    • Fixes wards (hereafter called "modifiers") becoming permanent when more than 8 of them are applied simultaneously;
    • Fixes modifiers becoming permanent after modified unit is transformed;
    • Fixes modifiers getting lost after modified unit is untransformed;
    • Fixes disappearing of modifiers applied on first attack of double attack;
    • Fixes attack source wards being reset incorrectly if its modifier also contains hp, regen or armor element;
    • Fixes attack class wards not being reset preventing it from being reapplied during battle;
    • Fixes incorrect handling of existing unit immunities;
    • Allows to apply modifiers even if there are no attack source wards among them;
    • Allows to target unit with a secondary attack even if there are no modifiers that can be applied;
    • Allows to heal and apply modifiers at once. Set QTY_HEAL > 0 in GAttacks.dbf and HEAL in GDynUpgr.dbf:
      • Allows to heal retreating allies by primary or secondary attack;
      • Allows to heal allies when battle ends, same as ordinary heal;
    • Allows to use revive as a secondary attack.
  • Fixes Scenario Editor bug with elves race as a caster in "Cast spell on location" event effect;

  • Fixes Scenario Editor to show spell cost information;

    Make sure the corresponding lines of DLG_R_C_SPELL in ScenEdit.dlg are changed as described below.

    Add 'X160TA0005' to fix elven mana name tooltip:

    IMAGE	IMG_BLUE,303,257,343,291,_RESOURCES_GREENM_B,"X160TA0005"
    

    Change resource names between IMG_JAUNE and IMG_ORANGE:

    IMAGE	IMG_JAUNE,163,257,203,291,_RESOURCES_BLACKM_B,"X100TA0098"
    IMAGE	IMG_ORANGE,28,257,68,291,_RESOURCES_BLUEM_B,"X100TA0096"
    
  • Fixes inability to 'Defend' as second attack if no other action except 'Instant resolve' and 'Auto battle' is available (the bug generally avoided by toggling 'Auto battle');

  • Fixes an issue with incomplete loading of scenario file causing some objects to be missing (if scenario contains too many objects, it caused in-game internal buffer to overflow over its limit of 512 KB);

  • Fixes rare crash while using drag'n'drop on inventory items if game server update arrives between mouse button press and release;

  • Fixes missing update of city encyclopedia popup dialog on visiting stack changes;

  • Fixes infamous crash in multiplayer games when observing other player's cities using encyclopedia popup dialog while the player performs unit reordering or summoning units in battle;

  • Fixes inability to use heal potion on transformed unit if its current hp is greater than maximum hp of unit it is transformed to (most common case is a unit transformed to Imp by a Witch while retaining his original hp);

  • Fixes crash on AI turn when it tries to exchange items and a source stack is destroyed in battle/event while moving to destination;

  • Fixes display of required buildings when multiple units have the same upgrade building;

  • Fixes stuck upgrades of foreign race mercenaries ('This unit is ready to upgrade but can not because it needs a building that is only accessible to the %RACE%'). It will now function as if 'Lock unit type' is applied;

  • Fixes errornous logic that allowed retreated units to upgrade under certain conditions. The behavior is now controllable via battle.allowRetreatedUnitsToUpgrade setting;

  • Fixes crash on scenario loading when level of any unit is below its template from GUnits.dbf, or above maximum level for generated units (restricted by total count of unit templates);

Scripting:

The toolset uses Lua for settings and advanced game mechanics. See luaApi for detailed information.

Tested on:

Disciples 2 Rise of the Elves v3.01 (Akella, Russobit, GOG).

Installation:

  • Rename original mss32.dll to mss23.dll;
  • Copy mss32.dll from this repository to game folder;
  • Copy Scripts folder to the game folder.

Deinstallation:

  • Delete mss32.dll;
  • Rename mss23.dll back to mss32.dll;
  • Delete Scripts folder from the game folder.

Versions prior 0.4:

Installation and deinstallation process is the same, but with binkw32.dll.

Building from sources:

Build Debug or Release Win32 target using Visual Studio solution located in mss32 folder.

License

Detours, GSL, fmt and sol2 submodules as well as Lua are using their own licenses.

This modification is not made or supported by Strategy First.
Disciples 2 is a trademark of Strategy First Inc.