-
Posts
199 -
Joined
Content Type
Forums
Events
Downloads
Gallery
Mods
News
Store
Posts posted by Bubb
-
-
Corrections:
Parameter #1: Target:
- 2 => NearestEnemyOf() *which evaluates as [EVILCUTOFF]
- 3+ => [ANYONE]
Parameter #2: Condition:
- 1 => See(NearestEnemyOf()) *which evaluates as See([EVILCUTOFF])
- 8 => PersonalSpaceDistance([ANYONE],4)
- 9 => PersonalSpaceDistance([ANYONE],10)
- 10 => Delay(Extra)
- 13 => TimeOfDay(Extra)
- 14 => PersonalSpaceDistance([ANYONE],Extra)
- 15 => StateCheck(Myself,Extra)
- 16 => Die()
Additional flags:
Special: Extra:
[Condition = 0] && [Extra | 1] => Trigger even if the effect host was the source of the hit
[Extra | 1] => When triggered, display strref 0xF000F6 ("A contingency spell has been triggered") as effect host and remove effect
[Extra | 2] => Fire subspell as effect source instead of effect host
[Extra | 4] => Suppress subspell casting glow and string
[Extra | 8] => Suppress subspell range checkMisc notes:
1) [param3 != 0] acts as if [Extra | 1] was specified, (and maintains the portrait icon)
2) New to v2.6, when:
- Starting Spell()
- And the resref being cast (first 7 letters) is a parent resource of an active op232 effect on the caster
- And the active op232 originated from op234 [param2=0/1] or was defined with [Extra | 1] or [param3 != 0]
=> Remove the active op232, (only remove one instance, even if more would have met the above)
-
The animation INIs could use a good cleaning — many of them ended up with dead fields / the wrong fields all together. Not really important from a bug-fixing perspective, (if the fields are incorrect the engine falls back to hardcoded defaults), though it would make working with them easier.
-
5 minutes ago, CamDawg said:
No.
I ask because some people have fought me on this, saying that it's like that in PnP. I agree that it seems silly from a gameplay perspective, but I don't know what the intent was, (or if that PnP claim is true).
-
Here's something that's up for debate, quoting past me:
SpoilerQuoteDid you know that any attack a thief makes while invisible will ignore the target's AC dexterity bonus?
To be exact, the attack must follow these rules:
1) Attacker must have a backstab multiplier of 2 or higher
2) Attacker must be STATE_INVISIBLE
3) Attacker's weapon must not be RANGED
In the following example:
- Attacking character THAC0 = 17
- Attacked character AC = 0, (dexterity contributing -4 bonus)
The thief's attack only requires a total roll of 13 to hit, even though a roll of 17 is required normally:SpoilerHowever, this mechanic isn't implemented properly...If the attacked character has a *penalty* to AC due to dexterity, they will be harder to hit while being attacked under the above conditions.
In the following example:
- Attacking character THAC0 = 17
- Attacked character AC = 9, (dexterity contributing +5 penalty)
The thief's attack should only require a total roll of 8 to hit, though a roll of 13 is now required:SpoilerBug(?): Should backstabs (which invert a creature's AC Dex modifier) make a creature with a Dex penalty harder to hit?
-
1 minute ago, Luke said:
In any case, modders should always use "TriggerOverride()", right...?
TriggerOverride() is just a compiler-shortcut for NextTriggerObject() + WhateverTrigger(), so it really doesn't matter whether you write it out or use the shortcut. It's convenient shorthand, but it still suffers from the same bugs. But yes, since NextTriggerObject() isn't intended to be a standalone trigger, it's probably safer to use TriggerOverride().
-
Both Balquo and Galactygon say this is a bug:
https://forums.beamdog.com/discussion/comment/1169333/#Comment_1169333
-
Quoting past me regarding NextTriggerObject() and how it breaks the trigger block it is in if it evaluates to an invalid creature:
Spoiler19/2020 at 10:44 AM, Bubb said:It's easier just to show the flaw in the trigger block evaluation code.
if (hasNextTriggerObjectOverride) { if (nextTriggerObjectOverride != NULL) { // do eval stuff hasNextTriggerObjectOverride = false } } else { // do eval stuff }
NextTriggerObject sets both hasNextTriggerObjectOverride=true, and if it can't find a valid object, nextTriggerObjectOverride=NULL. Once this happens, the engine gets stuck in a bad state. Since nextTriggerObjectOverride is NULL it never clears hasNextTriggerObjectOverride, and it forever skips evaluating further triggers, (in the current trigger block).
Note though, while it's not evaluating the triggers, it is still running through all of them and doing janitorial actions. Meaning - every non-OR'd trigger still sets the whole block's result to false, the active OR count still ticks down - another NextTriggerOverride has the potential of fixing the deadlock, etc.
The only way a trigger block can still succeed after NextTriggerOverride breaks is:
- The NextTriggerOverride was in an OR block
- There are no subsequent triggers after the OR block
- A trigger in the OR block, that is positioned above the NextTriggerOverride, already evaluated to true
or, further in the same OR block, another NextTriggerOverride evaluates to a valid creature, and fixes the bad state. Once that happens, the trigger block will start evaluating normally again from that point onward. So, I suppose, one way to prevent NextTriggerOverride from breaking everything would be something like this:
IF OR(3) TriggerOverride(Player6,Global("B3WEIRD","LOCALS",1)) TriggerOverride(Myself,False()) // This will fix the deadlock // Whatever trigger here THEN
-
To quote the IESDP, here's another bug with event triggers, (they really are the worst):
QuoteNOTE: Triggers with values below 0x4000 use an alternate event-driven system, which is buggy even for IE standards. A negated event trigger returns true if there are pending events that have yet to be processed, and if any of these pending events fails to satisfy the unnegated trigger.
You can see this effect by putting !OnCreation() on a creature. The block will fire every time the creature receives an event other than the one that is defined, such as taking damage — so not every time the triggers are checked after load as would be natural to expect. -
3 hours ago, subtledoctor said:
EDIT - just looking at the logic of the IESDP desription, it seems backwards: what it should be doing (and what ToBEx actually does?) is
Spell NOT disrupted if (1d20 - 1) > Spell Level + Damage Taken
Right, that's the intended formula, (with CHECK_MODE=1, Luck=0). The IESDP description I quoted is the observed behavior of the engine, not the intended behavior. I left out this note from the IESDP which I probably should of kept, I'll edit it in:
QuoteBug:
CHECK_MODE
values greater than or equal to1
are bugged (since all those inequality symbols should be<
instead of>
).
As a result, you might want to stick with the default behavior (CHECK_MODE=0
) until this bug is fixed.Inverting the last condition in the psedocode, (changing the > to <), aligns the behavior with ToBEx.
EDIT — Ok, I've finished editing my previous post. Let me know if it still needs work.
-
11 hours ago, subtledoctor said:
concentration checks should go on the list.
The IESDP lists the following behavior for CONCENTR.2DA's CHECK_MODE:
QuoteKnown values for
CHECK_MODE
are:- 0 ⟶ Any damage a spellcaster takes will cause them to fail their spellcasting
-
1 ⟶ Spell disrupted if
(1d20 - 1) + Luck > Spell Level + Damage Taken
-
2 ⟶ Spell disrupted if
(1d20 - 1) + (Constitution / 2) - 5 > Spell Level + 15
-
3 ⟶ Spell disrupted if
(1d20 - 1) + Luck > Spell Level + 15
-
4 ⟶ Spell disrupted if
(1d20 - 1) + (Constitution / 2) - 5 > Spell Level + Damage Taken
Bug:
CHECK_MODE
values greater than or equal to1
are bugged (since all those inequality symbols should be<
instead of>
).
As a result, you might want to stick with the default behavior (CHECK_MODE=0
) until this bug is fixed.And here's some reversed pseudocode from the engine backing that up:
Spoiler// CHECK_MODE bit0 = Use Luck instead of Constitution // CHECK_MODE bit1 = Use 15 instead of Damage Taken roll_modifier = nil if CHECK_MODE == 0 then // return 1 (Always disrupted) elseif bit0 == 1 then roll_modifier = luck else roll_modifier = math.floor(constitution / 2) - 5 end roll = random_inclusive(0, 19) + roll_modifier bound_modifier = nil if bit1 == 1 then bound_modifier = 0xF else bound_modifier = damage_taken end success_higher_bound = spell_level + bound_modifier // BUG: This condition is flipped if roll > success_higher_bound then // return 1 (Disrupted) else // return 0 (Not disrupted) end
The final condition is flipped — the behavior should be the following, based on TobEx:
Do NOT disrupt if (1d20 - 1) + (Luck or Constitution/2) >= (Spell Level) + (Damage Taken or 15)
not
Disrupt if (1d20 - 1) + (Luck or Constitution/2) > (Spell Level) + (Damage Taken or 15)
I.E. A greater Roll/Luck/Constitution should decrease the chance of disruption, not increase it.
-
Casters can't be disrupted by damage if they are facing SSW(1), SWW(3), NWW(5), NNW(7), NNE(9), NEE(11), SEE(13), or SSE(15). This happens because the disruption code is only checked if the caster is in the correct orientation to face the target. SEQ_DAMAGE rounds a creature's orientation down to the nearest even direction, causing the caster to momentarily not face the target, making the check fail. Here's an example:
Spoiler -
Here's one I had fixed in old-EEex:
Event triggers (IDS < 0x4000) "lock on" to a specific creature when using standard objects. For example:
IF Global("B3TEST","GLOBAL",1) AttackedBy(PartySlot1,DEFAULT) THEN RESPONSE #100 DisplayStringHead(Myself,1) // No, I'm sorry, none of them sound familiar. END
The AttackedBy() will only return true for whoever the party leader was during its first evaluation, even if you change the party order.
-
20 minutes ago, Lauriel said:
Pardon me if this has been discussed elsewhere, but I thought it would fit here. There is a state (I wouldn't know if it's a spell state or something hardwired in the engine that can't be fixed without @Bubb), but when someone is blind they can hide 100%. I'm sure we'd all agree this can't possibly be intended behavior. Is it possible, if it is hardwired, that we use a different 'state' on it? I know next to nothing about spell states so...it's just an ask.
That happens because the engine checks if the creature hiding can see any enemies, not if any enemies can see the creature. An exe patch could approximate a fix by changing that check to use the default range of 14, (instead of the current visual range, which is 2 when blinded).
-
5 hours ago, Luke said:
206 can block SPL and EFF V2 files (provided that `Parent Resource Type` @ 0x90 is set to `1|Spell`; moreover, the `Resource` field of opcode #206 and the `Parent Resource` field @ 0x94 of the EFF file must be the same string). It will also fire a string in the combat log upon triggering (however, the string is not firing as of v2.6, regression @Galactygon @Bubb ...?)
Yes, there's been a regression. op206's string is now bound by:
if (!pEffect->m_sourceRes.IsValid() || (pImmunitySpell->m_error != 0xf00074 && pImmunitySpell->m_error != 0xf00080)) { uint nNewFeedback = 0xffffffff; if (pImmunitySpell->m_error == 0xf00074) { nNewFeedback = 0xf00073; } pImmunitySpell->m_error = nNewFeedback; }
Basically, the strref has to be 0xF00074 or 0xF00080 for the engine to display it.
-
For CGameAnimationTypeMonsterQuadrant (0x1000-0x11FF), the engine disables shadows if:
extend_direction == 0 && extend_direction_test != 8
It does this by setting the shadow rgb at palette index (1) to 0x0 (if false_color == 0) or 0xFF00 (if false_color != 0). Looks like the animation renders correctly if you set extend_direction_test=8, so maybe that's a way to enable the shadow?
-
AR4000 is hardcoded into the action that upgrades SoA to ToB, (MoveToExpansion). MoveToExpansion() is always called when entering ToB — if you're starting from SoA a script calls MoveToExpansion(), and if you're starting a new game the engine evaluates STARTARE.2DA, then runs MoveToExpansion(), (that's why you get the glitchy Elthan dialog).
While hacky, your only option might be to have AR4000.BCS move the party somewhere else.
-
What exactly are you trying to do? The configurable UI hotkeys are defined in BGEE.LUA by the keybindings table, though the ordinals all have hardcoded meanings and aren't really customizable. Basic custom hotkeys can be defined in UI.MENU by (ab)using a new menu definition. For example, add:
menu { name 'B3_HOTKEYS' ignoreEsc label { on M action " Infinity_DisplayString('Hello from B3_HOTKEYS!') " } }
and edit the 'START' menu's onOpen to push 'B3_HOTKEYS', (something like):
menu { name 'START' align center center ignoreesc onOpen " Infinity_PushMenu('B3_HOTKEYS')
What this does is add an invisible, non-closable menu that listens for the "M" key to be pressed, running whatever Lua code is in the label's action. The Lua environment has very little functionality to interact with the game engine though, so depending on what you want to do, it's probably impossible.
-
EEex isn't needed; pretty sure a standard UI mod could display the bag in a sorted order.
-
If it helps any, scraping EE v2.6 results in the following section->key entries. I've left out some sections that the engine dynamically reads from since they aren't very interesting. Some of these keys are probably non-functional:
Spoiler[Fonts]
Zoom[Game Options]
3E Thief Sneak Attack
All Learn Spell Info
Always Dither
Area Effects Density
Area Effects Refresh Probability
Attack Sounds
Audible Range
Auto Pause Center
Auto Pause State
Automated 3D Animations
Automated Attack Sounds
Automated Diable Casting Glows
Automated Disable Brightest
Automated Disable VEFVidCells
Automated Disable VVC Sounds
Automated Faster Blur
Automated Foot Steps
Automated High Level Brighten
Automated Limit Transparency
Automated Low Performance
Automated Mid Level Brighten
Automated Speed Adjustment
Automated Translucent Shadows
Automated Very Low Performance
Bored Timeout
Cheats
Classic Selection Circles
Cleric Ranger Spells
Color Circles
Combat UI
Command Sounds Frequency
Confirm Dialog
Critical Hit Screen Shake
Difficulty Level
Disable Casting Glows
Disable Display Text
Disable Foot Steps During Combat
Disable Placed Sounds During Combat
Disable Statics During Combat
Disable VEFVidCells
Disable VVC Sounds
Duplicate Floating Text
Effect Text Level
Enable Fog
Enhanced Path Finding
Enhanced Path Search
Environmental Audio
Equipment Comparison
Expire Trap Highlights
Extra Combat Info
Extra Feedback
Faster Blur
Filter Games
Footsteps
Force Dialog Pause
Fully Disable Non Visible During Combat
GUI Feedback Level
Heal Party on Rest
Hearth of Fury
High Level Brighten
Hotkeys On Tooltips
HP Over Head
Infravision
Inventory Pause Warning
Journal Popups
Keyboard Scroll Speed
Locator Feedback Level
Low End Machine 2
Low Mem Sounds 1
Low Mem Sounds 2
Maximum HP
Memory Access
Memory Level
Message Box Top
Mid Level Brighten
Mouse Scroll Speed
Nightmare Bonus Gold
Nightmare Bonus XP
No Difficulty Based XP Bonus
One Time Popup
Over Confirm Everything
Pausing Map
Quick Item Mapping
Ranged Weapon Switching
Render Actions
Render Dynamic Search Map
Render Explored Map
Render Path
Render Search Map
Render Travel Regions
Reverse Mouse Wheel Zoom
Selection Sounds Frequency
Show AOE
Show Character HP
Show Date On Pause
Show Learnable Spells
Show Message Box Hint
Show Triggers On Tab
Smart Radius
Story Mode
Subtitles
Super Atomic Speed Fighting Action
Suppress Extra Difficulty Damage
Terrain Hugging
Tiles Precache Percent
Tutorial State
Visual Range
Weather
WILD SURGE KEYS[GameSpy]
Enabled
Port[Graphics]
Area Map Zoom
Backend
BGRA
Greyscale On Pause
Hardware Mouse Cursor
Height
Log Frame Times
Postprocessing
Redraw Entire Screen
Render Frame Times
Scale UI
Shaders
Show Black Space
Sprite Blur Amount
Use Character Highlights
Use Nearest Neighbour Scaling
Use Sprite Outlines
Width
Zoom Lock[Keyboard]
Repeat Delay
Repeat Rate[Language]
Text[Mouse]
Double Click Height
Double Click Width[Multiplayer]
AsyncEnumeration
Client Timeout
Default Permissions
Disable Banters
Enable Chat Menu
Import Character
Last Protocol Used
Pausing Dialog
Player Name
Port
Session Name[Program Options]
Active Campaign
Alternate SR Curve
BMP Screensaves
Brightness Correction
Cloud Saves Enabled
Cucumber
Debug Mode
Developer Mode
Disable Cosmetic Attacks
Disable Movies
Disable Sound
Display Subtitles
Drop Capitals
F FLOATTXT
F NORMAL
F REALMS
F STONEBIG
F STONESML
F TOOLFONT
Fake Touch UI
First Frame Outline
First Run
Font Name
Force Local IP
Install Type
Logging On
Maximum Frame Rate
Never Show Nuisance SOD
New Gui
Path Search Nodes
Screen Position X
Screen Position Y
Short Pregen Description
Sprite Mirror
SR Curve Radius
String Buffer
Strref On
Tooltips
Translucent Shadows
UI Edit Mode
Use Mirror FX
Volume Ambients
Volume Movie
Volume Music
Volume SFX
Volume Voices[Resolution]
HeightDeath
HeightDefault
HeightMedium
HeightPickContainer
HeightPickMulti
HeightPickSingle
HeightSmall
Left
Top
Width[Window]
Full Screen
h
Maximized
w
x
y -
The v2.0 keybinding system relies on spell tooltips. Apparently quicksave isn't properly handled and falls down into the spell keybindings code. It ends up searching the spell list for an empty tooltip, and since the internal innate abilities you add have a blank strref assigned, it matches and casts.
-
Help
in Modding Q&A
No, I meant what I posted. EEex versions >= v0.9.0-alpha are for EE v2.6. The transition to a 64bit executable forced EEex to change significantly, which broke backwards compatibility with mods. So, if you want to play High Powers, which was designed for the "old" EEex, you have to downgrade to EE v2.5 and use the EEex version that goes along with it, as I linked.
-
Help
in Modding Q&A
0x410f is an EEex trigger — EEex_IsImmuneToOpcode(O:Object*,I:Opcode*)
High Power Baldur's Gate requires EEex and will only work using:
1) Windows
2) EE v2.5
-
Via the power of the Wayback Machine, here are the links to the thread's attachments:
https://us.v-cdn.net/5019558/uploads/editor/br/96zoon5rgt6w.rar
https://us.v-cdn.net/5019558/uploads/editor/kr/qytbc6bm4cai.rar
-
I'm not sure exactly what caused it, but I think Skie got interrupted executing:
EscapeAreaMove("AR0700",3325,1240,SSW)
(this is from a dialog)
The engine uses opcode 186 to actually move the creature, and that effect got saved on her CRE entry in the SAV. On load the engine processes this opcode before the game has been fully initialized and it crashes. Edit: Or something like that; iirc when Skie attempts to move it crashes because she's not internally assigned to an area.
BG2:EE v2.6.6.0 - op232 corrections / special flags
in IESDP Archive Forum
Posted
The crash is a divide-by-zero in Delay(). The condition is pretty unreliable because two events need to line up for it to fire: the Delay() trigger needs to return true at the same time the contingency is checked, (every 101 ticks).
As lynx says
Yes
That's the fun part — you can't. Extra acting as both flags and parameters for some Condition values is annoying.
op177 is crazy in that it doesn't "add" the EFF to the creature, it merely wraps / executes it. So that's why op232 doesn't get removed when you apply it via op177, though there's still no way to stop the string from firing.
strrefs [0xF00000-0xF00537] index into enginest.2da, with the row being strref - 0xF00000. So, 0xF000F6 => row 246 => STRREF_GUI_FEEDBACK_CONTINGENCY_TRIGGER
Effect source = the creature that cast the spell
Effect host = the creature the effect is attached to
Yes