bool Heroes::ActionSpellCast(const Spell & spell) { std::string error; if(! CanMove()) { Dialog::Message("", _("Your hero is too tired to cast this spell today. Try again tomorrow."), Font::BIG, Dialog::OK); return false; } else if(spell == Spell::NONE || spell.isCombat() || ! CanCastSpell(spell, &error)) { if(error.size()) Dialog::Message("Error", error, Font::BIG, Dialog::OK); return false; } bool apply = false; switch(spell()) { case Spell::VIEWMINES: apply = ActionSpellViewMines(*this); break; case Spell::VIEWRESOURCES: apply = ActionSpellViewResources(*this); break; case Spell::VIEWARTIFACTS: apply = ActionSpellViewArtifacts(*this); break; case Spell::VIEWTOWNS: apply = ActionSpellViewTowns(*this); break; case Spell::VIEWHEROES: apply = ActionSpellViewHeroes(*this); break; case Spell::VIEWALL: apply = ActionSpellViewAll(*this); break; case Spell::IDENTIFYHERO: apply = ActionSpellIdentifyHero(*this); break; case Spell::SUMMONBOAT: apply = ActionSpellSummonBoat(*this); break; case Spell::DIMENSIONDOOR: apply = ActionSpellDimensionDoor(*this); break; case Spell::TOWNGATE: apply = isShipMaster() ? false : ActionSpellTownGate(*this); break; case Spell::TOWNPORTAL: apply = isShipMaster() ? false : ActionSpellTownPortal(*this); break; case Spell::VISIONS: apply = ActionSpellVisions(*this); break; case Spell::HAUNT: apply = ActionSpellSetGuardian(*this, spell, Monster::GHOST); break; case Spell::SETEGUARDIAN: apply = ActionSpellSetGuardian(*this, spell, Monster::EARTH_ELEMENT); break; case Spell::SETAGUARDIAN: apply = ActionSpellSetGuardian(*this, spell, Monster::AIR_ELEMENT); break; case Spell::SETFGUARDIAN: apply = ActionSpellSetGuardian(*this, spell, Monster::FIRE_ELEMENT); break; case Spell::SETWGUARDIAN: apply = ActionSpellSetGuardian(*this, spell, Monster::WATER_ELEMENT); break; default: break; } if(apply) { DEBUG(DBG_GAME, DBG_INFO, GetName() << " cast spell: " << spell.GetName()); SpellCasted(spell); return true; } return false; }
void Heroes::Redraw(Surface & dst, s32 dx, s32 dy, bool with_shadow) const { const Point & mp = GetCenter(); const Interface::GameArea & gamearea = Interface::Basic::Get().GetGameArea(); if(!(gamearea.GetRectMaps() & mp)) return; bool reflect = ReflectSprite(direction); const Sprite & sprite1 = SpriteHero(*this, sprite_index, reflect, false); const Sprite & sprite2 = SpriteFlag(*this, sprite_index, reflect, false); const Sprite & sprite3 = SpriteShad(*this, sprite_index); const Sprite & sprite4 = SpriteFroth(*this, sprite_index, reflect); Point dst_pt1(dx + (reflect ? TILEWIDTH - sprite1.x() - sprite1.w() : sprite1.x()), dy + sprite1.y() + TILEWIDTH); Point dst_pt2(dx + (reflect ? TILEWIDTH - sprite2.x() - sprite2.w() : sprite2.x()), dy + sprite2.y() + TILEWIDTH); Point dst_pt3(dx + sprite3.x(), dy + sprite3.y() + TILEWIDTH); Point dst_pt4(dx + (reflect ? TILEWIDTH - sprite4.x() - sprite4.w() : sprite4.x()), dy + sprite4.y() + TILEWIDTH); // apply offset if(sprite_index < 45) { s32 ox = 0; s32 oy = 0; int frame = (sprite_index % 9); switch(direction) { case Direction::TOP: oy = -4 * frame; break; case Direction::TOP_RIGHT: ox = 4 * frame; oy = -4 * frame; break; case Direction::TOP_LEFT: ox = -4 * frame; oy = -4 * frame; break; case Direction::BOTTOM_RIGHT: ox = 4 * frame; oy = 4 * frame; break; case Direction::BOTTOM: oy = 4 * frame; break; case Direction::BOTTOM_LEFT: ox = -4 * frame; oy = 4 * frame; break; case Direction::RIGHT: ox = 4 * frame; break; case Direction::LEFT: ox = -4 * frame; break; default: break; } dst_pt1.x += ox; dst_pt1.y += oy; dst_pt2.x += ox; dst_pt2.y += oy; dst_pt3.x += ox; dst_pt3.y += oy; dst_pt4.x += ox; dst_pt4.y += oy; } if(isShipMaster()) { dst_pt1.y -= 15; dst_pt2.y -= 15; dst_pt3.y -= 15; dst_pt4.y -= 15; sprite4.Blit(gamearea.RectFixed(dst_pt4, sprite4.w(), sprite4.h()), dst_pt4, dst); } // redraw sprites for shadow if(with_shadow) sprite3.Blit(gamearea.RectFixed(dst_pt3, sprite3.w(), sprite3.h()), dst_pt3, dst); // redraw sprites hero and flag sprite1.Blit(gamearea.RectFixed(dst_pt1, sprite1.w(), sprite1.h()), dst_pt1, dst); sprite2.Blit(gamearea.RectFixed(dst_pt2, sprite2.w(), sprite2.h()), dst_pt2, dst); // redraw dependences tiles Maps::Tiles & tile = world.GetTiles(center.x, center.y); const s32 centerIndex = GetIndex(); bool skip_ground = MP2::isActionObject(tile.GetObject(false), isShipMaster()); tile.RedrawTop(dst); if(Maps::isValidDirection(centerIndex, Direction::TOP)) world.GetTiles(Maps::GetDirectionIndex(centerIndex, Direction::TOP)).RedrawTop4Hero(dst, skip_ground); if(Maps::isValidDirection(centerIndex, Direction::BOTTOM)) { Maps::Tiles & tile_bottom = world.GetTiles(Maps::GetDirectionIndex(centerIndex, Direction::BOTTOM)); tile_bottom.RedrawBottom4Hero(dst); tile_bottom.RedrawTop(dst); } if(45 > GetSpriteIndex()) { if(Direction::BOTTOM != direction && Direction::TOP != direction && Maps::isValidDirection(centerIndex, direction)) { if(Maps::isValidDirection(Maps::GetDirectionIndex(centerIndex, direction), Direction::BOTTOM)) { Maps::Tiles & tile_dir_bottom = world.GetTiles(Maps::GetDirectionIndex(Maps::GetDirectionIndex(centerIndex, direction), Direction::BOTTOM)); tile_dir_bottom.RedrawBottom4Hero(dst); tile_dir_bottom.RedrawTop(dst); } if(Maps::isValidDirection(Maps::GetDirectionIndex(centerIndex, direction), Direction::TOP)) { Maps::Tiles & tile_dir_top = world.GetTiles(Maps::GetDirectionIndex(Maps::GetDirectionIndex(centerIndex, direction), Direction::TOP)); tile_dir_top.RedrawTop4Hero(dst, skip_ground); } } if(Maps::isValidDirection(centerIndex, Direction::BOTTOM)) { Maps::Tiles & tile_bottom = world.GetTiles(Maps::GetDirectionIndex(centerIndex, Direction::BOTTOM)); if(tile_bottom.GetObject() == MP2::OBJ_BOAT) tile_bottom.RedrawObjects(dst); } } if(Maps::isValidDirection(centerIndex, direction)) { if(Direction::TOP == direction) world.GetTiles(Maps::GetDirectionIndex(centerIndex, direction)).RedrawTop4Hero(dst, skip_ground); else world.GetTiles(Maps::GetDirectionIndex(centerIndex, direction)).RedrawTop(dst); } }