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; }
void Player::moveTo(const CCPoint& pos, const std::vector<CCPoint>& path) { if(!path.empty()) { std::vector<MoveInfo> moveInfos; for(auto& p : path) { moveInfos.push_back(MoveInfo(p)); } auto action = createAnimation(m_animTextureName, moveInfos, CCSize(48, 48), 4, 0.1f, 1); //CCHide * hide= CCHide::create(); m_sprite->runAction(action); action = createMoveAction( moveInfos, CCSize(48 * m_scale, 48 * m_scale), 0.4f); CCCallFunc* fun = CCCallFunc::create(getScene(), callfunc_selector(HelloWorld::inChooseActionState)); runAction(CCSequence::create(action, fun, 0)); } }
MoveObjectsToolController::MoveInfo MoveObjectsToolController::doStartMove(const InputState& inputState) { if (!inputState.modifierKeysPressed(ModifierKeys::MKNone) && !inputState.modifierKeysPressed(ModifierKeys::MKAlt) && !inputState.modifierKeysPressed(ModifierKeys::MKCtrlCmd) && !inputState.modifierKeysPressed(ModifierKeys::MKCtrlCmd | ModifierKeys::MKAlt)) return MoveInfo(); const Model::PickResult& pickResult = inputState.pickResult(); const Model::Hit& hit = pickResult.query().pickable().type(Model::Group::GroupHit | Model::Entity::EntityHit | Model::Brush::BrushHit).selected().first(); if (!hit.isMatch()) return MoveInfo(); if (!m_tool->startMove(inputState)) return MoveInfo(); return MoveInfo(hit.hitPoint()); }
MoveInfo Behaviour::tryEffect(EffectType type, double maxTurns) { for (Spell* spell : creature->getAttributes().getSpellMap().getAll()) { if (spell->hasEffect(type)) if (auto action = creature->castSpell(spell)) return { 1, action }; } auto items = creature->getEquipment().getItems(Item::effectPredicate(type)); for (Item* item : items) if (item->getApplyTime() <= maxTurns) if (auto action = creature->applyItem(item)) return MoveInfo(1, action); return NoMove; }
smart::vector<MoveInfo> doRegMoves(PhysReg::Map<PhysReg>& moves, PhysReg rTmp) { auto constexpr N = X64::kNumRegs > ARM::kNumRegs ? X64::kNumRegs : ARM::kNumRegs; smart::vector<MoveInfo> howTo; CycleInfo cycle_mem[N]; List<CycleInfo> cycles(cycle_mem, 0, N); PhysReg::Map<int> outDegree; PhysReg::Map<int> index; assert(moves[rTmp] == InvalidReg); for (auto reg : moves) { // Ignore moves from a register to itself if (reg == moves[reg]) moves[reg] = InvalidReg; index[reg] = -1; } // Iterate over the nodes filling in outDegree[] and cycles[] as we go int nextIndex = 0; for (auto reg : moves) { // skip registers we've visited already. if (index[reg] >= 0) continue; // Begin walking a path from reg. for (auto node = reg;;) { assert(nextIndex < N); index[node] = nextIndex++; auto next = moves[node]; if (next != InvalidReg) { ++outDegree[next]; if (index[next] < 0) { // There is an edge from node to next, and next has not been // visited. Extend current path to include next, then loop. node = next; continue; } // next already visited; check if next is on current path. if (index[next] >= index[reg]) { // found a cycle. cycles.push_back({ next, nextIndex - index[next] }); } } break; } } // Handle all moves that aren't part of a cycle. Only nodes with outdegree // zero are put into the queue, which is how nodes in a cycle get excluded. { PhysReg q[N]; int qBack = 0; auto enque = [&](PhysReg r) { assert(qBack < N); q[qBack++] = r; }; for (auto node : outDegree) { if (outDegree[node] == 0) enque(node); } for (int i = 0; i < qBack; ++i) { auto node = q[i]; if (moves[node] == InvalidReg) continue; auto nextNode = moves[node]; howTo.emplace_back(MoveInfo::Kind::Move, nextNode, node); --outDegree[nextNode]; if (outDegree[nextNode] == 0) enque(nextNode); } } // Deal with any cycles we encountered for (auto const& cycle : cycles) { // can't use xchg if one of the registers is SIMD bool hasSIMDReg = cycleHasSIMDReg(cycle, moves); if (cycle.length == 2 && !hasSIMDReg) { auto v = cycle.node; auto w = moves[v]; howTo.push_back(MoveInfo(MoveInfo::Kind::Xchg, w, v)); } else if (cycle.length == 3 && !hasSIMDReg) { auto v = cycle.node; auto w = moves[v]; howTo.push_back(MoveInfo(MoveInfo::Kind::Xchg, w, v)); auto x = moves[w]; howTo.push_back(MoveInfo(MoveInfo::Kind::Xchg, x, w)); } else { auto v = cycle.node; howTo.push_back(MoveInfo(MoveInfo::Kind::Move, v, rTmp)); auto w = v; auto x = moves[w]; while (x != v) { howTo.push_back(MoveInfo(MoveInfo::Kind::Move, x, w)); w = x; x = moves[w]; } howTo.push_back(MoveInfo(MoveInfo::Kind::Move, rTmp, w)); } } return howTo; }
MoveInfo MoveInfo::orWait() const { if (!move) return MoveInfo(value, Creature::wait()); else return *this; }