Giter VIP home page Giter VIP logo

Comments (7)

cygarniczka avatar cygarniczka commented on May 20, 2024 1

The armor twang sound behavior is complex. I made the graph to easier explain things.

Armor sound behavior BG2

Armor Type Sound File Names Play Sound Notes
Leather ARM_02, ARM_02D, ARM_02E, ARM_02F >> Short sharp
Studded Leather ARM_02, ARM_02A, ARM_02B, ARM_02C >> Prolonged
Chainmail ARM_03, ARM_03A, ARM_03B, ARM_03C, ARM_03D, ARM_03E, ARM_03F >> Clanky. ARM_03E and F volume is lowered in-game
Splint Mail ARM_01, ARM_01A, ARM_01B, ARM_01C, ARM_01D, ARM_01E, ARM_01F >> Clanky with plate sounds
Plate ARM_04, ARM_04A, ARM_04B, ARM_04C, ARM_04D >> More clanky
Full Plate ARM_04, ARM_04E, ARM_04F, ARM_04G, ARM_04H >> Less clanky

I uploaded files combined into sequence to zippyshare.

A real pandora box is footstep sound. There are at least 32 different types and it is going to take time to pin them down to the fine detail.

Walking Sound Type Sound Files Notes
Shallow Water Walking WAL_01, WAL_01A, WAL_01B, WAL_01C, WAL_01D Used near water bodies. Could be use for walking through shallow water. New feature?
Interior houses WAL_02, WAL_02A, WAL_02B, WAL_02C, WAL_02D, WAL_02E Carpets use different sound file(s)

If you know any good websites that can play audio on other sites by inserting embed let me know. All webs I tried the embed didn't work. Can't upload wAv and mp3 files on github.

from gemrb.

lynxlynxlynx avatar lynxlynxlynx commented on May 20, 2024 1

Bubb looked at the original and found the logic. It did change on turns and if the animation sequence changed. The choice of sound per armor type is random:


// 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")

from gemrb.

lynxlynxlynx avatar lynxlynxlynx commented on May 20, 2024

Wow, that's a great investigation, thanks! Did you notice any pattern on which sounds are played when? My guess would be it's just a random selection, with maybe the same starting twang (the only consistently named file).

Walksounds we already do and yes, it depends on the floor type. So no need to look into that.
These wavs are compressed anyway, so most players can't read them.
It also means that this has to wait for #106 or some bits would have to be redone.

from gemrb.

cygarniczka avatar cygarniczka commented on May 20, 2024

Did you notice any pattern on which sounds are played when?

All files associated with the given armor will play in sequence of 0X, A, B, C or 0X, E, F, D. For plate and full plate armors there are 5 sound files. There are no random files getting selected for armor twag. Those sounds files are really short. When all combined no more than 4 seconds. To figure out which goes to which armor I had to combine e.g. A, B, C in audacity to hear the whole sequence.

X stands for 2, 3 or 4.

ARM_01, ARM_01A, ARM_01B, ARM_01C, ARM_01D, ARM_01E, ARM_01F - I can't figure out what armor does this sound come from. It sounds awful similar to chainmail armor but it's not the same. I uploaded sounds for all armors for comparison in above post's table.

Here is how ARM_01 sounds:
ARM_01 A B C.wav
https://www36.zippyshare.com/v/4qzWP517/file.html

ARM_01 D E F.wav
https://www36.zippyshare.com/v/rYCvUQSn/file.html

ARM_01 A B C D E F.wav
https://www36.zippyshare.com/v/nIj5xc2m/file.html

///Edit: Updated and fixed the table. ARM_01 sounds belong to Splint Mail.

from gemrb.

lynxlynxlynx avatar lynxlynxlynx commented on May 20, 2024

This is going to be tricky. Only iwd2 uses specific item types to differentiate armor. There's only one field I see that could help a bit and that's the paperdoll armor, however that also has only 3 choices: leather, chain, plate. Even if filenames were used for guesses, splint mail would still be the same as chain (but the exe doesn't have them hardcoded anyway). Attaching the sound data to the main AC modifying opcode (when used as an equipping effect and from the armor slot) would work only partly, since high magic armor AC levels overlap.

So, more research is needed. :| Are there really 6/4 categories in bg2, is anything different in iwd1 and how to decide to use them. PST we can luckily ignore, while iwd2 has the itemtypes to implement the data part cleanly.

from gemrb.

skellytz avatar skellytz commented on May 20, 2024

Splint Mail ARM_01, ARM_01A, ARM_01B, ARM_01C, ARM_01D, ARM_01E, ARM_01F Clanky with plate sounds

I'm not sure where the "clanky plate sounds" description came from. These are clearly fabric sounds: shuffling and rustling. They were originally supposed to be mage robe sounds, but are unused as the game engine simply disables any armor sounds for mages:

// Character has mage animation, or non-mage wearing mage robes (See below)
	if (animation_id & 0xF00 == 0x200 || armor_code == 0x31)
	{
		return ""
	}

from gemrb.

lynxlynxlynx avatar lynxlynxlynx commented on May 20, 2024

Does it even matter? I'm not sure why you're revisiting an almost two year old thread.

from gemrb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.