Jump to content

The Black Scourge of Candle Cove -- Tchos' development diary


Tchos

Recommended Posts

It's funny how a three-word note on my to do list ("Destroy shrine option") can amount to so many hours. Well, to do it the way I wanted, anyway. The easy way would be to just make the thing bashable, and give little or no feedback on the effects. But it is of course comprised of multiple objects, as well as visual effects and lights that also needed to change if you choose to destroy it, and I wanted to provide more options, and consequences for the actions, and extras like spawning appropriate rubble, special effects, etc., and that's why it all took a while. It's off the list now, though.

I wrote another utility script for the purpose, which can be useful in other areas. The ga_effect script uses integers from the visualeffects.2da file, but it doesn't seem like all of them work. I'm not sure if this is one of those things left over from NWN1 or not, but I notice that some, but not all of them include named .sef files like what I usually use in scripts to create visual effects. I need to do a little more experimenting to know for sure, but it's not really important since my ga_ script instead uses the method I usually use, which is to specify the name of a .sef in the script's string, rather than a constant integer.

I made this one apply the effect at a location rather than on an object, since I was using a waypoint in this case to tell it where to apply it (since the object was being destroyed), but I'll make a slightly modified alternate version for applying directly to an object later for other purposes (for instance, I know how to remove a .sef from an object, but not from a location, which is important in the case of permanent effects rather than temporary ones).

Another few general-use scripts that came out of this were a simple one to damage the player a variable amount (seems like something that should be in there already, but I didn't see one) -- this one needs a little expanding to allow you to pick what kind of damage in the conversation fields like with the amount, but for this instance I've hardcoded the type.

Also a couple of placeable scripts: one for on damage, the other for on use, to start a conversation. I know there are several scripts there already to start conversations from placeables, but they start the conversation with the object itself, which is not good if you plan to destroy the object during the course of the conversation, so I made a modified version to read the intended conversation-starter (such as an ipoint) from a string on the object. I used a separate script and separate string for the on damage and on use versions, just in case any future use of these scripts would require different conversations for the two different actions.

I also set up the wandering monsters in the 2da for this area (which is the final area), so that only aquatic monsters have a chance of disturbing your rest. I may not have mentioned it before, but I've been careful to specify the selection of wandering monsters in each area that has them, so that they're always appropriate for the type of environment.

Link to comment
Share on other sites

  • Replies 254
  • Created
  • Last Reply

Top Posters In This Topic

I went through some of my earlier heartbeat scripts and did a little rewriting for better CPU efficiency. There were a few from the earlier work that were doing their full processing without any PC presence, so I added the early checks and aborts that I had built into the ones I wrote later, and replaced a few legacy commands with their improved counterparts. People reading through my code to see how to use my scripts will probably appreciate the more streamlined versions.

I also added a couple of script lines for the vision of the past (HideHostileCreatures & ShowHostileCreatures) so that enemies of the present would be hidden and not distract from the vision until it ended, and scripted the ipoint that controls all of these events to spawn only when the quest is at the necessary stage, rather than being there the whole time. I had already scripted it to destroy itself at the end of the events, but this saves an extra little bit of heartbeat processing before that time. It seems to work in my test, which is good. Fiddling with something complex after it's already working always has the potential to mess things up.

While I was in the forest, I also prepped another door for future expansion.

Speaking of messing things up, I found that I can't use the usual check that I normally use to abort a heartbeat early (to save processing if the PC's not around, in cases where the heartbeat doesn't need to do anything without the PC there) if the heartbeat is on a placeable, because placeables don't have AI, and thus:

if (GetAILevel() == AI_LEVEL_VERY_LOW) return;

always returns TRUE because the constant AI_LEVEL_VERY_LOW = 0. For placeables, instead, I'm using a check to see if the PC is in the same area as the placeable. If there's a more efficient way I could abort the heartbeat early on a placeable, I'd like to know.

I also made a new trigger script for subzone name displays, as in The Witcher. My thanks for this go to Marshall of Legends and Seraphimsage, whose custom UI displays served as the models for this one. Examining the SoZ overland map also brought illumination on how to handle the triggers for it.

I have not found a way to define a new font style anywhere except in fontfamily.xml. For the sake of mod compatibility, there should be a way to define a custom UI's own special fonts so that 1. They display as expected, regardless of any fontfamily.xml mods the user might have installed, and 2. It wouldn't require bundling one's own fontfamily.xml with the mod, with custom font styles included. As it is, I'll do without the custom font, though I'd really rather have one for this. If there is a way to add additional font definitions outside of the fontfamily.xml, I would like to know.

I have proper internet again, so I'll set about showing some screenshots for the more recent work, and maybe a video.

Edited by Tchos
Link to comment
Share on other sites

My Questland area has been developing the same problem in opening as the docks area has, and it's nowhere near as large or complicated. I was just trying to open it to test out some loot variables on a series of creatures (confirming something in my tutorial on the SoZ loot system), but it crashed the toolset on opening 5 times in a row. It's not actually a problem in this particular case, since it's only a testing area, and there's nothing in it that I don't also have in the actual areas or in the blueprints. I can just delete the area and make a new testing area. It's just a nagging sign that this may be a pattern -- that the more I work with an area, the harder it will become to open it.

 

As I was adding crafting loot drops to my enemies, there were certain ones that didn't have any appropriate distillable loot, so I wanted to create a new distillable body part for a particular kind of undead that doesn't have any. Investigating how to do this (for the OC crafting system) led me on an interesting journey. I found the 2DA files that have recipe lists, but the notes in them by ChazM say that they shouldn't be edited manually, and referred to a module that would be uploaded to the Vault.

 

I retrieved the module and ran it, and it had some basic instructions on creating new recipes. Sort of. The module functions as a kind of compiler for the 2DA entries that should not be manually edited. However, it doesn't do the best job of explaining how you define new recipes in the first place. I think Chaz left a sentence or two out of the "Creating Recipes" book that you get in-game, or at least what's there could be phrased a little better. I had to re-read it a few times to understand what needs to be done, and I'm not the only one who had trouble with it, judging from some of the comments on the Vault. The confusion stems from the fact that since part of the recipe generation takes place in-game, it needs to be a little more explicit that the first part must be done before the module is loaded.

 

To define a new recipe (including a distillable body part), you first modify the script ga_setrecipes outside of the game. Then you play the module, talk to the deer and tell it to run the script, then run another script to export the recipes into a log. Then, outside of the game again, you open the log file and copy the results into two 2da files. Logging has to be turned on for this purpose, and instructions for that are here.

 

Reading through the script also revealed why the toolset item "Skeleton Knuckle" doesn't do anything, and is instead an unexplained junk item. The script uses a skeleton rib for the constant SKELETON_KNUCKLE.

 

Anyway, it all worked fine. My new item distilled into the essences as expected, and the required skill level was properly set. I wrote it into the new 2das, and tried it out in my module with those 2das, and it didn't work. So I checked to see if there were any other crafting 2das in my override. Sure enough, Kaedrin's PrC overrides those files. So I put the 2das into my hak to override the override. Users of Kaedrin's will thus be missing the 36 recipes added by that pack while they play my module, so that they will be able to distill this module-specific item, and any others that I may add.

 

Here's a video sneak peek at the early cave design. The lights are placeholders, and there isn't much in the way of decoration yet (I still need to make at least 1 or 2 important placeables for it), there's almost no object or enemy placement, and there are placeholder humans standing around that I just have in there for my own reference while I'm building, to get a sense of scale, but you can get a general idea of where I'm going with this.

http://www.youtube.com/watch?v=GDKoHpKk67g

 

And here's the eating and resting:

http://www.youtube.com/watch?v=-gc2jZswU5M

 

The X-marks-the-spot effect for the overwater map:

http://www.youtube.com/watch?v=RZTacnIFKik

Edited by Tchos
Link to comment
Share on other sites

I spent some of today giving the various creatures different loot tables using the SoZ treasure system, but I really wanted to also give some randomised crafting supplies beyond the usual "animal parts dropping from animals", and that system doesn't include such things. As a sort of temporary measure, since I didn't feel like going as far as making 2da files for crafting supplies just yet, I used an item I had created for quest rewards -- a bag/box of goodies. The difference is that where the quest reward bags have specific goodies in them, here I made a pouch that randomly picks some items from the list of crafting materials, to represent an NPC's supply of crafting goods that s/he intended to use.

I made separate bags/boxes for blacksmithing supplies, alchemy supplies, woodworking goods, leatherworking goods, and scribal goods. It's convenient to have these items drop as random loot, deferring the generation of their contents to later. The way I scripted it, these containers contain somewhere around 1-6 supplies in their theme, though in future modules I'll add the ability to set the minimum, maximum, and percentage chance through variables.

I added some entries to the baseitems.2da, because none of the "miscellaneous" items (small, medium, large, etc.) were above half a pound. Also missing from this selection was a "paper" item, for readables other than "books". Setting an item's base item to "scroll" for a simple ransom note or shopping list has the undesired effect of allowing a wizard to scribe a spell onto it, while setting it to "book" makes that note weigh a pound and make a "thunk" sound when you pick it up or drop it. I was already modifying the baseitems.2da because of the fishing system, so I went ahead.

After doing this, the toolset started throwing up error boxes saying "wrong version". I removed the 2da and things went back to normal. Comparing the new one with a fresh copy from the Data folder's 2DA_X2.zip, I saw that the difference was that the new one had quotation marks around everything (including the version number, which is probably why it gave that particular error). This is the result of having opened the 2da in OpenOffice Calc (the OpenOffice suite's spreadsheet) and saving it from there. There's probably a way to prevent that behaviour, but I haven't looked into it, since I usually edit 2das in text editors, and only open them in a spreadsheet if there are a lot of columns that don't display neatly in a text editor.

Next I had to come up with a means of turning on and off the lights in the town area (the one I can't open) without having an area heartbeat or user defined event script specified in that area. Selecting and disabling all the lights in an area, and turning them on again, was no problem (using OBJECT_TYPE, not tags), but I needed a timekeeper to choose when to do it, which normally I'd put in the area heartbeat. Instead, I added some time-checking heartbeat code to an NPC who was already running a longer heartbeat than default (12 seconds) and who would always be there, so he could act as the timekeeper without adding another heartbeat object to the game. This of course would not have been necessary if I hadn't failed to heed the good advice of others to always set each area's scripts to something, even if the scripts don't yet exist. I started doing that a while ago (and making a list of what scripts are named for each area), but too late for this one.

I think I'll have to leave the torch fire effects alone, because I don't see a way to either hide them (ScriptHidden only works on creatures) or disable them -- only to destroy them and recreate them, and I don't really want to deal with storing all of that location information. Again, this is on the docks, so it's a little late to add something like SLS.

In other not entirely sane matters, I would like to know if there is a way to change an NPC's owned conversation by script (so that when a player clicks on them, it always fires a different conversation than was initially assigned), or if that's just one of the property fields that can't be modified by script. I have a functioning workaround if it's not possible, but it would be ideal if it were possible.

Link to comment
Share on other sites

I've been splitting some of my time between this and dealing with some placeable conversions (with permission). This is a bit tricky, since these particular plugins don't work in Gmax, so I had to download a 30-day trial of 3ds Max, which puts a limit on how many placeables I can convert to NWN2 (whatever I can do in that time). I've finished 43 so far, but that's for another thread, when I'm ready to announce it. Some of them are useful for this module, though.

But back to BCoCC news, I also made a new vertical hanging vine placeable for the undersea cavern, to accompany the stock vine placeables. Not sure how well you can see them in this screenshot, and the lighting removes a lot of the placeable's colour. The icicles seen in this screenshot near the middle top need to be retextured to be stone instead of ice, since they're supposed to be stalactites.

http://3.bp.blogspot.com/-_yciywN1e_k/UXBu_BMJbxI/AAAAAAAAE3E/CMTfNcB1Llo/s320/nwn2main+2013-04-18+14-36-38-70.jpg

Here's another in more neutral lighting.

http://4.bp.blogspot.com/-yvajoRqq-es/UXBzOPLtCfI/AAAAAAAAE3M/Y1cVQOS_iGE/s320/vines.jpg

I also tackled a complicated quest that I'd been putting off because of its large number of variables and possible solutions. As it turns out, I needed to reference a door in the unopenable docks area, but unfortunately I hadn't given it a unique tag. Not really a big deal, since I can just get the nearest door-type object to the waypoint, and that's the one I want, but it meant I couldn't use the ga_set_locked() script, since that script goes by tag only. That's fine, though, because I had more things to do via script in this spot that there aren't any ga_ scripts for, so it wouldn't really have saved much.

One problem I came across was that I can't seem to get a cloned creature (created with CopyObject(), with no change in tag) to follow the waypoint set of its original, who walks waypoints using the stock waypoint-walking code. The clone just stands there, even after nudging him, talking to him, going to a different area and coming back, and waiting around from a distance watching him, even if I throw in a ForceResumeWWP() command. I imagine it's something to do with initialisation and the "WWP controller" that the default system creates. I'd try spawning it instead, except that this is a Docks character without a blueprint, so I thought the scripting approach would be more convenient, if not for this issue.

Link to comment
Share on other sites

Setting the variable on the NPC to the tag override method of walking waypoints did not help, nor did me using the initialisation function on the newly spawned clone, which from reading the code seems like it should set it to use the controller, or create a new controller if one didn't exist.

So instead I'm approaching the problem from the opposite direction. Instead of spawning a replacement clone out of sight and sending the original off to perform the task, instead the clone will be sent to do the task, leaving the original to continue walking waypoints. I know it may sound strange to have two copies of an NPC next to each other, but these are uniformed guardsmen with helms, so they look alike anyway.

So I have the new guard walk up and ask what's going on, and the original gives him an order, and the clone salutes and goes off to do it, and the original continues walking the waypoints. Probably better this way than the other way. Moving on...

Link to comment
Share on other sites

Considering the possible causes of a problem posed by JonnieRS in another thread prompted me to check something in a conversation file, and solved a nagging problem I was having. I have an NPC who speaks barks on a heartbeat, but who is only supposed to speak those barks at a certain quest stage, and he was speaking them all the time.

The heartbeat calls a separate dialogue file from his main one, using SpeakOneLinerConversation(). I had a condition in the dialogue file using gc_journal_entry to check for the quest stage. The problem was that gc_journal_entry was not appropriate for a bark file, since as all conversation conditionals do, it defines the PC as PC Speaker. In a bark, there is no PC Speaker. This was creating a conditional result that always fired the barks.

I moved the check to the heartbeat itself, where I could define the PC more appropriately. I should have put it in there anyway, since it allows an earlier abort.

Since I've been getting more Gmax experience, I went ahead and fixed that tilted beer stein, so now it sits properly on a table.

http://4.bp.blogspot.com/-EZAfOX3Rq0c/UXkkOd-Mc5I/AAAAAAAAE3c/t7Pu0QxKSTA/s320/bcocc+fixed+stein.jpg

Link to comment
Share on other sites

  • 3 weeks later...

I made another effort to open the docks area, and after 4 tries, I managed to get it open. I seized that opportunity to apply area heartbeat, area user defined, and area exit scripts to it as I should have done in the first place. Next I placed the fishmonger table and a barrel of fish (from my Witcher placeable conversion project) near the fishing trainer. Now she actually has visible product to sell!

http://3.bp.blogspot.com/-mZjote1yqos/UY2NyOkIzCI/AAAAAAAAE7U/X5fGg5ZqBl0/s320/bcocc+fish.jpg

I was in the process of preparing to replace the placed city watchmen with spawned blueprints when the toolset froze up, ending that session. I saved and backed up before each new task.

I at least got one city watchman blueprint which I can use to replace any of the placed instances, but I didn't get the tags of the waypoints they're posted at and the tags of the patrollers, so if I want to do that, I need to write a script that I can fire from the console to report the tags of any nearby waypoints to where I'm standing. I probably won't do it. I was just thinking I could improve the performance of the docks area by changing most of the wandering NPCs to be controlled by a single area heartbeat instead of each running their own heartbeats.

At any rate, since I now have full area scripts on the docks, I was able to apply a script to fire user defined events on each day/night transition, and/or hourly. I used this to turn off all the lights in town during the day, and turn them on again when it gets dark. This seems to improve performance.

I did more work on a quest which involves some placeable manipulation. I really like those, myself, enough that such things are part of my design philosophy. Originally, I was just going to handle it through conversation, and I had it initially set up that way, but I changed it around and made it much more satisfying, in my opinion, with a more reactive environment with VFX and sound effects and things happening in response to your actions. I made sure it was completable with any kind of character, unless you actually have a negative value for a certain skill. Not likely at level 10, I think, and having an average-sized and varied party should make that a negligible risk.

I ended up writing a couple more scripts for it, and expanding one of the existing scripts to allow me to specify sound effects and animation playing when you use an object, where before the animation was hardcoded and there was no sound. I made sure to include defaults so that the script would perform the same way if you didn't use those variables for places where I had already used it in other areas. I really like all of these general-purpose scripts, where I can use them in such a wide variety of situations and have them do different combinations of things using the local variables.

In between this, and the placeable conversion project, I'm also playing other games, and finding all sorts of gameplay ideas in them that I'd like to include in future modding works.

Edited by Tchos
Link to comment
Share on other sites

I spent a long, long day making a better standalone lighthouse for the module, then UV mapping it, and then texturing it. I built it out of cylinders and cubes, sized and tapered (from scratch, though I did use reference). Oh, and two doughnut shapes, for the railings at the top. After making one set of thin vertical wooden pieces from cubes (for the windows), I found afterward that I could instead make a cylinder with only 3 sides, saving a few polygons. I did that for the second set of vertical pieces on the railing.

I decided to leave off the door and windows, since I had already been doing it with placeables in the toolset. I think it looks better than the previous one I had made out of parts. The main body itself could use more detailing in the middle area, like some cracks and shading around the window areas, and the texture is a bit too enlarged, making it look smaller than it should look, but I think it's done for now.

Gmax reports that it totals to 790 "faces", which may or may not be the same as "polygons". Obviously, I'm new at this, and don't know the proper terminology. I'm not sure how many polygons is a good number to shoot for, but I see that the similarly-shaped and sized city watchtower model from the vanilla game is 938 faces, so I think I'm fine.

I also notice that some of these stock city pieces are rather inefficiently designed in terms of UV mapping, leaving over half of the texture map entirely empty, which could have been used for better quality textures.

I think I can actually make a VFX for a rotating light beam coming out of it, too.

http://4.bp.blogspot.com/-g4YM2ga9cVI/UZVacnPCYpI/AAAAAAAAE9A/Egp-IpO1jII/s320/bcocc+new+lighthouse1.jpg http://2.bp.blogspot.com/-bW9czZN49EU/UZVacponCQI/AAAAAAAAE88/8PTJTIlCFxY/s320/bcocc+new+lighthouse2.jpg http://1.bp.blogspot.com/-z9wRSEZU0Hk/UZVacp5iWDI/AAAAAAAAE84/XorGlOXOuXs/s320/bcocc+new+lighthouse3.jpg http://3.bp.blogspot.com/-AzmYzxvvje0/UZVac5pOTMI/AAAAAAAAE9E/Z4agQmjzq2c/s320/bcocc+new+lighthouse4.jpg

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...