Pondering a quest I'm hoping to make (sometime) I was much annoyed by the fact that you have to edit so many files in order to add anything new. Though Nathan and Pieter have heroically kept track of all the changes made by different people, I think that for mere humans (such as me) it is quite impossible to set up a quest without messing everything up. I've been wondering about how to simplify that process.
As a start (based on an idea originally by Scheffnow, plus some code stolen from Nathan) I've written a function for locations_init so that it automatically loads all files in a "mods" subdirectory of locations/init and executes the initialization code in those files.
The following goes into locations_init.c:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->extern int InitModLocations();
object LocDirectory;
int LocationInitModLocations(int n)
{
DeleteAttribute(&LocDirectory, "");
LocDirectory.dir = "Program\\Locations\\init\\mods";
LocDirectory.mask = "*.c";
CreateEntity(&LocDirectory,"FINDFILESINTODIRECTORY");
DeleteClass(&LocDirectory);
aref arList;
makearef(arList, LocDirectory.filelist);
for(int i = 0; i < GetAttributesNum(arList); i++)
{
aref arCur = GetAttributeN(arList, i);
string fname = GetAttributeValue(arCur);
string fullname = "locations\\init\\mods\\"+fname;
if(LoadSegment(fullname))
{
ref pc = GetMainCharacter();
pc.numlocations = n; //Hack because we can't pass parameters to extern functions
n = InitModLocations();
DeleteAttribute(pc, "numlocations");
UnloadSegment(fullname);
}
else
{
Log_SetStringToLog("There's an error in the location init code in " + fname);
}
}
return n;
}<!--c2--></div><!--ec2-->
Then, at the end of the function InitLocations
(before the line nLocationsNum = n
, add:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->n = LocationInitModLocations(n);<!--c2--></div><!--ec2-->
Thus new locations can easily be added by just dropping a file into that directory, without any further editing of locations_init.c.
I'd very much like to see this merged into the build or modpack, because it will much simplify the addition of new locations. It will not break any of the existing code, just adds some functionality that modders can use or not use as they wish.
If anyone does wish to use it, all you need to do is put the following function in your file:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->int InitModLocations()
{
int n = GetMainCharacter().numlocations;
//...
//increase n by 1 for each new location.
return n;
}<!--c2--></div><!--ec2-->
Apart from the fact that it doesn't get n as a parameter (because extern functions with parameters don't work), the function is just like the ones in the stock game files in the Locations/init folder.
I'm however not sure how it all interacts with reinitializing - so I'd apprecitate any comments.
Sorry for posting so much code - couldn't get the attachment working - it kept saying I don't have permission <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/dunno.gif" style="vertical-align:middle" emoid="
" border="0" alt="dunno.gif" />
As a start (based on an idea originally by Scheffnow, plus some code stolen from Nathan) I've written a function for locations_init so that it automatically loads all files in a "mods" subdirectory of locations/init and executes the initialization code in those files.
The following goes into locations_init.c:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->extern int InitModLocations();
object LocDirectory;
int LocationInitModLocations(int n)
{
DeleteAttribute(&LocDirectory, "");
LocDirectory.dir = "Program\\Locations\\init\\mods";
LocDirectory.mask = "*.c";
CreateEntity(&LocDirectory,"FINDFILESINTODIRECTORY");
DeleteClass(&LocDirectory);
aref arList;
makearef(arList, LocDirectory.filelist);
for(int i = 0; i < GetAttributesNum(arList); i++)
{
aref arCur = GetAttributeN(arList, i);
string fname = GetAttributeValue(arCur);
string fullname = "locations\\init\\mods\\"+fname;
if(LoadSegment(fullname))
{
ref pc = GetMainCharacter();
pc.numlocations = n; //Hack because we can't pass parameters to extern functions
n = InitModLocations();
DeleteAttribute(pc, "numlocations");
UnloadSegment(fullname);
}
else
{
Log_SetStringToLog("There's an error in the location init code in " + fname);
}
}
return n;
}<!--c2--></div><!--ec2-->
Then, at the end of the function InitLocations
(before the line nLocationsNum = n

<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->n = LocationInitModLocations(n);<!--c2--></div><!--ec2-->
Thus new locations can easily be added by just dropping a file into that directory, without any further editing of locations_init.c.
I'd very much like to see this merged into the build or modpack, because it will much simplify the addition of new locations. It will not break any of the existing code, just adds some functionality that modders can use or not use as they wish.
If anyone does wish to use it, all you need to do is put the following function in your file:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->int InitModLocations()
{
int n = GetMainCharacter().numlocations;
//...
//increase n by 1 for each new location.
return n;
}<!--c2--></div><!--ec2-->
Apart from the fact that it doesn't get n as a parameter (because extern functions with parameters don't work), the function is just like the ones in the stock game files in the Locations/init folder.
I'm however not sure how it all interacts with reinitializing - so I'd apprecitate any comments.
Sorry for posting so much code - couldn't get the attachment working - it kept saying I don't have permission <img src="http://www.piratesahoy.com/forum/style_emoticons/<#EMO_DIR#>/dunno.gif" style="vertical-align:middle" emoid="
