• 0

    posted a message on Modify TooltipAppender through triggers

    Since the old forum is gone, I made a new thread at http://us.battle.net/forums/en/sc2/topic/20747895285#1

    Obviously I dont expect a fix, but I know that some official Blizzard rep sometimes lurks here, so hopefully this bump increases the chance that someone there sees it.

    Posted in: Galaxy Scripting
  • 0

    posted a message on Chat Commands with Arguments

    Take a look at the "Crap Patrol 2" map on BNET (it's unlocked for sc2edit), I've made a quite thorough debug system there.

    It's all contained in its own Debug subfolder in the treeview.

    In a live game you need to be authorized (4 people are, based on player bnet ids), but as long as you run the map through the editor you are automatically authorized.

    Posted in: Triggers
  • 0

    posted a message on How to modify this trigger so it makes several dead heroes respawn?

    Unit - Move (Triggering unit) instantly to (Start location of player (Owner of (Triggering unit))) (No Blend)

    Posted in: Triggers
  • 0

    posted a message on [Request] Trigger that counts points for two teams?

    I dont understand the problem with this, except there are so many different ways of doing it.

    I would just share vision of the structure with the relevant player group on unit behavior change, for example, save the team in a global variable and have a periodic trigger that runs and gives them "points", whatever that means.

    Posted in: Triggers
  • 0

    posted a message on How to modify this trigger so it makes several dead heroes respawn?

    Add the Valerian02a - Hero Death Prevention, Incapacitated and Incapacitated (Stand Up) behaviors to the relevant units.

    Make a trigger that registers for the event "Unit - Any Unit has Valerian02a - Incapacitated change Activate".

    Triggering Unit in that trigger is then the hero, and you should just use the "Start Location of Player" function to move it to the correct spot.

    Posted in: Triggers
  • 0

    posted a message on Pause / Unpause the game through code

    @FunkyUserName: Go

    No, timers still run then. Setting it to 0 or 0.01 has no effect.

    @SomeoneTookMyNameTT: Go

    That's interesting, I didnt think of that. Anyway this work started long before lotv.

    But I checked, and they use a cutscene that apparently stops game time. I did not investigate further, and I have no idea how cutscenes work, but here is the relevant code from VoidCampaignMissionLib:

        string auto96F65A59_val;
    
        // Variable Declarations
        string lv_locationFilter;
        string lv_spaceScene;
    
        // Variable Initialization
        lv_locationFilter = "";
        lv_spaceScene = "Cutscenes\\Mission_SoACalldown_OrbitalStrike.SC2Cutscene";
    
        // Implementation
        CameraSetValue(1, c_cameraValueDistance, 100.0, 0.3, -1, 0.0);
        Wait(0.25, c_timeGame);
        auto96F65A59_val = libVoiC_gf_StoryMapPlanet(libVoiC_gf_CurrentMap());
        if (auto96F65A59_val == "Korhal") {
            lv_locationFilter = "Korhal";
        }
        else if (auto96F65A59_val == "Shakuras") {
            lv_locationFilter = "Shakuras";
        }
        else {
        }
        CutsceneAddGlobalFilter(lv_locationFilter);
        libVoiC_gf_CampaignPlayCutscene2(lv_spaceScene, true, true);
        CutsceneRemoveGlobalFilter(lv_locationFilter);
        CameraApplyInfo(1, lp_camera, 0.0, -1, 10, true);
        CameraSetValue(1, c_cameraValueDistance, 100.0, 0.0, -1, 0.0);
        CameraSetValue(1, c_cameraValueDistance, CameraInfoGetValue(lp_camera, c_cameraValueDistance), 0.4, -1, 0.0);
    
    Posted in: Triggers
  • 0

    posted a message on Pause / Unpause the game through code

    Hi,

    I've written a custom timer registry to enable pausing/unpausing arcade maps from code.

    This does not count towards actual game pauses from the main menu (usually 3 per player).

    This has been tested and proven on a 10mb+ map with hundreds of timers running.

    The only thing it does not pause is missile animations. They will continue on their path, but the effect at the end of it will still apply when it should, and not immediately after the game is unpaused.

    You will obviously have to hide any custom dialogs manually in the Pause/Resume actions, and many of the things there (like stopping and starting AI time) might not be necessary in all maps.

    The main thing is just to use the provided API for elapsed or periodic timers instead of Blizzards. This ensures all custom timers are added to a pool that can be iterated and paused at will.

    If you look closely at the main loop trigger for periodic events, you will see that it waits 0.97 game time seconds between firing, and that it staggers a bit if it cant find any triggers to run. This is a failsafe against network latency and such, which means that sometimes things will not fire exactly to the split-second when you want it to, but trust me this has exactly zero impact on a game in the real world.

    The two custom event definitions are:

    • Periodic(time) - runs the trigger every time seconds, recurring.
    • Elapsed(time) - runs the trigger after time seconds, one time.

    The main action definitions are:

    • Toggle Periodic Trigger(onoff, trigger)
    • Set Periodic Time(trigger, time) - to change how often an already-registered periodic trigger should fire
    • Oneshot(time, trigger) - fires a new oneshot timer and executes the given trigger after the given time in seconds
    • Register Timer for Pause(timer) - if you have any timers that are created with Blizzards API, register it for pausing using this. Do not call this for any timers created with my API.
    • Pause Registered Timers() - pauses all oneshot and periodic timers
    • Unpause Registered Timers() - Starts them again

    The functions are:

    • Get Oneshot Timer for Trigger(trigger) - returns the registered Timer for the given trigger

    All in all it's very simple to use, just look at the triggers in the attached map.

    Please feel free to use this code however you wish, I am releasing it under CC-BY-NC-SA 4.0 or later which means you just need to mention my nick or name somewhere.

    Please consider uploading your map UNLOCKED to Battle.net. What on earth are you trying to hide anyway? This is how we learn from eachother. We all write crappy code, dont be ashamed of yours. Show it!

    Posted in: Triggers
  • 0

    posted a message on Custom Boss Bar Script

    It's quite easy to see how much CPU time the blizzard boss bar eats up if you enable the trigger debugging window in the editor.

    But basically what the Blizzard boss bar does is:

    1. Register for all life and shield change events for all units on the map
    2. Every time anything changes, by any amount, loop through 1...50 and check if the boss bar frame for id X is registered to the unit that changed
    3. Set the image, size, position and text of all elements on the boss frame for every event

    This is really expensive and eats up lots of CPU time.

    What mine does is it shows 1 boss at a time and only updates every 0.2 seconds.

    This is quite similar to FuzzyD's boss bars, except his are much more customizable and advanced with lots of options.

    Mine are super simple, with 1 API fire-and-forget.

    Posted in: Triggers
  • 0

    posted a message on Custom Boss Bar Script

    Hi,

    Below I've attached a custom boss bar script heavily inspired by libbossbars+ by fuzzyd and the blizzard boss bars, but much more slim and resource friendly.

    Please keep your maps in the Arcade unlocked for the world to see.

    What the hell are you hiding anyway except how crappy your code is? My code sure sucks, but that's nothing to be ashamed of. That's how you improve, grow and get better.

    Feel free to use it under the license CC-BY-NC-SA 4.0, unlike libbossbars+/advanced which are All Rights Reserved.

    https://creativecommons.org/licenses/by-nc-sa/4.0/

    Enjoy.

    Posted in: Triggers
  • 0

    posted a message on How to call ANY unit from unit group?

    Add a "General - Break" action directly underneath "Variable - Set Infantry or Artillery in group = True" at the same level (inside the loop).

    Posted in: Triggers
  • 0

    posted a message on Detect Replay playback

    PlayerType(1) returns 1 (c_playerTypeUser, as opposed to c_playerTypeNone) in replays as well.

    PlayerGroupActive() contains all players in the replay.

    What is it I dont understand?

    How do you get a group containing human players?

    Posted in: Triggers
  • 0

    posted a message on Custom base-building AI

    Hi,

    I've created a custom base-building AI so that an arcade map doesnt have to use the melee/campaign AI simply to construct a base.

    The attached map has all the details, but essentially it uses hidden structures that are scanned when the map loads and then removed immediately and rebuilt as the AI sees fit.

    It has some weird things to make it fit my map but not many, and the code is easily changed to accomodate anything.

    Please keep your maps in the Arcade unlocked for the world to see.

    What the hell are you hiding anyway except how crappy your code is?

    Feel free to use it under the license CC-BY-NC-SA 4.0 or later.

    https://creativecommons.org/licenses/by-nc-sa/4.0/

    Enjoy.

    Posted in: AI Development
  • 0

    posted a message on [UI]A sample map for Customized Health Bar

    @uroboros1987: Go

    Yes, put this in the UIXML:

            <!-- name of player -->
            <Frame type="UnitStatusPlayerName" name="PlayerName">
                <Anchor side="Top" relative="$parent" pos="Min" offset="-40"/>
                <Anchor side="Left" relative="$parent/AttachPointFrame" pos="Min" offset="-50"/>
                <Height val="60"/>
                <Width val="300"/>
                <VisibleToAlly val="true"/>
                <VisibleToOwner val="true"/>
    
                <Frame type="Label" name="Label">
                    <Anchor side="Top" relative="$parent" pos="Min" offset="0"/>
                    <Anchor side="Left" relative="$parent" pos="Min" offset="0"/>
                    <Height val="60"/>
                    <Style val="PlayerUnitName"/>
                </Frame>
            </Frame>
    

    PlayerUnitName is a custom text style based on HeaderTemplate: Horizontal justify: left vertical justify: middle

    Posted in: General Chat
  • 0

    posted a message on Detect Replay playback

    Hi,

    I'm not sure how the replay feature works, but I assume that it just records events and actions and replays it on a copy of the map from the bnet servers. Which means that all our triggers run as normal.

    That's what I assume.

    And if that's true, there should be some way to detect that we're in a replay and do things differently.

    I've tried the return values from GameIsSpeedLocked(), GameIsSeedLocked() and GameIsOnline(), but they are all the same as when playing in the arcade.

    Basically what I want to do is show additional information in replay mode for the viewer, but not show it to the player while in the game.

    Any thoughts?

    Posted in: Triggers
  • 0

    posted a message on [Solved] Disappearing Boss Bar

    The Blizzard boss bar code is truly horrible, here is some slightly better code.

    Put it in a custom script action and use initcpbb() as the init function at the bottom.

    Show a boss bar with a custom script cpbbRegisterBoss("texture
    location
    portrait.dds", bossUnit)

    Boss bars are automatically removed when the boss dies, and only 1 will show at a time with magic.

    // Boss bar code by Folk
    // Heavily inspired by FuzzyD's LibBossBars+ and initially ripped from Blizzards libntve.
    int cpbbEventIndex;
    unit cpbbEventUnit;
    int cpbbActive;
    struct cpbbData {
        bool used;
        unit boss;
        string portrait;
        text title;
    };
    const int CPBB_MAX = 10;
    cpbbData[CPBB_MAX] cpbbBosses;
    int cpbbDialog;
    int cpbbBgImgBar;
    int cpbbBgImgPortrait;
    int cpbbPortraitImage;
    int cpbbTitleLabel;
    int cpbbHpBorderImage;
    int cpbbHpLabel;
    int cpbbHpFullImage;
    int cpbbHpCurrentImage;
    bool cpbbUpdate(bool check, bool run) {
        int id = cpbbEventIndex;
        unit boss = cpbbEventUnit;
        int i = CPBB_MAX - 1;
        fixed current;
        fixed max;
        int width;
        while ( cpbbBosses[id].boss == boss ) {
            if ( cpbbActive == id ) {
                max = (UnitGetPropertyFixed(boss, c_unitPropLifeMax, true) + UnitGetPropertyFixed(boss, c_unitPropShieldsMax, true));
                if ( max == 0 || !UnitIsAlive(boss) ) {
                    TriggerDebugOutput(10, StringToText(UnitGetType(boss) + "/" + IntToString(id) + " gone."), false);
                    cpbbActive = -1;
                    DialogSetVisible(cpbbDialog, PlayerGroupAll(), false);
                    cpbbBosses[id].boss = null;
                    while ( i > -1 ) {
                        if ( i != id && cpbbBosses[i].used ) {
                            if ( cpbbBosses[i].boss != null && UnitIsAlive(cpbbBosses[i].boss) ) {
                                cpbbActive = i;
                                TriggerDebugOutput(10, StringToText("Found next boss: " + IntToString(i) + " (" + UnitGetType(cpbbBosses[i].boss) + ")"), false);
                                Wait(1, c_timeGame);
                                DialogSetVisible(cpbbDialog, PlayerGroupAll(), true);
                                break;
                            } else {
                                cpbbBosses[i].boss = null;
                                cpbbBosses[i].used = false;
                            }
                        }
                        i -= 1;
                    }
                    return true;
                }
                current = (UnitGetPropertyFixed(boss, c_unitPropLife, true) + UnitGetPropertyFixed(boss, c_unitPropShields, true));
                width = FixedToInt(350 * (current / max));
                DialogControlSetPropertyAsString(cpbbPortraitImage, c_triggerControlPropertyImage, PlayerGroupAll(), cpbbBosses[id].portrait);
                DialogControlSetPropertyAsText(cpbbTitleLabel, c_triggerControlPropertyText, PlayerGroupAll(), cpbbBosses[id].title);
                DialogControlSetPropertyAsText(cpbbHpLabel, c_triggerControlPropertyText, PlayerGroupAll(), FixedToText(current, 0));
                DialogControlSetSize(cpbbHpCurrentImage, PlayerGroupAll(), width, 34);
                Wait(0.2, c_timeGame);
            } else {
                Wait(1, c_timeGame);
            }
        }
        return true;
    }
    static void createBossBarDialog() {
        playergroup all = PlayerGroupAll();
        if ( cpbbDialog != c_invalidDialogId ) { return; }
        DialogCreate(520, 120, c_anchorTop, 0, 50, false);
        cpbbDialog = DialogLastCreated();
        DialogSetRenderPriority(cpbbDialog, 10);
        DialogSetImageVisible(cpbbDialog, false);
        cpbbBgImgBar = DialogControlCreate(cpbbDialog, c_triggerControlTypeImage);
        DialogControlSetFullDialog(cpbbBgImgBar, all, true);
        libNtve_gf_SetDialogItemImageType(cpbbBgImgBar, c_triggerImageTypeBorder, all);
        libNtve_gf_SetDialogItemImage(cpbbBgImgBar, "Assets\\Textures\\ui_mission_leaderboard_frame_light.dds", all);
        libNtve_gf_SetDialogItemColor(cpbbBgImgBar, Color(100.00, 50.20, 0.00), all);
        cpbbBgImgPortrait = DialogControlCreate(cpbbDialog, c_triggerControlTypeImage);
        libNtve_gf_SetDialogItemImageType(cpbbBgImgPortrait, c_triggerImageTypeBorder, all);
        libNtve_gf_SetDialogItemImage(cpbbBgImgPortrait, "Assets\\Textures\\ui_mission_leaderboard_frame_unit.dds", all);
        DialogControlSetSize(cpbbBgImgPortrait, all, 80, 80);
        DialogControlSetPosition(cpbbBgImgPortrait, all, c_anchorLeft, 18, 1);
        libNtve_gf_SetDialogItemColor(cpbbBgImgPortrait, Color(100.00, 50.20, 0.00), all);
        cpbbPortraitImage = DialogControlCreate(cpbbDialog, c_triggerControlTypeImage);
        DialogControlSetSize(cpbbPortraitImage, all, 70, 70);
        DialogControlSetPositionRelative(cpbbPortraitImage, all, c_anchorCenter, cpbbBgImgPortrait, c_anchorCenter, 0, 0);
        cpbbTitleLabel = DialogControlCreate(cpbbDialog, c_triggerControlTypeLabel);
        DialogControlSetSize(cpbbTitleLabel, all, 420, 48);
        DialogControlSetPositionRelative(cpbbTitleLabel, all, c_anchorTopLeft, cpbbPortraitImage, c_anchorTopRight, 0, 0);
        libNtve_gf_SetDialogItemStyle(cpbbTitleLabel, "BossBarTitleZerg", all);
        cpbbHpBorderImage = DialogControlCreate(cpbbDialog, c_triggerControlTypeImage);
        libNtve_gf_SetDialogItemImageType(cpbbHpBorderImage, c_triggerImageTypeBorder, all);
        libNtve_gf_SetDialogItemImage(cpbbHpBorderImage, "Assets\\Textures\\ui_mission_leaderboard_progressbar_frame.dds", all);
        DialogControlSetSize(cpbbHpBorderImage, all, 360, 37);
        DialogControlSetPositionRelative(cpbbHpBorderImage, all, c_anchorTop, cpbbTitleLabel, c_anchorBottom, 0, -12);
        libNtve_gf_SetDialogItemColor(cpbbHpBorderImage, Color(71.37, 32.16, 8.63), all);
        cpbbHpFullImage = DialogControlCreate(cpbbDialog, c_triggerControlTypeImage);
        libNtve_gf_SetDialogItemImageType(cpbbHpFullImage, c_triggerImageTypeBorder, all);
        libNtve_gf_SetDialogItemImage(cpbbHpFullImage, "Assets\\Textures\\ui_mission_leaderboard_progressbar_fill.dds", all);
        libNtve_gf_SetDialogItemColor(cpbbHpFullImage, Color(100.00, 0.00, 0.00), all);
        DialogControlSetSize(cpbbHpFullImage, all, 350, 34);
        DialogControlSetPositionRelative(cpbbHpFullImage, all, c_anchorCenter, cpbbHpBorderImage, c_anchorCenter, 0, 0);
        cpbbHpCurrentImage = DialogControlCreate(cpbbDialog, c_triggerControlTypeImage);
        libNtve_gf_SetDialogItemImageType(cpbbHpCurrentImage, c_triggerImageTypeBorder, all);
        libNtve_gf_SetDialogItemImage(cpbbHpCurrentImage, "Assets\\Textures\\ui_mission_leaderboard_progressbar_fill.dds", all);
        libNtve_gf_SetDialogItemColor(cpbbHpCurrentImage, Color(0.00, 100.00, 0.00), all);
        DialogControlSetPositionRelative(cpbbHpCurrentImage, all, c_anchorLeft, cpbbHpFullImage, c_anchorLeft, 0, 0);
        cpbbHpLabel = DialogControlCreate(cpbbDialog, c_triggerControlTypeLabel);
        libNtve_gf_SetDialogItemStyle(cpbbHpLabel, "BossBarHP", all);
        libNtve_gf_SetDialogItemRenderPriority(cpbbHpLabel, 520, all);
        DialogControlSetSize(cpbbHpLabel, all, 360, 38);
        DialogControlSetPositionRelative(cpbbHpLabel, all, c_anchorCenter, cpbbHpBorderImage, c_anchorCenter, 0, 0);
    }
    static void tRun(string s) {
        trigger t = TriggerCreate(s);
        TriggerExecute(t, false, false);
        TriggerDestroy(t);
    }
    void cpbbRegisterBoss(string portrait, unit boss) {
        int bossId = 0;
        createBossBarDialog();
        while ( true ) {
            if ( !cpbbBosses[bossId].used ) {
                break;
            }
            bossId += 1;
            if ( bossId == CPBB_MAX ) {
                TriggerDebugOutput(10, StringToText("Too many boss bars, denying " + UnitGetType(boss) + "."), false);
                return;
            }
        }
        TriggerDebugOutput(10, StringToText("Registered boss bar for " + UnitGetType(boss) + "@" + IntToString(bossId)), false);
        cpbbBosses[bossId].used = true;
        cpbbBosses[bossId].boss = boss;
        cpbbBosses[bossId].portrait = portrait;
        cpbbBosses[bossId].title = UnitGetName(boss);
        cpbbEventIndex = bossId;
        cpbbEventUnit = boss;
        cpbbActive = bossId;
        DialogSetVisible(cpbbDialog, PlayerGroupAll(), true);
        tRun("cpbbUpdate");
    }
    // -bb command takes the first unit selected by player 1 and makes it a boss
    // only available in editor mode
    bool cpbbchat(bool check, bool run) {
        unitgroup g = UnitGroupSelected(1);
        unit u;
        if (UnitGroupCount(g, 0) == 0) { return true; }
        u = UnitGroupUnit(g, 1);
        TriggerDebugOutput(10, StringToText("Selected unit: " + UnitGetType(u)), false);
        cpbbRegisterBoss("Assets\\Textures\\btn-building-zerg-spinecrawler.dds", u);
        return true;
    }
    void initcpbb() {
        if ( !GameIsTestMap(false) ) { return; }
        TriggerDebugOutput(10, StringToText("-bb command enabled, target anything and type it to get a boss bar for the target."), false);
        TriggerAddEventChatMessage(TriggerCreate("cpbbchat"), 1, "-bb", true);
    }
    
    Posted in: Triggers
  • To post a comment, please or register a new account.