InfoBoxy 13748 9

O temacie

Autor Splash

Zaczęty 7.10.2019 roku

Wyświetleń 13748

Odpowiedzi 9

Splash

Splash

Moderator
posty4208
Propsy3410
ProfesjaNierób
  • Moderator
Uszanowanko.

Jak zapewne wiecie, stworzona przez Piranha Bytes funkcja PrintScreen jest bardzo uboga i często spotykaliśmy się z sytuacją nakładających się na siebie informacji o otrzymanym doświadczeniu czy przedmiotach :facepalm: Natomiast oferowany przez LeGo system Print Soft jest taki se... Tak więc zrobiłem własny system wyświetlania wiadomości. Skrypt napisałem dość dawno, ale dopiero teraz trochę go doszlifowałem.


Skrypt jest bardzo łatwy w użyciu, ponieważ nie wymaga żadnej inicjalizacji (za wyjątkiem pakietów skryptowych), a niektóre właściwości można dowolnie konfigurować. W zależności od potrzeby wystarczy wywołać jedną z funkcji:
InfoBox_Create
InfoBox
AI_InfoBox

Jak to wygląda w praktyce:
https://www.youtube.com/watch?v=gQ9McwBiD5Q


Niestety YouTube mocno obciął jakość filmu skalując z 1050p do 720p xD

Skrypt:
Spoiler
const int InfoBox_PosX = 200; //pozycja X (0-8191)
const int InfoBox_PosY = 5000; //pozycja Y (0-8191)
const int InfoBox_SpaceBetweenBoxes = 30; //odstęp między oknami (0-8191)
const int InfoBox_DurationMS = 5000; //czas w milisekundach po jakim wiadomość ma zacząć zanikać
const int InfoBox_FadeInTimeMS = 500; //czas w milisekundach pojawiania się wiadomości (przejście poziomu kanału alfa z 0 do 255)
const int InfoBox_FadeOutTimeMS = 1000; //czas w milisekundach zanikania wiadomości
const int InfoBox_MoveXTimeMS = 500; //czas w milisekundach jaki ma zająć przesuwanie się okna w lewo do pozycji ustalonej w InfoBox_PosX
const int InfoBox_MoveYTimeMS = 400; //czas w milisekundach jaki ma zająć przesuwanie się okna w górę do pozycji ustalonej w InfoBox_PosY
const string InfoBox_DefaultTexture = "InfoBox.tga"; //domyślna tekstura

class CInfoBox {
    var int view;
    var int a8_duration;
    var int a8_movementX;
    var int a8_movementY;
    var int a8_alpha;
    var int bFadeOut;
    var int posY;
};

instance InfoBox@(CInfoBox);
var int InfoBox_CurrentSize;

func void InfoBox_Delete(var int hndl) {
    var CInfoBox InfoBox; InfoBox = get(hndl);
    View_Delete(InfoBox.view);
    delete(InfoBox.a8_duration);
    delete(InfoBox.a8_movementX);
    delete(InfoBox.a8_movementY);
    delete(InfoBox.a8_alpha);
    delete(hndl);
};

func void InfoBox_DeleteAll() {
    foreachHndl(InfoBox@, InfoBox_Delete);
};

func void InfoBox_A8PositionX(var int hndl, var int position) {
    var CInfoBox InfoBox; InfoBox = get(hndl);
    View_MoveTo(InfoBox.view, position, -1);
};

func void InfoBox_A8PositionY(var int hndl, var int position) {
    var CInfoBox InfoBox; InfoBox = get(hndl);
    var zCView view; view = View_Get(InfoBox.view);
    View_MoveTo(InfoBox.view, -1, position);

    if (view.vposy + view.vsizey <= 0) {
        InfoBox_Delete(hndl);
    };
};

func void InfoBox_A8Alpha(var int hndl, var int alpha) {
    var CInfoBox InfoBox; InfoBox = get(hndl);
    var zCView view; view = View_Get(InfoBox.view);
    view.alpha = alpha;
    view.fontColor = ChangeAlpha(view.fontColor, alpha);

    if (InfoBox.bFadeOut && !view.alpha) {
        InfoBox_Delete(hndl);
    };
};

func void InfoBox_A8Duration(var int hndl, var int duration) {
    var CInfoBox InfoBox; InfoBox = get(hndl);

    if (duration == InfoBox_DurationMS) {
        InfoBox.bFadeOut = true;
        Anim8(InfoBox.a8_alpha, 0, InfoBox_FadeOutTimeMS, A8_Constant);
    };
};

func void InfoBox_MoveUp(var int hndl) {
    var CInfoBox InfoBox; InfoBox = get(hndl);

    if (!Hlp_IsValidHandle(InfoBox.a8_movementY)) {
        InfoBox.a8_movementY = Anim8_NewExt(1, InfoBox_A8PositionY, hndl, false);
    };

    Anim8_RemoveIfEmpty(InfoBox.a8_movementY, true);
    var zCView view; view = View_Get(InfoBox.view);
    Anim8(InfoBox.a8_movementY, view.vposy, 0, A8_Constant);
    InfoBox.posY -= InfoBox_CurrentSize + InfoBox_SpaceBetweenBoxes;
    Anim8q(InfoBox.a8_movementY, InfoBox.posY, InfoBox_MoveYTimeMS, A8_SlowEnd);
};

func int InfoBox_GetLongestLineWidth(var string text, var string fontName, var int lines) {
    var int i; var string longest; longest = "";

    repeat(i, lines);
        var string str; str = STR_Split(text, "~", i);

        if (Print_GetStringWidth(str, fontName) > Print_GetStringWidth(longest, fontName)) {
            longest = str;
        };
    end;

    return Print_GetStringWidth(longest, fontName);
};

func int InfoBox_CenterTextLine(var int pixel, var int pixelSize) {
    return (1<<13>>1) - (Print_ToVirtual(pixel, pixelSize) / 2);
};

func int InfoBox_GetLongestLinePositionX(var zCView view) {
    var zCList list; list = _^(view.textLines_next);

    while(list.next);
        list = _^(list.next);
        var zCViewText t; t = _^(list.data);
        var int x;

        if (t.posx < x || !x) {
            x = t.posx;
        };
    end;

    return x;
};

func void InfoBox_AlignTextLines(var zCView view, var string fontName, var int bCenterLines) {
    var zCList list; list = _^(view.textLines_next);

    while(list.next);
        list = _^(list.next);
        var zCViewText t; t = _^(list.data);

        if (bCenterLines) {
            var int width; width = Print_GetStringWidth(t.text, fontName);
            t.posx = InfoBox_CenterTextLine(width, view.psizex);
        }
        else {
    t.posx = InfoBox_GetLongestLinePositionX(view);
        };

    end;
};

func void InfoBox_Create(var string text, var int bCenterLines, var string fontName, var int fontColor, var string textureName) {
    foreachHndl(InfoBox@, InfoBox_MoveUp);

    var int lines; lines = STR_SplitCount(text, "~");
    var int stringWidth; stringWidth = InfoBox_GetLongestLineWidth(text, fontName, lines);
    var int fontHeight; fontHeight = Print_GetFontHeight(fontName);
    var int x1; x1 = Print_ToPixel(InfoBox_PosX, PS_X);
    var int y1; y1 = Print_ToPixel(InfoBox_PosY, PS_Y);
    var int x2; x2 = x1 + stringWidth + (fontHeight * 2);
    var int y2; y2 = y1 + (fontHeight * 2 * lines);

    var int hndl; hndl = new(InfoBox@);
    var CInfoBox InfoBox; InfoBox = get(hndl);
    InfoBox.view = View_CreatePxl(x1, y1, x2, y2);
    View_SetTexture(InfoBox.view, textureName);
    var zCView view; view = View_Get(InfoBox.view);
    InfoBox.posY = view.vposy;
    InfoBox_CurrentSize = view.vsizey;

    var string firstLine; firstLine = STR_Split(text, "~", 0);
    var int width; width = Print_GetStringWidth(firstLine, fontName);
    var int xPos; xPos = InfoBox_CenterTextLine(width, view.psizex);
    var int posY; posY = InfoBox_CenterTextLine(fontHeight * lines, view.psizey);
    View_AddText(InfoBox.view, xPos, posY, text, fontName);
    InfoBox_AlignTextLines(view, fontName, bCenterLines);

    view.fontColor = fontColor;
    View_MoveTo(InfoBox.view, InfoBox_PosX + view.vsizex, -1);
    View_Open(InfoBox.view);

    InfoBox.a8_alpha = Anim8_NewExt(1, InfoBox_A8Alpha, hndl, false);
    Anim8q(InfoBox.a8_alpha, 255, InfoBox_FadeInTimeMS, A8_Constant);

    InfoBox.a8_movementX = Anim8_NewExt(1, InfoBox_A8PositionX, hndl, false);
    Anim8_RemoveIfEmpty(InfoBox.a8_movementX, true);
    Anim8(InfoBox.a8_movementX, view.vposx, 0, A8_Constant);
    Anim8q(InfoBox.a8_movementX, InfoBox_PosX, InfoBox_MoveXTimeMS, A8_SlowEnd);

    InfoBox.a8_duration = Anim8_NewExt(1, InfoBox_A8Duration, hndl, false);
    Anim8_RemoveIfEmpty(InfoBox.a8_duration, true);
    Anim8q(InfoBox.a8_duration, InfoBox_DurationMS, InfoBox_DurationMS, A8_Constant);
};

func void InfoBox(var string text, var int fontColor) {
    InfoBox_Create(text, true, FONT_ScreenSmall, fontColor, InfoBox_DefaultTexture);
};

func void AI_InfoBox(var string text, var int fontColor) {
    AI_Function_SI(hero, InfoBox, text, fontColor);
};

Tekstura tła:
https://drive.google.com/file/d/1lqFHvAWuWyVGCI8GXVtoHjCCn4XAgCzo/view

Parę informacji:
- Wiadomości które powędrują poza ekran są automatycznie usuwane (optymalizacja)
- Skoro skrypt udostępniam, to tak - macie pozwolenie na użycie go w swojej modyfiakcji
- Nie odpowiadam na pytania w stylu "Pokazuje mi się Unknown identifier. Co robić?"
- Skrypt nie podmienia oryginalnego systemu wiadomości. Musicie sami podmienić sobie w skryptach przypadki użycia funkcji PrintScreen, Print etc.
- Aby usunąć wszystkie info boxy, należy wywołać funkcję InfoBox_DeleteAll
- Co prawda nie testowałem tego w G1, ale nie widzę przeciwskazań w poprawnym działaniu

Aby dodać linijkę tekstu, należy w tekście zamieścić tyldę "~"
InfoBox("Pierwsza linijka~Druga linijka~Trzecia linijka", COL_White);


Dokładny opis użycia funkcji InfoBox_Create
InfoBox_Create(var string text, var int bCenterLines, var string fontName, var int fontColor, var string textureName)
- text - jak sama nazwa wskazuje, jest to po prostu tekst
- bCenterLines - czy linijki mają być wyśrodkowane (true lub false)
- fontName - nazwa czcionki
- fontColor - kolor czcionki w RGBA
- textureName - nazwa tekstury tła

Bez wyśrodkowanych linijek:


InfoBox_Create("Pierwsza linijka~Druga linijka~Trzecia linijka", false, FONT_ScreenSmall, COL_White, InfoBox_DefaultTexture);
PS. myślałem nad ustaleniem jakiejś stałej szerokości boxów by wyglądało to symetrycznie, ale obawiam się wyglądu pustki między tekstem a krawędziami tekstury, dlatego poczekam na wasz feedback.
 
Nie zajmuję się multiplayerami do Gothica. Przestańcie zawracać mi tym głowę...
Ps. Siemekk ma downa i śpi w pufie

Siemekk

Siemekk

Złote Wrota
posty2143
Propsy1153
ProfesjaProgramista
  • Złote Wrota
A tego murzyna z pierwszego screen'a jak mogę włączyć?
 

P.S A Splash w szafie i nie ma psychy by mi dać bana.

Splash

Splash

Moderator
posty4208
Propsy3410
ProfesjaNierób
  • Moderator
Musisz kupić DLC za 4,99 zł
 
Nie zajmuję się multiplayerami do Gothica. Przestańcie zawracać mi tym głowę...
Ps. Siemekk ma downa i śpi w pufie

SolariS

SolariS

Użytkownicy
posty361
Propsy77
ProfesjaGracz
  • Użytkownicy
Sorrki że nie na temat ale czy te bajery z UI na filmiku to wszystko twoja praca czy jakiś mod?
 

Simon Said

Simon Said

Moderator
Nilfgaard
posty6473
Propsy3037
ProfesjaTester
  • Moderator
  • Nilfgaard
Oczywiście, że jego. Splash to taaaaki modder.
 
http://chomikuj.pl/gothicwarrior

https://www.youtube.com/watch?v=UCMTYnPVyFu



Splash

Splash

Moderator
posty4208
Propsy3410
ProfesjaNierób
  • Moderator
( ͡° ͜ʖ ͡°)
 
Nie zajmuję się multiplayerami do Gothica. Przestańcie zawracać mi tym głowę...
Ps. Siemekk ma downa i śpi w pufie

pawbuj

pawbuj

Użytkownicy
posty1622
Propsy135
ProfesjaSkrypter
  • Użytkownicy

pawbuj

InfoBoxy
#6 2023-01-17, 19:18(Ostatnia zmiana: 2023-01-29, 10:00)
 w g1 działa trzeba tylko dodać gdzies na początku
const string FONT_ScreenSmall = "FONT_OLD_10_WHITE.TGA";
i tga musi być skonwertowana do tex, inaczej jest witaj pulpit.

 

overdriven

overdriven

Użytkownicy
posty7
ProfesjaProgramista
  • Użytkownicy

overdriven

InfoBoxy
#7 2024-09-23, 00:10(Ostatnia zmiana: 2024-09-25, 23:23)
Po 5 latach wciąż działa elegancko.

Tylko czy ja coś robię źle, czy ta wersja nie ma animacji i automatycznego znikania? Jeśli nie ma, to czy jest gdzieś dostępna nowa wersja?

Bez tego wiadomości nakładają się na siebie:


Każdą wiadomość odpalam przez InfoBox:
InfoBox("aaa", -1);
Edit: Ok, wszystko jasne.
Zabrakło informacji o tym, których pakietów użyto i jak je zainicjalizować. Wg samego autora Ikarusa i Ninjy, obecnie zalecana metoda to inicjalizacja przez Ninję, lecz wtedy robi się to trochę inaczej niż przez Ikarusa.
Konkretnie przez LeGo_MergeFlags zamiast LeGo_Init. Najprościej upewnić się na działającym przykładzie. Tylko tutaj mamy LeGo_MergeFlags(LeGo_ConsoleCommands), w naszym przypadku potrzebujemy LeGo_MergeFlags(LeGo_Anim8 | ...) i parę innych, których autor skryptu niestety omieszkał wymienić (:
 

Splash

Splash

Moderator
posty4208
Propsy3410
ProfesjaNierób
  • Moderator
Cytuj
i parę innych, których autor skryptu niestety omieszkał wymienić (:
Każdy korzystający z pakietów skryptowych doskonale wie, że trzeba je najpierw zainicjować aby działały prawidłowo. Nie wiń mnie za to, że nie byłeś łaskaw przeczytać dokumentacji LeGo.
https://lego.worldofplayers.de/?ReadMe
Cytuj
4. LeGo muss in der INIT_Global() initialisiert werden. Du musst alle Konstanten in einen Ausdruck kombinieren und dann LeGo_Init() einmalig(!) aufrufen, z.B. LeGo_Init(LeGo_Bloodsplats | LeGo_FrameFunctions);, wenn du die Bloodsplats und die FrameFunctions initialisieren möchtest. Es ist auch möglich, LeGo komplett zu initialisieren mit LeGo_All als Konstante oder einzelne Pakete (z.B. die Bloodsplats) zu entfernen: LeGo_Init(LeGo_All & ~LeGo_Bloodsplats);
Naprostszą metodą jest pełna inicjalizacja LeGo poprzez wywołanie w funkcji Init_Global funkcji LeGo_Init z argumentem LeGo_All, zamiast inicjalizować wszystko z osobna.
 
Nie zajmuję się multiplayerami do Gothica. Przestańcie zawracać mi tym głowę...
Ps. Siemekk ma downa i śpi w pufie

Simon Said

Simon Said

Moderator
Nilfgaard
posty6473
Propsy3037
ProfesjaTester
  • Moderator
  • Nilfgaard
Skoro już ten temat żyje to tylko pokażę, że @bogu9821 udało się to przepisać na Uniona, jakby ktoś był ciekaw  ^^


 
http://chomikuj.pl/gothicwarrior

https://www.youtube.com/watch?v=UCMTYnPVyFu




0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry