コード例 #1
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
void Monster::onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
	const Tile* oldTile, const Position& oldPos, bool teleport)
{
	Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport);
	if(creature == this)
	{
		if(isSummon())
			isMasterInRange = canSee(master->getPosition());

		updateTargetList();
		updateIdleStatus();
	}
	else
	{
		bool canSeeNewPos = canSee(newPos), canSeeOldPos = canSee(oldPos);
		if(canSeeNewPos && !canSeeOldPos)
			onCreatureEnter(const_cast<Creature*>(creature));
		else if(!canSeeNewPos && canSeeOldPos)
			onCreatureLeave(const_cast<Creature*>(creature));

		if(isSummon() && master == creature && canSeeNewPos) //Turn the summon on again
			isMasterInRange = true;

		updateIdleStatus();
		if(!followCreature && !isSummon() && isOpponent(creature)) //we have no target lets try pick this one
			selectTarget(const_cast<Creature*>(creature));
	}
}
コード例 #2
0
ファイル: actor.cpp プロジェクト: opentibia/server
bool Actor::selectTarget(Creature* creature)
{
#ifdef __DEBUG__
  std::cout << "Selecting target... " << std::endl;
#endif

  if(!isTarget(creature)){
    return false;
  }

  CreatureList::iterator it = std::find(targetList.begin(), targetList.end(), creature);
  if(it == targetList.end()){
    //Target not found in our target list.
#ifdef __DEBUG__
    std::cout << "Target not found in targetList." << std::endl;
#endif
    return false;
  }

  if(isHostile() || isSummon()){
    if(setAttackedCreature(creature) && !isSummon()){
      g_dispatcher.addTask(createTask(
        boost::bind(&Game::checkCreatureAttack, &g_game, getID())));
    }
  }

  return setFollowCreature(creature, true);
}
コード例 #3
0
ファイル: actor.cpp プロジェクト: opentibia/server
bool Actor::getNextStep(Direction& dir, uint32_t& flags)
{
  if(isIdle || getHealth() <= 0){
    //we dont have anyone watching might aswell stop walking
    eventWalk = 0;
    return false;
  }

  bool result = false;
  if((!followCreature || !hasFollowPath) && !isSummon()){
    if(followCreature){
      result = getRandomStep(getPosition(), dir);
    }else{
      if(getTimeSinceLastMove() > 1000){
        //choose a random direction
        result = getRandomStep(getPosition(), dir);
      }
    }
  }
  else if(isSummon() || followCreature){
    result = Creature::getNextStep(dir, flags);
    if(result){
      flags |= FLAG_PATHFINDING;
    }
    else{
      //target dancing
      if(attackedCreature && attackedCreature == followCreature){
        if(isFleeing()){
          result = getDanceStep(getPosition(), dir, false, false);
        }
        else if(cType.staticAttackChance() < (uint32_t)random_range(1, 100)){
          result = getDanceStep(getPosition(), dir);
        }
      }
    }
  }

  if(result && (canPushItems() || canPushCreatures()) ){
    const Position& pos = Combat::getCasterPosition(this, dir);
    Tile* tile = g_game.getParentTile(pos.x, pos.y, pos.z);
    if(tile){
      if(canPushItems()){
        pushItems(tile);
      }

      if(canPushCreatures()){
        pushCreatures(tile);
      }
    }
#ifdef __DEBUG__
    else{
      std::cout << "getNextStep - no tile." << std::endl;
    }
#endif
  }

  return result;
}
コード例 #4
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
bool Monster::getNextStep(Direction& dir, uint32_t& flags)
{
	if(isIdle || getHealth() <= 0)
	{
		//we dont have anyone watching might aswell stop walking
		eventWalk = 0;
		return false;
	}

	bool result = false;
	if((!followCreature || !hasFollowPath) && !isSummon())
	{
		if(followCreature || getTimeSinceLastMove() > 1000) //choose a random direction
			result = getRandomStep(getPosition(), dir);
	}
	else if(isSummon() || followCreature)
	{
		result = Creature::getNextStep(dir, flags);
		if(!result)
		{
			//target dancing
			if(attackedCreature && attackedCreature == followCreature)
			{
				if(isFleeing())
					result = getDanceStep(getPosition(), dir, false, false);
				else if(mType->staticAttackChance < (uint32_t)random_range(1, 100))
					result = getDanceStep(getPosition(), dir);
			}
		}
		else
			flags |= FLAG_PATHFINDING;
	}

	if(result && (canPushItems() || canPushCreatures()))
	{
		if(Tile* tile = g_game.getTile(Spells::getCasterPosition(this, dir)))
		{
			if(canPushItems())
				pushItems(tile);

			if(canPushCreatures())
				pushCreatures(tile);
		}
#ifdef __DEBUG__
		else
			std::clog << "[Warning - Monster::getNextStep] no tile found." << std::endl;
#endif
	}

	return result;
}
コード例 #5
0
ファイル: actor.cpp プロジェクト: opentibia/server
void Actor::onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
  const Tile* oldTile, const Position& oldPos, bool teleport)
{
  Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport);

  if(creature == this){
    if(isSummon()){
      isMasterInRange = canSee(getMaster()->getPosition());
    }

    updateTargetList();
    updateIdleStatus();

    /*
    TODO: Optimizations here
    if(teleport){
      //do a full update of the friend/target list
    }
    else{
      //partial update of the friend/target list
    }
    */
  }
  else{
    bool canSeeNewPos = canSee(newPos);
    bool canSeeOldPos = canSee(oldPos);

    if(canSeeNewPos && !canSeeOldPos){
      onCreatureEnter(const_cast<Creature*>(creature));
    }
    else if(!canSeeNewPos && canSeeOldPos){
      onCreatureLeave(const_cast<Creature*>(creature));
    }

    if(isSummon() && getMaster() == creature){
      if(canSeeNewPos){
        //Turn the summon on again
        isMasterInRange = true;
      }
    }

    updateIdleStatus();

    if(!followCreature && !isSummon()){
      //we have no target lets try pick this one
      if(isOpponent(creature)){
        selectTarget(const_cast<Creature*>(creature));
      }
    }
  }
}
コード例 #6
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
void Monster::onThinkTarget(uint32_t interval)
{
	if(isSummon() || mType->changeTargetSpeed <= 0)
		return;

	bool canChangeTarget = true;
	if(targetChangeCooldown > 0)
	{
		targetChangeCooldown -= interval;
		if(targetChangeCooldown <= 0)
		{
			targetChangeCooldown = 0;
			targetChangeTicks = (uint32_t)mType->changeTargetSpeed;
		}
		else
			canChangeTarget = false;
	}

	if(!canChangeTarget)
		return;

	targetChangeTicks += interval;
	if(targetChangeTicks < (uint32_t)mType->changeTargetSpeed)
		return;

	targetChangeTicks = 0;
	targetChangeCooldown = (uint32_t)mType->changeTargetSpeed;
	if(mType->changeTargetChance < random_range(1, 100))
		return;

	if(mType->targetDistance <= 1)
		searchTarget(TARGETSEARCH_RANDOM);
	else
		searchTarget(TARGETSEARCH_NEAREST);
}
コード例 #7
0
ファイル: monster.cpp プロジェクト: WibbenZ/forgottenserver
bool Monster::isFriend(const Creature* creature) const
{
	if (isSummon() && getMaster()->getPlayer()) {
		const Player* masterPlayer = getMaster()->getPlayer();
		const Player* tmpPlayer = nullptr;

		if (creature->getPlayer()) {
			tmpPlayer = creature->getPlayer();
		} else {
			const Creature* creatureMaster = creature->getMaster();

			if (creatureMaster && creatureMaster->getPlayer()) {
				tmpPlayer = creatureMaster->getPlayer();
			}
		}

		if (tmpPlayer && (tmpPlayer == getMaster() || masterPlayer->isPartner(tmpPlayer))) {
			return true;
		}
	} else if (creature->getMonster() && !creature->isSummon()) {
		return true;
	}

	return false;
}
コード例 #8
0
ファイル: actor.cpp プロジェクト: opentibia/server
void Actor::onThinkTarget(uint32_t interval)
{
  if(!isSummon()){
    if(cType.changeTargetSpeed() > 0){
      bool canChangeTarget = true;
      if(targetChangeCooldown > 0){
        targetChangeCooldown -= interval;
        if(targetChangeCooldown <= 0){
          targetChangeCooldown = 0;
          targetChangeTicks = (uint32_t)cType.changeTargetSpeed();
        }
        else{
          canChangeTarget = false;
        }
      }

      if(canChangeTarget){
        targetChangeTicks += interval;

        if(targetChangeTicks >= (uint32_t)cType.changeTargetSpeed()){
          targetChangeTicks = 0;
          targetChangeCooldown = (uint32_t)cType.changeTargetSpeed();

          if(cType.changeTargetChance() >= random_range(1, 100)){
            searchTarget(TARGETSEARCH_RANDOM);
          }
        }
      }
    }
  }
}
コード例 #9
0
void Monster::updateIdleStatus()
{
	//heightMinimum is declared static to avoid
	//several calls for getNumber (updateIdleStatus is called often)
	static int heightMinimum = 0;
	if (heightMinimum <= 0)
		heightMinimum = std::max(g_config.getNumber(ConfigManager::HEIGHT_MINIMUM_FOR_IDLE),(int64_t)1);

	bool idle = false;
	semiIdle = false;
	if(conditions.empty()){
		if(isSummon()){
			if(!isMasterInRange){
				idle = true;
			}
			else if(getMaster()->getMonster() && getMaster()->getMonster()->getIdleStatus()){
				idle = true;
			}
		}
		else{
			idle = targetList.empty();
			semiIdle = !idle;
			for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it){
				if (std::abs((*it)->getPosition().z - getPosition().z) < heightMinimum) {
					semiIdle = false;
					break;
				}
			}
		}
	}

	setIdle(idle);
}
コード例 #10
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
void Monster::getPathSearchParams(const Creature* creature, FindPathParams& fpp) const
{
	Creature::getPathSearchParams(creature, fpp);
	fpp.minTargetDist = 1;
	fpp.maxTargetDist = mType->targetDistance;
	if(isSummon())
	{
		if(master == creature)
		{
			fpp.maxTargetDist = 2;
			fpp.fullPathSearch = true;
		}
		else if(mType->targetDistance <= 1)
			fpp.fullPathSearch = true;
		else
			fpp.fullPathSearch = !canUseAttack(getPosition(), creature);
	}
	else if(isFleeing())
	{
		//Distance should be higher than the client view range (Map::maxClientViewportX/Map::maxClientViewportY)
		fpp.maxTargetDist = Map::maxViewportX;
		fpp.clearSight = fpp.fullPathSearch = false;
		fpp.keepDistance = true;
	}
	else if(mType->targetDistance <= 1)
		fpp.fullPathSearch = true;
	else
		fpp.fullPathSearch = !canUseAttack(getPosition(), creature);
}
コード例 #11
0
ファイル: actor.cpp プロジェクト: opentibia/server
void Actor::onThinkDefense(uint32_t interval)
{
  resetTicks = true;
  defenseTicks += interval;

  for(SpellList::const_iterator it = cType.spellDefenseList().begin(), spell_defense_list_end = cType.spellDefenseList().end(); it != spell_defense_list_end; ++it){
    if(it->speed > defenseTicks){
      resetTicks = false;
      continue;
    }

    if(defenseTicks % it->speed >= interval){
      //already used this spell for this round
      continue;
    }

    if((it->chance >= (uint32_t)random_range(1, 100))){
      g_game.onActorCastSpell(this, NULL, (*it).name);
    }
  }

  if(!isSummon() && (int32_t)summons.size() < cType.maxSummons()){
    for(SummonList::const_iterator it = cType.summonList().begin(), summon_list_end = cType.summonList().end(); it != summon_list_end; ++it){
      if(it->speed > defenseTicks){
        resetTicks = false;
        continue;
      }

      if((int32_t)summons.size() >= cType.maxSummons()){
        continue;
      }

      if(defenseTicks % it->speed >= interval){
        //already used this spell for this round
        continue;
      }

      if((it->chance >= (uint32_t)random_range(1, 100))){
        Actor* summon = Actor::create(it->name);
        if(summon){
          const Position& summonPos = getPosition();

          addSummon(summon);
          if(g_game.placeCreature(summon, summonPos)){
            g_game.addMagicEffect(summon->getPosition(), MAGIC_EFFECT_BLUE_BUBBLE);
            g_game.addMagicEffect(getPosition(), MAGIC_EFFECT_BLUE_BUBBLE);
          }
          else{
            removeSummon(summon);
          }
        }
      }
    }
  }

  if(resetTicks){
    defenseTicks = 0;
  }
}
コード例 #12
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature || (isSummon() && attackedCreature == this))
		return;

	bool updateLook = true, outOfRange = true;
	resetTicks = interval;
	attackTicks += interval;

	const Position& myPos = getPosition();
	const Position& targetPos = attackedCreature->getPosition();
	for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it)
	{
		if(it->isMelee && isFleeing())
			continue;

		bool inRange = false;
		if(canUseSpell(myPos, targetPos, *it, interval, inRange))
		{
			if(it->chance >= (uint32_t)random_range(1, 100))
			{
				if(updateLook)
				{
					updateLookDirection();
					updateLook = false;
				}

				double multiplier;
				if(maxCombatValue > 0) //defense
					multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_DEFENSE);
				else //attack
					multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_ATTACK);

				minCombatValue = (int32_t)(it->minCombatValue * multiplier);
				maxCombatValue = (int32_t)(it->maxCombatValue * multiplier);

				it->spell->castSpell(this, attackedCreature);
				if(it->isMelee)
					extraMeleeAttack = false;
#ifdef __DEBUG__
				static uint64_t prevTicks = OTSYS_TIME();
				std::clog << "doAttacking ticks: " << OTSYS_TIME() - prevTicks << std::endl;
				prevTicks = OTSYS_TIME();
#endif
			}
		}

		if(inRange)
			outOfRange = false;
		else if(it->isMelee) //melee swing out of reach
			extraMeleeAttack = true;
	}

	if(updateLook)
		updateLookDirection();

	if(resetTicks)
		attackTicks = 0;
}
コード例 #13
0
ファイル: actor.cpp プロジェクト: opentibia/server
void Actor::onAttackedCreature(Creature* target)
{
  Creature::onAttackedCreature(target);

  if(isSummon()){
    getMaster()->onSummonAttackedCreature(this, target);
  }
}
コード例 #14
0
ファイル: actor.cpp プロジェクト: opentibia/server
void Actor::onAttackedCreatureDrainMana(Creature* target, int32_t points)
{
  Creature::onAttackedCreatureDrainMana(target, points);

  if(isSummon()){
    getMaster()->onSummonAttackedCreatureDrainMana(this, target, points);
  }
}
コード例 #15
0
ファイル: monster.cpp プロジェクト: WibbenZ/forgottenserver
bool Monster::getNextStep(Direction& direction, uint32_t& flags)
{
	if (isIdle || getHealth() <= 0) {
		//we dont have anyone watching might aswell stop walking
		eventWalk = 0;
		return false;
	}

	bool result = false;
	if ((!followCreature || !hasFollowPath) && (!isSummon() || !isMasterInRange)) {
		if (followCreature || getTimeSinceLastMove() > 1000) {
			//choose a random direction
			result = getRandomStep(getPosition(), direction);
		}
	} else if ((isSummon() && isMasterInRange) || followCreature) {
		result = Creature::getNextStep(direction, flags);
		if (result) {
			flags |= FLAG_PATHFINDING;
		} else {
			//target dancing
			if (attackedCreature && attackedCreature == followCreature) {
				if (isFleeing()) {
					result = getDanceStep(getPosition(), direction, false, false);
				} else if (mType->info.staticAttackChance < static_cast<uint32_t>(uniform_random(1, 100))) {
					result = getDanceStep(getPosition(), direction);
				}
			}
		}
	}

	if (result && (canPushItems() || canPushCreatures())) {
		const Position& pos = Spells::getCasterPosition(this, direction);
		Tile* tile = g_game.map.getTile(pos);
		if (tile) {
			if (canPushItems()) {
				Monster::pushItems(tile);
			}

			if (canPushCreatures()) {
				Monster::pushCreatures(tile);
			}
		}
	}

	return result;
}
コード例 #16
0
void Monster::onAttackedCreatureDrainHealth(Creature* target, int32_t points)
{
	Creature::onAttackedCreatureDrainHealth(target, points);

	if(isSummon()){
		getMaster()->onSummonAttackedCreatureDrainHealth(this, target, points);
	}
}
コード例 #17
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
bool Monster::challengeCreature(Creature* creature)
{
	if(isSummon() || !selectTarget(creature))
		return false;

	targetChangeCooldown = 8000;
	targetChangeTicks = 0;
	return true;
}
コード例 #18
0
ファイル: monster.cpp プロジェクト: armadaazteca/tfs0.2.15
void Monster::onThink(uint32_t interval)
{
	Creature::onThink(interval);

	if(despawn())
	{
		g_game.internalTeleport(this, masterPos);
		setIdle(true);
	}
	else
	{
		updateIdleStatus();
		if(!isIdle)
		{
			addEventWalk();

			if(isSummon())
			{
				if(!attackedCreature)
				{
					if(getMaster() && getMaster()->getAttackedCreature())
					{
						///This happens if the monster is summoned during combat
						selectTarget(getMaster()->getAttackedCreature());
					}
					else if(getMaster() != followCreature)
					{
						//Our master has not ordered us to attack anything, lets follow him around instead.
						setFollowCreature(getMaster());
					}
				}
				else if(attackedCreature == this)
					setFollowCreature(NULL);
				else if(followCreature != attackedCreature)
				{
					//This happens just after a master orders an attack, so lets follow it aswell.
					setFollowCreature(attackedCreature);
				}
			}
			else if(!targetList.empty())
			{
				if(!followCreature || !hasFollowPath)
					searchTarget();
				else if(isFleeing())
				{
					if(attackedCreature && !canUseAttack(getPosition(), attackedCreature))
						searchTarget(TARGETSEARCH_ATTACKRANGE);
				}
			}

			onThinkTarget(interval);
			onThinkYell(interval);
			onThinkDefense(interval);
		}
	}
}
コード例 #19
0
ファイル: monster.cpp プロジェクト: CaosJunior/DxP
void Monster::onThink(uint32_t interval)

{
	Creature::onThink(interval);
	if(despawn())
	{
		g_game.removeCreature(this, true);
		setIdle(true);
		return;
	}

	updateIdleStatus();
	if(isIdle)
		return;

	if(teleportToMaster && doTeleportToMaster())
		teleportToMaster = false;

	addEventWalk();
	
	if(getMaster()){
    	if(getPosition().z != getMaster()->getPosition().z){
			g_game.internalTeleport(this, getMaster()->getPosition(), false);
			//g_game.addMagicEffect(getPosition(), MAGIC_EFFECT_SOUND_YELLOW);
		}
      } 
	
	if(isSummon())
	{
		if(!attackedCreature)
		{
            std::string strValue;
			if(getMaster() && getMaster()->getAttackedCreature()) //This happens if the monster is summoned during combat
				selectTarget(getMaster()->getAttackedCreature());
            else{
                setFollowCreature((getMaster()->getStorage(500, strValue) && strValue != "-1") ? NULL : getMaster());
            }

        }
		else if(attackedCreature == this)
			setFollowCreature(NULL);
		else if(followCreature != attackedCreature) //This happens just after a master orders an attack, so lets follow it aswell.
			setFollowCreature(attackedCreature);
	}
	else if(!targetList.empty())
	{
		if(!followCreature || !hasFollowPath)
			searchTarget();
		else if(isFleeing() && attackedCreature && !canUseAttack(getPosition(), attackedCreature))
			searchTarget(TARGETSEARCH_ATTACKRANGE);
	}

	onThinkTarget(interval);
	onThinkYell(interval);
	onThinkDefense(interval);
}
コード例 #20
0
ファイル: monster.cpp プロジェクト: WibbenZ/forgottenserver
bool Monster::selectTarget(Creature* creature)
{
	if (!isTarget(creature)) {
		return false;
	}

	auto it = std::find(targetList.begin(), targetList.end(), creature);
	if (it == targetList.end()) {
		//Target not found in our target list.
		return false;
	}

	if (isHostile() || isSummon()) {
		if (setAttackedCreature(creature) && !isSummon()) {
			g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
		}
	}
	return setFollowCreature(creature);
}
コード例 #21
0
ファイル: actor.cpp プロジェクト: opentibia/server
void Actor::doAttacking(uint32_t interval)
{
  if(!attackedCreature || (isSummon() && attackedCreature == this)){
    return;
  }

  // TODO: seems "outOfRange" is being unused. Why?
  //bool outOfRange = true;
  bool updateLook = true;

  resetTicks = interval != 0;
  attackTicks += interval;

  const Position& myPos = getPosition();
  const Position& targetPos = attackedCreature->getPosition();

  for(SpellList::const_iterator it = cType.spellAttackList().begin(), spell_list_end = cType.spellAttackList().end(); it != spell_list_end; ++it){
    bool inRange = false;
    if(canUseSpell(myPos, targetPos, *it, interval, inRange)){
      if(it->chance >= (uint32_t)random_range(1, 100)){
        if(updateLook){
          updateLookDirection();
          updateLook = false;
        }

        g_game.onActorCastSpell(this, attackedCreature, (*it).name);
        /*
        if(it->isMelee){
          extraMeleeAttack = false;
        }
        */
      }
    }
    /*
    if(inRange){
      outOfRange = false;
    }
    */
    /*
    else if(it->isMelee){
      //melee swing out of reach
      extraMeleeAttack = true;
    }
    */
  }

  if(updateLook){
    updateLookDirection();
  }

  if(resetTicks){
    attackTicks = 0;
  }
}
コード例 #22
0
ファイル: monster.cpp プロジェクト: armadaazteca/tfs0.2.15
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature || (isSummon() && attackedCreature == this))
		return;

	bool updateLook = true;

	resetTicks = interval != 0;
	attackTicks += interval;

	const Position& myPos = getPosition();
	const Position& targetPos = attackedCreature->getPosition();

	for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it)
	{
		bool inRange = false;
		if(canUseSpell(myPos, targetPos, *it, interval, inRange))
		{
			if(it->chance >= (uint32_t)random_range(1, 100))
			{
				if(updateLook)
				{
					updateLookDirection();
					updateLook = false;
				}

				minCombatValue = it->minCombatValue;
				maxCombatValue = it->maxCombatValue;
				it->spell->castSpell(this, attackedCreature);
				if(it->isMelee)
					extraMeleeAttack = false;

#ifdef __DEBUG__
				static uint64_t prevTicks = OTSYS_TIME();
				std::cout << "doAttacking ticks: " << OTSYS_TIME() - prevTicks << std::endl;
				prevTicks = OTSYS_TIME();
#endif
			}
		}

		if(!inRange && it->isMelee)
		{
			//melee swing out of reach
			extraMeleeAttack = true;
		}
	}

	if(updateLook)
		updateLookDirection();

	if(resetTicks)
		attackTicks = 0;
}
コード例 #23
0
ファイル: monster.cpp プロジェクト: WibbenZ/forgottenserver
void Monster::updateIdleStatus()
{
	bool idle = false;

	if (conditions.empty()) {
		if (!isSummon() && targetList.empty()) {
			idle = true;
		}
	}

	setIdle(idle);
}
コード例 #24
0
ファイル: monster.cpp プロジェクト: WibbenZ/forgottenserver
bool Monster::challengeCreature(Creature* creature)
{
	if (isSummon()) {
		return false;
	}

	bool result = selectTarget(creature);
	if (result) {
		targetChangeCooldown = 8000;
		targetChangeTicks = 0;
	}
	return result;
}
コード例 #25
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
bool Monster::convinceCreature(Creature* creature)
{
	Player* player = creature->getPlayer();
	if(player && !player->hasFlag(PlayerFlag_CanConvinceAll) && !mType->isConvinceable)
		return false;

	Creature* oldMaster = NULL;
	if(isSummon())
		oldMaster = master;

	if(oldMaster)
	{
		if(oldMaster->getPlayer() || oldMaster == creature)
			return false;

		oldMaster->removeSummon(this);
	}

	setFollowCreature(NULL);
	setAttackedCreature(NULL);
	destroySummons();

	creature->addSummon(this);
	updateTargetList();
	updateIdleStatus();

	//Notify surrounding about the change
	SpectatorVec list;
	g_game.getSpectators(list, getPosition(), false, true);
	g_game.getSpectators(list, creature->getPosition(), true, true);

	isMasterInRange = true;
	for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it)
		(*it)->onCreatureConvinced(creature, this);

	if(spawn)
	{
		spawn->removeMonster(this);
		spawn = NULL;
		masterRadius = -1;
	}

	if(raid)
	{
		raid->unRef();
		raid = NULL;
	}

	return true;
}
コード例 #26
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
bool Monster::isFriend(const Creature* creature)
{
	if(!isSummon() || !master->getPlayer())
		return creature->getMonster() && !creature->isSummon();

	const Player* tmpPlayer = NULL;
	if(creature->getPlayer())
		tmpPlayer = creature->getPlayer();
	else if(creature->getPlayerMaster())
		tmpPlayer = creature->getPlayerMaster();

	const Player* masterPlayer = master->getPlayer();
	return tmpPlayer && (tmpPlayer == masterPlayer || masterPlayer->isPartner(tmpPlayer));
}
コード例 #27
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
void Monster::onCreatureLeave(Creature* creature)
{
#ifdef __DEBUG__
	std::clog << "onCreatureLeave - " << creature->getName() << std::endl;
#endif
	if(isSummon() && master == creature)
	{
		if(!g_config.getBool(ConfigManager::TELEPORT_SUMMONS) && (!master->getPlayer()
			|| !g_config.getBool(ConfigManager::TELEPORT_PLAYER_SUMMONS)))
		{
			//Turn the monster off until its master comes back
			isMasterInRange = false;
			updateIdleStatus();
		}
		else if(!doTeleportToMaster())
			teleportToMaster = true;
	}

	//update friendList
	if(isFriend(creature))
	{
		CreatureList::iterator it = std::find(friendList.begin(), friendList.end(), creature);
		if(it != friendList.end())
		{
			(*it)->unRef();
			friendList.erase(it);
		}
#ifdef __DEBUG__
		else
			std::clog << "Monster: " << creature->getName() << " not found in the friendList." << std::endl;
#endif
	}

	//update targetList
	if(isOpponent(creature))
	{
		CreatureList::iterator it = std::find(targetList.begin(), targetList.end(), creature);
		if(it != targetList.end())
		{
			(*it)->unRef();
			targetList.erase(it);
			if(targetList.empty())
				updateIdleStatus();
		}
#ifdef __DEBUG__
		else
			std::clog << "Player: " << creature->getName() << " not found in the targetList." << std::endl;
#endif
	}
}
コード例 #28
0
ファイル: monster.cpp プロジェクト: alexisjojo/darkkonia
void Monster::onCreatureAppear(const Creature* creature)
{
	Creature::onCreatureAppear(creature);
	if(creature == this)
	{
		//We just spawned lets look around to see who is there.
		if(isSummon())
			isMasterInRange = canSee(master->getPosition());

		updateTargetList();
		updateIdleStatus();
	}
	else
		onCreatureEnter(const_cast<Creature*>(creature));
}
コード例 #29
0
ファイル: monster.cpp プロジェクト: armadaazteca/tfs0.2.15
void Monster::updateIdleStatus()
{
	bool idle = false;
	if(conditions.empty())
	{
		if(isSummon())
		{
			if(!isMasterInRange || (getMaster()->getMonster() && getMaster()->getMonster()->getIdleStatus()))
				idle = true;
		}
		else if(targetList.empty())
			idle = true;
	}
	setIdle(idle);
}
コード例 #30
0
ファイル: monster.cpp プロジェクト: CaosJunior/DxP
bool Monster::selectTarget(Creature* creature)
{
#ifdef __DEBUG__
	std::cout << "Selecting target... " << std::endl;
#endif
	if(!isTarget(creature))
		return false;
		
	if(!isHostile())
        return false;
        
     std::string value;
     if(getStorage(505, value) && value != "-1") {
       if(creature->isSummon()){
          if(value != creature->getMaster()->getName())
              return false;                     
       }else if(value != creature->getName()) //&& value != "0"){ -- se bugar  
           return false;    
     }   

	CreatureList::iterator it = std::find(targetList.begin(), targetList.end(), creature);
	if(it == targetList.end())
	{
		//Target not found in our target list.
#ifdef __DEBUG__
		std::cout << "Target not found in targetList." << std::endl;
#endif
		return false;
	}

	if((isHostile() || isSummon()) && setAttackedCreature(creature) && !isSummon())
		Dispatcher::getInstance().addTask(createTask(
			boost::bind(&Game::checkCreatureAttack, &g_game, getID())));

	return setFollowCreature(creature, true);
}