Jump to content

Terrain type stuff


Celtic Minstrel

Recommended Posts

Next on the reformatting list is Terrain Types. Don't suggest new special terrain abilities here, since adding those would not affect the terrain format. They can be suggested elsewhere.

 

So far, I've tried to create fields to specify the various special properties that the predefined terrains have. Fields I've added so far (some are for editor use):

  • Ground type (uncertain about this one; it specifies the base terrain or wall of a given terrain. For example, anything on stone floor would have the same ground type.)
  • Trim terrain (for terrain types that are trims, this specifies the type it borders. For example, for the cave wall trims, it would be the ground type of cave floor.)
  • Trim type (what sort of trim this terrain is/requires)
  • Object num (for automatic placement of object that take up multiple terrain spaces; currently the only examples are the 2-space rubbles. The cave rubble, for example, would both require the same object num.)
  • Object pos (probably inefficient; specifies where this terrain type goes in relation to the the top left terrain of the object.)
  • Combat arena (this is the only one that I'm definitely going to keep – I'll also make 1000 + town num cause the engine to load a town for the arena)

 

These aren't set in stone. Although I've added the fields to the structure already, I can always un-add them. If you can think of a better way to do any of these, or think that any of them are unnecessary, say so (and prefereably why).

 

Click to reveal.. (New Properties for the first 90 terrains)

Code:
                                Ground  Trim    Trim    Combat  Object  ObjectNum Name                        type    terrain type    arena   num     pos0   Cave Floor  (plain)         0       0       0       1       0       0,01   Cave Floor  (w/ frill)      0       0       0       1       0       0,02   Grass       (plain)         1       0       0       0       0       0,03   Grass       (w/ frill)      1       0       0       0       0       0,04   Grass       (w/ flowers)    1       0       0       0       0       0,05   Cave Wall   (plain)         2       0       0       0       0       0,06   Cave Wall   (south)         2       0       2       1       0       0,07   Cave Wall   (south secret)  2       0       2       1       0       0,08   Cave Wall   (southeast)     2       0       3       1       0       0,09   Cave Wall   (east)          2       0       4       1       0       0,010  Cave Wall   (east secret)   2       0       4       1       0       0,011  Cave Wall   (northeast)     2       0       5       1       0       0,012  Cave Wall   (north)         2       0       6       1       0       0,013  Cave Wall   (north secret)  2       0       6       1       0       0,014  Cave Wall   (northwest)     2       0       7       1       0       0,015  Cave Wall   (west)          2       0       8       1       0       0,016  Cave Wall   (west secret)   2       0       8       1       0       0,017  Cave Wall   (southwest)     2       0       9       1       0       0,018  Cave Wall   (ne inner)      2       0       10      1       0       0,019  Cave Wall   (se inner)      2       0       11      1       0       0,020  Cave Wall   (sw inner)      2       0       12      1       0       0,021  Cave Wall   (nw inner)      2       0       13      1       0       0,022  Mountains   (plain)         3       0       0       2       0       0,023  High Mountains              3       0       0       2       0       0,024  Mountains   (south)         3       2       2       2       0       0,025  Mountains   (southeast)     3       2       3       2       0       0,026  Mountains   (east)          3       2       4       2       0       0,027  Mountains   (northeast)     3       2       5       2       0       0,028  Mountains   (north)         3       2       6       2       0       0,029  Mountains   (northwest)     3       2       7       2       0       0,030  Mountains   (west)          3       2       8       2       0       0,031  Mountains   (southwest)     3       2       9       2       0       0,032  Mountains   (ne inner)      3       2       10      2       0       0,033  Mountains   (se inner)      3       2       11      2       0       0,034  Mountains   (sw inner)      3       2       12      2       0       0,035  Mountains   (nw inner)      3       2       13      2       0       0,036  Hills       (plain)         4       0       0       2       0       0,037  Hills       (w/ rocks)      4       0       0       2       0       0,038  Hills       (south)         4       1       2       2       0       0,039  Hills       (southeast)     4       1       3       2       0       0,040  Hills       (east)          4       1       4       2       0       0,041  Hills       (northeast)     4       1       5       2       0       0,042  Hills       (north)         4       1       6       2       0       0,043  Hills       (northwest)     4       1       7       2       0       0,044  Hills       (west)          4       1       8       2       0       0,045  Hills       (southwest)     4       1       9       2       0       0,046  Hills       (ne inner)      4       1       10      2       0       0,047  Hills       (se inner)      4       1       11      2       0       0,048  Hills       (sw inner)      4       1       12      2       0       0,049  Hills       (nw inner)      4       1       13      2       0       0,050  Water       (plain)         5       0       0       0       0       0,051  Water       (south)         5       1       2       0       0       0,052  Water       (southeast)     5       1       3       0       0       0,053  Water       (east)          5       1       4       0       0       0,054  Water       (northeast)     5       1       5       0       0       0,055  Water       (north)         5       1       6       0       0       0,056  Water       (northwest)     5       1       7       0       0       0,057  Water       (west)          5       1       8       0       0       0,058  Water       (southwest)     5       1       9       0       0       0,059  Water       (ne inner)      5       1       10      0       0       0,060  Water       (se inner)      5       1       11      0       0       0,061  Water       (sw inner)      5       1       12      0       0       0,062  Water       (nw inner)      5       1       13      0       0       0,063  Small Island                5       0       0       0       0       0,064  Rock                        5       0       0       0       0       0,065  Bridge      (west)          5       1       8       3       0       0,066  Bridge      (horizontal)    5       0       0       3       0       0,067  Bridge      (east)          5       1       4       3       0       0,068  Bridge      (north)         5       1       6       3       0       0,069  Bridge      (vertical)      5       0       0       3       0       0,070  Bridge      (south)         5       1       2       3       0       0,071  Water                       6       0       14      1       0       0,072  Bridge      (vertical)      6       0       14      4       0       0,073  Bridge      (horizontal)    6       0       14      4       0       0,074  Rock                        6       0       14      0       0       0,075  Lava                        7       0       14      1       0       0,076  Lava        (no damage)     7       0       14      1       0       0,077  Waterfall                   6       2       17      1       0       0,078  Portal                      0       0       0       1       0       0,079  Road        (cave)          0       0       15      14      0       0,0 80  Road        (grass)         1       0       15      15      0       0,081  Road        (hills)         4       0       15      16      0       0,082  Walkway     (cave)          8       0       16      1       0       0,083  Walkway     (grass)         8       0       16      1       0       0,084  Rubble      (cave single)   0       0       0       1       0       0,085  Rubble      (cave left)     0       0       0       1       1       0,086  Rubble      (cave right)    0       0       0       1       1       1,087  Rubble      (grass single)  1       0       0       0       0       0,088  Rubble      (grass left)    1       0       0       0       2       0,089  Rubble      (grass right)   1       0       0       0       2       1,090  Pit                         9       0       14      1       0       0,0

 

Click to reveal.. (Explanation of my Trim Type values)

These can be up for debate.

  1. not a trim, but trims will conform to it as if it's the same ground type (eg stone wall)
  2. south edge
  3. southeast corner
  4. east edge
  5. northeast corner
  6. north edge
  7. northwest corner
  8. west edge
  9. southwest corner
  10. northeast inner corner
  11. southeast inner corner
  12. southwest inner corner
  13. northwest inner corner
  14. small frills (like on lava and underground water; no trim_ter required)
  15. road (the game will treat it like a road space and draw roads; to trim_ter required)
  16. walkway (the game will draw walkway corners; no trim_ter required)
  17. waterfall (special case for waterfalls)

 

Click to reveal.. (List of Combat Arenas)

Arenas currently used by the game:

Code:
 0 - grassy field 1 - ordinary cave 2 - mountain 3 - surface bridge 4 - cave bridge 5 - rubble-strewn cave 6 - cave tree forest 7 - cave mushrooms 8 - cave swamp 9 - surface rocks10 - surface swamp11 - surface woods12 - shrubbery13 - stalagmites

The arena is chosen based on the terrain type. If the terrain type is >= 260, then arena 1 is used.

 

Arenas I've thought about adding:

Code:
14 - cave road15 - surface road16 - crops17 - cave fumarole18 - surface fumarole1000 + x - town x minus any preset creatures
Link to comment
Share on other sites

Okay, no-one seems to have any objections to anything, so I'll move on to terrain special properties. There are 24 currently available properties (including 0 - No Property), and two fields for additional information about these properties. Additional suggestions are very welcome.

 

Click to reveal.. (Current and proposed properties)

In parentheses after each are the additional parameters. Blue text indicates proposals.

  1. Change when step on (What to change to, number of sound)
  2. Does fire damage (Amount of damage done, multiplier)
  3. Does cold damage (Amount of damage done, multiplier)
  4. Does magic damage (Amount of damage done, multiplier)
  5. Poison land (Strength, Percentage chance)
  6. Diseased land (Strength, Percentage chance)
  7. Crumbling terrain (Terrain to change to, Unused - could be strength?)
  8. Lockable terrain (Terrain to change to when locked, Unused)
  9. Unlockable terrain (Terrain to change to when locked, Difficulty)
  10. Unlockable, bashable terrain (Terrain to change to when locked, Difficulty)
  11. Sign (Unused, Unused)
  12. Call local special (Special to call, Unused)
  13. Call scenario special (Special to call, Unused)
  14. Container (Unused, Unused)
  15. Waterfall South (Unused, Unused)
  16. Conveyor North (Unused, Unused)
  17. Conveyor East (Unused, Unused)
  18. Conveyor South (Unused, Unused)
  19. Conveyor West (Unused, Unused)
  20. Blocked to Monsters (Unused, Unused)
  21. Town entrance (Terrain type if hidden, Unused)
  22. Change when Used (Terrain to change to when used, Number of sound)
  23. Call scenario special when used (Special to call, Unused)
  24. Bridge - if the party boats over it, they get the option to land.
  25. Waterfall North
  26. Waterfall East
  27. Waterfall West
  28. Call local special when used
  29. Dangerous terrain - can't rest here
  30. Destroyed by quickfire
  31. Acidic land
  32. Damaging terrain (does weapon damage)
  33. Cursed land - has a chance of cursing you
  34. Blessed land - has a chance of blessing you (could be merged with above one since bless and curse are two sides of the same coin)
  35. Soporific land - has a chance of putting you to sleep

 

Why bridge? Because currently if I'm not mistaken, boating over lava will give the "Pilot under or land?" message every move. (The message is given if the terrain both is not blocked and can be boated over.) It could also be implemented as a new blockage type, though...

 

I'd actually like to merge 16 through 19 (the conveyors) into a single property (and use the extra field to specify direction), but I'm not sure there's any point to that. 12 and 13 could also be merged in a similar way.

 

Note that sound number 200 is "no sound". This is an unsatisfactory state of affairs, but there's not a lot we can do about it since the field is unsigned. So when the ability to add custom sounds is enabled, the custom sounds will start at 201 (and 200 will be skipped).

 

Oh, and I'm adding a field to the terrain type class to hold its name. No sense storing the terrain names in a separate array in the scenario record, is there?

 

Another field I'm considering adding is "special icon", which is only used by the editor. It would let you specify an extra little icon to display on the terrain in addition to any others that may be displayed there.

 

Speaking of which... does anyone know what all the icons are? Especially the unused ones. (They may all be seen here.)

 

Click to reveal.. (Used icons + my guesses for unused ones)

Water, Impassable, Grass, Cave, ???, ???, ???, Special space, Bridge, ???

???, ???, Wandering arrival point, ???, ???, ???, Conveyor south, Conveyor west, Conveyor north, Conveyor east

East town entry, Blocked to monsters, Out town entry, Secret passage/Change when step, ???, Blank, Sign, South town entry, West town entry, North town entry

Unlockable, Magic Unlockable, Impassable Unlockable, Disease land, Crumbling, Poison land, Container, Fiery land, Cold land, Zappy land

Any suggestions for new icons, or for how to use the unused ones? Not that they all need to be used, of course.

 

Random comment: Did you know you can push crates and barrels without moving, by using them?

Link to comment
Share on other sites

Well, currently the status inducing terrain types and the damaging terrain types, of which there are two and three respectively, use both the extra fields. If a third extra field was added, then yes, what you suggest would be possible.

 

 

So maybe I should also add another extra field, and then merge 2 through 4 and also merge 5 and 6. Also maybe 9 and 10. In that case, if all my proposed merges took place, the special properties list would look something like this:

 

Click to reveal..

  1. Change when step on (What to change to, number of sound, Unused)
  2. Damaging terrain; can't rest here (Amount of damage done, multiplier, damage type)
  3. Reserved
  4. Reserved
  5. Dangerous land; can't rest here; percentage chance may be 0 (Strength, Percentage chance, status type)
  6. Reserved
  7. Crumbling terrain (Terrain to change to, strength?, destroyed by what - quickfire, shatter/move mountains, or both)
  8. Lockable terrain (Terrain to change to when locked, Unused, Unused)
  9. Unlockable terrain (Terrain to change to when locked, Difficulty, can be bashed)
  10. Reserved
  11. Sign (Unused, Unused, Unused)
  12. Call special (Special to call, local or scenario?, Unused)
  13. Reserved
  14. Container (Unused, Unused, Unused)
  15. Waterfall (Direction, Unused, Unused)
  16. Conveyor Belt (Direction, Unused, Unused)
  17. Reserved
  18. Reserved
  19. Reserved
  20. Blocked to Monsters (Unused, Unused, Unused)
  21. Town entrance (Terrain type if hidden, Unused, Unused)
  22. Change when Used (Terrain to change to when used, Number of sound, Unused)
  23. Call special when used (Special to call, local or scenario?, Unused)
  24. Bridge - if the party boats over it, they get the option to land. (Unused, Unused, Unused)

 

Except that Bridge could be slotted into one of the now-reserved places – unless it's implemented as a blockage type instead.

Link to comment
Share on other sites

Any ideas what the W in row 1, the E in row 2, or the C in row 3 may be intended for? Or those three in row 1 between the C and the S? What about the one next to START?

 

If we have no idea what they're used for, and we need more small icons for any reason, one way is to replace on of the existing ones. I'd say those three on row 1 between C and S are prime candidates for replacing, as well as the blank one.

 

Alternatively, if we need more icons we can leave these as is and add an additional row of icons.

Link to comment
Share on other sites

Ohhhhh.... then the two just before START are probably meant to be bones and ash! I can't see one that could be quickfire, but it could have been replaced because he no longer needs it - unless the E makes sense for it, which to me it doesn't really. As for crate, either it was also replaced, or it was the C in the third row. And I'm guessing the W means water, though that doesn't explain why it's not used anywhere. Or it could mean wall. I dunno...

 

I think I'll take the bones icon and re-use it to mean bridge – it fits, certainly.

Link to comment
Share on other sites

I have implemented most of these changes to the terrain types. While all the changes involve terrain types only, it has affected many aspects of the code; hence, it will be its own revision.

 

One thing I noticed while doing this is that the Call Local Special terrain ability appears to call a town special even if outdoors! (Look in check_special_terrain(), switch(ter_special), case 12. Then look at run_special() for the meaning of the 2 in the second parameter.) This is now presumably fixed.

 

Another thing is that in place_trim it checks for terrain type 86, where it should be 90 (to judge by the comment).

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
One thing I noticed while doing this is that the Call Local Special terrain ability appears to call a town special even if outdoors! (Look in check_special_terrain(), switch(ter_special), case 12. Then look at run_special() for the meaning of the 2 in the second parameter.)

Nice one, that is now corrected and tested (I used which_combat_type to check whether a combat was happening outdoor or in town)

Originally Posted By: Celtic Minstrel
Another thing is that in place_trim it checks for terrain type 86, where it should be 90 (to judge by the comment).

Corrected (it only happens outside though, so is the check really useful ? confused)

Thanks,
Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
One thing I noticed while doing this is that the Call Local Special terrain ability appears to call a town special even if outdoors! (Look in check_special_terrain(), switch(ter_special), case 12. Then look at run_special() for the meaning of the 2 in the second parameter.)

Nice one, that is now corrected and tested (I used which_combat_type to check whether a combat was happening outdoor or in town)
What if you step on the terrain while walking outdoors? That's the change I made. I didn't make it call an outdoor node if you're in outdoor combat, though that's a good idea. And I also made another change there which is related to the whole rearranging of the terrain special properties.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
Another thing is that in place_trim it checks for terrain type 86, where it should be 90 (to judge by the comment).

Corrected (it only happens outside though, so is the check really useful ? confused)
What only happens outside? As far as I can tell, the check is intended to prevent frills from appearing at the edge of the outdoor combat terrain. I didn't actually check to see if the frills appeared there before the change, though.
Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
What if you step on the terrain while walking outdoors? That's the change I made. I didn't make it call an outdoor node if you're in outdoor combat, though that's a good idea. And I also made another change there which is related to the whole rearranging of the terrain special properties.

I've changed the case so that :
  • if in town or town_combat, the local special called is taken in the town specials list
  • if outdoor or outdoor_combat, the local special called is taken in the outdoor specials list
The only variables I check are mode (0 = outdoor,1 = in town or 2 = in combat) and which_combat_type (0 = outdoor 1 = in town).

Originally Posted By: Celtic Minstrel
What only happens outside? As far as I can tell, the check is intended to prevent frills from appearing at the edge of the outdoor combat terrain. I didn't actually check to see if the frills appeared there before the change, though.

Making pits appear in outdoor combat is quite hard, but changing the value of which_combat_type, i've been able to test it in town (and the frills are indeed not drawn in combat).
But is that useful ? Why would frills not be drawn while in combat ?
Nevertheless, that's some pretty trivials (graphicals) questions, and can be left alone without a problem ...

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
But is that useful ? Why would frills not be drawn while in combat ?


You know how you run off the edge of the map into blackness when you want to flee from an outdoor combat? That's the edge he's talking about. We don't want frills on that edge.
Link to comment
Share on other sites

Originally Posted By: Thuryl
You know how you run off the edge of the map into blackness when you want to flee from an outdoor combat? That's the edge he's talking about. We don't want frills on that edge.

Ok, that makes sense smile
Except that the check was indeed wrong (the checked terrain was the "right part of the two-squares long rock on white cave floor" terrain instead of the pit), so the frills were always drawn before ... But that's fixed now wink

Thanks,
Chokboyz
Link to comment
Share on other sites

Actually, we should probably change it so that the barrier at the edge of combat is not the same terrain as the pit, because if we're allowing towns to be used as combat arenas there's a distinct possibility for pits to appear in the actual arena. I would suggest making it terrain number 65535.

 

Speaking of combat arenas, it would appear that they are 26x26 spaces. (Confirmation, maybe?) In order to use towns as arenas, we would most likely want to do one of two things: either cut off 3 spaces from each side when loading the town terrain for the arena, or add 3 spaces on each side to the pre-existing arenas. Any comments?

 

Alternatively, we could just have two separate sizes of arena; but that would be more work, I think.

 

Originally Posted By: Chokboyz
The only variables I check are mode (0 = outdoor,1 = in town or 2 = in combat) and which_combat_type (0 = outdoor 1 = in town).
Hm... I actually used is_town() and is_out() instead of mode... I should think about whether to change that...
Link to comment
Share on other sites

I just had an idea about how to draw the frills that appear on lava, dark water, etc. (And the code seems to imply the also appear on walls? smirk I need to confirm this...) Instead of having a set of trims for each of the three main terrain types, we can have a single set in monochrome, to use as a mask. The mask can then be applied to the full terrain graphic of the adjacent terrain to get the desired result. I think it would be easiest to do this if the left and right halves were moved further apart, so that each frill is a full 28 by 36 pixels rather than half of that in one or both dimensions.

 

The advantage of this is that is will work for any type of terrain, with no extra work. It would have to correct for if the adjacent terrain is a wall, though... that might be difficult...

Link to comment
Share on other sites

Funny that you speaks about trims (or frills), since i've just finished adapting the code to use your FRILLS.bmp and display grass trims ... I just need to make a Windows version of the trims and it will be ok grin

What i did was simply to read the bmp from the FRILLS files (instead of the MIXED file) and adapt the draw_trim() function to take into account what terrains are adjacent (it's far from perfect though, only the global terrain, i.e cave or grass, is checked ...).

 

Originally Posted By: Celtic Minstrel
And the code seems to imply the also appear on walls? I need to confirm this...

Yup, it is supposed to smoothen corners of the walls (but the checking range seems odd and i don't see that much of a difference between trims and no trims ... So i don't know if it actually works for walls).

 

The mask idea is pretty good, but doesn't looks easy to implement ... (and yes, we should make each frill full 28 by 36 pixels, it will make it easier)

 

Originally Posted By: Celtic Minstrel
It would have to correct for if the adjacent terrain is a wall, though... that might be difficult...

If i'm not mistaken, there is a check somewhere in the (place_trim() maybe ...) that check if the square is a wall (isWall() ?), so that could be already implemented ...

 

Hope it helps,

Chokboyz

Link to comment
Share on other sites

I don't know about the Windows API, but with Quickdraw I can simply specify the mask when copying using CopyBits (or perhaps by used a separate, related command – I don't remember). So the masking would not be hard for me. What may be difficult is determining when to draw the frills, and also what graphic to mask for them.

 

 

 

No comments on the combat arena thing from the post before that?

Link to comment
Share on other sites

Originally Posted By: Celtic Minstrel
I don't know about the Windows API, but with Quickdraw I can simply specify the mask when copying using CopyBits (or perhaps by used a separate, related command – I don't remember). So the masking would not be hard for me. What may be difficult is determining when to draw the frills, and also what graphic to mask for them.

I found that you can specify the mask in Win32 API as well, so that part is ok. I suppose we need to draw the trims when the terrain is liquid or a pit (using the adjacent terrain textures, and if the adjacent square is a wall the default terrain ...), but that's only a (rather simple) idea ...

Originally Posted By: Celtic Minstrel
No comments on the combat arena thing from the post before that?

What do you means by combat arena ? If it's the terrain that is drawn when entering outdoor combat, cutting off 3 squares from the town seems better (after all, it's those unreachable three spaces that makes you leave town, am I mistaken ?).
And yes, terrains with number different then pits will need to be used as darkness to avoid glitches (whatever fixed number will be fine) ...

Chokboyz
Link to comment
Share on other sites

Originally Posted By: Chokboyz
I suppose we need to draw the trims when the terrain is liquid or a pit (using the adjacent terrain textures, and if the adjacent square is a wall use the default terrain ...), but that's only a (rather simple) idea ...
That would be fine, yes. It's not perfect, but it'll do.

Originally Posted By: Chokboyz
Originally Posted By: Celtic Minstrel
No comments on the combat arena thing from the post before that?

What do you means by combat arena ? If it's the terrain that is drawn when entering outdoor combat, cutting off 3 squares from the town seems better (after all, it's those unreachable three spaces that makes you leave town, am I mistaken ?).
Yes, that's what I mean, and yes, those 3 squares would be inaccessible in most towns anyway (though you can make at least two of them accessible).

I guess I'll do the truncated way, then.
Link to comment
Share on other sites

Okay. Walkways are now smoothed correctly. They actually were already – you just couldn't see it because the underlying terrain was walkway rather than grass. The way I've re-implemented the walkways means that a given walkway terrain will conform to one and only one ground type (eg grass, cave floor); however, you'll be able to make a walkway terrain conform to any ground type you wish, including custom types. It still works by replacing an existing walkway tile, rather than filling in corners between walkway tile (as I believe BoA does), so painting walkways will work just as before.

 

I have also just about finished getting the roads to connect properly. (Most of my problems were simple errors, too.) However, there's a major difference in how it handles roads crossing a transition from grass to hill. This means it will cross custom transitions just as well, but at the cost of slightly uglifying existing scenarios. Before, you would place a Road Hill terrain on the edge, and it would automatically be replaced with the proper edge transition. Now, however, you place the edge trim, creating a gap in the road, and this gap is automatically filled in.

 

It would be possible when converting scenarios to look for instances of roads crossing the transition, but I'm wondering if it's worth it? Technically, it's something that "breaks" earlier scenarios in the sense that they don't behave as they did before; however, it's a purely aesthetic break, so it won't affect gameplay.

Link to comment
Share on other sites

Quote:
It still works by replacing an existing walkway tile, rather than filling in corners between walkway tile (as I believe BoA does)

In case it's of any importance, BoA does not smooth walkways automatically (in part because in BoA they are terrain, rather than floors), it has to be done manually. For floors which are smoothed it works in what I think is the same way that you describe, replacing the just drawn floors so that they match the preexisting ones/
Link to comment
Share on other sites

The difference with walkways is that the replacement is done while playing the game, not in the editor.

 

I've gotten special spots to work now: they show up where they should and disappear when their SDF is set to 250 and they're a one-shot. (Apparently they also sometime appear where they shouldn't though... but that's less important.)

 

My current to-do list for terrain...

  • crash when attempting to draw a field (EXC_BAD_ACCESS while calling either LockPixels or CopyBits)
  • conveyors don't work outdoors
  • lava damages you even when you're in a boat
  • frills not drawn properly (actually, not drawn at all)
  • north, west, and east waterfalls not implemented
  • stepping on damaging terrain causes a crash
  • call special when stepped on/used doesn't work
  • can't use terrains with "call on use" ability
Link to comment
Share on other sites

Well, I implemented the code to draw frills using masking, and also changed the walkway code to use masking, but I can't test it because the STL is crashing for (as far as I can see) no reason at all. (It's just like the unexplainable crash I got when trying to implement saving. Unless STL containers for some reason can't be declared as a global container used across multiple files, I have no idea what could cause it.)

 

I got rid of the two variables to store strim (out_trim and town_trim) and now determine which trim to draw on the fly. Theoretically, this should mean that when changing terrain, the trim will automatically update if necessary.

 

(By the way, the linker is giving me warnings about some things – string, char_traits, length_error – having different visibility in two places. Could that be the culprit? And how could I squash those warnings?)

Link to comment
Share on other sites

Considering how much scrutiny the STL implementation has undergone I would argue that it's almost certainly the usage that's causing the crash, not a flaw in the library. However, I can't really say much more without seeing the code.

 

Likewise, if you're getting a bunch of warnings it would be good to heed them; unfortunately I again can't say much in specific given I don't think I've ever encountered warning like what you describe, and I don't know any of the details of your situation.

 

Can you post a representative potion of the code? (If not, I'd be happy to borrow a copy of the entire thing and take a stab at figuring out what the issue is.)

Link to comment
Share on other sites

I could post part of the code, but I think you'd have to conclude that there's no obvious error. And you can't borrow it 'til I commit, which I'll do now.

 

For reference, this is the line that caused the crash in pick_a_scen():

Code:
sprintf((char *) place_str,    "%s v%d.%d.%d - |  Difficulty: %s, Rating: %s |%s |%s",    scen_header_strs[store_scen_page_on * 3 + i][0].c_str(),    (short) scen_headers[store_scen_page_on * 3 + i].ver[0],    (short) scen_headers[store_scen_page_on * 3 + i].ver[1],    (short) scen_headers[store_scen_page_on * 3 + i].ver[2],    difficulty[scen_headers[store_scen_page_on * 3 + i].difficulty],    ratings[scen_headers[store_scen_page_on * 3 + i].default_ground],    scen_header_strs[store_scen_page_on * 3 + i][1].c_str(),    scen_header_strs[store_scen_page_on * 3 + i][2].c_str());

Since scen_header_strs was a vector of pointers to string, I thought this might be because for some reason one of those pointers was invalid. So I changed it to use a structure containing three strings... and it still crashed. The stack display said the crash occurred in string::c_str(), but the pointer showing the current line was in char_traits<char>::length() – maybe that means it was inlined? I dunno... anyway it was most likely the call to strlen, but I don't understand why. It may also be worth mentioning that I actually examined the scen_header_strs variable and found it to have more than 10 members (even though it had only 2 when I examined it just after it was populated) and all the members only blank strings. It was populated in boe.fileio.cpp, but accessed in boe.dlgutil.cpp, so I wondered whether there might be some inconsistency between the declarations in the two files, but there wasn't. (Besides, wouldn't that have caused a link error if there was?)

 

Then I changed it to use ostringstream instead of sprintf, and ran into the exact same barrier I ran into earlier with the save function – operator<< crashes for no apparent reason.

 

 

Oh, the code that populated the vector:

Code:
scen_header_str_type scen_strs;scen_strs.name = scenario.scen_name;scen_strs.who1 = scenario.who_wrote[0];scen_strs.who2 = scenario.who_wrote[1];p2cstr(spec.name);string curScenarioName((char*)spec.name);c2pstr((char*)spec.name);scen_strs.file = curScenarioName;// other stuff herescen_header_strs.push_back(scen_strs);
Obviously this is after changing to use a structure instead of an array, so this code snippet is more recent than the above code snippet.

 

It may be more useful to check out a (read-only) copy, though. I've just committed the latest changes to the repository, if you want to do that.

Link to comment
Share on other sites

Okay, I've checked out a copy. I guess I should have been more clear: I hadn't meant to make you check in code you weren't done with; you could have just sent me a copy of the files from your working copy.

 

At any rate, I'll be looking at it. Also, "Warnings about some things"? There are more than 600 of them!

Link to comment
Share on other sites

Originally Posted By: Niemand
Also, "Warnings about some things"? There are more than 600 of them!
Yeah, most of them are about unused variables though. Plus they're compiler warnings. The ones I was talking about were linker warnings, which is unusual.

(Though, some of those compiler warnings should probably be errors – "non-POD type passed via varargs" and "control reaches end of non-void function" have been annoying warnings that slip through unnoticed in the past.)

And I was theoretically done with the frills code – I just hadn't tested it yet. (Judging by past experience, it probably won't work the first time.)
Link to comment
Share on other sites

Well, that's odd. The crash when drawing fields seems to have magically fixed itself. smirk Ditto with the crash when stepping on damaging terrain. (Though I just noticed that all possible strings are being printed, not just the one for the damage that actually occurs... [EDIT: Fixed; simply missing break statements in switch cases])

 

I was able to bypass the problem with scenario header strings by renaming my test scenario to valleydy.exs; however, I haven't made much progress. The walkways work, sort of; they draw the correct corner, but they're masking blackness rather than the walkway icon. The extended walkway corners also seem to work. And the wall-rounding appears to work to, but it also fails to mask properly.

 

The most recent odd error is in the std::string destructor, of all things, when quitting (after main() has finished executing, I believe).

Link to comment
Share on other sites

(Quoted from the Monsters thread)

Originally Posted By: The Almighty Doer of Stuff
I saw talk in another thread of changing the way old scenarios look through the changes in the way roads, walkways, and other frills work.
I think you've misinterpreted something here. Yes, I'm changing the way frills, roads, and walkways work, but it will have little or no effect on how existing scenarios work.

 

For old scenarios, I think roads will work exactly the same (there may be one or two slight differences); the changes I'm making are more geared towards generalizing than to actually changing how things work. The only major difference at present is that roads crossing a hill boundary in old scenarios will show up as an abrupt transition – where there should be an edge square, there will be a full hill square. However, it would be fairly simple to fix that so that old scenarios show correctly in this situation.

 

Walkways in old scenarios will be mostly unchanged appearance-wise (once I get them to work properly). Again, my changes are more intended as generalization, to allow creation of walkways that round off to reveal hill or some custom terrain underneath. The one exception here is that a single square of walkway forming the point of a triangle will round off on both sides instead of one. I suppose there could be a switch for this, but I consider it to be minor; besides which I would think scenario designers tried to avoid this because it didn't look good.

 

And I consider the other frills to be a very minor thing. They will be unchanged underground, but on the surface they will be changed to work the same way as they already do underground. That leaves the wall-rounding, which is something that I suspect may not have worked in the original BoE; it's being implemented in such a way that it will work. In fact, it already works partially.

 

Originally Posted By: The Almighty Doer of Stuff
I think those should have a compatibility switch as well, in the form of the program functions exactly the way it always did for old-format scenarios, with the sole exception of fixing minor bugs.
I should be able to create a compatibility switch for surface frills. They're probably the only ones that really need it. I'd like to get the new version working first, though. I think it would be as simple as saying something like "IF compatibility switch is true AND current ground is not 0 THEN skip edge frills and wall-rounding and draw corner frills only using graphic #2". Well, okay, it would have to be checked in at least two places, but it shouldn't be too hard if it's really wanted.
Link to comment
Share on other sites

Whew. I've fought things back to the point that the Mac code compiles with no errors and only 348 warnings. I don't have the resources or knowledge to really test for any of the crashes you've described, so I mostly stuck to cleaning up the code. There were a few things I noticed and fixed:

 

-Nearly all headers were dangerously fragile; they did not themselves include library headers (string, vector) that they depended on. This made them dependent on only being included after all the headers that they should have contained references to.

 

-There were almost no include guards, the only one I saw was a nonstandard `#pragma once`.

 

-There were some very dangerous compiler flags set, namely 'one-byte bool' and 'char type is unsigned', so I unset them.

 

There were also some things I spotted but wasn't certain about changing (or couldn't):

 

-No files in the tools/dialogs/ group are actually checked in, and so are missing from my working copy, and that of anyone else who checks out the code freshly.

 

-Is the assignment deliberate? It looks like a mistake.

Code:
bool is_shore(unsigned short ter_type){	if (is_fluid(ter_type) == true)		return false;	if(scenario.ter_types[ter_type].trim_type = TRIM_WATERFALL)		return false;	return true;}

 

-In the code for `case TER_SPEC_DAMAGING:` in boe.specials.cpp, should the different cases in the switch have `break`s?

 

I haven't yet been able to fix those visibility warnings, but I'm still trying. Those are bothersome, as they could be signs of a deeper problem, so I'd like to get them cleared up.

 

EDIT: Was the -fpacked-struct=2 in there for binary compatibility with old savefiles and so forth? This seems like a dangerous thing to specify; I would personally be more comfortable using __attribute__ ((packed)) or __attribute__ ((aligned (<width>))), ugly though doing so would be, on structs that need it, or better yet nothing if it isn't specifically needed.

Link to comment
Share on other sites

Originally Posted By: Niemand
-No files in the tools/dialogs/ group are actually checked in, and so are missing from my working copy, and that of anyone else who checks out the code freshly.
That's right – I haven't gotten them anywhere near functionality (most of the member functions aren't even defined) so I haven't checked them in yet.

Originally Posted By: Niemand
-Is the assignment deliberate? It looks like a mistake.
Code:
bool is_shore(unsigned short ter_type){	if (is_fluid(ter_type) == true)		return false;	if(scenario.ter_types[ter_type].trim_type = TRIM_WATERFALL)		return false;	return true;}
Yeah, that's definitely a mistake. Maybe that's why the frills aren't working at all!

Originally Posted By: Niemand
-In the code for `case TER_SPEC_DAMAGING:` in boe.specials.cpp, should the different cases in the switch have `break`s?
Yes they should. I actually found and fixed that already.

I haven't yet been able to fix those visibility warnings, but I'm still trying. Those are bothersome, as they could be signs of a deeper problem, so I'd like to get them cleared up.

Originally Posted By: Niemand
EDIT: Was the -fpacked-struct=2 in there for binary compatibility with old savefiles and so forth? This seems like a dangerous thing to specify; I would personally be more comfortable using __attribute__ ((packed)) or __attribute__ ((aligned (<width>))), ugly though doing so would be, on structs that need it, or better yet nothing if it isn't specifically needed.
I have no idea why that was set. I know I already used __attribute__((packed)) on one struct. It's possible it was there for compatibility; I don't remember setting it myself though.

If it is for compatibility, then all the structs in oldstructs.h would need to have __attribute__((aligned(2))) if you unset it. (I think.)

Originally Posted By: Niemand
Whew. I've fought things back to the point that the Mac code compiles with no errors and only 348 warnings.
So does this mean you've nuked some unused variables? Or was it other warnings you got around? Or, did you disable those warnings? A number of warnings were also about incomplete switch statements – did you disable them, add the missing cases, or add a default case?

Originally Posted By: Niemand
I don't have the resources or knowledge to really test for any of the crashes you've described, so I mostly stuck to cleaning up the code. There were a few things I noticed and fixed:
...Should I be giving you repository access then? smile

Just note, there are a number of unused functions which I want to keep. Unless an unused function has an empty body, it should not be deleted. It may be used later. I dunno if you're deleting unused functions, but it would seem like a part of code cleanup to me at least.

Originally Posted By: Niemand
-Nearly all headers were dangerously fragile; they did not themselves include library headers (string, vector) that they depended on. This made them dependent on only being included after all the headers that they should have contained references to.
Yes, I know. For some reason I thought that was a good idea.

The headers in the classes group are also dependent on include order, which is the reason for classes.h.

Originally Posted By: Niemand
-There were almost no include guards, the only one I saw was a nonstandard `#pragma once`.
I thought there were #ifndef xxx #define xxx in one or two files as well. But yeah, I didn't generally include them.

Originally Posted By: Niemand
-There were some very dangerous compiler flags set, namely 'one-byte bool' and 'char type is unsigned', so I unset them.
Okay. I may have set those think that it would be harmless, or something; or hoping that since bool was never used in the original code it wouldn't affect anything. Or something. Actually, char unsigned may have already been set. I forget.

Originally Posted By: Niemand
I haven't yet been able to fix those visibility warnings, but I'm still trying. Those are bothersome, as they could be signs of a deeper problem, so I'd like to get them cleared up.
Yeah, I was sort of thinking the same thing... the signs of a deeper problem, I mean.
Link to comment
Share on other sites

Quote:
That's right – I haven't gotten them anywhere near functionality (most of the member functions aren't even defined) so I haven't checked them in yet.

Okay, I just wanted to point it out, since the files are listed in the project file itself. However, since it doesn't use them for anything, it's not a problem.

Quote:
I have no idea why that was set. I know I already used __attribute__((packed)) on one struct. It's possible it was there for compatibility; I don't remember setting it myself though.

If it is for compatibility, then all the structs in oldstructs.h would need to have __attribute__((aligned(2))) if you unset it. (I think.)

I'll go through and put this in, then; it will a messy since from what I've read it will have to be applied to every field, rather than just to the entire struct, but it's not like the structures in that that file are going to be changing.

Quote:
...Should I be giving you repository access then? smile

I suppose that would be appreciated; I can't sink too much time into this, but I might as well help out a bit by actually contributing code.

Quote:
Okay. I may have set those think that it would be harmless, or something; or hoping that since bool was never used in the original code it wouldn't affect anything. Or something. Actually, char unsigned may have already been set. I forget.

The one-byte bool one especially sounds like a good thing, the problem is that code compiled with it is subtly incompatible with code compiled without, according to the help. Since the system libraries are all compiled without it set, it seems best to avoid it unless one has a good reason.
Link to comment
Share on other sites

Originally Posted By: Niemand
Quote:
I have no idea why that was set. I know I already used __attribute__((packed)) on one struct. It's possible it was there for compatibility; I don't remember setting it myself though.

If it is for compatibility, then all the structs in oldstructs.h would need to have __attribute__((aligned(2))) if you unset it. (I think.)

I'll go through and put this in, then; it will a messy since from what I've read it will have to be applied to every field, rather than just to the entire struct, but it's not like the structures in that that file are going to be changing.
I hope that was the reason for it. You'd need to test to make sure loading still works properly (in particular, strings in special encounters or elsewhere appearing as random characters would be a good indication that it's not right).

Originally Posted By: Niemand
Quote:
...Should I be giving you repository access then? smile

I suppose that would be appreciated; I can't sink too much time into this, but I might as well help out a bit by actually contributing code.
Well, then you'll need to email me (or otherwise give me your email). You need a Google account (not necessary a Gmail address though).

You don't have to contribute just because you have respository access, though. wink It just means you can occasionally contribute.

Originally Posted By: Niemand
Quote:
Okay. I may have set those think that it would be harmless, or something; or hoping that since bool was never used in the original code it wouldn't affect anything. Or something. Actually, char unsigned may have already been set. I forget.

The one-byte bool one especially sounds like a good thing, the problem is that code compiled with it is subtly incompatible with code compiled without, according to the help. Since the system libraries are all compiled without it set, it seems best to avoid it unless one has a good reason.
...Ahhhh... I see how that could be a problem.
Link to comment
Share on other sites

There are 7 empty slots in the ter5 sheet (resID 804). Does anyone have any suggestions on what to put there? (You can see the sheets here.) Ideally it would be graphics that were actually originally created for one of the Exile games; however, I think all such graphics are already included, so that won't work. I suppose I could move some graphics from ter7 (resID 806) to fill the space; I just wanted to keep similar graphics together to some extent.

 

In addition to these 7 empty slots which must be filled, there are 80 potential slots that could be filled if we felt like it. I doubt they all will be though; however, if all 80 slots were filled we would be able to combine the Pick Picture button with the Animated button in the Edit Terrain dialog. I dunno if that's a good idea, but we could do it if there were 87 more graphics. Still, the chances of getting 87 more graphics is pretty slim.

Link to comment
Share on other sites

Ok, all this programming is way beyond me, but graphics I understand.

 

Have you added any of the terrains from the scenarios that came with blades? (I know there's at least one in Valley of Dying Things and I didn't notice it on the terrain sheet.)

 

If you don't mind edited or non-original-exiles graphics I also have quite a few edited ones (torches, bookshelves, and desk on marble floor, altar on grass, etc.) and several with my own base floor/wall graphics. And I can probably do others if you want anything specific.

They're all in the windows colors, though, and I notice your sheets are colored for mac?

 

Anyway, if you're interested, let me know and I'd be glad to send you what I have.

Link to comment
Share on other sites

First, I don't want to add the custom graphics for the basic scenarios. The three default scenarios serve as an example of how to do custom graphics; if their graphics were added to the main set and they no longer needed custom graphics, then there would no longer be such an example. So they're excluded on purpose.

 

I would also prefer to avoid adding new kinds of floor and walls, I think; I'd be most inclined to make an exception if they are adapted from Avernum.

 

There are a few specific graphics I would like. You'll notice that on ter7 there's only one cave entrance. I'd like to have a full complement of cave entrances, so if someone could make north-facing, east-facing, and west-facing cave entrances to match the original E3 graphics that would be great. And I don't mean simply flipping or rotating the graphic – that could cause it to not match properly. Another thing I'd like is to complete the complement of waterfalls. There's a south-flowing waterfall; I'd like north-flowing, east-flowing, and west-flowing waterfalls. (Though, the waterfalls wouldn't be able to fill in the 7 gaps, since they'd be animated.) Another specific graphic I'd like is a middle rubble space for the grass and grey cave floor. There's already one for the blue cave floor. Basically this allows creation of arbitrarily long trails of rubble. And also if there are any graphics from the Exile series that I've missed, let me know. I don't think I have missed any though.

 

Apart from those specific ones, I'd prefer graphics that are logical extensions of existing graphics (eg more stuff on marble floor, evil altar on grey cave floor, mushroom crops for both cave floor, transitions between the two cave floors) or graphics that are adapted from Avernum.

 

Now is probably a good time to mention that I have created some graphics that satisfy the criteria. For example, I made an adaptation of Avernum's crystal walls. I could include some these if others agree.

 

EDIT: Oh, by the way: we'll want them both in the darker Mac form and the lighter Windows form. I would advise making graphics as Mac graphics and then brightening them to create the Windows graphics; I assume that's what Jeff himself did.

Link to comment
Share on other sites

Quote:
First, I don't want to add the custom graphics for the basic scenarios. The three default scenarios serve as an example of how to do custom graphics; if their graphics were added to the main set and they no longer needed custom graphics, then there would no longer be such an example. So they're excluded on purpose.


I don't see why you can't keep both the pedagogical reasons AND put the specific graphics in the default files. You just don't change the scenario files and still have them pull the equivalent graphics from the external files instead. This serves as a good example, and gives the designer easy access to these graphics.

Now that we have source code and download speeds are fast compared to in 1997, we can drastically expand the number of default graphics. This also helps preserve these valuable things which are too often lost in the cyber-ether.
Link to comment
Share on other sites

Note however that unless we change the fact that animated graphics are 400 + slot, we can't have more than 400 non-animated graphics in total. That said, it wouldn't be too difficult to change – no harder, I think, than the change I made so that custom item graphics are 1000 + slot.

 

But what's the point of the default scenarios having custom graphics files if those graphics are also in the default graphic set?

 

Now, can anyone figure out why this code doesn't behave as expected?

Code:
PixMapHandle from_bits = GetPortPixMap(from_gworld);PixMapHandle mask_bits = GetPortPixMap(roads_gworld);PixMapHandle to_bits = GetPortPixMap(terrain_screen_gworld);LockPixels(to_bits);LockPixels(mask_bits);LockPixels(from_bits);CopyMask ((BitMap*) *from_bits, (BitMap*) *mask_bits, (BitMap*) *to_bits, &from_rect, &mask_rect, &to_rect);	UnlockPixels(from_bits);UnlockPixels(mask_bits);UnlockPixels(to_bits);

 

The from_gworld is one of the terrain sheets (ter1-ter7 and teranim); the roads_gworld is this sheet. Am I doing something wrong? Does the mask need to be a monochrome bitmap? Essentially what's happening is the mask only is being drawn, rather than being applied to the terrain graphic. There's definitely nothing wrong with mask_rect and to_rect (the correct mask is always drawn, and in the correct location), and from_rect appears to be fine as well.

Link to comment
Share on other sites

Quote:
But what's the point of the default scenarios having custom graphics files if those graphics are also in the default graphic set?


Instructive reasons. I guess you do not need to take every graphic from the Vogel scenarios, but I do think a few of them are prolific enough that they may as well be in the default graphics.
Link to comment
Share on other sites

I decided to make a new thread specifically for discussing the graphics. I'm not sure how I would go about determining which graphics have been used a lot. I don't really know all that many scenarios, so I think it's better for others to suggest graphics to be added.

Link to comment
Share on other sites

So, no-one can see anything wrong with that particular chunk of code?

 

I'd be inclined to think it's some kind of problem with from_gworld; however, swapping from_gworld and roads_gworld resulting in the appearance of graphics from from_gworld, blended with the graphic beneath it. The odd thing is that that's not what I would expect, either – I would have expected that since the mask is now being drawn, and what should be drawn is used as the mask, there should be some sort of clear divide between the area where the mask is white and that where it is black.

 

I'm going to try swapping from_rect and mask_rect, just because I have no idea what I could possibly do.

Link to comment
Share on other sites

Never mind – it turns out I was simply using the wrong function. With CopyDeepMask it works perfectly.

 

 

Finally! laugh

 

 

EDIT: Okay, spoke too soon. Walkways and wall-rounding works perfectly, but frills still don't work; and for some reason special spots are displaying on a white background now. smirk

Link to comment
Share on other sites

And fixed. Frills work perfectly (as far as I've tested), walkway rounds off properly, and walls are drawn with round corners.

 

 

Now I have two questions.

 

1.I want to make it so that damaging terrain doesn't affect you when you're in a boat. My question is, have there been any scenarios where you must boat over lava? (Or other damaging terrain.)

 

2.This one is a little complicated; it involves the automap. At present, the standard size for a map graphic is 6 by 6 pixels. Several of the most basic graphics, however, are not drawn from the set of 6x6 map graphics. (Examples: water, cave floor, grass, hills.) Instead, they are drawn from a set of pattern fills, most of which are 8x8 pixels. (A few are even larger, up to 32x32 pixels.) This means that they don't exactly fit into the grid; they'll overflow into adjacent spaces of the same type. So, making the map graphics 8x8 seems to me to be a decent compromise. It would require doing something in the scenario editor when viewing the map of a large town, though, since it currently fills the available area.

 

To (potentially) take this even further, maybe we should scrap all the map graphics and simply redo them. I think they are essentially scaled down versions of their respective large graphics; it seems to me, however, that it would be better to make them crisper, for example making simple terrains like grass and cave floor monochrome (green, grey, and blue-green, of course), and for the most part only using a few colours in each graphic. (This would also be more like the way Avernum handles them.)

 

And of course I'd like people to be able to provide their own map graphics for custom terrains.

 

...So, basically I'd like people's opinions on this. I'm not sure which is the best way to go.

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