Dries390
Well-Known Member
- Joined
- Sep 8, 2007
- Messages
- 91
- Solutions
- 4
- Reaction score
- 70
Hello everyone. I recently ran into some problems tring to create more complex landscapes using the forgotten server engine and set out to try and bypass, if not fix, these following issues
1a) The z =< 7 and z > 7 floors of the map don't communicate with each other. You can map something very nice below z = 7, but you will not be able to see it from above.
1b) Underground (z > 7) you can only see, at most, two floors down.
2) Remere's map editor has the same problem as 1a. When you map something below the ground, it's a pain to make sure everything lines up correctly on the surface.
3) The natural light cycle does not extend underground; even when it's light outside going under z = 7 will make it appear like you're in a cave.
A lot of smart people on the forums said a lot of smart things and so I was able to piece together how to perform all these changes. I've been sifting through a lot of random posts to try and piece everything together so I'll try to give credit to people where I remember who they were. Baxnie's post here:
showed me how to enable transparant water through otclient.
Requirements:
- You'll need to be able to re-compile Remere's map editor, your source of server (I use TFS 1.3 downgraded to 8.60 by Nekiro) and the OTClient. How to do this is explained at their respective github wiki's.
Disclaimer:
Please back up your files before messing with the source code. Things might go wrong and while I -can- usually fix my own code I can't guarantee I'll understand what's wrong with yours. Please use your head and try to learn -what- you're doing while applying these changes, my goal is really to write down as much as I can to help people figure out how to implement these changes rather than do everything for you. As far as I've tested, these changes work on my server and if anything goes really wrong I'll try to come back and update this.
Known Issues:
- I didn't put in the effort (yet) to fix how Remere offsets lower levels with respect to higher levels. This means your underground map will 'float' away when you go to z < 7, the lower levels keep being offset while the higher levels don't. This does -not- effect your map but it just looks really weird and might be a bit confusing.
Example:
This is how we want things to look when we're done (maybe mapped a lot better).
Server-side and OTClient-side
I based my modifications on Erexo's post here, all credits go to him:
TFS Modification
protocolgame.cpp l. 538 - l. 561
protocolgame.cpp l. 538 - l. 561
OTClient Modification
protocolgameparse.cpp l. 2044 - l. 2064
map.cpp l. 707 - l. 710
mapview.cpp l. 696 - l. 719
These changes should allow your server, and client, to communicate floors above z = 7 with those below z = 7. Mapping this way is, however, a huge pain in the butt because Remere can't see below z = 7. The following piece of code "fixes" this:
map_drawer.cpp l. 100 - l. 134
With the underground open, a new problem arises. Anyone going to z > 7 will be plunged into the depths of darkness because of how the day-night cycle is draw in the client, regardless of the fact that there is (maybe) no ground above it.
Here's a very crude illustration of the problem. I didn't like how "non-realistic" this was so I added the following code to my OTClient
mapview.cpp l. 117- l. 138
void MapView::draw(const Rect& rect)
This little snipper of code essentially checks if there are any tiles above the current position and, if not, changes the light intensity to the "above-ground" light-intensity i.e. the current level of light corresponding to the time of day 'shines' down into the pit. Here's an example I just tested.
I'm still working on testing and improving the lighting. One thing I've (just) noticed is that there's a small bit of ambient light tied to the character underground such that the two brightnesses don't -quite- match up, but it's quite minor and I'll probably find a way to change it.
Edit: IMPORTANT! Don't forget to check "show all floors" or hit ctrl+W!
Enjoy!
1a) The z =< 7 and z > 7 floors of the map don't communicate with each other. You can map something very nice below z = 7, but you will not be able to see it from above.
1b) Underground (z > 7) you can only see, at most, two floors down.
2) Remere's map editor has the same problem as 1a. When you map something below the ground, it's a pain to make sure everything lines up correctly on the surface.
3) The natural light cycle does not extend underground; even when it's light outside going under z = 7 will make it appear like you're in a cave.
A lot of smart people on the forums said a lot of smart things and so I was able to piece together how to perform all these changes. I've been sifting through a lot of random posts to try and piece everything together so I'll try to give credit to people where I remember who they were. Baxnie's post here:
How i can active Transparence
I saw a picture with the transparency of otclient and wanted to know how to enable it
otland.net
Requirements:
- You'll need to be able to re-compile Remere's map editor, your source of server (I use TFS 1.3 downgraded to 8.60 by Nekiro) and the OTClient. How to do this is explained at their respective github wiki's.
Disclaimer:
Please back up your files before messing with the source code. Things might go wrong and while I -can- usually fix my own code I can't guarantee I'll understand what's wrong with yours. Please use your head and try to learn -what- you're doing while applying these changes, my goal is really to write down as much as I can to help people figure out how to implement these changes rather than do everything for you. As far as I've tested, these changes work on my server and if anything goes really wrong I'll try to come back and update this.
Known Issues:
- I didn't put in the effort (yet) to fix how Remere offsets lower levels with respect to higher levels. This means your underground map will 'float' away when you go to z < 7, the lower levels keep being offset while the higher levels don't. This does -not- effect your map but it just looks really weird and might be a bit confusing.
Example:
This is how we want things to look when we're done (maybe mapped a lot better).
Server-side and OTClient-side
I based my modifications on Erexo's post here, all credits go to him:
How to make the player who is on the 7th floor see who is on the 8th floor
I am trying to create transparent water, I have added the sprites on the client and activated the transparency in otclient, but by default it is not possible to see who is on floor 8 being on the 7th floor. I made several changes in the sources of the client more without result. mapview.ccp...
otland.net
TFS Modification
protocolgame.cpp l. 538 - l. 561
C++:
void ProtocolGame::GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t width, int32_t height, NetworkMessage& msg)
{
int32_t skip = -1;
int32_t startz, endz, zstep;
if (z > 7) {
startz = 0; //floors z < 7 retrieve map description from z = 0
endz = 15; //floors z < 7 look for map until z = 15
zstep = 1;
} else {
startz = 15; //floors z >= 7 look for map until z = 15
endz = 0; //floors z >= 7 retrieve map description from z = 0
zstep = -1;
}
for (int32_t nz = startz; nz != endz + zstep; nz += zstep) {
GetFloorDescription(msg, x, y, nz, width, height, z - nz, skip);
}
if (skip >= 0) {
msg.addByte(skip);
msg.addByte(0xFF);
}
}
protocolgame.cpp l. 538 - l. 561
C++:
bool ProtocolGame::canSee(int32_t x, int32_t y, int32_t z) const
{
if (!player) {
return false;
}
const Position& myPos = player->getPosition();
if (myPos.z <= 7) {
//we are on ground level or above (7 -> 0)
//view is from current floor to floor 15.
if (z > 15) {
return false;
}
} else if (myPos.z >= 8) {
//we are underground (8 -> 15)
//view is from current floor to floor 15.
if (z > 15) {
return false;
}
}
//negative offset means that the action taken place is on a lower floor than ourself
int32_t offsetz = myPos.getZ() - z;
if ((x >= myPos.getX() - 8 + offsetz) && (x <= myPos.getX() + 9 + offsetz) &&
(y >= myPos.getY() - 6 + offsetz) && (y <= myPos.getY() + 7 + offsetz)) {
return true;
}
return false;
}
OTClient Modification
protocolgameparse.cpp l. 2044 - l. 2064
C++:
void ProtocolGame::setMapDescription(const InputMessagePtr& msg, int x, int y, int z, int width, int height)
{
int startz, endz, zstep;
if(z > Otc::SEA_FLOOR) {
startz = 0;
endz = 15;
zstep = 1;
}
else {
startz = 15;
endz = 0;
zstep = -1;
}
int skip = 0;
for(int nz = startz; nz != endz + zstep; nz += zstep)
skip = setFloorDescription(msg, x, y, nz, width, height, z - nz, skip);
}
map.cpp l. 707 - l. 710
C++:
int Map::getLastAwareFloor()
{
return Otc::SEA_FLOOR + 8;
}
mapview.cpp l. 696 - l. 719
C++:
int MapView::calcLastVisibleFloor()
{
if(!m_multifloor)
return calcFirstVisibleFloor();
int z = 7;
Position cameraPosition = getCameraPosition();
// this could happens if the player is not known yet
if(cameraPosition.isValid()) {
// view only underground floors when below sea level
if(cameraPosition.z > Otc::SEA_FLOOR)
z = 15;
else
z = 15;
}
if(m_lockedFirstVisibleFloor != -1)
z = std::max<int>(m_lockedFirstVisibleFloor, z);
// just ensure the that the floor is in the valid range
z = stdext::clamp<int>(z, 0, (int)Otc::MAX_Z);
return z;
}
These changes should allow your server, and client, to communicate floors above z = 7 with those below z = 7. Mapping this way is, however, a huge pain in the butt because Remere can't see below z = 7. The following piece of code "fixes" this:
map_drawer.cpp l. 100 - l. 134
C++:
void MapDrawer::SetupVars()
{
canvas->MouseToMap(&mouse_map_x, &mouse_map_y);
canvas->GetViewBox(&view_scroll_x, &view_scroll_y, &screensize_x, &screensize_y);
dragging = canvas->dragging;
dragging_draw = canvas->dragging_draw;
zoom = (float)canvas->GetZoom();
tile_size = int(TILE_SIZE / zoom); // after zoom
floor = canvas->GetFloor();
if(options.show_all_floors) {
if(floor < 8)
start_z = MAP_MAX_LAYER; // These two values for start_z allow the editor to get lower floors.
else
start_z = MAP_MAX_LAYER; //start_z = std::min(MAP_MAX_LAYER, floor + 2);
}
else
start_z = floor;
end_z = floor;
superend_z = (floor > GROUND_LAYER ? 8 : 0);
start_x = view_scroll_x / TILE_SIZE;
start_y = view_scroll_y / TILE_SIZE;
if(floor > GROUND_LAYER) {
start_x -= 2;
start_y -= 2;
}
end_x = start_x + screensize_x / tile_size + 2;
end_y = start_y + screensize_y / tile_size + 2;
}
Post automatically merged:
With the underground open, a new problem arises. Anyone going to z > 7 will be plunged into the depths of darkness because of how the day-night cycle is draw in the client, regardless of the fact that there is (maybe) no ground above it.
Here's a very crude illustration of the problem. I didn't like how "non-realistic" this was so I added the following code to my OTClient
mapview.cpp l. 117- l. 138
void MapView::draw(const Rect& rect)
C++:
Light ambientLight;
if(cameraPosition.z <= Otc::SEA_FLOOR) {
ambientLight = g_map.getLight();
} else {
int floorCounter = 0;
for (int iz = cameraPosition.z; iz > 0; iz--) {
Position dPos= cameraPosition;
dPos.z = dPos.z - iz;
TilePtr dTile = g_map.getTile(dPos);
if (dTile) {
floorCounter = floorCounter + 1;
}
}
if (floorCounter> 0) {
ambientLight.color = 215;
ambientLight.intensity = 0;
} else {
ambientLight = g_map.getLight();
}
}
ambientLight.intensity = std::max<int>(m_minimumAmbientLight*255, ambientLight.intensity);
m_lightView->setGlobalLight(ambientLight);
I'm still working on testing and improving the lighting. One thing I've (just) noticed is that there's a small bit of ambient light tied to the character underground such that the two brightnesses don't -quite- match up, but it's quite minor and I'll probably find a way to change it.
Edit: IMPORTANT! Don't forget to check "show all floors" or hit ctrl+W!
Enjoy!
Last edited: