The Black Scourge of Candle Cove -- Tchos' development diary
#951
Posté 25 novembre 2013 - 12:13
#952
Posté 25 novembre 2013 - 12:59
#953
Posté 25 novembre 2013 - 05:08
Calister68 wrote...
Whatever you plan to script, there's one thing I implore you not to do : PLEASE don't create a Daggerfall randomly-generated dungeon. I don't want to go nuts again
That was Diablo's schtick as well...
The whole notion of random dungeon design as a replayability tactic has always seemed flawed to me. I wish developers would have just put the time in to build unique dungeons. Players are going to replay games regardless of dungeon design. They're going to replay to try out a different class, or to see how story elements change if they choose a different choice during a quest. But to see a different version of the same tileset? I don't quite think so...
#954
Posté 25 novembre 2013 - 08:51
#955
Posté 30 novembre 2013 - 02:36
I looked through all the sourcebooks I could find for a symbol of Blibdoolpoolp, but I couldn't find any ready-made images like there were for other gods, like Sune. I needed it for banners / wall hangings. There was one that described the symbol, at least -- a lobster head and a black pearl. So I made one based on that description.
Pic
The topic of creature spawning came up in CF's thread, so I thought I'd show the way I'm doing it. This is a "place it and forget it" type of thing, so I can just put one line in all of my client enter scripts and not have to worry about area variables or specifying any creatures' resrefs in the script itself. Everything it needs to know, it gets from the waypoints themselves, and using a simple waypoint blueprint already marked as "active", it's just a matter of placing it in the area, sticking a creature resref in the waypoint's tag, and copying it around. And any time I want to spawn a different type of creature, I just use a different tag on the waypoint, and don't have to change anything anywhere else. Built for convenience.
// On Client Enter mass creature spawn script, by Tchos.
// Extracted from Tchos' module_inc file.
// This is an original script, but since it relies on the ginc_group include, I wanted to separate it from my other scripts that don't require includes.
void SpawnCreaturesAtMarkers()
{
// This function will only work when the caller is an area (as in an area script slot). To use this, just place a waypoint in your area, tagged with
// the resref of the creature you want to spawn. Optionally, add a local int saying how many copies of the creature you want to spawn.
// Will also work if you put the resref of the desired creature in a local variable on the waypoint called "SpawnResref", and the WP tag won't matter.
//
// If you're opting to spawn a group of creatures at a single waypoint, it will name the group by the area's tag + the creature's resref, for any desired
// later manipulation via group name.
object oArea = OBJECT_SELF;
int iSpawnActive;
int iNumToSpawn;
string sResRef;
string sTag;
location lLoc;
string sGroupName;
// This checks every object of all kinds in the area.
object oWP = GetFirstObjectInArea(oArea);
while(GetIsObjectValid(oWP))
{
// First check to see if this object has the magic variable.
iSpawnActive = GetLocalInt(oWP, "TchosSpawnActive");
// For each found object, do the following actions only if the object is
// a waypoint, and has a local int "TchosSpawnActive" equal to 1.
if(GetObjectType(oWP) == OBJECT_TYPE_WAYPOINT && iSpawnActive == 1)
{
// Since it has the magic variable, check to see if it also has any
// variables indicating what should be spawned, and how many.
sResRef = GetLocalString(oWP, "SpawnResref");
iNumToSpawn = GetLocalInt(oWP, "SpawnNumber");
// If number isn't specified, spawn 1.
if (iNumToSpawn == 0) { iNumToSpawn = 1; }
// If resref isn't given in local string, then spawn whatever comes after
// the presumed 3-character prefix in the tag, such as "sp_" (can be anything).
if (sResRef == "")
{
sTag = GetTag(oWP);
sResRef = GetStringRight(sTag, GetStringLength(sTag)-3);
}
lLoc = GetLocation(oWP);
// Different methods depending on whether we're spawning 1 or more than 1.
if ( iNumToSpawn > 1 )
{
// Spawn a group of creatures.
sGroupName = GetTag(oArea)+sResRef;
GroupSetSemicircleFormation(sGroupName);
GroupSetNoise(sGroupName);
GroupSpawnAtLocation(sGroupName, sResRef, lLoc, iNumToSpawn);
}
else
{
// Spawn 1 creature.
CreateObject(OBJECT_TYPE_CREATURE, sResRef, lLoc);
}
// All done. Waypoint no longer active, and will not spawn anything again, unless
// this variable is set to 1 again.
SetLocalInt(oWP, "TchosSpawnActive", 0);
}
oWP = GetNextObjectInArea(oArea);
}
}
Modifié par Tchos, 30 novembre 2013 - 02:37 .
#956
Posté 21 décembre 2013 - 05:10
I thought I had learned my lesson after making a path bordered by individually placed, rotated, and sized rocks, but now I'm texturing individual stairs on a ziggurat to make sure they're aligned.
Not much time left if I want to get this out before the end of the year, but I'm on my winter break now, so we'll see.
#957
Posté 21 décembre 2013 - 06:45
Tchos wrote...
I thought I had learned my lesson after making a path bordered by individually placed, rotated, and sized rocks, but now I'm texturing individual stairs on a ziggurat to make sure they're aligned.
We learn and apply many lessons me thinks but not to chase down perfection is the one we seem to ignore.
PJ
#958
Posté 21 décembre 2013 - 10:17
So there's a chance to see this mod released before the end of the year ? That's great news !
#959
Posté 21 décembre 2013 - 10:37
Fortunately, the stairs are all done now, and the temple area is baked and the walkmesh worked properly after only 6 or 7 attempts.
#960
Posté 21 décembre 2013 - 11:35
#961
Posté 21 décembre 2013 - 04:36
Tchos wrote...
Yes, especially if I resist the temptation to model a REAL statue of Blibdoolpoolp instead of using a statue of Dagon as a substitute, for the altar.
My bet is that you do it
I used one of the shrines from the whitcher project in my Kuo Toan area in the new mod.

It's not a nude woman with a lobsters head but it seemed a suitable alternative. It's very .... frog like in a Cthuluesk way.
PJ
Modifié par PJ156, 21 décembre 2013 - 04:37 .
#962
Posté 21 décembre 2013 - 08:09
#963
Posté 22 décembre 2013 - 12:14
I completed the general script for updating quests via item acquisition through all methods (picking up from the ground, out of a container, buying from a store, through a placeable, etc. -- any possible way of acquiring the item). Then I modified my placeable-based collection quest script so that it can be used in tandem with this script (some quest items can be gathered from placeables with skill checks, special effects, etc., and others can be obtained from killing creatures or finding them in a box or something).
The key difference that I needed to address was a contingency for the possibility of the player acquiring a quest item before taking the quest. For the placeable version of the script, this is a non-issue, since placeables can be made unusable until the player takes the quest. The way I first imagined this to be used is for the quest items to simply not be there to pick up until the player takes the quest. But I imagine that sometimes you might want to actually begin the quest by finding one of the items, so I added a secondary check -- if you include another variable that allows it, you can start the quest by picking up the item -- with the option of it showing a different journal entry when you do, so that instead of the journal saying that you've acquired one of the items you were searching for, if you weren't actually on that quest yet, it could instead show a journal entry saying you found a curious item that you might want to take to a certain person who you think might be interested, for example.
Anyway, it's another entry in this line of scripts that were complicated to design, just to make it simple to use for all sorts of things. I'm using it for a quest in the cave, which I could have done with more straightforward tag-based scripts, of course, but I wanted to make this system anyway, and why not have a real quest to try it out on? It's like killing a fly with a sledgehammer.
#964
Posté 29 décembre 2013 - 08:40
All I really wanted was a simple number to check to see how much a person or the person's associated faction likes you, so that they can offer different things, like access to members-only shops, or access to private areas, or conversely to bar you from amenities that they would normally offer to neutral parties. A simple local int stored on the player will suffice for that, for each faction, and an associated script to add or subtract values from that integer, for use in conversations (such as when you complete quests for a person) or on death events or other relevant actions.
In other news, I've added a few things to the item acquisition script, to provide optional contingencies for the possibility of finding some, or all, of the quest items before receiving the quest from the expected questgiver. Because you don't want the journal entry saying that "You found Mrs Badcrumble's missing pickaxe!" if you never met Mrs Badcrumble in the first place, and didn't know she was missing one. This makes the script more flexible, in case you don't want to use inventory checks, and instead want to do the conditional checks in the conversation entirely with the journal, and if you don't want to use separate tag-based item acquisition scripts for each item.
I went ahead and altered the module unacquire script, too, to add a couple of extra checks, like I did with the module acquire script. One check looks for a variable on the item that specifies a script to run on the event. You might wonder, why not just use a tag-based script? Because if I did that, I would need to either make a separate script to run for each tag, or make all of the tags of a particular set of items the same. This way, I can specify a particular script to run for a whole group of items, and still be able to manipulate them individually by their tags.
In this case, the purpose is to work with my quest tracking script, using the variables on the item that are used for that system, and causing the quest progress to step backward an appropriate amount if the player stops carrying a quest item. Thus, they will get a notification that the journal has been updated, showing that they no longer have the necessary items for the quest. This would also reset the variable on the item that prevents it from advancing the quest again if they pick up the same item again, so that it'll work again. Picking up the item again will restore the quest progress to the way it was before they dropped it. The important thing to emphasise here is that this is for a system that uses custom tokens in the journal, and so it can't be done by checking or manipulating the journal itself.
The other check in the module unacquire script is to look for a variable on the item called "NoDrop". This provides an alternative to the above method, in which the player simply can't drop the item. Thus, any item can be made undroppable by setting that variable.
You might wonder, why not just use the "cursed" flag? Several reasons. First, as has been pointed out here, cursed objects are an irritation to players who still have those items in their inventories after exporting the character and importing it into a new module, where those items are often no longer useful. With this method, since other modules will likely not be using my script, that variable will have no effect because no check will fire, and the object can be dropped in the normal manner.
Secondly, cursed items are a bother because they can't be removed from containers if they're marked as cursed (a workaround is to set the cursed flag once the player takes the item). My script only fires if the item is removed from a member of the player's party, so it can be removed from containers with no problem, but just can't be dropped again.
Likewise, cursed items can't be transferred between party members. This can be bothersome if you want to keep all quest items in one character's inventory, or if they're heavy and you picked them up with a weak character. I couldn't figure out a way of allowing you to drag the item onto a party member's portrait as usual, but I addressed this by allowing the player to target a party member, and dragging the item to the ground, which the script intercepts and transfers the item into the party member's inventory. A "tooltip" explains this process.
This was a somewhat complicated way of creating this final quest, but only because of all the extra frameworks I built to make future quests like this much easier to create. Really, after all this, the most complicated part of the process is the dialogue, and I don't know how to create a script to automate that process.
#965
Posté 29 décembre 2013 - 09:11
#966
Posté 29 décembre 2013 - 09:24
#967
Posté 29 décembre 2013 - 04:25
#968
Posté 30 décembre 2013 - 01:13
And actually, never mind what I said before about the transfer restrictions. Now I have it so that you can drag these undroppable quest items from your inventory directly onto a party member's portrait, as long as you have the party member targeted when you do.
#969
Posté 01 janvier 2014 - 02:35
2013 was a real renaissance of new custom content, ports, fixes, uncoverings of hidden material, and expansion and reorganising of old material, as well as numerous new faces. May 2014 be even better!
#970
Posté 08 janvier 2014 - 05:34
Today I reworked the trigger script gtr_bark_node. The normal script works very nicely for my recruitable companions. You can assign a hierarchy of priority for which companion should say something, if they're present. The way I have it set up here, whichever companion the player has in the party who has the most relevant or the most interesting line will be the one to speak up, which is how the normal script works. But in addition, if the player has no recruitable companions in the party, then it defaults to a skill check, and the first player-made party member who passes the skill check will speak up, with a bit less personality (but one which can be inferred from their choice of skills), to ensure that the player gets useful feedback and a little flavour in the areas.
At first I accomplished this effect with two triggers, and an On Enter script that would destroy the one for player-made party members if the player has at least one recruitable companion in the party, but I didn't want to do that for every area, and some areas have multiple triggers, so it would get complicated fast. The single-trigger solution works better.
In a test today, I found some unexpected behaviour. I had teleported directly to the kuo-toa temple to test out some of the kuo-toa AI, as well as the quest items, when I saw some sahuagin approaching the temple! The sahuagin had never approached the temple before, and they're from a rather distant subzone. I went to check on the rest of them, and found the whole lot of them crowded around a locked door barring their way to the temple, which promptly exploded as they detected me. So all of the sahuagin were trying to get into the temple, when before they had stayed patrolling their base camp.
This began when I added generic stop waypoints around the temple, which I had intended for only the kuo-toas to use. I had no idea that creatures from all across the map would attempt to approach those waypoints, when they barely seemed adequate for creatures nearby.
The solution seems to be to just add some stop waypoints in each subzone where there are creatures set to wander around. That should keep pulling them back if they try to wander off toward one of the other ones.
I modified my waypoint spawning script so that now I can add inventory items to specific spawning waypoints, so that I don't need to create separate blueprints for creatures of the same basic type that need to possess specific items.
I think I mentioned before that I created an alternative placeable script to generate random treasure on containers, exactly like the SoZ creature loot script, so that you can also specify loot tables with percentage drop rates for the objects, as well as specific items.
I created another alternative that simply picks items from a list of all possible consumables and crafting items in the OC, except it allows you to switch on or off any/all specific categories of items to pick from. For instance, you can set it to pick only scrolls if you put it on a wizard's scroll case. Or you can set all categories on if you're opening a box at a rummage sale. Also you can set a minimum and maximum number of items to generate. This all helped fill the containers in the temple with relevant items.
The temple is functional, but I'm still polishing it, and there's still some dialogue to write, such as for the last quest. Some of Kalister's resources have come just in time for my needs. [Note: Kalister uses two spellings, and he told me that that this is the preferred one.]
I'm concerned about this cave area. It's starting to become difficult to open in the toolset without crashing. I need to get the rest of the roofs and walls placed in there before it goes the way of the docks. Anything else, I think I can add via script if necessary. The walkmesh is finalised.
#971
Posté 08 janvier 2014 - 06:39
Tchos wrote...
[Note: Kalister uses two spellings, and he told me that that this is the preferred one.]
Indeed^_^
#972
Posté 20 janvier 2014 - 06:30
I figured out what was wrong with the progress bar code that was causing it to remain on the screen if the player switches party members while it's in progress. I have code in there to prevent the player from switching party members in those cases, but it doesn't prevent you from switching to the main character, which is where the UI was getting stuck. I don't know if it's possible to temporarily set the main PC to be unselectable as it is for the companions.
Anyway, all it took was a loop through the party to remove the UI when it's supposed to be removed at the end of the task.
I wrote a few new utility and helper scripts that are useful for the kind of quests I include, and one that addresses a limitation of the quest indicators -- in that they can only update the indicators on creatures that actually exist. Since I spawn an area's creatures only when the PC enters the area for the first time, sometimes a creature that I want to manipulate through a script doesn't exist yet, so I made a quickie little ga_ script to check if a creature exists, and if not, then spawn it and mark the waypoint so that it won't be spawned again later when the PC enters the area. This is useful not just for the quest system, but also to ensure that kill quests can be completed.
Also added another new ga_ script to toggle an arbitrary number of lights on or off based on their proximity to any reference object, since tags don't work for lights. This needed some debugging, because I forget that GetNearestObject() starts with 1 instead of 0.
I'm having trouble with a secret item. The script works elsewhere, but here it's firing once and never again, based on the debug text appearing only once for On Enter, and never for Heartbeat. Nothing in the script is set to disable it or destroy it after it's triggered once. The only thing I can guess is that the walkmesh might have something to do with it, because it's elevated above ground level, and whenever you draw a trigger, it drops the trigger to ground level even if you have a placeable with a walkmesh over it. But then why would it fire the On Enter script even the first time? It fires it because there's a creature standing in it, but that shouldn't prevent it from firing again on the heartbeat, or when someone else enters it. I don't get it.
Also added another wastebasket for players to dispose of unwanted items.
#973
Posté 29 mars 2014 - 09:18
I finally soldiered through a couple of quest conversations that were holding me back. Too many conditions, alternate paths, etc. The result is not as nuanced as I had in mind, and I can't say I'm satisfied with the way the quest ends as a result, but I had to push it through. I can fully understand the appeal of doing quests with little or no choice in the dialogue. It would take so much less time.
I haven't tested the conversations, but the first one should work, since I had tested the skeleton of the conversation before fleshing it out.
The quests are all done, then, and the only major thing left is to fill in the companion back stories, which basically amounts to more conversation work. There are many other little things that could be done, looking at my to-do list, but none are really necessary to get it out.
#974
Posté 30 mars 2014 - 12:12
Have there been many additions since the first beta?
#975
Posté 30 mars 2014 - 12:37
I can fully understand the appeal of doing quests with little or no choice in the dialogue. It would take so much less time.
I took the view early on that multiple outcomes to quests should be used only when I felt that it really added something to the overall plot/feel of the module.
They are not just hard to create but really hard to debug.
I admire your fortitude
PJ





Retour en haut





