diff --git a/game/engines/default/engine/Astar.lua b/game/engines/default/engine/Astar.lua index b1b2523d97732db1f350f661357720dd232323a3..e6587411071f3fcdc53836a8481f9c09f2073af9 100644 --- a/game/engines/default/engine/Astar.lua +++ b/game/engines/default/engine/Astar.lua @@ -126,8 +126,10 @@ function _M:calc(sx, sy, tx, ty, use_has_seen, heuristic) while next(open) do -- Find lowest of f_score local node, lowest = nil, 999999999999999 - for n, _ in pairs(open) do + local n, _ = next(open) + while n do if f_score[n] < lowest then node = n; lowest = f_score[n] end + n, _ = next(open, n) end if node == stop then return self:createPath(came_from, stop) end diff --git a/game/modules/tome/ai/worldnpcs.lua b/game/modules/tome/ai/worldnpcs.lua index 18eceebad8a80b3648ecc21e072519da1a4fa4c7..9710a80e2ce88011a1d8d8f2a88a10831de5df07 100644 --- a/game/modules/tome/ai/worldnpcs.lua +++ b/game/modules/tome/ai/worldnpcs.lua @@ -61,18 +61,19 @@ end) newAI("move_world_patrol", function(self) if not self.ai_state.route then self.ai_state.route = game.level:pickSpot{type="patrol", subtype=self.ai_state.route_kind} - else - local tx, ty = self.ai_state.route.x, self.ai_state.route.y local a = Astar.new(game.level.map, self) + self.ai_state.route_path = a:calc(self.x, self.y, self.ai_state.route.x, self.ai_state.route.y) +-- print(self.name, "Selecting route!", self.ai_state.route_path, "from", self.x, self.y, "to", self.ai_state.route.x, self.ai_state.route.y) + else local path = self.ai_state.route_path - if not path then path = a:calc(self.x, self.y, tx, ty) end - if not path then +-- print("Using route", self.ai_state.route_path) + if not path or not path[1] or (path[1] and math.floor(core.fov.distance(self.x, self.y, path[1].x, path[1].y)) > 1) then self.ai_state.route_path = nil self.ai_state.route = nil +-- print("Nulling!", path, path and path[1], path and path[1] and math.floor(core.fov.distance(self.x, self.y, path[1].x, path[1].y))) return true else local ret = self:move(path[1].x, path[1].y) table.remove(path, 1) - if #path == 0 then self.ai_state.route_path = nil self.ai_state.route = nil end return ret end end diff --git a/game/modules/tome/data/general/encounters/fareast-npcs.lua b/game/modules/tome/data/general/encounters/fareast-npcs.lua new file mode 100644 index 0000000000000000000000000000000000000000..4a4eafd56c4fe48a30e2815538e98871e6f1c8f2 --- /dev/null +++ b/game/modules/tome/data/general/encounters/fareast-npcs.lua @@ -0,0 +1,93 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +class = require("mod.class.WorldNPC") + +newEntity{ + name = "Sun Paladins patrol", + type = "patrol", subtype = "sunwall", + display = 'p', color = colors.GOLD, + faction = "sunwall", + level_range = {1, nil}, + sight = 4, + rarity = 3, + unit_power = 10, + ai = "world_patrol", ai_state = {route_kind="sunwall"}, +} + +newEntity{ + name = "Anorithil patrol", + type = "patrol", subtype = "allied kingdoms", + display = 'p', color = colors.YELLOW, + faction = "sunwall", + level_range = {1, nil}, + sight = 4, + rarity = 3, + unit_power = 10, + ai = "world_patrol", ai_state = {route_kind="sunwall"}, +} + +newEntity{ + name = "Orcs patrol", + type = "patrol", subtype = "orc pride", + display = 'o', color = colors.GREY, + faction = "orc-pride", + level_range = {1, nil}, + sight = 4, + rarity = 3, + unit_power = 8, + ai = "world_patrol", ai_state = {route_kind="orc-pride"}, + on_encounter = {type="ambush", width=14, height=14, nb={7,12}, filters={{type="humanoid", subtype="orc"}}}, +} + +newEntity{ + name = "lone bear", + type = "hostile", subtype = "animal", + display = 'q', color = colors.UMBER, + level_range = {1, nil}, + sight = 3, + rarity = 4, + unit_power = 1, + ai = "world_hostile", ai_state = {chase_distance=3}, + on_encounter = {type="ambush", width=10, height=10, nb={1,1}, filters={{type="animal", subtype="bear"}}}, +} + +newEntity{ + name = "pack of wolves", + type = "hostile", subtype = "animal", + display = 'c', color = colors.RED, image="npc/canine_w.png", + level_range = {1, nil}, + sight = 3, + rarity = 4, + unit_power = 1, + ai = "world_hostile", ai_state = {chase_distance=3}, + on_encounter = {type="ambush", width=10, height=10, nb={3,5}, filters={{type="animal", subtype="canine"}}}, +} + +newEntity{ + name = "dragon", + type = "hostile", subtype = "dragon", + display = 'D', color = colors.RED, + level_range = {12, nil}, + sight = 3, + rarity = 12, + unit_power = 7, + ai = "world_hostile", ai_state = {chase_distance=3}, + on_encounter = {type="ambush", width=10, height=10, nb={1,1}, filters={{type="dragon"}}}, +} diff --git a/game/modules/tome/data/general/encounters/fareast.lua b/game/modules/tome/data/general/encounters/fareast.lua index 2cd8bfa58675442e4d8194e4e736bd2564d22e25..54c21398fb3eb626059a38f06ff126a97d0a151c 100644 --- a/game/modules/tome/data/general/encounters/fareast.lua +++ b/game/modules/tome/data/general/encounters/fareast.lua @@ -79,71 +79,3 @@ newEntity{ return true end, } ----------------------------- Hostiles ----------------------------- - --- Ambushed! --- We construct a temporary zone on the fly -newEntity{ - name = "Orcs", - type = "hostile", subtype = "ambush", - level_range = {1, 50}, - rarity = 8, - coords = {{ x=0, y=0, w=100, h=100}}, - special_filter = function(self) - return game.player:reactionToward{faction="orc-pride"} < 0 and true or false - end, - on_encounter = function(self, who) - local gen = { class = "engine.generator.map.Forest", - edge_entrances = {4,6}, - sqrt_percent = 50, - zoom = 10, - floor = "GRASS", - wall = "TREE", - up = "UP", - down = "DOWN", - up = "UP_WILDERNESS_FAR_EAST", - } - local g = game.level.map(who.x, who.y, engine.Map.TERRAIN) - if not g.can_encounter then return false end - - if g.can_encounter == "desert" then gen.floor = "SAND" gen.wall = "PALMTREE" end - - local zone = engine.Zone.new("ambush", { - name = "Ambush!", - level_range = {20, 50}, - level_scheme = "player", - max_level = 1, - actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end, - width = 20, height = 20, - all_lited = true, - ambiant_music = "last", - generator = { - map = gen, - actor = { class = "engine.generator.actor.Random",nb_npc = {5, 7}, }, - trap = { class = "engine.generator.trap.Random", nb_trap = {0, 0}, }, - }, - - npc_list = mod.class.NPC:loadList("/data/general/npcs/orc.lua", nil, nil, function(e) e.make_escort=nil end), - grid_list = mod.class.Grid:loadList{"/data/general/grids/basic.lua", "/data/general/grids/forest.lua", "/data/general/grids/sand.lua"}, - object_list = mod.class.Object:loadList("/data/general/objects/objects.lua"), - trap_list = {}, - post_process = function(level) - -- Find a good starting location, on the opposite side of the exit - local sx, sy = level.map.w-1, rng.range(0, level.map.h-1) - level.spots[#level.spots+1] = { - check_connectivity = "entrance", - x = sx, - y = sy, - } - level.default_down = level.default_up - level.default_up = {x=sx, y=sy} - end, - }) - game.player:runStop() - game.player.energy.value = game.energy_to_act - game.paused = true - game:changeLevel(1, zone) - engine.ui.Dialog:simplePopup("Ambush!", "You have been ambushed by a patrol of orcs!") - return true - end, -} diff --git a/game/modules/tome/data/maps/wilderness/eyal.lua b/game/modules/tome/data/maps/wilderness/eyal.lua index f1fa099ad99835c522256a0f8a0381ecc3d16338..bcccf2cae1741ebac04fec2651ee9f0721e485f0 100644 --- a/game/modules/tome/data/maps/wilderness/eyal.lua +++ b/game/modules/tome/data/maps/wilderness/eyal.lua @@ -77,6 +77,7 @@ end prepareEntitiesList("maj_eyal_encounters", "mod.class.Encounter", "/data/general/encounters/maj-eyal.lua") prepareEntitiesList("maj_eyal_encounters_npcs", "mod.class.WorldNPC", "/data/general/encounters/maj-eyal-npcs.lua") prepareEntitiesList("fareast_encounters", "mod.class.Encounter", "/data/general/encounters/fareast.lua") +prepareEntitiesList("fareast_encounters_npcs", "mod.class.WorldNPC", "/data/general/encounters/fareast-npcs.lua") addData{ wda = { script="eyal", zones={} }, } @@ -88,22 +89,22 @@ addSpot({17, 39}, "patrol", "allied-kingdoms") addSpot({41, 18}, "patrol", "allied-kingdoms") addSpot({65, 11}, "patrol", "allied-kingdoms") addSpot({60, 38}, "patrol", "allied-kingdoms") -addSpot({25, 26}, "hostile", "random") -addSpot({26, 26}, "hostile", "random") -addSpot({25, 27}, "hostile", "random") -addSpot({26, 27}, "hostile", "random") -addSpot({56, 13}, "hostile", "random") -addSpot({57, 13}, "hostile", "random") -addSpot({56, 14}, "hostile", "random") -addSpot({57, 14}, "hostile", "random") -addSpot({45, 43}, "hostile", "random") -addSpot({46, 43}, "hostile", "random") -addSpot({45, 44}, "hostile", "random") -addSpot({46, 44}, "hostile", "random") -addSpot({7, 25}, "hostile", "random") -addSpot({8, 25}, "hostile", "random") -addSpot({7, 26}, "hostile", "random") -addSpot({8, 26}, "hostile", "random") +addSpot({25, 26}, "hostile", "maj-eyal") +addSpot({26, 26}, "hostile", "maj-eyal") +addSpot({25, 27}, "hostile", "maj-eyal") +addSpot({26, 27}, "hostile", "maj-eyal") +addSpot({56, 13}, "hostile", "maj-eyal") +addSpot({57, 13}, "hostile", "maj-eyal") +addSpot({56, 14}, "hostile", "maj-eyal") +addSpot({57, 14}, "hostile", "maj-eyal") +addSpot({45, 43}, "hostile", "maj-eyal") +addSpot({46, 43}, "hostile", "maj-eyal") +addSpot({45, 44}, "hostile", "maj-eyal") +addSpot({46, 44}, "hostile", "maj-eyal") +addSpot({7, 25}, "hostile", "maj-eyal") +addSpot({8, 25}, "hostile", "maj-eyal") +addSpot({7, 26}, "hostile", "maj-eyal") +addSpot({8, 26}, "hostile", "maj-eyal") addSpot({69, 22}, "zone-pop", "reknor") addSpot({155, 47}, "zone-pop", "eruan") addSpot({150, 55}, "zone-pop", "valley-moon-caverns") @@ -126,6 +127,16 @@ addSpot({162, 31}, "farportal-end", "gates-of-morning") addSpot({59, 39}, "farportal-end", "last-hope") addSpot({68, 22}, "farportal-end", "iron-throne") addSpot({59, 13}, "farportal-end", "demon-plane-arrival") +addSpot({162, 32}, "patrol", "sunwall") +addSpot({164, 42}, "patrol", "sunwall") +addSpot({163, 18}, "patrol", "sunwall") +addSpot({151, 30}, "patrol", "sunwall") +addSpot({141, 51}, "patrol", "orc-pride") +addSpot({147, 53}, "patrol", "orc-pride") +addSpot({163, 48}, "patrol", "orc-pride") +addSpot({167, 9}, "patrol", "orc-pride") +addSpot({155, 17}, "patrol", "orc-pride") +addSpot({132, 9}, "patrol", "orc-pride") -- addZone section addZone({1, 1, 78, 46}, "zonename", "Maj'Eyal") diff --git a/game/modules/tome/data/texts/intro-ghoul.lua b/game/modules/tome/data/texts/intro-ghoul.lua index b2746a3b1a6411486ebda307ea360876c7cc60d8..d1f010ae8b7723aec4b0e7ef8baf47fbc36c81d0 100644 --- a/game/modules/tome/data/texts/intro-ghoul.lua +++ b/game/modules/tome/data/texts/intro-ghoul.lua @@ -23,5 +23,5 @@ You have died ages ago, but that did not stop you, you were raised as an undead Your necromancer master has plans for you, but something is wrong, you seem to have kept your free will. Get rid of this evil mage and try to find a place in the world. -You has been raised in a place called the Blighted Scar, on the northern border of the Shaloren lands. Leave this forsaken place and try your luck in old forgotten places. +You have been raised in a place called the Blighted Scar, on the northern border of the Shaloren lands. Leave this forsaken place and try your luck in old forgotten places. ]] diff --git a/game/modules/tome/data/texts/intro-skeleton.lua b/game/modules/tome/data/texts/intro-skeleton.lua index eaabc781f19b8d1a73fe7ce18fa814cfbbd0ca0d..fe3f8b1d651cf7c3becbec567ff4ab308d089823 100644 --- a/game/modules/tome/data/texts/intro-skeleton.lua +++ b/game/modules/tome/data/texts/intro-skeleton.lua @@ -23,5 +23,5 @@ You have died ages ago, but that did not stop you, you were raised as an undead Your necromancer master has plans for you, but something is wrong, you seem to have kept your free will. Get rid of this evil mage and try to find a place in the world. -You has been raised in a place called the Blighted Scar, on the northern border of the Shaloren lands. Leave this forsaken place and try your luck in old forgotten places. +You have been raised in a place called the Blighted Scar, on the northern border of the Shaloren lands. Leave this forsaken place and try your luck in old forgotten places. ]] diff --git a/game/modules/tome/data/wda/eyal.lua b/game/modules/tome/data/wda/eyal.lua index c4620ed00b61412efbd13ab75124d862d6a19e6a..0b9450c78c7cb350dd291a074fba0049922a9e41 100644 --- a/game/modules/tome/data/wda/eyal.lua +++ b/game/modules/tome/data/wda/eyal.lua @@ -41,6 +41,7 @@ end if zone == "Maj'Eyal" then wda.cur_patrols = wda.cur_patrols or 0 wda.cur_hostiles = wda.cur_hostiles or 0 + print("==== Maj'Eyal", wda.cur_patrols, wda.cur_hostiles) -- Spawn random encounters local g = game.level.map(game.player.x, game.player.y, Map.TERRAIN) @@ -59,9 +60,9 @@ if zone == "Maj'Eyal" then -- Spawn some patrols if wda.cur_patrols < 3 then - local e = game.zone:makeEntity(game.level, "maj_eyal_encounters_npcs", {type="patrol"}, nil, true) + local e = game.zone:makeEntity(game.level, "maj_eyal_encounters_npcs", {type="patrol", subtype="allied kingdoms"}, nil, true) if e then - local spot = game.level:pickSpot{type="patrol", "allied-kingdoms"} + local spot = game.level:pickSpot{type="patrol", subtype="allied-kingdoms"} if spot and not game.level.map(spot.x, spot.y, Map.ACTOR) and not game.level.map.seens(spot.x, spot.y) then print("Spawned allied kingdom patrol", spot.x, spot.y, e.name) game.zone:addEntity(game.level, e, "actor", spot.x, spot.y) @@ -74,9 +75,9 @@ if zone == "Maj'Eyal" then -- Spawn some hostiles if wda.cur_hostiles < 4 and rng.percent(5) then - local e = game.zone:makeEntity(game.level, "maj_eyal_encounters_npcs", {type="hostile"}, nil, true) + local e = game.zone:makeEntity(game.level, "maj_eyal_encounters_npcs", {type="hostile", subtype="maj eyal"}, nil, true) if e then - local spot = game.level:pickSpot{type="hostile", "random"} + local spot = game.level:pickSpot{type="hostile", subtype="maj-eyal"} if spot and not game.level.map(spot.x, spot.y, Map.ACTOR) and not game.level.map.seens(spot.x, spot.y) then print("Spawned hostile", spot.x, spot.y, e.name) game.zone:addEntity(game.level, e, "actor", spot.x, spot.y) @@ -92,32 +93,64 @@ if zone == "Maj'Eyal" then --------------------------------------------------------------------- elseif zone == "Far East" then wda.cur_patrols = wda.cur_patrols or 0 + wda.cur_orc_patrols = wda.cur_orc_patrols or 0 wda.cur_hostiles = wda.cur_hostiles or 0 + print("==== Fareast", wda.cur_patrols, wda.cur_orc_patrols, wda.cur_hostiles) + + -- Spawn random encounters + local g = game.level.map(game.player.x, game.player.y, Map.TERRAIN) + if g and g.can_encounter then + local type = encounter_chance(game.player) + if type then + game.level:setEntitiesList("fareast_encounters_rng", game.zone:computeRarities("fareast_encounters_rng", game.level:getEntitiesList("fareast_encounters"), game.level, nil)) + local e = game.zone:makeEntity(game.level, "fareast_encounters_rng", {type=type, mapx=game.player.x, mapy=game.player.y, nb_tries=10}) + if e then + if e:check("on_encounter", game.player) then + e:added() + end + end + end + end -- Spawn some patrols - if wda.cur_patrols < 3 then - local e = game.zone:makeEntity(game.level, "encounters_npcs", {type="patrol"}, nil, true) + if wda.cur_patrols < 2 then + local e = game.zone:makeEntity(game.level, "fareast_encounters_npcs", {type="patrol", subtype="sunwall"}, nil, true) if e then - local spot = game.level:pickSpot{type="patrol", "sunwall"} + local spot = game.level:pickSpot{type="patrol", subtype="sunwall"} if spot and not game.level.map(spot.x, spot.y, Map.ACTOR) and not game.level.map.seens(spot.x, spot.y) then print("Spawned sunwall patrol", spot.x, spot.y, e.name) game.zone:addEntity(game.level, e, "actor", spot.x, spot.y) wda.cur_patrols = wda.cur_patrols + 1 - e.on_die = function() game.level.data.wda.cur_patrols = game.level.data.wda.cur_patrols - 1 end + e.world_zone = zone + e.on_die = function(self) game.level.data.wda.zones[self.world_zone].cur_patrols = game.level.data.wda.zones[self.world_zone].cur_patrols - 1 end + end + end + end + if wda.cur_orc_patrols < 4 then + local e = game.zone:makeEntity(game.level, "fareast_encounters_npcs", {type="patrol", subtype="orc pride"}, nil, true) + if e then + local spot = game.level:pickSpot{type="patrol", subtype="orc-pride"} + if spot and not game.level.map(spot.x, spot.y, Map.ACTOR) and not game.level.map.seens(spot.x, spot.y) then + print("Spawned sunwall patrol", spot.x, spot.y, e.name) + game.zone:addEntity(game.level, e, "actor", spot.x, spot.y) + wda.cur_orc_patrols = wda.cur_orc_patrols + 1 + e.world_zone = zone + e.on_die = function(self) game.level.data.wda.zones[self.world_zone].cur_orc_patrols = game.level.data.wda.zones[self.world_zone].cur_orc_patrols - 1 end end end end -- Spawn some hostiles if wda.cur_hostiles < 4 and rng.percent(5) then - local e = game.zone:makeEntity(game.level, "encounters_npcs", {type="hostile"}, nil, true) + local e = game.zone:makeEntity(game.level, "fareast_encounters_npcs", {type="hostile", subtype="fareast"}, nil, true) if e then - local spot = game.level:pickSpot{type="hostile", "random"} + local spot = game.level:pickSpot{type="hostile", subtype="fareast"} if spot and not game.level.map(spot.x, spot.y, Map.ACTOR) and not game.level.map.seens(spot.x, spot.y) then print("Spawned hostile", spot.x, spot.y, e.name) game.zone:addEntity(game.level, e, "actor", spot.x, spot.y) wda.cur_hostiles = wda.cur_hostiles + 1 - e.on_die = function() game.level.data.wda.cur_hostiles = game.level.data.wda.cur_hostiles - 1 end + e.world_zone = zone + e.on_die = function(self) game.level.data.wda.zones[self.world_zone].cur_hostiles = game.level.data.wda.zones[self.world_zone].cur_hostiles - 1 end end end end diff --git a/game/modules/tome/data/zones/wilderness/zone.lua b/game/modules/tome/data/zones/wilderness/zone.lua index f61f1e5f1ecbb910eaee4b84988049d6199597b1..d3e90a0e529193831b892791f40075c8dc51e0e2 100644 --- a/game/modules/tome/data/zones/wilderness/zone.lua +++ b/game/modules/tome/data/zones/wilderness/zone.lua @@ -24,12 +24,12 @@ return { level_range = {1, 1}, max_level = 1, width = 170, height = 100, --- all_remembered = true, --- all_lited = true, + all_remembered = true, + all_lited = true, persistant = "memory", ambiant_music = "Remembrance.ogg", wilderness = true, - wilderness_see_radius = 4, +-- wilderness_see_radius = 4, generator = { map = { class = "engine.generator.map.Static", diff --git a/tiled-maps/eyal.tmx b/tiled-maps/eyal.tmx index 28f7535ea889058c53397cddf04f5e334d8a59c0..90524da61ca1a58d2bf13c184885e8c51ceb6a75 100644 --- a/tiled-maps/eyal.tmx +++ b/tiled-maps/eyal.tmx @@ -247,25 +247,25 @@ </object> <object name="small hostiles" x="806" y="846" width="48" height="40"> <properties> - <property name="subtype" value=""random""/> + <property name="subtype" value=""maj-eyal""/> <property name="type" value=""hostile""/> </properties> </object> <object name="small hostiles" x="1799" y="425" width="46" height="42"> <properties> - <property name="subtype" value=""random""/> + <property name="subtype" value=""maj-eyal""/> <property name="type" value=""hostile""/> </properties> </object> <object name="small hostiles" x="1444" y="1385" width="50" height="48"> <properties> - <property name="subtype" value=""random""/> + <property name="subtype" value=""maj-eyal""/> <property name="type" value=""hostile""/> </properties> </object> <object name="small hostiles" x="226" y="813" width="52" height="44"> <properties> - <property name="subtype" value=""random""/> + <property name="subtype" value=""maj-eyal""/> <property name="type" value=""hostile""/> </properties> </object> @@ -425,6 +425,42 @@ <property name="type" value=""patrol""/> </properties> </object> + <object name="Orc pride patrol" x="4518" y="1636" width="26" height="24"> + <properties> + <property name="subtype" value=""orc-pride""/> + <property name="type" value=""patrol""/> + </properties> + </object> + <object name="Orc pride patrol" x="4708" y="1699" width="26" height="24"> + <properties> + <property name="subtype" value=""orc-pride""/> + <property name="type" value=""patrol""/> + </properties> + </object> + <object name="Orc pride patrol" x="5218" y="1538" width="26" height="24"> + <properties> + <property name="subtype" value=""orc-pride""/> + <property name="type" value=""patrol""/> + </properties> + </object> + <object name="Orc pride patrol" x="5347" y="293" width="26" height="24"> + <properties> + <property name="subtype" value=""orc-pride""/> + <property name="type" value=""patrol""/> + </properties> + </object> + <object name="Orc pride patrol" x="4963" y="548" width="26" height="24"> + <properties> + <property name="subtype" value=""orc-pride""/> + <property name="type" value=""patrol""/> + </properties> + </object> + <object name="Orc pride patrol" x="4227" y="292" width="26" height="24"> + <properties> + <property name="subtype" value=""orc-pride""/> + <property name="type" value=""patrol""/> + </properties> + </object> </objectgroup> <objectgroup name="addZone" width="170" height="100" visible="0"> <object name="Maj'Eyal" x="34" y="40" width="2488" height="1456">