I'm not really following what's going on in this thread, other than that you seem to be allowing things that are otherwise not possible.
Would this in any way be able to affect the party size? I doubt it, but one can dream!
Well... everything is possible, but within the realm of feasibility? That's another story...
I've looked at this before, and the game hardcodes "6 party members" checks in 600+ places, all of which would need to be looked at individually, and some requiring specially tailored workarounds. ------------------------------------------------------------------------------
The semester started up last week, and as I'm sure you can tell I haven't had as much time to work on this. I'm working on laying the groundwork for allowing new Opcodes to be implemented; this mostly consists of expanding the stats / spell states systems so that new opcodes can keep track of relevant values.
It appears there is no opcode to set arbitrary stats; Opcode #282 has no upper-bounds checking, (as referenced by the IESDP), so it can set stats 156+, though that is a woefully small slice of the available stats...
Would a proper stat setting opcode be desired? Other than that, I should have the expanded systems pushed to master soonish™.
If you allow me, I have 2 suggestions that could be nice to implement if it is possible
1- the first one is Cosmetic change similar to the SCS one :" stop Stoneskins from changing the caster's colour (BG2,TUTU,BGT)
The Stoneskin spell causes the recipient to turn a uniform grey colour, which is realistic but does get a bit monotonous when your spellcasters are permanently protected by it. Note that this effects NPC mages too. This tweak (which uses Ascension64's "ToB Extender" and so is unavailable on the Enhanced Edition) removes the colour change from the spell."
2- the second one would be to nerf thief detect illusion ability. It is quite overpowed considering it allow to reveal all kind of invisibility and illusions. (and bypass Spell immunity divination). we could change thieves' DI to give them personal invisibility detection instead of dispelling invisibility.
2- the second one would be to nerf thief detect illusion ability. It is quite overpowed considering it allow to reveal all kind of invisibility and illusions. (and bypass Spell immunity divination). we could change thieves' DI to give them personal invisibility detection instead of dispelling invisibility
Now that Bubb's added proper invisibility detection, you can already do this by using EE Keeper to set your skill in Detect Illusion to 0 and adding invisibility detection to your thief.
I'm not really following what's going on in this thread, other than that you seem to be allowing things that are otherwise not possible.
Would this in any way be able to affect the party size? I doubt it, but one can dream!
Well... everything is possible, but within the realm of feasibility? That's another story...
I've looked at this before, and the game hardcodes "6 party members" checks in 600+ places, all of which would need to be looked at individually, and some requiring specially tailored workarounds.
So, basically no. Well, that's a shame, but not unexpected in the least.
Would a proper stat setting opcode be desired? Other than that, I should have the expanded systems pushed to master soonish™.
YES! A request: could you make a stat-setting opcode that overrides the Modify Proficiencies opcode, regardless of the timing? Currently there's a problem with that opcode: because stat-setting effects with a higher timing (e.g. permanent after death) override effects with a lower timing (e.g. limited or while equipped) that set the same stat, the Black Blade of Disaster effect that gives the character grandmastery in longswords (while equipped) doesn't work if the character already has proficiency in longswords (permanent after death). The same goes for mod-introduced items that affect proficiencies, or new spells that do so.
2- the second one would be to nerf thief detect illusion ability. It is quite overpowed considering it allow to reveal all kind of invisibility and illusions. (and bypass Spell immunity divination). we could change thieves' DI to give them personal invisibility detection instead of dispelling invisibility
Now that Bubb's added proper invisibility detection, you can already do this by using EE Keeper to set your skill in Detect Illusion to 0 and adding invisibility detection to your thief.
I'm fairly sure that you could always do that. I think that it would be nice to have an option--definitely as an option-- to make the thief detect illusion work like detect invisibility by script, rather than as dispel illusion, without having to go that far. I want to see those points in detect illusion on my character sheet. (And, a mod like @OlvynChuru s epic skills could add more powerful illusion detection if your skill is high enough)
Detect Illusions: Externalizing it (and Turn Undead) to a spell file, similar to BARDSONG.SPL, would probably be best, so anyone can do with it as they want.
YES! A request: could you make a stat-setting opcode that overrides the Modify Proficiencies opcode, regardless of the timing? Currently there's a problem with that opcode: because stat-setting effects with a higher timing (e.g. permanent after death) override effects with a lower timing (e.g. limited or while equipped) that set the same stat, the Black Blade of Disaster effect that gives the character grandmastery in longswords (while equipped) doesn't work if the character already has proficiency in longswords (permanent after death). The same goes for mod-introduced items that affect proficiencies, or new spells that do so.
I'd argue that proficiency should not be temporarily set/incremented, as the level-up/dual-class processes cannot handle it. They would need to be fixed first.
Other than that, a limited timing mode (1/4096) will override timing mode 9, if applied afterwards. It's only the 'Set Value/%' equipped timing mode (2) that all other timing modes override. (For most effects):
Base Stat/State
'Set Value/%' timing mode 2, in order of application
'Set Value/%' timing mode other, in order of application
'Increment' timing mode 2
'Increment' timing mode other
An easy way to fix BBoD would be to just use increment effects, instead of a set effect:
B3_Invis.lua: Changes Opcode #193 to allow player-controlled creatures, which have said opcode applied, to see invisible sprites. Invisible sprites that are detected using Opcode #193 will only have their selection circle visible, though there is a setting at the top of the file which makes these creatures render as if under a detected improved invisiblity.
A great addition to this, if possible, would be to change the way the Detect Illusion thief skill works, so that instead of dispelling illusions, it does something like grant the thief opcode 193 invisibility detection for a couple rounds. And maybe also a hefty (+4? +8?) thac0/damage bonus against illusionary creatures, and maybe also an on-hit ability to opcode 337 dispel mirror image effects, for the same duration.
It appears there is no opcode to set arbitrary stats; Opcode #282 has no upper-bounds checking, (as referenced by the IESDP), so it can set stats 156+, though that is a woefully small slice of the available stats...
According to NearInfinity, there's an opcode labelled as Set state (namely #357). What can you tell us about it?
While you're at it, could you tell us if any of the following labelled opcodes is functional? So:
@Luke93: The following are defined, but completely empty. They probably are reserved slots for Beamdog to use:
Change background (#352) Tint screen (#353) Flash screen (#354) Soul exodus (#355) Stop all actions (#356) Set state (#357) Set AI script (#358)
The following are not defined, and will cause the engine to fall back and do nothing:
Play BAM file (single/dual) (#369) Play BAM file (#370) Play BAM file 2 (#371) Play BAM file 3 (#372) Play BAM file 4 (#373) Special spell hit (#374) Play BAM with effects (#375) Detect Evil (#376) Prayer (#378) Curse (#379) Embalm (#380) Induce hiccups (#381) Fist of iron (#382) Hit point transfer (#383)
* Could we make an opcode that temporarily replaces one of the
target's scripts with a script of our choice (resetting the script after
the effect ends)? This would let us make a lot of cool new enchantment
spells (like one that forces the target to spin in place for the
duration).
This is now implemented as Opcode #400. Everything is the same as Opcode #82, except that it can include a null script resref to force the game to zero out the field, (usually you just set the script to "None", and you should still do this...). And of course, the opcode restores the script slot's previous occupant when it expires.
Edit: What is going on with the forum's formatting?!
The new opcode works great! I used it to make an enchantment spell that forces the targets to Save vs. Spell or spin in place for the duration (I could call it Otto's Irresistible Spin). I also used it to make a cursed version of the Boots of the North that forces the wearer to constantly be walking north as long as the boots are equipped.
The new opcode works great! I used it to make an enchantment spell that forces the targets to Save vs. Spell or spin in place for the duration (I could call it Otto's Irresistible Spin). I also used it to make a cursed version of the Boots of the North that forces the wearer to constantly be walking north as long as the boots are equipped.
Oh man, about 20 spell ideas just went back on the table
(And yeah, the formatting is all messed up. I have no idea how this post is going to turn out)
I've pushed a commit to master that raises the number of stats from 202 to 65,737. Here's all the things that can access these new stats:
1. Lua function EEex_GetActorStat(actorID, statID) - (Can access vanilla stats as well)
2. CheckStat, CheckStatGT, and CheckStatLT scripting triggers.
3. Opcodes #318, #324, and #326.
4. New Opcode #401: Set Extended Stat
a) Parameter 1 => Stat ID
b) Parameter 2 => New Value
Opcode #401 will eventually be able to set any stat, but the vanilla stats actually differ in storage length so it's much more complicated to access them; for the time being Opcode #401 can only set stats above #202.
Please tell me if I've missed a vanilla mechanic that works with stats. If you have any suggestions on how to make the stat system more useful, now's the time to speak up!
I've pushed a commit to master that raises the number of stats from 202 to 65,737. Here's all the things that can access these new stats:
3. Opcodes #318, #324, and #326.
What values do new stats occupy in SPLPROT.2da for opcodes 318/324/326? Values 256 - 278 are reserved for various non-stat checks (source/not, circle size, multirow/not, areatype, daytime, evasion, source-target alignment match, EA, GENERAL, RACE, CLASS, SPECIFIC, GENDER, ALIGNMENT, STATE, SPLSTATE, Allies, Enemies, # Summons, Chapter)
Opcode #401 will eventually be able to set any stat, but the vanilla stats actually differ in storage length so it's much more complicated to access them; for the time being Opcode #401 can only set stats above #202.
If you need some help with identifying each stats size, the graph I made here should be a good start (graph is in topmost spoiler). The second "emtpy" line at 0x1080 is SUMMON_DISABLE_ACTION, I never did find IDENTIFYMODE, only that it's set by opcode 114. The layout of stats has changed since then, and I cannot be certain that all of those that occupy the 4 byte sections actually do so when the only value that can be set for them is '1'.
What values do new stats occupy in SPLPROT.2da for opcodes 318/324/326? Values 256 - 278 are reserved for various non-stat checks (source/not, circle size, multirow/not, areatype, daytime, evasion, source-target alignment match, EA, GENERAL, RACE, CLASS, SPECIFIC, GENDER, ALIGNMENT, STATE, SPLSTATE, Allies, Enemies, # Summons, Chapter)
That falls under a solid oops category. It is just an extension of the directly-referenced stats system... but yeah I did forget about those hardcoded exceptions in there. I actually can't think of a solution off the top of my head; do you have any suggestions? I suppose we could just not use those stat values if worst comes to worst... after all there are 60k+ now.
If you need some help with identifying each stats size, the graph I made here should be a good start (graph is in topmost spoiler). The second "emtpy" line at 0x1080 is SUMMON_DISABLE_ACTION, I never did find IDENTIFYMODE, only that it's set by opcode 114. The layout of stats has changed since then, and I cannot be certain that all of those that occupy the 4 byte sections actually do so when the only value that can be set for them is '1'.
Thanks! The symbols file is a blessing in this regard; it provides the offset and length of every single stat. The trickiness just comes from writing a function that has to have special read lengths for specific values. If you want I can post the current stat offsets / sizes.
Could EEex just append some dummy entries to stats.ids to represent those hard-coded entries? I assume any new stat added by a modder would be appended to stats.ids, so if those entries are already there, references to new stats will naturally avoid them... (unless I'm misunderstanding how stats work)
Yeah, it could. Just kind of feels wasteful having ~23 functional stats under the hood that can't be accessed through the splprot opcodes. Though, this sentiment stems from the rarity of free stats in vanilla... not really a problem anymore. It is the cleanest solution after all, so I guess the path forward is clear.
Out of curiosity, what's the number 65737 based on? It seems to be slightly higher than the max of a signed integer (65535).
^ OlvynChuru is correct. That being said, the actual number of new stats is completely arbitrary, and is defined by EEex_NewStatsCount in this file. It might actually be prudent to lower the number, as my tests show that increasing the stats to 65,737 increases the executable's memory footprint by about 40 megabytes for the average area. I'm not sure what would be considered an acceptable increase.
When using key bindings LUA file is it possible to block bubbling down key event to the game? For instance if I have key binding for player 1 set to '1' and then make shift+1 binding in LUA file then both actions will be executed.
If not then how would you select actor by ID 1,2,3,4,5,6 in your scripts? Then I can unbind 1-6 in game and just make small scripts that select player instead.
Also, If I hold SHIFT down and press '1' my shift+1 binding works but if I don't release SHIFT and press '1' again then my '1' binding is executed. I think shift flag should be persistent until released.
Currently I have not implemented a way to block key events from reaching the engine, and I am wary of doing so due to how invasive it is. Though, I've pushed to master an update that implements some new stuff that enables you to do what you want though my scripts. The last line of the hotkeys table is now an example on how to select a character though a keybinding, using a shift mod.
Currently I have not implemented a way to block key events from reaching the engine, and I am wary of doing so due to how invasive it is. Though, I've pushed to master an update that implements some new stuff that enables you to do what you want though my scripts. The last line of the hotkeys table is now an example on how to select a character though a keybinding, using a shift mod.
This isn't anything substantial, but it is so ridiculous i just gotta get it out.
I've been working on externalizing which classes can learn spells / cast spells / what level they cast spells at. I gave sunfire to Keldorn, and curiously enough he couldn't cast it, (it was greyed out). I thought it was some sort of "he's not a wizard" check so I was furiously tracing the source of the "disabled button" flag through the assembly. Spent around an hour tracking it down, just to realize it was because HE WAS WEARING ARMOR. Apparently I am so used to things being some sort of hardcoded voodoo that I completely forgot the simple rules of arcane casting...
Edit: And not to leave @Luke93 hanging: I'll see what I can do.
This isn't anything substantial, but it is so ridiculous i just gotta get it out.
I've been working on externalizing which classes can learn spells / cast spells / what level they cast spells at. I gave sunfire to Keldorn, and curiously enough he couldn't cast it, (it was greyed out). I thought it was some sort of "he's not a wizard" check so I was furiously tracing the source of the "disabled button" flag through the assembly. Spent around an hour tracking it down, just to realize it was because HE WAS WEARING ARMOR. Apparently I am so used to things being some sort of hardcoded voodoo that I completely forgot the simple rules of arcane casting...
Edit: And not to leave @Luke93 hanging: I'll see what I can do.
Lol. When you have a hammer, everything starts to look like a nail. And, man, do you have an awesome hammer (it's Mjölnir, right?)
Comments
------------------------------------------------------------------------------
Well... everything is possible, but within the realm of feasibility? That's another story...
I've looked at this before, and the game hardcodes "6 party members" checks in 600+ places, all of which would need to be looked at individually, and some requiring specially tailored workarounds.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Now, as for an update...
The semester started up last week, and as I'm sure you can tell I haven't had as much time to work on this. I'm working on laying the groundwork for allowing new Opcodes to be implemented; this mostly consists of expanding the stats / spell states systems so that new opcodes can keep track of relevant values.
It appears there is no opcode to set arbitrary stats; Opcode #282 has no upper-bounds checking, (as referenced by the IESDP), so it can set stats 156+, though that is a woefully small slice of the available stats...
Would a proper stat setting opcode be desired? Other than that, I should have the expanded systems pushed to master soonish™.
If you allow me, I have 2 suggestions that could be nice to implement if it is possible
1- the first one is Cosmetic change similar to the SCS one :" stop Stoneskins from changing the caster's colour (BG2,TUTU,BGT)
The Stoneskin spell causes the recipient to turn a uniform grey colour, which is realistic but does get a bit monotonous when your spellcasters are permanently protected by it. Note that this effects NPC mages too. This tweak (which uses Ascension64's "ToB Extender" and so is unavailable on the Enhanced Edition) removes the colour change from the spell."
2- the second one would be to nerf thief detect illusion ability. It is quite overpowed considering it allow to reveal all kind of invisibility and illusions. (and bypass Spell immunity divination).
we could change thieves' DI to give them personal invisibility detection instead of dispelling invisibility.
thanks
Externalizing it (and Turn Undead) to a spell file, similar to BARDSONG.SPL, would probably be best, so anyone can do with it as they want. I'd argue that proficiency should not be temporarily set/incremented, as the level-up/dual-class processes cannot handle it. They would need to be fixed first.
Other than that, a limited timing mode (1/4096) will override timing mode 9, if applied afterwards.
It's only the 'Set Value/%' equipped timing mode (2) that all other timing modes override.
(For most effects):
- Base Stat/State
- 'Set Value/%' timing mode 2, in order of application
- 'Set Value/%' timing mode other, in order of application
- 'Increment' timing mode 2
- 'Increment' timing mode other
An easy way to fix BBoD would be to just use increment effects, instead of a set effect:While you're at it, could you tell us if any of the following labelled opcodes is functional? So:
The following are defined, but completely empty. They probably are reserved slots for Beamdog to use:
Tint screen (#353)
Flash screen (#354)
Soul exodus (#355)
Stop all actions (#356)
Set state (#357)
Set AI script (#358)
The following are not defined, and will cause the engine to fall back and do nothing:
Play BAM file (#370)
Play BAM file 2 (#371)
Play BAM file 3 (#372)
Play BAM file 4 (#373)
Special spell hit (#374)
Play BAM with effects (#375)
Detect Evil (#376)
Prayer (#378)
Curse (#379)
Embalm (#380)
Induce hiccups (#381)
Fist of iron (#382)
Hit point transfer (#383)
In short, none of them work.
v0.3.0-alpha is now released:
The new opcode works great! I used it to make an enchantment spell that forces the targets to Save vs. Spell or spin in place for the duration (I could call it Otto's Irresistible Spin). I also used it to make a cursed version of the Boots of the North that forces the wearer to constantly be walking north as long as the boots are equipped.
(And yeah, the formatting is all messed up. I have no idea how this post is going to turn out)
Values 256 - 278 are reserved for various non-stat checks (source/not, circle size, multirow/not, areatype, daytime, evasion, source-target alignment match, EA, GENERAL, RACE, CLASS, SPECIFIC, GENDER, ALIGNMENT, STATE, SPLSTATE, Allies, Enemies, # Summons, Chapter)
If you need some help with identifying each stats size, the graph I made here should be a good start (graph is in topmost spoiler). The second "emtpy" line at 0x1080 is SUMMON_DISABLE_ACTION, I never did find IDENTIFYMODE, only that it's set by opcode 114. The layout of stats has changed since then, and I cannot be certain that all of those that occupy the 4 byte sections actually do so when the only value that can be set for them is '1'.
When using key bindings LUA file is it possible to block bubbling down key event to the game? For instance if I have key binding for player 1 set to '1' and then make shift+1 binding in LUA file then both actions will be executed.
If not then how would you select actor by ID 1,2,3,4,5,6 in your scripts? Then I can unbind 1-6 in game and just make small scripts that select player instead.
Also, If I hold SHIFT down and press '1' my shift+1 binding works but if I don't release SHIFT and press '1' again then my '1' binding is executed. I think shift flag should be persistent until released.