The weather forecast shows no more brainstorming for the time being, so I'll get back to my combat mod. Tomorrow I'm going to test all of your, kjeron, Weidu code for items, exceptional Strength and the rest. But I need another option for Apply Effects List. Some of the weapons are going to do knockback, but it wouldn't be appropriate on anything larger than, and maybe including, ogre size. I don't know how many circle sizes there are, I can think of 3... But the filters file only has "circle size <= 3" and "circle size > 3." Ogres are probably 2, so if I could have the code for an option < 2 ?
Some of the weapons are going to do knockback, but it wouldn't be appropriate on anything larger than, and maybe including, ogre size. I don't know how many circle sizes there are, I can think of 3... But the filters file only has "circle size <= 3" and "circle size > 3." Ogres are probably 2, so if I could have the code for an option < 2 ?
The PC animations are size 3, as are most vaguely humanoid creatures and animals, including ogres. Excluding dragons, almost everything else is either a 4 or 5, without much consistency. Dragons are 7-13, again not much consistency.
Okay, @kjeron ... I've gotten to testing your code for Strength, Exceptional Strength and patching offensive spells with a global spell state. I don't know if I did it wrong, but I'm getting an error about STR_CHECK_18_100 not converting to an integer somewhere.
DEFINE_ACTION_FUNCTION ADD_SPLPROT INT_VAR stat = 0 value = 0 relation = 0 RET new_row BEGIN
// [0:<=][1:=][2:<][3:>][4:>=][5:!=][6:b<=][7:b>=][8:b=][9:b!=][10:b>][11:b<]
ACTION_IF (stat > 278) BEGIN WARN ~SPLPROT.2DA - Stat out of Bounds.~ END
ACTION_IF ((stat != 259) AND (stat != 260) AND (relation > 11)) BEGIN WARN ~SPLPROT.2DA - Relation out of Bounds.~ END
COPY_EXISTING ~SPLPROT.2DA~ ~override~
COUNT_2DA_COLS cols
COUNT_2DA_ROWS cols rows
TEXT_SPRINT check_row ~~
TEXT_SPRINT check_stat ~~
SET new_row = 0
FOR(current_row = 0; current_row < rows; ++current_row) BEGIN READ_2DA_ENTRY current_row 1 cols check_stat
PATCH_IF (~%check_stat%~ STRING_EQUAL ~%stat%~) BEGIN READ_2DA_ENTRY current_row 2 cols check_value
PATCH_IF (~%check_value%~ STRING_EQUAL ~%value%~) BEGIN READ_2DA_ENTRY current_row 3 cols check_relation
PATCH_IF (~%check_relation%~ STRING_EQUAL ~%relation%~) BEGIN new_row = current_row current_row = rows END
END
END
END
PATCH_IF (new_row = 0) BEGIN
FOR(current_row = 0; current_row < rows; ++current_row) BEGIN READ_2DA_ENTRY current_row 1 cols check_stat
PATCH_IF (~%check_stat%~ STRING_EQUAL ~*~) BEGIN new_row = current_row current_row = rows END
END
PATCH_IF (new_row = 0) BEGIN new_row = rows INSERT_2DA_ROW rows cols ~%new_row% %stat% %value% %relation%~
END ELSE BEGIN SET_2DA_ENTRY new_row 1 cols ~%stat%~ SET_2DA_ENTRY new_row 2 cols ~%value%~ SET_2DA_ENTRY new_row 3 cols ~%relation%~ END
END
BUT_ONLY
END
LAF ADD_SPLPROT INT_VAR stat = 36 value = ~-1~ relation = 1 RET STR_CHECK = new_row END
LAF ADD_SPLPROT INT_VAR stat = 36 value = ~-1~ relation = 1 RET STR_CHECK = new_row END // Strength = 'Parameter1'
LAF ADD_SPLPROT INT_VAR stat = 36 value = 18 relation = 5 RET STR_N18 = new_row END // Strength != 18
LAF ADD_SPLPROT INT_VAR stat = 37 value = 0 relation = 5 RET EXSTR_N0 = new_row END // EXStrength != 0
LAF ADD_SPLPROT INT_VAR stat = 37 value = 1 relation = 3 RET EXSTR_L1 = new_row END // EXStrength < 1
LAF ADD_SPLPROT INT_VAR stat = 37 value = 50 relation = 2 RET EXSTR_G50 = new_row END // EXStrength > 50
LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L1 relation = EXSTR_G50 RET STR_1_50 = new_row END
// EXStrength != 1-50
LAF ADD_SPLPROT INT_VAR stat = 37 value = 51 relation = 3 RET EXSTR_L51 = new_row END // EXStrength < 50
LAF ADD_SPLPROT INT_VAR stat = 37 value = 75 relation = 2 RET EXSTR_G75 = new_row END // EXStrength > 76
LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L51 relation = EXSTR_G75 RET STR_51_75 = new_row END
// EXStrength != 51-75
LAF ADD_SPLPROT INT_VAR stat = 37 value = 76 relation = 3 RET EXSTR_L76 = new_row END // EXStrength < 76
LAF ADD_SPLPROT INT_VAR stat = 37 value = 90 relation = 2 RET EXSTR_G90 = new_row END // EXStrength > 90
LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L76 relation = EXSTR_G90 RET STR_76_90 = new_row END
// EXStrength != 76-90
LAF ADD_SPLPROT INT_VAR stat = 37 value = 91 relation = 3 RET EXSTR_L91 = new_row END // EXStrength < 91
LAF ADD_SPLPROT INT_VAR stat = 37 value = 99 relation = 2 RET EXSTR_G99 = new_row END // EXStrength > 100
LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L91 relation = EXSTR_G99 RET STR_91_99 = new_row END
// EXStrength != 91-99
LAF ADD_SPLPROT INT_VAR stat = 37 value = 100 relation = 5 RET EXSTR_N100 = new_row END // EXStrength != 100
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = EXSTR_N0 RET STR_CHECK_18 = new_row END
// Strength = 18/0 (not ((not STR18) or (not EX00)))
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_1_50 RET STR_CHECK_18_1_50 = new_row END
// Strength = 18/1 - 18/50
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_51_75 RET STR_CHECK_18_51_75 = new_row END
// Strength = 18/51 - 18/75
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_76_90 RET STR_CHECK_18_76_90 = new_row END
// Strength = 18/76 - 18/90
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_76_90 RET STR_CHECK_18_91_99 = new_row END
// Strength = 18/90 - 18/99
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_100 RET STR_CHECK_18_100 = new_row END
// Strength = 18/100
COPY ~X/CS-TRY.spl~ override
SAY NAME1 ~CS TRY~
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 16
STR_VAR
parameter2 = STR_CHECK
resource=~RET+1D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 17
STR_VAR
parameter2 = STR_CHECK
resource=~RET+1D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
STR_VAR
parameter2 = STR_CHECK_18
resource=~RET+2D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
STR_VAR
parameter2 = STR_CHECK_18_1_50
resource=~RET+3D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
STR_VAR
parameter2 = STR_CHECK_18_51_75
resource=~RET+3D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
STR_VAR
parameter2 = STR_CHECK_18_76_90
resource=~RET+4D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
STR_VAR
parameter2 = STR_CHECK_18_91_99
resource=~RET+5D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
STR_VAR
parameter2 = STR_CHECK_18_100
resource=~RET+6D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 19
STR_VAR
parameter2 = STR_CHECK
resource=~RET+7D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 20
STR_VAR
parameter2 = STR_CHECK
resource=~RET+8D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 21
STR_VAR
parameter2 = STR_CHECK
resource=~RET+9D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 22
STR_VAR
parameter2 = STR_CHECK
resource=~RET10D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 23
STR_VAR
parameter2 = STR_CHECK
resource=~RET11D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 24
STR_VAR
parameter2 = STR_CHECK
resource=~RET12D_#~
END
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 326
target = 1
timing = 0
duration = 2
parameter1 = 16
STR_VAR
parameter2 = STR_CHECK
resource=~RET14D_#~
END
COPY_EXISTING_REGEXP ~.*\.spl~ override
READ_BYTE 0x27 type
READ_BYTE 0x84 speed
READ_SHORT 0x68 ab_num
PATCH_IF ab_num > 0 BEGIN
PATCH_IF (type = 10) THEN BEGIN
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 328
target = 2
timing = 0
duration = 1
parameter2 = 97
special = 1
END
END
PATCH_IF (speed = 0 || speed = 1) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 1
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 2 || speed = 3) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 2
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 4 || speed = 5) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 3
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 6 || speed = 7) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 4
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 8 || speed = 9) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 5
parameter2 = 36
special = 1
END
END
END
BUT_ONLY
Okay, @kjeron ... I've gotten to testing your code for Strength, Exceptional Strength and patching offensive spells with a global spell state. I don't know if I did it wrong, but I'm getting an error about STR_CHECK_18_100 not converting to an integer somewhere.
LAF ADD_SPLPROT INT_VAR stat = 37 value = 100 relation = 5 RET EXSTR_N100 = new_row END // EXStrength != 100
LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_100 RET STR_CHECK_18_100 = new_row END
// Strength = 18/100
I wrote that from memory, sorry, it was a typo on my part, replace STR_100 with EXSTR_N100, or vice-versa.
Hi, I'm looking for a mod simplifying memorizing sequencer/сontingency type spells. In order not to pronounce before each fight the same combination of 3-6 long spells thrice. I want the used sequences/сontingency to be restored after rest or so that they can be made with the same one button. Maybe it's an AI script with hot keys like http://www.gibberlings3.net/cirerrek/seqmem.php
Hey, I want to try translating english mod to polish language. Can anybody tell me how should I do this step by step? Or link me to any good tutorial (I learn mostly by seeing examples, wall of text from documentation is not my way to go most of times).
In example, what should I edit & create structure of folder in order to translate mod adding new items to the game?
Sorry if this was asked before, but I couldn't find it.
@subtledoctor Thank you, It is this component (with others all well) is not installed on BG2: EE. Error:
It distresses me that it works only for the Mages. The Sorcerers lose the ability to create the Sequencer / Contingent spells. Metamagic:
This component makes revisions to the various Sequencer and Contingency spells in order to provide Mages with a unique ability unavailable to Sorcerers. If this component is installed, Sorcerers will be unable to learn Sequencer or Contingency spells. Minor Sequencer, Spell Sequencer, Spell Trigger, and Contingency are removed from the spell selection tables and are replaced with innate abilities. These innate abilities function identically to the original spells, but must first be unlocked by learning the spell from a scroll, casting that spell, and then resting. Chain Contingency is converted to a High Level Ability, and may be selected by Mages, Mage/Thieves, and Cleric/Mages via the high level ability selection menu.
That's because sorcerers are not trained and don't know jack about magic. They're just born on a ley line, or they have dragon blood, or some other excuse. Sequencers and contingencies are calculus to them.
Another hitch when patching spells. I used that bit of code to restrict the patching to spells with at least one ability, but it stops at the same file, one without. I'm trying to do two things here: add a target-marking spell state to abilities of offensive spells and give all spells a global spell state of the same length as their casting time, that's 1 second for every 2 points of speed. I would also prefer to remove this spell state instantly, if the spell is interrupted, but I don't know if that's possible. Anyway, the code giving me a "write out of bounds" error is this:
COPY_EXISTING_REGEXP ~.*\.spl~ override
READ_BYTE 0x27 type
READ_BYTE 0x84 speed
READ_SHORT 0x68 ab_num
PATCH_IF ab_num > 0 THEN BEGIN
PATCH_IF (type = 10) THEN BEGIN
LPF ADD_SPELL_EFFECT
INT_VAR
opcode = 328
target = 2
timing = 0
duration = 1
parameter2 = 97
special = 1
END
END
PATCH_IF (speed = 0 || speed = 1) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 1
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 2 || speed = 3) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 2
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 4 || speed = 5) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 3
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 6 || speed = 7) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 4
parameter2 = 36
special = 1
END
END
PATCH_IF (speed = 8 || speed = 9) THEN BEGIN
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 5
parameter2 = 36
special = 1
END
END
END
BUT_ONLY
The code for Strength worked, and that for exceptional Strength, I don't know. I get strange cross-referencing entries when I look at the created A.E.L. effects inside the spell. Str 18/100 is there by itself, but the interim ranges... Is this how they are supposed to look like?
By the way, are there ways to interrupt spell-casting other than by damage? Effect 60 doesn't stop it if the process is already on the way. Feeblemind for 1 second can do it, Pause curiously returns the character to the casting animation and the spell completes, Stun looks too unnatural, but all of this isn't quite right. I'm making a mechanism for interrupting, with some special effects, and it looks and sounds the best when the casting character gets struck for some damage. Then he recoils, grunts in pain, and the spell fizzles (though sometimes the glow plays out for the whole casting time - a mystery of Mystra). But they only cry out if damage is more than 0, and I'd rather not hurt them for real, even if I heal the damage right away. Who knows, they may just have 1 hp, or it may trigger a contingency... Is there anything that provokes screaming and/or breaks a spell without lowering hit points?
The code for Strength worked, and that for exceptional Strength, I don't know. I get strange cross-referencing entries when I look at the created A.E.L. effects inside the spell. Str 18/100 is there by itself, but the interim ranges... Is this how they are supposed to look like?
Yes, its comparing two other entries in SPLPROT. It looks confusing, but that's how it has to be done. Entries 94 and 144 should be (STR NOT = 18) and (EXSTR NOT = 100), respectively. It only returns true if both entry 94 and 144 are false (not match). Entry 94 returns false only when strength is 18. Entry 144 returns false only when extrastrength is 100. So this entry returns true when strength is 18 and extrastrength is 100.
By the way, are there ways to interrupt spell-casting other than by damage?
Wild Surge - must be active when casting completes. Not likely useful here. Opcode 148, Parameter2=0. Higher priority script actions/player input. (attack/move).
Like damage, none reliably work on spells with zero casting time.
That's all right, zero casting time should stay instant, but actions... Does ActionOverride + NoAction() interrupt it? Or an order to cast a non-existing spell?
The mod installed now, I'm going to check how Strength and the spell effects work. But I'm noticing a strange thing about this tp2 file. I have copied it together with all subfolders from another mod I was working on, just so I wouldn't need to create them manually. Then I deleted superfluous files and folders and changed all of the references. The old mod is not mentioned anywhere in this tp2. Yet somehow the setup still refers to that one's tp2 file and errors in it. The installation completes, the result isn't even "with warnings," but the results point to that other file. Do you have any idea why this may be happening?
That's all right, zero casting time should stay instant, but actions... Does ActionOverride + NoAction() interrupt it? Or an order to cast a non-existing spell?
ActionOverride([target],NoAction()) won't work, but you can use other actions to do nothing, such as ActionOverride([target],MoveToObject(Myself)) or ActionOverride([target],ForceSpellRES("",Myself)).
The old mod is not mentioned anywhere in this tp2. Yet somehow the setup still refers to that one's tp2 file and errors in it. The installation completes, the result isn't even "with warnings," but the results point to that other file. Do you have any idea why this may be happening?
All right. I'm still having trouble getting Set Spell State to recognize Special 1. I've done it in another mod, limiting myself to just the standard states, but it's not happening here. For those offensive spells I'll instead patch them with Cast Spell to my own hand-made spell. I'll put it together and point it to a custom spell state, after I've extended SPLSTATE. This number will be retained in other people's setups, yes?
Another thing. I have an invisible minion scripted to look around for a SPECIFIC value and then check allegiance. If it's an enemy, the minion casts a spell on it. There is only a second to do this before the SPECIFIC change expires. In a crowd, will I get better results if I give the minion protection from GOODCUTOFF? How is that going to work, the same way as with blindness - if I don't see you, you don't exist for me? I'm hoping to prevent the minion from scanning friendlies at all.
Hey, I want to try translating english mod to polish language. Can anybody tell me how should I do this step by step? Or link me to any good tutorial (I learn mostly by seeing examples, wall of text from documentation is not my way to go most of times).
You need a mod to be tra-ified first, which essentially means all of the new or modified bits of text--known better as strings--have been put into one or more separate text files, designated as something like file.tra.
Take a look at Tweaks, which has (I think) 10 different translations. I've set up the file structure such that all of the translation files are in separate, language-specific folders inside a 'languages' folder. Near the top of the mod's main tp2 file, you'll find something like this:
LANGUAGE ~English~ ~english~ ~cdtweaks/languages/english/description_updates.tra~ ~cdtweaks/languages/english/setup.tra~ // some other LANGUAGEs LANGUAGE ~Polski (Translation by yarpen, Artanis, dragionian, Evendur, Grjgori, and Neminus)~ ~polish~ ~cdtweaks/languages/english/setup.tra~ ~cdtweaks/languages/polish/setup.tra~ // some more LANGUAGEs
Each language has at least three entries. The first is how it's presented in the installer in the language menu, the second is the name of the language's folder, and finally one or more tra files are listed. Not all tra files are listed here, only the ones needed by the installer itself--you'll notice that Tweaks uses 12 tra files, but the English option only needs two loaded at install.
So, if the user selected to install the Polish language option of Tweaks, the installer would load ~cdtweaks/languages/english/setup.tra~ and ~cdtweaks/languages/polish/setup.tra~, in that order. This is a bit of a trick--since English is the 'native' language of the mod, I always know that the English setup.tra file is the most complete. By loading the same file in Polish next, it will then override the English strings with their Polish translations. Any strings which are not present in the Polish tra file will be presented in English, at least.
Tra files themselves are pretty straightforward. Here's a chunk of the English and Polish setup.tra files:
@0 = ~NPC Tweaks~ @1 = ~This step may take a few moments ...~ @2 = ~The Add Bags of Holding to BG is required for this component.~ @4 = ~Convenience Tweaks/Cheats~ @5 = ~The Exotic Item Pack is required for this component.~
@0 = ~Poprawki dla postaci przylaczalnych~ @1 = ~To moze chwile potrwac...~ @2 = ~Ten komponent wymaga komponentu 'Torby przechowywania dla BG'.~ @4 = ~Poprawki udogadniajace gre/oszustwa~ @5 = ~Ten komponent wymaga komponentu 'Zestaw egzotycznych przedmiotow'.~
If the user selects Polish, the mod will install using the second set of strings; in English it will use the first. The actual work of translating a mod is essentially grabbing the English tra files, copying them, and then replacing the text with its Polish equivalent. Mind the tilde marks, as they are important, but otherwise that's essentially it. Once complete, you just need to poke the mod author--sometimes repeatedly--until they integrate and put out the new, translated release.
Some questions have resolved themselves. But I'll ask @kjeron as the most experienced advisor here. Do you know why effects I patch spells with insist on appearing in the files in the wrong order? There is a very quick action series I need to squeeze into the casting time of spells, every AI tick counts. I patch the spells with a 72 first, then two instances of 326, and afterwards, less important, come two 177s. That's how the patching is written in the tp2. But the EFFs appear first in the effects list, then the 326s, and finally the 72 - backwards. Any idea why?
Some questions have resolved themselves. But I'll ask @kjeron as the most experienced advisor here. Do you know why effects I patch spells with insist on appearing in the files in the wrong order? There is a very quick action series I need to squeeze into the casting time of spells, every AI tick counts. I patch the spells with a 72 first, then two instances of 326, and afterwards, less important, come two 177s. That's how the patching is written in the tp2. But the EFFs appear first in the effects list, then the 326s, and finally the 72 - backwards. Any idea why?
The ADD_SPELL_CFEFFECT function adds new effects as the first effect by default The ADD_SPELL_EFFECT function adds new effects as the last effect by default. You can override this by using "insert_point":
LPF ADD_SPELL_CFEFFECT
INT_VAR
opcode = 328
target = 1
timing = 0
duration = 2
parameter2 = 36
special = 1
insert_point = ~-1~ // negative = last, zero = first
END
Okay... Some of the script actions are going to have to be done from inside projectiles instead, scripts are too slow. Can you explain what the IDS values are for there, and Neg. IDS1, and "IWD Style Check"?
The fields at 0x3a - 0x43 allow you to restrict the targets of a Area-Effect projectile. "IWD Style Check" enables these fields, I don't know why they don't work normally.
Each pair works like Opcode 318, using values from SPLPROT. 0x3c = Parameter1 0x3e = Parameter2
0x40 = Parameter1 0x42 = Parameter2
If the field pair is 0/0, it is not used. By default, any creature that matches BOTH values is not affected by the projectile. With "Use either IDS", any creature that matches EITHER value to not affected by the projectile. The "Neg. IDS1" and "Neg IDS2" change there respective check from "Match" to "Not Match".
Unlike ocpode 318, each of these fields is only 2 bytes, not 4, so it cannot be used for checks that require Parameter1 values over 65535 (mostly KIT and STATE checks). You would have to add entries to SPLPROT for specific kits or state combinations.
Theres only 2 real reasons to use these in place of Opcode 318:
The spell has a limited number of targets (using the projectiles Dice fields).
The spell is hostile and the enemy/ally/party flags are not appropriate (such as alignment-based spells).
The last reason is why I want this. I'm targeting briefly-changed custom SPECIFIC states, separately among allies and among enemies. I can filter allegiance first with effect targets, but then I need a further narrowing-down, and projectiles are the fastest way I know. Thanks for explaining. I guess I need an "is not" in one of these and the other empty.
Time for another question. Scripts. Objects. Latching on to someone you've just been attacking. Is there an object for that? It's not LastAttacker, not LastHitter, and LastTargetedBy doesn't seem to work for NPC at all.
You can place generic marker effects on creatures you hit. You can place script-name based marker variables on target/source when a script issues the "Attack()" action, could work for non-controllable creatures, until they get charmed/confused/panicked/etc...
But in general, an attacking creature is blind idiot flailing about. It doesn't directly know who it's attacking, if it's attacking, or when it attacks. It only knows when it hits someone and consequences happen.
You can place generic marker effects on creatures you hit. You can place script-name based marker variables on target/source when a script issues the "Attack()" action, could work for non-controllable creatures, until they get charmed/confused/panicked/etc...
But in general, an attacking creature is blind idiot flailing about. It doesn't directly know who it's attacking, if it's attacking, or when it attacks. It only knows when it hits someone and consequences happen.
I always want universal solutions. So script names are no good for me. But as far as hitting someone - the last object hit by the active creature could fit the bill. LastHitter isn't it, though, I need the reverse. In short, the situation is this: this a generic script for a creature to attack a target. If the target ends up dead (HPLT(LastKilled,1)), the creature is scripted to flee the area. This part of the script I have ready. But this is a universal script, and there is no telling what the creature will be armed with, a weapon or only fists. Thus, often the target is only going to fall unconscious from the attacks. The first case represents murder, the second a brawl. I'm missing the second half of the script that would make the active creature, after it knocks out the target, step away or go roam randomly. It cannot attack a prone target, but it stands over the body, unable to continue with anything because I have no object for a STATE_SLEEPING check.
This I've already asked some time ago, but I don't remember the answer... Patching creatures with Weidu, how can I find those that have an empty field? Nothing in their Override script field?
Fireball sets a global variable, mgArea1, on casting. I've been told that this controls the darkening of burned bodies. How does it work? How does the engine read it?
Comments
Also - this is mostly out of curiosity - can Set AI Type be made to recognize kits, for switching to kits as well as classes? Or in some other way?
Excluding dragons, almost everything else is either a 4 or 5, without much consistency. Dragons are 7-13, again not much consistency.
DEFINE_ACTION_FUNCTION ADD_SPLPROT INT_VAR stat = 0 value = 0 relation = 0 RET new_row BEGIN // [0:<=][1:=][2:<][3:>][4:>=][5:!=][6:b<=][7:b>=][8:b=][9:b!=][10:b>][11:b<] ACTION_IF (stat > 278) BEGIN WARN ~SPLPROT.2DA - Stat out of Bounds.~ END ACTION_IF ((stat != 259) AND (stat != 260) AND (relation > 11)) BEGIN WARN ~SPLPROT.2DA - Relation out of Bounds.~ END COPY_EXISTING ~SPLPROT.2DA~ ~override~ COUNT_2DA_COLS cols COUNT_2DA_ROWS cols rows TEXT_SPRINT check_row ~~ TEXT_SPRINT check_stat ~~ SET new_row = 0 FOR(current_row = 0; current_row < rows; ++current_row) BEGIN READ_2DA_ENTRY current_row 1 cols check_stat PATCH_IF (~%check_stat%~ STRING_EQUAL ~%stat%~) BEGIN READ_2DA_ENTRY current_row 2 cols check_value PATCH_IF (~%check_value%~ STRING_EQUAL ~%value%~) BEGIN READ_2DA_ENTRY current_row 3 cols check_relation PATCH_IF (~%check_relation%~ STRING_EQUAL ~%relation%~) BEGIN new_row = current_row current_row = rows END END END END PATCH_IF (new_row = 0) BEGIN FOR(current_row = 0; current_row < rows; ++current_row) BEGIN READ_2DA_ENTRY current_row 1 cols check_stat PATCH_IF (~%check_stat%~ STRING_EQUAL ~*~) BEGIN new_row = current_row current_row = rows END END PATCH_IF (new_row = 0) BEGIN new_row = rows INSERT_2DA_ROW rows cols ~%new_row% %stat% %value% %relation%~ END ELSE BEGIN SET_2DA_ENTRY new_row 1 cols ~%stat%~ SET_2DA_ENTRY new_row 2 cols ~%value%~ SET_2DA_ENTRY new_row 3 cols ~%relation%~ END END BUT_ONLY END LAF ADD_SPLPROT INT_VAR stat = 36 value = ~-1~ relation = 1 RET STR_CHECK = new_row END LAF ADD_SPLPROT INT_VAR stat = 36 value = ~-1~ relation = 1 RET STR_CHECK = new_row END // Strength = 'Parameter1' LAF ADD_SPLPROT INT_VAR stat = 36 value = 18 relation = 5 RET STR_N18 = new_row END // Strength != 18 LAF ADD_SPLPROT INT_VAR stat = 37 value = 0 relation = 5 RET EXSTR_N0 = new_row END // EXStrength != 0 LAF ADD_SPLPROT INT_VAR stat = 37 value = 1 relation = 3 RET EXSTR_L1 = new_row END // EXStrength < 1 LAF ADD_SPLPROT INT_VAR stat = 37 value = 50 relation = 2 RET EXSTR_G50 = new_row END // EXStrength > 50 LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L1 relation = EXSTR_G50 RET STR_1_50 = new_row END // EXStrength != 1-50 LAF ADD_SPLPROT INT_VAR stat = 37 value = 51 relation = 3 RET EXSTR_L51 = new_row END // EXStrength < 50 LAF ADD_SPLPROT INT_VAR stat = 37 value = 75 relation = 2 RET EXSTR_G75 = new_row END // EXStrength > 76 LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L51 relation = EXSTR_G75 RET STR_51_75 = new_row END // EXStrength != 51-75 LAF ADD_SPLPROT INT_VAR stat = 37 value = 76 relation = 3 RET EXSTR_L76 = new_row END // EXStrength < 76 LAF ADD_SPLPROT INT_VAR stat = 37 value = 90 relation = 2 RET EXSTR_G90 = new_row END // EXStrength > 90 LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L76 relation = EXSTR_G90 RET STR_76_90 = new_row END // EXStrength != 76-90 LAF ADD_SPLPROT INT_VAR stat = 37 value = 91 relation = 3 RET EXSTR_L91 = new_row END // EXStrength < 91 LAF ADD_SPLPROT INT_VAR stat = 37 value = 99 relation = 2 RET EXSTR_G99 = new_row END // EXStrength > 100 LAF ADD_SPLPROT INT_VAR stat = 0x103 value = EXSTR_L91 relation = EXSTR_G99 RET STR_91_99 = new_row END // EXStrength != 91-99 LAF ADD_SPLPROT INT_VAR stat = 37 value = 100 relation = 5 RET EXSTR_N100 = new_row END // EXStrength != 100 LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = EXSTR_N0 RET STR_CHECK_18 = new_row END // Strength = 18/0 (not ((not STR18) or (not EX00))) LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_1_50 RET STR_CHECK_18_1_50 = new_row END // Strength = 18/1 - 18/50 LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_51_75 RET STR_CHECK_18_51_75 = new_row END // Strength = 18/51 - 18/75 LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_76_90 RET STR_CHECK_18_76_90 = new_row END // Strength = 18/76 - 18/90 LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_76_90 RET STR_CHECK_18_91_99 = new_row END // Strength = 18/90 - 18/99 LAF ADD_SPLPROT INT_VAR stat = 0x104 value = STR_N18 relation = STR_100 RET STR_CHECK_18_100 = new_row END // Strength = 18/100 COPY ~X/CS-TRY.spl~ override SAY NAME1 ~CS TRY~ LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 16 STR_VAR parameter2 = STR_CHECK resource=~RET+1D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 17 STR_VAR parameter2 = STR_CHECK resource=~RET+1D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 STR_VAR parameter2 = STR_CHECK_18 resource=~RET+2D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 STR_VAR parameter2 = STR_CHECK_18_1_50 resource=~RET+3D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 STR_VAR parameter2 = STR_CHECK_18_51_75 resource=~RET+3D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 STR_VAR parameter2 = STR_CHECK_18_76_90 resource=~RET+4D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 STR_VAR parameter2 = STR_CHECK_18_91_99 resource=~RET+5D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 STR_VAR parameter2 = STR_CHECK_18_100 resource=~RET+6D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 19 STR_VAR parameter2 = STR_CHECK resource=~RET+7D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 20 STR_VAR parameter2 = STR_CHECK resource=~RET+8D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 21 STR_VAR parameter2 = STR_CHECK resource=~RET+9D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 22 STR_VAR parameter2 = STR_CHECK resource=~RET10D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 23 STR_VAR parameter2 = STR_CHECK resource=~RET11D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 24 STR_VAR parameter2 = STR_CHECK resource=~RET12D_#~ END LPF ADD_SPELL_EFFECT INT_VAR opcode = 326 target = 1 timing = 0 duration = 2 parameter1 = 16 STR_VAR parameter2 = STR_CHECK resource=~RET14D_#~ END COPY_EXISTING_REGEXP ~.*\.spl~ override READ_BYTE 0x27 type READ_BYTE 0x84 speed READ_SHORT 0x68 ab_num PATCH_IF ab_num > 0 BEGIN PATCH_IF (type = 10) THEN BEGIN LPF ADD_SPELL_EFFECT INT_VAR opcode = 328 target = 2 timing = 0 duration = 1 parameter2 = 97 special = 1 END END PATCH_IF (speed = 0 || speed = 1) THEN BEGIN LPF ADD_SPELL_CFEFFECT INT_VAR opcode = 328 target = 1 timing = 0 duration = 1 parameter2 = 36 special = 1 END END PATCH_IF (speed = 2 || speed = 3) THEN BEGIN LPF ADD_SPELL_CFEFFECT INT_VAR opcode = 328 target = 1 timing = 0 duration = 2 parameter2 = 36 special = 1 END END PATCH_IF (speed = 4 || speed = 5) THEN BEGIN LPF ADD_SPELL_CFEFFECT INT_VAR opcode = 328 target = 1 timing = 0 duration = 3 parameter2 = 36 special = 1 END END PATCH_IF (speed = 6 || speed = 7) THEN BEGIN LPF ADD_SPELL_CFEFFECT INT_VAR opcode = 328 target = 1 timing = 0 duration = 4 parameter2 = 36 special = 1 END END PATCH_IF (speed = 8 || speed = 9) THEN BEGIN LPF ADD_SPELL_CFEFFECT INT_VAR opcode = 328 target = 1 timing = 0 duration = 5 parameter2 = 36 special = 1 END END END BUT_ONLY
I'm looking for a mod simplifying memorizing sequencer/сontingency type spells. In order not to pronounce before each fight the same combination of 3-6 long spells thrice.
I want the used sequences/сontingency to be restored after rest or so that they can be made with the same one button.
Maybe it's an AI script with hot keys like http://www.gibberlings3.net/cirerrek/seqmem.php
In example, what should I edit & create structure of folder in order to translate mod adding new items to the game?
Sorry if this was asked before, but I couldn't find it.
Thank you,
It is this component (with others all well) is not installed on BG2: EE.
Error:
It distresses me that it works only for the Mages. The Sorcerers lose the ability to create the Sequencer / Contingent spells.
Metamagic:
This component makes revisions to the various Sequencer and Contingency spells in order to provide Mages with a unique ability unavailable to Sorcerers. If this component is installed, Sorcerers will be unable to learn Sequencer or Contingency spells.
Minor Sequencer, Spell Sequencer, Spell Trigger, and Contingency are removed from the spell selection tables and are replaced with innate abilities. These innate abilities function identically to the original spells, but must first be unlocked by learning the spell from a scroll, casting that spell, and then resting.
Chain Contingency is converted to a High Level Ability, and may be selected by Mages, Mage/Thieves, and Cleric/Mages via the high level ability selection menu.
By the way, are there ways to interrupt spell-casting other than by damage? Effect 60 doesn't stop it if the process is already on the way. Feeblemind for 1 second can do it, Pause curiously returns the character to the casting animation and the spell completes, Stun looks too unnatural, but all of this isn't quite right. I'm making a mechanism for interrupting, with some special effects, and it looks and sounds the best when the casting character gets struck for some damage. Then he recoils, grunts in pain, and the spell fizzles (though sometimes the glow plays out for the whole casting time - a mystery of Mystra). But they only cry out if damage is more than 0, and I'd rather not hurt them for real, even if I heal the damage right away. Who knows, they may just have 1 hp, or it may trigger a contingency... Is there anything that provokes screaming and/or breaks a spell without lowering hit points?
Entries 94 and 144 should be (STR NOT = 18) and (EXSTR NOT = 100), respectively.
It only returns true if both entry 94 and 144 are false (not match).
Entry 94 returns false only when strength is 18.
Entry 144 returns false only when extrastrength is 100.
So this entry returns true when strength is 18 and extrastrength is 100. Wild Surge - must be active when casting completes. Not likely useful here.
Opcode 148, Parameter2=0.
Higher priority script actions/player input. (attack/move).
Like damage, none reliably work on spells with zero casting time.
The mod installed now, I'm going to check how Strength and the spell effects work. But I'm noticing a strange thing about this tp2 file. I have copied it together with all subfolders from another mod I was working on, just so I wouldn't need to create them manually. Then I deleted superfluous files and folders and changed all of the references. The old mod is not mentioned anywhere in this tp2. Yet somehow the setup still refers to that one's tp2 file and errors in it. The installation completes, the result isn't even "with warnings," but the results point to that other file. Do you have any idea why this may be happening?
Another thing. I have an invisible minion scripted to look around for a SPECIFIC value and then check allegiance. If it's an enemy, the minion casts a spell on it. There is only a second to do this before the SPECIFIC change expires. In a crowd, will I get better results if I give the minion protection from GOODCUTOFF? How is that going to work, the same way as with blindness - if I don't see you, you don't exist for me? I'm hoping to prevent the minion from scanning friendlies at all.
Take a look at Tweaks, which has (I think) 10 different translations. I've set up the file structure such that all of the translation files are in separate, language-specific folders inside a 'languages' folder. Near the top of the mod's main tp2 file, you'll find something like this: Each language has at least three entries. The first is how it's presented in the installer in the language menu, the second is the name of the language's folder, and finally one or more tra files are listed. Not all tra files are listed here, only the ones needed by the installer itself--you'll notice that Tweaks uses 12 tra files, but the English option only needs two loaded at install.
So, if the user selected to install the Polish language option of Tweaks, the installer would load ~cdtweaks/languages/english/setup.tra~ and ~cdtweaks/languages/polish/setup.tra~, in that order. This is a bit of a trick--since English is the 'native' language of the mod, I always know that the English setup.tra file is the most complete. By loading the same file in Polish next, it will then override the English strings with their Polish translations. Any strings which are not present in the Polish tra file will be presented in English, at least.
Tra files themselves are pretty straightforward. Here's a chunk of the English and Polish setup.tra files: If the user selects Polish, the mod will install using the second set of strings; in English it will use the first. The actual work of translating a mod is essentially grabbing the English tra files, copying them, and then replacing the text with its Polish equivalent. Mind the tilde marks, as they are important, but otherwise that's essentially it. Once complete, you just need to poke the mod author--sometimes repeatedly--until they integrate and put out the new, translated release.
The ADD_SPELL_EFFECT function adds new effects as the last effect by default.
You can override this by using "insert_point":
Okay... Some of the script actions are going to have to be done from inside projectiles instead, scripts are too slow. Can you explain what the IDS values are for there, and Neg. IDS1, and "IWD Style Check"?
"IWD Style Check" enables these fields, I don't know why they don't work normally.
Each pair works like Opcode 318, using values from SPLPROT.
0x3c = Parameter1
0x3e = Parameter2
0x40 = Parameter1
0x42 = Parameter2
If the field pair is 0/0, it is not used.
By default, any creature that matches BOTH values is not affected by the projectile.
With "Use either IDS", any creature that matches EITHER value to not affected by the projectile.
The "Neg. IDS1" and "Neg IDS2" change there respective check from "Match" to "Not Match".
Unlike ocpode 318, each of these fields is only 2 bytes, not 4, so it cannot be used for checks that require Parameter1 values over 65535 (mostly KIT and STATE checks). You would have to add entries to SPLPROT for specific kits or state combinations.
Theres only 2 real reasons to use these in place of Opcode 318:
You can place script-name based marker variables on target/source when a script issues the "Attack()" action, could work for non-controllable creatures, until they get charmed/confused/panicked/etc...
But in general, an attacking creature is blind idiot flailing about. It doesn't directly know who it's attacking, if it's attacking, or when it attacks. It only knows when it hits someone and consequences happen.
Let's say I want to know which two CREs are used in the cutscene at the beginning of Siege of Dragonspear, for example.