Jump to content

Code Discussion Thread


Celtic Minstrel

Recommended Posts

This is really odd and confusing. Basically, I have a global variable that's accessed from two (actually three) different files, yet somehow it seems that there are separate copies of the variable for each file.

 

(The variable in question is scen_headers.)

Link to comment
Share on other sites

  • Replies 990
  • Created
  • Last Reply

Top Posters In This Topic

(The above problem is not yet solved, by the way.)

 

I discovered three differences between the Mac and Windows sounds. Sounds 60 and 97 are quite different in Mac and Windows, and sounds 78 and 79 in Windows are swapped relative to their position on the Mac. The latter I have corrected, but I'm not sure what to do about the former. It'd be good to retain both versions somehow.

 

I came across this inconsistency while writing a function to play outdoor ambient sounds, so that feature is now (theoretically) available.

Link to comment
Share on other sites

Whoa, what? Am I seeing this right? Does this code imply that wandering monsters are more likely to appear while waiting in towns with a lower difficulty?

 

Code:
j = get_ran(1,1,160 - univ.town.difficulty);if (j == 10)    create_wand_monst();

 

So, if difficulty is 0, there's a 1 in 160 chance, or about 0.006%. If the difficulty is 10, there's a 1 in 170 chance, or about 0.005%. And if the difficulty is 50, there's a 1 in 210 chance, or about 0.004%. So, as the difficulty increases, the chance of a wandering monster appearance decreases.

 

Of course, that's repeated up to 80 times, so the actual chance is more like 50% with difficulty 0, 47% with difficulty 10, and 38% with difficulty 50 (though that's not an allowed difficulty, of course).

 

Is this a bug? Should it be fixed? It could be done simply by changing the - to a +.

 

(For reference, this is in handle_action(); search for "Long wait", without the quotes, to find it. It will be about ten lines below that.)

Link to comment
Share on other sites

I've switched to using PNG files rather than PICT resources for the basic graphics. (By "basic", I mean everything except custom scenario graphics.) I also implemented it so that it checks the <scenario-name>.exr folder first for the graphic, then the graphics.exd folder, so if you (for example) include a file "ter4.png" amongst your custom scenario graphics it will override the default ter4.png.

 

Overriding is disabled for interface graphics though, so including a "terscreen.png" amongst your custom graphics will have no effect.

 

I'm trying to move away from resources as much as possible. The dialogs will be transformed into the XML format; the BNDL and the icon families are of course subsumed by the info.plist; Dungeon Bold will be a file instead of a FOND+sfnt resource; I have a .xib in progress which will eventually replace the menubar; I'll probably create the windows instead of getting them from a resource or a nib; and the patterns will hopefully be drawn from a GWorld (not sure how to do that yet; haven't looked into it). And the STR# lists will probably be either inserted directly into the relevant dialog XML or put in a file somewhere; I'm not sure how that should be done either. That just leaves the cursors, pretty much. I'm not sure what to do about them.

 

And I'll need to figure out how to use Quicktime to load sounds. I'm sure it's no harder than using it to load graphics.

 

Speaking of sounds, the Mac and Windows sounds are subtly different (well, except for the two that are completely different). Should I use just the Mac sounds, just the Windows sounds, or both? And what's the best format – AIF, WAV ...?

Link to comment
Share on other sites

AIF and WAV are, to the best of my knowledge, essentially equivalent formats which pretty much store the raw waveform of the sound, making them something of a lowest common denominator. However, given that the game sounds are already small and not of superb recording quality, there's probably no reason to use anything fancier.

 

With regard to cursors, I know that new programs often load cursors from TIFF images, so this should be possible. From a bit of reading, I found a number of complaints that there doesn't seem to be a non-deprecated way to do this entirely with Carbon, but Apple does give an example of how to wrap Cocoa cursor creation so that it can be used from Carbon: http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/. This seems a little odd, but maybe it is the best way. More research may be required.

Link to comment
Share on other sites

Also, I can't find any way to create a PixPat other than from a resource, nor any way to tile an image from some other source. Will I have to manually tile the patterns in order to get away from 'ppat' resources? That is, draw, shift right, draw, shift right, etc, shift down and left, draw, shift right, draw, etc etc.

Link to comment
Share on other sites

'Manually' tiling isn't as bad as you make it sound; just write a function that takes as arguments an image and an area to cover, and does the necessary work. That way you only have to write the code for it once, no matter how many times you need to use it. (In fact, I might take a stab at writing such a function; how are the images stored and what calls were you using to draw them so far?)

 

EDIT: If I remember correctly, snd resources can contain waveform data, much like aif and wav data, or they can contain sound instructions. The latter kind is very rare.

Link to comment
Share on other sites

The cursors thing worked – I needed to modify it a little (since I didn't need their main.c, and there were some essential bits in there), and I accidentally rotated the arrow_curs array (so I had to compensate). But now it works.

 

I think I'll nibify the menus (for all three programs) next. The dynamic spell and monster roster menus seem like they'd be the main difficulty there, but I haven't looked into that yet. Maybe it's really easy.

 

Currently, the pattern images are stored in two places: in "Blades of Exile Graphics" as 'ppat' resources, and in "graphics.exd/mac/pixpats.png" (both in the Scenario Editor folder). I think they're always drawn with FillCRect, so we needn't worry about filling an irregular region. I would put the function in graphtool.cpp (and the corresponding header) and probably call rect_draw_some_item to do the actual drawing (if possible).

 

I could probably write the function myself, but if you feel like writing it, go ahead. smile

Link to comment
Share on other sites

CoreAudio doesn't look all that terrible to use; there is a concise example on this page about playing short using System Audio Services, simple sounds, and a lengthy, very heavy duty example on this page on using Audio Queue services. However, neither of these looks quite right to me at a glance; the former might be suitable many of the game's noises, but not for music or background sounds, it appears. The latter looks like it would be massive overkill for the situations we would encounter.

 

This page gives a tutorial on using Quicktime for such tasks, that looks closer to what we would want, although the bit about having to use MoviesTask seems a bit off. On the other hand, maybe we could just make our own sound thread that would do nothing but call MoviesTask when there are sounds running.

Link to comment
Share on other sites

Thanks, I'll look into that. I think the QuickDraw functions aren't thread-safe, though. On the other hand, that probably doesn't matter if they're never called from the other thread.

 

 

I'm finally getting around to writing the code for editing terrain types using the new dialog engine; then I'll be able to catch any bugs in it (hopefully). And also any sections of the code that I may have left unfinished.

 

 

For replacing STR# resources, I think I may just use a plain text file with one string per line, and read it into a vector. I don't think the .strings format is quite right for this.

Link to comment
Share on other sites

Quote:
On the other hand, that probably doesn't matter if they're never called from the other thread.

That's the idea, this hypothetical thread would exist only to do work for Quicktime, playing sounds. If necessary, suitable locks could be assumedly arranged to guard the movie objects and keep the threads from stepping on each others' toes.

Also: How does this look for a tiling function? It assumes that you're going to load the images that were formerly ppat resources into GWorlds, and though it compiles, I haven't tested using it, as I wasn't sure whether the game yet loads the necessary texture in such a format or not.

Code:
void tileImage(GWorldPtr img, Rect area,short mode=0){	RgnHandle clip= NewRgn();	RectRgn(clip,&area);		GrafPtr cur_port;	GetPort(&cur_port);	const BitMap* drawDest = GetPortBitMapForCopyBits(cur_port);	PixMapHandle drawSource = GetPortPixMap(img);		Rect imgRect;	GetPortBounds(img, &imgRect);		int imgWidth=imgRect.right-imgRect.left;	int imgHeight=imgRect.bottom-imgRect.top;	int x,y;	unsigned int hrep = (int)((double(area.right-area.left)/imgWidth)+0.5);	unsigned int vrep = (int)((double(area.bottom-area.top)/imgHeight)+0.5);	for(unsigned int i=0; i<vrep; i++){		for(unsigned int j=0; j<hrep; j++){			x=area.left+i*imgWidth;			y=area.top+j*imgHeight;			Rect targetRect={y,x,y+imgHeight,x+imgWidth};			CopyBits((BitMap*)*drawSource, drawDest,&imgRect,&targetRect,mode,clip);		}	}	DisposeRgn(clip);}
Link to comment
Share on other sites

That looks like it would work, provided I load each pattern into a separate GWorld. I currently have them all on one sheet, but separating them wouldn't be too hard. In fact, it would be easier than it was to create the composite sheet. (I believe the "all on one sheet" version is used by Windows at the moment, but I'm still using 'ppat' resources.)

 

 

Were you going to commit that or did you expect me to copy/paste it?

Link to comment
Share on other sites

I can commit it, but since I wanted to verify whether it would suit the intended usage, I wanted to get your opinion on it first. It would of course be simple to make it take a source Rect as a parameter and only draw part of the GWorld, it just hadn't occurred to me to do that since the ppat resources were each separate objects. I'll write that later and then commit it.

Link to comment
Share on other sites

Okay then. Then I'll make bg (currently an array of PixPatHandle) into an array of Rect rather than an array of GWorldPtr, and add a new GWorldPtr for the pixpats.

 

 

 

And this'll also give me a chance to figure out svn conflict resolution with my client, since I've also modified graphtool.cpp. I think the part I missed last time was "update".

Link to comment
Share on other sites

First of all :

 

Originally Posted By: Chokboyz
i've found a bug with the current kill_pc() function : in a combat, if a pc is killed by backshots (i.e when running away from monsters), the first pc alive is set active with 0 AP, thus having a free extra action. To avoid this, i've changed the lines

While the bug is annoying, this "fix" is far worst because it give all monsters a free turn if they manage to kill a pc during the monsters turn (needless to say, that makes them wipe the party really fast). A real fix to this bug is to set the variable done_something to TRUE after pc_combat_move() call (in the handle_action() function) if the pc is dead (a possible way to see if it's the case, is to check if the current_pc variable has changed ...).

I've checked the Mac code in the repository and the previous faulty "fix" has, thankfully, not been applied.

The current fix has been tested and works wink

 

Concerning the graphic corruption bug : (from the repository issue description)

 

Originally Posted By: dlev89
Every once in a while, on entering or leaving a town, random graphics

(everything from monsters to objects to terrain) are shown on the screen

instead of town or outdoor terrain. This one's going to be difficult to

reproduce... Closing and reopening the game fixes it, and it really does

appear to be random - a saved game that produced the graphics corruption

once will not necessarily produce it again.

I suspected the problem was with the storage sheet and a possible out of bound item to draw or an index out of an array ...

Unfortunately, the whole graphic process was quite awkward, filling three arrays with informations about what graphic to copy on the storage sheet and such, not to mention the actual copying/drawing ... At this point, i decided that drawing the graphics directly from the terrains/monsters sheets was a much better option ...

So, i've rewritten the terrains/monsters drawing code so that no intermediate storage sheet is used. I've also change the loading procedures so that the terrains and monsters sheets are always loaded in memory.

Advantages : drawing is done faster, graphical limits are gone (no more "out of memory" error), the Mac/Windows graphics swapping can be done "in the fly" (without restarting the game), ...

Note that, after deleting all the storage sheet loading/using related functions, the executable was 10Ko smaller.

Disadvantage : a little more memory is used by the game (nothing really noticeable, some Ko at most).

 

That should also fix the previous graphic corruption bug (then again, it may be something else, since i wasn't been able to reproduce it).

 

I've also implemented a very crude custom intro picture handling : if the scenario.intro_pict is set to 30 (29 is the last one in SCENPICS.BMP), then the first picture of the custom sheet is used as the scenario intro icon (note that the dimensions of the intro picture are the same that the talking portrait ones, so the first two squares of the custom sheet will be used and they need the same formatting as the talking portrait).

 

Chokboyz

Link to comment
Share on other sites

I've already got my code loading all the sheets for use by the dialogs – I just need to make all the other drawing code use the same sheets.

 

Did you also get rid of the party template sheet? It seems that the game basically loads the PC graphic sheets and rearranges the graphics into the party template sheet, or something. This seems as pointless as the storage sheet.

 

Originally Posted By: Chokboyz

I've also implemented a very crude custom intro picture handling : if the scenario.intro_pict is set to 30 (29 is the last one in SCENPICS.BMP), then the first picture of the custom sheet is used as the scenario intro icon (note that the dimensions of the intro picture are the same that the talking portrait ones, so the first two squares of the custom sheet will be used and they need the same formatting as the talking portrait).

I was going to implement something along these lines eventually, but not quite like that. Your method sounds like it has one major disadvantage (does the custom scenario icon show up in the Pick Scenario dialog? It should). For use by the Pick Scenario dialog I intend to copy each relevant scenario graphic to a dedicated sheet. I hadn't yet decided about whether to use 1000 + x for the custom scenario graphic or use a separate 32x32 dedicated sheet (since graphics will now be a folder rather than a single file).

 

I would also suggest a different value for "first icon on the custom sheet", for example 100, in case we decide to add additional default scenario graphics. If I chose the second method (dedicate 32x32 sheet) I would probably implement it in that way.

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
Did you also get rid of the party template sheet? It seems that the game basically loads the PC graphic sheets and rearranges the graphics into the party template sheet, or something. This seems as pointless as the storage sheet.

Seems indeed as pointless as the storage sheet ... I'll then remove it, thanks for mentioning.

Originally Posted By: Celtic Minstrel
does the custom scenario icon show up in the Pick Scenario dialog? It should

It does show in Pick Scenario.

Originally Posted By: Celtic Minstrel
I would also suggest a different value for "first icon on the custom sheet", for example 100, in case we decide to add additional default scenario graphics. If I chose the second method (dedicate 32x32 sheet) I would probably implement it in that way.

Ok, I've change the value to 100. Note that intro_pic is an unsigned char so using the 1000 + x method is impossible (or we need to change the scenario structure). The dedicated sheet approach seems fine to me ...
Nonetheless, all i've done concerning the custom intro_pic is very crude and not supposed to be more than a test wink

Chokboyz

Edit : the party_template_gworld is now gone.
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Edit : the party_template_gworld is now gone.
Yay, maybe that'll be the next thing I do.

Okay, I'm getting a link error:
Quote:
dyld: Library not loaded: /usr/local/lib/libticpp.dylib
Referenced from: <very long path removed>/openexile/osx/build/Debug/Scenario Editor/BoE Scenario Editor.app/Contents/MacOS/BoE Scenario Editor
Reason: image not found
Now, obviously this would be easily fixed by simply moving libticpp.dylib to the expected location, but I'd rather change where it searches for it, and somehow I can't seem to determine how to do that. It's probably something very simple that I'm missing...
Link to comment
Share on other sites

When I built it as a static library, I got linker warnings about visibility, much like I had when I was linking the STL as a static library. (Probably because it uses the STL.) And my initial plan of linking it directly into each program (ie not precompiling it as a standard library!) failed because "#include <Carbon/Carbon.h>" is automatically prefixed to every file, and one of its names conflicted with one of ticpp's names (because they had a "using namespace ticpp;" statement). I didn't think editing the ticpp source files would be useful because it's included via svn externals.

 

{Ticpp also has a stupid setup involving the macro TIXML_USE_TICPP. The primary header file defines it, then checks to see if it's defined (so, basically, it does nothing for the header). The primary source file checks if it is defined, and only then does it actually include the header that defines it (so, basically, you get a lot of link errors because the file is emptied by the preprocessor). I solved this by defining it as a global symbol in the target settings. I get "macro redefined" warnings, but at least it works without editing the source.}

 

 

Link to comment
Share on other sites

My recommendation would be to try again with linking it in directly, without compiling it to a separate library. That's what I've personally found to work the best. One thing to do would be to turn off automatically prefixing every file with the Carbon #include, after it's much easier (and for reasons like this, safer) to just include it directly in the files that immediately need it. I've also run into that stupidity with TIXML_USE_TICPP; one solution (which would be better than mine of altering the source file, for the reasons you describe) would be to define that macro with the -D flag when compiling. (I'm not sure whether this is what you did or not, and I don't know if it will avoid the warning you describe, but I thought I'd mention it.)

Link to comment
Share on other sites

Originally Posted By: Niemand
One thing to do would be to turn off automatically prefixing every file with the Carbon #include, after it's much easier (and for reasons like this, safer) to just include it directly in the files that immediately need it.
I know, but I have no idea how to do this. Xcode sets or doesn't set this automatically when I create a target, and I don't know how to do it manually.

Originally Posted By: Niemand
I've also run into that stupidity with TIXML_USE_TICPP; one solution (which would be better than mine of altering the source file, for the reasons you describe) would be to define that macro with the -D flag when compiling. (I'm not sure whether this is what you did or not, and I don't know if it will avoid the warning you describe, but I thought I'd mention it.)
Yes, that is (effectively) what I did. (I added it to GCC_PREPROCESSOR_DEFINITIONS which I assume passes it to the compiler with the -D flag.) And it causes the "redefined macro" warning when it encounters the #define in ticpp.h. There's nothing that can be done about that without altering the source.
Link to comment
Share on other sites

The tileImage function did, in fact, work. There was one problem which was fixed by switching hrep and vrep, and I also added something to avoid clashes resulting from the pattern being drawn from different anchor points (after setting the clip region, I subtract from area.left and area.top just enough for it to be a multiple of width and height respectively). And there was one use of FillCRgn, so I added an overload that takes a RgnHandle as a parameter instead of a Rect.

Link to comment
Share on other sites

Huh, that's odd.

 

I removed the ticpp target and unset the prefix header settings. I think that's pretty much everything I did. And I'm using the same Xcode version, too (the one that came with MacOSX 10.5.0) – I've been putting off upgrading because it seems I need a developer account to do so.

 

So I have no idea what could be causing problems.

Link to comment
Share on other sites

Apparently my local copy was somehow corrupt, even though it was claiming to be up-to-date. I erased and restored it; now it opens fine.

 

Quote:
I've been putting off upgrading because it seems I need a developer account to do so.

You do, but the free student level account is sufficient; all it requires is an email address. It's worthwhile because you can both upgrade your main tools and download other ones that may be useful for more specific tasks. On the other hand, it's not something that you can't live without easily enough.

Link to comment
Share on other sites

Now I have another runtime error:

Code:
Program received signal:  “EXC_BAD_ACCESS”.Xcode: Introspection dylib not loaded because thread 1 has function: __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE on stack

I know what EXC_BAD_ACCESS is, but the other part confuses me. This occurs before execution of main(), in the STL. (I'm inserting elements into a map. If you want to look at the code, it's in cPict::init().)

 

 

 

On an unrelated note, I've been meaning to ask... if I overload a member function (such as operator[]) with both const and non-const forms (that's const this I'm referring to), will the const form be called whenever the function is not used as an l-value?

Link to comment
Share on other sites

I frankly have no idea what that crash is about, especially since I can't reproduce it. However, I had a some other problems with building the latest revision which I had to hack my way around:

-We're apparently now dependent on boost, and my copy is installed somewhere different that yours, so I just jammed it in with a -I flag.

-"in /Developer/SDKs/MacOSX10.4u.sdk/usr/local/lib/libGLU.dylib, file is not of required architecture" I ended up just disabling compilation for PowerPC to get this out of my way.

 

At any rate, I see nothing wrong with cPict::init(); what leads you to think that the problem is there? In particular, this seems to me inconsistent with your statement "This occurs before execution of main()..." since cPict::init() gets executed by main().

 

Quote:
if I overload a member function (such as operator[]) with both const and non-const forms (that's const this I'm referring to), will the const form be called whenever the function is not used as an l-value?

I'm not sure exactly; as you already know the const version will be called when const correctness strictly requires it, but I don't know which will be chosen if either could be used. Would it really matter? That is to say, were you planning to actually code them to behave all that differently such that using the non-const version as an r-value would cause a problem?

Link to comment
Share on other sites

Originally Posted By: Niemand
At any rate, I see nothing wrong with cPict::init(); what leads you to think that the problem is there? In particular, this seems to me inconsistent with your statement "This occurs before execution of main()..." since cPict::init() gets executed by main().
Actually, cPict::init() is called by cDialog::_init::_init(). The error occurs when inserting elements into the map.

Originally Posted By: Niemand
I'm not sure exactly; as you already know the const version will be called when const correctness strictly requires it, but I don't know which will be chosen if either could be used. Would it really matter? That is to say, were you planning to actually code them to behave all that differently such that using the non-const version as an r-value would cause a problem?
Well, for towns I have a member function terrain(x,y) which returns the terrain at a given spot as a reference, so it can be written to. (I did it this way to minimize the number of changes I would have to make.) For the ordinary towns, this works just fine, but for the template towns I think will need to do something different depending on whether you are setting the terrain or merely retrieving it. (When retrieving, it would have to do calculations to grab the terrain from the correct place, either the base or a city block; when setting, I would probably want to place the changed terrain on a separate overlay or something; I'm not quite sure yet.)

I could just not return a reference, and have a separate setter.

Originally Posted By: Niemand
I frankly have no idea what that crash is about, especially since I can't reproduce it.
I think adding the line "cDialog::_init cDialog::init;" just before line 714 in dialogxml/dialog.cpp (the line number actually doesn't matter, that's just where I put it) should allow you to reproduce it. I made a few other changes to that file, but they shouldn't matter, I think.

Originally Posted By: Niemand
-"in /Developer/SDKs/MacOSX10.4u.sdk/usr/local/lib/libGLU.dylib, file is not of required architecture" I ended up just disabling compilation for PowerPC to get this out of my way.
...Wait, what's libGLU for?
Link to comment
Share on other sites

Originally Posted By: Miramor
Huh... Anyone know what causes the "Unfortunately you die!" special node to be wrongly triggered in Bandits 2? If anyone can tell me what is going on there, that will be my first bug report...
[...]
It went off when the Ultimate Weapon's first form died - when Katothen opened up a way out of Deacon's lair and the invulnerable blue second form appeared. One of my PCs was wearing Lenin's pendant, so I'm pretty sure this wasn't supposed to happen.

In your case, the "Unfortunately you die!" (and again ... and again ...) is triggered if the blue form of the Ultimate Weapon is killed. Being Invulnerable and having 2500 HP, 50 armor and 40 skill/level, i'd say the only possible way to kill it is either to use the Debug Kill command or cast a Wound spell on it while being in debug mode ... If you did either that's the cause of the problem (i.e TM not wanting people to play his scenario in debug mode, killing everything on sight smile ). (note that using the Debug Kill command to kill the first three red forms may as well kill the blue form depending on how the special chain is done)
As far as i can tell, the Lenin's Pendant is only used to bypass the barriers right after the stairs at the beginning of the Lair of the Red Star.
I was able to play the encounter and escape without any problem.

On another note, it is actually possible to kill the party (with Kill nodes) then to End the Scenario in the same encounter, giving the player the possibility to save the party before giving the quit/restart/reload screen. I think that should be fixed (don't end the scenario if the party is dead, only give the quit/restart/reload screen).

Chokboyz




Link to comment
Share on other sites

I agree. While this will "break" TM's scenarios, it will probably break them in a good way.

 

I may have done the same thing in Terror From The Park, but I'm not sure. Even if I did, it's not a problem if the behavior is removed.

 

EDIT: Be careful not to break other nodes that are called after killing the party, though. Make it only affect End Scenario, like putting a check in the node to see if the party is dead before it does anything.

Link to comment
Share on other sites

Originally Posted By: The Almighty Doer of Stuff
I agree. While this will "break" TM's scenarios, it will probably break them in a good way.

I may have done the same thing in Terror From The Park, but I'm not sure. Even if I did, it's not a problem if the behavior is removed.

Ok, it's fixed ...

I've also found (one of the reason, i think) why empties appears.

When entering in a town that is not in memory, the program populate the c_town.monst.dudes array : if the monster number is 0 (i.e no monster), the time_flag, number, active and m_loc.x field are the only one to be set to 0 (80 for m_loc.x). Unfortunately, that leaves a lot of field in the previous state they were in the memory; amongst others monst_start.spec_enc_code.
So, for example, if you visited a town with monster 3 appearing on event 1 and you enter a new town with monster 3 being 0 (no monster); if the event 1 happens in the new town, an empty will appear (at the first monster start location coordinates).
Setting spec_enc_code to 0 when loading town in memory fix the problem.

I've also updated the scenario editor to set time_flag and spec_enc_code to 0 when deleting a monster, effectively cleaning the memory a bit.

Chokboyz

Edit : for information, did you use Town Encounters or Place Monster for the idol in the Killing Cave, ADoS (when the problem appears) ?
Link to comment
Share on other sites

I used Place Town Encounter. I started the scenario over after the bug occurred and lost the original, unfortunately, so it can't be used for testing purposes.

 

EDIT: However, I can say that I created the original idol, set its town encounter number, set up the node that placed it, and then moved the whole thing over to the left and then deleted the original. It occurred somewhere in that process, but I've been unable to replicate it.

Link to comment
Share on other sites

Originally Posted By: Chokboyz

In your case, the "Unfortunately you die!" (and again ... and again ...) is triggered if the blue form of the Ultimate Weapon is killed. Being Invulnerable and having 2500 HP, 50 armor and 40 skill/level, i'd say the only possible way to kill it is either to use the Debug Kill command or cast a Wound spell on it while being in debug mode ... If you did either that's the cause of the problem (i.e TM not wanting people to play his scenario in debug mode, killing everything on sight smile ). (note that using the Debug Kill command to kill the first three red forms may as well kill the blue form depending on how the special chain is done)
As far as i can tell, the Lenin's Pendant is only used to bypass the barriers right after the stairs at the beginning of the Lair of the Red Star.
I was able to play the encounter and escape without any problem.


Nope, in my case it was triggered when the second to last form was killed. The final blue form was never killed, and I was definitely not in debug mode.
Link to comment
Share on other sites

Originally Posted By: The Almighty Doer of Stuff
I used Place Town Encounter. I started the scenario over after the bug occurred and lost the original, unfortunately, so it can't be used for testing purposes.

EDIT: However, I can say that I created the original idol, set its town encounter number, set up the node that placed it, and then moved the whole thing over to the left and then deleted the original. It occurred somewhere in that process, but I've been unable to replicate it.

Ok, sounds like it was exactly the previous situation happening (deleted monsters, but memory not cleaned, and called Place Town Encounter).

Nonetheless, I've been able to test the fix with my own made scenario and it works ...
(and i have been able to reproduce empties appearing in Turtle Whipper's General Store in the Inn of Blades scenario that you mentionned : begin the scenario, goes to the docks, exit and goes to the marketplace, goes to Mage Xavier and make the demon appears (take the wand), goes to Turtle Whipper's General Shop ... wait, what's those ?!?)

Originally Posted By: Miramor
Nope, in my case it was triggered when the second to last form was killed. The final blue form was never killed, and I was definitely not in debug mode.

Unfortunately, i haven't been able to reproduce that. Leaving the NPC do the dirty work, i've been able to finish the encounter several times.
Just to be safe : note that there's only two forms : the red one that is summoned three times (after killing it two times) and the blue/red mix that is the invulnerable one. And you have only 100 moves to kill the three first "pink ultimate weapon" and escape before the bomb goes off.
If the behavior persist Ok, i've been able to experience it, so can you send me a copy of your savefile ? smile
(from preliminary inspection, don't let an NPC deal the killing blow to the third pink form to avoid the glitch)
Update : i've been able to experience the glitch with the original version of BoE ... frown (i think it's the mix of a node destroying the very same monster that has died and the fact that an NPC was in the middle of hitting it when it died that provokes the glitch, but i need some more testing).

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Setting spec_enc_code to 0 when loading town in memory fix the problem.
Why not just zero the array before populating it? For the moment, a simple memset would handle that quite well; in fact, my monster class doesn't have any virtual methods, so it would probably be safe even with that.




Also, Niemand, did you see my previous post?

If I can't figure out the problem there, I'll probably just waste some space and replace the map with a regular array.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
Why not just zero the array before populating it? For the moment, a simple memset would handle that quite well; in fact, my monster class doesn't have any virtual methods, so it would probably be safe even with that.

The array is populate each time a non-saved town is entered (only the four last towns are recorded in the savefile) and if the monster number x is of type 0 (empty) in the entered town, the corresponding index structure is left alone except for the fields mentioned. Resetting the whole struct to a "blank" one (0 for most field, -1 for some) can be done, but that has to be done each time a new town is entered.
I think we can left it the way it is, because the 0 type assure that the monster won't be accessed by the game (the only forgotten case was Place Town Encounter).

Also, i've updated the Scenario Editor "Delete Monster" function so that the fields checked in the game are cleaned (previously the town limit could be hit even without having the max monsters because, for example, spec_enc_code or life_flag were not set to 0 (-1 for the latter).) That should ensure that any future town creatures array is clean.

Chokboyz

Edit : Changed the way the town room/outdoor info rectangles were handled by the Scenario Editor ; the 16 rectangles are now initialized to coordinates((-1,-1),(-1,-1)), freeing the 0 coordinate and fixing the rectangle X description appearing at (0,0). Note that, for legacy scenario, the rectangles being saved in the scenario file, the "Rectangle X" description will always appears at (0,0) because the rectangles are saved at (0,0) (can be fixed by opening the scenario and deleting the rectangles via the menus).
A really trivial enhancement, but it's done smile
Link to comment
Share on other sites

Originally Posted By: Miramor
Chokboyz: Sure thing.

Well, that was one hell of a bug (and back luck) : for some reasons TM decides that when dying the third form calls a node that destroy it (actually freeing its monster slot (10)), then the following node force place the blue form. All of that is called by the kill_monsters() funciton.
What the force_place() function do is to ensure that a free spot is availaible to place the monster or make one (nice infinite loop glitch here : try putting 60 monsters with life flags in a large town and force place a monster ... rolleyes ), the previous monster slot being free the function then proceed to effectively place the monster ... Here is the trick, the third pink form slot being free, if there's enough monsters (Disco Joe will mass summoning enough for it to happens) to fill the gap left by the previous dying form, the first availaible slot will be 10, the one the Destroy Monster Node just had freed.
Unfortunately, that means that the new monster structure will be copied over the old one; given that the kill_monster() function is still not finished that's asking for trouble.
And in fact, the thing that is checked right after the Special on Death nodes chain is if a global scenario node is to be called ... The monster 10 now being the blue form, it indeed has one (255) : the "Unfortunately you die !" sequence ...

That's really improbable, but that's what happens smile
This can also happens in the original BoE.

There's no fix for that, because the Destroy Monster node shouldn't be called at all (don't hesitate to tell me, if i'm mistaken) : it's a scenario bug ...

Possible Workarounds :

- Refrain from summoning (and pray that Disco Joe keeps on tossing Firestorms and Divine Thuds)
- Kill the two and third forms in the same round (i've seen NPC do that, especially when hasted grin )
- Have some NPC killed frown
- Open the scenario in the Scenario Editor, go to town 28 and change the town special 54 to No Special (or whatever that does nothing), save and redo the encounter (if you're already in the Nuclear Bomb town, that you won't work).
- Persist on trying, one moment or another the free slot won't be 10 (the thing is not to summon anything after the second pink is dead. Note that if Disco Joe cast Major Haste, then it will likely be ok, given that Bladesman Wasazore will have 24 AP that is often enough to single-hand two pink forms).

Hope it helps,
Chokboyz
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

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...