Beispiel #1
0
 virtual MoveInfo getMove() {
   if (creature->getAttributes().getSkills().hasDiscrete(SkillId::HEALING)) {
     int healingRadius = 2;
     for (Position pos : creature->getPosition().getRectangle(
           Rectangle(-healingRadius, -healingRadius, healingRadius + 1, healingRadius + 1)))
       if (const Creature* other = pos.getCreature())
         if (creature->isFriend(other))
           if (auto action = creature->heal(creature->getPosition().getDir(other->getPosition())))
             return MoveInfo(0.5, action);
   }
   if (!creature->getAttributes().isHumanoid())
     return NoMove;
   if (creature->isAffected(LastingEffect::POISON)) {
     if (MoveInfo move = tryEffect(EffectType(EffectId::LASTING, LastingEffect::POISON_RESISTANT), 1))
       return move;
     if (MoveInfo move = tryEffect(EffectType(EffectId::CURE_POISON), 1))
       return move;
   }
   if (creature->getHealth() < 1) {
     if (MoveInfo move = tryEffect(EffectId::HEAL, 1))
       return move.withValue(min(1.0, 1.5 - creature->getHealth()));
     if (MoveInfo move = tryEffect(EffectId::HEAL, 3))
       return move.withValue(0.5 * min(1.0, 1.5 - creature->getHealth()));
   }
   for (Position pos : creature->getPosition().neighbors8())
     if (Creature* c = pos.getCreature())
       if (creature->isFriend(c) && c->getHealth() < 1)
         for (Item* item : creature->getEquipment().getItems(Item::effectPredicate(EffectId::HEAL)))
           if (auto action = creature->give(c, {item}))
             return MoveInfo(0.5, action);
   return NoMove;
 }
Beispiel #2
0
 double getThrowValue(Item* it) {
   if (contains<EffectType>({
         EffectType(EffectId::LASTING, LastingEffect::POISON),
         EffectType(EffectId::LASTING, LastingEffect::SLOWED),
         EffectType(EffectId::LASTING, LastingEffect::BLIND),
         EffectType(EffectId::LASTING, LastingEffect::SLEEP)},
         it->getEffectType()))
     return 100;
   return it->getModifier(ModifierType::THROWN_DAMAGE);
 }
Beispiel #3
0
 virtual double itemValue(const Item* item) override {
   if (contains<EffectType>({
         EffectType(EffectId::LASTING, LastingEffect::INVISIBLE),
         EffectType(EffectId::LASTING, LastingEffect::SLOWED),
         EffectType(EffectId::LASTING, LastingEffect::BLIND),
         EffectType(EffectId::LASTING, LastingEffect::SLEEP),
         EffectType(EffectId::LASTING, LastingEffect::POISON),
         EffectType(EffectId::LASTING, LastingEffect::POISON_RESISTANT),
         EffectId::CURE_POISON,
         EffectId::TELEPORT,
         EffectType(EffectId::LASTING, LastingEffect::STR_BONUS),
         EffectType(EffectId::LASTING, LastingEffect::DEX_BONUS)},
         item->getEffectType()))
     return 1;
   if (item->getClass() == ItemClass::AMMO && creature->getAttributes().getSkills().getValue(SkillId::ARCHERY) > 0)
     return 0.1;
   if (!creature->isEquipmentAppropriate(item))
     return 0;
   if (item->getModifier(ModifierType::THROWN_DAMAGE) > 0)
     return (double)item->getModifier(ModifierType::THROWN_DAMAGE) / 50;
   int damage = item->getModifier(ModifierType::DAMAGE);
   Item* best = getBestWeapon();
   if (best && best != item && best->getModifier(ModifierType::DAMAGE) >= damage)
       return 0;
   return (double)damage / 50;
 }
Beispiel #4
0
 virtual double itemValue(const Item* item) {
   if (item->getEffectType() == EffectType(EffectId::HEAL)) {
     return 0.5;
   }
   else
     return 0;
 }
Beispiel #5
0
optional<MinionEquipment::EquipmentType> MinionEquipment::getEquipmentType(const Item* it) {
  if (it->canEquip())
    return MinionEquipment::ARMOR;
  if (contains({ItemClass::RANGED_WEAPON, ItemClass::AMMO}, it->getClass()))
    return MinionEquipment::ARCHERY;
  if (it->getEffectType() == EffectType(EffectId::HEAL))
    return MinionEquipment::HEALING;
  if (contains(combatConsumables, it->getEffectType()))
    return MinionEquipment::COMBAT_ITEM;
  return none;
}
Beispiel #6
0
 MoveInfo getAttackMove(Creature* other, bool chase) {
   int distance = 10000;
   CHECK(other);
   if (other->getAttributes().isInvincible())
     return NoMove;
   Debug() << creature->getName().bare() << " enemy " << other->getName().bare();
   Vec2 enemyDir = creature->getPosition().getDir(other->getPosition());
   distance = enemyDir.length8();
   if (creature->getAttributes().isHumanoid() && !creature->getWeapon()) {
     if (Item* weapon = getBestWeapon())
       if (auto action = creature->equip(weapon))
         return {3.0 / (2.0 + distance), action.prepend([=](Creature* creature) {
           creature->setInCombat();
           other->setInCombat();
       })};
   }
   if (distance == 1)
     if (MoveInfo move = tryEffect(EffectId::AIR_BLAST, 1))
       return move;
   if (distance <= 5)
     for (EffectType effect : {
         EffectType(EffectId::LASTING, LastingEffect::INVISIBLE),
         EffectType(EffectId::LASTING, LastingEffect::STR_BONUS),
         EffectType(EffectId::LASTING, LastingEffect::DEX_BONUS),
         EffectType(EffectId::LASTING, LastingEffect::SPEED),
         EffectType(EffectId::DECEPTION),
         EffectType(EffectId::SUMMON, CreatureId::SPIRIT)})
       if (MoveInfo move = tryEffect(effect, 1))
         return move;
   if (distance > 1) {
     if (distance < 10) {
       if (MoveInfo move = getFireMove(enemyDir))
         return move;
       if (MoveInfo move = getThrowMove(enemyDir))
         return move;
     }
     if (chase && !other->getAttributes().dontChase() && !isChaseFrozen(other)) {
       lastSeen = none;
       if (auto action = creature->moveTowards(other->getPosition()))
         return {max(0., 1.0 - double(distance) / 10), action.prepend([=](Creature* creature) {
           creature->setInCombat();
           other->setInCombat();
           lastSeen = {other->getPosition(), creature->getGlobalTime(), LastSeen::ATTACK, other->getUniqueId()};
           if (!chaseFreeze.count(other) || other->getGlobalTime() > chaseFreeze.at(other).second)
             chaseFreeze[other] = make_pair(other->getGlobalTime() + 20, other->getGlobalTime() + 70);
         })};
     }
   }
   if (distance == 1)
     if (auto action = creature->attack(other, getAttackParams(other)))
       return {1.0, action.prepend([=](Creature* creature) {
           creature->setInCombat();
           other->setInCombat();
       })};
   return NoMove;
 }
Beispiel #7
0
   KeeperRL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
   even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along with this program.
   If not, see http://www.gnu.org/licenses/ . */

#include "stdafx.h"

#include "minion_equipment.h"
#include "item.h"
#include "creature.h"
#include "effect.h"

static vector<EffectType> combatConsumables {
    EffectType(EffectId::LASTING, LastingEffect::SPEED),
    EffectType(EffectId::LASTING, LastingEffect::SLOWED),
    EffectType(EffectId::LASTING, LastingEffect::SLEEP),
    EffectType(EffectId::LASTING, LastingEffect::POISON),
    EffectType(EffectId::LASTING, LastingEffect::BLIND),
    EffectType(EffectId::LASTING, LastingEffect::INVISIBLE),
    EffectType(EffectId::LASTING, LastingEffect::STR_BONUS),
    EffectType(EffectId::LASTING, LastingEffect::DEX_BONUS),
    EffectType(EffectId::LASTING, LastingEffect::POISON_RESISTANT),
};

template <class Archive>
void MinionEquipment::serialize(Archive& ar, const unsigned int version) {
  ar & SVAR(owners);
  CHECK_SERIAL;
}
void MeleeSystem::update(float dt) {
       
    CCArray * entities = this->entityManager->getAllEntitiesPosessingComponentOfClass("MeleeComponent");
    CCObject* object = NULL;
    CCARRAY_FOREACH(entities, object)
    {
        Entity* entity = (Entity*) object;
        RenderComponent* render = entity->render();
        MeleeComponent* melee = entity->melee();
        TeamComponent* team = entity->team();
        if (!render || !melee || !team) continue;
        
        bool aoeDamageCaused = false;
        CCArray * enemies = entity->getAllEntitiesOnTeam(OPPOSITE_TEAM(team->team),"RenderComponent");
        CCObject* temp = NULL;
        CCARRAY_FOREACH(enemies, temp){
            Entity* enemy = (Entity*) temp;
	        RenderComponent * enemyRender = enemy->render();
            HealthComponent * enemyHealth = enemy->health();
	     
            if (!enemyRender || !enemyHealth) continue;
 
			float distance = ccpDistance(render->node->getPosition(), enemyRender->node->getPosition());
			MonsterComponent* monsterCom = entity->monster();
            if (render->node->boundingBox().intersectsRect(enemyRender->node->boundingBox())
				||monsterCom && abs(distance) < monsterCom->monster->deck->fight.Range) {
                if (GetTickCount() - melee->_damage->lastDamageTime > melee->deck->fight.FireRate * 1000) {
                    CCPoint edge = ccp((render->node->getPosition().x+enemyRender->node->getPosition().x)/2,
						(render->node->getPosition().y+enemyRender->node->getPosition().y)/2);
					//make slow enemy
					MoveComponent* move = (MoveComponent*) enemy->move();
					if(move)
						move->velocity = ccpNormalize(move->velocity) ; 
#if SOUND
                    CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(melee->deck->sound);
#endif
					
            

					MonsterComponent* enemyMonster = enemy->monster();
					if(enemyMonster)
					{
						CCPoint currrent = enemyRender->node->getPosition();
						//float scale = enemyRender->node->getScale();
						CCScaleTo* a = CCScaleBy::create(0.1f,1.5f);
						int ran = rand()%2;
						CCRotateTo* b = CCRotateTo::create(0.1f,ran?15:-15);
						//CCRotateTo* c = CCRotateTo::create(0.1f,-30);
						CCRotateTo* d = CCRotateTo::create(0.1f,0);
						CCScaleTo* e = CCScaleTo::create(0.1f,1.0f);
						CCSequence* sequence = CCSequence::create(a,b,d,e,NULL);
						enemyRender->node->runAction(sequence);
								
					}

					MonsterComponent* monster = entity->monster();
					if(monster)
					{
						entityFactory->createEffect(EffectType((int)monster->monsterType +4),edge);
					}
					if (melee->deck->fight.aoe) {
		                        aoeDamageCaused = true;
		                    } else {
		                        melee->_damage->lastDamageTime = GetTickCount();
		                    }
		                    enemyHealth->curHP -= melee->deck->fight.Damage;
					char temp[64];
					sprintf(temp, "%d", (int)melee->deck->fight.Damage);
			
					CCLabelBMFont* hitLabel = CCLabelBMFont::create(temp,"Courier_red.fnt");
					hitLabel->setPosition(edge);
					entityFactory->_batchNode->getParent()->addChild(hitLabel);
					CCScaleTo* scaleFrom = CCScaleTo::create(0.1f,1.5f);
					CCDelayTime* delay = CCDelayTime::create(0.1f);
					CCScaleTo* scaleTo = CCScaleTo::create(0.1f,1.0f);
					CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,callfuncN_selector(MeleeSystem::clean));

					CCSequence* sequence = CCSequence::create(scaleFrom,delay,scaleTo,delay,actionMoveDone,NULL);

					hitLabel->runAction(sequence);

                    if (enemyHealth->curHP < 0) {
                        enemyHealth->curHP = 0;
                    }
                    if (melee->_damage->destroySelf) {
                        render->node->removeFromParentAndCleanup(true);
                        //CCLog("Removing entity:%d, I am a bullet.",entity->_eid);
                        this->entityManager->removeEntity(entity);
                    }
                }
            }
        }
Beispiel #9
0
 vector<DirEffectType> getOffensiveEffects() {
   return makeVec<DirEffectType>(
       DirEffectId::BLAST,
       DirEffectType(DirEffectId::CREATURE_EFFECT, EffectType(EffectId::LASTING, LastingEffect::STUNNED))
   );
 }