Jump to content

Code Discussion Thread


Celtic Minstrel

Recommended Posts

  • Replies 990
  • Created
  • Last Reply

Top Posters In This Topic

Originally Posted By: Chokboyz
Ok, when party is split the lone pc only will now be affected by Affect Health/SP/Skill Points/Statistics and Give Mage/Priest Spells.
The Kill/Raise Nodeis left untouched for compatibility reasons (although we can implement a "kill only present pc" switch via pic if revelant).

Sample of the code used (Affect Health Node) :
Code:
case 82:    for (i = 0; i < 6; i++)        if(PSD[304][0] > 0 && adven[i].main_status == MAIN_STATUS_ALIVE) //party split ?[/color]            adven[i].cur_health = minmax(0,	(int)adven[i].max_health,                adven[i].cur_health + spec.ex1a * ((spec.ex1b != 0) ? -1: 1));        else if (PSD[304][0] == 0 && ((pc < 0) || (pc == i)))    	    adven[i].cur_health = minmax(0,	(int)adven[i].max_health,                adven[i].cur_health + spec.ex1a * ((spec.ex1b != 0) ? -1: 1));    break;
Eek, what are you doing here? I've simply added some code near the top of the function:
Code:
if(PSD[sDF_IS_PARTY_SPLIT] && cur_node.type != SPEC_AFFECT_DEADNESS)    pc = PSD[sDF_PARTY_SPLIT_PC];else pc = current_pc_picked_in_spec_enc;
That last line (minus the else) was already present.

Isn't that more efficient? Notice that I've made a special exception for Kill/Raise Dead – it always affects current_pc_picked_in_spec_enc.

I'm unable to test it, though, since the old dialog engine is doing strange things.


Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
used Fireball against them, but after the fiery explosion I saw them take what appeared to be weapon damage.

Seems like a problem with boom_space() or add_explosion() ... Speaking of which, in your code, you've merged boom_space() and pre_boom_space() function and commented the type = type % 10 line, but the boom_space() function is called in damage_monst() with type = 51 ... The boom_space() function then does nothing because type is not between 0 and 4.
That doesn't seems to be the cause of the bug mentioned above (it's much likely add_explosion), but that can be a potential glitch ...
I'm pretty sure there never was a pre_boom_space(), at least by the time I first saw the code. And I commented that one line because I moved the sound to a separate parameter.

As for calling boom_space with type 51... that's for the amount of damage indicated in how_much_spec. If, as I suspect, that is the damage from assassination, it should be changed to type 1.

And finally, I don't think that problem was with add_explosion(), since that handles the animated explosions, right? That problem was after the explosion finished.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
What else besides hit points is affected?

Monsters damages can be multiplied by 3/2 or 2, depending on the pc vs. difficulty level difference. I suggest we use flag_i since it was not used in the original code as well (meaning its value is 0 for all legacy scenarios).

Originally Posted By: Celtic Minstrel
Okay, so I went in to incorporate the changes to the Affect PC nodes (making them affect only the active PC when the party is split), and ended up doing cleanup of the code. One odd thing I noticed is that when drinking a potion, the "swallow" sound is played only if the graphic 50, 51, or 52. I've removed this check, so the sound will be played no matter what the graphic (but only if the variety is POTION).


Originally Posted By: Celtic Minstrel
Another odd thing in this function is in case 120 (ITEM_SPELL_MASS_SUMMONING), in the for-loop. The end condition for the for-loop is "i < get_ran(1,3,5)", which I think means a new random value is used each time the loop executes! It will work just fine as-is, but it seems pointless. I suggest removing the get_ran call to just before the loop and storing it in a variable.


Originally Posted By: Celtic Minstrel
In use_space, when checking for "TER_SPEC_CALL_SPECIAL_WHEN_USED", there's no return statement. Because of this, the message "Nothing to use" is printed even though something was used. I added a "return true" to the end of the if clause to fix this.

Fixed.

Originally Posted By: Celtic Minstrel
In adj_town_look, when checking for blockage, the "Search: You find something!" messages were commented out. I uncommented them... though we need to check those if statements, because I think it's checking a Stuff Done Flag that it shouldn't check.

Those lines are absent of the Windows code (seems pretty redundant, so i won't add them). SDF checks in this code are definitely to be removed.

Originally Posted By: Celtic Minstrel
Also in that function, there's a switch statement that prints "(Use this space ...)" if the terrain type is 22 or 23... that is, Mountains. I've removed the switch statement altogether, since it had only one case, and moved the default case directly into the else statement. The original case is still present, but now checking the terrain ability to see if it's one of the two usable types.

Done. Did you change the variable terrain type to unsigned char so that it works for terrain with number > 127 ?

Originally Posted By: Celtic Minstrel
Additions to the list of constants

Will add them shortly.

Originally Posted By: Celtic Minstrel
Okay, I've removed the 50 node limit.

That's fine with me, but i'm not really sure about the escape key (outside of debug mode that is).
Whatever the case, if such an escape key is to be implemented, it will surely be "Ctrl+C".

Originally Posted By: Celtic Minstrel
Isn't that more efficient? Notice that I've made a special exception for Kill/Raise Dead – it always affects current_pc_picked_in_spec_enc.

Indeed. Adopted.

Chokboyz

Edit : in the townmode_spec() function, in the Split Party node case (193) the check if (party.stuff_done[304][0] > 0) doesn't include a return or is not followed by an else. The code so continue to run and the party can (disastrously) be split a second time.
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
What else besides hit points is affected?

Monsters damages can be multiplied by 3/2 or 2, depending on the pc vs. difficulty level difference. I suggest we use flag_i since it was not used in the original code as well (meaning its value is 0 for all legacy scenarios).
This really doesn't matter; new fields that we add will be initialized with a default value on loading. They won't be initialized with the value of some existing field.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
In adj_town_look, when checking for blockage, the "Search: You find something!" messages were commented out. I uncommented them... though we need to check those if statements, because I think it's checking a Stuff Done Flag that it shouldn't check.

Those lines are absent of the Windows code (seems pretty redundant, so i won't add them). SDF checks in this code are definitely to be removed.
In fact, I replaced all those lines with just an add_string_to_buf call. So, just before calling run_special, if "get_blockage(univ.town->terrain(where.x,where.y)) > 0", it prints "Search: You find something!".

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
Also in that function, there's a switch statement that prints "(Use this space ...)" if the terrain type is 22 or 23... that is, Mountains. I've removed the switch statement altogether, since it had only one case, and moved the default case directly into the else statement. The original case is still present, but now checking the terrain ability to see if it's one of the two usable types.

Done. Did you change the variable terrain type to unsigned char so that it works for terrain with number > 127 ?
No, I missed that. I've made it a ter_num_t now (which is an unsigned short).

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
Okay, I've removed the 50 node limit.

That's fine with me, but i'm not really sure about the escape key (outside of debug mode that is).
Whatever the case, if such an escape key is to be implemented, it will surely be "Ctrl+C".
...sorry, you're unsure of what?

Originally Posted By: Chokboyz
Edit : in the townmode_spec() function, in the Split Party node case (193) the check if (party.stuff_done[304][0] > 0) doesn't include a return or is not followed by an else. The code so continue to run and the party can (disastrously) be split a second time.
I put a break at the end of that if block to fix that. It probably was never caught because the documentation says you shouldn't allow the party to reach a Split Party node when they're already split. (At least I think it does.) I also added a break to the preceding if statement that checked for combat mode.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
This really doesn't matter; new fields that we add will be initialized with a default value on loading. They won't be initialized with the value of some existing field.

Yup, unfortunately there no way to set them for already existing scenarios (except by opening them and saving them with an updated editor). I thought that choosing a value we know the value would be better (some other flags were used for password encrypting so they have scenario specific values).

Originally Posted By: Celtic Minstrel
...sorry, you're unsure of what?

of whether we should give the player the ability to break node chains. Maybe if the debug mode is activate, but then again, since it's unprotected ... confused

Originally Posted By: Celtic Minstrel
I put a break at the end of that if block to fix that. It probably was never caught because the documentation says you shouldn't allow the party to reach a Split Party node when they're already split. (At least I think it does.) I also added a break to the preceding if statement that checked for combat mode.

Are you sure it won't break out of the if loop ?

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
This really doesn't matter; new fields that we add will be initialized with a default value on loading. They won't be initialized with the value of some existing field.

Yup, unfortunately there no way to set them for already existing scenarios (except by opening them and saving them with an updated editor). I thought that choosing a value we know the value would be better (some other flags were used for password encrypting so they have scenario specific values).
...Well, yes we can set them for already existing scenarios, when we convert them to the newer format.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
...sorry, you're unsure of what?

of whether we should give the player the ability to break node chains. Maybe if the debug mode is activate, but then again, since it's unprotected ... confused
I think it's fine – if the designer misses a place where an infinite loop could occur, you don't want to be forced to kill the program just because you forgot to (or could not, in the case of beta testers) enter debug mode. And I display a warning message when you do it, indicating that it's probably a bad idea to continue without reloading.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
I put a break at the end of that if block to fix that. It probably was never caught because the documentation says you shouldn't allow the party to reach a Split Party node when they're already split. (At least I think it does.) I also added a break to the preceding if statement that checked for combat mode.

Are you sure it won't break out of the if loop ?
Uh... "if" is not a loop, and hence break does not affect it. A break statement only affects loops (for, while, do) and switch statements.

The reason we don't want a "return" statement is that if we do that, the code after the switch statement will be skipped (which could potentially be a bad thing). Putting the rest of the case in an else would work, but I like the break statement better.
Link to comment
Share on other sites

Originally Posted By: Chokboyz
I've added an option (switch for now) to use Mac (darker) graphics with the Win32 version. The only changes i could notice were in terrains sheets, field sheet and maps sheets (the pc, monsters and items graphics are the same)...
I can't do this until the Windows version uses pngs which match those of the Mac version (currently it uses BMPs, some of which don't match).

Originally Posted By: Chokboyz
Does the Mac graphics have an equivalent of the rough graphic squares used in Win32 to draw on the map, or does it uses animmap/termap exclusively ? (for example, if you put a hill square with two boulders on it, will it appears like that on the map or rather like a plain hill square ?)
I neglected to tell you, but these were added to pixpats.png quite a while ago. I also added the ones for blue cave floor from Exile 3.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
The Mac version uses ppat resources for those files - I didn't upload the map ppats because I believe they are identical to the equivalent map graphic (termap.gif in the files I uploaded). If they aren't, though, I'll gladly add them (probably to pixpats.gif).

They are, but scaled down ... I've extracted bitmaps from files and scaled them down, but the result was not really pretty (as soon as the terrain was not plain (bushes, ...) the square appears somewhat garbled).
So, if you find time, i'll be glad you upload them smile
Which I did... though, didn't those ones also have a 6x6 version in the grid with all the other map squares?

Originally Posted By: Chokboyz
Anyway, I found a nice relic from Exile III in the place_spell_pattern() function :
[...]
I've deleted the code as it can lead to potential glitches (dialog 3464 and 3239 doesn't exist to begin with; i've locked up a game testing that wink ).
By the way, if anyone can confirm that town number 23 is Slime Pit (the level with the slime pool) and town number 46 is the town where you find the lone slime pool, don't hesitate ... I've found that it was indeed those town in Ishad Nha's Scenario Data sheet (Thanks smile )
Well, either I already removed it or it wasn't there in the first place in the Mac code. So that's good.

Originally Posted By: Chokboyz
A quick bug :

the create_wand_monst() function is bugged so that only the first monster type of the third and fourth row, and the second monster type of the fourth row may appear by pair (the editor tells us it should be the monster type of the last line for each row).
I choose to make a second monster of the last line type appears with a probability of 1/2 (inspired by the faulty code).
I looked at your code, and implemented this. The only difference is that I moved the second monster outside the loop, since it's only needed once anyway. I also made my code match yours a little more in terms of member functions.

Originally Posted By: Chokboyz
The start_outdoor_combat() function is also a little off from the Scenario Editor description :
the lines
short low[10] = {15,7,3,3,1,1,1,7,2,1};
short high[10] = {30,10,5,5,3,2,1,10,4,1};

should read
short low[10] = {15,7,4,3,2,1,1,7,2,1};
short high[10] = {30,10,6,5,3,2,1,10,4,1};

to be accurate ...
Done.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
In monst_check_special_terrain(), when checking is_force_barrier(), there's a check for the town number being greater than 20, which means that a monster can't break down a force barrier in towns 0 through 19 but can in towns 20 and up. This seems utterly pointless, so I've removed it.

A comment in that section of the code implies that the intention may have been to prevent monsters from breaking barriers in large towns, so it could be an E3 relic. The question, then, is: should we simply remove it, as I have, or should we replace it with a check for town size?
Well, I decided to make a flag. In the town structure, I replaced this line:
Code:
unsigned char specials1,specials2,res1,res2;

with these lines:
Code:
bool strong_barriers : 1;bool defy_mapping : 1;char reserved_bits : 6;

I check strong_barriers in monst_check_special_terrain when checking is_force_barrier; hidden_map is to cover the one use I had already gotten out of specials2, ie making a town map unavailable. It is checked in do_mage_spell (case 33), use_item (case ITEM_SPELL_MAGIC_MAP), and draw_map. Also, I'm not 100% sure how bit fields work, but I suspect reserved_bits is not actually necessary.

Originally Posted By: Goodbye World
Here;s a feature request:

Have an option to display animated terrain as animated (eg. go through all 4 frames when editing the map) in the scenario editor.

I'm assuming it could be possible to just steal the code from the game?
If I recall correctly, the new dialog engine can support this; in fact, it can animate other graphics too (such as monsters). However, it won't do this automatically; there's a member function to advance it to the next frame which would need to be called every x ticks or something.
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Ok, i've fixed Generic Portal and Generic Stairway nodes so that choosing leave will not call the next node in the chain ... I've also fixed the fact that the game was displaying a message if the (labeled unused) messages fields were not set to -1.
I've also added a description of a non-documented feature for Generic Portal/Portal which is : if extra2a is set to 0 just move the party and don't play SFX, if not play SFX.
Finally, i've added a better description of the extra2b field for Generic Stairway to display the fact that there are 8 differents messages to choose from ( 0 - stairs up, 1 - stairs down, 2 - path slopes up, 3 - path slopes down, 4 - slimy stairway up, 5 - slimy stairway down, 6 - dark passage up, 7 - dark passage down.). I've also made a check that would prevent the game from locking if the extra2b value was more or equal to 8.
Okay, so if Leave is clicked the encounter now ends?

I have to decide whether to fix this now and then change it again later, or wait and change it later...
Link to comment
Share on other sites

Celtic Minstrel: I had a realization about what's likely the problem you were having with your crash in cPict::init(). The key point is that it happens before main(). (Your claim that it was 'in the STL' was a red herring, my bet is that it is emphatically not in the library code, but in yours.) My guess is that you've run square into the static initialization order fiasco. You have a number of static objects, one of which calls functions on the others. The only trouble is that it's up to the compiler to construct your static objects, and it isn't aware of any special order in which it needs to do so, so it does it in whatever order it feels like. If it decides to construct the one which make calls on the others first, or at least earlier than some of the others, you get a crash. I notice that at the moment you're using an ugly old array, which works because it needs no construction, so it's ready for use as soon as the program is in memory.

 

The easiest way to deal with this is just to replace the static object with a static pointer and static function. In order to get the object the pointer points to, the function is called, and the function knows to construct the object if it sees that the pointer is uninitialized. This FAQ entry covers the method in more detail.

Link to comment
Share on other sites

When I said it was "in the STL" I simply meant that that's where it crashed, not that the STL was the cause of the crash.

 

In fact, I was trying to do something similar to the <iostream> initialization for the basic streams (cin, cout, cerr, clog). The static object exists only so that its constructor and destructor can be called.

 

For the map (cPict::drawPict), however, I have done as you suggest. It look a little ugly though, but that's acceptable (especially since it's a private static function).

 

(I almost entertained the notion of constructing it manually with placement new, but then I realized that it would later be reconstructed, making such an exercise pointless.)

 

It works now. The istringstream problem still exists though (which is probably due to attempting to read into an invalid variable, though I can't see why the variable would be invalid)

 

 

 

It's rather late to commit tonight, so I'll probably commit all these changes sometime tomorrow afternoon. (Committing can be a lengthy operation because I run diff on most of the files in order to create an accurate log entry of what I actually changed.)

Link to comment
Share on other sites

The diff step you describe is a very valuable one since accurate logs help everyone later on. One thing that might make the process easier is that if you tell Xcode about the version control system and repository (Preferences > SCM) you can then use the SCM > Compare With > Latest command to quickly get a good picture of the changes you've made. This is what I always use before committing.

 

Which stringstream usage is it that's giving you trouble? I can take a look at it and see if I spot anything.

Link to comment
Share on other sites

Something I just noticed - the Mindduel issue isn't resolved in Beta 1, i.e. mindduels are still weighted very heavily in monsters' favor, even with rings of will. Ideally, I would say that a level 40 monster with level 7 mage spells should be roughly equal to a level 50 mage with 20 intelligence. As it is, the monster will win every time.

Link to comment
Share on other sites

I'm using a subversion GUI that I found, which I think is fairly good.

 

Originally Posted By: Niemand
Which stringstream usage is it that's giving you trouble? I can take a look at it and see if I spot anything.
In cDialog::parse<cPict>(). I can't see anything wrong, but in the debugger the pair variable is displayed twice (except, when I output it with printf it always accesses the correct one).
Link to comment
Share on other sites

There are a couple of points here, although I don;t know if either accounts for your problem: First 'sin' is a very bad name for a variable, since it will conflict with the library math function of that name should that ever end up being visible in the same scope. Second, you are initializing the stringstream with an empty string, which is pointless.

 

In fact, I don't see any real reason for you to use an explicit stringstream at all; just use the templated GetValue() to fetch the attribute's value as the type you want.

Link to comment
Share on other sites

Originally Posted By: Niemand
First 'sin' is a very bad name for a variable, since it will conflict with the library math function of that name should that ever end up being visible in the same scope.
Yeah, I recently realized this. In this case it's meant to stand for "string in", after the default cin.

Perhaps I'll change it to strin or something... though, there's probably no reason to need the sin function anyway.

Originally Posted By: Niemand
Second, you are initializing the stringstream with an empty string, which is pointless.
Uh... what about the "sin.str(val)" line?

Originally Posted By: Niemand
In fact, I don't see any real reason for you to use an explicit stringstream at all; just use the templated GetValue() to fetch the attribute's value as the type you want.
...Whoa. I must've missed that. shocked
Link to comment
Share on other sites

I mainly pointed out the possible collision with the sin function because it could conceivably have been a source of weird errors in the futures if any of the header files involved brought in cmath.

 

Originally Posted By: Celtic Minstrel
Uh... what about the "sin.str(val)" line?

I was referring to the "std::istringstream sin(val);" line, which is immediately preceded by the "std::string name, val;" line.

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
...Well, yes we can set them for already existing scenarios, when we convert them to the newer format.

That's true ... I think i've not wrote any convertion code besides checking the scenario make version, so it can't implement it right now.

Originally Posted By: Celtic Minstrel
I think it's fine – if the designer misses a place where an infinite loop could occur, you don't want to be forced to kill the program just because you forgot to (or could not, in the case of beta testers) enter debug mode. And I display a warning message when you do it, indicating that it's probably a bad idea to continue without reloading.

Ok, that's fine with me, i'll implement it. Players will take their responsabilities smile
Edit : Implemented. Just a thoughn do you check for 'C' instead of 'c' in your 'Ctrl-C' checking ?

Originally Posted By: Celtic Minstrel
Uh... "if" is not a loop, and hence break does not affect it. A break statement only affects loops (for, while, do) and switch statements.

Of course ... Given i've used that numerous times in the code, i really don't know what i was thinking ... rolleyes

Originally Posted By: Celtic Minstrel
I can't do this until the Windows version uses pngs which match those of the Mac version (currently it uses BMPs, some of which don't match).

I'll make some PNG for you (if i found all the graphics), but that not top priority for now.

Quote:
I neglected to tell you, but these were added to pixpats.png quite a while ago. I also added the ones for blue cave floor from Exile 3.

Which I did... though, didn't those ones also have a 6x6 version in the grid with all the other map squares?

I found them a while ago and implemented them. smile

Originally Posted By: Celtic Minstrel
Okay, so if Leave is clicked the encounter now ends?

Exactly.

Originally Posted By: Miramor
Something I just noticed - the Mindduel issue isn't resolved in Beta 1, i.e. mindduels are still weighted very heavily in monsters' favor, even with rings of will. Ideally, I would say that a level 40 monster with level 7 mage spells should be roughly equal to a level 50 mage with 20 intelligence. As it is, the monster will win every time.

You know what ? A level 40 monster (mage spells level doesn't intervente) is exactly equivalent to a level 50 mage with 20 intelligence and a Ring of WIll equipped. Pretty good guess, here In fact i didn't noticed a bracket, a level 40 monster is exactly equivalent to a level 100 mage with 20 intelligence and a Ring of Will equipped. (for information, max experience is 15000, so max level should be 130-150 depending of what traits you took).
To make the balance shift in your favor, cast a few dumbfounds on the monsters before engaging in mindduel.
Note that each time you win a round, the following rounds will be easier for you to win (a mindduel fight is 10 rounds).
(i've just noticed that Magically Apt. doesn't give an advantage in mindduel, maybe that should be added ?)

Chokboyz
Link to comment
Share on other sites

Couple problems with that:

- Dumbfound didn't seem to work on monsters last I checked. They could still cast spells of any level when dumbfounded. (Might be fixed though?) My bad, dumbfounding does in fact work now. It just never gets monsters to the point where they can't cast any spells.

- Levels currently are still capped at 50 AFAIK, unless there's something odd going on internally? By, ahem, "clever" use of the Character Editor and Gain Experience nodes it's possible to gain experience equivalent to 200+ levels worth, but the PCs still appear as level 50 and their spells are no more effective than those of a level 50 PC.

 

Edit: Also, one more issue (just one, I promise wink ) - walking in non-combat mode gets slow (the time delay between steps increases) when animated terrain is in view, and gets slower the more animated terrain there is in sight. This might be a problem with running in Wine though. Can anyone on Windows confirm it?

Link to comment
Share on other sites

Originally Posted By: Miramor
Dumbfound didn't seem to work on monsters last I checked. They could still cast spells of any level when dumbfounded. (Might be fixed though?)

It works on monsters. Monsters can always cast first level mage spells Spark, Minor Haste, Strengh, Flame Cloud and Flame.
And a dumbfound magic user is penalized if mindduelling (in fact, after draining spells points, the victim becomes more and more affected by dumbfound and when it reach max value (8), the victim is killed). So cast dumbfound prior to all mindduel wink

Originally Posted By: Miramor
Levels currently are still capped at 50 AFAIK, unless there's something odd going on internally? By, ahem, "clever" use of the Character Editor and Gain Experience nodes it's possible to gain experience equivalent to 200+ levels worth, but the PCs still appear as level 50 and their spells are no more effective than those of a level 50 PC.

A (really) quick check of the code only shows experience cap at 15000, but that may as well be the case smile
I'll check if i find some time.

Originally Posted By: Miramor
one more issue (just one, I promise ) - walking in non-combat mode gets slow (the time delay between steps increases) when animated terrain is in view, and gets slower the more animated terrain there is in sight. This might be a problem with running in Wine though. Can anyone on Windows confirm it?

Noticed that (happens on Windows too). I wonder if BoE doesn't originally have such slowdowns, but i'll check it.

Chokboyz
Link to comment
Share on other sites

Dumbfound only works on monsters that aren't immune to magic, and if they aren't immune to magic it's usually easier to cast Paralyze on them or Simulacrum up a basilisk and kill them that way.

 

Actually, while we're changing things around, would it be too much to ask for the ability to set monster immunity to status effects on an individual basis, rather than having magic immunity cover all of them?

Link to comment
Share on other sites

Yes, that can be done.

 

Originally Posted By: Chokboyz
Ok, that's fine with me, i'll implement it. Players will take their responsabilities smile

Edit : Implemented. Just a thoughn do you check for 'C' instead of 'c' in your 'Ctrl-C' checking ?

I check for both (toupper© == 'C'). But it doesn't work for some reason.

 

Originally Posted By: Chokboyz
Quote:
I neglected to tell you, but these were added to pixpats.png quite a while ago. I also added the ones for blue cave floor from Exile 3.

 

Which I did... though, didn't those ones also have a 6x6 version in the grid with all the other map squares?

I found them a while ago and implemented them. smile

Including the blue ones? I haven't implemented those ones...

 

Originally Posted By: Chokboyz
(i've just noticed that Magically Apt. doesn't give an advantage in mindduel, maybe that should be added ?)
No, let's leave it as it is.
Link to comment
Share on other sites

I created a new function, check_for_interrupt, which checks the keyboard and returns true if Ctrl-C or Command-period is pressed; run_special now checks this function before displaying the message and setting next_spec to -1.

 

The reason for this is that I realized that there's one other way of getting into an infinite loop: in combat. If you're fighting Gorgons for example, it's possible for them to put the whole party to sleep and then just keep them asleep indefinitely, meaning that you don't have a chance to do anything (even reload).

 

I haven't actually implemented an interrupt for combat, though, because I'm not sure what should happen when the interrupt occurs. End combat mode? Return to main menu? Also, should it only work when the entire party is asleep/paralyzed?

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
I haven't actually implemented an interrupt for combat, though, because I'm not sure what should happen when the interrupt occurs. End combat mode? Return to main menu? Also, should it only work when the entire party is asleep/paralyzed?


Well, it's also important for when the party gets webbed into immobility. May as well just make it work at any time to account for situations we haven't come up with. The least abusable option is to make it spit you straight out to the main menu.
Link to comment
Share on other sites

Originally Posted By: Miramor
FWIW the webbed-into-immobility issue seems to be fixed now, using the current beta I've yet to see anyone's AP go below 2 even when heavily webbed.


I wouldn't exactly call that "fixing" anything.

Are you sure your characters weren't wearing AP-boosting items? I think there's a limit on how many AP you can lose from webs, so if you have more than 4 base AP, you'll never be webbed so badly you can't move.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
I created a new function, check_for_interrupt, which checks the keyboard and returns true if Ctrl-C or Command-period is pressed; run_special now checks this function before displaying the message and setting next_spec to -1.

Good idea, i've implemented it (only Ctrl-C though).

Originally Posted By: Celtic Minstrel
The reason for this is that I realized that there's one other way of getting into an infinite loop: in combat.

If you're looking for potential infinite loop : if you force place a monster in a large town where all sixty monsters have life flags, then the game will hang trying to find an available slot. (i've put a max amount of occurence before breaking the loop to prevent it)

Originally Posted By: Thuryl
I think there's a limit on how many AP you can lose from webs

Indeed, you can lose 4 AP max.

Originally Posted By: Miramor
This should definitely be fixed then.

Fix being webbed into immobility ?

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
If you're looking for potential infinite loop : if you force place a monster in a large town where all sixty monsters have life flags, then the game will hang trying to find an available slot. (i've put a max amount of occurence before breaking the loop to prevent it)
No interrupt needed, just allow more than 60 monsters. I'll do that eventually.
Link to comment
Share on other sites

Progress! The dialog engine works!

 

 

 

...Well, sort of, anyway.

 

Displaying the dialog no longer causes a crash. (I discovered that it's not okay to cast a GrafPtr to a GWorldPtr. Not sure why I was doing that in the first place.) I can also dismiss the dialog by clicking (what should be) the Cancel button.

 

The trouble is, it doesn't draw properly. In fact, it draws random colours behind the text strings and also tints the background another random colour. Furthermore, there's something wrong with calculating the window's framing rectangle: it's different each time the window is loaded from the file. The window's rect is calculated by taking the maximum right and bottom of its various components, so this means that some component has the wrong right or bottom. I haven't looked into it yet; this could be a bad value in an attribute, or it could be a problem reading in the value from the attribute.

 

But still, it's progress. smile

 

EDIT: Oh, the text is also random colours, and the buttons are just black rectangles. Presumably there's a problem with the source rect/gworld for the buttons.

Link to comment
Share on other sites

Well, some of these problems are solved. I forgot to initialize some things with default values (that was the cause of the random text colours, for example). I also improved the exception throwing to account for missing required attributes (in particular the top and left of the control). Exception handling could be improved though (it just prints the error and exits).

 

Anyway, one odd thing is that sometimes it attempts to draw the dialog in the main window rather than showing a new window; I'm confused about why this happens, since it seems to be somewhat random (a rebuild without changing anything seemed to fix it... but then it happened again later).

 

Buttons and rectangle are not yet fixed.

Link to comment
Share on other sites

I've been working on investigating details of struct layout and file format for legacy data. The only difference in the layouts of our structs (on a 64 bit Intel Mac) between using and not using __attribute__ ((aligned (2))) is that the p_loc member of the current_town_type type shifts by one byte because it is preceded by a one byte member (in_boat). Obviously being off by a byte reading the two byte party location would really screw things up, so we need to get this right. In order to do so, I need an original BoE savefile with the party in a scenario, in a town, preferably with knowledge of where the party was in the town when the game was saved. I've looked at the files included with Quintessence, but their flags indicate that the party is not in a scenario, so I can't check the current town data.

 

One alteration that I have made which should prevent things from shifting around in future is that I've replaced all usage of short int and long int with int16_t and int32_t, respectively. This matches the sizes they were already, and should just ensure that the code will work the same on any platform, so matter how weird, as long as there's a conforming compiler.

Link to comment
Share on other sites

Niemand, town location in a BoE save file:

Town location, when in town mode and only when in town mode, town number seems to be found at: 98,909 and x,y coordinates at 98,914 and 98,915. Town number also occurs at place 82,902. This can be verified by the spell Location, when the relevant save file is played.

See the topic,

http://www.ironycentral.com/forum/ubbthreads.php?ubb=showflat&Number=27554#Post27554

Link to comment
Share on other sites

@Celtic Minstrel: A Windows save should suffice, and it has already proven itself useful. More on that in a moment.

@Ishad Nha: You're correct about the global location of the data in the file, which is useful to me as an independent check, but I need to determine the location within the data structure.

 

Returning to the usefulness of the Windows save: The issue may not be limited to Windows savefiles, but I've already uncovered glaring problems. That is, unless ADoS has renamed his scenario to be all non-printing characters and had his party in a boat. All of the data structures are being read a few thousand bytes away from where they should be, and the data is being totally scrambled. This means I have a lot more work to do then I'd intended, but there must be at least one serious bug that I'm grappling with.

Link to comment
Share on other sites

Here it is, party location in terms of data structures:

struct current_town_type

 

82,902 2 short town_num

82,904 2 short difficulty;

82,906 3,506 town_record_type town;

86,412 4,096 char explored[64][64];

90,508 1 Boolean hostile;

90,509 8,400 creature_data_type dudes[60];

98,909 2 short which_town;

98,911 2 short friendly;

98,913 1 Boolean in_boat;

98,914 2 location p_loc;

total size: 98,916

 

Party location parts are:

82,902 2 short town_num

98,909 2 short which_town;

98,914 2 location p_loc;

 

It uses my normal format of

start:length in bytes:data type:description

 

Read the topic I mentioned if you want to see where struct current_town_type fits into the save file as a whole.

 

 

Link to comment
Share on other sites

Originally Posted By: Niemand
That is, unless ADoS has renamed his scenario to be all non-printing characters and had his party in a boat

Nope, the scenario name is valleydy.exs beginning at byte 45658 for the previous savefile. (party and pcs data need decryption but i'm sure you already knows that wink )
And the party is not in a boat.

Originally Posted By: Celtic Minstrel
Well, the Mac and Windows files are different; it may be just a byte order difference, but I'm not sure.

There's indeed the endianess difference (at last between PPC and Intel/AMD architecture), but there's also some difference in the reading process (2 byte skipped right before the party.total_m_killed long variable, when reading Mac PPC file on Windows).
After reading the party structure, the loading procedure is more or less the same for the two versions. smile

Chokboyz
Link to comment
Share on other sites

Exactly, so all of this indicates that something is going drastically wrong. I haven't yet been able to make much more progress; I've verified that the current and original data structures are at least very nearly the same sizes, so I can't yet account for why reading is so far off from where it should be.

Link to comment
Share on other sites

Trivial things :

 

in the function create_out_combat_terrain(), the cave bridge battlefield is never created (a basic cave floor battlefield is used instead) because the check

Click to reveal..
if (ter_type > 260)

ter_type = 1;

else ter_type = general_types[ter_type];

should be something like :

Click to reveal..
if(ter_type == 401 || ter_type == 402)

ter_type = 4;

else

if (ter_type > 260)

ter_type = 1;

else ter_type = general_types[ter_type];

Also, in the general_types[] array, the index 80 should be 11 and the indexes 215 and 216 are flipped (should be 1 and 0).

The ter_base[] and ground_type[] arrays are the same, so one should be deleted.

 

The wall trims are now working in Classic BoE (for the difference that makes wink ).

 

Chokboyz

Link to comment
Share on other sites

Originally Posted By: Miramor
Also, one more issue (just one, I promise ) - walking in non-combat mode gets slow (the time delay between steps increases) when animated terrain is in view, and gets slower the more animated terrain there is in sight.

I think i've located and fixed the problem : the slowdown appeared with the drawing of trims on animated water and walls, because the trims.bmp was loaded each time the draw_trim() function was called. The trims.bmp is now loaded in memory when the game is launched (forgot to do that when i loaded the main graphical sheets in memory).
I've not experienced slowdown since, but i'll keep an eye open (note that trim drawing was buggy, and that slowdown may appeared even if no walls or (animated) water is in sight. If that happens, suppress frills/shore frills in the Preferences menu and the game should run at full speed. If not, feel free to post about it.)

Chokboyz

Edit : Some code cleaning.
Cleaned unused variables : cartoon_happening was always FALSE and store_anim and store_anim_ul were never set or even initialized (despite being used crazy).

Board Triviality : the link to TrueSite still needs to be updated. I remember stumbling upon dead scenario download links, but that seems to be fixed the last two scenarios under the "Alcritas - ARC Series" section are giving 404 errors. Last, "Johnny favourite" scenario is misaligned.
A link to the repository (or at least the download page) is an idea to ponder (and since Celtic Minstrel's name has gone blue) wink

Last Edit : the game now recursively looks for scenarios in "scenarios/" subfolders; that should make the scenario folder less crowded.
Finally, the limit of maximum listed scenario is now gone (thanks to dynamic allocation).
I'll probably release Classic BoE Beta 2 this week-end (provided i encounter no bugs), unless someone has a bug to report or something ... wink
Link to comment
Share on other sites

By the way, I'd prefer if you make a new post rather than editing a post made a day or two earlier. Otherwise I'm likely to miss it.

 

Originally Posted By: Chokboyz
Edit : Some code cleaning.

Cleaned unused variables : cartoon_happening was always FALSE and store_anim and store_anim_ul were never set or even initialized (despite being used crazy).

These were used for the menu animation and the intro animation in Exile 3, I think. I don't think they'll be needed. We will do cutscenes, but probably in a different way; and a menu animation would not make sense.

 

Originally Posted By: Chokboyz
Board Triviality : the link to TrueSite still needs to be updated. I remember stumbling upon dead scenario download links, but that seems to be fixed the last two scenarios under the "Alcritas - ARC Series" section are giving 404 errors. Last, "Johnny favourite" scenario is misaligned.

A link to the repository (or at least the download page) is an idea to ponder (and since Celtic Minstrel's name has gone blue) wink

I've considered it; I heard that editing that can sometimes cause problems, but I'd be willing to try anyway. I'd need the corrections for the borken links, though.

 

Originally Posted By: Chokboyz
Last Edit : the game now recursively looks for scenarios in "scenarios/" subfolders; that should make the scenario folder less crowded.
Hm, not a bad idea. I actually have no idea whether my code does that. Probably not.

 

Originally Posted By: Chokboyz
Finally, the limit of maximum listed scenario is now gone (thanks to dynamic allocation).
How did you do this? Did you use malloc(), realloc() and free(), new[] and delete[], or a vector which will do all the work for you? I used a vector (though there's something fishy going on – somehow the relevant variable is not at the same address in both files where it is referenced? smirk )
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
By the way, I'd prefer if you make a new post rather than editing a post made a day or two earlier. Otherwise I'm likely to miss it.

Ok, i'll will smile

Originally Posted By: Celtic Minstrel
These were used for the menu animation and the intro animation in Exile 3, I think. I don't think they'll be needed. We will do cutscenes, but probably in a different way; and a menu animation would not make sense.

Coming to the same conclusion, I've deleted those without any problem.

Originally Posted By: Celtic Minstrel
Hm, not a bad idea. I actually have no idea whether my code does that. Probably not.

Not founding a native WIN32API function that does so, i've wrote the code so that it scan "scenarios/" and its subfolders for "*.exs" files, populating a listbox with its founding. The rest of the loading procedure is unchanged (except the dynamic allocation thing).
Tested and working with about 44 scenarios and 2 level subfolders.

Originally Posted By: Celtic Minstrel
How did you do this? Did you use malloc(), realloc() and free(), new[] and delete[], or a vector which will do all the work for you? I used a vector (though there's something fishy going on – somehow the relevant variable is not at the same address in both files where it is referenced? )

I refrained from using malloc(), realloc() and free() C functions, but used new[] and delete[]. Basically, each time the scen_headers are build, the game alloc the necessary memory for data_store2 and scen_headers.
The memory is freed (delete[]) each time a new allocation needs to be done (i.e each time the scen_headers are build and memory was previously allocated) and on program shutdown.

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