Thread Rating:
  • 2 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Random factoids about YR
#1
In no particular order, I'm going to post random things I find in the executable that may not be documented already. Comments welcome, so are inquiries. And if anyone wants to post this stuff on appropriate ModEnc pages, go ahead.
  • AI
    • ScriptTypes
      • A ScriptType only loads 50 first actions and ignores the rest.
      • Unlike most objects, it does care about the indices on the left, meaning it loads actions from 0= to 49= .
      • Script Actions 53 and 54 (Gather and Regroup) use [General]->RelaxedStray as their allowed stray distance, the rest use [General]->Stray .
    • TaskForces
      • A TaskForce only loads 6 first types of objects and ignores the rest.
      • Unlike most objects, it does care about the indices on the left, meaning it loads actions from 0= to 5= .
      • Contrary to what DZ says, BuildingTypes are not valid entries. That makes sense, of course.
    • AITriggerTypes
      • The so called "Unknown flag" is a dud. It's read from the file, but discarded and always set to 0.
      • TechLevel is read from the file, but discarded and internally recalculated by finding the max TechLevel from the units in both TaskForces associated with this AITriggerType.
      • The long string of mostly zeroes is interpreted as 32 bytes or 8 dwords packed into ASCII hex (there's room for four pairs of "compareArgument,comparator"). I haven't yet located anything else about this, but it doesn't seem the latter ones are actually used, meaning multi-conditional triggers would be unfortunately impossible.
  • Maps
    • Triggers
      • "Repeating" flag does not make any distinction like the older games did (see ModEnc Maps/Triggers for more info), it either repeats or doesn't.
    • Events & Actions
      • Events and Actions of a particular Trigger are listed in a comma-separated string in their respective section. The game reads only the first 512 characters of this string, so you should not exceed that. If you need more, use Attached Trigger feature on that particular Trigger.
      • Unlike TaskForces/ScriptTypes, there is no hard limit to how many Events or Actions can be attached to a single Trigger.
    • Events
      • Event arguments
        • INI format is "eventId=countEvents,listOfEvents", where listOfEvents is a comma-separated list of "eventType,arg1,arg2" and optional ",arg3".
          • The first argument, arg1, describes the kind of data arg2 and arg3 hold:
            • arg1 == 0: arg2 is a number, arg3 is not present.
            • arg1 == 1: arg2 is a string, arg3 is not present.
            • arg1 == 2: arg2 is a number, arg3 is a string.
          • The second argument, arg2, is the actual condition.
            • If it's a number, it's treated like one or as an index into the [Houses] list, depending on the event type.
            • If it's a string, it's a reference to a TeamType and can state either its ID("AF3456BH-G"), or its Name=, provided it has no commas.
          • The third argument, arg3, is only parsed if arg1 is 2. It is always treated as an object's ID and as such truncated to 24 characters.
      • Actions
        • Action arguments
          • INI format is "actionId=countActions,listOfActions", where listOfActions is a comma-separated list of "actionType,arg1,arg2,arg3,arg4,arg5,arg6,arg7".
          • The first argument, arg1, describes the kind of data arg2 and arg7 hold:
            • arg2
              • arg1 == 0: arg2 is a number.
              • arg1 == 1: arg2 is a reference to a TeamType.
              • arg1 == 2: arg2 is a reference to a TriggerType.
              • arg1 == 3: arg2 is a reference to a Tag.
              • arg1 == 4: arg2 is a simple string.
              • arg1 == 5: arg2 is a reference to a TeamType (again).
              • arg1 == 6: arg2 is an reference to an entry in [DialogList] (evamd.ini).
              • arg1 == 7: arg2 is an reference to an entry in [SoundList] (soundmd.ini).
              • arg1 == 8: arg2 is a reference to an entry in [Themes] (thememd.ini).
              • arg1 == 9: arg2 is a simple string (again).
              • arg1 == 10: arg2 is a string.
              • arg1 == 11: arg2 is a number (again).
            • arg7
              • arg1 == 5: arg7 is a number.
              • arg1 == 9: arg7 is a number.
              • arg1 == 11: arg7 is a number.
              • otherwise: arg7 is a waypoint's textual representation.
          • The second argument, arg2, is the actual argument.
            • If it's referring to a TeamType, TriggerType or a TagType, it is interpreted in two ways:
              • if arg2 is longer than four characters, it's treated as an ID ("ACH385-G").
              • otherwise it's treated as an index into the [TeamTypes]/[Triggers]/[Tags] list.
          • The third argument, arg3, is mostly unused, and always interpreted as a number.
          • The fourth argument, arg4, is mostly unused, and always interpreted as a number.
          • The fifth argument, arg5, is mostly unused, and always interpreted as a number.
          • The sixth argument, arg6, is mostly unused, and always interpreted as a number.
          • The seventh argument, arg7, is mostly used to refer to a waypoint that's the target of this action, but in certain cases it's a simple number that's an additional parameter for the action. Depends on the action type.
        • Specific Action data
          • Action 4 - Create Team: Obeys the TeamType's Max= setting.
          • Action 7 - Reinforcement: Creates the TeamType regardless of any restrictions.
          • Action 42 - Do Explosion At: Actually fires a weapon whose index is given as a param, not a warhead.
          • Action 43 - Meteor Impact At: Seems to actually be a "Spawn Voxel Anim At".
          • Action 44 - Ion Storm Start: Seems to now do the same as "Lightning Storm Start".
          • Action 45 - Ion Storm Stop: Doesn't defer functionality to Lighting Storm, seemingly just clears some internal flag, possibly one that tracks whether an Ion Storm is active.
          • Action 58 - Meteor Shower At: Uses a complex system to work out how many meteors to spawn. See appendix A.
          • Action 63 - Apply 100 Damage At: Detonates [CombatDamage]->C4Warhead with Damage=100 at the specified waypoint.
          • Actions 64 - 66 - (Small|Medium|Large) Light Flash: Pretends to detonate [CombatDamage]->C4Warhead with Damage=(50|100|300) respectively at the specified waypoint, and uses its Bright/CombatLightSize settings to create the flash. No damage is actually dealt as far as I can tell.
          • Action 80 - Reinforcement: If [TeamType]->Droppod=yes , then the team is paradropped in by a [PDPLANE]. If possible, the team's script is appended with action 5,0 (Guard Area).
          • Action 95 - Trigger Nuke Strike: Fires [NukePayload] at the specified waypoint.
          • Action 96 - Fire Chemical Missile: Fires [ChemLauncher] at the specified waypoint. (Doesn't work by default since ChemLauncher is not registered by any object or Weedguy-hack.)
          • Action 107 - Reinforcement By Chrono: If possible, the team's script is appended with action 5,0 (Guard Area).
    • Tubes
      • A Tube stops reading directions once it has read 99 directions or has found a direction "-1".
      • There is no apparent limit of how many tubes a map can contain, but if multiple tubes start at one cell, only the latest one will be actually functional.
    • Map variables
      • A map can contain up to a 100 local variables (Map's [VariableNames]).
      • A map can contain up to a 50 global variables (Rules [VariableNames]).
    • Houses
      • BaseNodes
        • A base node can refer to a BuildingType either by its ID or by prefixing its index in the BuildingTypes array with a '-' (minus). The game doesn't drop the '-' away though, so there might be alternative handling involved in this case - needs more testing.
  • Objects
    • Common (all INI-loadable types)
      • Name= is truncated to 23 characters. So is the ID.
    • Common (InfantryTypes, VehicleTypes, AircraftTypes, BuildingTypes)
      • VeteranAbilities= and EliteAbilities= indeed do not stack, as Vinifera7 correctly noted a while ago. However, they do complement each other - when elite, the unit is granted both EliteAbilities and VeteranAbilities, but they are toggles - either "has this ability" or "doesn't have this ability", not "has one level of this or two".
      • It seems that setting MobileFire=yes on a unit aloows it to ignore its ammo reload time. (Needs more testing.)
    • [Powerups]
      • Powerup-specific data:
        • Explosion - uses warhead from [CombatDamage]->C4Warhead.
        • Napalm - uses warhead from [CombatDamage]->FlameDamage.
        • Squad - activates Money.
        • Armor - if this unit has already picked up an Armor crate, activates Money.
        • Speed - if this unit has already picked up a Speed crate, activates Money.
        • Firepower - if this unit has already picked up a Firepower crate, activates Money.
        • ICBM - gives you one shot of the first entry from the [SuperWeaponTypes] which has Type=Nuke.
        • Invulnerability - activates Money.
        • IonStorm - activates Money.
        • Gas - uses a warhead [GAS] (case-insensitive).
        • Pod - activates Money.
        • Tiberium - randomizes the type of tiberium as well as its amount.
    • Animations
      • Adding a valid ExpireAnim= makes the Warhead= and related data work correctly like on debris.


Appendix A: Meteor Shower.
QuantityOfMeteors = MainIntensity + RandomIntensity - 1

Where:
RandomIntensity is a random integer [0..2]
MainIntensity depends on the action's param:
The action's param can be an integer in range [0..4], this corresponds to an array of numbers:
0 - 1 meteor.
1 - 5 meteors.
2 - 9 meteors.
3 - 15 meteors.
4 - 0 meteors.
The spread of the targeted area is also proportional to MainIntensity.
(Technically you can pass different numbers, since it's just indices into memory, but most of the time you will hit huge numbers as a result.)

For each meteor, a random number is picked, if it's even, the meteor will be METSMALL, otherwise, it will be METLARGE.

Worth playing: 1 | 2 | 3
Reply
#2
For "Do Explosion At", how would you easily calculate the index of a weapon to use since there is no list to initialise them so I assume the array gets built on the order they appear on units.
Reply
#3
Heh, nice info DC. Looking forward to seeing more Wink
Reply
#4
Special for Blade: Map load order:
  • LoadWaypoints()
  • Rules -> [Countries]
  • Rules -> [General]
  • ProgressBar_Update(3)
  • Theater_Init();
  • ProgressBar_Update(30)
  • UI -> [Advanced(Multiplayer)?CommandBar]
  • ProgressBar_Update(31)
  • Rules -> loadMisc()
  • ProgressBar_Update(35)
  • LoadGlobalAndLocalVariables()
  • Load main rules data
    • [Colors]
    • [ColorAdd]
    • [Countries]
    • [Sides]
    • Read the sections and prepare to load their data:
      • [OverlayTypes]
      • [SuperWeaponTypes]
      • [Warheads]
      • [SmudgeTypes]
      • [TerrainTypes]
      • [BuildingTypes]
      • [VehicleTypes]
      • [AircraftTypes]
      • [InfantryTypes]
      • [Animations]
      • [VoxelAnims]
      • [Particles]
      • [ParticleSystems]
    • [JumpjetControls]
    • [MultiplayerDialogSettings]
    • [AI]
    • [Powerups]
    • [LandCharacteristics]
    • [IQ]
    • [General]
    • Load data types for sections
      • [Countries]
      • [SuperWeaponTypes]
      • [AnimTypes]
      • [BuildingTypes]
      • [AircraftTypes]
      • [UnitTypes]
      • [InfantryTypes]
      • [WeaponTypes]
      • [ProjectileTypes]
      • [WarheadTypes]
      • [BuildingTypes]
      • [TerrainTypes]
      • [SmudgeTypes]
      • [OverlayTypes]
      • [Particles]
      • [ParticleSystems]
      • [VoxelAnimTypes]
      • MissionControl
    • LoadDifficulty("Easy")
    • LoadDifficulty("Normal")
    • LoadDifficulty("Difficult")
    • [CrateRules]
    • [CombatDamage]
    • [Radiation]
    • [ElevationModel]
    • [WallModel]
    • [AudioVisual]
    • [SpecialWeapons]
    • [Tiberiums]
    • [Advanced(Multiplayer)?CommandBar]
  • ProgressBar_Update(45)
  • -> [Houses]
  • LoadPlayerHouse()
  • ProgressBar_Update(50)
  • ProgressBar_Update(58)
  • AI -> [TeamTypes], map -> [TeamTypes]
  • AI -> [ScriptTypes], map -> [ScriptTypes]
  • AI -> [taskForces], map -> [TaskForces]
  • map -> [Triggers]
  • map -> [Tags]
  • AI -> [AITriggerTypes], map -> [AITriggerTypes]
  • ProgressBar_Update(60)
  • Display_LoadMap()
  • map -> [Tubes]
  • BuildingTypeClass_ToTile()
  • ProgressBar_Update(70)
  • Rules -> [OverlayTypes]
  • CellTypeClass_SetupCell()
  • Rules -> [TerrainTypes]
  • ProgressBar_Update(72)
  • map -> [Units]
  • ProgressBar_Update(74)
  • map -> [Aircraft]
  • map -> [Infantry]
  • ProgressBar_Update(76)
  • map -> [Structures]
  • ProgressBar_Update(78)
  • map -> [SmudgeTypes]
  • if(GameMode == 5)
    • TMCJ4F.INI -> Rules -> load()
  • ProgressBar_Update(82)
  • ProgressBar_Update(86)
  • Beacon_LoadArt()
  • ProgressBar_Update(90)
  • ProgressBar_Update(96)
  • ProgressBar_Update(98)

And more goodies for everyone:
  • AI:
    • Script Actions:
      • Load Into Transport:
        • tries to shove all units into the first unit of this taskforce, gives up as soon as that fails.
      • Attack Enemy Structure, Move To Enemy Structure, ChronoSphere to Enemy Structure, Move To Friendly Structure:
        • argument is the building's index in the [BuildingTypes] list, with one flag having four possible values:
          • Values:
            • Value 0 - pick structure whose position poses the least threat
            • Value 1 - pick structure whose position poses the most threat
            • Value 2 - pick structure which is closest to you
            • Value 3 - pick structure which is the farthest away from you
          • In hexadecimal, the result is argument = flag * 0x10000 | buildingIndex.
          • In layman's terms, at first the argument is the building's index. Add (Value * 65536) to the index to get the final argument you should use. This sets a theoretical limit of max 65536 (#0 - #65535) BuildingTypes in the game, should you feel insane enough to try that.
  • Maps:
    • [Waypoints]
      • Up to 702 waypoints are loaded. Unlike most objects, they are index-sensitive (meaning waypoints named 0= .. 701.. are loaded).
    • [Map]
      • An undocumented flag Fill= can be set to either "Clear" (default value) or "Water". When any cell's contained tile is not explicitly set in [IsoMapPack*], it will be left with the default tile of that tileset. Meaning, the old TS "trick" of deleting [IsoMapPack5] could yield a blank water-filled map with smaller filesize.
    • Actions
      • Action 109 - FireIronCurtain: radius hardcoded, all objects within the target cell or the 8 surrounding cells are IronCurtained.
  • Art:
    • [Animations]
      • Some flags whose effect is not quite clear: RunningFrames = , StopSound = (well, this one is obvious..).
    • BuildingTypes
      • DemandLoad = if set, the SHP will not be cached on map load, but loaded from disk when needed.
      • DemandLoadBuildup = -''- buildup
      • Buildup = cannot exceed 15 chars , is not interpreted as an animation, but as a filename
      • If NewTheater is set, theatre-specific art is only loaded if the building's ID starts with a letter and the second letter is either 'a' or 't'.
      • Theatre = if set, the SHP is assumed to have a theatre-specific extension (.tem, .sno, etc) instead of .shp.
      • TurretAnim = Won't load turret unless its name has a substring 'TUR' (case-insensitive).
    • VehicleTypes
      • If the unit's ID is [APC], 'W' is appended to its Image= and that file is loaded as turret art. Haven't yet found how to actually trigger its display.
      • If NoSpawnAlt is set, 'WO' is appended to its Image= and that is loaded as turret art.
  • Rules:
    • [General]
      • CliffBackImpassability = only really works when set to 2. Assumes all cliffs are 4 cells high.
      • VeinholeMaxGrowth = the game still allocates 8 bytes * this value for each veinhole present.
    • [OverlayTypes]
      • A lot of this functionality is index-sensitive. Overlays with indices 24 and 25 are assumed to be high concrete bridges, 237 and 238 - high wood bridges, 167 - veinhole, 126 - veins.
      • Veinhole Monsters still get constructed internally. I have just started looking into this part, but so far, each cell containing overlay index 167 invokes a veinhole construction, the eight cells surrounding it get overlaid with index 178 (veinholedummy), and, as mentioned above, 8 bytes * VeinholeMaxGrowth get allocated for that monster. At a quick glance, they can receive damage, grow, shrink, etc. If anyone feels like getting down and dirty to test this,that would be awesome.
    • [BuildingTypes]
      • When runs out of ammo, ammo is instantly refilled, except if Hospital=yes or Armory=yes, in which case ammo is never reloaded. There you go, proof for the old Ammo bug documented at ModEnc->Ammo
    • Common (InfantryTypes, VehicleTypes, AircraftTypes, BuildingTypes:
      • MyEffectivenessCoefficient=, TargetEffectivenessCoefficient=, TargetSpecialThreatCoeffiient=, TargetStrengthCoefficient=, TargetDistanceCoefficient= can be set per-unit , if not set, the game will load the "MyEffectivenessCoefficientDefault=" and such from [General].
      • (Elite)(Primary|Secondary)= get loaded if a unit's TurretCount is < 1. But (Elite)Weapon(0..17)= get loaded if a unit's WeaponCount is > 0. Which means it's quite possible to assemble a unit that at first glance has both Primary and Secondary, but doesn't actually use them OR Weapon(0..17). Heh.
        ClearAllWeapons = sets the object's (Elite)(Primary|Secondary) and (Elite)Weapon1 to blank, meaning the unit will only get weapons if it is an IFV and an infantry boards it. The weapons do remain loaded by the game as if loaded by a weedguy hack.
      • If the unit uses Primary/Secondary, its weapon art data is taken from (Elite)(Primary|Secondary)FireFLH, (Elite)(P|S)(BarrelLength|BarrelThickness) . If it's a weapon switcher, weapon art data is loaded from (Elite)(Weapon0..17)(BarrelLength|BarrelThickness|TurretLocked).
      • Only AlternateFLH0..4 are loaded, others are ignored.
      • PowersUnit= indeed takes only one object, which is interpreted as a [VehicleType].
      • DestroyAnim= takes a list of Animations, not just one.
      • NaturalParticleSystem= can be used to define a particle system which apparently will be spawned with the building.
      • NaturalParticleLocation= sets said particle system's position, most likely in leptons.
      • DamageParticleSystems= and DestroyParticleSystems= can be used to define lists of Particle Systems for appropriate events.
      • WeaponStages = should not exceed 6 or bad things will happen.
      • (Elite)AirstrikeTeamType = takes a single name of an [AircraftType].
      • Some flags whose effect is not quite clear: NoAutoFire = , AutoCrush =, Disableable = , RotCount = .

Worth playing: 1 | 2 | 3
Reply
#5
interesting read
Reply
#6
Wow - Fuck!
[Image: osen2o7mpmm4jg1fs0.jpg]
Reply
#7
DCoder Wrote:Common (InfantryTypes, VehicleTypes, AircraftTypes, BuildingTypes:
  • MyEffectivenessCoefficient=, TargetEffectivenessCoefficient=, TargetSpecialThreatCoeffiient=, TargetStrengthCoefficient=, TargetDistanceCoefficient= can be set per-unit , if not set, the game will load the "MyEffectivenessCoefficientDefault=" and such from [General].

I have tried telling this to people for a while now, but they would not take it Tongue

Still, i think there is way more to the Threat logic than we think...
Reply
#8
Part III is here!
  • AI:
    • Script Actions:
      • 6,x - Jump To Script Line: subtracts 2 from the argument, and uses the result as a 0-based index into its own line array. Passing 0 results in the team becoming unresponsive. Passing 1 results in focusing on the first line.
      • 17,x - Change Script: immediately abandons this ScriptType, and starts executing the ScriptType specified as the argument. (Finishes with calling Script Action 6, 1.)
      • 18,x - Change Team: creates the TeamType specified as an argument, liberates all of its own objects, and submits them to the newly created team's control. Limit of 6 different ObjectTypes per team still applies.
      • 31,0 - Commit Suicide: for each unit in the team, creates a fake weapon with Damage=thisUnit->CurrentHealth, Warhead= Rules->[CombatDamage]C4Warhead , and fires it at the unit in question. Naturally won't kill if C4Warhead has <100% Verses.
      • 43,0 - Wait Until Fully Loaded: Only succeeds once the team's first unit is full (that is, passengers in it == its Passengers setting, meaning it assumes all passengers are counted as if they took up one slot, which is only true for infantry). Which naturally leads to lockups when a would-be passenger is killed while trying to enter.
      • 44,0 - Unload TRUCKB: Will convert all TRUCKB in the team to TRUCKA.
      • 45,0 - Load TRUCKA: Will convert all TRUCKA in the team to TRUCKB.
      • 49,0 - Repeat Until Success: Seems more like "this team has achieved their goal". It simply sets an internal flag on the team which no other action (except Scout) ever touches. The "goal" flag is checked when dissolved the team (see the TeamTypes section below).
    • TeamTypes:
      • Group= is an actual "grouping" value for initial team assembly: the game will only recruit existing objects into a team if the object's Group= matches the Team's Group= or the Team's Group= is '-2'. These checks are not made if the team is Recruiter = yes.
      • The search for eligible objects is performed in a linear fashion running over the list of all objects currently on the map. For this purpose, the Team's Waypoint= or the owner house's central base cell is chosen as the 'home point'.
      • Once an eligible object is recruited, all the objects that were further from the home point than the recruited unit are disqualified from the search. This is repeated as long as there are objects to recruit. Objects with a Group setting different from that of the Team's are disadvantaged by artificially adding 12800 leptons to their comparable distance.
      • Each time a team is dissolved, the game iterates over the AITriggerTypes list:
        • For each trigger in that list, if the trigger's Primary TeamType is the same as is being dissolved, the trigger's probability is modified:
          • if its "goal" flag is set, Rules->[General]->AITriggerSuccessWeightDelta is added to its current probability;
          • otherwise, Rules->[General]->AITriggerFailureWeightDelta is added to its current probability.
        • In either case, the trigger's current probability is multiplied by Rules->[General]->AITriggerTrackRecordCoefficient= .
      • TransportsReturnOnUnload=yes will send away all objects with a positive Passengers = value after the first unload script action completes.
      • Each team member gets tagged with the team's Tag= , unless OnTransOnly = yes.
      • When scanning for units to recruit, the team will not take any from teams with Priority= higher than its own.
      • If Whiner=yes is set, members of the team taking any damage are treated as an attack on the AI's base and base defense operations kick in.
    • AITriggerTypes:
      • At least when deciding whether this trigger is eligible for creation, the long string of zeroes is not checked for further conditionals after the first check.
      • MinProbability and MaxProbability are interpreted as "when altering this trigger's probability, don't let it fall outside [MinProbability ... MaxProbability]".
      • Current Probability of 5000 is a special case, forcing this trigger as soon as its conditions are met, without any randomness or Threat-based selection involved.
      • "-G" is not internally enforced as a "global" suffix, the game simply tags all AITriggerTypes loaded from ai(md).ini as global and all loaded from the map as local.
      • The trigger will not be eligible as soon as either one of the two attached TeamTypes reaches its Max= , even if the other team can still be created.
      • It appears that while in skirmish a team's Max= is compared against the count of team's instances owned by the house spawning the trigger, in singleplayer Max= is compared with the total count of this team's instances on the map.
  • Rules:
    • [General]:
      • UseMinDefenseRule makes the AI settle for [General]->MinimumAIDefensiveTeams before starting other teams. When disabled, the AI will not refocus until it reaches [General]->MaximumAIDefensiveTeams instead. (Don't disable unless you have custom teams for soviets - they only have one such TeamType with Max=1, and their AI will act piss poor if it can't get this far.)
      • AIVirtualPurifiers does not apply in singleplayer campaigns.
      • SuspendPriority = suspends all TeamTypes whose Priority= is less than this, for [General]->SuspendDelay frames when base defense operations are invoked. (DZ's AI guide doesn't mention this, only the rules guide does. His AI guide states that lower Priority= makes the team more likely to get selected.)
      • PrerequisiteProcAlternate takes a _single_ VehicleType as a value, not a list.
    • [AudioVisual]:
      • ShakeScreen is still parsed and checked, but the routine supposed to shake the screen on this event has been emptied, meaning no effect happens. (EIP 00441C34) Setting it to zero will cause an IE at EIP 00441C28.
      • SplashList accepts an unlimited number of anims, and picks which one to show depending on the firing weapon's Damage= - a zero-based index is acquired by dividing Damage= by 35 and rounding down to an integer value. Is only activated if tile being attacked is Land=Water.
      • TiberiumExplosive = is only used to determine whether the tiberium carried by a just destroyed unit should explode, if a certain scenario flag is set. I don't yet have the flag, but I can say this doesn't have any effect on deciding whether raw ore lying around is explosive.
    • [BuildingTypes]:
      • IsThreatRatingNode= is broken - when a building with this set is constructed, its owner house takes note of that. However, when such a building is destroyed, its owner house thinks it still has a TRN without ever noticing it lost one. Meaning, once the TRN is built, its house will reap its benefits for the remainder of the game. Some Threat Rating related info is described below, in appendix B.
      • A BuildingType destroyed by a Sparky=yes warhead can display several instances of animations from the [AudioVisual]->OnFire list. By default, OnFire= is not defined in YR, which is why Sparky = yes warheads cause IEs. For each cell formerly occupied by the building, a random number from the interval [0 .. (Building width in cells + Building height in cells + 5)] is generated:
        • 0..4 - First animation from OnFire gets played.
        • 5..7 - Second.
        • 8 - Third.
        • 9+ - No animation.
    • [Infantry/Vehicle/Aircraft/BuildingTypes]
      • DestroyAnim= can take a list of animations and will pick one at random to display.
      • Things that will not retaliate:
        • Objects without weapons (duh...).
        • Infantry possessing C4 (against buildings).
        • Objects with CanRetaliate=no.
        • Enslaved objects.
        • Mind Controllers with no spare links.
        • Objects owned by human players that currently have a target.
        • Objects attacked by countries allied with their owners.
        • Human-owned vehicles that deploy into buildings with Artillary=yes.
        • Human-owned non-building objects that are not in (Guard/Area Guard/Patrol) missions when [General]->PlayerReturnFire = no.
        • AI units managed by a TeamType with Suicide=yes.
        • AI units that already have a target, given that this attacker poses exactly as much threat after ThreatRating work (weird, but hey, I didn't write the code, albeit changing it to "posing as much or less threat" would most likely be a one byte change).
        • Objects whose weapon has 1% or less Verses against attacker armor type (the code is if Verses <= 0.01, very bad float math practice but I am not sure this is the sole reason why the infamous "1% doesn't differ from 2%" bug exists).
    • Projectiles:
      • If Degenerates = yes, then the weapon loses 1 point of damage per frame until its damage drops to 5. Only applicable if the projectile also is Dropping = yes, ROT > 0, or Ranged = yes. (As far as I can see, this is the only place where Ranged = is validated.)
    • [Warheads]:
      • AnimList accepts an unlimited number of anims, and picks which one to show depending on the firing weapon's Damage= - a zero-based index is acquired by dividing Damage= by 25 and rounding down to an integer value. Special case: if EMEffect=yes, it will pick a random anim from AnimList= . Special case: if warhead is the same one as [CombatDamage]->LightningWarhead= , then the animation played will be [AudioVisual]->LightningConBoltExplosion= .
    • [TerrainTypes]:
      • [General]->TreeStrength= is used as a fallback in case you don't explicitly specify a Strength= for this TerrainType or specify -1 as the Strength = .
    • [OverlayTypes]:
      • If Explodes=yes is set, upon receiving any damage this Overlay erases itself and causes an additional explosion which uses [CombatDamage]->AmmoCrateDamage= and [CombatDamage]->C4Warhead= . This will iterate over the debris list in [General]->BarrelDebris with an 85% chance of spawning each debris, and a 25% chance this will also spawn the particle from [General]->BarrelParticle.
      • If Tiberium=yes is set, then this overlay receives Armor=wood.
    • Miscellaneous:
      • Reason for the [General]->PrismSupportModifier glitch: All INI "parse a value" functions take a "fallback" argument which defines the value to use if parsing fails. When reading rules, PSM is read with fallback = 0. Being a float value, PSM is multiplied by 100 and saved. Later, when reading map, if [General] is present, PSM is read with fallback = (saved PSM value from Rules). The value returned by this parser is multiplied by 100 and saved. Which means, if you haven't specified PSM in the map's [General] but the map has [General], the correct PSM value gets multiplied by 100 again.
      • Content Scan is performed by summing up the Points= and ThreatPosed= of all passengers present aboard a transport, adding the transport's own Points= , and adding the transport's own Points= and ThreatPosed= . This is done if difficulty control says ContentScan = yes or the house's IQ level is equal to or above the level in [IQ]->ContentScan = . Otherwise, only the transport's own Points= + ThreatPosed= are counted.
      • As has been mentioned by VK before, the game reads <mapname>.ini when loading a map and interprets it as a rules-addon. It also reads LANGRULE.INI and interprets it the same way.
      • As has been mentioned by VK before, the game still contains residual code meant to load all RULEMD*.INI files as alternatives to RULESMD.INI and give the user a choice to pick which one s/he would like to use. Recreating a dialog with resource ID 0x93 will activate said functionality, although I haven't closely inspected the code that actually populates the list and interprets it.
  • Art:
    • When an animation is triggered over water, the engine generates feedback animations: if the animation has IsMeteor = yes, then it plays the last entry on [AudioVisual]->SplashList list, otherwise it plays the first entry from that same list and the animation from [AudioVisual]->Wake . Neither event is fired if the animation has an ExpireAnim set.
    • If the animation has defined a Spawns = flag, the engine picks a random number from 0 to SpawnCount, adds it to another random number from that same interval, and spawns that many instances of the animation listed in Spawns, all at the same position.
    • Setting TrailerSeperation (not my fault WW can't spell) to zero will cause an IE.
    • Setting Layer=Air on an item forces its Z position to [General]->FlightLevel = .
    • MakeInfantry = falls back to giving ownership of spawned animation to a house named "Civilian" unless this animation has a valid house as an owner. Ownership for this purpose is set only in the following cases:
      • * if the anim is the [AudioVisual]->InfantryVirus/InfantryMutate and is a result of an infantry getting killed;
      • * if the anim is called PSIWARN and spawned as a "PsiWarning" (when a nuke is launched, and its target cell is within radius of a Psychic Sensor, PSIWARN is played as a hint for the owner of said Sensor).
    • HideIfNoOre = does exactly what it says, _hides_ the animation if the tile contains no ore. The animation still gets played, and all associated effects such as spawned Particles, do get created, the anim is just not drawn onto the screen. This is also what happens to the [AudioVisual]->Behind animation if the option to show hidden objects is disabled.
  • Maps:
    • [Tags]:
      • Unlike Triggers, which use "0 - single-shot, any other - repeating" comparison, Tags use "0 - single-shot, 2 - repeating, any other - inactive" comparison. Consistency is for the weak-minded!
    • [Events]:
      • In fact, there is a limit on how many events a Trigger can have. In addition to the event listing string being < 512 chars long, the trigger cannot support over 32 events correctly (same reason as why there can't be over 32 countries in an Owner= string).

Appendix B: Threat Rating
If the house owning this unit does possess a Threat Rating Node, then its TargetEffectivenessCoefficient and related ones are used, otherwise the Dumb- counterparts from [General] are.

As I mentioned earlier, a unit can specify its own TargetEffectivenessCoefficient, TargetStrengthCoefficient and other threat evaluation coefficients or fallback to the defaults in [General]. Below, all unqualified flags are assumed to be referring to "this unit" and not the "Attacker".

A unit evaluates how much threat an Attacker poses to it this way:
Code:
tempValue = Attacker weapon's Verses against this unit * TargetEffectivenessCoefficient;
if(Attacker is currently targeting this unit) { // don't look at me, I didn't write the code
    tempValue = tempValue * (-1);
}
Threat = tempValue;

tempValue = Attacker->SpecialThreatValue (floating point number, btw, not just 0 or 1) * TargetSpecialThreatCoefficient;
Threat = Threat + tempValue;

if(this unit is currently considering Attacker's owner house as the Enemy House ) {
    Threat = Threat + [General]->EnemyHouseThreatBonus;
}

tempValue = This unit's weapon's Verses against Attacker * MyEffectivenessCoefficient;
Threat = Threat + tempValue;

tempValue = TargetStrengthCoefficient * Attacker's current health percentage;
Threat = Threat + tempValue;

tempValue = TargetDistanceCoefficient * Distance between this unit and Attacker;
Threat = Threat + tempValue;

Threat = Threat + 100000;
The result is only used in a couple of cases - when deciding whether to retaliate and in one other case which I haven't quite figured out.


P. S. Next time, I'm planning to describe the way common objects (Infantry/Vehicle/Aircraft/BuildingTypes and rules generic sections such as General, CombatDamage, etc.) are loaded from INI, i.e. which flags are read, what value types they take, etc. Unless anyone has other wishes, of course. That will take up a lot of space, so I will probably do one ObjectType per post (a lot more chances for you to click Thanks too Big Grin 2 ).

P.P.S. Of course, I could stop posting this stuff if nobody actually finds it interesting.

P.P.P.S. Also, I have a revised Map Actions information table that I'm going to post at ModEnc soon.

Worth playing: 1 | 2 | 3
Reply
#9
This info is gold, DCoder! Don't stop posting it! (unless of course you're taking time out to work on that dll...)
Ever wondered what the hell is going on?
Believe me friend you're not the only one.
--Lysdexia

Check out Launch Base for RA2/YR - http://marshall.strategy-x.com
Also home to the Purple Alert mod, 1.002 UMP, and the YR Playlist Manager.
Reply
#10
Holy shit. I love you D.

Really!
[Image: osen2o7mpmm4jg1fs0.jpg]
Reply
#11
DCoder Wrote:Objects attacked by countries allied with their owners.
It's technically possible that you are allied with a country, while that country is not allied with you.

Since you did not mention that units won't retaliate against civilans, I gather that you are allied with the civs (technically), but the civs are not allied with you? That would be the answer to this myth, heh.

DCoder Wrote:Recreating a dialog with resource ID 0x93 will activate said functionality, although I haven't closely inspected the code that actually populates the list and interprets it.
I tried it with an additional rules ini, and it worked.
It lists the Name= property as of [General] instead of the file name.

Just the window with ID 0x93 won't be enough of course.
Read through the dialog function for the single controls (a ListBox and a button IIRC).

Would be good if you tried it yourself as well, you could provide some screenshots. Smile
[Image: jsfml.png]
Reply
#12
Its quite interesting actually, though u have yet to make it list anything (in TS).

Also, i you right click the list and click "What is this" it tries to call SUN.HLP...
Reply
#13
Marshall Wrote:This info is gold, DCoder! Don't stop posting it! (unless of course you're taking time out to work on that dll...)
Thank you Smile I was feeling kinda tired of coding that dll recently, so I figured I'd switch to a different code-related field, that being this analysis, to clear my head. I will switch back to coding the dll soon, I'd imagine, don't worry. (If you feel I'm going too slowly, I'd have no problems giving the source, format info, and all that stuff to someone else.)

pd Wrote:Since you did not mention that units won't retaliate against civilans, I gather that you are allied with the civs (technically), but the civs are not allied with you? That would be the answer to this myth, heh.
Yeah, neutral MakeInfantry results (which are switched to Civilian side) attack AI's base before mine, and the AI only retaliates when a unit gets hit, not before, but it certainly does. Also on the topic of technical possibilities of alliances, I have always been amused by the need to explicitly list the country itself in the allies list Big Grin 2 . Either it's a bug in WW's map editor that FA2 carried over, or something really whacky going on.

Worth playing: 1 | 2 | 3
Reply
#14
I'm almost done with the huge table of what reads what. After that I might turn to coding the dll again or I might keep inspecting the code for more random tidbits. Are there any particular thoughts about what areas I should investigate? I.e. AI logic, object interaction, map scripting, whether or not certain flags actually work, residues of TS/FS code, developing a better except analysis tool, etc.?
(I have an idea to improve pd's YRMonitor tool to make inspecting runtime data easier. For example, it would be quite simple to get an overview of AITriggers with their current probabilities (as requested somewhere in the bugtracker) in real time with that.)

Worth playing: 1 | 2 | 3
Reply
#15
* gordon-creAtive votes for AI logic with the user patch thing in mind...
[Image: osen2o7mpmm4jg1fs0.jpg]
Reply




Users browsing this thread: 1 Guest(s)