Implemented drinkable potions, noeffect entity effect,
Clears entity effects on death
This commit is contained in:
parent
1eb04a48ee
commit
2185c72c2c
@ -850,7 +850,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
|
||||
case DIG_STATUS_SHOOT_EAT:
|
||||
{
|
||||
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
||||
if (ItemHandler->IsFood() || ItemHandler->IsDrinkable())
|
||||
if (ItemHandler->IsFood() || ItemHandler->IsDrinkable(&m_Player->GetEquippedItem()))
|
||||
{
|
||||
m_Player->AbortEating();
|
||||
return;
|
||||
@ -1182,9 +1182,9 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
||||
{
|
||||
HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
|
||||
}
|
||||
else if ((ItemHandler->IsFood() || ItemHandler->IsDrinkable()) && !m_Player->IsGameModeCreative())
|
||||
else if ((ItemHandler->IsFood() || ItemHandler->IsDrinkable(&Equipped)) && !m_Player->IsGameModeCreative())
|
||||
{
|
||||
if (m_Player->IsSatiated() && !ItemHandler->IsDrinkable())
|
||||
if (m_Player->IsSatiated() && !ItemHandler->IsDrinkable(&Equipped))
|
||||
{
|
||||
// The player is satiated, they cannot eat
|
||||
return;
|
||||
|
@ -9,6 +9,7 @@ public:
|
||||
/** All types of entity effects (numbers correspond to IDs) */
|
||||
enum eType
|
||||
{
|
||||
efNoEffect = 0,
|
||||
efSpeed = 1,
|
||||
efSlowness = 2,
|
||||
efHaste = 3,
|
||||
|
@ -52,8 +52,22 @@ void cPawn::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cPawn::KilledBy(cEntity *a_Killer)
|
||||
{
|
||||
ClearEntityEffects();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPawn::AddEntityEffect(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect)
|
||||
{
|
||||
if (a_EffectType == cEntityEffect::efNoEffect)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_EntityEffects[a_EffectType] = a_Effect;
|
||||
m_World->BroadcastEntityEffect(*this, a_EffectType, a_Effect.GetIntensity(), a_Effect.m_Ticks);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
cPawn(eEntityType a_EntityType, double a_Width, double a_Height);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void KilledBy(cEntity * a_Killer) override;
|
||||
|
||||
/** Applies an entity effect
|
||||
* @param a_EffectType The entity effect to apply
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "ItemNetherWart.h"
|
||||
#include "ItemPainting.h"
|
||||
#include "ItemPickaxe.h"
|
||||
#include "ItemPotion.h"
|
||||
#include "ItemThrowable.h"
|
||||
#include "ItemRedstoneDust.h"
|
||||
#include "ItemRedstoneRepeater.h"
|
||||
@ -124,6 +125,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
|
||||
case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType);
|
||||
case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType);
|
||||
case E_ITEM_PAINTING: return new cItemPaintingHandler(a_ItemType);
|
||||
case E_ITEM_POTIONS: return new cItemPotionHandler();
|
||||
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);
|
||||
@ -502,8 +504,10 @@ bool cItemHandler::IsFood(void)
|
||||
|
||||
|
||||
|
||||
bool cItemHandler::IsDrinkable(void)
|
||||
bool cItemHandler::IsDrinkable(const cItem * a_Item)
|
||||
{
|
||||
UNUSED(a_Item);
|
||||
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_ITEM_MILK:
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
virtual bool IsFood(void);
|
||||
|
||||
/** Indicates if this item is drinkable */
|
||||
virtual bool IsDrinkable(void);
|
||||
virtual bool IsDrinkable(const cItem * a_Item);
|
||||
|
||||
/** Blocks simply get placed */
|
||||
virtual bool IsPlaceable(void);
|
||||
|
@ -11,13 +11,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsDrinkable(void) override
|
||||
virtual bool IsDrinkable(const cItem * a_Item) override
|
||||
{
|
||||
UNUSED(a_Item);
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool EatItem(cPlayer * a_Player, cItem * a_Item) override
|
||||
{
|
||||
UNUSED(a_Item);
|
||||
a_Player->ClearEntityEffects();
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
a_Player->GetInventory().AddItem(E_ITEM_BUCKET);
|
||||
|
137
src/Items/ItemPotion.h
Normal file
137
src/Items/ItemPotion.h
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Entities/EntityEffects.h"
|
||||
|
||||
class cItemPotionHandler:
|
||||
public cItemHandler
|
||||
{
|
||||
typedef cItemHandler super;
|
||||
|
||||
cEntityEffect::eType GetEntityEffectType(short a_ItemDamage)
|
||||
{
|
||||
// Potion effect bits are different from entity effect values
|
||||
// For reference: http://minecraft.gamepedia.com/Data_values#.22Potion_effect.22_bits
|
||||
switch (a_ItemDamage & 15)
|
||||
{
|
||||
case 1: return cEntityEffect::efRegeneration;
|
||||
case 2: return cEntityEffect::efSpeed;
|
||||
case 3: return cEntityEffect::efFireResistance;
|
||||
case 4: return cEntityEffect::efPoison;
|
||||
case 5: return cEntityEffect::efInstantHealth;
|
||||
case 6: return cEntityEffect::efNightVision;
|
||||
case 8: return cEntityEffect::efWeakness;
|
||||
case 9: return cEntityEffect::efStrength;
|
||||
case 10: return cEntityEffect::efSlowness;
|
||||
case 12: return cEntityEffect::efInstantDamage;
|
||||
case 13: return cEntityEffect::efWaterBreathing;
|
||||
case 14: return cEntityEffect::efInvisibility;
|
||||
|
||||
// No effect potions
|
||||
case 0:
|
||||
case 7:
|
||||
case 11:
|
||||
case 15:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cEntityEffect::efNoEffect;
|
||||
}
|
||||
|
||||
short GetEntityEffectIntensity(short a_ItemDamage)
|
||||
{
|
||||
// Level II potion if fifth bit is set
|
||||
if (a_ItemDamage & 32) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int GetEntityEffectDuration(short a_ItemDamage)
|
||||
{
|
||||
// Base duration in ticks
|
||||
int base = 0;
|
||||
double tier_multi = 1, ext_multi = 1, splash_multi = 1;
|
||||
|
||||
switch (GetEntityEffectType(a_ItemDamage))
|
||||
{
|
||||
case cEntityEffect::efRegeneration:
|
||||
case cEntityEffect::efPoison:
|
||||
{
|
||||
base = 900;
|
||||
break;
|
||||
}
|
||||
|
||||
case cEntityEffect::efSpeed:
|
||||
case cEntityEffect::efFireResistance:
|
||||
case cEntityEffect::efNightVision:
|
||||
case cEntityEffect::efStrength:
|
||||
case cEntityEffect::efWaterBreathing:
|
||||
case cEntityEffect::efInvisibility:
|
||||
{
|
||||
base = 3600;
|
||||
break;
|
||||
}
|
||||
|
||||
case cEntityEffect::efWeakness:
|
||||
case cEntityEffect::efSlowness:
|
||||
{
|
||||
base = 1800;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If potion is level 2, half the duration. If not, stays the same
|
||||
tier_multi = GetEntityEffectIntensity(a_ItemDamage) > 0 ? 0.5 : 1;
|
||||
|
||||
// If potion is extended, multiply duration by 8/3. If not, stays the same
|
||||
// Extended potion if sixth bit is set
|
||||
ext_multi = a_ItemDamage & 64 ? (8.0/3.0) : 1;
|
||||
|
||||
// If potion is splash potion, multiply duration by 3/4. If not, stays the same
|
||||
splash_multi = !IsDrinkable(a_ItemDamage) ? 0.75 : 1;
|
||||
|
||||
// For reference: http://minecraft.gamepedia.com/Data_values#.22Tier.22_bit
|
||||
// http://minecraft.gamepedia.com/Data_values#.22Extended_duration.22_bit
|
||||
// http://minecraft.gamepedia.com/Data_values#.22Splash_potion.22_bit
|
||||
|
||||
return base * tier_multi * ext_multi * splash_multi;
|
||||
}
|
||||
|
||||
bool IsDrinkable(short a_ItemDamage)
|
||||
{
|
||||
// Drinkable potion if 13th bit is set
|
||||
// For reference: http://minecraft.gamepedia.com/Potions#Data_value_table
|
||||
return a_ItemDamage & 8192;
|
||||
}
|
||||
|
||||
public:
|
||||
cItemPotionHandler():
|
||||
super(E_ITEM_POTIONS)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsDrinkable(const cItem * a_Item) override
|
||||
{
|
||||
return IsDrinkable(a_Item->m_ItemDamage);
|
||||
}
|
||||
|
||||
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
|
||||
{
|
||||
// Called when potion is a splash potion
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool EatItem(cPlayer * a_Player, cItem * a_Item) override
|
||||
{
|
||||
// Called when potion is a drinkable potion
|
||||
short potion_damage = a_Item->m_ItemDamage;
|
||||
a_Player->AddEntityEffect(GetEntityEffectType(potion_damage),
|
||||
cEntityEffect(GetEntityEffectDuration(potion_damage),
|
||||
GetEntityEffectIntensity(potion_damage),
|
||||
a_Player));
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
a_Player->GetInventory().AddItem(E_ITEM_GLASS_BOTTLE);
|
||||
return true;
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user