summaryrefslogtreecommitdiffstats
path: root/source/Items
diff options
context:
space:
mode:
Diffstat (limited to 'source/Items')
-rw-r--r--source/Items/ItemBow.h80
-rw-r--r--source/Items/ItemHandler.cpp26
-rw-r--r--source/Items/ItemHandler.h9
-rw-r--r--source/Items/ItemThrowable.h90
4 files changed, 195 insertions, 10 deletions
diff --git a/source/Items/ItemBow.h b/source/Items/ItemBow.h
new file mode 100644
index 000000000..845192ef7
--- /dev/null
+++ b/source/Items/ItemBow.h
@@ -0,0 +1,80 @@
+
+// ItemBow.h
+
+// Declares the cItemBowHandler class representing the itemhandler for bows
+
+
+
+
+
+#pragma once
+
+#include "../Entities/ProjectileEntity.h"
+
+
+
+
+
+class cItemBowHandler :
+ public cItemHandler
+{
+ typedef cItemHandler super;
+
+public:
+ cItemBowHandler(void) :
+ super(E_ITEM_BOW)
+ {
+ }
+
+
+ virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
+ {
+ ASSERT(a_Player != NULL);
+
+ // Check if the player has an arrow in the inventory, or is in Creative:
+ if (!(a_Player->IsGameModeCreative() || a_Player->GetInventory().HasItems(cItem(E_ITEM_ARROW))))
+ {
+ return false;
+ }
+ a_Player->StartChargingBow();
+ return true;
+ }
+
+
+ virtual void OnItemShoot(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override
+ {
+ // Actual shot - produce the arrow with speed based on the ticks that the bow was charged
+ ASSERT(a_Player != NULL);
+
+ int BowCharge = a_Player->FinishChargingBow();
+ double Force = (double)BowCharge / 20;
+ Force = (Force * Force + 2 * Force) / 3; // This formula is used by the 1.6.2 client
+ if (Force < 0.1)
+ {
+ // Too little force, ignore the shot
+ return;
+ }
+ if (Force > 1)
+ {
+ Force = 1;
+ }
+
+ // Create the arrow entity:
+ cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2);
+ if (Arrow == NULL)
+ {
+ return;
+ }
+ if (!Arrow->Initialize(a_Player->GetWorld()))
+ {
+ delete Arrow;
+ return;
+ }
+ a_Player->GetWorld()->BroadcastSpawnEntity(*Arrow);
+ }
+} ;
+
+
+
+
+
diff --git a/source/Items/ItemHandler.cpp b/source/Items/ItemHandler.cpp
index 66d36e1a6..2ae193d52 100644
--- a/source/Items/ItemHandler.cpp
+++ b/source/Items/ItemHandler.cpp
@@ -8,6 +8,7 @@
// Handlers:
#include "ItemBed.h"
+#include "ItemBow.h"
#include "ItemBrewingStand.h"
#include "ItemBucket.h"
#include "ItemCauldron.h"
@@ -21,6 +22,7 @@
#include "ItemLighter.h"
#include "ItemMinecart.h"
#include "ItemPickaxe.h"
+#include "ItemThrowable.h"
#include "ItemRedstoneDust.h"
#include "ItemRedstoneRepeater.h"
#include "ItemSapling.h"
@@ -47,18 +49,24 @@ cItemHandler * cItemHandler::m_ItemHandler[2268];
-cItemHandler *cItemHandler::GetItemHandler(int a_ItemType)
+cItemHandler * cItemHandler::GetItemHandler(int a_ItemType)
{
- if(a_ItemType < 0) a_ItemType = 0;
+ if (a_ItemType < 0)
+ {
+ ASSERT(!"Bad item type");
+ a_ItemType = 0;
+ }
- if(!m_HandlerInitialized)
- { //We have to initialize
+ if (!m_HandlerInitialized)
+ {
+ // We need to initialize
memset(m_ItemHandler, 0, sizeof(m_ItemHandler));
m_HandlerInitialized = true;
}
- if(m_ItemHandler[a_ItemType])
- return m_ItemHandler[a_ItemType];
- m_ItemHandler[a_ItemType] = CreateItemHandler(a_ItemType);
+ if (m_ItemHandler[a_ItemType] == NULL)
+ {
+ m_ItemHandler[a_ItemType] = CreateItemHandler(a_ItemType);
+ }
return m_ItemHandler[a_ItemType];
}
@@ -77,15 +85,19 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
case E_BLOCK_SAPLING: return new cItemSaplingHandler(a_ItemType);
case E_BLOCK_WOOL: return new cItemClothHandler(a_ItemType);
case E_ITEM_BED: return new cItemBedHandler(a_ItemType);
+ case E_ITEM_BOW: return new cItemBowHandler;
case E_ITEM_BREWING_STAND: return new cItemBrewingStandHandler(a_ItemType);
case E_ITEM_CAULDRON: return new cItemCauldronHandler(a_ItemType);
case E_ITEM_DYE: return new cItemDyeHandler(a_ItemType);
+ case E_ITEM_EGG: return new cItemEggHandler();
+ case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler();
case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType);
case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType);
case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType);
case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType);
case E_ITEM_SIGN: return new cItemSignHandler(a_ItemType);
+ case E_ITEM_SNOWBALL: return new cItemSnowballHandler();
case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType);
case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType);
diff --git a/source/Items/ItemHandler.h b/source/Items/ItemHandler.h
index 44d43e8f7..e39bb054b 100644
--- a/source/Items/ItemHandler.h
+++ b/source/Items/ItemHandler.h
@@ -21,8 +21,11 @@ class cItemHandler
public:
cItemHandler(int a_ItemType);
- /// Called when the player tries to use the item. Return false to make the item unusable. DEFAULT: False
- virtual bool OnItemUse(cWorld *a_World, cPlayer *a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); //eg for fishing or hoes
+ /// Called when the player tries to use the item (right mouse button). Return false to make the item unusable. DEFAULT: False
+ virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir);
+
+ /// Called when the client sends the SHOOT status in the lclk packet
+ virtual void OnItemShoot(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) {}
/// Called while the player diggs a block using this item
virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace);
@@ -88,7 +91,7 @@ protected:
int m_ItemType;
static cItemHandler *CreateItemHandler(int m_ItemType);
- static cItemHandler *m_ItemHandler[2268];
+ static cItemHandler * m_ItemHandler[E_ITEM_LAST + 1];
static bool m_HandlerInitialized; //used to detect if the itemhandlers are initialized
};
diff --git a/source/Items/ItemThrowable.h b/source/Items/ItemThrowable.h
new file mode 100644
index 000000000..dacdb6157
--- /dev/null
+++ b/source/Items/ItemThrowable.h
@@ -0,0 +1,90 @@
+
+// ItemThrowable.h
+
+// Declares the itemhandlers for throwable items: eggs, snowballs and ender pearls
+
+
+
+
+
+#pragma once
+
+
+
+
+
+class cItemThrowableHandler :
+ public cItemHandler
+{
+ typedef cItemHandler super;
+public:
+ cItemThrowableHandler(int a_ItemType, cProjectileEntity::eKind a_ProjectileKind, double a_SpeedCoeff) :
+ super(a_ItemType),
+ m_ProjectileKind(a_ProjectileKind),
+ m_SpeedCoeff(a_SpeedCoeff)
+ {
+ }
+
+
+ virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override
+ {
+ Vector3d Pos = a_Player->GetThrowStartPos();
+ Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
+ a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, &Speed);
+ return true;
+ }
+
+protected:
+ cProjectileEntity::eKind m_ProjectileKind;
+ double m_SpeedCoeff;
+} ;
+
+
+
+
+
+class cItemEggHandler :
+ public cItemThrowableHandler
+{
+ typedef cItemThrowableHandler super;
+public:
+ cItemEggHandler(void) :
+ super(E_ITEM_EGG, cProjectileEntity::pkEgg, 30)
+ {
+ }
+} ;
+
+
+
+
+class cItemSnowballHandler :
+ public cItemThrowableHandler
+{
+ typedef cItemThrowableHandler super;
+
+public:
+ cItemSnowballHandler(void) :
+ super(E_ITEM_SNOWBALL, cProjectileEntity::pkSnowball, 30)
+ {
+ }
+} ;
+
+
+
+
+
+class cItemEnderPearlHandler :
+ public cItemThrowableHandler
+{
+ typedef cItemThrowableHandler super;
+
+public:
+ cItemEnderPearlHandler(void) :
+ super(E_ITEM_ENDER_PEARL, cProjectileEntity::pkEnderPearl, 30)
+ {
+ }
+} ;
+
+
+
+