/
Mr.Stalin
/
FOnline-Engine
Обзор
Документация
Войти
/
Mr.Stalin
/
FOnline-Engine
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Source/Scripting/AngelScript/CoreScripts/FixedDropMenu.fos
208 строк
6 KB
cvet
Strong nullable (#164)
25 май 2026, 11:45
Не верифицирован
25 май 2026, 11:45
04a4963
Код
Авторство
О чём код?
namespace FixedDropMenu { #if CLIENT funcdef bool DropMenuNeedShowButton(Critter cr, Item item); funcdef void DropMenuButtonAction(Critter cr, Item item); class DropButton { int SortIndex; Sprite::Sprite PicNormal; Sprite::Sprite PicActive; DropMenuNeedShowButton NeedShow; DropMenuButtonAction Action; }; class FixedDropMenu : Gui::IDropMenu { MouseButton MouseBtn; CursorType Cursor; timespan ShowTime; int ButtonHeight; string ArtDir; string OpenSound; DropButton[] Buttons = {}; DropButton[] ShowButtons = {}; bool Pressed; int PressedOffsetY; nanotime MouseStayTick; Entity? SelectedEntity; FixedDropMenu(MouseButton mouseButton, CursorType cursor, timespan showTime, int buttonHeight, string artDir, string openSound) { MouseBtn = mouseButton; Cursor = cursor; ShowTime = showTime; ButtonHeight = buttonHeight; ArtDir = artDir; OpenSound = openSound; Buttons = array<DropButton>(); ShowButtons = array<DropButton>(); Pressed = false; PressedOffsetY = 0; MouseStayTick = ZERO_NANOTIME; SelectedEntity = null; } void AddButton(int sortIndex, DropMenuNeedShowButton needShow, DropMenuButtonAction action, string picNormal, string picActive) { DropButton button = DropButton(); button.SortIndex = sortIndex; button.PicNormal = Sprite::Sprite(ArtDir + picNormal); button.PicActive = Sprite::Sprite(ArtDir + picActive); button.NeedShow = needShow; button.Action = action; Buttons.insertLast(button); } private Entity? get_SafeSelectedEntity() { // Simulate entity weak reference Entity? selectedEntity = SelectedEntity; if (selectedEntity != null && selectedEntity.IsDestroyed) { SelectedEntity = null; } return SelectedEntity; } void Draw() { if (ShowButtons.length() > 0) { ipos pos = Game.MousePos + ipos(20, 20); int activeIndex = PressedOffsetY / ButtonHeight; activeIndex = Math::Clamp(activeIndex, 0, ShowButtons.length() - 1); for (int i = 0; i < ShowButtons.length(); i++) { DropButton button = ShowButtons[i]; Sprite::Sprite pic = i == activeIndex ? button.PicActive : button.PicNormal; pic.Draw(pos); pos.y += ButtonHeight; } } } void MouseDown(MouseButton button) { if (MouseBtn == button && Cursor == Gui::Cursor && SafeSelectedEntity != null) { Pressed = true; PressedOffsetY = 0; MouseStayTick = Game.FrameTime; } } void MouseUp(MouseButton button) { if (MouseBtn == button && SafeSelectedEntity != null) { Pressed = false; if (ShowButtons.length() == 0) { CollectShowButtons(true); } int activeIndex = PressedOffsetY / ButtonHeight; activeIndex = Math::Clamp(activeIndex, 0, ShowButtons.length() - 1); DropButton dropButton = ShowButtons[activeIndex]; ShowButtons.clear(); Entity? entity = SafeSelectedEntity; SelectedEntity = null; if (entity != null && !entity.IsDestroyed) { Critter? cr = cast<Critter>(entity); Item? item = cast<Item>(entity); if (dropButton.NeedShow(cr, item)) { dropButton.Action(cr, item); } } } } bool PreMouseMove(ipos offset) { if (Pressed) { if (offset != ZERO_IPOS) { PressedOffsetY += offset.y; Game.SetMousePos(Game.MousePos - offset); } return true; } return false; } void PostMouseMove(ipos offset) { if (Cursor == Gui::Cursor) { Entity? prevEntity = SafeSelectedEntity; SelectedEntity = null; Gui::Object? hoveredObj = Gui::GetHoveredObject(); Gui::Screen? screen = Gui::GetActiveScreen(); if (hoveredObj != null) { if (hoveredObj.Grid != null && cast<Gui::ItemView?>(hoveredObj.Grid) != null) { SelectedEntity = cast<Gui::ItemView>(hoveredObj.Grid).GetItem(hoveredObj.CellIndex); } } else if (HasCurMap && (screen == null || !screen.IsModal)) { Entity? entity = CurMap.GetEntityAtScreenPos(Game.MousePos); if (entity != null && (cast<Critter?>(entity) != null || cast<Item?>(entity) != null)) { SelectedEntity = entity; } } if (prevEntity != SafeSelectedEntity || offset != ZERO_IPOS) { MouseStayTick = Game.FrameTime; ShowButtons.clear(); } } } void InputLost() { Pressed = false; SelectedEntity = null; ShowButtons.clear(); } void Loop() { if (SafeSelectedEntity != null) { if (Cursor != Gui::Cursor) { Pressed = false; SelectedEntity = null; ShowButtons.clear(); } else if (MouseStayTick != ZERO_NANOTIME && Game.FrameTime - ShowTime >= MouseStayTick) { MouseStayTick = ZERO_NANOTIME; CollectShowButtons(!Pressed); if (ShowButtons.length() == 0) { Pressed = false; SelectedEntity = null; } } } } private void CollectShowButtons(bool onlyFirst) { ShowButtons.clear(); Critter? cr = cast<Critter>(SafeSelectedEntity); Item? item = cast<Item>(SafeSelectedEntity); for (int i = 0; i < Buttons.length(); i++) { if (Buttons[i].NeedShow(cr, item)) { ShowButtons.insertLast(Buttons[i]); if (onlyFirst) { break; } } } } }; #endif }