Beispiel #1
0
void TileObjectBattleMapPart::removeFromMap()
{
	bool requireRecalc = owningTile != nullptr;
	auto prevOwningTile = owningTile;
	auto prevDrawOnTile = drawOnTile;

	TileObject::removeFromMap();

	if (requireRecalc)
	{
		prevOwningTile->updateBattlescapeParameters();
		prevDrawOnTile->updateBattlescapeUIDrawOrder();
	}
}
Beispiel #2
0
void Tile::updateBattlescapeParameters()
{
	if (map.ceaseUpdates)
	{
		return;
	}
	bool providedGroundUpwards = solidGround && height >= 0.9625f;
	height = 0.0f;
	movementCostIn = -1; // -1 means empty, and will be set to 4 afterwards
	movementCostOver = 255;
	movementCostLeft = 0;
	movementCostRight = 0;
	solidGround = false;
	canStand = false;
	hasLift = false;
	hasExit = false;
	walkSfx = nullptr;
	objectDropSfx = nullptr;
	supportProviderForItems = nullptr;
	closedDoorLeft = false;
	closedDoorRight = false;
	for (auto &o : ownedObjects)
	{
		if (o->getType() == TileObject::Type::Ground || o->getType() == TileObject::Type::Feature)
		{
			auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(o)->getOwner();
			if (!mp->isAlive())
			{
				continue;
			}
			height = std::max(height, (float)mp->type->height);
			if (mp->type->floor ||
			    (o->getType() == TileObject::Type::Feature && !mp->type->gravlift))
			{
				if (!supportProviderForItems ||
				    supportProviderForItems->type->height < mp->type->height)
				{
					supportProviderForItems = mp;
				}
			}
			solidGround = solidGround || (mp->type->floor && !mp->type->gravlift) ||
			              (o->getType() == TileObject::Type::Feature && !mp->type->gravlift);
			hasLift = hasLift || mp->type->gravlift;
			hasExit = hasExit || mp->type->exit;
			movementCostIn = std::max(movementCostIn, mp->type->movement_cost);
			if (mp->type->sfxIndex != -1)
			{
				walkSfx = mp->type->walkSounds;
				objectDropSfx = mp->type->objectDropSound;
			}
		}
		if (o->getType() == TileObject::Type::LeftWall)
		{
			auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(o)->getOwner();
			if (!mp->isAlive())
			{
				continue;
			}
			movementCostLeft = mp->type->movement_cost;
			closedDoorLeft = mp->door && !mp->door->open;
		}
		if (o->getType() == TileObject::Type::RightWall)
		{
			auto mp = std::static_pointer_cast<TileObjectBattleMapPart>(o)->getOwner();
			if (!mp->isAlive())
			{
				continue;
			}
			movementCostRight = mp->type->movement_cost;
			closedDoorRight = mp->door && !mp->door->open;
		}
	}
	canStand = solidGround || hasLift;
	if (!canStand && position.z > 0)
	{
		// check if tile below is full height
		auto t = map.getTile(position.x, position.y, position.z - 1);
		// Floating point precision is lacking somtimes so even though we have to compare with
		// 0.975, we do this
		canStand = t->solidGround && t->height >= 0.9625f;
		if (canStand)
		{
			movementCostIn = std::max(movementCostIn, t->movementCostOver);
		}
	}
	if (movementCostIn == -1)
	{
		movementCostIn = 4;
	}
	// Height of 39 means whole tile
	if (height == 39 && solidGround)
	{
		movementCostOver = movementCostIn;
		movementCostIn = 255;
		// Provide solid ground upwards
		if (position.z + 1 < map.size.z)
		{
			auto t = map.getTile(position.x, position.y, position.z + 1);
			if (!t->canStand)
			{
				t->canStand = true;
				t->movementCostIn = std::max(movementCostOver, t->movementCostIn);
			}
		}
	}
	height = height / (float)TILE_Z_BATTLE;
	// Propagate update upwards if we provided ground and ceased to do so
	if (!(solidGround && height >= 0.9625f) && providedGroundUpwards && position.z + 1 < map.size.z)
	{
		auto t = map.getTile(position.x, position.y, position.z + 1);
		t->updateBattlescapeParameters();
	}
}