void cPlayer::MoveTo( const Vector3d & a_NewPos ) { if ((a_NewPos.y < -990) && (GetPosY() > -100)) { // When attached to an entity, the client sends position packets with weird coords: // Y = -999 and X, Z = attempting to create speed, usually up to 0.03 // We cannot test m_AttachedTo, because when deattaching, the server thinks the client is already deattached while // the client may still send more of these nonsensical packets. if (m_AttachedTo != NULL) { Vector3d AddSpeed(a_NewPos); AddSpeed.y = 0; m_AttachedTo->AddSpeed(AddSpeed); } return; } // TODO: should do some checks to see if player is not moving through terrain // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too Vector3d DeltaPos = a_NewPos - GetPosition(); UpdateMovementStats(DeltaPos); SetPosition( a_NewPos ); SetStance(a_NewPos.y + 1.62); }
void cMinecartWithFurnace::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 (m_IsFueled) { m_FueledTimeLeft--; if (m_FueledTimeLeft < 0) { m_IsFueled = false; m_World->BroadcastEntityMetadata(*this); return; } if (GetSpeed().Length() > 6) { return; } AddSpeed(GetSpeed() / 4); } }
void Unit::UpgleWeapon() { auto weapon = m_WeaponQueue.front(); weapon->AddCount(2); weapon->AddDamage(5); weapon->AddSize(0.01f); weapon->AddSpeed(3); weapon->UpdateLabel(); }
void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) { if (GetSpeed().Length() > 7.5) { return; } Vector3d ToAddSpeed = m_Attachee->GetLookVector() * (a_Sideways * 0.4) ; ToAddSpeed.y = 0; AddSpeed(ToAddSpeed); }
void cMinecartWithFurnace::OnRightClicked(cPlayer & a_Player) { if (a_Player.GetEquippedItem().m_ItemType == E_ITEM_COAL) { if (!a_Player.IsGameModeCreative()) { a_Player.GetInventory().RemoveOneEquippedItem(); } if (!m_IsFueled) // We don't want to change the direction by right clicking it. { AddSpeed(a_Player.GetLookVector().x, 0, a_Player.GetLookVector().z); } m_IsFueled = true; m_FueledTimeLeft = m_FueledTimeLeft + 600; // The minecart will be active 600 more ticks. m_World->BroadcastEntityMetadata(*this); } }
void cMinecartWithFurnace::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); if (m_IsFueled) { m_FueledTimeLeft--; if (m_FueledTimeLeft < 0) { m_IsFueled = false; m_World->BroadcastEntityMetadata(*this); return; } if (GetSpeed().Length() > 6) { return; } AddSpeed(GetSpeed() / 4); } }
bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) { if (cRoot::Get()->GetPluginManager()->CallHookTakeDamage(*this, a_TDI)) { return false; } if (m_Health <= 0) { // Can't take damage if already dead return false; } if (m_InvulnerableTicks > 0) { // Entity is invulnerable return false; } if ((a_TDI.Attacker != NULL) && (a_TDI.Attacker->IsPlayer())) { cPlayer * Player = (cPlayer *)a_TDI.Attacker; // IsOnGround() only is false if the player is moving downwards if (!Player->IsOnGround()) // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) { a_TDI.FinalDamage += 2; m_World->BroadcastEntityAnimation(*this, 4); // Critical hit } Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } m_Health -= (short)a_TDI.FinalDamage; // TODO: Apply damage to armor if (m_Health < 0) { m_Health = 0; } if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs { int KnockbackLevel = 0; if (a_TDI.Attacker->GetEquippedWeapon().m_ItemType == E_ITEM_BOW) { KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch); } else { KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); } Vector3d additionalSpeed(0, 0, 0); switch (KnockbackLevel) { case 1: { additionalSpeed.Set(5, .3, 5); break; } case 2: { additionalSpeed.Set(8, .3, 8); break; } default: { additionalSpeed.Set(2, .3, 2); break; } } AddSpeed(a_TDI.Knockback * additionalSpeed); } m_World->BroadcastEntityStatus(*this, esGenericHurt); m_InvulnerableTicks = 10; if (m_Health <= 0) { KilledBy(a_TDI.Attacker); if (a_TDI.Attacker != NULL) { a_TDI.Attacker->Killed(this); } } return true; }