diff --git a/game/engines/default/engine/Map.lua b/game/engines/default/engine/Map.lua index 8ddb87af031bb5c5976776ba8e05d1bcd79b2875..3dc3841d93e21ca03aded77c52cea335d2de6a1d 100644 --- a/game/engines/default/engine/Map.lua +++ b/game/engines/default/engine/Map.lua @@ -444,14 +444,17 @@ function _M:minimapDisplay(dx, dy, x, y, w, h, transp) self._map:toScreenMiniMap(dx, dy, x, y, w, h, transp or 0.6) end ---- Displays the map on a surface --- @return a surface containing the drawn map -function _M:display(x, y, nb_keyframe) +--- Displays the map on screen +-- @param x the coord where to start drawing, if null it uses self.display_x +-- @param y the coord where to start drawing, if null it uses self.display_y +-- @param nb_keyframes the number of keyframes elapsed since last draw +-- @param always_show tell the map code to force display unseed entities as remembered (used for smooth FOV shading) +function _M:display(x, y, nb_keyframe, always_show) nb_keyframes = nb_keyframes or 1 local ox, oy = self.display_x, self.display_y self.display_x, self.display_y = x or self.display_x, y or self.display_y - self._map:toScreen(self.display_x, self.display_y, nb_keyframe) + self._map:toScreen(self.display_x, self.display_y, nb_keyframe, always_show) -- Tactical display if self.view_faction then diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index df762e958bcb9a871cf5741cfdfc57f53c465404..2625f73bfad816ac4a059618b65bc71b81f83672 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -338,6 +338,14 @@ function _M:setupDisplayMode(reboot, mode) if gfx.tiles == "ascii" then Map.tiles.use_images = false Map.tiles.force_back_color = {r=0, g=0, b=0, a=255} end if gfx.tiles == "ascii_full" then Map.tiles.use_images = false end if gfx.tiles == "shockbolt" then Map.tiles.nicer_tiles = true end + + -- Create the framebuffer + self.fbo = core.display.newFBO(Map.viewport.width, Map.viewport.height) + if self.fbo then + self.fbo_shader = Shader.new("main_fbo") + if not self.fbo_shader.shad then self.fbo = nil self.fbo_shader = nil end + end + if self.player then self.player:updateMainShader() end end if not mode or mode == "postinit" then @@ -347,14 +355,6 @@ function _M:setupDisplayMode(reboot, mode) self.level.map:moveViewSurround(self.player.x, self.player.y, 8, 8) end self:setupMiniMap() - - -- Create the framebuffer - self.fbo = core.display.newFBO(Map.viewport.width, Map.viewport.height) - if self.fbo then - self.fbo_shader = Shader.new("main_fbo") - if not self.fbo_shader.shad then self.fbo = nil self.fbo_shader = nil end - end - if self.player then self.player:updateMainShader() end end end @@ -729,7 +729,8 @@ function _M:display(nb_keyframes) -- Now the map, if any if self.level and self.level.map and self.level.map.finished then -- Display the map and compute FOV for the player if needed - if self.level.map.changed then + local changed = self.level.map.changed + if changed then self.player:playerFOV() end @@ -738,18 +739,21 @@ function _M:display(nb_keyframes) self.fbo:use(true) if self.level.data.background then self.level.data.background(self.level, 0, 0, nb_keyframes) end - self.level.map:display(0, 0, nb_keyframes) - self.target:display(0, 0) + self.level.map:display(0, 0, nb_keyframes, true) -- Display at the base of the FBO and make sure to display everything as the shader will do smooth FOV over it if self.level.data.foreground then self.level.data.foreground(self.level, 0, 0, nb_keyframes) end if self.level.data.weather_particle then self.state:displayWeather(self.level, self.level.data.weather_particle, nb_keyframes) end self.fbo:use(false) _2DNoise:bind(1, false) + if changed then self.level.map._map:updateSeensTexture() end + self.level.map._map:bindSeensTexture(2) + self.fbo_shader:setUniform("seensinfo", {self.level.map._map:getSeensInfo()}) self.fbo:toScreen( self.level.map.display_x, self.level.map.display_y, self.level.map.viewport.width, self.level.map.viewport.height, self.fbo_shader.shad ) + self.target:display() -- Basic display else diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index a84ff27ac560b8490166c2eea78c85e37919adba..6d141ac749a645184f8e6b46e0487b49410b9da8 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -731,6 +731,7 @@ function _M:playerUseItem(object, item, inven) if game.zone.wilderness then game.logPlayer(self, "You cannot use items on the world map.") return end local use_fct = function(o, inven, item) + if not o then return end local co = coroutine.create(function() self.changed = true diff --git a/game/modules/tome/data/gfx/shaders/main_fbo.frag b/game/modules/tome/data/gfx/shaders/main_fbo.frag index 013d4d9cba8e7cc61ba7469b07628b1c1290478f..5e68631fc9ba4acd243dc9412c707629e0ab627e 100644 --- a/game/modules/tome/data/gfx/shaders/main_fbo.frag +++ b/game/modules/tome/data/gfx/shaders/main_fbo.frag @@ -5,11 +5,35 @@ uniform float tick; uniform sampler2D noisevol; uniform vec2 texSize; uniform sampler2D tex; +uniform sampler2D seens; +uniform vec4 seensinfo; uniform vec3 colorize; +// Return the given pixel, this allows things like blur to work even with smooth fov shading +vec4 get_pixel(vec2 coord) +{ + /* + * Few lines to do some tricky things + * The game provides use with a "seens" texture that is the computed FOV + * We use this to lookup the current tile and shadow it as needed + * seenscoords is arranged as this: (tile_w, tile_h, view_scene_w, view_scene_h) + * We offset by 1x1.25 tiles .. dont ask why, it just works :/ + */ + vec2 seenscoord = vec2((((coord.x + 64 / texSize.x) / seensinfo.r)) * texSize.x / seensinfo.b, (((coord.y + 80 / texSize.y) / seensinfo.g)) * texSize.y / seensinfo.a); + vec3 seen = texture2D(seens, seenscoord); + vec4 res = texture2D(tex, coord.xy); + res.r *= seen.r; + res.g *= seen.g; + res.b *= seen.b; + + // Now we got our shaded pixel, we can do otehr stuff with it +// res = texture2D(tex, coord.xy); // this is a non shading version + return res; +} + void main(void) { - gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); + gl_FragColor = get_pixel(gl_TexCoord[0]); if (motionblur > 0.0) { @@ -34,7 +58,7 @@ void main(void) { for(int j = -blursize; j <= 0; j++) { - sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); + sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); } } } @@ -44,7 +68,7 @@ void main(void) { for(int j = 0; j <= blursize; j++) { - sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); + sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); } } } @@ -54,7 +78,7 @@ void main(void) { for(int j = -blursize; j <= 0; j++) { - sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); + sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); } } } @@ -64,7 +88,7 @@ void main(void) { for(int j = 0; j <= blursize; j++) { - sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); + sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); } } } @@ -86,7 +110,7 @@ void main(void) { for(int j = -blursize; j <= blursize; j++) { - sample += texture2D(tex, vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); + sample += get_pixel(vec2(gl_TexCoord[0].xy+vec2(float(i)*offset.x, float(j)*offset.y))); } } sample /= (blur*2.0) * (blur*2.0); diff --git a/game/modules/tome/data/gfx/shaders/main_fbo.lua b/game/modules/tome/data/gfx/shaders/main_fbo.lua index 9eadd16867901340bce9646efac4874ce23133b0..423e85468fb34b8a50a9a697600a44006c40de9b 100644 --- a/game/modules/tome/data/gfx/shaders/main_fbo.lua +++ b/game/modules/tome/data/gfx/shaders/main_fbo.lua @@ -23,6 +23,7 @@ return { args = { tex = { texture = 0 }, noisevol = { texture = 1 }, + seens = { texture = 2 }, }, clone = false, } diff --git a/game/modules/tome/data/gfx/shockbolt/trap/poison_vines01.png b/game/modules/tome/data/gfx/shockbolt/trap/poison_vines01.png index e84fe111458c95d0156c93396b062a4ec06cc997..d073c63f575fba21148045b53381f90981bfd1df 100644 Binary files a/game/modules/tome/data/gfx/shockbolt/trap/poison_vines01.png and b/game/modules/tome/data/gfx/shockbolt/trap/poison_vines01.png differ diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index 58d104ba4aa9176426df5b3b677c212b951e6ec9..a54e96742799533791e14aaa5bf3e3297050fb09 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -744,13 +744,14 @@ newTalent{ detect_power = 6 * self:getTalentLevel(t), disarm_power = 10 * self:getTalentLevel(t), level_range = {self.level, self.level}, message = "@Target@ is caught in a web!", + pin_dur = dur, canTrigger = function(self, x, y, who) if who.type == "spiderkin" then return false end return mod.class.Trap.canTrigger(self, x, y, who) end, triggered = function(self, x, y, who) if who:checkHit(self.disarm_power + 5, who:combatPhysicalResist(), 0, 95, 15) and who:canBe("stun") and who:canBe("pin") then - who:setEffect(who.EFF_PINNED, dur, {}) + who:setEffect(who.EFF_PINNED, self.pin_dur, {}) else game.logSeen(who, "%s resists!", who.name:capitalize()) end diff --git a/src/core_lua.c b/src/core_lua.c index a6e2cbc9dd5e5addfd984d4a9b8995afa0a4ddb5..56ab81fcdec359d9100880973df18d323390abde 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -1373,7 +1373,7 @@ static int gl_fbo_toscreen(lua_State *L) if (lua_isuserdata(L, 6)) { shader_type *s = (shader_type*)auxiliar_checkclass(L, "gl{program}", 6); - useShader(s, 0, 0, w, h, r, g, b, a); + useShader(s, fbo->w, fbo->h, w, h, r, g, b, a); } glDisable(GL_BLEND); diff --git a/src/map.c b/src/map.c index 8771dd872bd38ec93b96bcccb5a40b820b185399..b9e7fae71d5b68902c182258129415312ef40843 100644 --- a/src/map.c +++ b/src/map.c @@ -497,17 +497,25 @@ static int map_new(lua_State *L) map->mwidth = mwidth; map->mheight = mheight; map->grids = calloc(w, sizeof(map_object***)); - map->grids_seens = calloc(w, sizeof(float*)); + map->grids_seens = calloc(w * h, sizeof(float)); map->grids_remembers = calloc(w, sizeof(bool*)); map->grids_lites = calloc(w, sizeof(bool*)); map->minimap = calloc(w, sizeof(unsigned char*)); printf("C Map size %d:%d :: %d\n", mwidth, mheight,mwidth * mheight); + glGenTextures(1, &(map->seens_texture)); + tglBindTexture(GL_TEXTURE_2D, map->seens_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 4, map->mwidth + 3, map->mheight + 3, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + map->seens_map = calloc((map->mwidth + 3)*(map->mheight + 3)*4, sizeof(GLubyte)); + for (i = 0; i < w; i++) { map->grids[i] = calloc(h, sizeof(map_object**)); for (j = 0; j < h; j++) map->grids[i][j] = calloc(zdepth, sizeof(map_object*)); - map->grids_seens[i] = calloc(h, sizeof(float)); +// map->grids_seens[i] = calloc(h, sizeof(float)); map->grids_remembers[i] = calloc(h, sizeof(bool)); map->grids_lites[i] = calloc(h, sizeof(bool)); map->minimap[i] = calloc(h, sizeof(unsigned char)); @@ -525,7 +533,7 @@ static int map_free(lua_State *L) { for (j = 0; j < map->h; j++) free(map->grids[i][j]); free(map->grids[i]); - free(map->grids_seens[i]); +// free(map->grids_seens[i]); free(map->grids_remembers[i]); free(map->grids_lites[i]); free(map->minimap[i]); @@ -542,6 +550,9 @@ static int map_free(lua_State *L) luaL_unref(L, LUA_REGISTRYINDEX, map->mo_list_ref); + glDeleteTextures(1, &map->seens_texture); + free(map->seens_map); + lua_pushnumber(L, 1); return 1; } @@ -645,7 +656,7 @@ static int map_set_seen(lua_State *L) float v = lua_tonumber(L, 4); if (x < 0 || y < 0 || x >= map->w || y >= map->h) return 0; - map->grids_seens[x][y] = v; + map->grids_seens[y*map->w+x] = v; return 0; } @@ -680,7 +691,7 @@ static int map_clean_seen(lua_State *L) for (i = 0; i < map->w; i++) for (j = 0; j < map->h; j++) - map->grids_seens[i][j] = 0; + map->grids_seens[j*map->w+i] = 0; return 0; } @@ -706,6 +717,87 @@ static int map_clean_lite(lua_State *L) return 0; } +static int map_get_seensinfo(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + lua_pushnumber(L, map->tile_w); + lua_pushnumber(L, map->tile_h); + lua_pushnumber(L, map->seensinfo_w); + lua_pushnumber(L, map->seensinfo_h); + return 4; +} + +static int map_update_seen_texture(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + + tglBindTexture(GL_TEXTURE_2D, map->seens_texture); + + int mx = map->used_mx; + int my = map->used_my; + GLubyte *seens = map->seens_map; + int ptr = 0; + int ii, jj; + map->seensinfo_w = map->mwidth + 3; + map->seensinfo_h = map->mheight + 3; + + for (jj = map->mheight + 3 - 1; jj >= 0; jj--) + { + for (ii = 0; ii < map->mwidth + 3; ii++) + { + int i = mx - 1 + ii, j = my - 1 + jj; + if ((i < 0) || (j < 0) || (i >= map->w) || (j >= map->h)) + { + seens[ptr] = 0; + seens[ptr+1] = 0; + seens[ptr+2] = 0; + seens[ptr+3] = 255; + ptr += 4; + continue; + } + float v = map->grids_seens[j*map->w+i] * 255; + if (v) + { + if (v > 255) v = 255; + if (v < 0) v = 0; + seens[ptr] = (GLubyte)(map->shown_b * v); + seens[ptr+1] = (GLubyte)(map->shown_g * v); + seens[ptr+2] = (GLubyte)(map->shown_r * v); + } + else if (map->grids_remembers[i][j]) + { + seens[ptr] = (GLubyte)(map->obscure_b * 255); + seens[ptr+1] = (GLubyte)(map->obscure_g * 255); + seens[ptr+2] = (GLubyte)(map->obscure_r * 255); + } + else + { + seens[ptr] = 0; + seens[ptr+1] = 0; + seens[ptr+2] = 0; + } + seens[ptr+3] = 255; + ptr += 4; + } + } + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, map->mwidth + 3, map->mheight + 3, GL_BGRA, GL_UNSIGNED_BYTE, seens); + + return 0; +} + +static int map_bind_seen_texture(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + int unit = luaL_checknumber(L, 2); + if (unit > 0 && !multitexture_active) return 0; + + if (unit > 0) tglActiveTexture(GL_TEXTURE0+unit); + tglBindTexture(GL_TEXTURE_2D, map->seens_texture); + if (unit > 0) tglActiveTexture(GL_TEXTURE0); + + return 0; +} + static int map_set_scroll(lua_State *L) { map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); @@ -800,8 +892,8 @@ static int map_get_scroll(lua_State *L) } \ } -inline void display_map_quad(GLuint *cur_tex, int *vert_idx, int *col_idx, map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes) ALWAYS_INLINE; -void display_map_quad(GLuint *cur_tex, int *vert_idx, int *col_idx, map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes) +inline void display_map_quad(GLuint *cur_tex, int *vert_idx, int *col_idx, map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes, bool always_show) ALWAYS_INLINE; +void display_map_quad(GLuint *cur_tex, int *vert_idx, int *col_idx, map_type *map, int dx, int dy, float dz, map_object *m, int i, int j, float a, float seen, int nb_keyframes, bool always_show) { float r, g, b; GLfloat *vertices = map->vertices; @@ -811,29 +903,40 @@ void display_map_quad(GLuint *cur_tex, int *vert_idx, int *col_idx, map_type *ma /******************************************************** ** Select the color to use ********************************************************/ - if (seen) + if (always_show) { - if (m->tint_r < 1 || m->tint_g < 1 || m->tint_b < 1) - { - r = (map->shown_r + m->tint_r)/2; g = (map->shown_g + m->tint_g)/2; b = (map->shown_b + m->tint_b)/2; - } - else - { - r = map->shown_r; g = map->shown_g; b = map->shown_b; - } - r *= seen; - g *= seen; - b *= seen; + // In smooth fov mode it's the shader that does FOV display + r = m->tint_r; g = m->tint_g; b = m->tint_b; + a = 1; } else { - if (m->tint_r < 1 || m->tint_g < 1 || m->tint_b < 1) + if (seen) { - r = (map->obscure_r + m->tint_r)/2; g = (map->obscure_g + m->tint_g)/2; b = (map->obscure_b + m->tint_b)/2; + if (m->tint_r < 1 || m->tint_g < 1 || m->tint_b < 1) + { + r = (map->shown_r + m->tint_r)/2; g = (map->shown_g + m->tint_g)/2; b = (map->shown_b + m->tint_b)/2; + } + else + { + r = map->shown_r; g = map->shown_g; b = map->shown_b; + } + r *= seen; + g *= seen; + b *= seen; + a = seen; } else { - r = map->obscure_r; g = map->obscure_g; b = map->obscure_b; + if (m->tint_r < 1 || m->tint_g < 1 || m->tint_b < 1) + { + r = (map->obscure_r + m->tint_r)/2; g = (map->obscure_g + m->tint_g)/2; b = (map->obscure_b + m->tint_b)/2; + } + else + { + r = map->obscure_r; g = map->obscure_g; b = map->obscure_b; + } + a = map->obscure_r; } } @@ -932,6 +1035,7 @@ static int map_to_screen(lua_State *L) int x = luaL_checknumber(L, 2); int y = luaL_checknumber(L, 3); int nb_keyframes = luaL_checknumber(L, 4); + bool always_show = lua_toboolean(L, 5); int i = 0, j = 0, z = 0; int vert_idx = 0; int col_idx = 0; @@ -952,6 +1056,9 @@ static int map_to_screen(lua_State *L) x -= animdx; y -= animdy; + map->used_mx = mx; + map->used_my = my; + // Always display some more of the map to make sure we always see it all for (z = 0; z < map->zdepth; z++) { @@ -966,15 +1073,15 @@ static int map_to_screen(lua_State *L) map_object *mo = map->grids[i][j][z]; if (!mo) continue; - if ((mo->on_seen && map->grids_seens[i][j]) || (mo->on_remember && map->grids_remembers[i][j]) || mo->on_unknown) + if ((mo->on_seen && map->grids_seens[j*map->w+i]) || (mo->on_remember && (always_show || map->grids_remembers[i][j])) || mo->on_unknown) { - if (map->grids_seens[i][j]) + if (map->grids_seens[j*map->w+i]) { - display_map_quad(&cur_tex, &vert_idx, &col_idx, map, dx, dy, z, mo, i, j, map->shown_a, map->grids_seens[i][j], nb_keyframes); + display_map_quad(&cur_tex, &vert_idx, &col_idx, map, dx, dy, z, mo, i, j, map->shown_a, map->grids_seens[j*map->w+i], nb_keyframes, always_show); } else { - display_map_quad(&cur_tex, &vert_idx, &col_idx, map, dx, dy, z, mo, i, j, map->obscure_a, 0, nb_keyframes); + display_map_quad(&cur_tex, &vert_idx, &col_idx, map, dx, dy, z, mo, i, j, map->obscure_a, 0, nb_keyframes, always_show); } } } @@ -1039,9 +1146,9 @@ static int minimap_to_screen(lua_State *L) map_object *mo = map->grids[i][j][z]; if (!mo || mo->mm_r < 0) continue; - if ((mo->on_seen && map->grids_seens[i][j]) || (mo->on_remember && map->grids_remembers[i][j]) || mo->on_unknown) + if ((mo->on_seen && map->grids_seens[j*map->w+i]) || (mo->on_remember && map->grids_remembers[i][j]) || mo->on_unknown) { - if (map->grids_seens[i][j]) + if (map->grids_seens[j*map->w+i]) { r = mo->mm_r; g = mo->mm_g; b = mo->mm_b; a = transp; colors[col_idx] = r; colors[col_idx+1] = g; colors[col_idx+2] = b; colors[col_idx+3] = (a); @@ -1097,6 +1204,8 @@ static const struct luaL_reg map_reg[] = { {"__gc", map_free}, {"close", map_free}, + {"updateSeensTexture", map_update_seen_texture}, + {"bindSeensTexture", map_bind_seen_texture}, {"setZoom", map_set_zoom}, {"setShown", map_set_shown}, {"setObscure", map_set_obscure}, @@ -1107,6 +1216,7 @@ static const struct luaL_reg map_reg[] = {"setSeen", map_set_seen}, {"setRemember", map_set_remember}, {"setLite", map_set_lite}, + {"getSeensInfo", map_get_seensinfo}, {"setScroll", map_set_scroll}, {"getScroll", map_get_scroll}, {"toScreen", map_to_screen}, diff --git a/src/map.h b/src/map.h index 08125680af762a93e6d880cad3d886498100f6f5..a885e8fb1274ee2be7b0717b6c93f2efac000e23 100644 --- a/src/map.h +++ b/src/map.h @@ -50,7 +50,7 @@ typedef struct { typedef struct { map_object* ***grids; - float **grids_seens; + float *grids_seens; bool **grids_remembers; bool **grids_lites; unsigned char **minimap; @@ -58,6 +58,9 @@ typedef struct { GLfloat *vertices; GLfloat *colors; GLfloat *texcoords; + GLubyte *seens_map; + + GLuint seens_texture; int mo_list_ref; @@ -78,6 +81,9 @@ typedef struct { int mx, my, mwidth, mheight; float oldmx, oldmy; int move_step, move_max; + float used_mx, used_my; + int seensinfo_w; + int seensinfo_h; } map_type; #endif