Skip to content

General mod Questions thread

1646566676870»

Comments

  • jmerryjmerry Member Posts: 3,822
    BCaesar wrote: »
    Hi all, I've got a question.
    Is there any way to add a spell to someone's spell book mid-game?
    For example as a quest reward I want to give Dorn Call Lightning as a level 3 spell.

    I'm pretty sure it's exactly the same as adding a special ability. The Avenger's 2da file uses the same code for adding innate shapeshifting abilities as it does for adding the spells they get in their spellbook, after all.
    The game chooses whether to put it in the spellbook or the special ability button based on how that spell is flagged (wizard, priest, innate, or some rarer options). So, if you just give him the existing priest spell, it'll go in his spellbook. If you wanted to put a mage spell like Larloch's Minor Drain in his spellbook instead, you'd have to clone that as a priest spell.
    Timbo0o0o0
  • SatrhanSatrhan Member Posts: 75
    I'm trying to make a change to an installed soundset without having to reinstall my entire mod setup.
    I played through BG1 with this particular soundset with no problems. However in BG2 it has a slight issue, somehow two of the common confirmation sounds have been replaced with the ones that you should get when repeatedly clicking on the character. Hearing a snarky comment about every other time I get feedback on an order is getting old, quick.
    Of course I installed the voicepack as one of the first mods, because why not, not like anything can go wrong with them right?

    I had hoped it would be as simple as replacing the soundfile in the override folder, but no such luck.
    I've learned that the sounds are governed by the CHARSND.2da file, and have found which lines could correspond to the sound. But its all a five or six numbers long string, no reference to a filename.
    Still leaves about ten options to blindly try, so might be a bit of a drag to check them all.

    So questions;
    1) will changing the sounds in here work? I don't mind having doubles of some other sounds, just not the snark.
    2) can I somehow see which number corresponds to which sound effect?
  • CahirCahir Member, Moderator, Translator (NDA) Posts: 2,819
    I have a technical question. What is the engine tolerance for the sound files length in other languages? Does it need to be the same length, or maybe there is some tolerance (i.e +/-15%), or no limit in the sound file length at all?
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    @Bubb
    As usual, I need your help with some other script actions.
    1. Can you confirm that if a creature is performing either "RandomWalk()" or "RandomWalkContinuous()" or "RandomTurn()", then "ActionListEmpty()" will never return true?
    2. Can you confirm that the time in "RandomWalkTime(I:Time*)" or "RandomWalkContinuousTime(I:Time*)" is measured in script passes? For instance, if I write "RandomWalkTime(1)", then the targeted creature will walk for one round. After that, the engine will forcibly stop it. Is that correct?
    3. How much time is "RandomTurn()" supposed to last? It seems to last indefinitely, but that'd be kinda weird, so I'm sure I'm missing something...
  • BubbBubb Member Posts: 999
    edited October 2020
    @Luke93:

    1) Correct, these actions will never stop, (unless interrupted in specific situations), and thus never leave the action list.

    2) "Time" represents how many times the action will be ticked before terminating. Actions are normally ticked once per second at 30FPS.

    Note that:
    • RandomTurn() / RandomWalk() executes Wait() for a random amount of time, (1-40 seconds), if the creature goes off-screen.
    • RandomTurn() waits 1-10 seconds between each evaluation.
    • RandomWalk() has a 50/50 chance to MoveToPoint(), or do a pass of RandomTurn(), (including RandomTurn()'s wait time).
    • RandomWalkContinuous() is the same as RandomWalk(), just with the offscreen-wait removed and no RandomTurn() chance.

    While these actions are Wait()'ing, they won't be ticked. Thus, a RandomWalkTime(1) can technically go into a 10 second Wait() immediately, and be blocking the action list for much longer than a second. If the parameter was 5, for example, this "5" wouldn't be counting down while the script is waiting.

    3) RandomTurn() lasts forever.

    _Luke_
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    @Bubb

    OK, here's another one: "SUMMLIMT.2DA"
    • What creatures qualify as NORMAL? Only those whose GENDER (0x275) is SUMMONED?
    • What creatures qualify as CELESTIAL?
    • Is it possible to add other entries/LABELs?
  • BubbBubb Member Posts: 999
    edited November 2020
    @Luke93:

    1) When engine is summoning any creature, checks for existing-creatures that match:

    (EA <= 15 and EA != 3) and (GENDER = 6 or GENDER = 9)
    

    And holds them to the NORMAL limit.

    2) When engine is summoning a creature with one of the following hardcoded resrefs, ["DEVAGOOD", "DEVAEVIL", "PLANGOOD", "PLANEVIL"], additionally checks for existing-creatures that match:

    (EA <= 15 and EA != 3) and (GENDER = 5) and (animationID = 0x7F3B or animationID = 0x7F3C)
    

    And holds them to the CELESTIAL limit.

    * Side note: a CELESTIAL will be blocked if the NORMAL limit has already been reached, but the NORMAL limit won't be blocked if the CELESTIAL limit has already been reached. Aka if you summon your planetar first, you can have 5 NORMAL + 1 CELESTIAL. If you summon your planetar last, you can only have 4 NORMAL + 1 CELESTIAL.

    3) No
    kjeron_Luke_
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited November 2020
    Bubb wrote: »
    3) RandomTurn() lasts forever.

    But will the script be processed again from the top of the file as usual (even if this action lasts forever)?

    That is to say: if the following block was part of the player script, one press of K would get them into endless rotation...?
    IF
    	HotKey(K)
    THEN
    	RESPONSE #100
    		RandomTurn()
    END
    

    [SOLVED, hopefully]: it does cause continuous turning. It's clearly not blocking either, since a True() block after it also triggers all the time. Another way to test it:
    IF
    	Range(Protagonist,10)
    	See(Protagonist)
    THEN
    	RESPONSE #100
    		DisplayStringHead(Myself,3)
    		SmallWait(100)
    END
    
    IF
    	True()
    THEN
    	RESPONSE #100
    		RandomTurn()
    END
    
    Post edited by _Luke_ on
  • BCaesarBCaesar Member Posts: 453
    Question: Is there a way to make someone leave the group but not talk to me after?

    We run into endless problems when we kick someone out and have them turn Enemy() but then they wander over and talk to Player1. We've tried all sorts of stuff that's probably 80% effective depending on the NPC and the save. Anyone know a fail-safe way to just turn it off, so someone will just leave and not talk?

    Thanks.
  • BCaesarBCaesar Member Posts: 453
    BCaesar wrote: »
    Question: Is there a way to make someone leave the group but not talk to me after?

    We run into endless problems when we kick someone out and have them turn Enemy() but then they wander over and talk to Player1. We've tried all sorts of stuff that's probably 80% effective depending on the NPC and the save. Anyone know a fail-safe way to just turn it off, so someone will just leave and not talk?

    Thanks.

    I found it!
    ChangeAIScript("",DEFAULT)

    If I put that in NPC's don't talk to me after they leave.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    @Bubb

    Could you please tell us what are the hidden mechanics behind opcode #245 and #246?
    Thanks in advance!
  • TaylanTaylan Member Posts: 76
    Is there a quick, up-to-date rundown of NI modding somewhere for someone who's already a programmer?

    My first question would be how to decompile BIF files.
  • RatatoskrRatatoskr Member Posts: 711
    Not sure if anyone knows the answer to this, but one of our players is getting a weird gotcha in their heavily modded EET game.

    For them, the pickpocket skill on our NPC thief is stuck at 45 on the character screen. When they level up, they can add to it and it should be over 100, but the character screen doesn't change. Any ideas?

    This isn't happening on any of my games and I don't see anything that should cause it. Thanks.
  • jasteyjastey Member Posts: 2,669
    Taylan wrote: »
    Is there a quick, up-to-date rundown of NI modding somewhere for someone who's already a programmer?

    My first question would be how to decompile BIF files.

    @Taylan BIF files are just the compressed archives (hope that's the right term) the engine stores all files in. You can browse and export the game files in BIFs using a tool like Near Infinity.
    Taylan
  • TaylanTaylan Member Posts: 76
    jastey wrote: »
    Taylan wrote: »
    Is there a quick, up-to-date rundown of NI modding somewhere for someone who's already a programmer?

    My first question would be how to decompile BIF files.

    @Taylan BIF files are just the compressed archives (hope that's the right term) the engine stores all files in. You can browse and export the game files in BIFs using a tool like Near Infinity.

    Thanks for the response! I've already gotten my answers on the G3 forums:

    https://www.gibberlings3.net/forums/topic/32377-modding-basics-for-programmers/

    The most important things seem to be:
    1. NearInfinity for digging around in game files and editing them to test stuff.
    2. The IESDP for detailed information on the file formats.
    3. The WeiDU Documentation for understanding how to create a packaged mod with a convenient installer.
    jastey
  • ArunsunArunsun Member Posts: 1,592
    Hi everyone,
    After too long a break I'm back to trying to make mods, but I am super rusty and have no idea how to handle some of my ideas for the mod.

    The mod I'm trying to create is a mage kit centered around a new debuff, with some spells having effects only if the target is affected by that debuff.

    Here are my questions:

    The debuff in question has a constant effect, but its duration varies depending on the constitution of the target and the level of the caster. All of the spells that apply the debuff apply it in the same way, but sometimes with a save, sometimes without it. All undeads are immune to it and magic resistance does not affect it, even though it can affect the other components of the spell. What I plan to do is to have:
    • A first spell that checks for the saving throw. If the saving throw is failed, it applies the next spell through opcode 326
    • That next spell checks for undeath, and if the target is not undead, applies another spell, through opcode 326
    • That other spell checks for each constitution interval and apply the relevant spell with the correct duration, from a series of other spells which apply the debuff for a certain duration. The idea here is to take advantage of the fact that effects that appear later in the list are executed after, so I can just apply all the effects by checking for Constitution > X, and the next effect which checks for Constitution > Y overrides the effect of the previous spell by removing it and applying the next one, and so on until the target does not pass the Constitution > Z check, in which case only the last spell on which she passed the check is applied
    My plan is to start the chain with the first spell for those that require a saving throw and with the second one for those that bypass the saving throw. Can anyone confirm that this would work? Since it really is the core of the gameplay of the kit, I really need that to work properly. I'm open to alternative, perhaps more efficient solutions.

    I would like to limit the schools to which the kit has access to only 3: Alteration, Abjuration and Illusion. Is there any way to do that cleanly? It would mean preventing them from learning spells, using related scrolls and, ideally preventing picking the spells in the character builder for characters that do not belong to these three schools (though for that last point I would always have a cleanup spell applied post character creation that removes everything the character should not have).

    Regarding the debuff itself, since many spells will have different or additional effects depending on the debuff, the only way I could think of was to expand the SPLSTATE.IDS table to add my own state, and then check for that condition in my spells using OPCODE 326, which makes it easy to do if/else using the triggers SPLSTATE = or !=. I know that splstate.ids is a shared resource, meaning I might override another mod that does the same thing with the same value for their custom status, so I was wondering if there was a better way to do things. If there is no better way, is SPLSTATE.IDS actually limited to 255 as it appears to be in the file, or does it have another limit? Using something beyond 255 would reduce the risk of collision with another mode.

    Cheers and thank you in advance for your help!
  • AllbrotherAllbrother Member Posts: 261
    edited February 2021
    Sorcerer doesn't have a clab.2da (the 01 usually reserved for trueclass is applied to the DD instead). How would one go about assigning them special abilities?
  • RatatoskrRatatoskr Member Posts: 711
    Hi folks. I just ran into a weird glitch that I'm pretty sure is caused by someone else's mod, but I'd love to fix anyway if possible.

    After creating way too much fancy new mod stuff with Cromwell, I can no longer remove my NPC thief from my party while their offhand is empty and I cannot remove HaerDalis at all. If I attempt to do so, my game crashes. It's definitely the item creation that caused this since I have before/after saves and my other characters are fine.

    Any ideas? I'd like to track down the cause of the glitch but I'm not even sure where to start.
  • harperfan7harperfan7 Member Posts: 30
    edited February 2021
    I'm trying to mod BGEE for the first time. I moved the game to a folder in my desktop to avoid steam updates. I installed SCS, tweaks anthology, and spell revisions. Went through the little black-background text box that asks all the (i) (n) questions. The mods are in the games folder (specifically "Baldurs Gate Enhanced Edition" folder, which is in "BGEE"). But when I start up the game the mods aren't active. I feel like I'm missing a step.

    edit: figured it out
    Post edited by harperfan7 on
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2021
    _Luke_ wrote: »
    @Bubb

    Could you please tell us what are the hidden mechanics behind opcode #245 (0xF5) and #246 (0xF6)?
    Thanks in advance!

    Bumped...
  • The_Baffled_KingThe_Baffled_King Member Posts: 147
    edited March 2021
    Modding the chapter changes and dream sequences in BG:EE

    Can anyone tell me, please, if it's possible to mod BG:EE so that the cut-scenes and the dream sequences marking transitions between chapters can occur in a different order? It's one of a few things that might motivate me to try to learn to mod, but I want to know beforehand whether it's achieveable. Any pointers as to how to make these changes are also much appreciated! To clarify what I mean:

    The vanilla game advances through Chapters 2-3-4-5 in sequential order, with the chapter transitions triggered by a unique event (Davaeorn dies, etc). Each transition is linked to a unique cut-scene (image, text screen, and audio) and dream sequence (image, text screen, and audio), the latter of which provides CHARNAME with a new special ability. Additionally, a new section in CHARNAME's journal is created for the new chapter. The only valid path accepted by the game is as follows:

    2: (CLW/LMD) Nashkel Mines - 3: (CLW/LMD) Bandit Camp - 4: (SP/H) Cloakwood Mines - 5: (SP/H) Baldur's Gate.

    I want to create a more open game world in which the following 6 paths are all possibilities:

    2: (CLW/LMD) Nashkel Mines - 3: (CLW/LMD) Bandit Camp - 4: (SP/H) Cloakwood Mines - 5: (SP/H) Baldur's Gate.
    2: (CLW/LMD) Nashkel Mines - 3: (CLW/LMD) Cloakwood Mines - 4: (SP/H) Bandit Camp - 5: (SP/H) Baldur's Gate.
    2: (CLW/LMD) Bandit Camp - 3: (CLW/LMD) Nashkel Mines - 4: (SP/H) Cloakwood Mines - 5: (SP/H) Baldur's Gate.
    2: (CLW/LMD) Bandit Camp - 3: (CLW/LMD) Cloakwood Mines - 4: (SP/H) Nashkel Mines - 5: (SP/H) Baldur's Gate.
    2: (CLW/LMD) Cloakwood Mines - 3: (CLW/LMD) Nashkel Mines - 4: (SP/H) Bandit Camp - 5: (SP/H) Baldur's Gate.
    2: (CLW/LMD) Cloakwood Mines - 3: (CLW/LMD) Bandit Camp - 4: (SP/H) Nashkel Mines - 5: (SP/H) Baldur's Gate.

    I still want the chapter transitions and the granting of a new ability to be marked by a cut-scene and dream sequence, respectively. In order for this to make sense with the alternative paths, I would need to write 12 or 15 alternative cut-scenes to replace the existing 3. As in the vanilla game, the game would recognise the events that trigger a chapter increment (Mulahey dies, Tazok's papers are stolen, Davaeorn dies), but it would allow the chapter to increment by one regardless of the order in which the events happen, and it would choose the cut scene that corresponds to whatever path CHARNAME takes in each game.

    The dream sequences would remain the same in terms of their content, but the game would need to recognise that the dreams will often need to be played in a different order (eg the Bandit Camp dream always plays after the player pilfers Tazok's papers, regardless of whether they do so before, between, or after the deaths of Mulahey and Davaeorn). Finally, the game would ideally also recognise that the dream sequences following the Nashkel Mines, the Bandit Camp, and the Cloakwood Mines may award either CLW/LMD or SP/H, so that CHARNAME always receives a second CLW/LMD before receiving two SP/H.

    Using the Cloakwood Mines as an example, I see that the change in chapter is triggered with IncrementChapter("CHPTXT5"), which points at a 2DA file with stringrefs for the name of the chapter and the content of the text screen (CHPTXT5.2DA). I also see a similar 2DA file with stringrefs for the content of the text screen for the dream sequence, and the file names for the .SPL resources that relate to the relevant CHARNAME special abilities (DRMTXT5.2DA). Finally, I see the .WAV files and the .MOS files providing audio and image for both the cut-scene (CHAPTER4.WAV and GUICHP5A.MOS) and the dream sequence (DREAM4G/E.WAV and GUIDRM5.MOS). What I can't see is how the game tells itself what .WAV and .MOS files to access, or how it tells itself to look at DRMTXT5.2DA.

    Of course, I have no idea what I'm doing, so that may be why I can't find what I'm looking for... Sorry by the way for the long post!
  • afrothundaaaaafrothundaaaa Member Posts: 16
    edited August 2021
    This comment was removed
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited September 2021
    Bubb wrote: »
    @Luke93: By "straight" I mean that literally only object selectors work this way. Nesting them inside conventional objects, (anything in OBJECT.IDS), doesn't constantly reevaluate. I'm starting to question whether this object selector behavior was even intentional, or if it's just an unintended side effect of how AttackReevaluate() processes the object internally.

    @Bubb

    May I resurrect this topic...? I've got a related question.

    Even if "NearestEnemyOfType([EA.GENERAL.RACE.CLASS.SPECIFIC.GENDER.ALIGN])" does not constantly reevaluate, it is still true that the specified object is not bound, right?

    In other words: can you confirm that the following script
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(NearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(NearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(SecondNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(SecondNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(ThirdNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(ThirdNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(FourthNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(FourthNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(FifthNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(FifthNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(SixthNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(SixthNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(SeventhNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(SeventhNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(EighthNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(EighthNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(NinthNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(NinthNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(TenthNearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(TenthNearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    

    is basically identical to this one
    IF
    	OR(2)
    		!GlobalTimerNotExpired("spell_cast","LOCALS")
    		CheckStatGT(Myself,0,AURACLEANSING)
    	HaveSpell(WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    	CheckStatLT(Myself,60,SPELLFAILUREMAGE)
    	See(NearestEnemyOfType([0.HUMANOID]))
    THEN
    	RESPONSE #100
    		SetGlobalTimer("spell_cast","LOCALS",ONE_ROUND)
    		Spell(NearestEnemyOfType([0.HUMANOID]),WIZARD_MAGIC_MISSILE)  // SPWI112.SPL (Magic Missile)
    END
    

    That is: if I'm always interested into the Nearest creature of a certain type, then I can safely omit "SecondNearestEnemyOfType()", "ThirdNearestEnemyOfType()", "FourthNearestEnemyOfType()", etc...

    And of course, the same holds for straight object selectors, i.e.: the following script
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See([PC])
    THEN
    	RESPONSE #100
    		AttackReevaluate([PC],30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(SecondNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(SecondNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(ThirdNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(ThirdNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(FourthNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(FourthNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(FifthNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(FifthNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(SixthNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(SixthNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(SeventhNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(SeventhNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(EighthNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(EighthNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(NinthNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(NinthNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(TenthNearest([PC]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(TenthNearest([PC]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See([GOODCUTOFF])
    THEN
    	RESPONSE #100
    		AttackReevaluate([GOODCUTOFF],30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(SecondNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(SecondNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(ThirdNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(ThirdNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(FourthNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(FourthNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(FifthNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(FifthNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(SixthNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(SixthNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(SeventhNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(SeventhNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(EighthNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(EighthNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(NinthNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(NinthNearest([GOODCUTOFF]),30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See(TenthNearest([GOODCUTOFF]))
    THEN
    	RESPONSE #100
    		AttackReevaluate(TenthNearest([GOODCUTOFF]),30)
    END
    
    is identical to this one
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See([PC])
    THEN
    	RESPONSE #100
    		AttackReevaluate([PC],30)
    END
    
    IF
    	Allegiance(Myself,EVILCUTOFF)
    	See([GOODCUTOFF])
    THEN
    	RESPONSE #100
    		AttackReevaluate([GOODCUTOFF],30)
    END
    
    ?
    Post edited by _Luke_ on
Sign In or Register to comment.