Jump to content

Need help with a couple of mini-mods


Recommended Posts

I'm getting a collection of NI patches that I want to turn into a mini-mod, but I'm unsure how to start. Most of the tutorials are for dialog or scripting, but all I want to do is:

Component 1: Foggy weather in more places

1) Append several new lines to FOGAREA.2DA appropriately for an EET build. I doubt anyone would want this mod, and I only play EET, but I'd be open to working out how to do this for the separate EEs as subcomponents. I have NI patches for both the BG and BG2 areas.

2) Patch the fog probability for each area added above.

Component 2:

1) Add/equip the helm of opposite alignment to Viconia at the start. Yes, I know it doesn't make sense that she would still choose Shar as a neutral good cleric, but this solution comes close to explaining why she left the Underdark. More importantly, I actually *like* Viconia's dark, gloomy mood far more than the other available clerics. I know I could alter her alignment, but I prefer to use the helm as it makes more sense in character, and, having her alignment based on an item, gives her a bit of a disability to make up for that ridiculous magic resistance.

2) Patch her script so that she won't leave a good-aligned party at high-rep by checking *specifically* that she has said helm equipped. If the helm is *not* equipped, she behaves as usual. In the event she is killed, it will make things more interesting.

Component 3:

1) If Shades of the Sword Coast is detected, patch the hide-out plane flags for day/night.

I'm doing these by going in after all the mods are installed and patching everything with NI. I haven't found any WEIDU tutorials that specifically cover these sorts of patches, and I would like to write this mini-mod myself so that I know how it works. I'm unsure where to start, though.

Link to comment

Taking a stab at this ...

(1) : How would I do something like this ... first, build a table of the changes we're going to make. Do it as a 2DA file; that way, we can just read it in with READ_2DA_ENTRIES_NOW to get all that in the form of an array. This makes it easy to edit later, as all of the changes we're making are in an easily readable file of their own.

Now, for each row of this table, we're going to do two things. Add a row to FOGAREA.2DA, and edit an ARE file. That's probably best done with two separate loops through the array. The first time around, we have FOGAREA.2DA loaded and use INSERT_2DA_ROW. The second time around, we load up a new ARE file for every row and edit one field in it.

(2) : First off, understand the actual mechanics of characters leaving. Viconia does not ever directly check reputation, only "happiness". Which is based on both party reputation and the character's current alignment. So there's no need to change her script or dialogue at all; if she's wearing the helm, she'll stick around at high reputation and leave at low reputation. All you need to do is add the item to her CRE file(s). That's nice and easy; ADD_CRE_ITEM with the appropriate parameters. You know what? Here's a fully functional version:

Spoiler
ACTION_FOR_EACH viccy IN ~VICONI~ ~VICONI4~ ~VICONI6~ ~viconi6_~ ~viconi7~ ~VICONI8~ ~VICONI9~ ~VICONI11~ ~VICONI13~ BEGIN // All versions except ToB; no need for that campaign.
    COPY_EXISTING ~%viccy%.CRE~ ~override~
        ADD_CRE_ITEM ~HELM02~ #0 #0 #0 ~IDENTIFIED~ ~HELMET~ // Add the helmet.
    BUT_ONLY IF_EXISTS // Skip if this CRE doesn't exist.
END

 

(3) No idea what you're even talking about here. But there are several ways to detect a mod. You can look for the existence of a particular file, either a resource that mod adds or a marker file specifically created to aid this sort of detection. You can use MOD_IS_INSTALLED to be more direct about it. And there are probably other methods out there that I haven't thought of. Whatever method you use here, it should be a predicate requirement for the component; with no need to do anything if the mod isn't detected, you might as well skip it entirely if the condition isn't met.

Then in the body of the component, you go through and make the changes.

Link to comment

Yeah, I kind of assumed there would be some array to array copying for that first one. I'm going to peruse some existing mods that do similar things and see how they did it.

As for Viconia, I was referring to this code in BDVICONI.BCS

Spoiler

IF
    !AreaCheck("bd0120")  // Tomb Safehouse  First Floor
    !AreaCheck("bd0130")  // Tomb Safehouse  Second Floor
    InParty(Myself)
    ReputationGT(Player1,15)
    !HasItemEquipedReal("helm02",Myself)  // Helm of Opposite Alignment << I added this
    Global("bd_viconia_reputation_warning","GLOBAL",0)
THEN
    RESPONSE #100
        SetGlobal("bd_viconia_reputation_warning","GLOBAL",1)
END

IF
    !AreaCheck("bd0120")  // Tomb Safehouse  First Floor
    !AreaCheck("bd0130")  // Tomb Safehouse  Second Floor
    InParty(Myself)
    See(Player1)
    CombatCounter(0)
    !See([ENEMY])
    Global("bd_viconia_reputation_warning","GLOBAL",1)
    ReputationGT(Player1,15)
    !GlobalTimerNotExpired("bd_reputation_warning_timer","global")
THEN
    RESPONSE #100
        SetGlobalTimerRandom("bd_reputation_warning_timer","global",ONE_HOUR,TWO_HOURS)
        StartDialogueNoSet(Player1)
END

 

Link to comment

Hmm ... yeah, OK, a warning for high reputation is something that you wouldn't want going off if Viconia is flipped to good.

That's also the only instance of a reputation check in any of Viconia's scripts. So it's one very narrow edit. One or two blocks to change. Some possible methods:

- REPLACE_BCS_BLOCK. Create files with the exact BAF scripting of the block you want to replace and the one you want to replace with it, load up BDVICONI.BCS, use the command.

- REPLACE_TEXTUALLY. Load up the file, use DECOMPILE_AND_PATCH to convert it to BAF format temporarily, replace a smaller segment. This one's regexp-based, so it works best if you understand that system. But you can use it to replace just that "ReputationGT(Player1,15)" line with itself plus the equipment (or alignment) check.

Link to comment
Posted (edited)

Ok, I am now getting serious with the fog mod to the point of trying to learn WEIDU code. However, I'm still a bit unclear on a couple of things.

I created a 2DA file with the new fog parameters I want to append to FOGAREA.2DA and I can read them in. It was at that moment I realized I don't know how to manipulate arrays. I need to check the first column of each row of the new 2DA, see if it already exists in the target 2DA, and if not, append the entire row - which is where I got stuck. I need to create a new 1x10 array from the row I pulled from my 103x10 array for the append. Either that, or insert them one value at a time, but then how to add the CRLF at the end?

After that, if the row is to be appended, I need to change the fog probability of the associated ARE file - some of which are in override and some of which are stock. Since this is an EET only mod, the target destination is fixed, so that's not an issue.

Edited by maurvir
Link to comment
18 minutes ago, maurvir said:

I created a 2DA file with the new fog parameters I want to append to FOGAREA.2DA and I can read them in. It was at that moment I realized I don't know how to manipulate arrays. I need to check the first column of each row of the new 2DA, see if it already exists in the target 2DA, and if not, append the entire row - which is where I got stuck. I need to create a new 1x10 array from the row I pulled from my 103x10 array for the append. Either that, or insert them one value at a time, but then how to add the CRLF at the end?

You might want to look at the "a7_clone_2da_entry" function in this commit for the EEFP how it could be done. It deals with adding new 2DA entries as well as updating existing entries: https://github.com/Gibberlings3/EE_Fixpack/pull/101/files

 

18 minutes ago, maurvir said:

After that, if the row is to be appended, I need to change the fog probability of the associated ARE file - some of which are in override and some of which are stock.

That's nothing COPY_EXISTING can't handle.

Link to comment
Posted (edited)

Ok, this *seems* to work, but I'm not sure it's the best way to do it:

BACKUP ~weather/backup~
AUTHOR ~Maur'vir maurvir@gmail.com~
AUTO_TRA ~weather/%s~
AUTO_EVAL_STRINGS
LANGUAGE ~English~ ~english~ ~weather/setup.tra~

BEGIN @1 /* ~Weather~ */
REQUIRE_PREDICATE GAME_IS ~bgee eet~ @026

COPY_EXISTING "%MOD_FOLDER%/2da/weather.2da" ~override~
	COUNT_2DA_ROWS 15 src_rowcount
	READ_2DA_ENTRIES_NOW weather_params 15
	PATCH_PRINT "Total areas : %src_rowcount%"

// Patch FOGAREA.2DA
COPY_EXISTING "FOGAREA.2DA" ~override~
    COUNT_2DA_ROWS 10 tgt_rowcount
	FOR (i=1;i < src_rowcount;++i) BEGIN
	    READ_2DA_ENTRY_FORMER weather_params i 0 area_name
	    READ_2DA_ENTRY_FORMER weather_params i 1 alpha
	    READ_2DA_ENTRY_FORMER weather_params i 2 contrast
	    READ_2DA_ENTRY_FORMER weather_params i 3 outer_r
	    READ_2DA_ENTRY_FORMER weather_params i 4 outer_g
	    READ_2DA_ENTRY_FORMER weather_params i 5 outer_b
	    READ_2DA_ENTRY_FORMER weather_params i 6 inner_r
	    READ_2DA_ENTRY_FORMER weather_params i 7 inner_g
	    READ_2DA_ENTRY_FORMER weather_params i 8 inner_b
	    READ_2DA_ENTRY_FORMER weather_params i 9 pre_disp
		SPRINT next_line "%area_name% %alpha% %contrast% %outer_r% %outer_g% %outer_b% %inner_r% %inner_g% %inner_b% %pre_disp%"
		PATCH_PRINT "Adding new area fog definition: %next_line%"
        INSERT_2DA_ROW tgt_rowcount 10 "%next_line%"
		tgt_rowcount = %tgt_rowcount% + 1
	END

// Patch each affected ARE file
FOR (i=1;i < src_rowcount; ++i) BEGIN
    READ_2DA_ENTRY_FORMER weather_params i 0 area_name
    READ_2DA_ENTRY_FORMER weather_params i 10 rain_prob
    READ_2DA_ENTRY_FORMER weather_params i 11 snow_prob
    READ_2DA_ENTRY_FORMER weather_params i 12 fog_prob
    READ_2DA_ENTRY_FORMER weather_params i 13 lightning_prob
	SPRINT target_are "%area_name%.ARE"
    PATCH_PRINT "Adjusting weather probabilities for %target_are% : rain [%rain_prob%] snow [%snow_prob%] fog [%fog_prob%] lightning [%lightning_prob%]"
	INNER_PATCH_FILE "%target_are%" BEGIN
        WRITE_SHORT 0x4a %rain_prob%
	    WRITE_SHORT 0x4c %snow_prob%
	    WRITE_SHORT 0x4e %fog_prob%
	    WRITE_SHORT 0x50 %lightning_prob%
    END
END

I have all of the parameters stored in a file called weather.2da, which is copied to the override folder even though I don't need it afterward. Not sure how to delete it, though.

I also haven't figured out how to get it to skip the 2DA insert if the row is already defined - right now, it inserts blindly.

Edited by maurvir
Link to comment
5 minutes ago, maurvir said:

I have all of the parameters stored in a file called weather.2da, which is copied to the override folder even though I don't need it afterward. Not sure how to delete it, though.

Close it with a BUT_ONLY. After all, you didn't make any changes to the file.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...