Jump to content

Bubb

Modders
  • Posts

    199
  • Joined

Everything posted by Bubb

  1. Here's a fun one I helped @morpheus562 investigate. Repo steps: 1) Blind a party member. 2) Kill them with Magic Missile. Minor Bug: The game restores their visual range and reenables their ability to clear the FoW, even though they are dead. Serious Bug: The area's character counter is now off — it thinks two party members died when only one did. If you then kill everyone but charname, the engine believes no characters exist in the area and forces the viewport to the master area. Charname becomes unselectable and the game is softlocked.
  2. There's barely any code behind it. It updates the creature's target with the supplied object, (for the purposes of rendering the reticle), but does nothing else and never self-terminates.
  3. I can't tell you if it's intended, but of all the opcodes that use EFF files: op177 - CGameEffectApplyEffect - Checks for immunities to EFF op182 - CGameEffectApplyEffectEquipItem - Does not check for immunities to EFF op183 - CGameEffectApplyEffectEquipItemType - Does not check for immunities to EFF op248 - CGameEffectMeleeEffect - Checks for immunities to EFF op249 - CGameEffectRangeEffect - Checks for immunities to EFF op272 - CGameEffectRepeatingApplyEffect - Checks for immunities to EFF op283 - CGameEffectCurseApplyEffect - Does not check for immunities to EFF You might be able to abuse the bugged op182; if you supply an empty ITM resref it should apply 100% of the time.
  4. Yes: And I can confirm it's an EE bug dating back to at least v1.3 — the buggy block doesn't exist in oBG2:ToB's op235.
  5. SPLPROT.2DA => STAT == 0x102 checks against the animation INI field "personal_space", or whatever value the creature currently has it set to. The following animations are hardcoded to be immune to op235, (given that the target isn't a party member, I.E has a portrait slot): The opcode also has this weird block: if (this->m_sourceRes.startsWith("SP")) { this->m_effectAmount = (100 - pSprite->m_derivedStats.m_nResistMagic) / 100 * (float)this->m_effectAmount; if (this->m_effectAmount == 0) { return 0; // Terminate } } It's attempting to dampen the knockback speed with the target's magic resistance, but it fails at casting the first division to a float. If the spell resref starts with "SP" any positive magic resistance will make the speed parameter 0, causing the opcode to immediately terminate.
  6. Not much I can do except refixing the quickspell slots not reacting to CGameSprite::AddSpecialAbility(). Edit: This is now fixed in the master version of EEex.
  7. The mod uses EEex to pull data directly from the actionbar, so yes, anything that displays via the actionbar's "cast spell" menu will be handled. All spells are displayed unless one of the filters is used, which can limit the view to either Cleric or Mage spells, or by matching a search string.
  8. Please Note: EEex is required to use this mod — EEex is (at the time of writing) only available on Windows platforms. Overview: This mod seeks to replace the standard actionbar spell selection with an alternative that is more convenient for the player. The primary enhancements over the default spell selection include: Displaying all available spells at once, (categorized by level). No more endlessly clicking the right-arrow to get to your 9th level spells! A searchable spell list. Know which spell you want to cast? Just type the first couple of characters and press enter. The ability to narrow view to only Mage or Cleric spells; useful for Mage/Clerics. Screenshots: Installation: Download: Here Install EEex (forum). Download the zip file above and copy the contents into your game's base folder. Run setup-bubb_spell_menu.exe and follow the prompts to install. Make sure to run the game with InfinityLoader.exe after installing EEex. Mod Compatibility: Compatible with the following UI overhauls, (when installed after): Dragonspear UI++, (at the time of writing, the latest version can be found in this comment by artyfox; this version is required for compatibility) EET, EET_GUI Infinity UI++ LeUI, LeUI-BG1EE, LeUI-IWDEE, LeUI-SoD UI tweaks can go anywhere in the installation order relative to this mod.
  9. That error usually happens if you've manually gone and downloaded the outdated InfinityLoader release from GitHub. As EEex's readme says: Just install EEex — don't worry about the loader, it'll install as a part of setup-EEex.exe.
  10. That block works fine on my end. Maybe another mod is messing with the stat?
  11. 197 is a hardcoded projectile that plays SHAREA.BAM.
  12. The engine displays it when: Action #139 PlayerDialog(): [ Dialog forced because MoveToObject() failed, (I haven't observed this ever happening) AND Fails to enter dialog window ] OR [ Fails to enter dialog window AND SPEECH.2DA => EXISTANCE has no valid entries on target cre AND SPEECH.2DA => SELECT_COMMON has no valid entries on target cre AND [ target EA != ENEMY || SPEECH.2DA => HOSTILE_DIALOG has no valid entries on target cre ] ] The string gets trimmed when being displayed so it doesn't really matter if that leading space is there or not.
  13. 0xF00041 doesn't have a leading space in my BG2:EE installs: "has nothing to say to you." 0xF00070 and 0xF000C5, ("Find Trap Mode " and "Turn Undead Mode "), appear unused — the engine doesn't reference them. 0xF0010F and 0xF00110, ("Party AI Off " and "Party AI On"), as lefreut says, are only referenced in UI.MENU by their real strref: function getPartyAITooltip() if aiButtonToggle == 1 then return Infinity_FetchString(15918) else return Infinity_FetchString(15917) end end Kinda defeats the point of the enginest entry.
  14. Ok, I'll attempt to explain how op272's Type=3 works and why it's buggy. First, some things you need to know before I get to the opcode: The main engine loop ticks along at the set FPS value, normally 30tps. I will call this an "engine tick". Creature AI ticks at random mutiples of the engine ticks based on the object's internal ID. Normal creatures tick every other engine tick, Hastened creatures tick every engine tick, Slowed creatures tick every 4 engine ticks. The persistent effect list is updated every AI tick as long as the game is unpaused. 15 of these updates constitute a period. Note how AI ticks can occur at 15tps, 30tps, or 7.5tps given the state of the creature. "world time" ticks every other engine tick while the game is unpaused; spells use world time for duration. Now, how op272 Type=3 works: 1) The world time the effect is decoded at is stored at .EFF +0x6C. This decode happens when the effect is added to the projectile, (I.E. at the end of casting), NOT when the effect is applied to the target. 2) When the effect is applied to the target the engine decides how long it will wait until applying op272's resref field. It does this via: m_periodCounter = (<current world time> - <decode time>) / 15 % m_period // where m_period is Param1 when using type Param2=3 3) Remember how a period is 15 AI ticks? The persisent effect list keeps track of a creature-wide count of how many times it has been ticked. Every 15 AI ticks of this creature-wide counter => m_periodCounter increments and op272 checks if it should apply its resref. For type Param2=3, the resref is applied once the following is satisfied: ++m_periodCounter >= m_period Once op272's resref is applied the process starts over from step 2. Let's step through a real example to see how the above works, Param2=3, Param1=2: The system works OK at normal AI speed. However, if a creature is hastened it sneaks in extra applications. Consider: Slow appears to work OK most of the time, though maybe I've missed something: And remember that pausing while op272 is active still double-counts a worldTime tick, causing additional problems.
  15. It's complicated. The general idea is that the persistent effects list is checked every 15 AI ticks. Spell duration works on "world time", and when you pause the game "world time" is reversed by 1 tick. So, you get a situation where a single "world time" tick is processed multiple times: worldTime increases to 1, everything in the game is processed. I pause the game, worldTime is reverted to 0, everything in the game is processed. I unpause the game, worldTime increases to 1, everything in the game is processed. Oops, worldtime=1 was processed twice, which ticked the AI twice in a single "world time" tick... this is why pausing speeds up op272's next evaluation. As for op272 happening multiple times in a single tick, I don't know. It's theoretically possible if the effects list is ticked 15+ times in a single update while the game is unpaused, but I have no idea what would cause that. Do you have an example? And no, there's no way to fix the interval being inconsistent, it's a design flaw of the engine.
  16. I also observe identical 104 stat distributions with a custom autoroller; it appears the rng breaks down at these extreme probabilities, though I can't tell you why.
  17. For this specific case argent's suggestion is more elegant. My solution is more generalized -- it should work for all symbol names and should continue to function even if a mod decided to go crazy with whitespace. Edit: Argent's solution also needs to be tweaked slightly: APPEND ~gtimes.ids~ ~3600 AJROM_TIMER~ UNLESS ~[ %TAB%]AJROM_TIMER%MNL%*$~ Without that %MNL%* WeiDU doesn't match the EOL anchor when Windows-style newlines are being used, (a source of much agony in the Discord).
  18. Slightly overkill, but EEex uses something like this: DEFINE_ACTION_FUNCTION B3_ESCAPE_STRING STR_VAR str = ~~ RET escaped_str BEGIN ACTION_DEFINE_ASSOCIATIVE_ARRAY to_escape BEGIN ~$~ => 1 ~^~ => 1 ~.~ => 1 ~*~ => 1 ~+~ => 1 ~?~ => 1 ~[~ => 1 ~]~ => 1 ~\~ => 1 END OUTER_PATCH_SAVE escaped_str ~%str%~ BEGIN limit = BUFFER_LENGTH FOR (i = 0; i < limit; ++i) BEGIN READ_ASCII i character (1) PATCH_IF VARIABLE_IS_SET EVAL ~to_escape_%character%~ BEGIN INSERT_BYTES i 1 WRITE_ASCII i ~\~ ++i ++limit END END END END DEFINE_ACTION_FUNCTION B3_APPEND_UNIQUE_IDS STR_VAR file_name = ~~ column_one = ~~ column_two = ~~ BEGIN LAF B3_ESCAPE_STRING STR_VAR str = EVAL ~%column_one%~ RET column_one_escaped = escaped_str END LAF B3_ESCAPE_STRING STR_VAR str = EVAL ~%column_two%~ RET column_two_escaped = escaped_str END APPEND ~%file_name%.IDS~ ~%column_one% %column_two%~ UNLESS ~^[ %TAB%]*%column_one_escaped%[ %TAB%]+%column_two_escaped%[ %TAB%]*%MNL%*$~ END This appends an entry only if there isn't an exact match already present in the file, (barring whitespace). Used like: LAF B3_APPEND_UNIQUE_IDS STR_VAR file_name = ~GTIMES~ column_one = ~3600~ column_two = ~AJROM_TIMER~ END LAF B3_APPEND_UNIQUE_IDS STR_VAR file_name = ~GTIMES~ column_one = ~3600~ column_two = ~C#AJROM_TIMER~ END (I started writing this before argent commented so I'm still posting it)
  19. I think a broken implementation shows clear intent, even if the description doesn't mention it.
  20. Well, it works in my tests, and I've stepped through the game in a debugger to confirm that. Make sure you: 1) Are installing it on the latest IWD2 patch version, v2.01. 2) That the option is under the [Game Options] section. 3) That the INI value didn't get reset from last time. 4) That there's only one instance of Suppress Extra Difficulty Damage in the INI. If it still isn't working, could you upload your INI for me to test.
  21. You're right — the option's code is still in the engine, but the game immediately discards the INI value and sets it to 0. I've attached a mod that restores the INI option, though since it might have been intentionally disabled I don't know if it will cause problems. bubb_unlock_iwd2_suppress_difficulty_damage.zip
  22. Open icewind2.ini, add the following under the [Game Options] section: Suppress Extra Difficulty Damage=1
  23. ...And since PROFICIENCY2WEAPON is what applies the penalties for dual-wielding, having a weapon created by op111 removes the thac0 penalties for dual-wielding all together. @RoyalProtector The thac0 difference between your character's main-hand and off-hand are from the different enchantment levels of the weapons. Since BBoD is created by op111 Two-Weapon Style is completely ignored, including any penalties it would have otherwise applied.
  24. There's an exception in the engine -- if PROFICIENCY2WEAPON is going to be applied and the currently-selected weapon is in SLOT_MISC19, apply PROFICIENCYSINGLEWEAPON instead.
×
×
  • Create New...