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); }
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); } } }
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); }
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); } } } } } }
void FadeManager::deleteTarget(QWidget *targetToDelete, FadeManager::AnimationSequenceType fromWhichGroup) { if(fromWhichGroup == Parallel) { auto animToRemove = searchTarget(targetToDelete, Parallel); if(animToRemove == nullptr) return; a_parallelAnimations.removeAnimation(animToRemove); } else { auto animToRemove = searchTarget(targetToDelete, Sequential); if(animToRemove == nullptr) return; a_sequentialAnimations.removeAnimation(animToRemove); } }
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; std::string strValue; int32_t value; if(getStorage(502, strValue)) { value = atoi(strValue.c_str()); } if(mType->targetDistance <= 1 && value == -1) searchTarget(TARGETSEARCH_RANDOM); else searchTarget(TARGETSEARCH_NEAREST); }
void FadeManager::editTarget(QWidget *targetToModify, int msecs, FadeManager::AnimationSequenceType fromWhichGroup) { if(fromWhichGroup == Parallel) { auto animToModify = searchTarget(targetToModify, Parallel); if(animToModify == nullptr) return; auto *anim = (QPropertyAnimation*) animToModify; anim->setDuration(msecs); } else { auto animToModify = searchTarget(targetToModify, Sequential); if(animToModify == nullptr) return; auto *anim = (QPropertyAnimation*) animToModify; anim->setDuration(msecs); } }
void FadeManager::editTarget(QWidget *targetToModify, FadeManager::FadeMode mode, FadeManager::AnimationSequenceType fromWhichGroup) { if(fromWhichGroup == Parallel) { auto animToModify = searchTarget(targetToModify, Parallel); if(animToModify == nullptr) return; auto *anim = (QPropertyAnimation*) animToModify; auto *container = (QGraphicsOpacityEffect*) anim->targetObject(); setMode(anim, mode, container); } else { auto animToModify = searchTarget(targetToModify, Sequential); if(animToModify == nullptr) return; auto *anim = (QPropertyAnimation*) animToModify; auto *container = (QGraphicsOpacityEffect*) anim->targetObject(); setMode(anim, mode, container); } }
void FadeManager::changeTargetGroup(QWidget *targetToModify, FadeManager::AnimationSequenceType fromWhichGroup) { if(fromWhichGroup == Parallel) { auto animToModify = searchTarget(targetToModify, Parallel); if(animToModify == nullptr) return; auto *anim = (QPropertyAnimation*) animToModify; a_parallelAnimations.removeAnimation(anim); a_sequentialAnimations.addAnimation(anim); } else { auto animToModify = searchTarget(targetToModify, Sequential); if(animToModify == nullptr) return; auto *anim = (QPropertyAnimation*) animToModify; a_sequentialAnimations.removeAnimation(anim); a_parallelAnimations.addAnimation(anim); } }
void Monster::onThinkTarget(uint32_t interval) { if (!isSummon()) { if (mType->info.changeTargetSpeed != 0) { bool canChangeTarget = true; if (targetChangeCooldown > 0) { targetChangeCooldown -= interval; if (targetChangeCooldown <= 0) { targetChangeCooldown = 0; targetChangeTicks = mType->info.changeTargetSpeed; } else { canChangeTarget = false; } } if (canChangeTarget) { targetChangeTicks += interval; if (targetChangeTicks >= mType->info.changeTargetSpeed) { targetChangeTicks = 0; targetChangeCooldown = mType->info.changeTargetSpeed; if (mType->info.changeTargetChance >= uniform_random(1, 100)) { if (mType->info.targetDistance <= 1) { searchTarget(TARGETSEARCH_RANDOM); } else { searchTarget(TARGETSEARCH_NEAREST); } } } } } } }
///////////////////////////////////// //行動(移動、攻撃 ///////////////////////////////////// void Enemy::action() { //攻撃目標が制圧できた場合次の攻撃目標を探す if (pole[targetID]->type == TYPE::ENEMY) { targetPos = searchTarget(); } //敵とターゲットの距離 const float enemyToTarget = (pos.x - targetPos.x) * (pos.x - targetPos.x) + (pos.z - targetPos.z) * (pos.z - targetPos.z); const unsigned int onAttack = 50; //攻撃可能距離 yaw = atan2(targetPos.x - pos.x, targetPos.z - pos.z) * 180 / M_PI; move(enemyToTarget, onAttack); attack(enemyToTarget, onAttack); }
////////////////////////// //更新 /////////////////////////// void NPC::update(std::list< NPC* >_NPC) { //攻撃目標が制圧できた場合次の攻撃目標を探す if (pole[targetID]->type == type) { targetPos = searchTarget(); } targetPos = enemyTarget(_NPC); //敵とターゲットの距離 const auto toTarget = (pos.x - targetPos.x) * (pos.x - targetPos.x) + (pos.z - targetPos.z) * (pos.z - targetPos.z); //攻撃可能距離 const auto onAttack = 30; //ターゲットの方向に向く yaw = atan2(targetPos.x - pos.x, targetPos.z - pos.z) * 180 / M_PI; attackCount--; stepCount--; if (isDead() == false) {//死んでいなければ行動する move(toTarget, onAttack); attack(toTarget, onAttack); } else {//死んでいたらカウントが増える if (HP < 0) HP = 0; isDeadTimer++; } }
void Monster::onThink(uint32_t interval) { Creature::onThink(interval); if (mType->info.thinkEvent != -1) { // onThink(self, interval) LuaScriptInterface* scriptInterface = mType->info.scriptInterface; if (!scriptInterface->reserveScriptEnv()) { std::cout << "[Error - Monster::onThink] Call stack overflow" << std::endl; return; } ScriptEnvironment* env = scriptInterface->getScriptEnv(); env->setScriptId(mType->info.thinkEvent, scriptInterface); lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.thinkEvent); LuaScriptInterface::pushUserdata<Monster>(L, this); LuaScriptInterface::setMetatable(L, -1, "Monster"); lua_pushnumber(L, interval); if (scriptInterface->callFunction(2)) { return; } } if (!isInSpawnRange(position)) { 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(nullptr); } 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); } } }