Jump to content


CamDawg

Member Since 18 Sep 2003
Offline Last Active Private

Topics I've Started

Mods are actually... legal?

03 March 2018 - 04:51 PM

This came up in a discussion on being able to monetize NWNEE servers on the Beamdog forums, but apparently WotC has a fan content policy that's actually fairly liberal.

 

Essentially, as long as your content--and AFAICT this means mods--is

  • free (though donations and ad revenue are allowed)
  • marked as unofficial (they even have recommended language)
  • legal otherwise (e.g. no copyrighted content from someone else)

it's good to go.


Of cleric kits and strongholds

08 February 2018 - 08:02 PM

I've seen this come up a few places, so I thought I'd write up some helpful advice on integrating your shiny new cleric kit into the BG2 cleric strongholds.
 
Players are routed to one of the three potential strongholds in the Temple District based on their class and alignment. After you meet Gaal preaching in the street, you're approached by one of the temple leaders--Arval for Lathander, Oisig for Helm, or Nallabir for Talos--who then initiates the Unseeing Eye quest. After successful completion of the quest, clerics are offered a place in the temple and others are thanked and dismissed.
 
After Gaal speaks, determining who spawns is a pretty straightforward process:

  1. Non-clerics get Oisig and work for Helm.
  2. Clerics kitted to one of the three temples always get that temple, e.g. Morninglords of Lathander will always be approached by Arval to work for the Lathander temple.
  3. All other clerics get approached based upon their alignment:
    • In vanilla BG2 good go to Lathander, neutral to Helm, and evil to Talos.
    • In EE or with Divine Remix installed, Lathander takes NG and CG, Helm takes LN and LE, and Talos takes CN, CE, and NE. LG will get approached by Lathander, but have the option of working for Helm, and TN will get approached by Helm but be able to work for Lathander.

If you're satisfied with the existing alignment distribution for your kit, then you're done. For example, EEs introduced the Tyr kit with allowed alignments LG, LN, or NG. Nothing was done for the temples, so (per step 3, above) Tyr priests will either go to Lathander (NG), Helm (LN), or get approached by Lathander with an option to work for Helm (LG). This is the trivial case, of course.

 

Let's take a more interesting example, such as a Tempus kit. Tempus, being CN, accepts followers of CG, CN, CE, and TN alignments. If we let it go to the defaults, as we did with Tyr, then CE and CN followers serve Talos, CG to Lathander, and TN are approached by Helm but can work for Lathander. Tempus and Helm and diametrically opposed, and the idea of Oisig approaching a Battleguard of Tempus for assistance is particularly unsatisfying from a role-playing standpoint. So let's walk through the process of how these mechanisms work, and what we need to do to change them.

 

The good news is that all of this is determined, more or less, by who spawns after Gaal speaks. Once your questgiver has spawned, you're locked into that temple--there are no more kit checks, so if you can get it right up front, the rest will follow.

 

First, the initial spawn of the temple rep. This is controlled by four blocks in the temple district's area script, ar0900.bcs. A quick note, before we go further: the code and snippets are from BG2EE, but the ideas and mechanisms are the same, even if the code required is going to vary a bit.

IF
  Global("GaalSpoke","AR0900",1)
  OR(2)
    Alignment(Player1,MASK_GOOD)
    Kit(Player1,GODLATHANDER)
  OR(6)
    Class(Player1,CLERIC)
    Class(Player1,FIGHTER_CLERIC)
    Class(Player1,CLERIC_MAGE)
    Class(Player1,CLERIC_THIEF)
    Class(Player1,FIGHTER_MAGE_CLERIC)
    Class(Player1,CLERIC_RANGER)
  !Kit(Player1,GODHELM)
  !Kit(Player1,GODTALOS)
THEN
  RESPONSE #100
    Wait(2)
    CreateCreature("bharval",[3077.1630],SW)  // High Mornmaster Arval
    SetGlobal("GoodMask","AR0900",1)
    SetGlobal("GaalSpoke","AR0900",2)
END

IF
  Global("GaalSpoke","AR0900",1)
  OR(4)
    Alignment(Player1,LAWFUL_NEUTRAL)
    Alignment(Player1,NEUTRAL)
    Alignment(Player1,LAWFUL_EVIL)
    Kit(Player1,GODHELM)
  OR(6)
    Class(Player1,CLERIC)
    Class(Player1,FIGHTER_CLERIC)
    Class(Player1,CLERIC_MAGE)
    Class(Player1,CLERIC_THIEF)
    Class(Player1,FIGHTER_MAGE_CLERIC)
    Class(Player1,CLERIC_RANGER)
  !Kit(Player1,GODLATHANDER)
  !Kit(Player1,GODTALOS)
THEN
  RESPONSE #100
    Wait(2)
    CreateCreature("bhoisig",[3077.1630],SW)  // High Watcher Oisig
    SetGlobal("NeutralMask","AR0900",1)
    SetGlobal("GaalSpoke","AR0900",2)
END

IF
  Global("GaalSpoke","AR0900",1)
  OR(4)
    Alignment(Player1,CHAOTIC_NEUTRAL)
    Alignment(Player1,NEUTRAL_EVIL)
    Alignment(Player1,CHAOTIC_EVIL)
    Kit(Player1,GODTALOS)
  OR(6)
    Class(Player1,CLERIC)
    Class(Player1,FIGHTER_CLERIC)
    Class(Player1,CLERIC_MAGE)
    Class(Player1,CLERIC_THIEF)
    Class(Player1,FIGHTER_MAGE_CLERIC)
    Class(Player1,CLERIC_RANGER)
  !Kit(Player1,GODLATHANDER)
  !Kit(Player1,GODHELM)
THEN
  RESPONSE #100
    Wait(2)
    CreateCreature("bhnalla",[3077.1630],SW)  // Stormherald Nallabir
    SetGlobal("EvilMask","AR0900",1)
    SetGlobal("GaalSpoke","AR0900",2)
END

IF
  Global("GaalSpoke","AR0900",1)
  !Class(Player1,CLERIC)
  !Class(Player1,FIGHTER_CLERIC)
  !Class(Player1,CLERIC_MAGE)
  !Class(Player1,CLERIC_THIEF)
  !Class(Player1,FIGHTER_MAGE_CLERIC)
  !Class(Player1,CLERIC_RANGER)
THEN
  RESPONSE #100
    Wait(2)
    CreateCreature("bhoisig",[3077.1630],SW)  // High Watcher Oisig
    SetGlobal("NeutralMask","AR0900",1)
    SetGlobal("GaalSpoke","AR0900",2)
END

The fourth block is the catch-all for non-clerics, but the rest follow a predictable pattern--check the variable that the Gaal cutscene has occurred, that Player1 is either a cleric kitted to the temple or matches the alignments laid out above, is a cleric, and is not kitted to one of the other temples. For our Tempus example, it's that second block that poses the problem--a TN Tempus clerics fulfills all of these conditions, so we block it by adding a kit check:

IF
  Global("GaalSpoke","AR0900",1)
  OR(4)
    Alignment(Player1,LAWFUL_NEUTRAL)
    Alignment(Player1,NEUTRAL)
    Alignment(Player1,LAWFUL_EVIL)
    Kit(Player1,GODHELM)
  OR(6)
    Class(Player1,CLERIC)
    Class(Player1,FIGHTER_CLERIC)
    Class(Player1,CLERIC_MAGE)
    Class(Player1,CLERIC_THIEF)
    Class(Player1,FIGHTER_MAGE_CLERIC)
    Class(Player1,CLERIC_RANGER)
  !Kit(Player1,GODLATHANDER)
  !Kit(Player1,GODTALOS)  
  !Kit(Player1,OHTEMPUS)
THEN
  RESPONSE #100
    Wait(2)
    CreateCreature("bhoisig",[3077.1630],SW)  // High Watcher Oisig
    SetGlobal("NeutralMask","AR0900",1)
    SetGlobal("GaalSpoke","AR0900",2)
END

via this WeiDU code

COPY_EXISTING ~ar0900.bcs~ ~override~
  DECOMPILE_AND_PATCH BEGIN
    REPLACE_TEXTUALLY ~\(!Kit(Player1,GODLATHANDER)[ %TAB%%LNL%%MNL%%WNL%]+!Kit(Player1,GODTALOS)\)~ ~\1 !Kit(Player1,OHTEMPUS)~
  END
  BUT_ONLY

This blocks Oisig from spawning for a TN Tempus cleric. However, we still need to spawn Arval in this case. The laziest--and thus, most preferable--way to do this is just to extend the bottom of the script with a bit specifically tailored for such; this is basically a copy-and-paste of the Arval spawn block with altered conditions:

IF
  Global("GaalSpoke","AR0900",1)    
  Alignment(Player1,NEUTRAL)
  Kit(Player1,OHTEMPUS)
  OR(6)
    Class(Player1,CLERIC)
    Class(Player1,FIGHTER_CLERIC)
    Class(Player1,CLERIC_MAGE)
    Class(Player1,CLERIC_THIEF)
    Class(Player1,FIGHTER_MAGE_CLERIC)
    Class(Player1,CLERIC_RANGER)
THEN
  RESPONSE #100
    Wait(2)
    CreateCreature("bharval",[3077.1630],SW)  // High Mornmaster Arval
    SetGlobal("GoodMask","AR0900",1)
    SetGlobal("GaalSpoke","AR0900",2)
END

And now we get Arval for TN Tempus clerics. One last little bit remains to be done for EE games; remember that both Arval and Oisig will be ambivalent to LG/TN clerics, respectively, and we don't want Arval to offer Helm for our TN Tempus cleric. These offers are made in Arval's dialogue (BHARVAL) state 2 and in Oisig's dialogue (BHOISIG) state 2. Once again, it's an easy solution in .d code:

EXTEND_BOTTOM BHARVAL 2 
  IF ~Alignment(Player1,NEUTRAL) Kit(Player1,OHTEMPUS)~ THEN DO ~OpenDoor("DOR0902b") EscapeAreaMove("AR0902",577,650,14)~ UNSOLVED_JOURNAL #3439 EXIT
END

You're basically copying transition 0, but adding new conditions to preempt transitions 1 or 2. In this case, the conditions are that the cleric is a TN follower of Tempus.

 

That's basically it. Once the player enters the temple to speak with the questgiver (Arval, Oisig, or Nallabir) no more kit checks are performed.

 

As always suggestions, feedback, etc. is appreciated.


Small errors in file format pages

24 January 2018 - 10:54 AM

In the container section for the v1.0 area format, the four bounding boxes are all listed as offset 0x38. They should be 0x38, 0x3a, 0x3c, 0x3e.

 

In the item v1.1 page, the info and image at the top of the page are copied from the 1.0 page and are not correct for 1.1 as the header is 154 bytes, not 114.


The Spoiler Topic

15 January 2018 - 02:05 PM

This thread will be for any details beyond the readme that players may want. I was asked over at the BD forums what, exactly, Exotic Items adds to the game.

It's a fairly conservative list of additions:

Spoiler

 

Feel free to ask for further spoilers. :)


Translate IWDification? Here's 90% of it done!

10 January 2018 - 10:45 AM

Since most of the strings for IWDification are pulled directly from IWDEE, I wrote a small tool that anyone can run on their language of IWDEE and generate the majority of the main tra file.

 

Extract this on your IWDEE install, make sure the game language is set to the translation you want, run it, and then uninstall it.

 

It will generate game_strings.tra and game_strings_ee.tra inside the iwdification_translate folder. From there, you have about ~20 strings to translate for game_strings (many of which can be copied from elsewhere, as noted in the generated file), ~5 for game_strings_ee, and ~8 strings for the whole of setup.tra to finish the translation.