summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--data/test.lua15
-rw-r--r--src/game-server/map.cpp13
-rw-r--r--src/game-server/movingobject.cpp15
-rw-r--r--src/game-server/object.hpp3
-rw-r--r--src/scripting/lua.cpp31
6 files changed, 79 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 0cdcb751..77ea9585 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-03-15 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/game-server/map.cpp, src/game-server/movingobject.hpp,
+ src/game-server/object.hpp: Fixed a crash caused by the new blocking
+ system (thanks to peavey for reporting).
+ * src/scripting/lua.cpp: Implemented script binding for controllig
+ movement of beings.
+ * data/test.lua: Implemented NPC which moves around when talked to.
+
2008-03-13 Philipp Sehmisch <tmw@crushnet.org>
* src/game-server/being.cpp, src/game-server/character.cpp,
diff --git a/data/test.lua b/data/test.lua
index 556ce33d..d4a161d1 100644
--- a/data/test.lua
+++ b/data/test.lua
@@ -6,6 +6,7 @@ atinit(function()
create_npc(110, 50 * 32 + 16, 19 * 32 + 16, my_npc1)
create_npc(108, 51 * 32 + 16, 25 * 32 + 16, my_npc4)
create_npc(126, 45 * 32 + 16, 25 * 32 + 16, my_npc5)
+ create_npc(122, 58 * 32 + 16, 15 * 32 + 16, my_npc6)
end)
function my_npc1(npc, ch)
@@ -73,4 +74,18 @@ function my_npc5(npc, ch)
tmw.monster_create(1012, 46 * 32 + 16, 24 * 32 + 16)
tmw.monster_create(1012, 46 * 32 + 16, 26 * 32 + 16)
end
+end
+
+
+local guard_position = 1
+
+function my_npc6(npc, ch)
+
+ if guard_position == 1 then
+ tmw.being_walk(npc, 61 * 32 + 16, 15 * 32 + 16, 400)
+ guard_position = 2
+ else
+ tmw.being_walk(npc, 55 * 32 + 16, 15 * 32 + 16, 400)
+ guard_position = 1
+ end
end \ No newline at end of file
diff --git a/src/game-server/map.cpp b/src/game-server/map.cpp
index c4f2c02e..ceb48b04 100644
--- a/src/game-server/map.cpp
+++ b/src/game-server/map.cpp
@@ -98,9 +98,12 @@ Map::setSize(int width, int height)
void Map::blockTile(int x, int y, BlockType type)
{
- if (type == BLOCKTYPE_NONE) return;
+ if (type == BLOCKTYPE_NONE || x < 0 || y < 0 || x >= mWidth || y >= mHeight)
+ {
+ return;
+ }
+
int tileNum = x + y * mWidth;
- assert (tileNum <= mWidth * mHeight);
if (++mOccupation[type][tileNum])
{
@@ -124,10 +127,12 @@ void Map::blockTile(int x, int y, BlockType type)
void Map::freeTile(int x, int y, BlockType type)
{
- if (type == BLOCKTYPE_NONE) return;
+ if (type == BLOCKTYPE_NONE || x < 0 || y < 0 || x >= mWidth || y >= mHeight)
+ {
+ return;
+ }
int tileNum = x + y * mWidth;
- assert (tileNum <= mWidth * mHeight);
if (!(--mOccupation[type][tileNum]))
{
diff --git a/src/game-server/movingobject.cpp b/src/game-server/movingobject.cpp
index f7db2d93..70334341 100644
--- a/src/game-server/movingobject.cpp
+++ b/src/game-server/movingobject.cpp
@@ -20,6 +20,8 @@
* $Id$
*/
+#include <cassert>
+
#include "game-server/map.hpp"
#include "game-server/mapcomposite.hpp"
#include "game-server/movingobject.hpp"
@@ -43,14 +45,22 @@ void MovingObject::setPosition(const Point &p)
void MovingObject::setMap(MapComposite *map)
{
- Point p = getPosition();
+ assert (map);
MapComposite *oldMap = getMap();
+ Point p = getPosition();
+
if (oldMap)
{
oldMap->getMap()->freeTile(p.x / 32, p.y / 32, getBlockType());
}
- map->getMap()->blockTile(p.x / 32, p.y / 32, getBlockType());
Object::setMap(map);
+ map->getMap()->blockTile(p.x / 32, p.y / 32, getBlockType());
+ /* the last line might look illogical because the current position is
+ * invalid on the new map, but it is necessary to block the old position
+ * because the next call of setPosition() will automatically free the old
+ * position. When we don't block the position now the occupation counting
+ * will be off.
+ */
}
void MovingObject::setDestination(Point const &dst)
@@ -63,6 +73,7 @@ void MovingObject::setDestination(Point const &dst)
void MovingObject::move()
{
mOld = getPosition();
+
if (mActionTime > 100)
{
// Current move has not yet ended
diff --git a/src/game-server/object.hpp b/src/game-server/object.hpp
index f50dff4d..92980d02 100644
--- a/src/game-server/object.hpp
+++ b/src/game-server/object.hpp
@@ -51,7 +51,8 @@ class Object : public Thing
*/
Object(int type)
: Thing(type),
- mUpdateFlags(0)
+ mUpdateFlags(0),
+ mPos(Point(0, 0))
{}
/**
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index a5de9917..7437af83 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -106,6 +106,13 @@ static Character *getCharacter(lua_State *s, int p)
return static_cast<Character *>(t);
}
+static Being *getBeing(lua_State *s, int p)
+{
+ if (!lua_islightuserdata(s, p)) return NULL;
+ Thing *t = static_cast<Thing *>(lua_touserdata(s, p));
+ return static_cast<Being *>(t);
+}
+
/**
* Callback for sending a NPC_MESSAGE.
* tmw.npc_message(npc, character, string)
@@ -370,6 +377,29 @@ static int LuaNpc_Trade(lua_State *s)
}
/**
+ * Function for making a being walk to a position
+ * being_walk(Being *being, int x, int y, int speed)
+ */
+static int LuaBeing_Walk(lua_State *s)
+{
+ if (!lua_isnumber(s, 2) || !lua_isnumber(s, 3) || !lua_isnumber(s, 4))
+ {
+ LOG_WARN("LuaBeing_walk called with incorrect parameters.");
+ return 0;
+ }
+
+ lua_pushlightuserdata(s, (void *)&registryKey);
+ lua_gettable(s, LUA_REGISTRYINDEX);
+
+ Being *being = getBeing(s, 1);
+ Point destination(lua_tointeger(s, 2), lua_tointeger(s, 3));
+ being->setDestination(destination);
+ being->setSpeed(lua_tointeger(s, 4));
+
+ return 0;
+}
+
+/**
* Callback for creating a monster on the current map.
* tmw.monster_create(int type, int x, int y)
*/
@@ -493,6 +523,7 @@ LuaScript::LuaScript():
{ "chr_get_quest", &LuaChr_GetQuest },
{ "chr_set_quest", &LuaChr_SetQuest },
{ "monster_create", &LuaMonster_Create },
+ { "being_walk", &LuaBeing_Walk },
{ NULL, NULL }
};
luaL_register(mState, "tmw", callbacks);