/
Mr.Stalin
/
FOnline-Engine
Обзор
Документация
Войти
/
Mr.Stalin
/
FOnline-Engine
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Source/Client/ItemHexView.cpp
312 строк
8 KB
cvet
Non const locals (#190)
24 июл 2026, 10:46
Не верифицирован
24 июл 2026, 10:46
4883d25
Код
Авторство
О чём код?
// __________ ___ ______ _ // / ____/ __ \____ / (_)___ ___ / ____/___ ____ _(_)___ ___ // / /_ / / / / __ \/ / / __ \/ _ \ / __/ / __ \/ __ `/ / __ \/ _ ` // / __/ / /_/ / / / / / / / / / __/ / /___/ / / / /_/ / / / / / __/ // /_/ \____/_/ /_/_/_/_/ /_/\___/ /_____/_/ /_/\__, /_/_/ /_/\___/ // /____/ // FOnline Engine // https://fonline.ru // https://github.com/cvet/fonline // // MIT License // // Copyright (c) 2006 - 2026, Anton Tsvetinskiy aka cvet <cvet@tut.by> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // #include "ItemHexView.h" #include "Client.h" #include "EffectManager.h" #include "MapSprite.h" #include "MapView.h" FO_BEGIN_NAMESPACE ItemHexView::ItemHexView(ptr<MapView> map, ident_t id, ptr<const ProtoItem> proto, nptr<const Properties> props) : ItemView(map->GetEngine(), id, proto, props), HexView(map) { FO_STACK_TRACE_ENTRY(); } void ItemHexView::Init() { FO_STACK_TRACE_ENTRY(); if (GetIsTile()) { SetDrawEffect(GetIsRoofTile() ? _engine->EffectMngr.Effects.Roof : _engine->EffectMngr.Effects.Tile); } else if (GetDrawFlatten()) { SetDrawEffect(_engine->EffectMngr.Effects.Flat.get()); } else { SetDrawEffect(_engine->EffectMngr.Effects.Generic); } RefreshAnim(); RefreshAlpha(); } void ItemHexView::SetupSprite(ptr<MapSprite> mspr) { FO_STACK_TRACE_ENTRY(); HexView::SetupSprite(mspr); mspr->SetElevation(GetIsTile() && GetIsRoofTile() ? numeric_cast<int16_t>(_engine->Settings->MapRoofElevation) : GetElevation()); mspr->SetColor(GetColorize() ? GetColorizeColor() : ucolor::clear); mspr->SetEggAppearence(GetEggType()); if (!GetNoLightInfluence()) { mspr->SetLight(GetCorner(), _map->GetLightData(), _map->GetSize()); } if (!mspr->IsHidden() && GetHideSprite()) { mspr->SetHidden(true); } } auto ItemHexView::GetAnim() const -> ptr<const Sprite> { FO_NO_STACK_TRACE_ENTRY(); FO_VERIFY_AND_THROW(_anim, "Item has no animation sprite"); return _anim; } void ItemHexView::Process() { FO_STACK_TRACE_ENTRY(); if (IsFading()) { ProcessFading(); } if (_isMoving) { nanotime time = _engine->GameTime.GetFrameTime(); float32_t dt = (time - _moveUpdateLastTime).to_ms<float32_t>(); _moveUpdateLastTime = time; _moveCurOffset += _moveStepOffset * _moveSpeed * dt; RefreshOffs(); float32_t dist = (_moveCurOffset - _moveStartOffset).dist(); if (dist >= _moveWholeDist) { _moveCurOffset = (_moveStartOffset + _moveStepOffset) * _moveWholeDist; _isMoving = false; } int32_t proc = _moveWholeDist > 0.0f ? iround<int32_t>(dist / _moveWholeDist * 100.0f) : 100; auto step_hex = _moveSteps[_moveSteps.size() * std::min(proc, 99) / 100]; if (auto hex = GetHex(); hex != step_hex) { const auto [x, y] = GeometryHelper::GetHexOffset(hex, step_hex); _moveStartOffset.x -= numeric_cast<float32_t>(x); _moveStartOffset.y -= numeric_cast<float32_t>(y); _moveCurOffset.x -= numeric_cast<float32_t>(x); _moveCurOffset.y -= numeric_cast<float32_t>(y); RefreshOffs(); _map->MoveItem(this, step_hex); } } } void ItemHexView::MoveToHex(mpos hex, float32_t speed) { FO_STACK_TRACE_ENTRY(); auto cur_hex = GetHex(); if (cur_hex == hex) { _isMoving = false; return; } _isMoving = true; _moveSpeed = speed; _moveSteps.clear(); _moveSteps.emplace_back(cur_hex); _map->TraceBullet(cur_hex, hex, 0, 0.0f, nullptr, CritterFindType::Any, nullptr, nullptr, &_moveSteps, false); ipos32 pos_offset = GeometryHelper::GetHexOffset(cur_hex, hex); pos_offset.y += _engine->Random(5, 25); // Center of body _moveStepOffset = GeometryHelper::GetStepsCoords({}, pos_offset); _moveWholeDist = fpos32(pos_offset).dist(); _moveStartOffset = fpos32(_sprOffset); _moveCurOffset = _moveStartOffset; _moveDir = mdir(iround<int32_t>(GeometryHelper::GetDirAngle(cur_hex, hex))); _moveUpdateLastTime = _engine->GameTime.GetFrameTime(); } void ItemHexView::RefreshAlpha() { FO_STACK_TRACE_ENTRY(); SetDefaultAlpha(GetColorize() ? GetColorizeColor().comp.a : 0xFF); } void ItemHexView::PlayAnim(hstring anim_name, bool looped, bool reversed) { FO_STACK_TRACE_ENTRY(); _animName = anim_name; _animLooped = looped; _animReversed = reversed; _animStopped = false; _animTime = reversed ? 0.0f : 1.0f; if (_anim) { _anim->Play(_animName, _animLooped, _animReversed); } } void ItemHexView::StopAnim() { FO_STACK_TRACE_ENTRY(); _animStopped = true; if (_anim) { _anim->Stop(); } } void ItemHexView::SetAnimTime(float32_t normalized_time) { FO_STACK_TRACE_ENTRY(); _animTime = normalized_time; if (_anim) { _anim->SetTime(_animTime); } } void ItemHexView::SetAnimDir(mdir dir) { FO_STACK_TRACE_ENTRY(); _animDir = dir; if (_anim) { _anim->SetDir(_animDir); } } void ItemHexView::RefreshAnim() { FO_STACK_TRACE_ENTRY(); bool is_anim_init = !_anim; auto pic_name = GetPicMap(); if (pic_name) { _anim = _engine->SprMngr.LoadSprite(pic_name, AtlasType::MapSprites); } else { _anim = nullptr; } if (_anim) { if (_map->IsMapperMode()) { _anim->Stop(); _anim->SetTime(0.0f); } else if (is_anim_init) { _anim->PlayDefault(); } else { _anim->SetTime(_animTime); _anim->SetDir(_animDir); if (!_animStopped && _animLooped) { _anim->Play(_animName, _animLooped, _animReversed); } } } else { _anim = _engine->ResMngr.GetItemDefaultSpr(); } _spr = _anim; RefreshOffs(); } auto ItemHexView::GetEggType() const noexcept -> EggAppearenceType { FO_NO_STACK_TRACE_ENTRY(); if (GetDisableEgg() || GetDrawFlatten()) { return EggAppearenceType::None; } switch (GetCorner()) { case CornerType::South: return EggAppearenceType::ByXOrY; case CornerType::North: return EggAppearenceType::ByXAndY; case CornerType::EastWest: case CornerType::West: return EggAppearenceType::ByY; case CornerType::East: case CornerType::NorthSouth: return EggAppearenceType::ByX; } return EggAppearenceType::None; } void ItemHexView::RefreshOffs() { FO_STACK_TRACE_ENTRY(); auto offset = GetOffset(); _sprOffset = ipos32 {offset.x, offset.y}; _rootOffset = ipos32 {offset.x, offset.y}; if (_isMoving) { _sprOffset.x += iround<int32_t>(_moveCurOffset.x); _sprOffset.y += iround<int32_t>(_moveCurOffset.y); } } void ItemHexView::SetMultihexEntries(vector<mpos> entries) { FO_STACK_TRACE_ENTRY(); if (!entries.empty()) { if (!_multihexEntries) { _multihexEntries.emplace(); } *_multihexEntries = std::move(entries); } else { _multihexEntries.reset(); } } FO_END_NAMESPACE