void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); if (!IsTicking()) { // The base class tick destroyed us return; } if (IsBaby()) { return; // Babies don't lay eggs } if ( ((m_EggDropTimer == 6000) && GetRandomProvider().RandBool()) || m_EggDropTimer == 12000 ) { cItems Drops; m_EggDropTimer = 0; Drops.push_back(cItem(E_ITEM_EGG, 1)); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); } else { m_EggDropTimer++; } }
void cSheep::OnRightClicked(cPlayer & a_Player) { const cItem & EquippedItem = a_Player.GetEquippedItem(); if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && !IsSheared() && !IsBaby()) { m_IsSheared = true; m_World->BroadcastEntityMetadata(*this); a_Player.UseEquippedItem(); cItems Drops; int NumDrops = m_World->GetTickRandomNumber(2) + 1; Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor)); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); m_World->BroadcastSoundEffect("mob.sheep.shear", GetPosX(), GetPosY(), GetPosZ(), 1.0f, 1.0f); } else if ((EquippedItem.m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - EquippedItem.m_ItemDamage)) { m_WoolColor = 15 - EquippedItem.m_ItemDamage; if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } m_World->BroadcastEntityMetadata(*this); } }
void cOcelot::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); if (!IsTicking()) { // The base class tick destroyed us return; } if (!IsTame() && !IsBaby()) { if (m_CheckPlayerTickCount == 23) { m_World->DoWithNearestPlayer(GetPosition(), 10, [&](cPlayer & a_Player) -> bool { cItems Items; GetBreedingItems(Items); if (Items.ContainsType(a_Player.GetEquippedItem().m_ItemType)) { if (!IsBegging()) { SetIsBegging(true); m_World->BroadcastEntityMetadata(*this); } MoveToPosition(a_Player.GetPosition()); } else { if (IsBegging()) { SetIsBegging(false); m_World->BroadcastEntityMetadata(*this); } } return true; }, true); m_CheckPlayerTickCount = 0; } else { m_CheckPlayerTickCount++; } } if (IsTame() && !IsSitting()) { TickFollowPlayer(); } else if (IsSitting()) { StopMovingToPosition(); } m_World->BroadcastEntityMetadata(*this); }
void cOcelot::SpawnOn(cClientHandle & a_ClientHandle) { super::SpawnOn(a_ClientHandle); if (!IsBaby() && GetRandomProvider().RandBool(1.0 / 7.0)) { m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), m_MobType, true); m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), m_MobType, true); } }
void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer) { if (IsBaby()) { return; // Babies don't drop items } unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_FEATHER); AddRandomDropItem(a_Drops, 1, 1, IsOnFire() ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN); }
void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer) { if (IsBaby()) { return; // Babies don't drop items } unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER); AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF); }
void cPig::GetDrops(cItems & a_Drops, cEntity * a_Killer) { if (IsBaby()) { return; // Babies don't drop items } unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 1, 3 + LootingLevel, IsOnFire() ? E_ITEM_COOKED_PORKCHOP : E_ITEM_RAW_PORKCHOP); if (m_bIsSaddled) { a_Drops.push_back(cItem(E_ITEM_SADDLE, 1)); } }
void cHorse::GetDrops(cItems & a_Drops, cEntity * a_Killer) { if (IsBaby()) { return; // Babies don't drop items } unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); } AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_LEATHER); if (IsSaddled()) { a_Drops.push_back(m_Saddle); } if (!m_Armor.IsEmpty()) { a_Drops.push_back(m_Armor); } }
void cPassiveMonster::OnRightClicked(cPlayer & a_Player) { super::OnRightClicked(a_Player); const cItem & EquippedItem = a_Player.GetEquippedItem(); // If a player holding breeding items right-clicked me, go into love mode if ((m_LoveCooldown == 0) && !IsInLove() && !IsBaby()) { cItems Items; GetBreedingItems(Items); if (Items.ContainsType(EquippedItem.m_ItemType)) { if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } m_LoveTimer = 20 * 30; // half a minute m_World->BroadcastEntityStatus(*this, esMobInLove); } } // If a player holding my spawn egg right-clicked me, spawn a new baby if (EquippedItem.m_ItemType == E_ITEM_SPAWN_EGG) { eMonsterType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(EquippedItem.m_ItemDamage); if ( (MonsterType == m_MobType) && (m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), m_MobType, true) != cEntity::INVALID_ID) // Spawning succeeded ) { if (!a_Player.IsGameModeCreative()) { // The mob was spawned, "use" the item: a_Player.GetInventory().RemoveOneEquippedItem(); } } } }
void cMonster::KilledBy(TakeDamageInfo & a_TDI) { super::KilledBy(a_TDI); if (m_SoundHurt != "") { m_World->BroadcastSoundEffect(m_SoundDeath, GetPosX(), GetPosY(), GetPosZ(), 1.0f, 0.8f); } int Reward; switch (m_MobType) { // Animals case mtChicken: case mtCow: case mtHorse: case mtPig: case mtRabbit: case mtSheep: case mtSquid: case mtMooshroom: case mtOcelot: case mtWolf: { Reward = m_World->GetTickRandomNumber(2) + 1; break; } // Monsters case mtCaveSpider: case mtCreeper: case mtEnderman: case mtGhast: case mtGuardian: case mtSilverfish: case mtSkeleton: case mtSpider: case mtWitch: case mtZombie: case mtZombiePigman: case mtSlime: case mtMagmaCube: { Reward = 6 + (m_World->GetTickRandomNumber(2)); break; } case mtBlaze: { Reward = 10; break; } // Bosses case mtEnderDragon: { Reward = 12000; break; } case mtWither: { Reward = 50; break; } default: { Reward = 0; break; } } if ((a_TDI.Attacker != nullptr) && (!IsBaby())) { m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward); } m_DestroyTimer = std::chrono::milliseconds(0); }
void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); if (!IsTicking()) { // The base class tick destroyed us return; } GET_AND_VERIFY_CURRENT_CHUNK(Chunk, POSX_TOINT, POSZ_TOINT); ASSERT((GetTarget() == nullptr) || (GetTarget()->IsPawn() && (GetTarget()->GetWorld() == GetWorld()))); if (m_AttackCoolDownTicksLeft > 0) { m_AttackCoolDownTicksLeft -= 1; } if (m_Health <= 0) { // The mob is dead, but we're still animating the "puff" they leave when they die m_DestroyTimer += a_Dt; if (m_DestroyTimer > std::chrono::seconds(1)) { Destroy(true); } return; } if (m_TicksSinceLastDamaged < 100) { ++m_TicksSinceLastDamaged; } if ((GetTarget() != nullptr)) { ASSERT(GetTarget()->IsTicking()); if (GetTarget()->IsPlayer()) { if (static_cast<cPlayer *>(GetTarget())->IsGameModeCreative()) { SetTarget(nullptr); m_EMState = IDLE; } } } // Process the undead burning in daylight. HandleDaylightBurning(*Chunk, WouldBurnAt(GetPosition(), *Chunk)); bool a_IsFollowingPath = false; if (m_PathfinderActivated) { if (ReachedFinalDestination()) { StopMovingToPosition(); // Simply sets m_PathfinderActivated to false. } else { // Note that m_NextWayPointPosition is actually returned by GetNextWayPoint) switch (m_PathFinder.GetNextWayPoint(*Chunk, GetPosition(), &m_FinalDestination, &m_NextWayPointPosition, m_EMState == IDLE ? true : false)) { case ePathFinderStatus::PATH_FOUND: { /* If I burn in daylight, and I won't burn where I'm standing, and I'll burn in my next position, and at least one of those is true: 1. I am idle 2. I was not hurt by a player recently. Then STOP. */ if ( m_BurnsInDaylight && ((m_TicksSinceLastDamaged >= 100) || (m_EMState == IDLE)) && WouldBurnAt(m_NextWayPointPosition, *Chunk) && !WouldBurnAt(GetPosition(), *Chunk) ) { // If we burn in daylight, and we would burn at the next step, and we won't burn where we are right now, and we weren't provoked recently: StopMovingToPosition(); } else { a_IsFollowingPath = true; // Used for proper body / head orientation only. MoveToWayPoint(*Chunk); } break; } case ePathFinderStatus::PATH_NOT_FOUND: { StopMovingToPosition(); break; } default: { } } } } SetPitchAndYawFromDestination(a_IsFollowingPath); switch (m_EMState) { case IDLE: { // If enemy passive we ignore checks for player visibility. InStateIdle(a_Dt, a_Chunk); break; } case CHASING: { // If we do not see a player anymore skip chasing action. InStateChasing(a_Dt, a_Chunk); break; } case ESCAPING: { InStateEscaping(a_Dt, a_Chunk); break; } case ATTACKING: break; } // switch (m_EMState) BroadcastMovementUpdate(); if (m_AgingTimer > 0) { m_AgingTimer--; if ((m_AgingTimer <= 0) && IsBaby()) { SetAge(1); m_World->BroadcastEntityMetadata(*this); } } }
void cMonster::KilledBy(cEntity * a_Killer) { super::KilledBy(a_Killer); if (m_SoundHurt != "") { m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f); } int Reward; switch (m_MobType) { // Animals case cMonster::mtChicken: case cMonster::mtCow: case cMonster::mtHorse: case cMonster::mtPig: case cMonster::mtSheep: case cMonster::mtSquid: case cMonster::mtMooshroom: case cMonster::mtOcelot: case cMonster::mtWolf: { Reward = m_World->GetTickRandomNumber(2) + 1; break; } // Monsters case cMonster::mtCaveSpider: case cMonster::mtCreeper: case cMonster::mtEnderman: case cMonster::mtGhast: case cMonster::mtSilverfish: case cMonster::mtSkeleton: case cMonster::mtSpider: case cMonster::mtWitch: case cMonster::mtZombie: case cMonster::mtZombiePigman: case cMonster::mtSlime: case cMonster::mtMagmaCube: { Reward = 6 + (m_World->GetTickRandomNumber(2)); break; } case cMonster::mtBlaze: { Reward = 10; break; } // Bosses case cMonster::mtEnderDragon: { Reward = 12000; break; } case cMonster::mtWither: { Reward = 50; break; } default: { Reward = 0; break; } } if ((a_Killer != NULL) && (!IsBaby())) { m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward); } m_DestroyTimer = 0; }