summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--data/scripts/libtmw.lua16
-rw-r--r--data/test.lua23
-rw-r--r--src/game-server/being.hpp2
-rw-r--r--src/game-server/collisiondetection.cpp9
-rw-r--r--src/game-server/collisiondetection.hpp8
-rw-r--r--src/scripting/lua.cpp98
7 files changed, 148 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 2029655d..66cf172b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-05-22 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/game-server/being.hpp, src/game-server/collisiondetection.cpp,
+ src/game-server/collisiondetection.hpp, src/scripting/lua:cpp,
+ data/scripts/libtmw.lua: Implemented script bindings for getting beings
+ in a circular map area and damaging beings.
+ * data/test.lua: Scripted an NPC which damages all monsters and characters
+ which come close to it.
+
2008-05-22 Roderic Morris <roderic@ccs.neu.edu>
* src/utils/sha256.cpp, src/utils/encryption.cpp,
diff --git a/data/scripts/libtmw.lua b/data/scripts/libtmw.lua
index 681b4340..7125162c 100644
--- a/data/scripts/libtmw.lua
+++ b/data/scripts/libtmw.lua
@@ -14,6 +14,22 @@
-- Software Foundation; either version 2 of the License, or any later version. --
----------------------------------------------------------------------------------
+-- constant identifiers (is there some LUA way to make them real constants?)
+
+DAMAGE_PHYSICAL = 0
+DAMAGE_MAGICAL = 1
+DAMAGE_OTHER = 2
+
+ELEMENT_NEUTRAL = 0
+ELEMENT_FIRE = 1
+ELEMENT_WATER = 2
+ELEMENT_EARTH = 3
+ELEMENT_AIR = 4
+ELEMENT_LIGHTNING = 5
+ELEMENT_METAL = 6
+ELEMENT_WOOD = 7
+ELEMENT_ICE = 8
+
-- Table that associates to each NPC pointer the handler function that is
-- called when a player starts talking to an NPC.
diff --git a/data/test.lua b/data/test.lua
index 944413a7..e33f2de1 100644
--- a/data/test.lua
+++ b/data/test.lua
@@ -22,6 +22,7 @@ atinit(function()
create_npc("Teleporter", 201, 51 * 32 + 16, 25 * 32 + 16, npc4_talk, npclib.walkaround_wide)
create_npc("Spider Tamer", 126, 45 * 32 + 16, 25 * 32 + 16, npc5_talk, npclib.walkaround_map)
create_npc("Guard", 122, 58 * 32 + 16, 15 * 32 + 16, npc6_talk, npc6_update)
+ create_npc("Fire Demon", 202, 58 * 32 + 16, 35 * 32 + 16, firedemon_talk, firedemon_update)
tmw.trigger_create(56 * 32, 32 * 32, 64, 64, "patrol_waypoint", 1, true)
tmw.trigger_create(63 * 32, 32 * 32, 64, 64, "patrol_waypoint", 2, true)
@@ -135,3 +136,25 @@ function npc6_update(npc)
tmw.being_say(npc, "can't someone order me to walk to the other side of the gate?")
end
end
+
+
+function firedemon_talk(npc, ch)
+ do_message(npc, ch, "Burn, puny mortals! BURN! BUUUURN!!!")
+end
+
+local firedemon_timer = 0;
+
+function firedemon_update(npc)
+ firedemon_timer = firedemon_timer + 1
+ if (firedemon_timer == 5) then
+ firedemon_timer = 0
+ local victims = tmw.get_beings_in_circle(tmw.posX(npc), tmw.posY(npc), 64)
+ local i = 1;
+ while (victims[i]) do
+ tmw.being_damage(victims[i], 20, 10, 32000, DAMAGE_MAGICAL, ELEMENT_FIRE)
+ i = i + 1
+ end
+ end
+
+ npclib.walkaround_map(npc)
+end
diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp
index 6c7ff398..870fd78a 100644
--- a/src/game-server/being.hpp
+++ b/src/game-server/being.hpp
@@ -48,7 +48,7 @@ enum Direction
*/
enum
{
- DAMAGE_PHYSICAL,
+ DAMAGE_PHYSICAL = 0,
DAMAGE_MAGICAL,
DAMAGE_OTHER
};
diff --git a/src/game-server/collisiondetection.cpp b/src/game-server/collisiondetection.cpp
index 7f0817ca..110ef575 100644
--- a/src/game-server/collisiondetection.cpp
+++ b/src/game-server/collisiondetection.cpp
@@ -193,3 +193,12 @@ Collision::diskWithCircleSector(const Point &diskCenter, int diskRadius,
return false;
}
+bool
+Collision::CircleWithCircle(const Point &center1, int radius1,
+ const Point &center2, int radius2)
+{
+ int distx = center1.x - center2.x;
+ int disty = center1.y - center2.y;
+ double dist = sqrt((distx * distx) + (disty * disty));
+ return (dist < radius1 + radius2);
+}
diff --git a/src/game-server/collisiondetection.hpp b/src/game-server/collisiondetection.hpp
index 95c77d4b..f3b5afa1 100644
--- a/src/game-server/collisiondetection.hpp
+++ b/src/game-server/collisiondetection.hpp
@@ -47,6 +47,14 @@ namespace Collision
diskWithCircleSector(const Point &diskCenter, int diskRadius,
const Point &sectorCenter, int sectorRadius,
int halfTopAngle, int placeAngle);
+
+ /**
+ * Checks if two circles intersect.
+ */
+ bool
+ CircleWithCircle(const Point &center1, int radius1,
+ const Point &center2, int radius2);
+
}
#endif
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 9f160bca..622096eb 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -31,10 +31,12 @@ extern "C" {
#include "defines.h"
#include "game-server/buysell.hpp"
#include "game-server/character.hpp"
+#include "game-server/collisiondetection.hpp"
#include "game-server/gamehandler.hpp"
#include "game-server/inventory.hpp"
#include "game-server/item.hpp"
#include "game-server/itemmanager.hpp"
+#include "game-server/mapcomposite.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/monster.hpp"
#include "game-server/monstermanager.hpp"
@@ -441,6 +443,29 @@ static int LuaBeing_Say(lua_State *s)
return 0;
}
+
+/**
+ * Applies combat damage to a being
+ * tmw.being_damage(victim, value, delta, cth, type, element)
+ */
+static int LuaBeing_Damage(lua_State *s)
+{
+ Being *being = getBeing(s, 1);
+
+ Damage damage;
+ damage.base = lua_tointeger(s, 2);
+ damage.delta = lua_tointeger(s, 3);
+ damage.cth = lua_tointeger(s, 4);
+ damage.type = lua_tointeger(s, 5);
+ damage.element = lua_tointeger(s, 6);
+ damage.usedSkill = 0;
+
+ being->damage(NULL, damage);
+
+ return 0;
+}
+
+
/**
* Function for getting the x-coordinate of the position of a being
*/
@@ -656,6 +681,45 @@ static int LuaChatmessage(lua_State *s)
return 0;
}
+/**
+ * Gets a LUA table with the being IDs of all beings
+ * inside of a circular area of the current map.
+ * tmw.get_beings_in_circle (x, y, radius)
+ */
+static int LuaGetBeingsInCircle(lua_State *s)
+{
+ int x = lua_tointeger(s, 1);
+ int y = lua_tointeger(s, 2);
+ int r = lua_tointeger(s, 3);
+
+ lua_pushlightuserdata(s, (void *)&registryKey);
+ lua_gettable(s, LUA_REGISTRYINDEX);
+ Script *t = static_cast<Script *>(lua_touserdata(s, -1));
+ MapComposite *m = t->getMap();
+
+ //create a lua table with the beings in the given area.
+ lua_newtable(s);
+ int tableStackPosition = lua_gettop(s);
+ int tableIndex = 1;
+ for (MovingObjectIterator i(m->getAroundPointIterator(Point(x, y), r)); i; ++i)
+ {
+ char t = (*i)->getType();
+ if (t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER)
+ {
+ Being *b = static_cast<Being *> (*i);
+ if (Collision::CircleWithCircle(b->getPosition(), b->getSize(),
+ Point (x, y), r))
+ {
+ lua_pushinteger(s, tableIndex);
+ lua_pushlightuserdata (s, b);
+ lua_settable (s, tableStackPosition);
+ tableIndex++;
+ }
+ }
+ }
+
+ return 1;
+}
LuaScript::LuaScript():
nbArgs(-1)
@@ -665,22 +729,24 @@ LuaScript::LuaScript():
// Put some callback functions in the scripting environment.
static luaL_reg const callbacks[] = {
- { "npc_create", &LuaNpc_Create },
- { "npc_message", &LuaNpc_Message },
- { "npc_choice", &LuaNpc_Choice },
- { "npc_trade", &LuaNpc_Trade },
- { "chr_warp", &LuaChr_Warp },
- { "chr_inv_change", &LuaChr_InvChange },
- { "chr_inv_count", &LuaChr_InvCount },
- { "chr_get_quest", &LuaChr_GetQuest },
- { "chr_set_quest", &LuaChr_SetQuest },
- { "monster_create", &LuaMonster_Create },
- { "being_walk", &LuaBeing_Walk },
- { "being_say", &LuaBeing_Say },
- { "posX", &LuaPosX },
- { "posY", &LuaPosY },
- { "trigger_create", &LuaTrigger_Create },
- { "chatmessage", &LuaChatmessage },
+ { "npc_create", &LuaNpc_Create },
+ { "npc_message", &LuaNpc_Message },
+ { "npc_choice", &LuaNpc_Choice },
+ { "npc_trade", &LuaNpc_Trade },
+ { "chr_warp", &LuaChr_Warp },
+ { "chr_inv_change", &LuaChr_InvChange },
+ { "chr_inv_count", &LuaChr_InvCount },
+ { "chr_get_quest", &LuaChr_GetQuest },
+ { "chr_set_quest", &LuaChr_SetQuest },
+ { "monster_create", &LuaMonster_Create },
+ { "being_walk", &LuaBeing_Walk },
+ { "being_say", &LuaBeing_Say },
+ { "being_damage", &LuaBeing_Damage },
+ { "posX", &LuaPosX },
+ { "posY", &LuaPosY },
+ { "trigger_create", &LuaTrigger_Create },
+ { "chatmessage", &LuaChatmessage },
+ { "get_beings_in_circle", &LuaGetBeingsInCircle},
{ NULL, NULL }
};
luaL_register(mState, "tmw", callbacks);