fixed inventory colors and lost animation
i hope now un/equipping off-hand weapon do not touch main hand animation
(v8) Main hand colors don't change anymore, but the offhand weapon colors still use CRE values. So, there's always a mismatch, eg main hand sw1h07 -> ITM colors, offhand sw1h07 -> CRE colors. Look at vanilla BG2 offhand color checks; they don't have this issue.
false_color moved from extani60 and extani64 to global EXTANIM.2DA
it affects other animation types except 0xxx, 4xxx, Bxxx, Dxxx(tobex dosn't have hooks for this types yet) and all other types without this field like Exxx
Now overriding false_color in EXTANIM doesn't seem to work at all.
I never hear armor sound from mages with robes
Try 0x6600 (BG2 char) anim_class=W CLCK09, CLCK14, CLCK16. They will play ARM_02 (leather), ARM_03 (chain) and ARM_04 (plate).
I've done some more research into these sounds. Looks like ARM_01 sounds are never used in the original games, but they are supposed to be robe sounds. The game engine simply disables all armor sounds for vanilla mage anims. This could be another cool optional tweak to restore robe sounds.
Here's what Bubb dug out in the executable. It should be easy enough to inject in GetSndArmor something like: if ((mage anim or robe item) and armor code > 1) then return "ARM_01" + random_ascii
// Called by CGameSprite::AIUpdate
CGameSprite::ChangeDirection()
{
if (CGameSprite.m_nNewDirection == CGameSprite.m_nDirection)
{
return // Exit function
}
CGameAnimationType::SLOW_MOVE_SCALE = 6 // Const
move_scale = CGameAnimationType::GetMoveScale()
if (move_scale < CGameAnimationType::SLOW_MOVE_SCALE * 2)
{
movement_value = 2 - (move_scale / CGameAnimationType::SLOW_MOVE_SCALE)
remainder = CGameSprite.m_id % movement_value
remainder2 = CInfGame.m_worldTime.m_gameTime % movement_value
if (remainder != remainder2)
{
return // Exit function
}
}
goto :armor_sound_logic
}
--------------------------------------------------------------------------------
// Called in many different places, (sequence corresponds to SEQ.IDS)
CGameSprite::SetSequence(new_sequence)
{
old_sequence = CGameSprite.m_nSequence
if (new_sequence == old_sequence && new_sequence != 7)
{
return // Exit function
}
stats = CGameSprite::GetActiveStats()
state = stats.m_generalState
if (
state & 0x80 != 0 // STATE_STONE_DEATH
|| state & 0x40 != 0 // STATE_FROZEN_DEATH
|| state & 0x1000 != 0 // STATE_SILENCED
)
{
return // Exit function
}
goto :armor_sound_logic
}
--------------------------------------------------------------------------------
:armor_sound_logic // Inlined in the above two functions
stats = CGameSprite::GetActiveStats()
if (stats.m_generalState & 0x1000 == 0) // Not STATE_SILENCED
{
if (!CInfGame.m_options.m_bDisableFootstepsDuringCombat || CGameArea.m_nBattleSongCounter <= 0)
{
if (
(CInfGame.m_options.m_bAutomatedSoundFootStepsOn && CInfGame.m_options.m_soundFootStepsOn)
|| (CInfGame::GetCharacterPortraitNum() != -1) // Is one of the "core" 6 party members
)
{
armor_sound = CGameAnimationTypeCharacter::GetSndArmor()
if (armor_sound != "")
{
// Play armor sound
}
}
}
}
--------------------------------------------------------------------------------
CGameAnimationTypeCharacter::GetSndArmor()
{
animation_id = CGameAnimationTypeCharacter.baseclass_0.m_animationID // ANIMATE.IDS
armor_code = CGameAnimationTypeCharacter.m_armorCode // (See below)
// Character has mage animation, or non-mage wearing mage robes (See below)
if (animation_id & 0xF00 == 0x200 || armor_code == 0x31)
{
return ""
}
// ARM_04G and ARM_04H exist, but can't be picked by the following random(??)
random_ascii = rand{ascii a-f or "", equal probability}
return "ARM_0" + armor_code + random_ascii
}
--------------------------------------------------------------------------------
m_armorCode is set on the character via CItem::TranslateAnimationType().
// Flags
is_mage_animation = CGameSprite.m_baseStats.m_animationType & 0xF00 == 0x200 // ANIMATE.IDS
is_itm_mage_robes = Item_Header_st.animationType[1] == 0x57 ("W") // Second byte at +0x22 of .ITM
// Return conditions for Armor(2) items:
is_itm_mage_robes && is_mage_animation => return Item_Header_st.animationType[0] // First byte at +0x22 of .ITM
!is_itm_mage_robes && !is_mage_animation => return Item_Header_st.animationType[0] // First byte at +0x22 of .ITM
is_itm_mage_robes && !is_mage_animation => return 0x31 ("1")
!is_itm_mage_robes && is_mage_animation => return 0x31 ("1")
Edited by skellytz, 28 May 2022 - 07:44 AM.