summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Server/Plugins/APIDump/APIDesc.lua42
-rw-r--r--Server/Plugins/APIDump/Classes/World.lua60
-rw-r--r--src/Blocks/WorldInterface.h2
-rw-r--r--src/Entities/Pickup.cpp16
-rw-r--r--src/Entities/Pickup.h18
-rw-r--r--src/World.cpp16
-rw-r--r--src/World.h3
7 files changed, 151 insertions, 6 deletions
diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua
index ce0390947..65ae69144 100644
--- a/Server/Plugins/APIDump/APIDesc.lua
+++ b/Server/Plugins/APIDump/APIDesc.lua
@@ -9260,6 +9260,16 @@ a_Player:OpenWindow(Window);
]],
Functions =
{
+ CanCombine =
+ {
+ Returns =
+ {
+ {
+ Type = "boolean"
+ }
+ },
+ Notes = "Returns whether this pickup is allowed to combine with other similar pickups.",
+ },
CollectedBy =
{
Params =
@@ -9298,6 +9308,16 @@ a_Player:OpenWindow(Window);
},
Notes = "Returns the item represented by this pickup",
},
+ GetLifetime =
+ {
+ Returns =
+ {
+ {
+ Type = "number",
+ },
+ },
+ Notes = "Returns the total length of this pickup's lifespan, in ticks.",
+ },
IsCollected =
{
Returns =
@@ -9329,6 +9349,28 @@ a_Player:OpenWindow(Window);
},
Notes = "Sets the pickup's age, in ticks.",
},
+ SetCanCombine =
+ {
+ Params =
+ {
+ {
+ Name = "CanCombine",
+ Type = "boolean",
+ },
+ },
+ Notes = "Sets whether this pickup is allowed to combine with other similar pickups.",
+ },
+ SetLifetime =
+ {
+ Params =
+ {
+ {
+ Name = "LifeTimeInTicks",
+ Type = "number",
+ },
+ },
+ Notes = "Sets the total lifespan of this pickup before it despawns, in ticks. Does not reset the age of the pickup, use SetAge(0). If new lifetime is less than the current age, pickup will despawn.",
+ },
},
Inherits = "cEntity",
},
diff --git a/Server/Plugins/APIDump/Classes/World.lua b/Server/Plugins/APIDump/Classes/World.lua
index 429d32ed6..e452db2ff 100644
--- a/Server/Plugins/APIDump/Classes/World.lua
+++ b/Server/Plugins/APIDump/Classes/World.lua
@@ -3009,6 +3009,66 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
},
Notes = "Spawns a {{cFallingBlock|Falling Block}} entity at the specified coords with the given block type/meta. Returns the EntityID of the new falling block, or {{cEntity#INVALID_ID|cEntity#INVALID_ID}} if no falling block was created.",
},
+ SpawnItemPickup =
+ {
+ Params =
+ {
+ {
+ Name = "PosX",
+ Type = "number",
+ },
+ {
+ Name = "PosY",
+ Type = "number",
+ },
+ {
+ Name = "PosZ",
+ Type = "number",
+ },
+ {
+ Name = "Item",
+ Type = "cItem",
+ },
+ {
+ Name = "SpeedX",
+ Type = "number",
+ IsOptional = true,
+ Notes = "Speed along X coordinate to spawn with. Default is 0.",
+ },
+ {
+ Name = "SpeedY",
+ Type = "number",
+ IsOptional = true,
+ Notes = "Speed along Y coordinate to spawn with. Default is 0.",
+ },
+ {
+ Name = "SpeedZ",
+ Type = "number",
+ IsOptional = true,
+ Notes = "Speed along Z coordinate to spawn with. Default is 0.",
+ },
+ {
+ Name = "LifetimeTicks",
+ Type = "number",
+ IsOptional = true,
+ Notes = "Length of the pickups lifetime, in ticks. Default 5 minutes (6000 ticks)",
+ },
+ {
+ Name = "CanCombine",
+ Type = "boolean",
+ IsOptional = true,
+ Notes = "Whether this pickup is allowed to combine with other similar pickups.",
+ },
+ },
+ Returns =
+ {
+ {
+ Name = "EntityID",
+ Type = "number",
+ }
+ },
+ Notes = "Creates a single pickup entity of the given item at the given position with the given speed, and returns the entities unique ID."
+ },
SpawnItemPickups =
{
{
diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h
index c6cf070a0..bac6e2bdf 100644
--- a/src/Blocks/WorldInterface.h
+++ b/src/Blocks/WorldInterface.h
@@ -33,6 +33,8 @@ public:
/** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified. */
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) = 0;
+ virtual UInt32 SpawnItemPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f, int a_LifetimeTicks = 6000, bool a_CanCombine = true) = 0;
+
/** Spawns a mob of the specified type.
Returns the mob's UniqueID if recognized and spawned, or cEntity::INVALID_ID on failure. */
virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby) = 0;
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index 5f64d6fbe..0c6c8feab 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -40,8 +40,9 @@ public:
Vector3d EntityPos = a_Entity->GetPosition();
double Distance = (EntityPos - m_Position).Length();
- cItem & Item = static_cast<cPickup *>(a_Entity)->GetItem();
- if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()))
+ cPickup * OtherPickup = static_cast<cPickup *>(a_Entity);
+ cItem & Item = OtherPickup->GetItem();
+ if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem()) && OtherPickup->CanCombine())
{
short CombineCount = Item.m_ItemCount;
if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize())
@@ -66,6 +67,9 @@ public:
a_Entity->GetWorld()->BroadcastEntityRelMove(*a_Entity, static_cast<char>(DiffX), static_cast<char>(DiffY), static_cast<char>(DiffZ));
/* End of experimental animation */
a_Entity->Destroy();
+
+ // Reset the timer
+ m_Pickup->SetAge(0);
}
else
{
@@ -92,12 +96,14 @@ protected:
-cPickup::cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */)
+cPickup::cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX, float a_SpeedY, float a_SpeedZ, int a_LifetimeTicks, bool a_CanCombine)
: cEntity(etPickup, a_PosX, a_PosY, a_PosZ, 0.2, 0.2)
, m_Timer(0)
, m_Item(a_Item)
, m_bCollected(false)
, m_bIsPlayerCreated(IsPlayerCreated)
+ , m_bCanCombine(a_CanCombine)
+ , m_Lifetime(cTickTime(a_LifetimeTicks))
{
SetGravity(-16.0f);
SetAirDrag(0.02f);
@@ -165,7 +171,7 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
// Try to combine the pickup with adjacent same-item pickups:
- if ((m_Item.m_ItemCount < m_Item.GetMaxStackSize()) && IsOnGround()) // Don't combine if already full or not on ground
+ if ((m_Item.m_ItemCount < m_Item.GetMaxStackSize()) && IsOnGround() && CanCombine()) // Don't combine if already full or not on ground
{
// By using a_Chunk's ForEachEntity() instead of cWorld's, pickups don't combine across chunk boundaries.
// That is a small price to pay for not having to traverse the entire world for each entity.
@@ -188,7 +194,7 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
}
- if (m_Timer > std::chrono::minutes(5)) // 5 minutes
+ if (m_Timer > m_Lifetime)
{
Destroy(true);
return;
diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h
index ed5949f37..c2fcbd7f2 100644
--- a/src/Entities/Pickup.h
+++ b/src/Entities/Pickup.h
@@ -25,7 +25,7 @@ public:
CLASS_PROTODEF(cPickup)
- cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f);
+ cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f, int a_LifetimeTicks = 6000, bool a_CanCombine = true);
cItem & GetItem(void) {return m_Item; } // tolua_export
const cItem & GetItem(void) const {return m_Item; }
@@ -36,12 +36,24 @@ public:
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ /** Returns whether this pickup is allowed to combine with other similar pickups */
+ bool CanCombine(void) const { return m_bCanCombine; } // tolua_export
+
+ /** Sets whether this pickup is allowed to combine with other similar pickups */
+ void SetCanCombine(bool a_CanCombine) { m_bCanCombine = a_CanCombine; } // tolua_export
+
/** Returns the number of ticks that this entity has existed */
int GetAge(void) const { return std::chrono::duration_cast<cTickTime>(m_Timer).count(); } // tolua_export
/** Set the number of ticks that this entity has existed */
void SetAge(int a_Age) { m_Timer = cTickTime(a_Age); } // tolua_export
+ /** Returns the number of ticks that this pickup should live for */
+ int GetLifetime(void) const { return std::chrono::duration_cast<cTickTime>(m_Lifetime).count(); } // tolua_export
+
+ /** Set the number of ticks that this pickup should live for */
+ void SetLifetime(int a_Lifetime) { m_Lifetime = cTickTime(a_Lifetime); } // tolua_export
+
/** Returns true if the pickup has already been collected */
bool IsCollected(void) const { return m_bCollected; } // tolua_export
@@ -58,4 +70,8 @@ private:
bool m_bCollected;
bool m_bIsPlayerCreated;
+
+ bool m_bCanCombine;
+
+ std::chrono::milliseconds m_Lifetime;
}; // tolua_export
diff --git a/src/World.cpp b/src/World.cpp
index fa2116597..da7d8fb2d 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -2223,6 +2223,22 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double
+UInt32 cWorld::SpawnItemPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, float a_SpeedX, float a_SpeedY, float a_SpeedZ, int a_LifetimeTicks, bool a_CanCombine)
+{
+ cPickup * Pickup = new cPickup(a_PosX, a_PosY, a_PosZ, a_Item, false, a_SpeedX, a_SpeedY, a_SpeedZ, a_LifetimeTicks, a_CanCombine);
+ if (!Pickup->Initialize(*this))
+ {
+ delete Pickup;
+ Pickup = nullptr;
+ return cEntity::INVALID_ID;
+ }
+ return Pickup->GetUniqueID();
+}
+
+
+
+
+
UInt32 cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta)
{
cFallingBlock * FallingBlock = new cFallingBlock(Vector3i(a_X, a_Y, a_Z), BlockType, BlockMeta);
diff --git a/src/World.h b/src/World.h
index bae7adbb9..a3180e008 100644
--- a/src/World.h
+++ b/src/World.h
@@ -443,6 +443,9 @@ public:
/** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified. */
virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) override;
+ /** Spawns a single pickup containing the specified item. */
+ virtual UInt32 SpawnItemPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f, int a_LifetimeTicks = 6000, bool a_CanCombine = true) override;
+
/** Spawns an falling block entity at the given position.
Returns the UniqueID of the spawned falling block, or cEntity::INVALID_ID on failure. */
UInt32 SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta);