From 1cca9b13b3d320ff767cfc552413265b2ef6e0d6 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 6 Jun 2012 20:18:50 +0000 Subject: Item-dropping code rewritten and centralized - now there's only one place to modify if we want to split or merge same-item drops: cWorld:SpawnItemPickups(). Also, mined blocks can now drop more items, and they recognize if they're being mined by the correct tool. git-svn-id: http://mc-server.googlecode.com/svn/trunk@561 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- VC2008/MCServer.vcproj | 5 + source/Bindings.cpp | 136 +++++++++++++++- source/Bindings.h | 2 +- source/cBlockToPickup.cpp | 380 +++++++++++++++++++++++++++++++++++---------- source/cBlockToPickup.h | 28 +++- source/cCavespider.cpp | 30 +++- source/cChestEntity.cpp | 5 +- source/cChicken.cpp | 41 +++-- source/cChunk.cpp | 22 +-- source/cChunkMap.cpp | 18 +-- source/cChunkMap.h | 4 +- source/cClientHandle.cpp | 82 +++++----- source/cCow.cpp | 40 +++-- source/cCraftingWindow.cpp | 20 +-- source/cCreeper.cpp | 28 +++- source/cEnderman.cpp | 29 +++- source/cFluidSimulator.cpp | 35 +++-- source/cFurnaceEntity.cpp | 5 +- source/cGhast.cpp | 25 ++- source/cItem.h | 12 +- source/cMonster.cpp | 18 +-- source/cMonster.h | 10 +- source/cPig.cpp | 25 ++- source/cPiston.cpp | 22 +-- source/cPlayer.cpp | 101 +++++++----- source/cPluginManager.h | 1 + source/cSheep.cpp | 45 +++++- source/cSheep.h | 7 +- source/cSkeleton.cpp | 27 +++- source/cSlime.cpp | 22 ++- source/cSpider.cpp | 23 ++- source/cSquid.cpp | 14 +- source/cWorld.cpp | 51 +++++- source/cWorld.h | 11 +- source/cZombie.cpp | 27 +++- source/cZombiepigman.cpp | 31 +++- 36 files changed, 1056 insertions(+), 326 deletions(-) diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index e21dfbe19..e5a04a919 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="MCServer" ProjectGUID="{32012054-0C96-4C43-AB27-174FF8E72D66}" + RootNamespace="MCServer" Keyword="Win32Proj" TargetFrameworkVersion="0" > @@ -1848,6 +1849,10 @@ RelativePath="..\banned.ini" > + + diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 257e588b4..1ebe6ceec 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 06/05/12 17:10:07. +** Generated automatically by tolua++-1.0.92 on 06/06/12 21:50:56. */ #ifndef __cplusplus @@ -9895,8 +9895,7 @@ static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S) !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_isvaluenil(tolua_S,5,&tolua_err) || !tolua_isusertype(tolua_S,5,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,6,&tolua_err) + !tolua_isnoobj(tolua_S,5,&tolua_err) ) goto tolua_lerror; else @@ -9906,12 +9905,11 @@ static int tolua_AllToLua_cWorld_DigBlock00(lua_State* tolua_S) int a_X = ((int) tolua_tonumber(tolua_S,2,0)); int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); int a_Z = ((int) tolua_tonumber(tolua_S,4,0)); - cItem* a_PickupItem = ((cItem*) tolua_tousertype(tolua_S,5,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DigBlock'", NULL); #endif { - bool tolua_ret = (bool) self->DigBlock(a_X,a_Y,a_Z,*a_PickupItem); + bool tolua_ret = (bool) self->DigBlock(a_X,a_Y,a_Z); tolua_pushboolean(tolua_S,(bool)tolua_ret); } } @@ -17174,7 +17172,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_BLOCK_RED_MUSHROOM",E_BLOCK_RED_MUSHROOM); tolua_constant(tolua_S,"E_BLOCK_GOLD_BLOCK",E_BLOCK_GOLD_BLOCK); tolua_constant(tolua_S,"E_BLOCK_IRON_BLOCK",E_BLOCK_IRON_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STONE_SLAB",E_BLOCK_DOUBLE_STONE_SLAB); tolua_constant(tolua_S,"E_BLOCK_DOUBLE_STEP",E_BLOCK_DOUBLE_STEP); + tolua_constant(tolua_S,"E_BLOCK_STONE_SLAB",E_BLOCK_STONE_SLAB); tolua_constant(tolua_S,"E_BLOCK_STEP",E_BLOCK_STEP); tolua_constant(tolua_S,"E_BLOCK_BRICK",E_BLOCK_BRICK); tolua_constant(tolua_S,"E_BLOCK_TNT",E_BLOCK_TNT); @@ -17189,15 +17189,18 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_BLOCK_REDSTONE_WIRE",E_BLOCK_REDSTONE_WIRE); tolua_constant(tolua_S,"E_BLOCK_DIAMOND_ORE",E_BLOCK_DIAMOND_ORE); tolua_constant(tolua_S,"E_BLOCK_DIAMOND_BLOCK",E_BLOCK_DIAMOND_BLOCK); + tolua_constant(tolua_S,"E_BLOCK_CRAFTING_TABLE",E_BLOCK_CRAFTING_TABLE); tolua_constant(tolua_S,"E_BLOCK_WORKBENCH",E_BLOCK_WORKBENCH); tolua_constant(tolua_S,"E_BLOCK_CROPS",E_BLOCK_CROPS); tolua_constant(tolua_S,"E_BLOCK_SOIL",E_BLOCK_SOIL); tolua_constant(tolua_S,"E_BLOCK_FARMLAND",E_BLOCK_FARMLAND); tolua_constant(tolua_S,"E_BLOCK_FURNACE",E_BLOCK_FURNACE); + tolua_constant(tolua_S,"E_BLOCK_LIT_FURNACE",E_BLOCK_LIT_FURNACE); tolua_constant(tolua_S,"E_BLOCK_BURNING_FURNACE",E_BLOCK_BURNING_FURNACE); tolua_constant(tolua_S,"E_BLOCK_SIGN_POST",E_BLOCK_SIGN_POST); tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOOR",E_BLOCK_WOODEN_DOOR); tolua_constant(tolua_S,"E_BLOCK_LADDER",E_BLOCK_LADDER); + tolua_constant(tolua_S,"E_BLOCK_RAIL",E_BLOCK_RAIL); tolua_constant(tolua_S,"E_BLOCK_MINECART_TRACKS",E_BLOCK_MINECART_TRACKS); tolua_constant(tolua_S,"E_BLOCK_COBBLESTONE_STAIRS",E_BLOCK_COBBLESTONE_STAIRS); tolua_constant(tolua_S,"E_BLOCK_WALLSIGN",E_BLOCK_WALLSIGN); @@ -17215,6 +17218,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK); tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS); tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY); + tolua_constant(tolua_S,"E_BLOCK_SUGARCANE",E_BLOCK_SUGARCANE); tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS); tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX); tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE); @@ -17259,6 +17263,15 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_BLOCK_DRAGON_EGG",E_BLOCK_DRAGON_EGG); tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_OFF",E_BLOCK_REDSTONE_LAMP_OFF); tolua_constant(tolua_S,"E_BLOCK_REDSTONE_LAMP_ON",E_BLOCK_REDSTONE_LAMP_ON); + tolua_constant(tolua_S,"E_BLOCK_DOUBLE_WOODEN_SLAB",E_BLOCK_DOUBLE_WOODEN_SLAB); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_SLAB",E_BLOCK_WOODEN_SLAB); + tolua_constant(tolua_S,"E_BLOCK_COCA_PLANT",E_BLOCK_COCA_PLANT); + tolua_constant(tolua_S,"E_BLOCK_SANDSTONE_STAIRS",E_BLOCK_SANDSTONE_STAIRS); + tolua_constant(tolua_S,"E_BLOCK_EMERALD_ORE",E_BLOCK_EMERALD_ORE); + tolua_constant(tolua_S,"E_BLOCK_ENDER_CHEST",E_BLOCK_ENDER_CHEST); + tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE_HOOK",E_BLOCK_TRIPWIRE_HOOK); + tolua_constant(tolua_S,"E_BLOCK_TRIPWIRE",E_BLOCK_TRIPWIRE); + tolua_constant(tolua_S,"E_BLOCK_EMERALD_BLOCK",E_BLOCK_EMERALD_BLOCK); tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_); tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY); tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE); @@ -17303,7 +17316,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM); tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK); tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_STONE_SLAB",E_ITEM_DOUBLE_STONE_SLAB); tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP); + tolua_constant(tolua_S,"E_ITEM_STONE_SLAB",E_ITEM_STONE_SLAB); tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP); tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK); tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT); @@ -17375,10 +17390,20 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL); tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME); tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE); + tolua_constant(tolua_S,"E_ITEM_DOUBLE_WOODEN_SLAB",E_ITEM_DOUBLE_WOODEN_SLAB); + tolua_constant(tolua_S,"E_ITEM_WOODEN_SLAB",E_ITEM_WOODEN_SLAB); + tolua_constant(tolua_S,"E_ITEM_COCA_PLANT",E_ITEM_COCA_PLANT); + tolua_constant(tolua_S,"E_ITEM_SANDSTONE_STAIRS",E_ITEM_SANDSTONE_STAIRS); + tolua_constant(tolua_S,"E_ITEM_EMERALD_ORE",E_ITEM_EMERALD_ORE); + tolua_constant(tolua_S,"E_ITEM_ENDER_CHEST",E_ITEM_ENDER_CHEST); + tolua_constant(tolua_S,"E_ITEM_TRIPWIRE_HOOK",E_ITEM_TRIPWIRE_HOOK); + tolua_constant(tolua_S,"E_ITEM_TRIPWIRE",E_ITEM_TRIPWIRE); + tolua_constant(tolua_S,"E_ITEM_EMERALD_BLOCK",E_ITEM_EMERALD_BLOCK); tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL); tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE); tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE); tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL); + tolua_constant(tolua_S,"E_ITEM_RED_APPLE",E_ITEM_RED_APPLE); tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE); tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW); tolua_constant(tolua_S,"E_ITEM_ARROW",E_ITEM_ARROW); @@ -17457,6 +17482,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK); tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK); tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY); + tolua_constant(tolua_S,"E_ITEM_SUGARCANE",E_ITEM_SUGARCANE); tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE); tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER); tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK); @@ -17502,6 +17528,12 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON); tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER); tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON); + tolua_constant(tolua_S,"E_ITEM_SPAWN_EGG",E_ITEM_SPAWN_EGG); + tolua_constant(tolua_S,"E_ITEM_BOTTLE_O_ENCHANTING",E_ITEM_BOTTLE_O_ENCHANTING); + tolua_constant(tolua_S,"E_ITEM_FIRE_CHARGE",E_ITEM_FIRE_CHARGE); + tolua_constant(tolua_S,"E_ITEM_BOOK_AND_QUILL",E_ITEM_BOOK_AND_QUILL); + tolua_constant(tolua_S,"E_ITEM_WRITTEN_BOOK",E_ITEM_WRITTEN_BOOK); + tolua_constant(tolua_S,"E_ITEM_EMERALD",E_ITEM_EMERALD); tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC); tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC); tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC); @@ -17532,6 +17564,99 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_META_TALL_GRASS_DEAD_SHRUB",E_META_TALL_GRASS_DEAD_SHRUB); tolua_constant(tolua_S,"E_META_TALL_GRASS_GRASS",E_META_TALL_GRASS_GRASS); tolua_constant(tolua_S,"E_META_TALL_GRASS_FERN",E_META_TALL_GRASS_FERN); + tolua_constant(tolua_S,"E_META_SANDSTONE_NORMAL",E_META_SANDSTONE_NORMAL); + tolua_constant(tolua_S,"E_META_SANDSTONE_ORNAMENT",E_META_SANDSTONE_ORNAMENT); + tolua_constant(tolua_S,"E_META_SANDSTONE_SMOOTH",E_META_SANDSTONE_SMOOTH); + tolua_constant(tolua_S,"E_META_WOOL_WHITE",E_META_WOOL_WHITE); + tolua_constant(tolua_S,"E_META_WOOL_ORANGE",E_META_WOOL_ORANGE); + tolua_constant(tolua_S,"E_META_WOOL_MAGENTA",E_META_WOOL_MAGENTA); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTBLUE",E_META_WOOL_LIGHTBLUE); + tolua_constant(tolua_S,"E_META_WOOL_YELLOW",E_META_WOOL_YELLOW); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTGREEN",E_META_WOOL_LIGHTGREEN); + tolua_constant(tolua_S,"E_META_WOOL_PINK",E_META_WOOL_PINK); + tolua_constant(tolua_S,"E_META_WOOL_GRAY",E_META_WOOL_GRAY); + tolua_constant(tolua_S,"E_META_WOOL_LIGHTGRAY",E_META_WOOL_LIGHTGRAY); + tolua_constant(tolua_S,"E_META_WOOL_CYAN",E_META_WOOL_CYAN); + tolua_constant(tolua_S,"E_META_WOOL_PURPLE",E_META_WOOL_PURPLE); + tolua_constant(tolua_S,"E_META_WOOL_BLUE",E_META_WOOL_BLUE); + tolua_constant(tolua_S,"E_META_WOOL_BROWN",E_META_WOOL_BROWN); + tolua_constant(tolua_S,"E_META_WOOL_GREEN",E_META_WOOL_GREEN); + tolua_constant(tolua_S,"E_META_WOOL_RED",E_META_WOOL_RED); + tolua_constant(tolua_S,"E_META_WOOL_BLACK",E_META_WOOL_BLACK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE",E_META_DOUBLE_STEP_STONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_SANDSTONE",E_META_DOUBLE_STEP_SANDSTONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_WOODEN",E_META_DOUBLE_STEP_WOODEN); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_COBBLESTONE",E_META_DOUBLE_STEP_COBBLESTONE); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_BRICK",E_META_DOUBLE_STEP_BRICK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_BRICK",E_META_DOUBLE_STEP_STONE_BRICK); + tolua_constant(tolua_S,"E_META_DOUBLE_STEP_STONE_SECRET",E_META_DOUBLE_STEP_STONE_SECRET); + tolua_constant(tolua_S,"E_META_STEP_STONE",E_META_STEP_STONE); + tolua_constant(tolua_S,"E_META_STEP_SANDSTONE",E_META_STEP_SANDSTONE); + tolua_constant(tolua_S,"E_META_STEP_PLANKS",E_META_STEP_PLANKS); + tolua_constant(tolua_S,"E_META_STEP_COBBLESTONE",E_META_STEP_COBBLESTONE); + tolua_constant(tolua_S,"E_META_STEP_BRICK",E_META_STEP_BRICK); + tolua_constant(tolua_S,"E_META_STEP_STONE_BRICK",E_META_STEP_STONE_BRICK); + tolua_constant(tolua_S,"E_META_STEP_STONE_SECRET",E_META_STEP_STONE_SECRET); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE",E_META_SILVERFISH_EGG_STONE); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_COBBLESTONE",E_META_SILVERFISH_EGG_COBBLESTONE); + tolua_constant(tolua_S,"E_META_SILVERFISH_EGG_STONE_BRICK",E_META_SILVERFISH_EGG_STONE_BRICK); + tolua_constant(tolua_S,"E_META_STONE_BRICK_NORMAL",E_META_STONE_BRICK_NORMAL); + tolua_constant(tolua_S,"E_META_STONE_BRICK_MOSSY",E_META_STONE_BRICK_MOSSY); + tolua_constant(tolua_S,"E_META_STONE_BRICK_CRACKED",E_META_STONE_BRICK_CRACKED); + tolua_constant(tolua_S,"E_META_STONE_BRICK_ORNAMENT",E_META_STONE_BRICK_ORNAMENT); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_APPLE",E_BLOCK_WOODEN_DOUBLE_STEP_APPLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER",E_BLOCK_WOODEN_DOUBLE_STEP_CONIFER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH",E_BLOCK_WOODEN_DOUBLE_STEP_BIRCH); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE",E_BLOCK_WOODEN_DOUBLE_STEP_JUNGLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_APPLE",E_BLOCK_WOODEN_STEP_APPLE); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_CONIFER",E_BLOCK_WOODEN_STEP_CONIFER); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_BIRCH",E_BLOCK_WOODEN_STEP_BIRCH); + tolua_constant(tolua_S,"E_BLOCK_WOODEN_STEP_JUNGLE",E_BLOCK_WOODEN_STEP_JUNGLE); + tolua_constant(tolua_S,"E_META_COAL_NORMAL",E_META_COAL_NORMAL); + tolua_constant(tolua_S,"E_META_COAL_CHARCOAL",E_META_COAL_CHARCOAL); + tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_NORMAL",E_META_GOLDEN_APPLE_NORMAL); + tolua_constant(tolua_S,"E_META_GOLDEN_APPLE_ENCHANTED",E_META_GOLDEN_APPLE_ENCHANTED); + tolua_constant(tolua_S,"E_META_DYE_BLACK",E_META_DYE_BLACK); + tolua_constant(tolua_S,"E_META_DYE_RED",E_META_DYE_RED); + tolua_constant(tolua_S,"E_META_DYE_GREEN",E_META_DYE_GREEN); + tolua_constant(tolua_S,"E_META_DYE_BROWN",E_META_DYE_BROWN); + tolua_constant(tolua_S,"E_META_DYE_BLUE",E_META_DYE_BLUE); + tolua_constant(tolua_S,"E_META_DYE_PURPLE",E_META_DYE_PURPLE); + tolua_constant(tolua_S,"E_META_DYE_CYAN",E_META_DYE_CYAN); + tolua_constant(tolua_S,"E_META_DYE_LIGHTGRAY",E_META_DYE_LIGHTGRAY); + tolua_constant(tolua_S,"E_META_DYE_GRAY",E_META_DYE_GRAY); + tolua_constant(tolua_S,"E_META_DYE_PINK",E_META_DYE_PINK); + tolua_constant(tolua_S,"E_META_DYE_LIGHTGREEN",E_META_DYE_LIGHTGREEN); + tolua_constant(tolua_S,"E_META_DYE_YELLOW",E_META_DYE_YELLOW); + tolua_constant(tolua_S,"E_META_DYE_LIGHTBLUE",E_META_DYE_LIGHTBLUE); + tolua_constant(tolua_S,"E_META_DYE_MAGENTA",E_META_DYE_MAGENTA); + tolua_constant(tolua_S,"E_META_DYE_ORANGE",E_META_DYE_ORANGE); + tolua_constant(tolua_S,"E_META_DYE_WHITE",E_META_DYE_WHITE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CREEPER",E_META_SPAWN_EGG_CREEPER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SKELETON",E_META_SPAWN_EGG_SKELETON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SPIDER",E_META_SPAWN_EGG_SPIDER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE",E_META_SPAWN_EGG_ZOMBIE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SLIME",E_META_SPAWN_EGG_SLIME); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_GHAST",E_META_SPAWN_EGG_GHAST); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ZOMBIE_PIGMAN",E_META_SPAWN_EGG_ZOMBIE_PIGMAN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDERMAN",E_META_SPAWN_EGG_ENDERMAN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CAVE_SPIDER",E_META_SPAWN_EGG_CAVE_SPIDER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SILVERFISH",E_META_SPAWN_EGG_SILVERFISH); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_BLAZE",E_META_SPAWN_EGG_BLAZE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_MAGMA_CUBE",E_META_SPAWN_EGG_MAGMA_CUBE); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_GIANT",E_META_SPAWN_EGG_GIANT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_ENDER_DRAGON",E_META_SPAWN_EGG_ENDER_DRAGON); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_PIG",E_META_SPAWN_EGG_PIG); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SHEEP",E_META_SPAWN_EGG_SHEEP); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_COW",E_META_SPAWN_EGG_COW); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_CHICKEN",E_META_SPAWN_EGG_CHICKEN); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SQUID",E_META_SPAWN_EGG_SQUID); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_WOLF",E_META_SPAWN_EGG_WOLF); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_MOOSHROOM",E_META_SPAWN_EGG_MOOSHROOM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_OCELOT",E_META_SPAWN_EGG_OCELOT); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_VILLAGER",E_META_SPAWN_EGG_VILLAGER); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_SNOW_GOLEM",E_META_SPAWN_EGG_SNOW_GOLEM); + tolua_constant(tolua_S,"E_META_SPAWN_EGG_IRON_GOLEM",E_META_SPAWN_EGG_IRON_GOLEM); tolua_function(tolua_S,"BlockStringToType",tolua_AllToLua_BlockStringToType00); tolua_function(tolua_S,"StringToItem",tolua_AllToLua_StringToItem00); tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE); @@ -17786,6 +17911,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_PLUGIN_KILLED",cPluginManager::E_PLUGIN_KILLED); tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATED",cPluginManager::E_PLUGIN_CHUNK_GENERATED); tolua_constant(tolua_S,"E_PLUGIN_CHUNK_GENERATING",cPluginManager::E_PLUGIN_CHUNK_GENERATING); + tolua_constant(tolua_S,"E_PLUGIN_BLOCK_TO_DROPS",cPluginManager::E_PLUGIN_BLOCK_TO_DROPS); tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cPluginManager_GetPluginManager00); tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00); tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00); diff --git a/source/Bindings.h b/source/Bindings.h index 707a60575..568a4625f 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 06/05/12 17:10:08. +** Generated automatically by tolua++-1.0.92 on 06/06/12 21:50:56. */ /* Exported function */ diff --git a/source/cBlockToPickup.cpp b/source/cBlockToPickup.cpp index 73d44afee..c9c8cbb67 100644 --- a/source/cBlockToPickup.cpp +++ b/source/cBlockToPickup.cpp @@ -4,96 +4,310 @@ #include "cBlockToPickup.h" #include "Defines.h" #include "BlockID.h" -#include "stdlib.h" #include "MersenneTwister.h" -ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_UsedItemID ) -{ - MTRand r1; - (void)a_UsedItemID; - switch( a_BlockID ) + + + +static void AddRandomDrop(cItems & a_Drops, MTRand & r1, int a_OneInNChance, ENUM_ITEM_ID a_ItemID) +{ + if (r1.randInt(a_OneInNChance - 1) != 0) { - case E_BLOCK_AIR: - return E_ITEM_EMPTY; - case E_BLOCK_COBBLESTONE: - case E_BLOCK_STONE: - if(ItemCategory::IsPickaxe(a_UsedItemID)) - return E_ITEM_COBBLESTONE; - return E_ITEM_EMPTY; - case E_BLOCK_GRASS: - return E_ITEM_DIRT; - case E_BLOCK_FIRE: - return E_ITEM_EMPTY; - case E_BLOCK_GLASS: - return E_ITEM_EMPTY; - case E_BLOCK_DIRT: - return E_ITEM_DIRT; - case E_BLOCK_LOG: - return E_ITEM_LOG; - case E_BLOCK_LEAVES: - if( a_UsedItemID == E_ITEM_SHEARS ) - return E_ITEM_LEAVES; - else - if(r1.randInt() % 5 == 0) return E_ITEM_SAPLING; - return E_ITEM_EMPTY; - case E_BLOCK_COAL_ORE: - return E_ITEM_COAL; - case E_BLOCK_LAPIS_ORE: - return E_ITEM_DYE; - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_REDSTONE_ORE: - return E_ITEM_REDSTONE_DUST; - case E_BLOCK_DIAMOND_ORE: - return E_ITEM_DIAMOND; - case E_BLOCK_IRON_BLOCK: - return E_ITEM_IRON_BLOCK; - case E_BLOCK_DIAMOND_BLOCK: - return E_ITEM_DIAMOND_BLOCK; - case E_BLOCK_GOLD_BLOCK: - return E_ITEM_GOLD_BLOCK; - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: - return E_ITEM_SIGN; - case E_BLOCK_REDSTONE_WIRE: - return E_ITEM_REDSTONE_DUST; - case E_BLOCK_REDSTONE_TORCH_OFF: - return E_ITEM_REDSTONE_TORCH_ON; - case E_BLOCK_MELON: - return E_ITEM_MELON_SLICE; - case E_BLOCK_WOODEN_DOOR: - return E_ITEM_WOODEN_DOOR; - case E_BLOCK_IRON_DOOR: - return E_ITEM_IRON_DOOR; - case E_BLOCK_GLOWSTONE: - return E_ITEM_GLOWSTONE_DUST; - case E_BLOCK_DOUBLE_STEP: - return E_ITEM_STEP; - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - return E_ITEM_REDSTONE_REPEATER; - default: - return (ENUM_ITEM_ID)a_BlockID; + return; } + a_Drops.push_back(cItem(a_ItemID)); } -char cBlockToPickup::PickupCount(unsigned char a_BlockID) + + + + +void cBlockToPickup::ToPickup(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedItemID, cItems & a_Drops) { MTRand r1; - switch(a_BlockID) + + switch (a_BlockType) { - case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_REDSTONE_ORE: - return r1.randInt() % 2 + 4; - case E_BLOCK_GLOWSTONE: - return r1.randInt() % 3 + 2; - case E_BLOCK_MELON: - return r1.randInt() % 8 + 3; - case E_BLOCK_LAPIS_ORE: - return r1.randInt() % 5 + 4; - case E_BLOCK_DOUBLE_STEP: - return 2; - default: - return 1; - } -} \ No newline at end of file + // Blocks that always drop themselves as the only item, no matter what tool; copy damage from meta: + case E_BLOCK_LOG: + case E_BLOCK_PLANKS: + case E_BLOCK_WOOL: + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, a_BlockMeta)); + return; + } + + + // Blocks that always drop themselves as the only item, no matter what tool, set damage value zero: + case E_BLOCK_DIRT: + case E_BLOCK_SAPLING: + case E_BLOCK_SAND: + case E_BLOCK_TORCH: + case E_BLOCK_YELLOW_FLOWER: + case E_BLOCK_RED_ROSE: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_TNT: + case E_BLOCK_CRAFTING_TABLE: + case E_BLOCK_FURNACE: + case E_BLOCK_CACTUS: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_POWERED_RAIL: + case E_BLOCK_DETECTOR_RAIL: + case E_BLOCK_RAIL: + case E_BLOCK_LADDER: + case E_BLOCK_LEVER: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_STONE_BUTTON: + case E_BLOCK_JUKEBOX: + case E_BLOCK_FENCE: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_PUMPKIN: + case E_BLOCK_NETHERRACK: + case E_BLOCK_SOULSAND: + case E_BLOCK_JACK_O_LANTERN: + case E_BLOCK_TRAPDOOR: + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1, 0)); + return; + } + + + // Blocks that always drop a single item, no matter what tool: + case E_BLOCK_SIGN_POST: + case E_BLOCK_WALLSIGN: a_Drops.push_back(cItem(E_ITEM_SIGN, 1)); return; + case E_BLOCK_REDSTONE_WIRE: a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); return; + case E_BLOCK_GLOWSTONE: a_Drops.push_back(cItem(E_ITEM_GLOWSTONE_DUST, 1)); return; + case E_BLOCK_REDSTONE_REPEATER_OFF: + case E_BLOCK_REDSTONE_REPEATER_ON: a_Drops.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1)); return; + case E_BLOCK_COBWEB: a_Drops.push_back(cItem(E_ITEM_STRING, 1)); return; + case E_BLOCK_FARMLAND: + case E_BLOCK_GRASS: a_Drops.push_back(cItem(E_ITEM_DIRT, 1)); return; + case E_BLOCK_LIT_FURNACE: a_Drops.push_back(cItem(E_ITEM_FURNACE, 1)); return; + case E_BLOCK_SUGARCANE: a_Drops.push_back(cItem(E_ITEM_SUGARCANE, 1)); return; + case E_BLOCK_PUMPKIN_STEM: a_Drops.push_back(cItem(E_ITEM_PUMPKIN_SEEDS, 1)); return; + case E_BLOCK_MELON_STEM: a_Drops.push_back(cItem(E_ITEM_MELON_SEEDS, 1)); return; + + + // Doors seem to need their meta set to 1 + case E_BLOCK_WOODEN_DOOR: a_Drops.push_back(cItem(E_ITEM_WOODEN_DOOR, 1, 1)); return; + case E_BLOCK_IRON_DOOR: a_Drops.push_back(cItem(E_ITEM_IRON_DOOR, 1, 1)); return; + + + //////////////////////// + // Ores: + + // Coal ore requires a pickaxe: + case E_BLOCK_COAL_ORE: + { + if (ItemCategory::IsPickaxe(a_UsedItemID)) + { + a_Drops.push_back(cItem(E_ITEM_COAL, 1)); + } + return; + } + + // Iron ore requires a stone or better pickaxe: + case E_BLOCK_IRON_ORE: + { + if ( + (a_UsedItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_IRON_ORE, 1)); + } + return; + } + + // Gold and diamond ores require an iron or better pickaxe: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_DIAMOND_ORE: + { + if ( + (a_UsedItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Obsidian require a diamond pickaxe: + case E_BLOCK_OBSIDIAN: + { + if (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Redstone requires an iron or better pickaxe: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_REDSTONE_ORE: + { + if ( + (a_UsedItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_REDSTONE_DUST, 4 + (short)r1.randInt(1))); + } + return; + } + + // Lapis ore requires a stone or better pickaxe: + case E_BLOCK_LAPIS_ORE: + { + if ( + (a_UsedItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItemID == E_ITEM_GOLD_PICKAXE) || + (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem(E_ITEM_DYE, 4 + (short)r1.randInt(4), E_META_DYE_BLUE)); + } + return; + } + + + //////////////////////// + // Resource blocks: + + // Iron and lapis blocks require a stone or better pickaxe: + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_LAPIS_BLOCK: + { + if ( + (a_UsedItemID == E_ITEM_STONE_PICKAXE) || + (a_UsedItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + // Diamond and gold blocks require an iron or better pickaxe: + case E_BLOCK_DIAMOND_BLOCK: + { + if ( + (a_UsedItemID == E_ITEM_IRON_PICKAXE) || + (a_UsedItemID == E_ITEM_DIAMOND_PICKAXE) + ) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + } + + + // These blocks require a pickaxe to drop themselves: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_BRICK: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_STONE_PRESSURE_PLATE: + { + if (ItemCategory::IsPickaxe(a_UsedItemID)) + { + a_Drops.push_back(cItem((ENUM_ITEM_ID)a_BlockType, 1)); + } + return; + } + + + // Stone requires a pickaxe to drop cobblestone: + case E_BLOCK_STONE: + { + if (ItemCategory::IsPickaxe(a_UsedItemID)) + { + a_Drops.push_back(cItem(E_ITEM_COBBLESTONE, 1)); + } + return; + } + + + // Snow requires a shovel to harvest: + case E_BLOCK_SNOW: + { + if (ItemCategory::IsShovel(a_UsedItemID)) + { + a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 1)); + } + return; + } + + + // Leaves require shears for harvesting and have a chance of dropping a sapling and a red apple: + case E_BLOCK_LEAVES: + { + if (a_UsedItemID == E_ITEM_SHEARS) + { + a_Drops.push_back(cItem(E_ITEM_LEAVES, 1)); + } + else + { + AddRandomDrop(a_Drops, r1, 5, E_ITEM_SAPLING); + AddRandomDrop(a_Drops, r1, 200, E_ITEM_APPLE); + } + return; + } + + + // Crops drop a wheat and possibly another seeds when ripe; always drop at least a single seed + case E_BLOCK_CROPS: + { + if (a_BlockMeta == 7) + { + AddRandomDrop(a_Drops, r1, 3, E_ITEM_SEEDS); + a_Drops.push_back(cItem(E_ITEM_WHEAT, 1)); + } + a_Drops.push_back(cItem(E_ITEM_SEEDS, 1)); + return; + } + + + // Vines drop only with shears, otherwise they are destroyed + case E_BLOCK_VINES: + { + if (a_UsedItemID == E_ITEM_SHEARS) + { + a_Drops.push_back(cItem(E_ITEM_VINES, 1)); + } + return; + } + + + // Random multi-drop blocks: + case E_BLOCK_TALL_GRASS: a_Drops.push_back(cItem(E_ITEM_SEEDS, (short)r1.randInt(3) / 2, 1)); return; + case E_BLOCK_MELON: a_Drops.push_back(cItem(E_ITEM_MELON_SLICE, 3 + (short)r1.randInt(2), 1)); return; + + + // Fixed multi-drop blocks: + case E_BLOCK_DOUBLE_STONE_SLAB: a_Drops.push_back(cItem(E_ITEM_STONE_SLAB, 2, 0)); return; + case E_BLOCK_DOUBLE_WOODEN_SLAB: a_Drops.push_back(cItem(E_ITEM_STEP, 2, 0)); return; + case E_BLOCK_SNOW_BLOCK: a_Drops.push_back(cItem(E_ITEM_SNOWBALL, 4, 0)); return; + + default: + { + return; + } + } // switch (a_BlockType) +} + + + + + diff --git a/source/cBlockToPickup.h b/source/cBlockToPickup.h index a59d64318..315d75b33 100644 --- a/source/cBlockToPickup.h +++ b/source/cBlockToPickup.h @@ -1,14 +1,28 @@ #pragma once #ifndef _WIN32 -#include "BlockID.h" + #include "BlockID.h" #else -enum ENUM_ITEM_ID; + enum ENUM_ITEM_ID; #endif -class cBlockToPickup -{ +#include "cItem.h" + + + + + +class cBlockToPickup // tolua_export +{ // tolua_export public: - static ENUM_ITEM_ID ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_UsedItemID ); - static char PickupCount(unsigned char a_BlockID); -}; + /// For a given block and tool, returns the list of drops generated + static void ToPickup(BLOCKTYPE a_BlockID, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedItemID, cItems & a_Drops); // tolua_export + + /// Returns true if the tool used for the block is the right one for the job. cClientHandle uses this to determine whether to decrease tool durability twice as much + static bool IsRightTool(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, ENUM_ITEM_ID a_UsedTool); // tolua_export + +}; // tolua_export + + + + diff --git a/source/cCavespider.cpp b/source/cCavespider.cpp index 5008270f1..8c2a1ca2c 100644 --- a/source/cCavespider.cpp +++ b/source/cCavespider.cpp @@ -3,33 +3,57 @@ #include "cCavespider.h" + + + + cCavespider::cCavespider() { m_MobType = 59; GetMonsterConfig("Cavespider"); } + + + + cCavespider::~cCavespider() { } + + + + bool cCavespider::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cCavespider" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cCavespider::Tick(float a_Dt) { cMonster::Tick(a_Dt); m_EMPersonality = (GetWorld()->GetWorldTime() < (12000 + 1000) ) ? PASSIVE : AGGRESSIVE; } + + + + void cCavespider::KilledBy( cEntity* a_Killer ) { - cMonster::RandomDropItem(E_ITEM_STRING, 0, 2); - - cMonster::RandomDropItem(E_ITEM_SPIDER_EYE, 0, 1); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); + AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); cMonster::KilledBy( a_Killer ); } + + + + diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index 7a0de425a..c7f4e6b0d 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -54,15 +54,16 @@ cChestEntity::~cChestEntity() void cChestEntity::Destroy() { // Drop items + cItems Pickups; for( int i = 0; i < c_ChestHeight * c_ChestWidth; ++i ) { if( !m_Content[i].IsEmpty() ) { - cPickup * Pickup = new cPickup( m_PosX * 32 + 16, m_PosY * 32 + 16, m_PosZ * 32 + 16, m_Content[i], 0, 1.f, 0 ); - Pickup->Initialize(m_World); + Pickups.push_back(m_Content[i]); m_Content[i].Empty(); } } + m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); if (m_JoinedChest) { m_JoinedChest->RemoveJoinedChest(this); diff --git a/source/cChicken.cpp b/source/cChicken.cpp index 37321410b..2073393d6 100644 --- a/source/cChicken.cpp +++ b/source/cChicken.cpp @@ -3,7 +3,14 @@ #include "cChicken.h" -//TODO Drop egg every 5-10 minutes + + + + +// TODO Drop egg every 5-10 minutes + + + cChicken::cChicken() @@ -12,28 +19,38 @@ cChicken::cChicken() GetMonsterConfig("Chicken"); } + + + + cChicken::~cChicken() { } + + + + bool cChicken::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cChicken" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cChicken::KilledBy( cEntity* a_Killer ) { - //Drops 0-2 Feathers - cMonster::RandomDropItem(E_ITEM_FEATHER, 0, 2); - - // Raw Chicken - if(GetMetaData() == BURNING) - { - cMonster::DropItem(E_ITEM_COOKED_CHICKEN, 1); - }else{ - cMonster::DropItem(E_ITEM_RAW_CHICKEN, 1); - } + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_FEATHER); + Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1)); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); -} \ No newline at end of file +} + + + + diff --git a/source/cChunk.cpp b/source/cChunk.cpp index c918c589e..6d260e5b1 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -419,7 +419,8 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) unsigned int index = (*itr); Vector3i BlockPos = IndexToCoordinate( index ); - char BlockID = GetBlock( index ); + BLOCKTYPE BlockID = GetBlock( index ); + NIBBLETYPE BlockMeta = GetMeta(index); switch ( BlockID ) { case E_BLOCK_REDSTONE_REPEATER_OFF: @@ -443,16 +444,17 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) case E_BLOCK_RED_MUSHROOM: case E_BLOCK_BROWN_MUSHROOM: // Stuff that drops when block below is destroyed { - if( GetBlock( BlockPos.x, BlockPos.y-1, BlockPos.z ) == E_BLOCK_AIR ) + if (GetBlock(BlockPos.x, BlockPos.y - 1, BlockPos.z) == E_BLOCK_AIR) { SetBlock( BlockPos, E_BLOCK_AIR, 0 ); Vector3i WorldPos = PositionToWorldPosition( BlockPos ); m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); - - cPickup* Pickup = new cPickup( WorldPos.x * 32 + 16, WorldPos.y * 32 + 16, WorldPos.z * 32 + 16, cItem( cBlockToPickup::ToPickup( (ENUM_ITEM_ID)BlockID, E_ITEM_EMPTY) , 1 ) ); - Pickup->Initialize( m_World ); + + cItems Pickups; + cBlockToPickup::ToPickup(BlockID, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); } break; } @@ -477,8 +479,9 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) m_World->GetSimulatorManager()->WakeUp(WorldPos.x, WorldPos.y, WorldPos.z); - cPickup* Pickup = new cPickup( WorldPos.x * 32 + 16, WorldPos.y * 32 + 16, WorldPos.z * 32 + 16, cItem( cBlockToPickup::ToPickup( (ENUM_ITEM_ID)BlockID, E_ITEM_EMPTY) , 1 ) ); - Pickup->Initialize( m_World ); + cItems Pickups; + cBlockToPickup::ToPickup(BlockID, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); } break; } @@ -492,8 +495,9 @@ void cChunk::Tick(float a_Dt, MTRand & a_TickRandom) if( m_World->GetBlock( AttachedTo ) == E_BLOCK_AIR ) { SetBlock( BlockPos, E_BLOCK_AIR, 0 ); - cPickup* Pickup = new cPickup( WorldPos.x * 32 + 16, WorldPos.y * 32 + 16, WorldPos.z * 32 + 16, cItem( (ENUM_ITEM_ID)BlockID, 1 ) ); - Pickup->Initialize( m_World ); + cItems Pickups; + cBlockToPickup::ToPickup(BlockID, BlockMeta, E_ITEM_EMPTY, Pickups); + m_World->SpawnItemPickups(Pickups, WorldPos.x, WorldPos.y, WorldPos.z); } break; } diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index f28e2ecb0..93bc8ded0 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -23,17 +23,6 @@ -#define RECI_RAND_MAX (1.f/RAND_MAX) -inline float fRadRand( float a_Radius ) -{ - MTRand r1; - return ((float)r1.rand() * RECI_RAND_MAX)*a_Radius - a_Radius*0.5f; -} - - - - - //////////////////////////////////////////////////////////////////////////////// // cChunkMap: @@ -747,7 +736,7 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) -bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z, cItem & a_PickupItem) +bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z) { int PosX = a_X, PosY = a_Y, PosZ = a_Z, ChunkX, ChunkZ; @@ -766,11 +755,6 @@ bool cChunkMap::DigBlock(int a_X, int a_Y, int a_Z, cItem & a_PickupItem) m_World->GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); - if ( !a_PickupItem.IsEmpty() ) - { - cPickup * Pickup = new cPickup( a_X * 32 + 16 + (int)fRadRand(16.f), a_Y * 32 + 16 + (int)fRadRand(16.f), a_Z * 32 + 16 + (int)fRadRand(16.f), a_PickupItem ); - Pickup->Initialize(m_World); - } return true; } diff --git a/source/cChunkMap.h b/source/cChunkMap.h index 1d2459d21..f8155d5ae 100644 --- a/source/cChunkMap.h +++ b/source/cChunkMap.h @@ -104,8 +104,8 @@ public: /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); - bool DigBlock (int a_X, int a_Y, int a_Z, cItem & a_PickupItem); - void SendBlockTo (int a_X, int a_Y, int a_Z, cPlayer * a_Player); + bool DigBlock (int a_X, int a_Y, int a_Z); + void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); /// Compares clients of two chunks, calls the callback accordingly void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 5df31b36b..4f0d14988 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -84,6 +84,16 @@ +#define RECI_RAND_MAX (1.f/RAND_MAX) +inline int fRadRand(MTRand & r1, int a_BlockCoord) +{ + return a_BlockCoord * 32 + (int)(16 * ((float)r1.rand() * RECI_RAND_MAX) * 16 - 8); +} + + + + + int cClientHandle::s_ClientCount = 0; @@ -769,22 +779,29 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Direction, a_Packet->m_Status ); - if (a_Packet->m_Status == 0x04) // Drop block + + // Do we want plugins to disable tossing items? Probably no, so toss item before asking plugins for permission + if (a_Packet->m_Status == 0x04) // Drop held item { m_Player->TossItem(false); return; } cWorld* World = m_Player->GetWorld(); + BLOCKTYPE OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + NIBBLETYPE OldMeta = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - char OldBlock = World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - char MetaData = World->GetBlockMeta(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); - + if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_DIG, 4, a_Packet, m_Player, OldBlock, OldMeta)) + { + // The plugin doesn't agree with the digging, replace the block on the client and quit: + World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); + return; + } + bool bBroken = ( (a_Packet->m_Status == 0x02) || (g_BlockOneHitDig[(int)OldBlock]) || - ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1)) || - ((m_Player->GetInventory().GetEquippedItem().m_ItemID == E_ITEM_SHEARS) && (OldBlock == E_BLOCK_LEAVES)) + ((a_Packet->m_Status == 0x00) && (m_Player->GetGameMode() == 1)) ); if ((OldBlock == E_BLOCK_WOODEN_DOOR) && !bBroken) @@ -792,27 +809,11 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); } - cItem PickupItem; + cItems PickupItems; if (bBroken && !(m_Player->GetGameMode() == 1)) // broken { - ENUM_ITEM_ID PickupID = cBlockToPickup::ToPickup((ENUM_BLOCK_ID)OldBlock, m_Player->GetInventory().GetEquippedItem().m_ItemID); - PickupItem.m_ItemID = PickupID; - PickupItem.m_ItemHealth = MetaData; - PickupItem.m_ItemCount = cBlockToPickup::PickupCount(OldBlock); - if (OldBlock == E_BLOCK_LAPIS_ORE) - { - PickupItem.m_ItemHealth = 4; - } - if (cDoors::IsDoor(OldBlock)) - { - PickupItem.m_ItemHealth = 1; //For a complete door this works :D - } - } - - if (cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::E_PLUGIN_BLOCK_DIG, 2, a_Packet, m_Player, &PickupItem)) - { - World->SendBlockTo(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, m_Player); - return; + // TODO: Allow plugins to change the dropped objects + cBlockToPickup::ToPickup(OldBlock, OldMeta, m_Player->GetInventory().GetEquippedItem().m_ItemID, PickupItems); } int pX = a_Packet->m_PosX; @@ -836,32 +837,31 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) return; } - if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, PickupItem)) + if (!World->DigBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ)) { return; } - if (OldBlock == E_BLOCK_REDSTONE_TORCH_ON) - { - cRedstone Redstone(World); - Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); - } - if (OldBlock == E_BLOCK_REDSTONE_TORCH_OFF) - { - cRedstone Redstone(World); - Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); - } - if (OldBlock == E_BLOCK_REDSTONE_WIRE) + World->SpawnItemPickups(PickupItems, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ); + + switch (OldBlock) { - cRedstone Redstone(World); - Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); + case E_BLOCK_REDSTONE_TORCH_ON: + case E_BLOCK_REDSTONE_TORCH_OFF: + case E_BLOCK_REDSTONE_WIRE: + { + cRedstone Redstone(World); + Redstone.ChangeRedstone(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, false); + break; + } } + if ((OldBlock == E_BLOCK_PISTON) || (OldBlock == E_BLOCK_STICKY_PISTON)) { int newX = a_Packet->m_PosX; int newY = a_Packet->m_PosY; int newZ = a_Packet->m_PosZ; - AddPistonDir(newX, newY, newZ, MetaData & ~(8), 1); + AddPistonDir(newX, newY, newZ, OldMeta & ~(8), 1); if (World->GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) { World->SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); @@ -871,7 +871,7 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet) if (cDoors::IsDoor(OldBlock)) { // Special actions for destroyed door (Destroy second part) - if (MetaData & 8) + if (OldMeta & 8) { // Was upper part of door if (cDoors::IsDoor(World->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY - 1, a_Packet->m_PosZ))) diff --git a/source/cCow.cpp b/source/cCow.cpp index 56651dd24..18c78aeb1 100644 --- a/source/cCow.cpp +++ b/source/cCow.cpp @@ -3,7 +3,15 @@ #include "cCow.h" -//TODO: Milk Cow + + + + +// TODO: Milk Cow + + + + cCow::cCow() { @@ -11,28 +19,38 @@ cCow::cCow() GetMonsterConfig("Cow"); } + + + + cCow::~cCow() { } + + + + bool cCow::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cCow" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cCow::KilledBy( cEntity* a_Killer ) { - //Drops 0-2 Lether - cMonster::RandomDropItem(E_ITEM_LEATHER, 0, 2); - - if(GetMetaData() == BURNING) - { - cMonster::RandomDropItem(E_ITEM_STEAK, 1, 3); - }else{ - cMonster::RandomDropItem(E_ITEM_RAW_BEEF, 1, 3); - } - + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER); + AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + diff --git a/source/cCraftingWindow.cpp b/source/cCraftingWindow.cpp index 94bc3cde8..8d499c514 100644 --- a/source/cCraftingWindow.cpp +++ b/source/cCraftingWindow.cpp @@ -10,6 +10,7 @@ #include "cInventory.h" #include "cPickup.h" #include "cRoot.h" +#include "cWorld.h" #include "packets/cPacket_WindowClick.h" #include "packets/cPacket_InventorySlot.h" @@ -116,23 +117,24 @@ void cCraftingWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_P -void cCraftingWindow::Close( cPlayer & a_Player ) +void cCraftingWindow::Close(cPlayer & a_Player) { // Start from slot 1, don't drop what's in the result slot + cItems Drops; for( int i = 1; i < GetNumSlots(); i++ ) { - cItem* Item = GetSlot( i ); - if( Item->m_ItemID > 0 && Item->m_ItemCount > 0 ) + cItem * Item = GetSlot(i); + if (!Item->IsEmpty()) { - float vX = 0, vY = 0, vZ = 0; - EulerToVector( -a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY ); - vY = -vY*2 + 1.f; - cPickup* Pickup = new cPickup( (int)(a_Player.GetPosX()*32), (int)(a_Player.GetPosY()*32) + (int)(1.6f*32), (int)(a_Player.GetPosZ()*32), *Item, vX*2, vY*2, vZ*2 ); - Pickup->Initialize( a_Player.GetWorld() ); + Drops.push_back(*Item); } Item->Empty(); } - cWindow::Close( a_Player ); + float vX = 0, vY = 0, vZ = 0; + EulerToVector( -a_Player.GetRotation(), a_Player.GetPitch(), vZ, vX, vY); + vY = -vY*2 + 1.f; + a_Player.GetWorld()->SpawnItemPickups(Drops, a_Player.GetPosX(), a_Player.GetPosY() + 1.6f, a_Player.GetPosZ(), vX * 2, vY * 2, vZ * 2); + cWindow::Close(a_Player); } diff --git a/source/cCreeper.cpp b/source/cCreeper.cpp index 351ddf519..34573a9bf 100644 --- a/source/cCreeper.cpp +++ b/source/cCreeper.cpp @@ -3,16 +3,28 @@ #include "cCreeper.h" + + + + cCreeper::cCreeper() { m_MobType = 50; GetMonsterConfig("Creeper"); } + + + + cCreeper::~cCreeper() { } + + + + bool cCreeper::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cCreeper" ) == 0 ) return true; @@ -20,11 +32,21 @@ bool cCreeper::IsA( const char* a_EntityType ) } + + + void cCreeper::KilledBy( cEntity* a_Killer ) { - cMonster::RandomDropItem(E_ITEM_GUNPOWDER, 0, 2); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); + + // TODO Check if killed by a skeleton, then drop random music disk - //TODO Check if killed by a skeleton then drop random music disk + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); -} \ No newline at end of file +} + + + + diff --git a/source/cEnderman.cpp b/source/cEnderman.cpp index 6b0856187..8fbad6a39 100644 --- a/source/cEnderman.cpp +++ b/source/cEnderman.cpp @@ -3,22 +3,38 @@ #include "cEnderman.h" + + + + cEnderman::cEnderman() { m_MobType = 58; GetMonsterConfig("Enderman"); } + + + + cEnderman::~cEnderman() { } + + + + bool cEnderman::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cEnderman" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cEnderman::Tick(float a_Dt) { cMonster::Tick(a_Dt); @@ -29,10 +45,19 @@ void cEnderman::Tick(float a_Dt) } } + + + + void cEnderman::KilledBy( cEntity* a_Killer ) { - //Drops 0-1 Enderpearl - cMonster::RandomDropItem(E_ITEM_ENDER_PEARL, 0, 1); + cItems Drops; + AddRandomDropItem(Drops, 0, 1, E_ITEM_ENDER_PEARL); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + diff --git a/source/cFluidSimulator.cpp b/source/cFluidSimulator.cpp index c2df9b1f2..38bf55d77 100644 --- a/source/cFluidSimulator.cpp +++ b/source/cFluidSimulator.cpp @@ -1,13 +1,19 @@ #include "Globals.h" + +#include +#include + #include "cFluidSimulator.h" #include "cWorld.h" #include "Vector3i.h" #include "BlockID.h" #include "Defines.h" -#include -#include "cPickup.h" #include "cItem.h" -#include +#include "cBlockToPickup.h" + + + + //#define DEBUG_FLUID #ifdef DEBUG_FLUID @@ -17,6 +23,9 @@ #endif + + + class cFluidSimulator::FluidData { public: @@ -343,14 +352,15 @@ void cFluidSimulator::Simulate( float a_Dt ) { char DownID = m_World->GetBlock( pos.x, pos.y-1, pos.z ); bool bWashedAwayItem = CanWashAway( DownID ); - if( (IsPassableForFluid(DownID) || bWashedAwayItem)&&!IsStationaryBlock(DownID) ) // free for fluid + if( (IsPassableForFluid(DownID) || bWashedAwayItem) && !IsStationaryBlock(DownID) ) // free for fluid { if( bWashedAwayItem ) { - cPickup* Pickup = new cPickup( pos.x * 32 + 16, (pos.y-1) * 32 + 16, pos.z * 32 + 16, cItem( (ENUM_ITEM_ID)DownID, 1, m_World->GetBlockMeta( pos.x, pos.y-1, pos.z ) ) ); - Pickup->Initialize( m_World ); + cItems Drops; + cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(pos.x, pos.y - 1, pos.z), E_ITEM_EMPTY, Drops); + m_World->SpawnItemPickups(Drops, pos.x, pos.y - 1, pos.z); } - if( pos.y > 0 ) + if (pos.y > 0) { m_World->FastSetBlock( pos.x, pos.y-1, pos.z, m_FluidBlock, 8 ); // falling AddBlock( pos.x, pos.y-1, pos.z ); @@ -374,14 +384,15 @@ void cFluidSimulator::Simulate( float a_Dt ) char BlockID = m_World->GetBlock( p.x, p.y, p.z ); bool bWashedAwayItem = CanWashAway( BlockID ); - if(!IsPassableForFluid(BlockID)) continue; + if (!IsPassableForFluid(BlockID)) continue; - if( !IsAllowedBlock( BlockID ) ) + if (!IsAllowedBlock(BlockID)) { - if( bWashedAwayItem ) + if (bWashedAwayItem) { - cPickup* Pickup = new cPickup( p.x * 32 + 16, p.y * 32 + 16, p.z * 32 + 16, cItem( (ENUM_ITEM_ID)BlockID, 1, m_World->GetBlockMeta( p.x, p.y, p.z ) ) ); - Pickup->Initialize( m_World ); + cItems Drops; + cBlockToPickup::ToPickup(DownID, m_World->GetBlockMeta(p.x, p.y, p.z), E_ITEM_EMPTY, Drops); + m_World->SpawnItemPickups(Drops, p.x, p.y, p.z); } if( p.y == pos.y ) diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp index 4e831cdff..925682590 100644 --- a/source/cFurnaceEntity.cpp +++ b/source/cFurnaceEntity.cpp @@ -58,15 +58,16 @@ cFurnaceEntity::~cFurnaceEntity() void cFurnaceEntity::Destroy() { // Drop items + cItems Pickups; for( int i = 0; i < 3; i++) { if( !m_Items[i].IsEmpty() ) { - cPickup* Pickup = new cPickup( m_PosX * 32 + 16, m_PosY * 32 + 16, m_PosZ * 32 + 16, m_Items[i], 0, 1.f, 0 ); - Pickup->Initialize(m_World); + Pickups.push_back(m_Items[i]); m_Items[i].Empty(); } } + m_World->SpawnItemPickups(Pickups, m_PosX, m_PosY, m_PosZ); } diff --git a/source/cGhast.cpp b/source/cGhast.cpp index fb336364d..c19753641 100644 --- a/source/cGhast.cpp +++ b/source/cGhast.cpp @@ -3,28 +3,47 @@ #include "cGhast.h" + + + + cGhast::cGhast() { m_MobType = 56; GetMonsterConfig("Ghast"); } + + + + cGhast::~cGhast() { } + + + + bool cGhast::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cGhast" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cGhast::KilledBy( cEntity* a_Killer ) { - cMonster::RandomDropItem(E_ITEM_GUNPOWDER, 0, 2); - - cMonster::RandomDropItem(E_ITEM_GHAST_TEAR, 0, 1); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER); + AddRandomDropItem(Drops, 0, 1, E_ITEM_GHAST_TEAR); cMonster::KilledBy( a_Killer ); } + + + diff --git a/source/cItem.h b/source/cItem.h index a0832ef03..4311cc3f0 100644 --- a/source/cItem.h +++ b/source/cItem.h @@ -8,6 +8,10 @@ namespace Json class Value; }; + + + + class cItem //tolua_export { //tolua_export public: @@ -94,4 +98,10 @@ public: char m_ItemCount; //tolua_export short m_ItemHealth; //tolua_export -}; //tolua_export \ No newline at end of file +}; //tolua_export + +typedef std::vector cItems; + + + + diff --git a/source/cMonster.cpp b/source/cMonster.cpp index 1820bae4d..7834b855a 100644 --- a/source/cMonster.cpp +++ b/source/cMonster.cpp @@ -7,10 +7,7 @@ #include "cClientHandle.h" #include "cWorld.h" #include "cPlayer.h" -#include "BlockID.h" #include "Defines.h" -#include "cPickup.h" -#include "cItem.h" #include "cMonsterConfig.h" #include "MersenneTwister.h" @@ -548,21 +545,16 @@ void cMonster::SetSightDistance(float sd) -void cMonster::DropItem(ENUM_ITEM_ID a_Item, unsigned int a_Count) +void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth) { - if (a_Count > 0) + MTRand r1; + int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min; + if (Count > 0) { - cPickup * Pickup = new cPickup( (int)(m_Pos.x * 32), (int)(m_Pos.y * 32), (int)(m_Pos.z * 32), cItem( a_Item, (char) a_Count ) ); - Pickup->Initialize( GetWorld() ); + a_Drops.push_back(cItem(a_Item, Count, a_ItemHealth)); } } - -void cMonster::RandomDropItem(ENUM_ITEM_ID a_Item, unsigned int a_Min, unsigned int a_Max) -{ - MTRand r1; - return cMonster::DropItem(a_Item, r1.randInt() % (a_Max + 1 - a_Min) + a_Min); -} \ No newline at end of file diff --git a/source/cMonster.h b/source/cMonster.h index 4a292d193..b1e237d80 100644 --- a/source/cMonster.h +++ b/source/cMonster.h @@ -5,6 +5,8 @@ #include "Defines.h" #include "cWorld.h" #include "BlockID.h" +#include "cItem.h" +#include "BlockID.h" @@ -91,7 +93,9 @@ protected: float m_AttackRange; float m_AttackInterval; - void DropItem(ENUM_ITEM_ID a_Item, unsigned int a_Count); - void RandomDropItem(ENUM_ITEM_ID a_Item, unsigned int a_Min, unsigned int a_Max); - + void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0); }; //tolua_export + + + + diff --git a/source/cPig.cpp b/source/cPig.cpp index a35075233..2654b41cf 100644 --- a/source/cPig.cpp +++ b/source/cPig.cpp @@ -13,22 +13,39 @@ cPig::cPig() GetMonsterConfig("Pig"); } + + + + cPig::~cPig() { } + + + + bool cPig::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cPig" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cPig::KilledBy( cEntity* a_Killer ) { - //Drops 0-2 meat - cMonster::RandomDropItem(E_ITEM_RAW_MEAT, 0, 2); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_RAW_MEAT); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); - //TODO: Check for burning state + // TODO: Check for burning state cMonster::KilledBy( a_Killer ); -} \ No newline at end of file +} + + + + diff --git a/source/cPiston.cpp b/source/cPiston.cpp index f97a80b8c..c89fb5077 100644 --- a/source/cPiston.cpp +++ b/source/cPiston.cpp @@ -51,7 +51,8 @@ unsigned short cPiston::FirstPassthroughBlock( int pistonX, int pistonY, int pis -void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) { +void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) +{ char pistonBlock = m_World->GetBlock( pistx, pisty, pistz ); char pistonMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); char isSticky = (char)(pistonBlock == E_BLOCK_STICKY_PISTON) * 8; @@ -59,21 +60,22 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) { if ( (pistonMeta & 0x8) == 0x0 ) // only extend if piston is not already extended { unsigned short dist = FirstPassthroughBlock(pistx, pisty, pistz, pistonMeta); - if(dist>9000) return; // too many blocks + if (dist > 9000) return; // too many blocks AddDir( pistx, pisty, pistz, pistonMeta & 7, dist+1 ) - char currBlock = m_World->GetBlock( pistx, pisty, pistz ); - if( currBlock != E_BLOCK_AIR ) { - cItem PickupItem; - PickupItem.m_ItemID = cBlockToPickup::ToPickup( (ENUM_BLOCK_ID) currBlock, E_ITEM_EMPTY ); - PickupItem.m_ItemCount = 1; - cPickup* Pickup = new cPickup( pistx*32 + 16, pisty*32 + 16, pistz*32 + 16, PickupItem ); - Pickup->Initialize( m_World ); + BLOCKTYPE currBlock = m_World->GetBlock (pistx, pisty, pistz); + NIBBLETYPE currMeta = m_World->GetBlockMeta(pistx, pisty, pistz); + if (currBlock != E_BLOCK_AIR) + { + cItems PickupItems; + cBlockToPickup::ToPickup(currBlock, currMeta, E_ITEM_EMPTY, PickupItems); + m_World->SpawnItemPickups(PickupItems, pistx, pisty, pistz); recalc = true; } int oldx = pistx, oldy = pisty, oldz = pistz; char currBlockMeta; - for( int i = dist+1; i>0; i-- ) { + for (int i = dist+1; i>0; i--) + { AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 ) currBlock = m_World->GetBlock( pistx, pisty, pistz ); currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 9cfe4d644..60ae9f888 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -345,32 +345,40 @@ void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) } } -void cPlayer::KilledBy( cEntity* a_Killer ) + + + + +void cPlayer::KilledBy(cEntity * a_Killer) { - cPawn::KilledBy( a_Killer ); + cPawn::KilledBy(a_Killer); - if( m_Health > 0 ) return; // not dead yet =] + if (m_Health > 0) + { + return; // not dead yet =] + } m_bVisible = false; // So new clients don't see the player - MTRand r1; // Puke out all the items cItem* Items = m_Inventory->GetSlots(); - for( unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i ) + cItems Pickups; + for (unsigned int i = 1; i < m_Inventory->c_NumSlots; ++i) { if( !Items[i].IsEmpty() ) { - float SpeedX = ((r1.randInt()%1000)-500) /100.f; - float SpeedY = ((r1.randInt()%1000)) /100.f; - float SpeedZ = ((r1.randInt()%1000)-500) /100.f; - cPickup* Pickup = new cPickup( (int)(m_Pos.x*32), (int)(m_Pos.y*32), (int)(m_Pos.z*32), Items[i], SpeedX, SpeedY, SpeedZ ); - Pickup->Initialize( GetWorld() ); + Pickups.push_back(Items[i]); } Items[i].Empty(); } + m_World->SpawnItemPickups(Pickups, m_Pos.x, m_Pos.y, m_Pos.z, 10); SaveToDisk(); // Save it, yeah the world is a tough place ! } + + + + void cPlayer::Respawn() { m_Health = GetMaxHealth(); @@ -409,30 +417,41 @@ void cPlayer::OpenWindow( cWindow* a_Window ) m_CurrentWindow = a_Window; } + + + + void cPlayer::CloseWindow(char a_WindowType) { - if (a_WindowType == 0) { // Inventory - if(m_Inventory->GetWindow()->GetDraggingItem() && m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0) + if (a_WindowType == 0) + { + // Inventory + if ( + (m_Inventory->GetWindow()->GetDraggingItem() != NULL) && + (m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0) + ) { LOG("Player holds item! Dropping it..."); TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount ); } //Drop whats in the crafting slots (1, 2, 3, 4) - for( int i = 1; i <= 4; i++ ) + cItems Drops; + for (int i = 1; i <= 4; i++) { cItem* Item = m_Inventory->GetSlot( i ); - if( Item->m_ItemID > 0 && Item->m_ItemCount > 0 ) + if (!Item->IsEmpty()) { - float vX = 0, vY = 0, vZ = 0; - EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); - vY = -vY*2 + 1.f; - cPickup* Pickup = new cPickup( (int)(GetPosX()*32), (int)(GetPosY()*32) + (int)(1.6f*32), (int)(GetPosZ()*32), *Item, vX*2, vY*2, vZ*2 ); - Pickup->Initialize( GetWorld() ); + Drops.push_back(*Item); } Item->Empty(); } + float vX = 0, vY = 0, vZ = 0; + EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY); + vY = -vY*2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); } + if (m_CurrentWindow) { // FIXME: If the player entity is destroyed while having a chest window open, the chest will not close @@ -652,6 +671,10 @@ bool cPlayer::IsInGroup( const char* a_Group ) return false; } + + + + void cPlayer::ResolvePermissions() { m_ResolvedPermissions.clear(); // Start with an empty map yo~ @@ -741,39 +764,37 @@ AString cPlayer::GetColor(void) const void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) { - if( a_bDraggingItem ) + cItems Drops; + if (a_bDraggingItem) { - cItem* Item = GetInventory().GetWindow()->GetDraggingItem(); - if( Item->m_ItemID > 0 && Item->m_ItemCount >= a_Amount ) + cItem * Item = GetInventory().GetWindow()->GetDraggingItem(); + if (!Item->IsEmpty()) { - float vX = 0, vY = 0, vZ = 0; - EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); - vY = -vY*2 + 1.f; - cPickup* Pickup = new cPickup( (int)(GetPosX()*32), (int)(GetPosY()*32) + (int)(1.6f*32), (int)(GetPosZ()*32), cItem( Item->m_ItemID, (char)a_Amount, Item->m_ItemHealth), vX*2, vY*2, vZ*2 ); - Pickup->Initialize( GetWorld() ); + Drops.push_back(*Item); if( Item->m_ItemCount > a_Amount ) Item->m_ItemCount -= (char)a_Amount; else Item->Empty(); } - return; } - - // Else drop equipped item - cItem DroppedItem = GetInventory().GetEquippedItem(); - if( DroppedItem.m_ItemID > 0 && DroppedItem.m_ItemCount > 0 ) + else { - DroppedItem.m_ItemCount = 1; - if( GetInventory().RemoveItem( DroppedItem ) ) + // Else drop equipped item + cItem DroppedItem = GetInventory().GetEquippedItem(); + if (!DroppedItem.IsEmpty()) { - DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again - float vX = 0, vY = 0, vZ = 0; - EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); - vY = -vY*2 + 1.f; - cPickup* Pickup = new cPickup( (int)(GetPosX()*32), (int)(GetPosY()*32) + (int)(1.6f*32), (int)(GetPosZ()*32), DroppedItem, vX*2, vY*2, vZ*2 ); - Pickup->Initialize( GetWorld() ); + DroppedItem.m_ItemCount = 1; + if (GetInventory().RemoveItem(DroppedItem)) + { + DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again + Drops.push_back(DroppedItem); + } } } + float vX = 0, vY = 0, vZ = 0; + EulerToVector( -GetRotation(), GetPitch(), vZ, vX, vY ); + vY = -vY*2 + 1.f; + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); } diff --git a/source/cPluginManager.h b/source/cPluginManager.h index b6983a5e3..8d0a82a39 100644 --- a/source/cPluginManager.h +++ b/source/cPluginManager.h @@ -29,6 +29,7 @@ public: //tolua_export E_PLUGIN_KILLED, // tolua_export E_PLUGIN_CHUNK_GENERATED, // tolua_export E_PLUGIN_CHUNK_GENERATING, // tolua_export + E_PLUGIN_BLOCK_TO_DROPS, // tolua_export }; // tolua_export static cPluginManager * GetPluginManager(); //tolua_export diff --git a/source/cSheep.cpp b/source/cSheep.cpp index 5f4dd6379..921cd2d28 100644 --- a/source/cSheep.cpp +++ b/source/cSheep.cpp @@ -3,30 +3,63 @@ #include "cSheep.h" + + + + //Todo: Implement color -cSheep::cSheep() + + + + +cSheep::cSheep(void) : + m_IsSheared(false), + m_WoolColor(0) // TODO: E_META_WOOL_WHITE { m_MobType = 91; GetMonsterConfig("Sheep"); } + + + + cSheep::~cSheep() { } + + + + bool cSheep::IsA( const char* a_EntityType ) { - if( strcmp( a_EntityType, "cSheep" ) == 0 ) return true; + if (strcmp( a_EntityType, "cSheep" ) == 0) + { + return true; + } return cMonster::IsA( a_EntityType ); } + + + + void cSheep::KilledBy( cEntity* a_Killer ) { - //Todo: Check wheather it is sheared - //Todo: Check color + // TODO: Check whether it is sheared + // TODO: Check color - cMonster::DropItem(E_ITEM_WHITE_CLOTH, 1); + if (!m_IsSheared) + { + cItems Drops; + Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor)); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); + } cMonster::KilledBy( a_Killer ); -} \ No newline at end of file +} + + + diff --git a/source/cSheep.h b/source/cSheep.h index 170ea93fc..9faa25592 100644 --- a/source/cSheep.h +++ b/source/cSheep.h @@ -7,8 +7,11 @@ class cSheep : public cPassiveMonster public: cSheep(); ~cSheep(); + + bool m_IsSheared; + NIBBLETYPE m_WoolColor; // Uses E_META_WOOL_ constants for colors - virtual bool IsA( const char* a_EntityType ); + virtual bool IsA(const char * a_EntityType); - virtual void KilledBy( cEntity* a_Killer ); + virtual void KilledBy(cEntity * a_Killer); }; diff --git a/source/cSkeleton.cpp b/source/cSkeleton.cpp index 8574e3c29..eb6ea1234 100644 --- a/source/cSkeleton.cpp +++ b/source/cSkeleton.cpp @@ -13,16 +13,28 @@ cSkeleton::cSkeleton() GetMonsterConfig("Skeleton"); } + + + + cSkeleton::~cSkeleton() { } + + + + bool cSkeleton::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cSkeleton" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cSkeleton::Tick(float a_Dt) { cMonster::Tick(a_Dt); @@ -34,11 +46,20 @@ void cSkeleton::Tick(float a_Dt) } } + + + + void cSkeleton::KilledBy( cEntity* a_Killer ) { - cMonster::RandomDropItem(E_ITEM_ARROW, 0, 2); - - cMonster::RandomDropItem(E_ITEM_BONE, 0, 2); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_ARROW); + AddRandomDropItem(Drops, 0, 2, E_ITEM_BONE); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + diff --git a/source/cSlime.cpp b/source/cSlime.cpp index 67f9e8dc8..7cef1bb14 100644 --- a/source/cSlime.cpp +++ b/source/cSlime.cpp @@ -15,20 +15,38 @@ cSlime::cSlime() GetMonsterConfig("Slime"); } + + + + cSlime::~cSlime() { } + + + + bool cSlime::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cSlime" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cSlime::KilledBy( cEntity* a_Killer ) { //TODO: only when tiny - cMonster::RandomDropItem(E_ITEM_SLIMEBALL, 0, 2); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_SLIMEBALL); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); -} \ No newline at end of file +} + + + + diff --git a/source/cSpider.cpp b/source/cSpider.cpp index a1d3a62d9..47f4e2750 100644 --- a/source/cSpider.cpp +++ b/source/cSpider.cpp @@ -13,21 +13,38 @@ cSpider::cSpider() GetMonsterConfig("Spider"); } + + + + cSpider::~cSpider() { } + + + + bool cSpider::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cSpider" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cSpider::KilledBy( cEntity* a_Killer ) { - cMonster::RandomDropItem(E_ITEM_STRING, 0, 2); - - cMonster::RandomDropItem(E_ITEM_SPIDER_EYE, 0, 1); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING); + AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + diff --git a/source/cSquid.cpp b/source/cSquid.cpp index 1d3b332f4..52c0cbf30 100644 --- a/source/cSquid.cpp +++ b/source/cSquid.cpp @@ -26,14 +26,24 @@ bool cSquid::IsA( const char* a_EntityType ) return cMonster::IsA( a_EntityType ); } + + + + void cSquid::KilledBy( cEntity* a_Killer ) { - //Drops 0-3 Ink Sacs - cMonster::RandomDropItem(E_ITEM_DYE, 0, 3); + // Drops 0-3 Ink Sacs + cItems Drops; + AddRandomDropItem(Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK); + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + void cSquid::Tick(float a_Dt) { cPassiveMonster::Tick(a_Dt); diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 91b7b69bc..5cb9c5f0d 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -938,6 +938,48 @@ char cWorld::GetBlockSkyLight( int a_X, int a_Y, int a_Z ) +void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed) +{ + MTRand r1; + a_FlyAwaySpeed /= 1000; // Pre-divide, so that we can don't have to divide each time inside the loop + for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) + { + float SpeedX = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); + float SpeedY = (float)(a_FlyAwaySpeed * r1.randInt(1000)); + float SpeedZ = (float)(a_FlyAwaySpeed * (r1.randInt(1000) - 500)); + cPickup * Pickup = new cPickup( + (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), + *itr, SpeedX, SpeedY, SpeedZ + ); + Pickup->Initialize(this); + } +} + + + + + +void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ) +{ + MTRand r1; + for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) + { + cPickup * Pickup = new cPickup( + (int)(a_BlockX * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockY * 32) + r1.randInt(16) + r1.randInt(16), + (int)(a_BlockZ * 32) + r1.randInt(16) + r1.randInt(16), + *itr, (float)a_SpeedX, (float)a_SpeedY, (float)a_SpeedZ + ); + Pickup->Initialize(this); + } +} + + + + + void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType) { m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType); @@ -956,14 +998,9 @@ bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) -bool cWorld::DigBlock( int a_X, int a_Y, int a_Z, cItem & a_PickupItem ) +bool cWorld::DigBlock( int a_X, int a_Y, int a_Z) { - bool res = m_ChunkMap->DigBlock(a_X, a_Y, a_Z, a_PickupItem); - if (res) - { - GetSimulatorManager()->WakeUp(a_X, a_Y, a_Z); - } - return res; + return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); } diff --git a/source/cWorld.h b/source/cWorld.h index 3f8080f06..c3a521d1b 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -19,6 +19,7 @@ #include "ChunkSender.h" #include "Defines.h" #include "LightingThread.h" +#include "cItem.h" @@ -206,14 +207,20 @@ public: char GetBlockSkyLight( int a_X, int a_Y, int a_Z ); //tolua_export // TODO: char GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export + /// Spawns item pickups for each item in the list. May compress pickups if too many entities: + void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0); + + /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: + void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ); + /// Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); /// Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); - bool DigBlock( int a_X, int a_Y, int a_Z, cItem & a_PickupItem ); //tolua_export - void SendBlockTo( int a_X, int a_Y, int a_Z, cPlayer* a_Player ); //tolua_export + bool DigBlock (int a_X, int a_Y, int a_Z); //tolua_export + void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); //tolua_export const double & GetSpawnX() { return m_SpawnX; } //tolua_export const double & GetSpawnY(); //tolua_export diff --git a/source/cZombie.cpp b/source/cZombie.cpp index 566f271fc..b8f9553d2 100644 --- a/source/cZombie.cpp +++ b/source/cZombie.cpp @@ -13,16 +13,28 @@ cZombie::cZombie() GetMonsterConfig("Zombie"); } + + + + cZombie::~cZombie() { } + + + + bool cZombie::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cZombie" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cZombie::Tick(float a_Dt) { cMonster::Tick(a_Dt); @@ -33,9 +45,22 @@ void cZombie::Tick(float a_Dt) } } + + + + void cZombie::KilledBy( cEntity* a_Killer ) { - cMonster::RandomDropItem(E_ITEM_ROTTEN_FLESH, 0, 2); + cItems Drops; + AddRandomDropItem(Drops, 0, 2, E_ITEM_ROTTEN_FLESH); + + // TODO: Rare drops + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + diff --git a/source/cZombiepigman.cpp b/source/cZombiepigman.cpp index afe6248b7..024c0bd62 100644 --- a/source/cZombiepigman.cpp +++ b/source/cZombiepigman.cpp @@ -13,16 +13,28 @@ cZombiepigman::cZombiepigman() GetMonsterConfig("Zombiepigman"); } + + + + cZombiepigman::~cZombiepigman() { } + + + + bool cZombiepigman::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cZombiepigman" ) == 0 ) return true; return cMonster::IsA( a_EntityType ); } + + + + void cZombiepigman::Tick(float a_Dt) { cMonster::Tick(a_Dt); @@ -33,10 +45,23 @@ void cZombiepigman::Tick(float a_Dt) } } -void cZombiepigman::KilledBy( cEntity* a_Killer ) + + + + +void cZombiepigman::KilledBy(cEntity * a_Killer) { - cMonster::RandomDropItem(E_ITEM_ROTTEN_FLESH, 0, 1); - cMonster::RandomDropItem(E_ITEM_GOLD_NUGGET, 0, 1); + cItems Drops; + AddRandomDropItem(Drops, 0, 1, E_ITEM_ROTTEN_FLESH); + AddRandomDropItem(Drops, 0, 1, E_ITEM_GOLD_NUGGET); + + // TODO: Rare drops + + m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z); cMonster::KilledBy( a_Killer ); } + + + + -- cgit v1.2.3