コード例 #1
0
ファイル: World.cpp プロジェクト: ZwodahS/LD30
void World::move(zf::Direction direction)
{
    if (player and player->canMove())
    {
        if (player->isGrabbing())
        {
            auto mod = zf::getModifier(direction);
            auto playerTargetPosition = player->position + mod;
            bool canMove = true;
            if (inRange(playerTargetPosition))
            {
                auto grabbed = player->getGrabbedObjects();
                auto destinationObject = getObject(playerTargetPosition);
                if (!destinationObject || std::find(grabbed.begin(), grabbed.end(), destinationObject) != grabbed.end())
                {
                    for (auto object : grabbed)
                    {
                        if (!object->canGrabbed(direction, *player, grabbed))
                        {
                            canMove = false;
                            break;
                        }
                    }
                    if (canMove)
                    {
                        moveObject(*player, player->position + mod);
                        player->objectMoved();
                        for (auto object : grabbed)
                        {
                            moveObject (*object, object->position + mod);
                        }
                        player->doWork(game.balance.Player_MoveCost + grabbed.size() * game.balance.Player_GrabCost);
                    }
                }
            }
        }
        else
        {
            auto mod = zf::getModifier(direction);
            auto targetPosition = player->position + mod;
            if (inRange(targetPosition))
            {
                auto object = getObject(targetPosition);
                auto objectTargetPosition = targetPosition + mod;
                if (!object)
                {
                    moveObject(*player, targetPosition);
                    player->objectMoved();
                    player->doWork(game.balance.Player_MoveCost);
                }
                else if (object->type == WorldObject::ObjectType::FoodObject)
                {
                    player->eat();
                    removeFromGrid(object);
                    removeFromList(object);
                    delete object;
                    moveObject(*player, targetPosition);
                    player->objectMoved();
                }
                else if (inRange(objectTargetPosition))
                {
                    auto objectObstacle = getObject(objectTargetPosition);
                    if (!object->isPushable())
                    {
                    }
                    else if (!objectObstacle)
                    {
                        moveObject(*player, targetPosition);
                        player->objectMoved();
                        moveObject(*object, targetPosition + mod);
                        player->doWork(game.balance.Player_MoveCost + game.balance.Player_PushCost);
                    }
                    /// cant push, see if we can combine
                    else if (object->type == WorldObject::ObjectType::SandObject && objectObstacle->type == WorldObject::ObjectType::SandObject)
                    {
                        // merge the sand object
                        auto sandSource = static_cast<SandObject*>(object);
                        auto sandTarget = static_cast<SandObject*>(objectObstacle);
                        if (sandSource->count + sandTarget->count <= 4)
                        {
                            // can only merge if their total is < 4
                            sandTarget->count += sandSource->count;
                            // respawn sandSource
                            sandSource->count = 1;
                            removeFromGrid(sandSource);
                            removeFromList(sandSource);
                            moveObject(*player, targetPosition);
                            player->objectMoved();
                            if (spawnSand())
                            {
                                spawnObject(sandSource);
                            }
                            else
                            {
                                delete sandSource;
                            }
                        }
                        player->doWork(game.balance.Player_MoveCost + game.balance.Player_PushCost);
                    }
                    else if (object->type == WorldObject::ObjectType::SandObject && objectObstacle->type == WorldObject::ObjectType::WaterObject)
                    {
                        auto sandSource = static_cast<SandObject*>(object);
                        auto waterTarget = static_cast<WaterObject*>(objectObstacle);
                        if (waterTarget->flood)
                        {
                            removeFromGrid(waterTarget);
                            removeFromList(waterTarget);
                            waterTarget->flood = false;
                            waterTarget->floodMeter = 0;
                            outputBlocks.push_back(waterTarget);
                            sandSource->count-=1;
                            if (sandSource->count <= 0)
                            {
                                removeFromGrid(sandSource);
                                removeFromList(sandSource);
                                delete sandSource;
                            }
                            else
                            {
                                moveObject(*sandSource, objectTargetPosition);
                            }
                            moveObject(*player, targetPosition);
                            player->objectMoved();
                        }
                        player->doWork(game.balance.Player_MoveCost + game.balance.Player_PushCost);
                    }
                    else if (object->type == WorldObject::ObjectType::TreeObject && objectObstacle->type == WorldObject::ObjectType::WaterObject)
                    {
                        auto treeSource = static_cast<TreeObject*>(object);
                        auto waterTarget = static_cast<WaterObject*>(objectObstacle);
                        if (treeSource->grow())
                        {
                            removeFromGrid(waterTarget);
                            removeFromList(waterTarget);
                            delete waterTarget;
                            moveObject(*treeSource, objectTargetPosition);
                            moveObject(*player, targetPosition);
                            player->objectMoved();
                        }
                        player->doWork(game.balance.Player_MoveCost + game.balance.Player_PushCost);
                    }
                    else if (object->type == WorldObject::ObjectType::StoneObject && objectObstacle->type == WorldObject::ObjectType::VolcanoObject)
                    {
                        auto volcanoTarget = static_cast<VolcanoObject*>(objectObstacle);
                        volcanoTarget->blocked = true;
                        removeFromGrid(object);
                        removeFromList(object);
                        delete object;
                        moveObject(*player, targetPosition);
                        player->objectMoved();
                        player->doWork(game.balance.Player_MoveCost + game.balance.Player_PushCost);
                    }
                }
            }
        }
    }
}
コード例 #2
0
ファイル: monster.cpp プロジェクト: novasdream/tyano-core
void Monster::pushMonsters() {
	if (!isAlive() || !canPushCreatures()) {
		return;
	}

	auto creatures = getTile()->getCreatures();
	if (creatures == nullptr) {
		return;
	}

	bool hasPushableMonsters = false;
	for (const auto& creature : *creatures) {
		if (creature == this) {
			continue;
		}

		auto monster = creature->getMonster();
		if (monster == nullptr) {
			continue;
		}
		if (!monster->isPushable()) {
			continue;
		}

		hasPushableMonsters = true;
		break;
	}

	if (!hasPushableMonsters) {
		// optimization to prevent unnecessary vector copy below
		return;
	}

	auto initialCreatures = *creatures;

	bool killedCreatures = false;
	for (const auto& creature : initialCreatures) {
		if (creature == this) {
			continue;
		}

		auto monster = creature->getMonster();
		if (monster == nullptr) {
			continue;
		}
		if (!monster->isPushable()) {
			continue;
		}

		Direction direction = monster->getRandomStepDirection(false);
		if (!monster->stepInDirection(direction)) {
			monster->setDropLoot(LOOT_DROP_NONE);
			monster->drainHealth(this, COMBAT_DEATHDAMAGE, -monster->getHealth());

			killedCreatures = true;
		}
	}

	if (killedCreatures) {
		server.game().addMagicEffect(getPosition(), MAGIC_EFFECT_BLOCKHIT);
	}
}