Releases: armoha/euddraft
Releases · armoha/euddraft
euddraft 0.10.1.5
[0.10.1.5] - 2024.10.11
Changed
- Renamed
CUnit.set_noclip
/clear_noclip
(report by 고래밥은맛있어)
Added
StringBuffer
can be used as argument for format printing function (reported by Yuuki-Asuna)
Bugfix
- epScript: allow 0 as initial value for typed local variables
- Fix bug that caused QuickDebug map to be broken in euddraft 0.10.1.0-4 (reported by 블라인드)
- Fix compilation error in member comparison condition of variable scdata instance (reported by furina)
- Fix RecursionError
Improved
- In cp read function, combine action of adding non-zero cpoffset to function call trigger
euddraft 0.10.1.4
[0.10.1.4] - 2024.10.09
Bugfix
- Fixed bug where some triggers wouldn't execute after 4,294,967,295 game ticks (2,087 days in Fastest game), or after setting 0x57F23C to -1 (reported by snoqqqq)
Improved
- Improve error message for format print functions when placeholders are more than arguments (reported by Yuuki-Asuna)
euddraft 0.10.1.3
Changed
- Remove unused issueError parameter in Encode functions
scdata.flags.Flag = X;
only takestrue
,false
,1
,0
orEUDVariable
Added
-
Add literal type hints for basic triggers, scdata and
EUDLoopPlayer
-
scdata: add
ButtonSetMember
, changeCUnit.currentButtonSet
to ButtonSet type
Bugfix
- Fixed
TrgUnit.rank
from word to byte - Fixed compilation error in
EUDJump(variable)
(reported by 공나물) - Fixed build error with input map missing
(listfile)
(reported by 귀여미)
Improved
- Remove '[Warning]' text in front of type errors
- Add simple MPQ protection
euddraft 0.10.1.1
[0.10.1.1] - 2024.10.02
Bugfix
- Fixed compilation error when turning off [freeze] protection
Improved
- Update Korean localization
euddraft 0.10.1.0
Changelog
[0.10.1.0] - 2024.09.30
Changed
- Rewrite
mpqapi
in Rust, change usage ofMPQ
class:
# Instantiate MPQs
mpq = MPQ.open(MPQpath) # Open an MPQ
mpq = MPQ.create(create_path, sector_size=3, file_count=1024) # create MPQ
# *advanced* Create an MPQ with the same content with a new sector_size
mpq = MPQ.clone_with_sector_size(MPQpath, create_path, sector_size)
# Read the MPQ internal file
file_content: bytes = mpq.extract_file(filepath) # extract file from MPQ
# Get file names from (listfile)
filenames: list[str] = mpq.get_file_names_from_listfile()
# Add files to MPQ
mpq.add_file(name_to_use_in_MPQ, path_of_file_to_be_added, replace_existing=True)
# get/change the maximum number of files limit
maximum_number_of_files: int = mpq.get_max_file_count()
mpq.set_max_file_count(new_file_count_limit)
mpq.compact() # defragment / compress MPQ
- Changed
MPQAddFile
to also accept the path of file to be added:MPQAddFile(name_to_use_in_MPQ, file_path_or_file_content)
BecauseStormLib
requires a file system path, it is more advantageous to enter a file path. Entering the file contents as in the old usage creates a temporary file and passes the temporary file location toStormLib
, with the overhead of copying the file contents.
Bugfix
- epScript:
var globalVariable = constant_initial_value;
created an empty trigger scope, causing aRecursionError
when there are at least 327 of these global variables (reported by snoqqqq) - Fix autoupdate to not leave old files behind
Improved
- Replace setuptools with maturin in eudplib packaging, make it easy to build eudplib
- Optimized
CUnit.check_buildq
- Optimized
LoadMap
- Optimized number of eudplib initialisation triggers
euddraft 0.10.0.2
Changelog
[0.10.0.2] - 2024.09.26
Bugfix
- Fixed bug in fixed line print functions;
StringBuffer.printfAt
,DisplayTextAt
, etc. (reported by 고래밥은맛있어, 맛있는건못참아) - scdata: Fix compilation error in 2 byte member
+=
(reported by 텔) - Fix compilation error in
f_epdread_cp
function (reported by 맛있는건못참아) - Fix compilation error when assigning 0 to
CUnit
variable (reported by @Chromowolf) - Fix
f_rand
returned 0 (reported by @Chromowolf)
Improved
- Add stack trace to warning messages (reported by 콤)
- Optimized the number of triggers in
EUDByteReader.readbyte()
,f_raise_CCMU()
,f_getcurpl()
euddraft 0.10.0.1
Changelog
[0.10.0.1] - 2024.09.23
Bugfix
- [MSQC] Fix mouse button event compilation error (reported by 텔)
- Bugfix:
DisplayTextAt
,DisplayTextAllAt
compilation error fixed (reported by @Dr-zzt) - Fixed bug with Korean translation text not showing up
Improved
- Optimize
f_rand()
function and fix to not change CurrentPlayer - Added error message for invalid arguments when creating
EUDVariable
,EUDXVariable
,EUDVArray
euddraft 0.10.0.0
Changelog
[0.10.0.0] - 2024.09.22
Changed
EUDArray
now uses EPD by default- For backward compatibility with existing code,
EPD(EPD of ConstExpr)
returns EPD as is (with warning message) - Added
ptrEUDArray
anderrorReapplyEPD
flags to[main]
[main] ptrEUDArray : True errorReapplyEPD : True :: If the `ptrEUDArray` flag is turned on, EUDArray will use the ptr address as before :: If the `errorReapplyEPD` flag is turned on, applying the EPD function to a constant EPD value will result in an error
- If the
ptrEUDArray
flag is on, EPD is not calculated when array is only used in passing to or from function boundaries. When array element is accessed, EPD calculation trigger is added at array declaration on demand.
- For backward compatibility with existing code,
- epScript: Added type variable feature.
- Reference types (
EUDArray
,EUDVArray
, epScriptobject
(=EUDStruct
),EUDStructArray
,CUnit
,CSprite
) can only be assigned to the same type. Operations such as+=,
-=,
*=,
/=
are not supported because they can change to invalid addresses. - Value types (such as
LocalLocale
,TrgUnit
,Weapon
,UnitOrder
,Flingy
,Sprite
,Image
,TrgPlayer
,Upgrade
,Tech
, etc.) supports assigment and other operations like+=
,-=
, ...
- Reference types (
// Syntax
var name: Type = initialValue;
static var name: Type = initialValue;
var name1: type1, name2: type2, name3: type3 = initial1, initial2, initial3;
// Example
function onPluginStart() {
// Link hatchery to larvae
var hatchery: CUnit = 0;
foreach(unit : EUDLoopPlayerCUnit()) {
if (unit.unitType == "Zerg Hatchery") {
hatchery = unit;
}
}
foreach(unit : EUDLoopPlayerCUnit()) {
if (unit.unitType == "Zerg Larva") {
larva.connectedUnit = hatchery;
}
}
}
- epScript: Relative Path Import Bug Fixes and Behavior Changes
- Fixed a bug that caused modules to be duplicated every time a relative path import was made.
- If a path can be imported with an absolute path, it will be replaced with an absolute path import.
- Consider making the path accessible with
sys.path.insert(1, path)
when a parent folder prevents importing, or consider adding__init__.py
when importing between files inside a folder to be recognized as a Python package.
- Changed behavior of epScript
object
(=EUDMethod
ofEUDStruct
) to not duplicate triggers for each static instance they call - Change cast behavior: don't copy the value, just use it as is and apply the type.
- Simplified
EUDVariable
constructor:EUDVariable
now only accepts an initial value as a constructor.- For advanced initialization options, use
EUDXVariable(epd, modifier, initial value, (optional) bitmask 0xFFFFFFFF by default)
.
- For advanced initialization options, use
- Fix
f_getuserplayerid()
andEUDLoopPlayer
to returnTrgPlayer
type - Change
DBString
memory layout Db
initialized with"string"
will raise error if string has a null byte in the middleDBString
will raise error with a \0 null byte in the middleobjFieldN
flag won't change the maximum number of objects (=32768)
Added
EUDVArray
supports epScriptforeach
loop
const varr = EUDVArray(10)(py_range(10));
foreach(x : varr) {
printAll("{}", x);
if (x >= 5) break;
}
// prints: 0, 1, 2, 3, 4, 5
- scdata: Added current upgrade/tech level read/write
- Optimized to cache epd and subp for upgrade/tech and player, so that if they are unchanged or only change them with
+= 1
, epd and subp are not recalculated, and instead reuse the previously calculated results. (See Improved section)
- Optimized to cache epd and subp for upgrade/tech and player, so that if they are unchanged or only change them with
// Upgrade[TrgPlayer] = New_Upgrade_Level;
const infantryWeapon = Upgrade("Terran Infantry Weapon");
foreach(player : EUDLoopPlayer()) {
infantryWeapon[player] = 1;
}
// const upgrade_level = Upgrade[TrgPlayer];
printAll("current Terran Infantry Weapon level for P1: {}", infantryWeapon[player]);
// Tech[TrgPlayer] = new Tech level;
var spiderMines: Tech = "Spider Mines";
spiderMines[P1] = 1;
// const hasResearched = Tech[TrgPlayer]; // return 1 if tech is non-zero
once (Tech("Stim Pack")[P1]) {
printAll("Red researched stim pack.");
}
- scdata: Added
TrgUnit
members:TrgUnit.unitBoundsLT
TrgUnit.unitBoundsRB
TrgUnit.unitBoundsL
TrgUnit.unitBoundsT
TrgUnit.unitBoundsR
TrgUnit.unitBoundsB
- Added
UnitGroup.length
(suggested by 쥬뱅) EUDLightBool
can be initialized withTrue
(suggested by @Chromowolf)- Added
suppressWarnings
flag on[main]
(suggested by Ultraviolet)- This suppresses every warnings in Python
- EUD Editor 2 has longstanding issue of not distinguishing warning and error. You can workaround this issue with
suppressWarnings
flag.
- Added simple obfuscation to constant strings for print functions
Bugfix
- Fixed
<
,>
forEUDVariable
(reported by 고래밥은맛있어) - epScript: fixed incorrect line number on error (reported by @Chromowolf)
- (armoha/eudplib#28) fixed infinite loop in
EUDLoopRange(start, end)
whenstart == end
(contributed by 고래밥은맛있어) - Fixed constant CUnit instance e.g.
CUnit(EPD(0x59CCA8))
- Fixed
EUDStruct.cast
could returnNone
when subclass overrides__init__
without_from
parameter - Fixed bug where Python warning messages were not printed
- Fixed bugs with
CUnit(constant)
,CSprite.from_ptr (constant)
Improved
- Improved epd and cp read functions to share their triggers
- Performance improvements for
EUDVArray
,PVariable
,f_repmovsd_epd
, etc. - Fixed
$L
andsetloc_epd
to also warn of location name misspellings - Added compilation error when string count exceeds 65535
- Improved
ConstExpr
division compile error message - scdata: Improved error message for
UnsupportedMember
- scdata: added caching to improve performance with ArrayMember
- When accessing a non-4-byte member, if the variable is unchanged, it will reuse the previously calculated result instead of recalculating epd, subp.
scdataInstance += 1;
is specialized to update all cache values, so cache invalidation and recalculation does not occur.
var unit: TrgUnit = dwrand() % 228;
// (1)
unit.maxShield = 10000;
unit.elevation = 1;
unit = dwrand() % 228;
// (2)
unit.maxHp = 10000 * 256;
// (3)
unit.hasShield = false;
/*
ArrayMember of the scdata instance wrapping EUDVariable will cache derived values for members whose stride is not 4 bytes.
All non-4-byte-stride member accesses will perform a cache check condition and update derived values if the value has changed.
Because unit uses 1-byte (elevation, hasShield) and 2-byte (maxShield) members, the cache check condition detects a value change at (1), and every derived values are updated; unit / 4, unit % 4, unit / 2 and 2*(unit % 2).
(member usages affect globally to every usages, even retroactively)
`var unit` is unchanged between unit.maxShield and unit.elevation, so unit.elevation does not run update for derived values.
`unit`'s value has changed at (2) ,but unit.maxHp is a 4-byte member, so it does not run perform a cache check condition.
unit.hasShield access at (3) will perform a cache check condition and may update derived values.
*/
// The cache is associated with the wrapped variable, not the scdata instance.
// If cast interprets the same variable as multiple types, the bitmask range can be extended by the largest type.
var v = 23; // 0x17
const p = TrgPlayer.cast(v);
P12.cummulativeMineral = 9999;
// TrgPlayer's bitmask is 0xF
// If that's all we've written, we'll print out the cumulative gas for P8 (playerID=7)
printAll("{}", p.cumulativeGas);
// If we cast variable v to a TrgUnit, and access a non-4-byte-stride member,
// the bitmask of variable v is expanded from 0xF (TrgPlayer) to 0xFF (TrgUnit) globally:
const u = TrgUnit.cast(v);
printAll(u.gasCost, 200);
// This acts globally, so,
// The above printAll("{}", p.cumulativeGas); will print 9999,
// which is P24's cumulative gas = P12's cumulative minerals.
- Miscellaneous bug fixes and improvements
euddraft 0.9.11.2
[0.9.11.2] - 2024.09.07
Changed
- [MSQC] local condition and
val
syntax allow not onlyEUDVariable
,EUDXVariable
, ``EUDLightVariable, EUDLightBool
but any object registered by `EUDRegisterObjectToNamespace` (suggested by 고래밥은맛있어)
Bugfix
- Bugfix: `CUnit/CSprite.from_ptr(ptr)' returns old value when ptr is 0 (reported by @Dr-zzt)
- Fixed bug with CUnit/CSprite not caching ptr/epd
Improved
- Change
f_getuserplayerid
andEUDLoopPlayer
to returnTrgPlayer
.- Considering that in the future
f_getuserplayerid
will return a subclass ofTrgPlayer
and provide local/desync offsets as members
- Considering that in the future
- eudplib 0.77.9 update
- Updated Korean translation files
euddraft 0.9.11.1
[0.9.11.1] - 2024.09.04
Changed
- Update known features in scdata (contributed by DarkenedFantasies)
- CSprite.flags.Flag4 (0x10) ->
CSprite.flags.IsSubunit
: sorts sprite elevation higher, so that subunits always appear above base unit - CSprite.unknown0x12 ->
CSprite.grpWidth
- CSprite.unknown0x13 ->
CSprite.grpHeight
- CUnit/TrgUnit.movementFlags.Unknown ->
CUnit/TrgUnit.movementFlags.BrakeOnPathStep
: unit decelerates when reaching the end of current path segment - CUnit.ghostNukeMissile ->
CUnit.ghostNukeDot
: points to CThingy of nuclear dot - TrgUnit.AIFlags ->
TrgUnit.dontBecomeGuard
- Tech.requirementOffset ->
Tech.researchRequirementOffset
,Tech.techUseRequirementOffset
- CSprite.flags.Flag4 (0x10) ->
Added
- Added multi-dimensional object array, added bound check for object array (suggested by 고래밥은맛있어)
// epScript example)
object Point { var x, y; };
function onPluginStart() {
const point2x3 = (Point * 3 * 2)();
// static allocation of objects
foreach(i : py_range(2)) {
point2x3[i] = (Point * 3)();
foreach(j : py_range(3)) {
point2x3[i][j] = Point()
}
}
point2x3[2]; // index out of bound error
point2x3[0][3]; // index out of bound error
}
- Added scdata members
TrgPlayer.unitColor
TrgPlayer.minimapColor
TrgPlayer.remainingGamePause
TrgPlayer.missionObjectives
TrgPlayer.unitScore
TrgPlayer.buildingScore
TrgPlayer.killScore
TrgPlayer.razingScore
TrgPlayer.customScore
- Added scdata flag members
CUnit.pathingFlags
CUnit.pathingFlags.HasCollision
(0x01)CUnit.pathingFlags.IsStacked
(0x02)CUnit.pathingFlags.Decollide
(0x04)
TrgUnit.groupFlags
TrgUnit.groupFlags.Zerg
(0x01)TrgUnit.groupFlags.Terran
(0x02)TrgUnit.groupFlags.Protoss
(0x04)TrgUnit.groupFlags.Men
(0x08)TrgUnit.groupFlags.Building
(0x10)TrgUnit.groupFlags.Factory
(0x20)TrgUnit.groupFlags.Independent
(0x40)TrgUnit.groupFlags.Neutral
(0x80)
TrgUnit.movementFlags
: Same asCUnit.movementFlags
.TrgUnit.movementFlags.OrderedAtLeastOnce
(0x01)TrgUnit.movementFlags.Accelerating
(0x02)TrgUnit.movementFlags.Braking
(0x04)TrgUnit.movementFlags.StartingAttack
(0x08)TrgUnit.movementFlags.Moving
(0x10)TrgUnit.movementFlags.Lifted
(0x20)TrgUnit.movementFlags.Unknown
(0x40)TrgUnit.movementFlags.AlwaysZero
(0x80)TrgUnit.movementFlags.HoverUnit
(0xC1)
TrgUnit.baseProperty
TrgUnit.baseProperty.Building
(0x00000001)TrgUnit.baseProperty.Addon
(0x00000002)TrgUnit.baseProperty.Flyer
(0x00000004)TrgUnit.baseProperty.Worker
(0x00000008)TrgUnit.baseProperty.Subunit
(0x00000010)TrgUnit.baseProperty.FlyingBuilding
(0x00000020)TrgUnit.baseProperty.Hero
(0x00000040)TrgUnit.baseProperty.RegeneratesHp
(0x00000080)TrgUnit.baseProperty.AnimatedIdle
(0x00000100)TrgUnit.baseProperty.Cloakable
(0x00000200)TrgUnit.baseProperty.TwoUnitsInOneEgg
(0x00000400)TrgUnit.baseProperty.SingleEntity
(0x00000800): prevent multiple selections, checked for all Powerups units.TrgUnit.baseProperty.ResourceDepot
(0x00001000): Where to return resourcesTrgUnit.baseProperty.ResourceContainer
(0x00002000)TrgUnit.baseProperty.Robotic
(0x00004000)TrgUnit.baseProperty.Detector
(0x00008000)TrgUnit.baseProperty.Organic
(0x00010000)TrgUnit.baseProperty.RequiresCreep
(0x00020000)TrgUnit.baseProperty.Unused
(0x00040000)TrgUnit.baseProperty.RequiresPsi
(0x00080000)TrgUnit.baseProperty.Burrowable
(0x00100000)TrgUnit.baseProperty.Spellcaster
(0x00200000)TrgUnit.baseProperty.PermanentCloak
(0x00400000)TrgUnit.baseProperty.PickupItem
(0x00800000): Checked for units that can be held like powerupsTrgUnit.baseProperty.IgnoresSupplyCheck
(0x01000000)TrgUnit.baseProperty.MediumOverlay
(0x02000000): related to spell effect overlay sizeTrgUnit.baseProperty.LargeOverlay
(0x04000000)TrgUnit.baseProperty.AutoAttackAndMove
(0x08000000)TrgUnit.baseProperty.CanAttack
(0x10000000)TrgUnit.baseProperty.Invincible
(0x20000000)TrgUnit.baseProperty.Mechanical
(0x40000000)TrgUnit.baseProperty.ProducesUnits
(0x80000000)
TrgUnit.availabilityFlags
TrgUnit.availabilityFlags.NonNeutral
(0x001)TrgUnit.availabilityFlags.UnitListing
(0x002): be able to be created with CreateUnit actionTrgUnit.availabilityFlags.MissionBriefing
(0x004)TrgUnit.availabilityFlags.PlayerSettings
(0x008)TrgUnit.availabilityFlags.AllRaces
(0x010)TrgUnit.availabilityFlags.SetDoodadState
(0x020)TrgUnit.availabilityFlags.NonLocationTriggers
(0x040)TrgUnit.availabilityFlags.UnitHeroSettings
(0x080)TrgUnit.availabilityFlags.LocationTriggers
(0x100)TrgUnit.availabilityFlags.BroodWarOnly
(0x200)
Weapon.targetFlags
Weapon.targetFlags.Air
(0x001)Weapon.targetFlags.Ground
(0x002)Weapon.targetFlags.Mechanical
(0x004)Weapon.targetFlags.Organic
(0x008)Weapon.targetFlags.NonBuilding
(0x010)Weapon.targetFlags.NonRobotic
(0x020)Weapon.targetFlags.Terrain
(0x040)Weapon.targetFlags.OrganicOrMechanical
(0x080)Weapon.targetFlags.PlayerOwned
(0x100): Can target only your own units, like a defiler's consume
- Added scdata enum members
CUnit.resourceType
= "None", "Gas", "Ore", "GasOrOre", "PowerUp"
What the worker is carryingTrgUnit.nameString
= "string"TrgUnit.rank
= "Rank name" see link for a list of ranksTrgUnit.readySound/whatSoundStart/whatSoundEnd/pissedSoundStart/pissedSoundEnd/yesSoundStart/yesSoundEnd
= sfxdata.dat StarCraft sound effects file path (case insensitive, both '/' and '' are allowed as separators)TrgUnit.sizeType
= "Independent", "Small", "Medium", "Large"TrgUnit.rightClickAction
= "NoCommand_AutoAttack", "NormalMove_NormalAttack", "NormalMove_NoAttack", "NoMove_NormalAttack", "Harvest", "HarvestAndRepair", "Nothing"Flingy.movementControl
= "FlingyDat", "PartiallyMobile_Weapon", "IscriptBin"Weapon.damageType
= "Independent", "Explosive", "Concussive", "Normal", "IgnoreArmor"Weapon.explosionType
= "None", "NormalHit", "SplashRadial", "SplashEnemy", "Lockdown", "NuclearMissile", "Parasite", "Broodlings", "EmpShockwave", "Irradiate", "Ensnare", "Plague", "StasisField", "DarkSwarm", "Consume", "YamatoGun", "Restoration", "DisruptionWeb", "CorrosiveAcid", "MindControl", "Feedback", "OpticalFlare", "Maelstrom", "Unknown_Crash", "SplashAir"weapon.behavior
= "Fly_DoNotFollowTarget", "Fly_FollowTarget", "AppearOnTargetUnit", "PersistOnTargetSite", "AppearOnTargetSite", "AppearOnAttacker", "AttackAndSelfDestruct", "Bounce", "AttackNearbyArea", "GoToMaxRange"Tech/Upgrade.race
= "Zerg", "Terran", "Protoss", "All"Image.drawingFunction
= "Normal", "NormalNoHallucination", "NonVisionCloaking", "NonVisionCloaked", "NonVisionDecloaking", "VisionCloaking", "VisionCloaked", "VisionDecloaking", "EMPShockwave", "UseRemapping", "Shadow", "HpBar", "WarpTexture", "SelectionCircle", "PlayerColorOverride", "HideGFX_ShowSizeRect", "Hallucination", "WarpFlash"UnitOrder.animation
= "Init", "Death", "GndAttkInit", "AirAttkInit", "Unused1", "GndAttkRpt", "AirAttkRpt", "CastSpell", "GndAttkToIdle", "AirAttkToIdle", "Unused2", "Walking", "WalkingToIdle", "SpecialState1", "SpecialState2", "AlmostBuilt", "Built", "Landing", "LiftOff", "IsWorking", "WorkingToIdle", "WarpIn", "Unused3", "StarEditInit", "Disable", "Burrow", "UnBurrow", "Enable", "NoAnimation"
- offsetmap: add an optional
stride
argument to the constructor ofArrayMember
- Example 1) Define
TrgUnit.constructionGraphic
asconstructionGraphic = ArrayMember(0x6610B0, MemberKind.IMAGE, stride=4)
because it is of typeImage
but the stride is 4 bytes. - Example 2)
TrgPlayer.unitColor
is 1 byte in size, but the gap is 8 bytes, so we define it asunitColor = ArrayMember(0x581D76, MemberKind.BYTE, stride=8)
.
- Example 1) Define
- offsetmap: add
ArrayEnumMember
Bugfix
- Fix
{:c}
,{:n}
(PColor
,PName
) compilation error (reported by spin137) - Fix compilation error in
DisplayTextAll
,DisplayTextAllAt
functions (reported by @Dr-zzt) - Fix size, offset errors in scdata (reported by DarkenedFantasies)
CUnit.gatherQueueCount
: size -> boolCUnit.isUnderStorm
: size -> boolCUnit.resourceBelongsToAI
: size -> boolTrgUnit.constructionGraphic
: size -> dwordWeapon.targetFlags
: size -> wordWeapon.maxRange
: offset -> 0x657470Weapon.cooldown
: offset -> 0x656FB8Upgrade.mineralCostBase
: offset -> 0x655740
- scdata uses more specific types (reported by DarkenedFantasies)
TrgUnit.constructionGraphic
: ImageTrgUnit.armorUpgrade
: UpgradeTrgUnit.portrait
: PortraitTrgUnit.nameString
: TrgStringWeapon.label
: StatTextWeapon.icon
: iconWeapon.upgrade
: UpgradeWeapon.targetErrorMessage
: StatTextUpgrade.label
: StatTextUpgrade.icon
: iconUnitOrder.icon
: IconUnitOrder.weapon
: WeaponUnitOrder.techUsed
: TechUnitOrder.obscuredOrder
: UnitOrder
Improved
- Improved error message for invalid input when creating
CUnit
,CSprite