示例#1
0
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);
}
示例#2
0
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);
	}
}
示例#3
0
void Unit::UpgleWeapon()
{
    auto weapon = m_WeaponQueue.front();
    weapon->AddCount(2);
    weapon->AddDamage(5);
    weapon->AddSize(0.01f);
    weapon->AddSpeed(3);
    weapon->UpdateLabel();
}
示例#4
0
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);
}
示例#5
0
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);
    }
}
示例#6
0
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);
    }
}
示例#7
0
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;
}