From 4df7063152c9a52e798350f5c80309b39f5b2d3c Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Thu, 26 Nov 2009 00:01:44 +0000
Subject: [PATCH] scrolling

git-svn-id: http://svn.net-core.org/repos/t-engine4@43 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/Map.lua                           | 23 +++++++++++-----
 game/engine/Mouse.lua                         |  3 +++
 game/engine/Target.lua                        |  6 ++---
 game/modules/tome/class/Game.lua              | 26 +++++++++++++++++--
 game/modules/tome/class/Player.lua            |  5 +++-
 .../tome/data/zones/ancient_ruins/zone.lua    |  4 +--
 src/main.c                                    | 22 ++++++++++++++++
 7 files changed, 74 insertions(+), 15 deletions(-)

diff --git a/game/engine/Map.lua b/game/engine/Map.lua
index ae06e00d6b..252997662b 100644
--- a/game/engine/Map.lua
+++ b/game/engine/Map.lua
@@ -26,7 +26,7 @@ rememberDisplayOrder = { TERRAIN }
 -- @param tile_h height of a single tile
 function _M:setViewPort(x, y, w, h, tile_w, tile_h)
 	self.display_x, self.display_y = x, y
-	self.viewport = {width=w, height=h}
+	self.viewport = {width=w, height=h, mwidth=math.floor(w/tile_w), mheight=math.floor(h/tile_h)}
 	self.tiles = Tiles.new(tile_w, tile_h)
 	self.tile_w, self.tile_h = tile_w, tile_h
 end
@@ -46,6 +46,8 @@ end
 -- @param x screen coordonate where the map will be displayed (this has no impact on the real display). This is used to compute mouse clicks
 -- @param y screen coordonate where the map will be displayed (this has no impact on the real display). This is used to compute mouse clicks
 function _M:init(w, h)
+	self.mx = 0
+	self.my = 0
 	self.w, self.h = w, h
 	self.map = {}
 	self.lites = {}
@@ -154,7 +156,8 @@ function _M:display()
 		local z
 		local order
 		local friend
-		for i = 0, self.w - 1 do for j = 0, self.h - 1 do
+		for i = self.mx, self.mx + self.viewport.mwidth - 1 do
+		for j = self.my, self.my + self.viewport.mheight - 1 do
 			e, si = nil, 1
 			z = i + j * self.w
 			order = displayOrder
@@ -163,19 +166,19 @@ function _M:display()
 				while not e and si <= #order do e = self(i, j, order[si]) si = si + 1 end
 				if e then
 					if self.seens[z] then
-						self.surface:merge(self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image), i * self.tile_w, j * self.tile_h)
+						self.surface:merge(self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 					elseif self.remembers[z] then
-						self.surface:merge(self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image), i * self.tile_w, j * self.tile_h)
+						self.surface:merge(self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 					end
 					-- Tactical overlay ?
 					if self.view_faction and e.faction then
 						friend = Faction:factionReaction(self.view_faction, e.faction)
 						if friend > 0 then
-							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_friend), i * self.tile_w, j * self.tile_h)
+							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_friend), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 						elseif friend < 0 then
-							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_enemy), i * self.tile_w, j * self.tile_h)
+							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_enemy), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 						else
-							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_neutral), i * self.tile_w, j * self.tile_h)
+							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_neutral), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h)
 						end
 					end
 				end
@@ -262,3 +265,9 @@ function _M:rememberAll(x, y, w, h)
 	end end
 end
 
+--- Sets the current view area with the given coords at the center
+function _M:centerViewAround(x, y)
+	self.mx = x - math.floor(self.viewport.mwidth / 2)
+	self.my = y - math.floor(self.viewport.mheight / 2)
+	self.changed = true
+end
diff --git a/game/engine/Mouse.lua b/game/engine/Mouse.lua
index d0b67249d0..eb5779811f 100644
--- a/game/engine/Mouse.lua
+++ b/game/engine/Mouse.lua
@@ -20,6 +20,9 @@ function _M:receiveMouse(button, x, y)
 	end
 end
 
+function _M:receiveMouseMotion(button, x, y, xrel, yrel)
+end
+
 --- Setups as the current game keyhandler
 function _M:setCurrent()
 	core.mouse.set_current_handler(self)
diff --git a/game/engine/Target.lua b/game/engine/Target.lua
index 4d09264622..63854dcb95 100644
--- a/game/engine/Target.lua
+++ b/game/engine/Target.lua
@@ -42,10 +42,10 @@ function _M:display()
 	local lx, ly = l()
 	while lx and ly do
 		if not game.level.map.seens(lx, ly) then s = self.sr end
-		s:toScreen(self.display_x + lx * self.tile_w, self.display_y + ly * self.tile_h)
+		s:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w, self.display_y + (ly - game.level.map.my) * self.tile_h)
 		lx, ly = l()
 	end
-	self.cursor:toScreen(self.display_x + self.target.x * self.tile_w, self.display_y + self.target.y * self.tile_h)
+	self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w, self.display_y + (self.target.y - game.level.map.my) * self.tile_h)
 end
 
 function _M:setActive(v)
@@ -71,7 +71,7 @@ function _M:scan(dir, radius)
 
 	if dir ~= 5 then
 		-- Get a list of actors in the direction given
-		core.fov.calc_beam(self.target.x, self.target.y, radius, dir, 45, checker, function()end, self)
+		core.fov.calc_beam(self.target.x, self.target.y, radius, dir, 55, checker, function()end, self)
 	else
 		-- Get a list of actors all around
 		core.fov.calc_circle(self.target.x, self.target.y, radius, checker, function()end, self)
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 25b58be804..3b98e5e7cb 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -79,12 +79,12 @@ function _M:display()
 		end
 		self.level.map:display():toScreen(self.level.map.display_x, self.level.map.display_y)
 
-		-- DIsplay the targetting system if active
+		-- Display the targetting system if active
 		self.target:display()
 
 		-- Display a tooltip if available
 		local mx, my = core.mouse.get()
-		local tmx, tmy = math.floor(mx / self.level.map.tile_w), math.floor(my / self.level.map.tile_h)
+		local tmx, tmy = math.floor(mx / self.level.map.tile_w) + self.level.map.mx, math.floor(my / self.level.map.tile_h) + self.level.map.my
 		local tt = self.level.map:checkAllEntities(tmx, tmy, "tooltip")
 		if tt and self.level.map.seens(tmx, tmy) then
 			self.tooltip:set(tt)
@@ -246,6 +246,28 @@ function _M:setupMouse()
 		if button == "wheelup" then self.log:scrollUp(1) end
 		if button == "wheeldown" then self.log:scrollUp(-1) end
 	end)
+
+	local derivx, derivy = 0, 0
+	self.mouse.receiveMouseMotion = function(self, button, x, y, xrel, yrel)
+		if button ~= "left" then return end
+		derivx = derivx + xrel
+		derivy = derivy + yrel
+		game.level.map.changed = true
+		if derivx >= game.level.map.tile_w then
+			game.level.map.mx = game.level.map.mx - 1
+			derivx = derivx - game.level.map.tile_w
+		elseif derivx <= -game.level.map.tile_w then
+			game.level.map.mx = game.level.map.mx + 1
+			derivx = derivx + game.level.map.tile_w
+		end
+		if derivy >= game.level.map.tile_h then
+			game.level.map.my = game.level.map.my - 1
+			derivy = derivy - game.level.map.tile_h
+		elseif derivy <= -game.level.map.tile_h then
+			game.level.map.my = game.level.map.my + 1
+			derivy = derivy + game.level.map.tile_h
+		end
+	end
 end
 
 --- Ask if we realy want to close, if so, save the game first
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index b1fc8c6246..5b246ddfba 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -7,11 +7,14 @@ function _M:init(t)
 	mod.class.Actor.init(self, t)
 	self.player = true
 	self.faction = "players"
-	self.combat = { dam=10, atk=4, apr=2, def=6, armor=4 }
+	self.combat = { dam=10, atk=40, apr=2, def=6, armor=4 }
 end
 
 function _M:move(x, y, force)
 	local moved = mod.class.Actor.move(self, x, y, force)
+	if moved then
+		game.level.map:centerViewAround(self.x, self.y)
+	end
 	return moved
 end
 
diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua
index 716a0e70c5..cd20151559 100644
--- a/game/modules/tome/data/zones/ancient_ruins/zone.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua
@@ -1,7 +1,7 @@
 return {
 	name = "ancient ruins",
 	max_level = 5,
-	width = 50, height = 30,
+	width = 100, height = 100,
 	all_remembered = true,
 	all_lited = true,
 	level_npcs = {5, 10},
@@ -16,7 +16,7 @@ return {
 		},
 		actor = {
 			class = "engine.generator.actor.Random",
-			nb_npc = {10, 20},
+			nb_npc = {200, 200},
 		},
 	}
 }
diff --git a/src/main.c b/src/main.c
index 8b68823a3c..70990a2eef 100644
--- a/src/main.c
+++ b/src/main.c
@@ -152,6 +152,27 @@ void on_event(SDL_Event *event)
 			docall(L, 4, 0);
 		}
 		break;
+	case SDL_MOUSEMOTION:
+		if (current_mousehandler != LUA_NOREF)
+		{
+			lua_rawgeti(L, LUA_REGISTRYINDEX, current_mousehandler);
+			lua_pushstring(L, "receiveMouseMotion");
+			lua_gettable(L, -2);
+			lua_remove(L, -2);
+			lua_rawgeti(L, LUA_REGISTRYINDEX, current_mousehandler);
+			if (event->motion.state & SDL_BUTTON(1)) lua_pushstring(L, "left");
+			else if (event->motion.state & SDL_BUTTON(2)) lua_pushstring(L, "middle");
+			else if (event->motion.state & SDL_BUTTON(3)) lua_pushstring(L, "right");
+			else if (event->motion.state & SDL_BUTTON(4)) lua_pushstring(L, "wheelup");
+			else if (event->motion.state & SDL_BUTTON(5)) lua_pushstring(L, "wheeldown");
+			else lua_pushstring(L, "none");
+			lua_pushnumber(L, event->motion.x);
+			lua_pushnumber(L, event->motion.y);
+			lua_pushnumber(L, event->motion.xrel);
+			lua_pushnumber(L, event->motion.yrel);
+			docall(L, 6, 0);
+		}
+		break;
 	}
 }
 
@@ -261,6 +282,7 @@ int main(int argc, char *argv[])
 		{
 			switch(event.type)
 			{
+			case SDL_MOUSEMOTION:
 			case SDL_MOUSEBUTTONDOWN:
 			case SDL_KEYDOWN:
 				/* handle key presses */
-- 
GitLab