From 42ea85786a44b519eb79f08a350020ed693d2e0e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 Aug 2013 23:48:03 +0200 Subject: [PATCH 01/25] Thrown ender pearls now teleport and hurt. --- source/BlockID.h | 1 + source/Entities/ProjectileEntity.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/source/BlockID.h b/source/BlockID.h index de8335e85..b7e9f3779 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -659,6 +659,7 @@ enum eDamageType dtFireContact, // Standing inside a fire block dtInVoid, // Falling into the Void (Y < 0) dtPotionOfHarming, + dtEnderPearl, // Thrown an ender pearl, teleported by it dtAdmin, // Damage applied by an admin command // Some common synonyms: diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index 91b2c97a8..8f9f3b480 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -316,7 +316,13 @@ cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, double a_X void cThrownEnderPearlEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) { - // TODO: Teleport the creator here, make them take 5 damage + // Teleport the creator here, make them take 5 damage: + if (m_Creator != NULL) + { + // TODO: The coords might need some tweaking based on the block face + m_Creator->TeleportToCoords(a_BlockX + 0.5, a_BlockY + 1.7, a_BlockZ + 0.5); + m_Creator->TakeDamage(dtEnderPearl, this, 5, 0); + } Destroy(); } From 2a5b2e826aa2c5aeff262bbe48c572d6076d4451 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 11:32:17 +0200 Subject: [PATCH 02/25] AnvilStats: ignoring the world subfolder --- Tools/AnvilStats/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/Tools/AnvilStats/.gitignore b/Tools/AnvilStats/.gitignore index 6832eb9f8..6574e4a3e 100644 --- a/Tools/AnvilStats/.gitignore +++ b/Tools/AnvilStats/.gitignore @@ -5,3 +5,4 @@ Debug/ Release/ Profiling *.png +world/ From f91ff9e68b6332ce6ca1903fed4f7a17f6e5c80d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 12:25:53 +0200 Subject: [PATCH 03/25] Added the cBoundingBox class. --- VC2008/MCServer.vcproj | 8 + source/AllToLua.pkg | 1 + source/Bindings.cpp | 605 ++++++++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/BoundingBox.cpp | 195 +++++++++++++ source/BoundingBox.h | 67 +++++ 6 files changed, 870 insertions(+), 8 deletions(-) create mode 100644 source/BoundingBox.cpp create mode 100644 source/BoundingBox.h diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 7ffa3c887..2c1624ded 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -386,6 +386,14 @@ RelativePath="..\source\BlockTracer.h" > + + + + diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index 8d87be307..b423c43a5 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -53,6 +53,7 @@ $cfile "Vector3d.h" $cfile "Vector3i.h" $cfile "Matrix4f.h" $cfile "Cuboid.h" +$cfile "BoundingBox.h" $cfile "Tracer.h" $cfile "Group.h" $cfile "BlockArea.h" diff --git a/source/Bindings.cpp b/source/Bindings.cpp index cbe728cbf..871fd9c9c 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/30/13 18:03:04. +** Generated automatically by tolua++-1.0.92 on 09/01/13 12:24:41. */ #ifndef __cplusplus @@ -53,6 +53,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "Vector3i.h" #include "Matrix4f.h" #include "Cuboid.h" +#include "BoundingBox.h" #include "Tracer.h" #include "Group.h" #include "BlockArea.h" @@ -163,6 +164,13 @@ static int tolua_collect_cTracer (lua_State* tolua_S) return 0; } +static int tolua_collect_cBoundingBox (lua_State* tolua_S) +{ + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + Mtolua_delete(self); + return 0; +} + static int tolua_collect_Vector3f (lua_State* tolua_S) { Vector3f* self = (Vector3f*) tolua_tousertype(tolua_S,1,0); @@ -204,13 +212,14 @@ static int tolua_collect_Vector3d (lua_State* tolua_S) static void tolua_reg_types (lua_State* tolua_S) { tolua_usertype(tolua_S,"cThrownEnderPearlEntity"); - tolua_usertype(tolua_S,"TakeDamageInfo"); tolua_usertype(tolua_S,"cPluginManager"); + tolua_usertype(tolua_S,"TakeDamageInfo"); tolua_usertype(tolua_S,"cMonster"); - tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cCuboid"); + tolua_usertype(tolua_S,"cWindow"); tolua_usertype(tolua_S,"cCraftingRecipe"); tolua_usertype(tolua_S,"cPlugin"); - tolua_usertype(tolua_S,"cWindow"); + tolua_usertype(tolua_S,"cCraftingGrid"); tolua_usertype(tolua_S,"cStringMap"); tolua_usertype(tolua_S,"cItemGrid"); tolua_usertype(tolua_S,"cBlockArea"); @@ -218,12 +227,12 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cLuaWindow"); tolua_usertype(tolua_S,"cServer"); tolua_usertype(tolua_S,"cRoot"); - tolua_usertype(tolua_S,"cCuboid"); - tolua_usertype(tolua_S,"std::vector"); tolua_usertype(tolua_S,"cGroup"); + tolua_usertype(tolua_S,"std::vector"); + tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cPickup"); tolua_usertype(tolua_S,"std::vector"); - tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"cBoundingBox"); tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"cChunkDesc"); tolua_usertype(tolua_S,"cFurnaceRecipe"); @@ -22316,6 +22325,559 @@ static int tolua_AllToLua_cCuboid_IsSorted00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: new of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new00 +static int tolua_AllToLua_cBoundingBox_new00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnumber(tolua_S,7,0,&tolua_err) || + !tolua_isnoobj(tolua_S,8,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + double a_MinX = ((double) tolua_tonumber(tolua_S,2,0)); + double a_MaxX = ((double) tolua_tonumber(tolua_S,3,0)); + double a_MinY = ((double) tolua_tonumber(tolua_S,4,0)); + double a_MaxY = ((double) tolua_tonumber(tolua_S,5,0)); + double a_MinZ = ((double) tolua_tonumber(tolua_S,6,0)); + double a_MaxZ = ((double) tolua_tonumber(tolua_S,7,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(a_MinX,a_MaxX,a_MinY,a_MaxY,a_MinZ,a_MaxZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new00_local +static int tolua_AllToLua_cBoundingBox_new00_local(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnumber(tolua_S,7,0,&tolua_err) || + !tolua_isnoobj(tolua_S,8,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + double a_MinX = ((double) tolua_tonumber(tolua_S,2,0)); + double a_MaxX = ((double) tolua_tonumber(tolua_S,3,0)); + double a_MinY = ((double) tolua_tonumber(tolua_S,4,0)); + double a_MaxY = ((double) tolua_tonumber(tolua_S,5,0)); + double a_MinZ = ((double) tolua_tonumber(tolua_S,6,0)); + double a_MaxZ = ((double) tolua_tonumber(tolua_S,7,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(a_MinX,a_MaxX,a_MinY,a_MaxY,a_MinZ,a_MaxZ)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'new'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new01 +static int tolua_AllToLua_cBoundingBox_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Min = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Max = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(*a_Min,*a_Max)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new01_local +static int tolua_AllToLua_cBoundingBox_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Min = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Max = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(*a_Min,*a_Max)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new02 +static int tolua_AllToLua_cBoundingBox_new02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Pos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + double a_Radius = ((double) tolua_tonumber(tolua_S,3,0)); + double a_Height = ((double) tolua_tonumber(tolua_S,4,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(*a_Pos,a_Radius,a_Height)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_new01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new02_local +static int tolua_AllToLua_cBoundingBox_new02_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Pos = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + double a_Radius = ((double) tolua_tonumber(tolua_S,3,0)); + double a_Height = ((double) tolua_tonumber(tolua_S,4,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(*a_Pos,a_Radius,a_Height)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_new01_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new03 +static int tolua_AllToLua_cBoundingBox_new03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cBoundingBox",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cBoundingBox* a_Orig = ((const cBoundingBox*) tolua_tousertype(tolua_S,2,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(*a_Orig)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_new02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_new03_local +static int tolua_AllToLua_cBoundingBox_new03_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cBoundingBox",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const cBoundingBox* a_Orig = ((const cBoundingBox*) tolua_tousertype(tolua_S,2,0)); + { + cBoundingBox* tolua_ret = (cBoundingBox*) Mtolua_new((cBoundingBox)(*a_Orig)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cBoundingBox"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_new02_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Move of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_Move00 +static int tolua_AllToLua_cBoundingBox_Move00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + double a_OffX = ((double) tolua_tonumber(tolua_S,2,0)); + double a_OffY = ((double) tolua_tonumber(tolua_S,3,0)); + double a_OffZ = ((double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Move'", NULL); +#endif + { + self->Move(a_OffX,a_OffY,a_OffZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Move'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Move of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_Move01 +static int tolua_AllToLua_cBoundingBox_Move01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_Off = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Move'", NULL); +#endif + { + self->Move(*a_Off); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_Move00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Expand of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_Expand00 +static int tolua_AllToLua_cBoundingBox_Expand00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + double a_ExpandX = ((double) tolua_tonumber(tolua_S,2,0)); + double a_ExpandY = ((double) tolua_tonumber(tolua_S,3,0)); + double a_ExpandZ = ((double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Expand'", NULL); +#endif + { + self->Expand(a_ExpandX,a_ExpandY,a_ExpandZ); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Expand'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: DoesIntersect of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_DoesIntersect00 +static int tolua_AllToLua_cBoundingBox_DoesIntersect00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cBoundingBox",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + const cBoundingBox* a_Other = ((const cBoundingBox*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DoesIntersect'", NULL); +#endif + { + bool tolua_ret = (bool) self->DoesIntersect(*a_Other); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DoesIntersect'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: Union of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_Union00 +static int tolua_AllToLua_cBoundingBox_Union00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cBoundingBox",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + const cBoundingBox* a_Other = ((const cBoundingBox*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Union'", NULL); +#endif + { + cBoundingBox tolua_ret = (cBoundingBox) self->Union(*a_Other); + { +#ifdef __cplusplus + void* tolua_obj = Mtolua_new((cBoundingBox)(tolua_ret)); + tolua_pushusertype(tolua_S,tolua_obj,"cBoundingBox"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#else + void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(cBoundingBox)); + tolua_pushusertype(tolua_S,tolua_obj,"cBoundingBox"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); +#endif + } + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'Union'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_IsInside00 +static int tolua_AllToLua_cBoundingBox_IsInside00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_Point = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*a_Point); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsInside'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_IsInside01 +static int tolua_AllToLua_cBoundingBox_IsInside01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + double a_X = ((double) tolua_tonumber(tolua_S,2,0)); + double a_Y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_Z = ((double) tolua_tonumber(tolua_S,4,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(a_X,a_Y,a_Z); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_IsInside00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_IsInside02 +static int tolua_AllToLua_cBoundingBox_IsInside02(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cBoundingBox",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + cBoundingBox* a_Other = ((cBoundingBox*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*a_Other); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_IsInside01(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_IsInside03 +static int tolua_AllToLua_cBoundingBox_IsInside03(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_Min = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Max = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsInside'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsInside(*a_Min,*a_Max); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_IsInside02(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class cTracer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00 static int tolua_AllToLua_cTracer_new00(lua_State* tolua_S) @@ -28280,6 +28842,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"dtFireContact",dtFireContact); tolua_constant(tolua_S,"dtInVoid",dtInVoid); tolua_constant(tolua_S,"dtPotionOfHarming",dtPotionOfHarming); + tolua_constant(tolua_S,"dtEnderPearl",dtEnderPearl); tolua_constant(tolua_S,"dtAdmin",dtAdmin); tolua_constant(tolua_S,"dtPawnAttack",dtPawnAttack); tolua_constant(tolua_S,"dtEntityAttack",dtEntityAttack); @@ -29329,6 +29892,34 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsSorted",tolua_AllToLua_cCuboid_IsSorted00); tolua_endmodule(tolua_S); #ifdef __cplusplus + tolua_cclass(tolua_S,"cBoundingBox","cBoundingBox","",tolua_collect_cBoundingBox); + #else + tolua_cclass(tolua_S,"cBoundingBox","cBoundingBox","",NULL); + #endif + tolua_beginmodule(tolua_S,"cBoundingBox"); + tolua_function(tolua_S,"new",tolua_AllToLua_cBoundingBox_new00); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cBoundingBox_new00_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cBoundingBox_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cBoundingBox_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cBoundingBox_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cBoundingBox_new01_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cBoundingBox_new02); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cBoundingBox_new02_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cBoundingBox_new02_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cBoundingBox_new03); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cBoundingBox_new03_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cBoundingBox_new03_local); + tolua_function(tolua_S,"Move",tolua_AllToLua_cBoundingBox_Move00); + tolua_function(tolua_S,"Move",tolua_AllToLua_cBoundingBox_Move01); + tolua_function(tolua_S,"Expand",tolua_AllToLua_cBoundingBox_Expand00); + tolua_function(tolua_S,"DoesIntersect",tolua_AllToLua_cBoundingBox_DoesIntersect00); + tolua_function(tolua_S,"Union",tolua_AllToLua_cBoundingBox_Union00); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside00); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside01); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside02); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside03); + tolua_endmodule(tolua_S); + #ifdef __cplusplus tolua_cclass(tolua_S,"cTracer","cTracer","",tolua_collect_cTracer); #else tolua_cclass(tolua_S,"cTracer","cTracer","",NULL); diff --git a/source/Bindings.h b/source/Bindings.h index faa81e4c8..8ff6ee2c6 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/30/13 18:03:05. +** Generated automatically by tolua++-1.0.92 on 09/01/13 12:24:42. */ /* Exported function */ diff --git a/source/BoundingBox.cpp b/source/BoundingBox.cpp new file mode 100644 index 000000000..9af726223 --- /dev/null +++ b/source/BoundingBox.cpp @@ -0,0 +1,195 @@ + +// BoundingBox.cpp + +// Implements the cBoundingBox class representing an axis-aligned bounding box with floatingpoint coords + +#include "Globals.h" +#include "BoundingBox.h" + + + + + +cBoundingBox::cBoundingBox(double a_MinX, double a_MaxX, double a_MinY, double a_MaxY, double a_MinZ, double a_MaxZ) : + m_Min(a_MinX, a_MinY, a_MinZ), + m_Max(a_MaxX, a_MaxY, a_MaxZ) +{ +} + + + + + +cBoundingBox::cBoundingBox(const Vector3d & a_Min, const Vector3d & a_Max) : + m_Min(a_Min), + m_Max(a_Max) +{ +} + + + + + +cBoundingBox::cBoundingBox(const Vector3d & a_Pos, double a_Radius, double a_Height) : + m_Min(a_Pos.x - a_Radius, a_Pos.y, a_Pos.z - a_Radius), + m_Max(a_Pos.x + a_Radius, a_Pos.y + a_Height, a_Pos.z + a_Radius) +{ +} + + + + + +cBoundingBox::cBoundingBox(const cBoundingBox & a_Orig) : + m_Min(a_Orig.m_Min), + m_Max(a_Orig.m_Max) +{ +} + + + + + +void cBoundingBox::Move(double a_OffX, double a_OffY, double a_OffZ) +{ + m_Min.x += a_OffX; + m_Min.y += a_OffY; + m_Min.z += a_OffZ; + m_Max.x += a_OffX; + m_Max.y += a_OffY; + m_Max.z += a_OffZ; +} + + + + + +void cBoundingBox::Move(const Vector3d & a_Off) +{ + m_Min.x += a_Off.x; + m_Min.y += a_Off.y; + m_Min.z += a_Off.z; + m_Max.x += a_Off.x; + m_Max.y += a_Off.y; + m_Max.z += a_Off.z; +} + + + + + +void cBoundingBox::Expand(double a_ExpandX, double a_ExpandY, double a_ExpandZ) +{ + m_Min.x -= a_ExpandX; + m_Min.y -= a_ExpandY; + m_Min.z -= a_ExpandZ; + m_Max.x += a_ExpandX; + m_Max.y += a_ExpandY; + m_Max.z += a_ExpandZ; +} + + + + + +bool cBoundingBox::DoesIntersect(const cBoundingBox & a_Other) +{ + return ( + ((a_Other.m_Min.x < m_Max.x) && (a_Other.m_Max.x > m_Min.x)) && // X coords intersect + ((a_Other.m_Min.y < m_Max.y) && (a_Other.m_Max.y > m_Min.y)) && // Y coords intersect + ((a_Other.m_Min.z < m_Max.z) && (a_Other.m_Max.z > m_Min.z)) // Z coords intersect + ); +} + + + + + +cBoundingBox cBoundingBox::Union(const cBoundingBox & a_Other) +{ + return cBoundingBox( + std::min(m_Min.x, a_Other.m_Min.x), + std::min(m_Min.y, a_Other.m_Min.y), + std::min(m_Min.z, a_Other.m_Min.z), + std::max(m_Max.x, a_Other.m_Max.x), + std::max(m_Max.y, a_Other.m_Max.y), + std::max(m_Max.z, a_Other.m_Max.z) + ); +} + + + + + +bool cBoundingBox::IsInside(const Vector3d & a_Point) +{ + return ( + ((a_Point.x >= m_Min.x) && (a_Point.x < m_Max.x)) && + ((a_Point.y >= m_Min.y) && (a_Point.y < m_Max.y)) && + ((a_Point.z >= m_Min.z) && (a_Point.z < m_Max.z)) + ); +} + + + + + +bool cBoundingBox::IsInside(double a_X, double a_Y,double a_Z) +{ + return ( + ((a_X >= m_Min.x) && (a_X < m_Max.x)) && + ((a_Y >= m_Min.y) && (a_Y < m_Max.y)) && + ((a_Z >= m_Min.z) && (a_Z < m_Max.z)) + ); +} + + + + + +bool cBoundingBox::IsInside(cBoundingBox & a_Other) +{ + // If both a_Other's coords are inside this, then the entire a_Other is inside + return (IsInside(a_Other.m_Min) && IsInside(a_Other.m_Max)); +} + + + + + +bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max) +{ + // If both coords are inside this, then the entire a_Other is inside + return (IsInside(a_Min) && IsInside(a_Max)); +} + + + + + +bool cBoundingBox::Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection) +{ + a_Intersection.m_Min.x = std::max(m_Min.x, a_Other.m_Min.x); + a_Intersection.m_Max.x = std::min(m_Max.x, a_Other.m_Max.x); + if (a_Intersection.m_Min.x >= a_Intersection.m_Max.x) + { + return false; + } + a_Intersection.m_Min.y = std::max(m_Min.y, a_Other.m_Min.y); + a_Intersection.m_Max.y = std::min(m_Max.y, a_Other.m_Max.y); + if (a_Intersection.m_Min.y >= a_Intersection.m_Max.y) + { + return false; + } + a_Intersection.m_Min.z = std::max(m_Min.z, a_Other.m_Min.z); + a_Intersection.m_Max.z = std::min(m_Max.z, a_Other.m_Max.z); + if (a_Intersection.m_Min.z >= a_Intersection.m_Max.z) + { + return false; + } + return true; +} + + + + diff --git a/source/BoundingBox.h b/source/BoundingBox.h new file mode 100644 index 000000000..5a07df20e --- /dev/null +++ b/source/BoundingBox.h @@ -0,0 +1,67 @@ + +// BoundingBox.h + +// Declares the cBoundingBox class representing an axis-aligned bounding box with floatingpoint coords + + + + +#pragma once + +#include "Vector3d.h" + + + + + +// tolua_begin + +class cBoundingBox +{ +public: + cBoundingBox(double a_MinX, double a_MaxX, double a_MinY, double a_MaxY, double a_MinZ, double a_MaxZ); + cBoundingBox(const Vector3d & a_Min, const Vector3d & a_Max); + cBoundingBox(const Vector3d & a_Pos, double a_Radius, double a_Height); + cBoundingBox(const cBoundingBox & a_Orig); + + /// Moves the entire boundingbox by the specified offset + void Move(double a_OffX, double a_OffY, double a_OffZ); + + /// Moves the entire boundingbox by the specified offset + void Move(const Vector3d & a_Off); + + /// Expands the bounding box by the specified amount in each direction (so the box becomes larger by 2 * Expand in each direction) + void Expand(double a_ExpandX, double a_ExpandY, double a_ExpandZ); + + /// Returns true if the two bounding boxes intersect + bool DoesIntersect(const cBoundingBox & a_Other); + + /// Returns the union of the two bounding boxes + cBoundingBox Union(const cBoundingBox & a_Other); + + /// Returns true if the point is inside the bounding box + bool IsInside(const Vector3d & a_Point); + + /// Returns true if the point is inside the bounding box + bool IsInside(double a_X, double a_Y,double a_Z); + + /// Returns true if a_Other is inside this bounding box + bool IsInside(cBoundingBox & a_Other); + + /// Returns true if a boundingbox specified by a_Min and a_Max is inside this bounding box + bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max); + + // tolua_end + + /// Calculates the intersection of the two bounding boxes; returns true if nonempty + bool Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection); + +protected: + Vector3d m_Min; + Vector3d m_Max; + +} ; // tolua_export + + + + From b12d2edb4e7e2c1815a2219c2aa8eb6d6be69947 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 19:05:58 +0200 Subject: [PATCH 04/25] Renamed BLOCK_FACE constants to use the new coord-wise names. The old names are still present, but deprecated. --- source/Defines.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/source/Defines.h b/source/Defines.h index 6bc1a18f6..331b4dd05 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -43,16 +43,24 @@ extern bool g_BlockIsSolid[256]; -/// Block face constants, used in PlayerDigging and PlayerBlockPlacement packets -enum +/// Block face constants, used in PlayerDigging and PlayerBlockPlacement packets and bbox collision calc +enum eBlockFace { - BLOCK_FACE_NONE = -1, // Interacting with no block face - swinging the item in the air - BLOCK_FACE_BOTTOM = 0, // Interacting with the bottom face of the block (YM) - BLOCK_FACE_TOP = 1, // Interacting with the top face of the block (YP) - BLOCK_FACE_NORTH = 2, // Interacting with the northern face of the block (ZP) - BLOCK_FACE_SOUTH = 3, // Interacting with the southern face of the block (ZM) - BLOCK_FACE_WEST = 4, // Interacting with the western face of the block (XP) - BLOCK_FACE_EAST = 5, // Interacting with the eastern face of the block (XM) + BLOCK_FACE_NONE = -1, // Interacting with no block face - swinging the item in the air + BLOCK_FACE_XM = 5, // Interacting with the X- face of the block + BLOCK_FACE_XP = 4, // Interacting with the X+ face of the block + BLOCK_FACE_YM = 0, // Interacting with the Y- face of the block + BLOCK_FACE_YP = 1, // Interacting with the Y+ face of the block + BLOCK_FACE_ZM = 3, // Interacting with the Z- face of the block + BLOCK_FACE_ZP = 2, // Interacting with the Z+ face of the block + + // Synonyms using the (deprecated) world directions: + BLOCK_FACE_BOTTOM = BLOCK_FACE_YM, // Interacting with the bottom face of the block + BLOCK_FACE_TOP = BLOCK_FACE_YP, // Interacting with the top face of the block + BLOCK_FACE_NORTH = BLOCK_FACE_ZP, // Interacting with the northern face of the block + BLOCK_FACE_SOUTH = BLOCK_FACE_ZM, // Interacting with the southern face of the block + BLOCK_FACE_WEST = BLOCK_FACE_XP, // Interacting with the western face of the block + BLOCK_FACE_EAST = BLOCK_FACE_XM, // Interacting with the eastern face of the block } ; From 5fccd67bada2be7a3fbb2df3abf08bfde58b600b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 19:08:51 +0200 Subject: [PATCH 05/25] Added line collision calculation to cBoundingBox. --- source/Bindings.cpp | 284 ++++++++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/BoundingBox.cpp | 114 +++++++++++++++-- source/BoundingBox.h | 16 +++ source/Vector3d.cpp | 72 +++++++++-- source/Vector3d.h | 85 ++++++++---- 6 files changed, 527 insertions(+), 46 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 871fd9c9c..c5b5df159 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/01/13 12:24:41. +** Generated automatically by tolua++-1.0.92 on 09/01/13 19:03:24. */ #ifndef __cplusplus @@ -20233,6 +20233,24 @@ static int tolua_set_Vector3f_z(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* get function: EPS of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_EPS +static int tolua_get_Vector3d_EPS(lua_State* tolua_S) +{ + tolua_pushnumber(tolua_S,(lua_Number)Vector3d::EPS); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: NO_INTERSECTION of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_NO_INTERSECTION +static int tolua_get_Vector3d_NO_INTERSECTION(lua_State* tolua_S) +{ + tolua_pushnumber(tolua_S,(lua_Number)Vector3d::NO_INTERSECTION); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class Vector3d */ #ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00 static int tolua_AllToLua_Vector3d_new00(lua_State* tolua_S) @@ -20731,6 +20749,114 @@ static int tolua_AllToLua_Vector3d_Cross00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: LineCoeffToXYPlane of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_LineCoeffToXYPlane00 +static int tolua_AllToLua_Vector3d_LineCoeffToXYPlane00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_OtherEnd = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + double a_Z = ((double) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LineCoeffToXYPlane'", NULL); +#endif + { + double tolua_ret = (double) self->LineCoeffToXYPlane(*a_OtherEnd,a_Z); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LineCoeffToXYPlane'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: LineCoeffToXZPlane of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_LineCoeffToXZPlane00 +static int tolua_AllToLua_Vector3d_LineCoeffToXZPlane00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_OtherEnd = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + double a_Y = ((double) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LineCoeffToXZPlane'", NULL); +#endif + { + double tolua_ret = (double) self->LineCoeffToXZPlane(*a_OtherEnd,a_Y); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LineCoeffToXZPlane'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: LineCoeffToYZPlane of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_LineCoeffToYZPlane00 +static int tolua_AllToLua_Vector3d_LineCoeffToYZPlane00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const Vector3d",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const Vector3d* self = (const Vector3d*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_OtherEnd = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + double a_X = ((double) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LineCoeffToYZPlane'", NULL); +#endif + { + double tolua_ret = (double) self->LineCoeffToYZPlane(*a_OtherEnd,a_X); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'LineCoeffToYZPlane'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: Equals of class Vector3d */ #ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_Equals00 static int tolua_AllToLua_Vector3d_Equals00(lua_State* tolua_S) @@ -22878,6 +23004,147 @@ tolua_lerror: } #endif //#ifndef TOLUA_DISABLE +/* method: IsInside of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_IsInside04 +static int tolua_AllToLua_cBoundingBox_IsInside04(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,5,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Min = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Max = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); + const Vector3d* a_Point = ((const Vector3d*) tolua_tousertype(tolua_S,4,0)); + { + bool tolua_ret = (bool) cBoundingBox::IsInside(*a_Min,*a_Max,*a_Point); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_IsInside03(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: IsInside of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_IsInside05 +static int tolua_AllToLua_cBoundingBox_IsInside05(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnoobj(tolua_S,7,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Min = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Max = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); + double a_X = ((double) tolua_tonumber(tolua_S,4,0)); + double a_Y = ((double) tolua_tonumber(tolua_S,5,0)); + double a_Z = ((double) tolua_tonumber(tolua_S,6,0)); + { + bool tolua_ret = (bool) cBoundingBox::IsInside(*a_Min,*a_Max,a_X,a_Y,a_Z); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_IsInside04(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CalcLineIntersection of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_CalcLineIntersection00 +static int tolua_AllToLua_cBoundingBox_CalcLineIntersection00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cBoundingBox* self = (cBoundingBox*) tolua_tousertype(tolua_S,1,0); + const Vector3d* a_Line1 = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Line2 = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); + double a_LineCoeff = ((double) tolua_tonumber(tolua_S,4,0)); + char a_Face = ((char) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CalcLineIntersection'", NULL); +#endif + { + bool tolua_ret = (bool) self->CalcLineIntersection(*a_Line1,*a_Line2,a_LineCoeff,a_Face); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushnumber(tolua_S,(lua_Number)a_LineCoeff); + tolua_pushnumber(tolua_S,(lua_Number)a_Face); + } + } + return 3; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CalcLineIntersection'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CalcLineIntersection of class cBoundingBox */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cBoundingBox_CalcLineIntersection01 +static int tolua_AllToLua_cBoundingBox_CalcLineIntersection01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cBoundingBox",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,4,&tolua_err) || !tolua_isusertype(tolua_S,4,"const Vector3d",0,&tolua_err)) || + (tolua_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"const Vector3d",0,&tolua_err)) || + !tolua_isnumber(tolua_S,6,0,&tolua_err) || + !tolua_isnumber(tolua_S,7,0,&tolua_err) || + !tolua_isnoobj(tolua_S,8,&tolua_err) + ) + goto tolua_lerror; + else + { + const Vector3d* a_Min = ((const Vector3d*) tolua_tousertype(tolua_S,2,0)); + const Vector3d* a_Max = ((const Vector3d*) tolua_tousertype(tolua_S,3,0)); + const Vector3d* a_Line1 = ((const Vector3d*) tolua_tousertype(tolua_S,4,0)); + const Vector3d* a_Line2 = ((const Vector3d*) tolua_tousertype(tolua_S,5,0)); + double a_LineCoeff = ((double) tolua_tonumber(tolua_S,6,0)); + char a_Face = ((char) tolua_tonumber(tolua_S,7,0)); + { + bool tolua_ret = (bool) cBoundingBox::CalcLineIntersection(*a_Min,*a_Max,*a_Line1,*a_Line2,a_LineCoeff,a_Face); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + tolua_pushnumber(tolua_S,(lua_Number)a_LineCoeff); + tolua_pushnumber(tolua_S,(lua_Number)a_Face); + } + } + return 3; +tolua_lerror: + return tolua_AllToLua_cBoundingBox_CalcLineIntersection00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class cTracer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cTracer_new00 static int tolua_AllToLua_cTracer_new00(lua_State* tolua_S) @@ -28895,6 +29162,12 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_array(tolua_S,"g_BlockRequiresSpecialTool",tolua_get_AllToLua_g_BlockRequiresSpecialTool,tolua_set_AllToLua_g_BlockRequiresSpecialTool); tolua_array(tolua_S,"g_BlockIsSolid",tolua_get_AllToLua_g_BlockIsSolid,tolua_set_AllToLua_g_BlockIsSolid); tolua_constant(tolua_S,"BLOCK_FACE_NONE",BLOCK_FACE_NONE); + tolua_constant(tolua_S,"BLOCK_FACE_XM",BLOCK_FACE_XM); + tolua_constant(tolua_S,"BLOCK_FACE_XP",BLOCK_FACE_XP); + tolua_constant(tolua_S,"BLOCK_FACE_YM",BLOCK_FACE_YM); + tolua_constant(tolua_S,"BLOCK_FACE_YP",BLOCK_FACE_YP); + tolua_constant(tolua_S,"BLOCK_FACE_ZM",BLOCK_FACE_ZM); + tolua_constant(tolua_S,"BLOCK_FACE_ZP",BLOCK_FACE_ZP); tolua_constant(tolua_S,"BLOCK_FACE_BOTTOM",BLOCK_FACE_BOTTOM); tolua_constant(tolua_S,"BLOCK_FACE_TOP",BLOCK_FACE_TOP); tolua_constant(tolua_S,"BLOCK_FACE_NORTH",BLOCK_FACE_NORTH); @@ -29799,6 +30072,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_cclass(tolua_S,"Vector3d","Vector3d","",NULL); #endif tolua_beginmodule(tolua_S,"Vector3d"); + tolua_variable(tolua_S,"EPS",tolua_get_Vector3d_EPS,NULL); + tolua_variable(tolua_S,"NO_INTERSECTION",tolua_get_Vector3d_NO_INTERSECTION,NULL); tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new00); tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new00_local); tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new00_local); @@ -29819,6 +30094,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SqrLength",tolua_AllToLua_Vector3d_SqrLength00); tolua_function(tolua_S,"Dot",tolua_AllToLua_Vector3d_Dot00); tolua_function(tolua_S,"Cross",tolua_AllToLua_Vector3d_Cross00); + tolua_function(tolua_S,"LineCoeffToXYPlane",tolua_AllToLua_Vector3d_LineCoeffToXYPlane00); + tolua_function(tolua_S,"LineCoeffToXZPlane",tolua_AllToLua_Vector3d_LineCoeffToXZPlane00); + tolua_function(tolua_S,"LineCoeffToYZPlane",tolua_AllToLua_Vector3d_LineCoeffToYZPlane00); tolua_function(tolua_S,"Equals",tolua_AllToLua_Vector3d_Equals00); tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add00); tolua_function(tolua_S,".add",tolua_AllToLua_Vector3d__add01); @@ -29918,6 +30196,10 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside01); tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside02); tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside03); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside04); + tolua_function(tolua_S,"IsInside",tolua_AllToLua_cBoundingBox_IsInside05); + tolua_function(tolua_S,"CalcLineIntersection",tolua_AllToLua_cBoundingBox_CalcLineIntersection00); + tolua_function(tolua_S,"CalcLineIntersection",tolua_AllToLua_cBoundingBox_CalcLineIntersection01); tolua_endmodule(tolua_S); #ifdef __cplusplus tolua_cclass(tolua_S,"cTracer","cTracer","",tolua_collect_cTracer); diff --git a/source/Bindings.h b/source/Bindings.h index 8ff6ee2c6..e667d24d0 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/01/13 12:24:42. +** Generated automatically by tolua++-1.0.92 on 09/01/13 19:03:25. */ /* Exported function */ diff --git a/source/BoundingBox.cpp b/source/BoundingBox.cpp index 9af726223..c845fe372 100644 --- a/source/BoundingBox.cpp +++ b/source/BoundingBox.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "BoundingBox.h" +#include "Defines.h" @@ -123,11 +124,7 @@ cBoundingBox cBoundingBox::Union(const cBoundingBox & a_Other) bool cBoundingBox::IsInside(const Vector3d & a_Point) { - return ( - ((a_Point.x >= m_Min.x) && (a_Point.x < m_Max.x)) && - ((a_Point.y >= m_Min.y) && (a_Point.y < m_Max.y)) && - ((a_Point.z >= m_Min.z) && (a_Point.z < m_Max.z)) - ); + return IsInside(m_Min, m_Max, a_Point); } @@ -136,11 +133,7 @@ bool cBoundingBox::IsInside(const Vector3d & a_Point) bool cBoundingBox::IsInside(double a_X, double a_Y,double a_Z) { - return ( - ((a_X >= m_Min.x) && (a_X < m_Max.x)) && - ((a_Y >= m_Min.y) && (a_Y < m_Max.y)) && - ((a_Z >= m_Min.z) && (a_Z < m_Max.z)) - ); + return IsInside(m_Min, m_Max, a_X, a_Y, a_Z); } @@ -167,6 +160,107 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max) +bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point) +{ + return ( + ((a_Point.x >= a_Min.x) && (a_Point.x < a_Max.x)) && + ((a_Point.y >= a_Min.y) && (a_Point.y < a_Max.y)) && + ((a_Point.z >= a_Min.z) && (a_Point.z < a_Max.z)) + ); +} + + + + + +bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z) +{ + return ( + ((a_X >= a_Min.x) && (a_X < a_Max.x)) && + ((a_Y >= a_Min.y) && (a_Y < a_Max.y)) && + ((a_Z >= a_Min.z) && (a_Z < a_Max.z)) + ); +} + + + + + +bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face) +{ + return CalcLineIntersection(m_Min, m_Max, a_Line1, a_Line2, a_LineCoeff, a_Face); +} + + + + + +bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face) +{ + char Face = 0; + double Coeff = Vector3d::NO_INTERSECTION; + + // Check each individual bbox face for intersection with the line, remember the one with the lowest coeff + double c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Min.z); + if (c < Coeff) + { + Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; + Coeff = c; + } + c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Max.z); + if (c < Coeff) + { + Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; + Coeff = c; + } + c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Min.y); + if (c < Coeff) + { + Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; + Coeff = c; + } + c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y); + if (c < Coeff) + { + Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; + Coeff = c; + } + c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Min.x); + if (c < Coeff) + { + Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; + Coeff = c; + } + c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Max.x); + if (c < Coeff) + { + Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; + Coeff = c; + } + + if (Coeff >= Vector3d::NO_INTERSECTION) + { + // There has been no intersection + return false; + } + + Vector3d Intersection = a_Line1 + (a_Line2 - a_Line1) * Coeff; + if (!IsInside(a_Min, a_Max, Intersection)) + { + // The line intersects with the individual wall planes, but not within this bounding box + return false; + } + + // True intersection, return all the values: + a_LineCoeff = Coeff; + a_Face = Face; + return true; +} + + + + + bool cBoundingBox::Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection) { a_Intersection.m_Min.x = std::max(m_Min.x, a_Other.m_Min.x); diff --git a/source/BoundingBox.h b/source/BoundingBox.h index 5a07df20e..7b6391942 100644 --- a/source/BoundingBox.h +++ b/source/BoundingBox.h @@ -51,6 +51,22 @@ public: /// Returns true if a boundingbox specified by a_Min and a_Max is inside this bounding box bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max); + /// Returns true if the specified point is inside the bounding box specified by its min/max corners + static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point); + + /// Returns true if the specified point is inside the bounding box specified by its min/max corners + static bool IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z); + + /** Returns true if this bounding box is intersected by the line specified by its two points + Also calculates the distance along the line in which the intersection occurs (0 .. 1) + */ + bool CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face); + + /** Returns true if the specified bounding box is intersected by the line specified by its two points + Also calculates the distance along the line in which the intersection occurs (0 .. 1) and the face hit (BLOCK_FACE_ constants) + */ + static bool CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face); + // tolua_end /// Calculates the intersection of the two bounding boxes; returns true if nonempty diff --git a/source/Vector3d.cpp b/source/Vector3d.cpp index 987c380dc..96ebebab5 100644 --- a/source/Vector3d.cpp +++ b/source/Vector3d.cpp @@ -8,16 +8,70 @@ -Vector3d::Vector3d(const Vector3f & v ) - : x( v.x ) - , y( v.y ) - , z( v.z ) +const double Vector3d::EPS = 0.000001; ///< The max difference between two coords for which the coords are assumed equal +const double Vector3d::NO_INTERSECTION = 1e70; ///< Return value of LineCoeffToPlane() if the line is parallel to the plane + + + + + +Vector3d::Vector3d(const Vector3f & v) : + x(v.x), + y(v.y), + z(v.z) { } -Vector3d::Vector3d(const Vector3f * v ) - : x( v->x ) - , y( v->y ) - , z( v->z ) + + + + +Vector3d::Vector3d(const Vector3f * v) : + x(v->x), + y(v->y), + z(v->z) { -} \ No newline at end of file +} + + + + + +double Vector3d::LineCoeffToXYPlane(const Vector3d & a_OtherEnd, double a_Z) const +{ + if (abs(z - a_OtherEnd.z) < EPS) + { + return NO_INTERSECTION; + } + return (a_Z - z) / (a_OtherEnd.z - z); +} + + + + + +double Vector3d::LineCoeffToXZPlane(const Vector3d & a_OtherEnd, double a_Y) const +{ + if (abs(y - a_OtherEnd.y) < EPS) + { + return NO_INTERSECTION; + } + return (a_Y - y) / (a_OtherEnd.y - y); +} + + + + + +double Vector3d::LineCoeffToYZPlane(const Vector3d & a_OtherEnd, double a_X) const +{ + if (abs(x - a_OtherEnd.x) < EPS) + { + return NO_INTERSECTION; + } + return (a_X - x) / (a_OtherEnd.x - x); +} + + + + diff --git a/source/Vector3d.h b/source/Vector3d.h index ecc72e421..081ce353f 100644 --- a/source/Vector3d.h +++ b/source/Vector3d.h @@ -3,26 +3,54 @@ #include class Vector3f; -class Vector3d // tolua_export -{ // tolua_export -public: // tolua_export + + + +// tolua_begin + +class Vector3d +{ +public: + static const double EPS; ///< The max difference between two coords for which the coords are assumed equal + static const double NO_INTERSECTION; ///< Return value of LineCoeffToPlane() if the line is parallel to the plane + // convert from float - Vector3d(const Vector3f & v ); // tolua_export - Vector3d(const Vector3f * v ); // tolua_export + Vector3d(const Vector3f & v); + Vector3d(const Vector3f * v); - Vector3d() : x(0), y(0), z(0) {} // tolua_export - Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} // tolua_export + Vector3d() : x(0), y(0), z(0) {} + Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} - inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } // tolua_export - inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } // tolua_export - inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } // tolua_export - inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } // tolua_export - inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } // tolua_export - inline double SqrLength() const { return x * x + y * y + z * z; } // tolua_export - inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } // tolua_export - inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } // tolua_export + inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } + inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } + inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } + inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } + inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } + inline double SqrLength() const { return x * x + y * y + z * z; } + inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } + inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } + + /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Z coord + The result satisfies the following equation: + (*this + Result * (a_OtherEnd - *this)).z = a_Z + */ + double LineCoeffToXYPlane(const Vector3d & a_OtherEnd, double a_Z) const; - inline bool Equals( const Vector3d & v ) const { return (x == v.x && y == v.y && z == v.z ); } // tolua_export + /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Y coord + The result satisfies the following equation: + (*this + Result * (a_OtherEnd - *this)).y = a_Y + */ + double LineCoeffToXZPlane(const Vector3d & a_OtherEnd, double a_Y) const; + + /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified X coord + The result satisfies the following equation: + (*this + Result * (a_OtherEnd - *this)).x = a_X + */ + double LineCoeffToYZPlane(const Vector3d & a_OtherEnd, double a_X) const; + + inline bool Equals(const Vector3d & v) const { return ((x == v.x) && (y == v.y) && (z == v.z)); } + + // tolua_end void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } @@ -30,14 +58,21 @@ public: // tolua_export void operator -= ( Vector3d* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } void operator *= ( double a_f ) { x *= a_f; y *= a_f; z *= a_f; } - Vector3d operator + (const Vector3d & v2) const { return Vector3d(x + v2.x, y + v2.y, z + v2.z ); } // tolua_export - Vector3d operator + (const Vector3d * v2) const { return Vector3d(x + v2->x, y + v2->y, z + v2->z ); } // tolua_export - Vector3d operator - (const Vector3d & v2) const { return Vector3d(x - v2.x, y - v2.y, z - v2.z ); } // tolua_export - Vector3d operator - (const Vector3d * v2) const { return Vector3d(x - v2->x, y - v2->y, z - v2->z ); } // tolua_export - Vector3d operator * (const double f) const { return Vector3d(x * f, y * f, z * f ); } // tolua_export - Vector3d operator * (const Vector3d & v2) const { return Vector3d(x * v2.x, y * v2.y, z * v2.z ); } // tolua_export - Vector3d operator / (const double f) const { return Vector3d(x / f, y / f, z / f ); } // tolua_export + // tolua_begin + + Vector3d operator + (const Vector3d & v2) const { return Vector3d(x + v2.x, y + v2.y, z + v2.z ); } + Vector3d operator + (const Vector3d * v2) const { return Vector3d(x + v2->x, y + v2->y, z + v2->z ); } + Vector3d operator - (const Vector3d & v2) const { return Vector3d(x - v2.x, y - v2.y, z - v2.z ); } + Vector3d operator - (const Vector3d * v2) const { return Vector3d(x - v2->x, y - v2->y, z - v2->z ); } + Vector3d operator * (const double f) const { return Vector3d(x * f, y * f, z * f ); } + Vector3d operator * (const Vector3d & v2) const { return Vector3d(x * v2.x, y * v2.y, z * v2.z ); } + Vector3d operator / (const double f) const { return Vector3d(x / f, y / f, z / f ); } + + double x, y, z; +} ; + +// tolua_end + + - double x, y, z; // tolua_export -};// tolua_export From 0dec48d4969bc1973b228c09f6d38d4d63a0a005 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 20:06:49 +0200 Subject: [PATCH 06/25] Added dtRangedAttack, fixed faulty StringTODamageType() --- source/BlockID.cpp | 39 ++++++++++++++++++++++----------------- source/BlockID.h | 4 ++++ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/source/BlockID.cpp b/source/BlockID.cpp index 40664647a..4d7cd6003 100644 --- a/source/BlockID.cpp +++ b/source/BlockID.cpp @@ -419,6 +419,7 @@ AString DamageTypeToString(eDamageType a_DamageType) switch (a_DamageType) { case dtAttack: return "dtAttack"; + case dtRangedAttack: return "dtRangedAttack"; case dtLightning: return "dtLightning"; case dtFalling: return "dtFalling"; case dtDrowning: return "dtDrowning"; @@ -463,6 +464,7 @@ eDamageType StringToDamageType(const AString & a_DamageTypeString) { // Cannonical names: { dtAttack, "dtAttack"}, + { dtRangedAttack, "dtRangedAttack"}, { dtLightning, "dtLightning"}, { dtFalling, "dtFalling"}, { dtDrowning, "dtDrowning"}, @@ -478,23 +480,26 @@ eDamageType StringToDamageType(const AString & a_DamageTypeString) { dtAdmin, "dtAdmin"}, // Common synonyms: - { dtPawnAttack, "dtAttack"}, - { dtEntityAttack, "dtAttack"}, - { dtMob, "dtAttack"}, - { dtMobAttack, "dtAttack"}, - { dtFall, "dtFalling"}, - { dtDrown, "dtDrowning"}, - { dtSuffocation, "dtSuffocating"}, - { dtStarvation, "dtStarving"}, - { dtHunger, "dtStarving"}, - { dtCactus, "dtCactusContact"}, - { dtCactuses, "dtCactusContact"}, - { dtCacti, "dtCactusContact"}, - { dtLava, "dtLavaContact"}, - { dtPoison, "dtPoisoning"}, - { dtBurning, "dtOnFire"}, - { dtInFire, "dtFireContact"}, - { dtPlugin, "dtAdmin"}, + { dtAttack, "dtPawnAttack"}, + { dtAttack, "dtEntityAttack"}, + { dtAttack, "dtMob"}, + { dtAttack, "dtMobAttack"}, + { dtRangedAttack, "dtArrowAttack"}, + { dtRangedAttack, "dtArrow"}, + { dtRangedAttack, "dtProjectile"}, + { dtFalling, "dtFall"}, + { dtDrowning, "dtDrown"}, + { dtSuffocating, "dtSuffocation"}, + { dtStarving, "dtStarvation"}, + { dtStarving, "dtHunger"}, + { dtCactusContact, "dtCactus"}, + { dtCactusContact, "dtCactuses"}, + { dtCactusContact, "dtCacti"}, + { dtLavaContact, "dtLava"}, + { dtPoisoning, "dtPoison"}, + { dtOnFire, "dtBurning"}, + { dtFireContact, "dtInFire"}, + { dtAdmin, "dtPlugin"}, } ; for (int i = 0; i < ARRAYCOUNT(DamageTypeMap); i++) { diff --git a/source/BlockID.h b/source/BlockID.h index b7e9f3779..00aeff4d6 100644 --- a/source/BlockID.h +++ b/source/BlockID.h @@ -647,6 +647,7 @@ enum eDamageType { // Canonical names for the types (as documented in the plugin wiki): dtAttack, // Being attacked by a mob + dtRangedAttack, // Being attacked by a projectile, possibly from a mob dtLightning, // Hit by a lightning strike dtFalling, // Falling down; dealt when hitting the ground dtDrowning, // Drowning in water / lava @@ -667,6 +668,9 @@ enum eDamageType dtEntityAttack = dtAttack, dtMob = dtAttack, dtMobAttack = dtAttack, + dtArrowAttack = dtRangedAttack, + dtArrow = dtRangedAttack, + dtProjectile = dtRangedAttack, dtFall = dtFalling, dtDrown = dtDrowning, dtSuffocation = dtSuffocating, From e35402c61aa8c9749ff65e5a083184d369f79f15 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 20:39:22 +0200 Subject: [PATCH 07/25] Fixed an error in cBoundingBox's line-collision algorithm. --- source/BoundingBox.cpp | 20 ++++++-------------- source/Vector3d.h | 9 ++++++--- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/source/BoundingBox.cpp b/source/BoundingBox.cpp index c845fe372..bf53f3c6a 100644 --- a/source/BoundingBox.cpp +++ b/source/BoundingBox.cpp @@ -202,37 +202,37 @@ bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d & // Check each individual bbox face for intersection with the line, remember the one with the lowest coeff double c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Min.z); - if (c < Coeff) + if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; Coeff = c; } c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Max.z); - if (c < Coeff) + if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; Coeff = c; } c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Min.y); - if (c < Coeff) + if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; Coeff = c; } c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y); - if (c < Coeff) + if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; Coeff = c; } c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Min.x); - if (c < Coeff) + if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; Coeff = c; } c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Max.x); - if (c < Coeff) + if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; Coeff = c; @@ -244,14 +244,6 @@ bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d & return false; } - Vector3d Intersection = a_Line1 + (a_Line2 - a_Line1) * Coeff; - if (!IsInside(a_Min, a_Max, Intersection)) - { - // The line intersects with the individual wall planes, but not within this bounding box - return false; - } - - // True intersection, return all the values: a_LineCoeff = Coeff; a_Face = Face; return true; diff --git a/source/Vector3d.h b/source/Vector3d.h index 081ce353f..a06a17c09 100644 --- a/source/Vector3d.h +++ b/source/Vector3d.h @@ -11,9 +11,6 @@ class Vector3f; class Vector3d { public: - static const double EPS; ///< The max difference between two coords for which the coords are assumed equal - static const double NO_INTERSECTION; ///< Return value of LineCoeffToPlane() if the line is parallel to the plane - // convert from float Vector3d(const Vector3f & v); Vector3d(const Vector3f * v); @@ -33,18 +30,21 @@ public: /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Z coord The result satisfies the following equation: (*this + Result * (a_OtherEnd - *this)).z = a_Z + If the line is too close to being parallel, this function returns NO_INTERSECTION */ double LineCoeffToXYPlane(const Vector3d & a_OtherEnd, double a_Z) const; /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Y coord The result satisfies the following equation: (*this + Result * (a_OtherEnd - *this)).y = a_Y + If the line is too close to being parallel, this function returns NO_INTERSECTION */ double LineCoeffToXZPlane(const Vector3d & a_OtherEnd, double a_Y) const; /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified X coord The result satisfies the following equation: (*this + Result * (a_OtherEnd - *this)).x = a_X + If the line is too close to being parallel, this function returns NO_INTERSECTION */ double LineCoeffToYZPlane(const Vector3d & a_OtherEnd, double a_X) const; @@ -69,6 +69,9 @@ public: Vector3d operator / (const double f) const { return Vector3d(x / f, y / f, z / f ); } double x, y, z; + + static const double EPS; ///< The max difference between two coords for which the coords are assumed equal + static const double NO_INTERSECTION; ///< Return value of LineCoeffToPlane() if the line is parallel to the plane } ; // tolua_end From 4f04724cfdbc4b6c7908423d0ad232a2ef374b1d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 22:38:09 +0200 Subject: [PATCH 08/25] Made cBoundingBox class inclusive in both coord edges. Also added (a disabled) self-test to cBoundingBox. --- source/BoundingBox.cpp | 60 +++++++++++++++++++++++++++++++++++------- source/BoundingBox.h | 5 ++++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/source/BoundingBox.cpp b/source/BoundingBox.cpp index bf53f3c6a..e2b8c313e 100644 --- a/source/BoundingBox.cpp +++ b/source/BoundingBox.cpp @@ -11,6 +11,48 @@ +#if 0 + +/// A simple self-test that is executed on program start, used to verify bbox functionality +class SelfTest +{ +public: + SelfTest(void) + { + Vector3d Min(1, 1, 1); + Vector3d Max(2, 2, 2); + Vector3d LineDefs[] = + { + Vector3d(1.5, 4, 1.5), Vector3d(1.5, 3, 1.5), // Should intersect at 2, face 1 (YP) + Vector3d(1.5, 0, 1.5), Vector3d(1.5, 4, 1.5), // Should intersect at 0.25, face 0 (YM) + Vector3d(0, 0, 0), Vector3d(2, 2, 2), // Should intersect at 0.5, face 0, 3 or 5 (anyM) + Vector3d(0.999, 0, 1.5), Vector3d(0.999, 4, 1.5), // Should not intersect + Vector3d(1.999, 0, 1.5), Vector3d(1.999, 4, 1.5), // Should intersect at 0.25, face 0 (YM) + Vector3d(2.001, 0, 1.5), Vector3d(2.001, 4, 1.5), // Should not intersect + } ; + for (int i = 0; i < ARRAYCOUNT(LineDefs) / 2; i++) + { + double LineCoeff; + char Face; + Vector3d Line1 = LineDefs[2 * i]; + Vector3d Line2 = LineDefs[2 * i + 1]; + bool res = cBoundingBox::CalcLineIntersection(Min, Max, Line1, Line2, LineCoeff, Face); + printf("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d\n", + Line1.x, Line1.y, Line1.z, + Line2.x, Line2.y, Line2.z, + res ? 1 : 0, LineCoeff, Face + ); + } // for i - LineDefs[] + printf("BoundingBox selftest complete."); + } +} Test; + +#endif + + + + + cBoundingBox::cBoundingBox(double a_MinX, double a_MaxX, double a_MinY, double a_MaxY, double a_MinZ, double a_MaxZ) : m_Min(a_MinX, a_MinY, a_MinZ), m_Max(a_MaxX, a_MaxY, a_MaxZ) @@ -96,9 +138,9 @@ void cBoundingBox::Expand(double a_ExpandX, double a_ExpandY, double a_ExpandZ) bool cBoundingBox::DoesIntersect(const cBoundingBox & a_Other) { return ( - ((a_Other.m_Min.x < m_Max.x) && (a_Other.m_Max.x > m_Min.x)) && // X coords intersect - ((a_Other.m_Min.y < m_Max.y) && (a_Other.m_Max.y > m_Min.y)) && // Y coords intersect - ((a_Other.m_Min.z < m_Max.z) && (a_Other.m_Max.z > m_Min.z)) // Z coords intersect + ((a_Other.m_Min.x <= m_Max.x) && (a_Other.m_Max.x >= m_Min.x)) && // X coords intersect + ((a_Other.m_Min.y <= m_Max.y) && (a_Other.m_Max.y >= m_Min.y)) && // Y coords intersect + ((a_Other.m_Min.z <= m_Max.z) && (a_Other.m_Max.z >= m_Min.z)) // Z coords intersect ); } @@ -163,9 +205,9 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max) bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point) { return ( - ((a_Point.x >= a_Min.x) && (a_Point.x < a_Max.x)) && - ((a_Point.y >= a_Min.y) && (a_Point.y < a_Max.y)) && - ((a_Point.z >= a_Min.z) && (a_Point.z < a_Max.z)) + ((a_Point.x >= a_Min.x) && (a_Point.x <= a_Max.x)) && + ((a_Point.y >= a_Min.y) && (a_Point.y <= a_Max.y)) && + ((a_Point.z >= a_Min.z) && (a_Point.z <= a_Max.z)) ); } @@ -176,9 +218,9 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, cons bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z) { return ( - ((a_X >= a_Min.x) && (a_X < a_Max.x)) && - ((a_Y >= a_Min.y) && (a_Y < a_Max.y)) && - ((a_Z >= a_Min.z) && (a_Z < a_Max.z)) + ((a_X >= a_Min.x) && (a_X <= a_Max.x)) && + ((a_Y >= a_Min.y) && (a_Y <= a_Max.y)) && + ((a_Z >= a_Min.z) && (a_Z <= a_Max.z)) ); } diff --git a/source/BoundingBox.h b/source/BoundingBox.h index 7b6391942..cfaf6a318 100644 --- a/source/BoundingBox.h +++ b/source/BoundingBox.h @@ -16,6 +16,11 @@ // tolua_begin +/** Represents two sets of coords, minimum and maximum for each direction. +All the coords within those limits (inclusive the edges) are considered "inside" the box. +For intersection purposes, though, if the intersection is "sharp" in any coord (i. e. zero volume), +the boxes are considered non-intersecting. +*/ class cBoundingBox { public: From a884fbb91937d3243c15477428a31cc764d03a84 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 22:40:35 +0200 Subject: [PATCH 09/25] Arrows deal damage. Still needs some tweaks, they hit the shooter most of the time. --- source/Entities/ProjectileEntity.cpp | 127 ++++++++++++++++++++++++++- source/Entities/ProjectileEntity.h | 4 + 2 files changed, 127 insertions(+), 4 deletions(-) diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index 8f9f3b480..ed7803410 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -8,6 +8,9 @@ #include "../ClientHandle.h" #include "Player.h" #include "../LineBlockTracer.h" +#include "../BoundingBox.h" +#include "../ChunkMap.h" +#include "../Chunk.h" @@ -63,6 +66,82 @@ protected: +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cProjectileEntityCollisionCallback: + +class cProjectileEntityCollisionCallback : + public cEntityCallback +{ +public: + cProjectileEntityCollisionCallback(cProjectileEntity * a_Projectile, const Vector3d & a_Pos, const Vector3d & a_NextPos) : + m_Projectile(a_Projectile), + m_Pos(a_Pos), + m_NextPos(a_NextPos), + m_MinCoeff(1), + m_HitEntity(NULL) + { + } + + + virtual bool Item(cEntity * a_Entity) override + { + if (a_Entity == m_Projectile) + { + // Self-colision + return false; + } + + cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + + // Instead of colliding the bounding box with another bounding box in motion, we collide an enlarged bounding box with a hairline. + // The results should be good enough for our purposes + double LineCoeff; + char Face; + EntBox.Expand(m_Projectile->GetWidth() / 2, m_Projectile->GetHeight() / 2, m_Projectile->GetWidth() / 2); + if (!EntBox.CalcLineIntersection(m_Pos, m_NextPos, LineCoeff, Face)) + { + // No intersection whatsoever + return false; + } + + // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) + // TODO: Allow plugins to interfere about which entities can be hit + + if (LineCoeff < m_MinCoeff) + { + // The entity is closer than anything we've stored so far, replace it as the potential victim + m_MinCoeff = LineCoeff; + m_HitEntity = a_Entity; + } + + // Don't break the enumeration, we want all the entities + return false; + } + + /// Returns the nearest entity that was hit, after the enumeration has been completed + cEntity * GetHitEntity(void) const { return m_HitEntity; } + + /// Returns the line coeff where the hit was encountered, after the enumeration has been completed + double GetMinCoeff(void) const { return m_MinCoeff; } + + /// Returns true if the callback has encountered a true hit + bool HasHit(void) const { return (m_MinCoeff < 1); } + +protected: + cProjectileEntity * m_Projectile; + const Vector3d & m_Pos; + const Vector3d & m_NextPos; + double m_MinCoeff; // The coefficient of the nearest hit on the Pos line + + // Although it's bad(tm) to store entity ptrs from a callback, we can afford it here, because the entire callback + // is processed inside the tick thread, so the entities won't be removed in between the calls and the final processing + cEntity * m_HitEntity; // The nearest hit entity +} ; + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cProjectileEntity: @@ -192,17 +271,39 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // Trace the tick's worth of movement as a line: Vector3d NextPos = Pos + PerTickSpeed; cProjectileTracerCallback TracerCallback(this); - if (cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos)) + if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos)) { - // Nothing in the way, update the position - SetPosition(NextPos); + // Something has been hit, abort all other processing + return; } + // Test for entity collisions: + cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos); + a_Chunk.ForEachEntity(EntityCollisionCallback); + if (EntityCollisionCallback.HasHit()) + { + // An entity was hit: + // DEBUG: + Vector3d HitPos = Pos + (NextPos - Pos) * EntityCollisionCallback.GetMinCoeff(); + LOGD("Projectile %d has hit an entity %d (%s) at {%.02f, %.02f, %.02f} (coeff %.03f)", + m_UniqueID, + EntityCollisionCallback.GetHitEntity()->GetUniqueID(), + EntityCollisionCallback.GetHitEntity()->GetClass(), + HitPos.x, HitPos.y, HitPos.z, + EntityCollisionCallback.GetMinCoeff() + ); + OnHitEntity(*(EntityCollisionCallback.GetHitEntity())); + } + // TODO: Test the entities in the neighboring chunks, too + + // Update the position: + SetPosition(NextPos); + // Add gravity effect to the vertical speed component: SetSpeedY(GetSpeedY() + m_Gravity / 20); // DEBUG: - LOGD("Arrow %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}", + LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}", m_UniqueID, GetPosX(), GetPosY(), GetPosZ(), GetSpeedX(), GetSpeedY(), GetSpeedZ() @@ -277,6 +378,24 @@ void cArrowEntity::SpawnOn(cClientHandle & a_Client) +void cArrowEntity::OnHitEntity(cEntity & a_EntityHit) +{ + if (!a_EntityHit.IsMob() && !a_EntityHit.IsMinecart() && !a_EntityHit.IsPlayer()) + { + // Not an entity that interacts with an arrow + return; + } + + // TODO: The damage dealt should be based on arrow speed in addition to the damage coeff + a_EntityHit.TakeDamage(dtRangedAttack, this, (int)(2.5 * m_DamageCoeff), 1); + + Destroy(); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cThrownEggEntity: diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index 95dc00abc..da82c82ea 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -50,6 +50,9 @@ public: /// Called by the physics blocktracer when the entity hits a solid block, the block's coords and the face hit is given virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace); + /// Called by the physics blocktracer when the entity hits another entity + virtual void OnHitEntity(cEntity & a_EntityHit) {} + // tolua_begin /// Returns the kind of the projectile (fast class identification) @@ -140,6 +143,7 @@ protected: // cProjectileEntity overrides: virtual void SpawnOn(cClientHandle & a_Client) override; + virtual void OnHitEntity(cEntity & a_EntityHit) override; // tolua_begin } ; From f5e0c8c77e66685f58a5013674c5f74a647d69a5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 2 Sep 2013 19:51:13 +0200 Subject: [PATCH 10/25] cBoundingBox: Only forward collisions are calculated. --- source/BoundingBox.cpp | 20 ++++++++++++++------ source/BoundingBox.h | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/source/BoundingBox.cpp b/source/BoundingBox.cpp index e2b8c313e..d8a1bc679 100644 --- a/source/BoundingBox.cpp +++ b/source/BoundingBox.cpp @@ -239,42 +239,50 @@ bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face) { + if (IsInside(a_Min, a_Max, a_Line1)) + { + // The starting point is inside the bounding box. + a_LineCoeff = 0; + a_Face = BLOCK_FACE_YM; // Make it look as the top face was hit, although none really are. + return true; + } + char Face = 0; double Coeff = Vector3d::NO_INTERSECTION; // Check each individual bbox face for intersection with the line, remember the one with the lowest coeff double c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Min.z); - if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) + if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; Coeff = c; } c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Max.z); - if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) + if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; Coeff = c; } c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Min.y); - if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) + if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; Coeff = c; } c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y); - if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) + if ((c >= 0) && (c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; Coeff = c; } c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Min.x); - if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) + if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; Coeff = c; } c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Max.x); - if ((c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) + if ((c >= 0) && (c < Coeff) && IsInside(a_Min, a_Max, a_Line1 + (a_Line2 - a_Line1) * c)) { Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; Coeff = c; diff --git a/source/BoundingBox.h b/source/BoundingBox.h index cfaf6a318..ff9963989 100644 --- a/source/BoundingBox.h +++ b/source/BoundingBox.h @@ -64,11 +64,13 @@ public: /** Returns true if this bounding box is intersected by the line specified by its two points Also calculates the distance along the line in which the intersection occurs (0 .. 1) + Only forward collisions (a_LineCoeff >= 0) are returned. */ bool CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face); /** Returns true if the specified bounding box is intersected by the line specified by its two points Also calculates the distance along the line in which the intersection occurs (0 .. 1) and the face hit (BLOCK_FACE_ constants) + Only forward collisions (a_LineCoeff >= 0) are returned. */ static bool CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face); From 7433b3723ca06575e986ea48fd4a2a2af4047189 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 2 Sep 2013 21:40:56 +0200 Subject: [PATCH 11/25] Projectiles don't collide with their creators. --- source/Entities/ProjectileEntity.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index ed7803410..8bc9abdb0 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -85,9 +85,13 @@ public: virtual bool Item(cEntity * a_Entity) override { - if (a_Entity == m_Projectile) + if ( + (a_Entity == m_Projectile) || // Do not check collisions with self + (a_Entity == m_Projectile->GetCreator()) // Do not check whoever shot the projectile + ) { - // Self-colision + // TODO: Don't check creator only for the first 5 ticks + // so that arrows stuck in ground and dug up can hurt the player return false; } From e8b77ea2f5a9245f9ed3b28a7a637cf584037914 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 2 Sep 2013 21:56:55 +0200 Subject: [PATCH 12/25] Projectiles slow down in water and lava. --- source/Entities/ProjectileEntity.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index 8bc9abdb0..bef411559 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -24,13 +24,18 @@ class cProjectileTracerCallback : { public: cProjectileTracerCallback(cProjectileEntity * a_Projectile) : - m_Projectile(a_Projectile) + m_Projectile(a_Projectile), + m_SlowdownCoeff(0.99) // Default slowdown when not in water { } + double GetSlowdownCoeff(void) const { return m_SlowdownCoeff; } + protected: cProjectileEntity * m_Projectile; + double m_SlowdownCoeff; + // cCallbacks overrides: virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { if (g_BlockIsSolid[a_BlockType]) @@ -47,12 +52,14 @@ protected: case E_BLOCK_STATIONARY_LAVA: { m_Projectile->StartBurning(30); + m_SlowdownCoeff = std::min(m_SlowdownCoeff, 0.9); // Slow down to 0.9* the speed each tick when moving through lava break; } case E_BLOCK_WATER: case E_BLOCK_STATIONARY_WATER: { m_Projectile->StopBurning(); + m_SlowdownCoeff = std::min(m_SlowdownCoeff, 0.8); // Slow down to 0.8* the speed each tick when moving through water break; } } // switch (a_BlockType) @@ -280,6 +287,7 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // Something has been hit, abort all other processing return; } + // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later // Test for entity collisions: cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos); @@ -303,8 +311,11 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // Update the position: SetPosition(NextPos); - // Add gravity effect to the vertical speed component: - SetSpeedY(GetSpeedY() + m_Gravity / 20); + // Add slowdown and gravity effect to the speed: + Vector3d NewSpeed(GetSpeed()); + NewSpeed.y += m_Gravity / 20; + NewSpeed *= TracerCallback.GetSlowdownCoeff(); + SetSpeed(NewSpeed); // DEBUG: LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}", From 3a921955d94851b4f0148f69f3f0c35a227aa8f5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 3 Sep 2013 08:37:15 +0200 Subject: [PATCH 13/25] Arrows deal damage based on their speed. --- source/Entities/ProjectileEntity.cpp | 14 ++++++++++---- source/Entities/ProjectileEntity.h | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index bef411559..c259cb52f 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -345,7 +345,8 @@ void cProjectileEntity::SpawnOn(cClientHandle & a_Client) cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : super(pkArrow, a_Creator, a_X, a_Y, a_Z, 0.5, 0.5), m_PickupState(psNoPickup), - m_DamageCoeff(2) + m_DamageCoeff(2), + m_IsCritical(false) { SetSpeed(a_Speed); SetMass(0.1); @@ -361,7 +362,8 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : super(pkArrow, &a_Player, a_Player.GetThrowStartPos(), a_Player.GetThrowSpeed(a_Force * 1.5 * 20), 0.5, 0.5), m_PickupState(psInSurvivalOrCreative), - m_DamageCoeff(2) + m_DamageCoeff(2), + m_IsCritical((a_Force >= 1)) { } @@ -401,8 +403,12 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit) return; } - // TODO: The damage dealt should be based on arrow speed in addition to the damage coeff - a_EntityHit.TakeDamage(dtRangedAttack, this, (int)(2.5 * m_DamageCoeff), 1); + int Damage = (int)(GetSpeed().Length() / 20 * m_DamageCoeff + 0.5); + if (m_IsCritical) + { + Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); + } + a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); Destroy(); } diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index da82c82ea..bd282d7e7 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -140,6 +140,9 @@ protected: /// The coefficient applied to the damage that the arrow will deal, based on the bow enchantment. 2.0 for normal arrow double m_DamageCoeff; + + /// If true, the arrow deals more damage + bool m_IsCritical; // cProjectileEntity overrides: virtual void SpawnOn(cClientHandle & a_Client) override; From f7d58944273be0390c9e583eaa5bad0bcfcbfa5d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 3 Sep 2013 08:39:35 +0200 Subject: [PATCH 14/25] Added cArrowEntity's criticalness to the API. --- source/Bindings.cpp | 113 +++++++++++++++++++++++------ source/Bindings.h | 2 +- source/Entities/ProjectileEntity.h | 6 ++ 3 files changed, 99 insertions(+), 22 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index c5b5df159..00da10f43 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/01/13 19:03:24. +** Generated automatically by tolua++-1.0.92 on 09/03/13 08:38:38. */ #ifndef __cplusplus @@ -9966,6 +9966,71 @@ static int tolua_AllToLua_cArrowEntity_CanPickup00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: IsCritical of class cArrowEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cArrowEntity_IsCritical00 +static int tolua_AllToLua_cArrowEntity_IsCritical00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cArrowEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cArrowEntity* self = (const cArrowEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsCritical'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsCritical(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsCritical'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetIsCritical of class cArrowEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cArrowEntity_SetIsCritical00 +static int tolua_AllToLua_cArrowEntity_SetIsCritical00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cArrowEntity",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cArrowEntity* self = (cArrowEntity*) tolua_tousertype(tolua_S,1,0); + bool a_IsCritical = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetIsCritical'", NULL); +#endif + { + self->SetIsCritical(a_IsCritical); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetIsCritical'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: Get of class cPluginManager */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_Get00 static int tolua_AllToLua_cPluginManager_Get00(lua_State* tolua_S) @@ -20233,24 +20298,6 @@ static int tolua_set_Vector3f_z(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* get function: EPS of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3d_EPS -static int tolua_get_Vector3d_EPS(lua_State* tolua_S) -{ - tolua_pushnumber(tolua_S,(lua_Number)Vector3d::EPS); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - -/* get function: NO_INTERSECTION of class Vector3d */ -#ifndef TOLUA_DISABLE_tolua_get_Vector3d_NO_INTERSECTION -static int tolua_get_Vector3d_NO_INTERSECTION(lua_State* tolua_S) -{ - tolua_pushnumber(tolua_S,(lua_Number)Vector3d::NO_INTERSECTION); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - /* method: new of class Vector3d */ #ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3d_new00 static int tolua_AllToLua_Vector3d_new00(lua_State* tolua_S) @@ -21274,6 +21321,24 @@ static int tolua_set_Vector3d_z(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* get function: EPS of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_EPS +static int tolua_get_Vector3d_EPS(lua_State* tolua_S) +{ + tolua_pushnumber(tolua_S,(lua_Number)Vector3d::EPS); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: NO_INTERSECTION of class Vector3d */ +#ifndef TOLUA_DISABLE_tolua_get_Vector3d_NO_INTERSECTION +static int tolua_get_Vector3d_NO_INTERSECTION(lua_State* tolua_S) +{ + tolua_pushnumber(tolua_S,(lua_Number)Vector3d::NO_INTERSECTION); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class Vector3i */ #ifndef TOLUA_DISABLE_tolua_AllToLua_Vector3i_new00 static int tolua_AllToLua_Vector3i_new00(lua_State* tolua_S) @@ -29097,6 +29162,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"dimOverworld",dimOverworld); tolua_constant(tolua_S,"dimEnd",dimEnd); tolua_constant(tolua_S,"dtAttack",dtAttack); + tolua_constant(tolua_S,"dtRangedAttack",dtRangedAttack); tolua_constant(tolua_S,"dtLightning",dtLightning); tolua_constant(tolua_S,"dtFalling",dtFalling); tolua_constant(tolua_S,"dtDrowning",dtDrowning); @@ -29115,6 +29181,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"dtEntityAttack",dtEntityAttack); tolua_constant(tolua_S,"dtMob",dtMob); tolua_constant(tolua_S,"dtMobAttack",dtMobAttack); + tolua_constant(tolua_S,"dtArrowAttack",dtArrowAttack); + tolua_constant(tolua_S,"dtArrow",dtArrow); + tolua_constant(tolua_S,"dtProjectile",dtProjectile); tolua_constant(tolua_S,"dtFall",dtFall); tolua_constant(tolua_S,"dtDrown",dtDrown); tolua_constant(tolua_S,"dtSuffocation",dtSuffocation); @@ -29527,6 +29596,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetDamageCoeff",tolua_AllToLua_cArrowEntity_GetDamageCoeff00); tolua_function(tolua_S,"SetDamageCoeff",tolua_AllToLua_cArrowEntity_SetDamageCoeff00); tolua_function(tolua_S,"CanPickup",tolua_AllToLua_cArrowEntity_CanPickup00); + tolua_function(tolua_S,"IsCritical",tolua_AllToLua_cArrowEntity_IsCritical00); + tolua_function(tolua_S,"SetIsCritical",tolua_AllToLua_cArrowEntity_SetIsCritical00); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cThrownEggEntity","cThrownEggEntity","cProjectileEntity",NULL); tolua_beginmodule(tolua_S,"cThrownEggEntity"); @@ -30072,8 +30143,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_cclass(tolua_S,"Vector3d","Vector3d","",NULL); #endif tolua_beginmodule(tolua_S,"Vector3d"); - tolua_variable(tolua_S,"EPS",tolua_get_Vector3d_EPS,NULL); - tolua_variable(tolua_S,"NO_INTERSECTION",tolua_get_Vector3d_NO_INTERSECTION,NULL); tolua_function(tolua_S,"new",tolua_AllToLua_Vector3d_new00); tolua_function(tolua_S,"new_local",tolua_AllToLua_Vector3d_new00_local); tolua_function(tolua_S,".call",tolua_AllToLua_Vector3d_new00_local); @@ -30108,6 +30177,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_variable(tolua_S,"x",tolua_get_Vector3d_x,tolua_set_Vector3d_x); tolua_variable(tolua_S,"y",tolua_get_Vector3d_y,tolua_set_Vector3d_y); tolua_variable(tolua_S,"z",tolua_get_Vector3d_z,tolua_set_Vector3d_z); + tolua_variable(tolua_S,"EPS",tolua_get_Vector3d_EPS,NULL); + tolua_variable(tolua_S,"NO_INTERSECTION",tolua_get_Vector3d_NO_INTERSECTION,NULL); tolua_endmodule(tolua_S); #ifdef __cplusplus tolua_cclass(tolua_S,"Vector3i","Vector3i","",tolua_collect_Vector3i); diff --git a/source/Bindings.h b/source/Bindings.h index e667d24d0..86ce70c9a 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/01/13 19:03:25. +** Generated automatically by tolua++-1.0.92 on 09/03/13 08:38:39. */ /* Exported function */ diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index bd282d7e7..415b64e90 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -131,6 +131,12 @@ public: /// Returns true if the specified player can pick the arrow up bool CanPickup(const cPlayer & a_Player) const; + /// Returns true if the arrow is set as critical + bool IsCritical(void) const { return m_IsCritical; } + + /// Sets the IsCritical flag + void SetIsCritical(bool a_IsCritical) { m_IsCritical = a_IsCritical; } + // tolua_end protected: From 2c5e566fe7de5399fac5588671b2b6f611e6bda6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 3 Sep 2013 09:41:31 +0200 Subject: [PATCH 15/25] Implemented exact block hit position. Arrows now stick out of blocks at the exact position where they hit. --- source/Entities/ProjectileEntity.cpp | 47 +++++++++++++++------------- source/Entities/ProjectileEntity.h | 10 +++--- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index c259cb52f..b97f72884 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -41,8 +41,22 @@ protected: if (g_BlockIsSolid[a_BlockType]) { // The projectile hit a solid block - m_Projectile->OnHitSolidBlock(a_BlockX, a_BlockY, a_BlockZ, a_EntryFace); - return true; + // Calculate the exact hit coords: + cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1); + Vector3d Line1 = m_Projectile->GetPosition(); + Vector3d Line2 = Line1 + m_Projectile->GetSpeed(); + double LineCoeff = 0; + char Face; + if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) + { + Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; + m_Projectile->OnHitSolidBlock(Intersection, Face); + return true; + } + else + { + LOGD("WEIRD! block tracer reports a hit, but BBox tracer doesn't. Ignoring the hit."); + } } // Convey some special effects from special blocks: @@ -206,26 +220,17 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, -void cProjectileEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) +void cProjectileEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) { - // TODO: Set proper position based on what face was hit - switch (a_BlockFace) - { - case BLOCK_FACE_TOP: SetPosition(0.5 + a_BlockX, 1.0 + a_BlockY, 0.5 + a_BlockZ); break; - case BLOCK_FACE_BOTTOM: SetPosition(0.5 + a_BlockX, a_BlockY, 0.5 + a_BlockZ); break; - case BLOCK_FACE_EAST: SetPosition( a_BlockX, 0.5 + a_BlockY, 0.5 + a_BlockZ); break; - case BLOCK_FACE_WEST: SetPosition(1.0 + a_BlockX, 0.5 + a_BlockY, 0.5 + a_BlockZ); break; - case BLOCK_FACE_NORTH: SetPosition(0.5 + a_BlockX, 0.5 + a_BlockY, 1.0 + a_BlockZ); break; - case BLOCK_FACE_SOUTH: SetPosition(0.5 + a_BlockX, 0.5 + a_BlockY, a_BlockZ); break; - case BLOCK_FACE_NONE: SetPosition(0.5 + a_BlockX, 0.5 + a_BlockY, 0.5 + a_BlockZ); break; - } + // Set the position based on what face was hit: + SetPosition(a_HitPos); SetSpeed(0, 0, 0); // DEBUG: LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, hit solid block at face %d", m_UniqueID, - GetPosX(), GetPosY(), GetPosZ(), - a_BlockFace + a_HitPos.x, a_HitPos.y, a_HitPos.z, + a_HitFace ); m_IsInGround = true; @@ -287,7 +292,7 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // Something has been hit, abort all other processing return; } - // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later + // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff // Test for entity collisions: cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos); @@ -430,7 +435,7 @@ cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y, -void cThrownEggEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) +void cThrownEggEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) { // TODO: Random-spawn a chicken or four @@ -454,13 +459,13 @@ cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, double a_X -void cThrownEnderPearlEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) +void cThrownEnderPearlEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) { // Teleport the creator here, make them take 5 damage: if (m_Creator != NULL) { // TODO: The coords might need some tweaking based on the block face - m_Creator->TeleportToCoords(a_BlockX + 0.5, a_BlockY + 1.7, a_BlockZ + 0.5); + m_Creator->TeleportToCoords(a_HitPos.x + 0.5, a_HitPos.y + 1.7, a_HitPos.z + 0.5); m_Creator->TakeDamage(dtEnderPearl, this, 5, 0); } @@ -484,7 +489,7 @@ cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, do -void cThrownSnowballEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) +void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) { // TODO: Apply damage to certain mobs (blaze etc.) and anger all mobs diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index 415b64e90..5863b4f10 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -47,8 +47,8 @@ public: static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed = NULL); - /// Called by the physics blocktracer when the entity hits a solid block, the block's coords and the face hit is given - virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace); + /// Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace); /// Called by the physics blocktracer when the entity hits another entity virtual void OnHitEntity(cEntity & a_EntityHit) {} @@ -179,7 +179,7 @@ protected: // tolua_end // cProjectileEntity overrides: - virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override; + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; // tolua_begin @@ -207,7 +207,7 @@ protected: // tolua_end // cProjectileEntity overrides: - virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override; + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; // tolua_begin @@ -235,7 +235,7 @@ protected: // tolua_end // cProjectileEntity overrides: - virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override; + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; // tolua_begin From 4c24781a621b3c572a43f24235dbab696dff0b35 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 3 Sep 2013 10:20:56 +0200 Subject: [PATCH 16/25] Added cEntity's gravity to the Lua API. --- source/Bindings.cpp | 69 +++++++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- source/Entities/Entity.h | 4 +++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 00da10f43..ad9e85ada 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/03/13 08:38:38. +** Generated automatically by tolua++-1.0.92 on 09/03/13 10:19:58. */ #ifndef __cplusplus @@ -6654,6 +6654,71 @@ tolua_lerror: } #endif //#ifndef TOLUA_DISABLE +/* method: GetGravity of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetGravity00 +static int tolua_AllToLua_cEntity_GetGravity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetGravity'", NULL); +#endif + { + float tolua_ret = (float) self->GetGravity(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetGravity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetGravity of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetGravity00 +static int tolua_AllToLua_cEntity_SetGravity00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Gravity = ((float) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetGravity'", NULL); +#endif + { + self->SetGravity(a_Gravity); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetGravity'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetRawDamageAgainst of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRawDamageAgainst00 static int tolua_AllToLua_cEntity_GetRawDamageAgainst00(lua_State* tolua_S) @@ -29460,6 +29525,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cEntity_TakeDamage00); tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cEntity_TakeDamage01); tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cEntity_TakeDamage02); + tolua_function(tolua_S,"GetGravity",tolua_AllToLua_cEntity_GetGravity00); + tolua_function(tolua_S,"SetGravity",tolua_AllToLua_cEntity_SetGravity00); tolua_function(tolua_S,"GetRawDamageAgainst",tolua_AllToLua_cEntity_GetRawDamageAgainst00); tolua_function(tolua_S,"GetArmorCoverAgainst",tolua_AllToLua_cEntity_GetArmorCoverAgainst00); tolua_function(tolua_S,"GetKnockbackAmountAgainst",tolua_AllToLua_cEntity_GetKnockbackAmountAgainst00); diff --git a/source/Bindings.h b/source/Bindings.h index 86ce70c9a..e214d7ff2 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/03/13 08:38:39. +** Generated automatically by tolua++-1.0.92 on 09/03/13 10:19:59. */ /* Exported function */ diff --git a/source/Entities/Entity.h b/source/Entities/Entity.h index f407cd2c1..aa5d8fbd2 100644 --- a/source/Entities/Entity.h +++ b/source/Entities/Entity.h @@ -201,6 +201,10 @@ public: /// Makes this entity take the specified damage. The values are packed into a TDI, knockback calculated, then sent through DoTakeDamage() void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount); + float GetGravity(void) const { return m_Gravity; } + + void SetGravity(float a_Gravity) { m_Gravity = a_Gravity; } + // tolua_end /// Makes this entity take damage specified in the a_TDI. The TDI is sent through plugins first, then applied From bd9956b35f043f0fb0bfa54c0b2168d40d5aa0af Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 4 Sep 2013 20:42:37 +0200 Subject: [PATCH 17/25] ProtoProxy: Improved logging for fixed-point numbers. "Absolute integers" and velocity are reported including their fractional part. --- Tools/ProtoProxy/Connection.cpp | 40 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index 08daf5766..0ebe18fb3 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -232,6 +232,18 @@ enum +AString PrintableAbsIntTriplet(int a_X, int a_Y, int a_Z, double a_Divisor = 32) +{ + return Printf("<%d, %d, %d> ~ {%.02f, %.02f, %.02f}", + a_X, a_Y, a_Z, + (double)a_X / a_Divisor, (double)a_Y / a_Divisor, (double)a_Z / a_Divisor + ); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cConnection: @@ -1481,7 +1493,7 @@ bool cConnection::HandleServerEntityRelativeMove(void) HANDLE_SERVER_PACKET_READ(ReadByte, Byte, dz); Log("Received a PACKET_ENTITY_RELATIVE_MOVE from the server:"); Log(" EntityID = %d", EntityID); - Log(" RelMove = <%d, %d, %d>", dx, dy, dz); + Log(" RelMove = %s", PrintableAbsIntTriplet(dx, dy, dz).c_str()); COPY_TO_CLIENT(); return true; } @@ -1500,7 +1512,7 @@ bool cConnection::HandleServerEntityRelativeMoveLook(void) HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); Log("Received a PACKET_ENTITY_RELATIVE_MOVE_LOOK from the server:"); Log(" EntityID = %d", EntityID); - Log(" RelMove = <%d, %d, %d>", dx, dy, dz); + Log(" RelMove = %s", PrintableAbsIntTriplet(dx, dy, dz).c_str()); Log(" Yaw = %d", Yaw); Log(" Pitch = %d", Pitch); COPY_TO_CLIENT(); @@ -1529,14 +1541,14 @@ bool cConnection::HandleServerEntityStatus(void) bool cConnection::HandleServerEntityTeleport(void) { HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockY); - HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsX); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsY); + HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsZ); HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch); Log("Received a PACKET_ENTITY_TELEPORT from the server:"); Log(" EntityID = %d", EntityID); - Log(" Pos = {%d, %d, %d}", BlockX, BlockY, BlockZ); + Log(" Pos = (%d, %d, %d) ~ {%.02f, %.02f, %.02f}", AbsX, AbsY, AbsZ, (double)AbsX / 32, (double)AbsY / 32, (double)AbsZ / 32); Log(" Yaw = %d", Yaw); Log(" Pitch = %d", Pitch); COPY_TO_CLIENT(); @@ -1555,7 +1567,7 @@ bool cConnection::HandleServerEntityVelocity(void) HANDLE_SERVER_PACKET_READ(ReadBEShort, short, VelocityZ); Log("Received a PACKET_ENTITY_VELOCITY from the server:"); Log(" EntityID = %d", EntityID); - Log(" Velocity = <%d, %d, %d>", VelocityX, VelocityY, VelocityZ); + Log(" Velocity = %s", PrintableAbsIntTriplet(VelocityX, VelocityY, VelocityZ, 8000).c_str()); COPY_TO_CLIENT(); return true; } @@ -1967,9 +1979,9 @@ bool cConnection::HandleServerSpawnMob(void) Log("Received a PACKET_SPAWN_MOB from the server:"); Log(" EntityID = %d", EntityID); Log(" MobType = %d", MobType); - Log(" Pos = <%d, %d, %d> ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 32, PosY / 32, PosZ / 32); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Angles = [%d, %d, %d]", Yaw, Pitch, HeadYaw); - Log(" Velocity = <%d, %d, %d>", VelocityX, VelocityY, VelocityZ); + Log(" Velocity = %s", PrintableAbsIntTriplet(VelocityX, VelocityY, VelocityZ, 8000).c_str()); Log(" Metadata, length = %d (0x%x):\n%s", Metadata.length(), Metadata.length(), HexDump.c_str()); LogMetadata(Metadata, 4); COPY_TO_CLIENT(); @@ -2000,7 +2012,7 @@ bool cConnection::HandleServerSpawnNamedEntity(void) Log("Received a PACKET_SPAWN_NAMED_ENTITY from the server:"); Log(" EntityID = %d (0x%x)", EntityID, EntityID); Log(" Name = %s", EntityName.c_str()); - Log(" Pos = <%d, %d, %d> ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 32, PosY / 32, PosZ / 32); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Rotation = ", Yaw, Pitch); Log(" CurrentItem = %d", CurrentItem); Log(" Metadata, length = %d (0x%x):\n%s", Metadata.length(), Metadata.length(), HexDump.c_str()); @@ -2073,12 +2085,12 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) Log("Received a PACKET_SPAWN_OBJECT_VEHICLE from the server:"); Log(" EntityID = %d (0x%x)", EntityID, EntityID); Log(" ObjType = %d (0x%x)", ObjType, ObjType); - Log(" Pos = <%d, %d, %d> ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 32, PosY / 32, PosZ / 32); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Rotation = ", Yaw, Pitch); Log(" DataIndicator = %d (0x%x)", DataIndicator, DataIndicator); if (DataIndicator != 0) { - Log(" Velocity = <%d, %d, %d>", VelocityX, VelocityY, VelocityZ); + Log(" Velocity = %s", PrintableAbsIntTriplet(VelocityX, VelocityY, VelocityZ, 8000).c_str()); DataLog(ExtraData.data(), ExtraData.size(), " ExtraData size = %d:", ExtraData.size()); } COPY_TO_CLIENT(); @@ -2100,7 +2112,7 @@ bool cConnection::HandleServerSpawnPainting(void) Log("Received a PACKET_SPAWN_PAINTING from the server:"); Log(" EntityID = %d", EntityID); Log(" ImageName = \"%s\"", ImageName.c_str()); - Log(" Pos = <%d, %d, %d> ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 32, PosY / 32, PosZ / 32); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Direction = %d", Direction); COPY_TO_CLIENT(); return true; @@ -2127,7 +2139,7 @@ bool cConnection::HandleServerSpawnPickup(void) Log("Received a PACKET_SPAWN_PICKUP from the server:"); Log(" EntityID = %d", EntityID); Log(" Item = %s", ItemDesc.c_str()); - Log(" Pos = <%d, %d, %d> ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 32, PosY / 32, PosZ / 32); + Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str()); Log(" Angles = [%d, %d, %d]", Rotation, Pitch, Roll); COPY_TO_CLIENT(); return true; From 5c0039e7b01347735f813e9ef680732f03956a56 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 4 Sep 2013 22:02:04 +0200 Subject: [PATCH 18/25] Removed an unused include --- source/Defines.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/Defines.h b/source/Defines.h index 331b4dd05..6dd81137e 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -353,8 +353,7 @@ inline void AddFaceDirection(int & a_BlockX, unsigned char & a_BlockY, int & a_B -#include -#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f +#define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f inline void EulerToVector(double a_Pan, double a_Pitch, double & a_X, double & a_Y, double & a_Z) { From 3f4718154bcce6fd06939fcc0f0b20ea7181be1e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 17:14:37 +0200 Subject: [PATCH 19/25] Arrows have proper yaw and pitch when shot, and stop when they hit a block. --- source/Entities/Entity.cpp | 33 +++++++++++++++++++++++++ source/Entities/Entity.h | 6 +++++ source/Entities/ProjectileEntity.cpp | 37 ++++++++++++++++++++++------ source/Entities/ProjectileEntity.h | 2 +- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/source/Entities/Entity.cpp b/source/Entities/Entity.cpp index b936d8d73..a07811a96 100644 --- a/source/Entities/Entity.cpp +++ b/source/Entities/Entity.cpp @@ -253,6 +253,39 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R +void cEntity::SetRotationFromSpeed(void) +{ + const double EPS = 0.0000001; + if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS)) + { + // atan2() may overflow or is undefined, pick any number + SetRotation(0); + return; + } + SetRotation(atan2(m_Speed.x, m_Speed.z) * 180 / PI); +} + + + + + +void cEntity::SetPitchFromSpeed(void) +{ + const double EPS = 0.0000001; + double xz = sqrt(m_Speed.x * m_Speed.x + m_Speed.z * m_Speed.z); // Speed XZ-plane component + if ((abs(xz) < EPS) && (abs(m_Speed.y) < EPS)) + { + // atan2() may overflow or is undefined, pick any number + SetPitch(0); + return; + } + SetPitch(atan2(m_Speed.y, xz) * 180 / PI); +} + + + + + void cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) { if (cRoot::Get()->GetPluginManager()->CallHookTakeDamage(*this, a_TDI)) diff --git a/source/Entities/Entity.h b/source/Entities/Entity.h index aa5d8fbd2..0e30f230c 100644 --- a/source/Entities/Entity.h +++ b/source/Entities/Entity.h @@ -205,6 +205,12 @@ public: void SetGravity(float a_Gravity) { m_Gravity = a_Gravity; } + /// Sets the rotation to match the speed vector (entity goes "face-forward") + void SetRotationFromSpeed(void); + + /// Sets the pitch to match the speed vector (entity gies "face-forward") + void SetPitchFromSpeed(void); + // tolua_end /// Makes this entity take damage specified in the a_TDI. The TDI is sent through plugins first, then applied diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index b97f72884..81ac336f0 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -16,6 +16,13 @@ +/// Converts an angle in radians into a byte representation used by the network protocol +#define ANGLE_TO_PROTO(X) (Byte)(X * 255 / 360) + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cProjectileTracerCallback: @@ -189,6 +196,8 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve m_IsInGround(false) { SetSpeed(a_Speed); + SetRotationFromSpeed(); + SetPitchFromSpeed(); } @@ -321,12 +330,15 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) NewSpeed.y += m_Gravity / 20; NewSpeed *= TracerCallback.GetSlowdownCoeff(); SetSpeed(NewSpeed); + SetRotationFromSpeed(); + SetPitchFromSpeed(); // DEBUG: - LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}", + LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, speed {%.02f, %.02f, %.02f}, rot {%.02f, %.02f}", m_UniqueID, GetPosX(), GetPosY(), GetPosZ(), - GetSpeedX(), GetSpeedY(), GetSpeedZ() + GetSpeedX(), GetSpeedY(), GetSpeedZ(), + GetRotation(), GetPitch() ); } @@ -337,7 +349,8 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) void cProjectileEntity::SpawnOn(cClientHandle & a_Client) { // Default spawning - use the projectile kind to spawn an object: - a_Client.SendSpawnObject(*this, m_ProjectileKind, 0, 0, 0); + a_Client.SendSpawnObject(*this, m_ProjectileKind, 12, ANGLE_TO_PROTO(GetRotation()), ANGLE_TO_PROTO(GetPitch())); + a_Client.SendEntityMetadata(*this); } @@ -355,8 +368,11 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a { SetSpeed(a_Speed); SetMass(0.1); - LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f}", - m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ() + SetRotationFromSpeed(); + SetPitchFromSpeed(); + LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}", + m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(), + GetRotation(), GetPitch() ); } @@ -392,14 +408,21 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const -void cArrowEntity::SpawnOn(cClientHandle & a_Client) +void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) { - a_Client.SendSpawnObject(*this, pkArrow, 0, 0, 0); + super::OnHitSolidBlock(a_HitPos, a_HitFace); + + // Broadcast the position and speed packets before teleporting: + BroadcastMovementUpdate(); + + // Teleport the entity to the exact hit coords: + m_World->BroadcastTeleportEntity(*this); } + void cArrowEntity::OnHitEntity(cEntity & a_EntityHit) { if (!a_EntityHit.IsMob() && !a_EntityHit.IsMinecart() && !a_EntityHit.IsPlayer()) diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index 5863b4f10..43aecac0e 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -151,7 +151,7 @@ protected: bool m_IsCritical; // cProjectileEntity overrides: - virtual void SpawnOn(cClientHandle & a_Client) override; + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit) override; // tolua_begin From 3b1c83acf8a0592f3c09a6bd530f8b695272b1ab Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 18:12:22 +0200 Subject: [PATCH 20/25] Renamed cWorld::DoExplosiontAt() to cWorld::DoExplosionAt() --- source/Bindings.cpp | 14 +++++++------- source/Blocks/BlockBed.cpp | 2 +- source/ChunkMap.cpp | 2 +- source/ChunkMap.h | 2 +- source/Entities/TNTEntity.cpp | 2 +- source/World.cpp | 4 ++-- source/World.h | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index ad9e85ada..d30636ba9 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -12428,9 +12428,9 @@ static int tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: DoExplosiontAt of class cWorld */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DoExplosiontAt00 -static int tolua_AllToLua_cWorld_DoExplosiontAt00(lua_State* tolua_S) +/* method: DoExplosionAt of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_DoExplosionAt00 +static int tolua_AllToLua_cWorld_DoExplosionAt00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -12458,16 +12458,16 @@ static int tolua_AllToLua_cWorld_DoExplosiontAt00(lua_State* tolua_S) eExplosionSource a_Source = ((eExplosionSource) (int) tolua_tonumber(tolua_S,7,0)); void* a_SourceData = ((void*) tolua_touserdata(tolua_S,8,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DoExplosiontAt'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DoExplosionAt'", NULL); #endif { - self->DoExplosiontAt(a_ExplosionSize,a_BlockX,a_BlockY,a_BlockZ,a_CanCauseFire,a_Source,a_SourceData); + self->DoExplosionAt(a_ExplosionSize,a_BlockX,a_BlockY,a_BlockZ,a_CanCauseFire,a_Source,a_SourceData); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'DoExplosiontAt'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'DoExplosionAt'.",&tolua_err); return 0; #endif } @@ -29808,7 +29808,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetSpawnZ",tolua_AllToLua_cWorld_GetSpawnZ00); tolua_function(tolua_S,"WakeUpSimulators",tolua_AllToLua_cWorld_WakeUpSimulators00); tolua_function(tolua_S,"WakeUpSimulatorsInArea",tolua_AllToLua_cWorld_WakeUpSimulatorsInArea00); - tolua_function(tolua_S,"DoExplosiontAt",tolua_AllToLua_cWorld_DoExplosiontAt00); + tolua_function(tolua_S,"DoExplosionAt",tolua_AllToLua_cWorld_DoExplosionAt00); tolua_function(tolua_S,"GetSignLines",tolua_AllToLua_cWorld_GetSignLines00); tolua_function(tolua_S,"GrowTree",tolua_AllToLua_cWorld_GrowTree00); tolua_function(tolua_S,"GrowTreeFromSapling",tolua_AllToLua_cWorld_GrowTreeFromSapling00); diff --git a/source/Blocks/BlockBed.cpp b/source/Blocks/BlockBed.cpp index f5e9db88d..66eb9130c 100644 --- a/source/Blocks/BlockBed.cpp +++ b/source/Blocks/BlockBed.cpp @@ -56,7 +56,7 @@ void cBlockBedHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, i if (a_World->GetDimension() != dimOverworld) { Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ); - a_World->DoExplosiontAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords); + a_World->DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords); } else { diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index a15f3aed1..3c098fdfe 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -1562,7 +1562,7 @@ bool cChunkMap::ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback -void cChunkMap::DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlocksAffected) +void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlocksAffected) { // Don't explode if outside of Y range (prevents the following test running into unallocated memory): if ((a_BlockY < 0) || (a_BlockY > cChunkDef::Height - 1)) diff --git a/source/ChunkMap.h b/source/ChunkMap.h index b0af0d779..fcb164f7b 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -184,7 +184,7 @@ public: bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Lua-accessible /// Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates - void DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected); + void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected); /// Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false. bool DoWithEntityByID(int a_UniqueID, cEntityCallback & a_Callback); // Lua-accessible diff --git a/source/Entities/TNTEntity.cpp b/source/Entities/TNTEntity.cpp index ad3d9ae0c..339107b2e 100644 --- a/source/Entities/TNTEntity.cpp +++ b/source/Entities/TNTEntity.cpp @@ -52,7 +52,7 @@ void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk) { Destroy(true); LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ()); - m_World->DoExplosiontAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this); + m_World->DoExplosionAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this); return; } } diff --git a/source/World.cpp b/source/World.cpp index ab783d7a7..a3572a48a 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -969,7 +969,7 @@ bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback -void cWorld::DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) +void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) { if (cPluginManager::Get()->CallHookExploding(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) || (a_ExplosionSize <= 0)) { @@ -979,7 +979,7 @@ void cWorld::DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_Bl // TODO: Add damage to entities, add support for pickups, and implement block hardiness Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); cVector3iArray BlocksAffected; - m_ChunkMap->DoExplosiontAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected); + m_ChunkMap->DoExplosionAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected); BroadcastSoundEffect("random.explode", (int)floor(a_BlockX * 8), (int)floor(a_BlockY * 8), (int)floor(a_BlockZ * 8), 1.0f, 0.6f); { cCSLock Lock(m_CSPlayers); diff --git a/source/World.h b/source/World.h index 9e2bf4e8f..1f475a4ac 100644 --- a/source/World.h +++ b/source/World.h @@ -414,13 +414,13 @@ public: | esCreeper | cCreeper * | | esBed | cVector3i * | | esEnderCrystal | Vector3i * | - | esGhastFireball | TBD | + | esGhastFireball | cGhastFireballEntity * | | esWitherSkullBlack | TBD | | esWitherSkullBlue | TBD | | esWitherBirth | TBD | | esPlugin | void * | */ - void DoExplosiontAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export + void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export /// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp From af694a516d3d6d659d02672f69cd50b98f9ac08d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 18:33:15 +0200 Subject: [PATCH 21/25] Debuggers plugin: Removed unneeded global --- MCServer/Plugins/Debuggers/Debuggers.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index be16e3465..f5cd57116 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -1,6 +1,5 @@ --- Global variables -PLUGIN = {}; -- Reference to own plugin object +-- Global variables g_DropSpensersToActivate = {}; -- A list of dispensers and droppers (as {World, X, Y Z} quadruplets) that are to be activated every tick g_HungerReportTick = 10; g_ShowFoodStats = false; -- When true, each player's food stats are sent to them every 10 ticks @@ -11,8 +10,6 @@ g_ShowFoodStats = false; -- When true, each player's food stats are sent to the function Initialize(Plugin) - PLUGIN = Plugin - Plugin:SetName("Debuggers") Plugin:SetVersion(1) @@ -480,6 +477,7 @@ end function OnWorldTick(a_World, a_Dt) + -- Report food stats, if switched on: local Tick = a_World:GetWorldAge(); if (not(g_ShowFoodStats) or (math.mod(Tick, 10) ~= 0)) then return false; From 06b01af017d373377a58604fa36a1607323fa6dc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 18:53:14 +0200 Subject: [PATCH 22/25] Implemented ghast fireball and firecharge projectiles --- MCServer/Plugins/Debuggers/Debuggers.lua | 16 ++++ source/Entities/ProjectileEntity.cpp | 109 +++++++++++++++++++++-- source/Entities/ProjectileEntity.h | 65 +++++++++++++- 3 files changed, 179 insertions(+), 11 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index f5cd57116..b895da05e 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -43,6 +43,7 @@ function Initialize(Plugin) PluginManager:BindCommand("/ench", "debuggers", HandleEnchCmd, "- Provides an instant dummy enchantment window"); PluginManager:BindCommand("/fs", "debuggers", HandleFoodStatsCmd, "- Turns regular foodstats message on or off"); PluginManager:BindCommand("/arr", "debuggers", HandleArrowCmd, "- Creates an arrow going away from the player"); + PluginManager:BindCommand("/fb", "debuggers", HandleFireballCmd, "- Creates a ghast fireball as if shot by the player"); -- Enable the following line for BlockArea / Generator interface testing: -- PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); @@ -823,3 +824,18 @@ end + +function HandleFireballCmd(a_Split, a_Player) + local World = a_Player:GetWorld(); + local Pos = a_Player:GetEyePosition(); + local Speed = a_Player:GetLookVector(); + Speed:Normalize(); + Pos = Pos + Speed * 2; + + World:CreateProjectile(Pos.x, Pos.y, Pos.z, cProjectileEntity.pkGhastFireball, a_Player, Speed * 10); + return true; +end + + + + diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index 81ac336f0..81a708f9a 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -214,10 +214,12 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, switch (a_Kind) { - case pkArrow: return new cArrowEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkEgg: return new cThrownEggEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkEnderPearl: return new cThrownEnderPearlEntity(a_Creator, a_X, a_Y, a_Z, Speed); - case pkSnowball: return new cThrownSnowballEntity (a_Creator, a_X, a_Y, a_Z, Speed); + case pkArrow: return new cArrowEntity (a_Creator, a_X, a_Y, a_Z, Speed); + case pkEgg: return new cThrownEggEntity (a_Creator, a_X, a_Y, a_Z, Speed); + case pkEnderPearl: return new cThrownEnderPearlEntity(a_Creator, a_X, a_Y, a_Z, Speed); + case pkSnowball: return new cThrownSnowballEntity (a_Creator, a_X, a_Y, a_Z, Speed); + case pkGhastFireball: return new cGhastFireballEntity (a_Creator, a_X, a_Y, a_Z, Speed); + case pkFireCharge: return new cFireChargeEntity (a_Creator, a_X, a_Y, a_Z, Speed); // TODO: the rest } @@ -309,8 +311,9 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) if (EntityCollisionCallback.HasHit()) { // An entity was hit: - // DEBUG: Vector3d HitPos = Pos + (NextPos - Pos) * EntityCollisionCallback.GetMinCoeff(); + + // DEBUG: LOGD("Projectile %d has hit an entity %d (%s) at {%.02f, %.02f, %.02f} (coeff %.03f)", m_UniqueID, EntityCollisionCallback.GetHitEntity()->GetUniqueID(), @@ -318,7 +321,8 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) HitPos.x, HitPos.y, HitPos.z, EntityCollisionCallback.GetMinCoeff() ); - OnHitEntity(*(EntityCollisionCallback.GetHitEntity())); + + OnHitEntity(*(EntityCollisionCallback.GetHitEntity()), HitPos); } // TODO: Test the entities in the neighboring chunks, too @@ -423,7 +427,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) -void cArrowEntity::OnHitEntity(cEntity & a_EntityHit) +void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) { if (!a_EntityHit.IsMob() && !a_EntityHit.IsMinecart() && !a_EntityHit.IsPlayer()) { @@ -523,3 +527,94 @@ void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_Hi +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cGhastFireballEntity : + +cGhastFireballEntity::cGhastFireballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : + super(pkGhastFireball, a_Creator, a_X, a_Y, a_Z, 1, 1) +{ + SetSpeed(a_Speed); + SetGravity(0); +} + + + + + +void cGhastFireballEntity::Explode(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + m_World->DoExplosionAt(1, a_BlockX, a_BlockY, a_BlockZ, true, esGhastFireball, this); +} + + + + + +void cGhastFireballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) +{ + Destroy(); + Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z)); +} + + + + + +void cGhastFireballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) +{ + Destroy(); + Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z)); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cFireChargeEntity : + +cFireChargeEntity::cFireChargeEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed) : + super(pkFireCharge, a_Creator, a_X, a_Y, a_Z, 0.3125, 0.3125) +{ + SetSpeed(a_Speed); + SetGravity(0); +} + + + + + +void cFireChargeEntity::Explode(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + if (m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) + { + m_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 1); + } +} + + + + + +void cFireChargeEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) +{ + Destroy(); + Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z)); +} + + + + + +void cFireChargeEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) +{ + Destroy(); + Explode((int)floor(a_HitPos.x), (int)floor(a_HitPos.y), (int)floor(a_HitPos.z)); + + // TODO: Some entities are immune to hits + a_EntityHit.StartBurning(5 * 20); // 5 seconds of burning +} + + + + diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index 43aecac0e..3e87f5a2c 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -51,7 +51,7 @@ public: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace); /// Called by the physics blocktracer when the entity hits another entity - virtual void OnHitEntity(cEntity & a_EntityHit) {} + virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) {} // tolua_begin @@ -152,7 +152,7 @@ protected: // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; - virtual void OnHitEntity(cEntity & a_EntityHit) override; + virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; // tolua_begin } ; @@ -231,8 +231,6 @@ public: cThrownSnowballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); protected: - - // tolua_end // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; @@ -245,6 +243,65 @@ protected: +class cGhastFireballEntity : + public cProjectileEntity +{ + typedef cProjectileEntity super; + +public: + + // tolua_end + + CLASS_PROTODEF(cGhastFireballEntity); + + cGhastFireballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); + +protected: + + void Explode(int a_BlockX, int a_BlockY, int a_BlockZ); + + // cProjectileEntity overrides: + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; + virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; + + // TODO: Deflecting the fireballs by arrow- or sword- hits + + // tolua_begin + +} ; + + + + + +class cFireChargeEntity : + public cProjectileEntity +{ + typedef cProjectileEntity super; + +public: + + // tolua_end + + CLASS_PROTODEF(cFireChargeEntity); + + cFireChargeEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); + +protected: + + void Explode(int a_BlockX, int a_BlockY, int a_BlockZ); + + // cProjectileEntity overrides: + virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override; + virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; + + // tolua_begin + +} ; + + + + // tolua_end From 7938f18c57c4ef3909d93b7c13f9e24b2b4c81f5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 21:26:17 +0200 Subject: [PATCH 23/25] Implemented loading more projectiles from MCA. --- source/Entities/ProjectileEntity.h | 7 +- source/WorldStorage/NBTChunkSerializer.cpp | 2 +- source/WorldStorage/WSSAnvil.cpp | 130 ++++++++++++++++++++- source/WorldStorage/WSSAnvil.h | 26 +++-- 4 files changed, 151 insertions(+), 14 deletions(-) diff --git a/source/Entities/ProjectileEntity.h b/source/Entities/ProjectileEntity.h index 3e87f5a2c..547aa174e 100644 --- a/source/Entities/ProjectileEntity.h +++ b/source/Entities/ProjectileEntity.h @@ -67,6 +67,11 @@ public: /// Returns true if the projectile has hit the ground and is stuck there bool IsInGround(void) const { return m_IsInGround; } + // tolua_end + + /// Sets the internal InGround flag. To be used by MCA loader only! + void SetIsInGround(bool a_IsInGround) { m_IsInGround = a_IsInGround; } + protected: eKind m_ProjectileKind; @@ -76,8 +81,6 @@ protected: /// True if the projectile has hit the ground and is stuck there bool m_IsInGround; - // tolua_end - // cEntity overrides: virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override; diff --git a/source/WorldStorage/NBTChunkSerializer.cpp b/source/WorldStorage/NBTChunkSerializer.cpp index baae0dc01..ef6165142 100644 --- a/source/WorldStorage/NBTChunkSerializer.cpp +++ b/source/WorldStorage/NBTChunkSerializer.cpp @@ -340,7 +340,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) m_Writer.AddShort("xTile", (Int16)floor(Pos.x)); m_Writer.AddShort("yTile", (Int16)floor(Pos.y)); m_Writer.AddShort("zTile", (Int16)floor(Pos.z)); - m_Writer.AddShort("inTile", 0); // TODO: Query the block type (is it needed?) + m_Writer.AddShort("inTile", 0); // TODO: Query the block type m_Writer.AddShort("shake", 0); // TODO: Any shake? m_Writer.AddByte ("inGround", a_Projectile->IsInGround() ? 1 : 0); diff --git a/source/WorldStorage/WSSAnvil.cpp b/source/WorldStorage/WSSAnvil.cpp index 3ab64148e..fa0066dc6 100644 --- a/source/WorldStorage/WSSAnvil.cpp +++ b/source/WorldStorage/WSSAnvil.cpp @@ -952,14 +952,34 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadMinecartHFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } - if (strncmp(a_IDTag, "Item", a_IDTagLength) == 0) + else if (strncmp(a_IDTag, "Item", a_IDTagLength) == 0) { LoadPickupFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } - if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0) + else if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0) { LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "Snowball", a_IDTagLength) == 0) + { + LoadSnowballFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } + else if (strncmp(a_IDTag, "Egg", a_IDTagLength) == 0) + { + LoadEggFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } + else if (strncmp(a_IDTag, "Fireball", a_IDTagLength) == 0) + { + LoadFireballFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } + else if (strncmp(a_IDTag, "SmallFireball", a_IDTagLength) == 0) + { + LoadFireChargeFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } + else if (strncmp(a_IDTag, "ThrownEnderpearl", a_IDTagLength) == 0) + { + LoadThrownEnderpearlFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } // TODO: other entities } @@ -1100,7 +1120,7 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { std::auto_ptr Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); - if (!LoadEntityBaseFromNBT(*Arrow.get(), a_NBT, a_TagIdx)) + if (!LoadProjectileBaseFromNBT(*Arrow.get(), a_NBT, a_TagIdx)) { return; } @@ -1136,6 +1156,86 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ +void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr Snowball(new cThrownSnowballEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + if (!LoadProjectileBaseFromNBT(*Snowball.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Store the new snowball in the entities list: + a_Entities.push_back(Snowball.release()); +} + + + + + +void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr Egg(new cThrownEggEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + if (!LoadProjectileBaseFromNBT(*Egg.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Store the new egg in the entities list: + a_Entities.push_back(Egg.release()); +} + + + + + +void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr Fireball(new cGhastFireballEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + if (!LoadProjectileBaseFromNBT(*Fireball.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Store the new fireball in the entities list: + a_Entities.push_back(Fireball.release()); +} + + + + + +void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr FireCharge(new cFireChargeEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + if (!LoadProjectileBaseFromNBT(*FireCharge.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Store the new FireCharge in the entities list: + a_Entities.push_back(FireCharge.release()); +} + + + + + +void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr Enderpearl(new cThrownEnderPearlEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); + if (!LoadProjectileBaseFromNBT(*Enderpearl.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Store the new enderpearl in the entities list: + a_Entities.push_back(Enderpearl.release()); +} + + + + + bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) { double Pos[3]; @@ -1167,6 +1267,30 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N +bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) +{ + if (!LoadEntityBaseFromNBT(a_Entity, a_NBT, a_TagIdx)) + { + return false; + } + + bool IsInGround = false; + int InGroundIdx = a_NBT.FindChildByName(a_TagIdx, "inGround"); + if (InGroundIdx > 0) + { + IsInGround = (a_NBT.GetByte(InGroundIdx) != 0); + } + a_Entity.SetIsInGround(IsInGround); + + // TODO: Load inTile, TileCoords + + return true; +} + + + + + bool cWSSAnvil::LoadDoublesListFromNBT(double * a_Doubles, int a_NumDoubles, const cParsedNBT & a_NBT, int a_TagIdx) { if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List) || (a_NBT.GetChildrenType(a_TagIdx) != TAG_Double)) diff --git a/source/WorldStorage/WSSAnvil.h b/source/WorldStorage/WSSAnvil.h index b2556ab50..d92a2df72 100644 --- a/source/WorldStorage/WSSAnvil.h +++ b/source/WorldStorage/WSSAnvil.h @@ -18,6 +18,8 @@ // fwd: ItemGrid.h class cItemGrid; +class cProjectileEntity; + @@ -138,18 +140,26 @@ protected: void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength); - void LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMinecartFFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMinecartTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMinecartHFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadArrowFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadMinecartFFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadMinecartTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadMinecartHFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadArrowFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadSnowballFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadEggFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFireballFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFireChargeFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); /// Loads entity common data from the NBT compound; returns true if successful bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); + /// Loads projectile common data from the NBT compound; returns true if successful + bool LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIx); + /// Loads an array of doubles of the specified length from the specified NBT list tag a_TagIdx; returns true if successful bool LoadDoublesListFromNBT(double * a_Doubles, int a_NumDoubles, const cParsedNBT & a_NBT, int a_TagIdx); From d6c4447022bf47c39747ddf428be75bf80880e98 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 21:26:50 +0200 Subject: [PATCH 24/25] Updated the API bindings. --- source/Bindings.cpp | 164 +++++++++++++++++++++++++++++++------------- source/Bindings.h | 2 +- 2 files changed, 119 insertions(+), 47 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index d30636ba9..e61757e69 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/03/13 10:19:58. +** Generated automatically by tolua++-1.0.92 on 09/07/13 21:26:23. */ #ifndef __cplusplus @@ -212,67 +212,69 @@ static int tolua_collect_Vector3d (lua_State* tolua_S) static void tolua_reg_types (lua_State* tolua_S) { tolua_usertype(tolua_S,"cThrownEnderPearlEntity"); - tolua_usertype(tolua_S,"cPluginManager"); - tolua_usertype(tolua_S,"TakeDamageInfo"); - tolua_usertype(tolua_S,"cMonster"); + tolua_usertype(tolua_S,"cFurnaceEntity"); + tolua_usertype(tolua_S,"cEntity"); tolua_usertype(tolua_S,"cCuboid"); - tolua_usertype(tolua_S,"cWindow"); - tolua_usertype(tolua_S,"cCraftingRecipe"); - tolua_usertype(tolua_S,"cPlugin"); - tolua_usertype(tolua_S,"cCraftingGrid"); - tolua_usertype(tolua_S,"cStringMap"); - tolua_usertype(tolua_S,"cItemGrid"); - tolua_usertype(tolua_S,"cBlockArea"); tolua_usertype(tolua_S,"cEnchantments"); - tolua_usertype(tolua_S,"cLuaWindow"); - tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"cMonster"); + tolua_usertype(tolua_S,"cPluginLua"); tolua_usertype(tolua_S,"cRoot"); - tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"std::vector"); - tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cPickup"); - tolua_usertype(tolua_S,"std::vector"); - tolua_usertype(tolua_S,"cBoundingBox"); - tolua_usertype(tolua_S,"cClientHandle"); + tolua_usertype(tolua_S,"cItems"); + tolua_usertype(tolua_S,"cFireChargeEntity"); + tolua_usertype(tolua_S,"cWorld"); tolua_usertype(tolua_S,"cChunkDesc"); tolua_usertype(tolua_S,"cFurnaceRecipe"); - tolua_usertype(tolua_S,"Vector3i"); - tolua_usertype(tolua_S,"cChatColor"); - tolua_usertype(tolua_S,"cThrownSnowballEntity"); - tolua_usertype(tolua_S,"cWebAdmin"); - tolua_usertype(tolua_S,"cCraftingRecipes"); - tolua_usertype(tolua_S,"cItems"); - tolua_usertype(tolua_S,"cWebPlugin"); - tolua_usertype(tolua_S,"cItem"); + tolua_usertype(tolua_S,"cPluginManager"); tolua_usertype(tolua_S,"Vector3f"); - tolua_usertype(tolua_S,"cArrowEntity"); - tolua_usertype(tolua_S,"cDropSpenserEntity"); - tolua_usertype(tolua_S,"sWebAdminPage"); - tolua_usertype(tolua_S,"HTTPFormData"); + tolua_usertype(tolua_S,"cCraftingRecipes"); tolua_usertype(tolua_S,"cChestEntity"); tolua_usertype(tolua_S,"cDispenserEntity"); - tolua_usertype(tolua_S,"HTTPRequest"); - tolua_usertype(tolua_S,"cBlockEntity"); - tolua_usertype(tolua_S,"cItemGrid::cListener"); - tolua_usertype(tolua_S,"HTTPTemplateRequest"); - tolua_usertype(tolua_S,"cFurnaceEntity"); - tolua_usertype(tolua_S,"cDropperEntity"); - tolua_usertype(tolua_S,"cPluginLua"); - tolua_usertype(tolua_S,"cBlockEntityWithItems"); + tolua_usertype(tolua_S,"cGhastFireballEntity"); tolua_usertype(tolua_S,"cLineBlockTracer"); - tolua_usertype(tolua_S,"cCriticalSection"); - tolua_usertype(tolua_S,"cIniFile"); - tolua_usertype(tolua_S,"cEntity"); tolua_usertype(tolua_S,"cListeners"); + tolua_usertype(tolua_S,"cThrownSnowballEntity"); + tolua_usertype(tolua_S,"Vector3d"); + tolua_usertype(tolua_S,"TakeDamageInfo"); + tolua_usertype(tolua_S,"cCraftingRecipe"); + tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cItemGrid"); + tolua_usertype(tolua_S,"cBlockArea"); + tolua_usertype(tolua_S,"cLuaWindow"); + tolua_usertype(tolua_S,"cInventory"); + tolua_usertype(tolua_S,"cBoundingBox"); + tolua_usertype(tolua_S,"cBlockEntityWithItems"); + tolua_usertype(tolua_S,"HTTPFormData"); + tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"cArrowEntity"); + tolua_usertype(tolua_S,"cDropSpenserEntity"); + tolua_usertype(tolua_S,"cWindow"); + tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cGroup"); + tolua_usertype(tolua_S,"cStringMap"); + tolua_usertype(tolua_S,"cBlockEntity"); + tolua_usertype(tolua_S,"cCriticalSection"); + tolua_usertype(tolua_S,"HTTPTemplateRequest"); + tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"std::vector"); + tolua_usertype(tolua_S,"cClientHandle"); + tolua_usertype(tolua_S,"cChatColor"); + tolua_usertype(tolua_S,"sWebAdminPage"); + tolua_usertype(tolua_S,"cWebPlugin"); + tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"cWebAdmin"); + tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"cPawn"); - tolua_usertype(tolua_S,"cThrownEggEntity"); + tolua_usertype(tolua_S,"cPlayer"); tolua_usertype(tolua_S,"cGroupManager"); tolua_usertype(tolua_S,"cBlockEntityWindowOwner"); - tolua_usertype(tolua_S,"cInventory"); + tolua_usertype(tolua_S,"HTTPRequest"); tolua_usertype(tolua_S,"cProjectileEntity"); - tolua_usertype(tolua_S,"cWorld"); - tolua_usertype(tolua_S,"cPlayer"); - tolua_usertype(tolua_S,"Vector3d"); + tolua_usertype(tolua_S,"cItemGrid::cListener"); + tolua_usertype(tolua_S,"cDropperEntity"); + tolua_usertype(tolua_S,"cThrownEggEntity"); } /* method: new of class cIniFile */ @@ -6719,6 +6721,68 @@ static int tolua_AllToLua_cEntity_SetGravity00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: SetRotationFromSpeed of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetRotationFromSpeed00 +static int tolua_AllToLua_cEntity_SetRotationFromSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetRotationFromSpeed'", NULL); +#endif + { + self->SetRotationFromSpeed(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetRotationFromSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetPitchFromSpeed of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPitchFromSpeed00 +static int tolua_AllToLua_cEntity_SetPitchFromSpeed00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetPitchFromSpeed'", NULL); +#endif + { + self->SetPitchFromSpeed(); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetPitchFromSpeed'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetRawDamageAgainst of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetRawDamageAgainst00 static int tolua_AllToLua_cEntity_GetRawDamageAgainst00(lua_State* tolua_S) @@ -29527,6 +29591,8 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"TakeDamage",tolua_AllToLua_cEntity_TakeDamage02); tolua_function(tolua_S,"GetGravity",tolua_AllToLua_cEntity_GetGravity00); tolua_function(tolua_S,"SetGravity",tolua_AllToLua_cEntity_SetGravity00); + tolua_function(tolua_S,"SetRotationFromSpeed",tolua_AllToLua_cEntity_SetRotationFromSpeed00); + tolua_function(tolua_S,"SetPitchFromSpeed",tolua_AllToLua_cEntity_SetPitchFromSpeed00); tolua_function(tolua_S,"GetRawDamageAgainst",tolua_AllToLua_cEntity_GetRawDamageAgainst00); tolua_function(tolua_S,"GetArmorCoverAgainst",tolua_AllToLua_cEntity_GetArmorCoverAgainst00); tolua_function(tolua_S,"GetKnockbackAmountAgainst",tolua_AllToLua_cEntity_GetKnockbackAmountAgainst00); @@ -29675,6 +29741,12 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_cclass(tolua_S,"cThrownSnowballEntity","cThrownSnowballEntity","cProjectileEntity",NULL); tolua_beginmodule(tolua_S,"cThrownSnowballEntity"); tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cGhastFireballEntity","cGhastFireballEntity","cProjectileEntity",NULL); + tolua_beginmodule(tolua_S,"cGhastFireballEntity"); + tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cFireChargeEntity","cFireChargeEntity","cProjectileEntity",NULL); + tolua_beginmodule(tolua_S,"cFireChargeEntity"); + tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cPluginManager","cPluginManager","",NULL); tolua_beginmodule(tolua_S,"cPluginManager"); tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUPS",cPluginManager::HOOK_BLOCK_TO_PICKUPS); diff --git a/source/Bindings.h b/source/Bindings.h index e214d7ff2..67e8ad14f 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 09/03/13 10:19:59. +** Generated automatically by tolua++-1.0.92 on 09/07/13 21:26:23. */ /* Exported function */ From d1b68f61500e975d01c4328c01da8ed52657a64d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Sep 2013 21:56:22 +0200 Subject: [PATCH 25/25] Added a (disabled) block logging to projectile path-tracing. --- source/Entities/ProjectileEntity.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/Entities/ProjectileEntity.cpp b/source/Entities/ProjectileEntity.cpp index 81a708f9a..4c8e680d0 100644 --- a/source/Entities/ProjectileEntity.cpp +++ b/source/Entities/ProjectileEntity.cpp @@ -45,6 +45,16 @@ protected: // cCallbacks overrides: virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { + /* + // DEBUG: + LOGD("Hit block %d:%d at {%d, %d, %d} face %d, %s (%s)", + a_BlockType, a_BlockMeta, + a_BlockX, a_BlockY, a_BlockZ, a_EntryFace, + g_BlockIsSolid[a_BlockType] ? "solid" : "non-solid", + ItemToString(cItem(a_BlockType, 1, a_BlockMeta)).c_str() + ); + */ + if (g_BlockIsSolid[a_BlockType]) { // The projectile hit a solid block