示例#1
0
Monster::Monster(MonsterClass *specy):
    Being(OBJECT_MONSTER),
    mSpecy(specy),
    mTargetListener(&monsterTargetEventDispatch),
    mOwner(NULL),
    mCurrentAttack(NULL)
{
    LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ").");

    setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER);

    /*
     * Initialise the attribute structures.
     */
    const AttributeManager::AttributeScope &mobAttr =
        attributeManager->getAttributeScope(MonsterScope);

    for (AttributeManager::AttributeScope::const_iterator it = mobAttr.begin(),
         it_end = mobAttr.end(); it != it_end; ++it)
    {
        mAttributes.insert(std::pair< unsigned int, Attribute >
                           (it->first, Attribute(*it->second)));
    }

    /*
     * Set the attributes to the values defined by the associated monster
     * class with or without mutations as needed.
     */

    int mutation = specy->getMutation();

    for (AttributeMap::iterator it2 = mAttributes.begin(),
         it2_end = mAttributes.end(); it2 != it2_end; ++it2)
    {
        double attr = 0.0f;

        if (specy->hasAttribute(it2->first))
        {
            attr = specy->getAttribute(it2->first);

            setAttribute(it2->first,
                  mutation ?
                  attr * (100 + (rand()%(mutation << 1)) - mutation) / 100.0 :
                  attr);
        }
    }

    setSize(specy->getSize());
    setGender(specy->getGender());

    // Set positions relative to target from which the monster can attack
    int dist = specy->getAttackDistance();
    mAttackPositions.push_back(AttackPosition(dist, 0, LEFT));
    mAttackPositions.push_back(AttackPosition(-dist, 0, RIGHT));
    mAttackPositions.push_back(AttackPosition(0, -dist, DOWN));
    mAttackPositions.push_back(AttackPosition(0, dist, UP));

    // Load default script
    loadScript(specy->getScript());
}
示例#2
0
MonsterComponent::MonsterComponent(Entity &entity, MonsterClass *specy):
    mSpecy(specy),
    mOwner(nullptr)
{
    LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ").");

    auto *beingComponent = entity.getComponent<BeingComponent>();

    auto *actorComponent = entity.getComponent<ActorComponent>();
    actorComponent->setWalkMask(Map::BLOCKMASK_WALL |
                                Map::BLOCKMASK_CHARACTER);
    actorComponent->setBlockType(BLOCKTYPE_MONSTER);
    actorComponent->setSize(specy->getSize());

    /*
     * Initialise the attribute structures.
     */

    for (auto attrInfo : attributeManager->getAttributeScope(MonsterScope))
    {
        beingComponent->createAttribute(attrInfo.first, *attrInfo.second);
    }

    /*
     * Set the attributes to the values defined by the associated monster
     * class with or without mutations as needed.
     */

    int mutation = specy->getMutation();

    for (auto &attribute : specy->getAttributes())
    {
        double attributeValue = attribute.second;
        if (mutation != 0)
        {
            double factor = 100 + (rand() % (mutation * 2)) - mutation;
            attributeValue = attributeValue * factor / 100.0;
        }
        beingComponent->setAttribute(entity, attribute.first, attributeValue);
    }

    beingComponent->setGender(specy->getGender());

    beingComponent->signal_died.connect(sigc::mem_fun(this,
                                            &MonsterComponent::monsterDied));

    // Set positions relative to target from which the monster can attack
    int dist = specy->getAttackDistance();
    mAttackPositions.push_back(AttackPosition(dist, 0, LEFT));
    mAttackPositions.push_back(AttackPosition(-dist, 0, RIGHT));
    mAttackPositions.push_back(AttackPosition(0, -dist, DOWN));
    mAttackPositions.push_back(AttackPosition(0, dist, UP));

    MonsterCombatComponent *combatComponent =
            new MonsterCombatComponent(entity, specy);
    entity.addComponent(combatComponent);

    double damageMutation = mutation ?
                (100.0 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1.0;
    combatComponent->setDamageMutation(damageMutation);

    combatComponent->signal_damaged.connect(
            sigc::mem_fun(this, &MonsterComponent::receivedDamage));
}