void cPlayer::AddFoodExhaustion(double a_Exhaustion) { if (!(IsGameModeCreative() || IsGameModeSpectator())) { m_FoodExhaustionLevel = std::min(m_FoodExhaustionLevel + a_Exhaustion, 40.0); } }
void cPlayer::UseEquippedItem(int a_Amount) { if (IsGameModeCreative() || IsGameModeSpectator()) // No damage in creative or spectator { return; } // If the item has an unbreaking enchantment, give it a random chance of not breaking: cItem Item = GetEquippedItem(); int UnbreakingLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking); if (UnbreakingLevel > 0) { int chance; if (ItemCategory::IsArmor(Item.m_ItemType)) { chance = 60 + (40 / (UnbreakingLevel + 1)); } else { chance = 100 / (UnbreakingLevel + 1); } cFastRandom Random; if (Random.NextInt(101) <= chance) { return; } } if (GetInventory().DamageEquippedItem(a_Amount)) { m_World->BroadcastSoundEffect("random.break", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); } }
void cPlayer::SetGameMode(eGameMode a_GameMode) { if ((a_GameMode < gmMin) || (a_GameMode >= gmMax)) { LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode); return; } if (m_GameMode == a_GameMode) { // Gamemode already set return; } m_GameMode = a_GameMode; m_ClientHandle->SendGameMode(a_GameMode); if (!(IsGameModeCreative() || IsGameModeSpectator())) { SetFlying(false); SetCanFly(false); } m_World->BroadcastPlayerListUpdateGameMode(*this); }
void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtPlugin)) { if (IsGameModeCreative()) { // No damage / health in creative mode if not void or plugin damage return; } } if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) { cPlayer* Attacker = (cPlayer*) a_TDI.Attacker; if ((m_Team != NULL) && (m_Team == Attacker->m_Team)) { if (!m_Team->AllowsFriendlyFire()) { // Friendly fire is disabled return; } } } super::DoTakeDamage(a_TDI); // Any kind of damage adds food exhaustion AddFoodExhaustion(0.3f); SendHealth(); }
void cPlayer::UseEquippedItem(void) { if (IsGameModeCreative()) // No damage in creative { return; } GetInventory().DamageEquippedItem(); }
void cPlayer::UseEquippedItem(void) { if (IsGameModeCreative()) // No damage in creative { return; } if (GetInventory().DamageEquippedItem()) { m_World->BroadcastSoundEffect("random.break", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); } }
void cPlayer::TickBurning(cChunk & a_Chunk) { // Don't burn in creative and stop burning in creative if necessary if (!IsGameModeCreative()) { super::TickBurning(a_Chunk); } else if (IsOnFire()) { m_TicksLeftBurning = 0; OnFinishedBurning(); } }
void cPlayer::HandleFood(void) { // Ref.: http://www.minecraftwiki.net/wiki/Hunger if (IsGameModeCreative()) { // Hunger is disabled for Creative return; } // Apply food exhaustion that has accumulated: if (m_FoodExhaustionLevel > 4.0) { m_FoodExhaustionLevel -= 4.0; if (m_FoodSaturationLevel > 0.0) { m_FoodSaturationLevel = std::max(m_FoodSaturationLevel - 1.0, 0.0); } else { SetFoodLevel(m_FoodLevel - 1); } } // Heal or damage, based on the food level, using the m_FoodTickTimer: if ((m_FoodLevel >= 18) || (m_FoodLevel <= 0)) { m_FoodTickTimer++; if (m_FoodTickTimer >= 80) { m_FoodTickTimer = 0; if ((m_FoodLevel >= 18) && (GetHealth() < GetMaxHealth())) { // Regenerate health from food, incur 3 pts of food exhaustion: Heal(1); AddFoodExhaustion(3.0); } else if ((m_FoodLevel <= 0) && (m_Health > 1)) { // Damage from starving TakeDamage(dtStarving, NULL, 1, 1, 0); } } } else { m_FoodTickTimer = 0; } }
void cPlayer::ApplyFoodExhaustionFromMovement() { if (IsGameModeCreative()) { return; } // If we have just teleported, apply no exhaustion if (m_bIsTeleporting) { m_bIsTeleporting = false; return; } // If riding anything, apply no food exhaustion if (m_AttachedTo != NULL) { return; } // Process exhaustion every two ticks as that is how frequently m_LastPos is updated // Otherwise, we apply exhaustion for a 'movement' every tick, one of which is an already processed value if (GetWorld()->GetWorldAge() % 2 != 0) { return; } // Calculate the distance travelled, update the last pos: Vector3d Movement(GetPosition() - m_LastPos); Movement.y = 0; // Only take XZ movement into account // Apply the exhaustion based on distance travelled: double BaseExhaustion = Movement.Length(); if (IsSprinting()) { // 0.1 pt per meter sprinted BaseExhaustion = BaseExhaustion * 0.1; } else if (IsSwimming()) { // 0.015 pt per meter swum BaseExhaustion = BaseExhaustion * 0.015; } else { // 0.01 pt per meter walked / sneaked BaseExhaustion = BaseExhaustion * 0.01; } m_FoodExhaustionLevel += BaseExhaustion; }
void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType != dtInVoid) { if (IsGameModeCreative()) { // No damage / health in creative mode return; } } super::DoTakeDamage(a_TDI); // Any kind of damage adds food exhaustion AddFoodExhaustion(0.3f); SendHealth(); }
void cPlayer::SetTouchGround(bool a_bTouchGround) { m_bTouchGround = a_bTouchGround; if (!m_bTouchGround) { if (GetPosY() > m_LastJumpHeight) { m_LastJumpHeight = (float)GetPosY(); } cWorld * World = GetWorld(); if ((GetPosY() >= 0) && (GetPosY() < cChunkDef::Height)) { BLOCKTYPE BlockType = World->GetBlock(float2int(GetPosX()), float2int(GetPosY()), float2int(GetPosZ())); if (BlockType != E_BLOCK_AIR) { m_bTouchGround = true; } if ( (BlockType == E_BLOCK_WATER) || (BlockType == E_BLOCK_STATIONARY_WATER) || (BlockType == E_BLOCK_LADDER) || (BlockType == E_BLOCK_VINES) ) { m_LastGroundHeight = (float)GetPosY(); } } } else { float Dist = (float)(m_LastGroundHeight - floor(GetPosY())); int Damage = (int)(Dist - 3.f); if (m_LastJumpHeight > m_LastGroundHeight) Damage++; m_LastJumpHeight = (float)GetPosY(); if ((Damage > 0) && (!IsGameModeCreative())) { TakeDamage(dtFalling, NULL, Damage, Damage, 0); } m_LastGroundHeight = (float)GetPosY(); } }
void cPlayer::SetGameMode(eGameMode a_GameMode) { if ((a_GameMode < gmMin) || (a_GameMode >= gmMax)) { LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode); return; } if (m_GameMode == a_GameMode) { // Gamemode already set return; } m_GameMode = a_GameMode; m_ClientHandle->SendGameMode(a_GameMode); if (!IsGameModeCreative()) { SetFlying(false); SetCanFly(false); } }
void cPlayer::ApplyFoodExhaustionFromMovement() { if (IsGameModeCreative()) { return; } // Calculate the distance travelled, update the last pos: Vector3d Movement(GetPosition() - m_LastFoodPos); Movement.y = 0; // Only take XZ movement into account m_LastFoodPos = GetPosition(); // If riding anything, apply no food exhaustion if (m_AttachedTo != NULL) { return; } // Apply the exhaustion based on distance travelled: double BaseExhaustion = Movement.Length(); if (IsSprinting()) { // 0.1 pt per meter sprinted BaseExhaustion = BaseExhaustion * 0.1; } else if (IsSwimming()) { // 0.015 pt per meter swum BaseExhaustion = BaseExhaustion * 0.015; } else { // 0.01 pt per meter walked / sneaked BaseExhaustion = BaseExhaustion * 0.01; } m_FoodExhaustionLevel += BaseExhaustion; }
bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtPlugin)) { if (IsGameModeCreative()) { // No damage / health in creative mode if not void or plugin damage return false; } } if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) { cPlayer * Attacker = (cPlayer *)a_TDI.Attacker; if ((m_Team != NULL) && (m_Team == Attacker->m_Team)) { if (!m_Team->AllowsFriendlyFire()) { // Friendly fire is disabled return false; } } } if (super::DoTakeDamage(a_TDI)) { // Any kind of damage adds food exhaustion AddFoodExhaustion(0.3f); SendHealth(); m_Stats.AddValue(statDamageTaken, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); return true; } return false; }
void cPlayer::HandleFood(void) { // Ref.: http://www.minecraftwiki.net/wiki/Hunger if (IsGameModeCreative()) { // Hunger is disabled for Creative return; } // Remember the food level before processing, for later comparison int LastFoodLevel = m_FoodLevel; // Heal or damage, based on the food level, using the m_FoodTickTimer: if ((m_FoodLevel > 17) || (m_FoodLevel <= 0)) { m_FoodTickTimer++; if (m_FoodTickTimer >= 80) { m_FoodTickTimer = 0; if (m_FoodLevel >= 17) { // Regenerate health from food, incur 3 pts of food exhaustion: Heal(1); m_FoodExhaustionLevel += 3; } else if ((m_FoodLevel <= 0) && (m_Health > 1)) { // Damage from starving TakeDamage(dtStarving, NULL, 1, 1, 0); } } } // Apply food poisoning food exhaustion: if (m_FoodPoisonedTicksRemaining > 0) { m_FoodPoisonedTicksRemaining--; m_FoodExhaustionLevel += 0.025; // 0.5 per second = 0.025 per tick } else { m_World->BroadcastRemoveEntityEffect(*this, E_EFFECT_HUNGER); // Remove the "Hunger" effect. } // Apply food exhaustion that has accumulated: if (m_FoodExhaustionLevel >= 4) { m_FoodExhaustionLevel -= 4; if (m_FoodSaturationLevel >= 1) { m_FoodSaturationLevel -= 1; } else { m_FoodLevel = std::max(m_FoodLevel - 1, 0); } } if (m_FoodLevel != LastFoodLevel) { SendHealth(); } }