• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

My Concept for Buildings "Building"

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
I've done it in the past by having invisible dummy hero builders. They were accessible using the hero hotkeys/buttons, and were instantly moved to the target build location (using setunitx/y) when ordered to build.

I did basically that too. Would want to make a "can't build there" sound if out of range. Perhaps create a block if its out of range, and then move the builder there. Playing wise, I think the Selection-deselection thing is very awkward, but don't know how to do it without it.

I think moving the "Town" (build command card) around instead of creating one at every town is the better option.
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
You can use this to simulate an error message: http://www.wc3c.net/showthread.php?t=101260

Just call it as
  • Custom script: call SimError (GetOwningPlayer(GetTriggerUnit()), "Construction location out of range.")

That requires vJass I belive (but I'll keep that in mind for the future). Besides "Can't build there." is good enough for me. ;)

A Problem with using Selection Scale as a marker for buildable area is that there is a giant health-bar created... Need to make a unit for that that is only visible for the owner of triggering unit.

Using this model on a locust unit works somewhat... UI\Feedback\TargetPreSelected\TargetPreSelected.mdl

Issues:
- Doesn't work properly on hills.
- And blinks /(birth/deaty)
- Looks horrible!



How to solve the problem with the buildable marker? Also ingame it flies, i set its movement height to -350 to make it on the ground (as seen above), but apparently it doesn't work in-game.
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
Two ideas:
- Loads of ubersplats along the circle. Downside is that it's visible to enemies, unless if that isn't an issue.
- Create a custom SFX. emitters along a circle, going up some height.

Whats an ubersplant? You mean creating units in a circle to act as the marker?

Creating 36 or 20 units every time a builder is selected and removing it when deselected, is that legit? Using a circle of power as a marker currently, though it still disappears if the hillside is too steep. Think I'm gonna use rally point model for it. ;)

  • For each (Integer A) from 1 to 20, do (Actions)
    • Loop - Actions
      • Unit - Create 1 City Boarder for Player 1 (Red) at ((Position of TownController[0]) offset by 1100.00 towards (18.25 x (Real((Integer A)))) degrees) facing 0.00 degrees
      • Unit - Hide (Last created unit)
      • Custom script: if GetLocalPlayer() == Player(0) then
      • Unit - Unhide (Last created unit)
      • Custom script: endif
- Unhiding removes Locust, funny and bad for me!
- Do I risk desync or any such thing with this?
- Was this what you had in mind?
- What happens if I remove the units?
 
Last edited:
Level 25
Joined
Jul 10, 2006
Messages
3,315
Ubersplat is a texture placed on the ground, like when a building is built it creates that square of bricks/blight/roots. This won't be hidden behind the terrain, because it is the terrain.

Creating units is a bad idea, I think. You could rather create SFX or floating texts.

Yes, it will desync when you hide/unhide units for local player.

What I had in mind is a custom SFX, but I don't know exactly how to make it.

EDIT: Another simple solution to simply remove the health bar: if you look at neutral buildings, they don't have health bars. Take a look at their settings and copy that. I think you just need to add the Invulnerable (neutral) ability.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
EDIT: Another simple solution to simply remove the health bar: if you look at neutral buildings, they don't have health bars. Take a look at their settings and copy that. I think you just need to add the Invulnerable (neutral) ability.

It was something about classification neutral, and it being a building. Sadly real buildings can't build (^^).
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
Can't you at least just grab the order from the building?
Have you tried using the item Ivory Tower ability as a base?

Buildings have no option of "constructing units" in object editor. The only solution would be to use a spell-book and build item ability. Then I would need to fake the cost instead and error messages related to that. If I remember correctly the placing of those pocket-buildings can be a bit strange. But its worth a try.
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
This line crashes the map. Help?
JASS:
call IssueBuildOrderByIdLocBJ(udg_Builder[p_num], udg_BuildingType[i], Location(x2, y2))
Here is the rest.

*EDIT: I don't know how many infinite loops I've been creating lately, oh well... works now! Any feedback on below trigger? :<

JASS:
function OrderConstructionMain takes nothing returns boolean
    local trigger t = GetTriggeringTrigger()
    local real x1 = GetLocationX(GetUnitLoc(GetTriggerUnit()))
    local real y1 = GetLocationY(GetUnitLoc(GetTriggerUnit()))
    local real x2 = GetLocationX(GetOrderPointLoc())
    local real y2 = GetLocationY(GetOrderPointLoc())
    local integer p_num = GetPlayerId(GetTriggerPlayer())
    local unit u
    local integer i = 0
    loop
        exitwhen udg_BuildingOrderID[i] == null
        if (OrderId2StringBJ(GetIssuedOrderIdBJ()) == udg_BuildingOrderID[i]) then
            call DisableTrigger(t)
            if (DistanceBetweenPoints(Location(x1, y1), Location(x2, y2)) > udg_BuildRange) then
                set u = CreateUnit(Player(12), 'n000', x2, y2, 0.0)
                call UnitApplyTimedLifeBJ( 0.10, 'BTLF', u)
                set u = null
            endif
            // Orders dummy to begin construction
            call ShowUnitShow(udg_Builder[p_num])
            call SetUnitPositionLoc(udg_Builder[p_num], Location(x2, y2))
            call IssueBuildOrderByIdLocBJ(udg_Builder[p_num], udg_BuildingType[i], Location(x2, y2))
            call EnableTrigger(t)
            set t = null
        endif
        set i = i + 1
    endloop
    return false
endfunction

//===========================================================================
function InitTrig_Order_Construction takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerAddCondition(t, Condition( function OrderConstructionMain ) )
    set t = null
endfunction
 
Last edited:
If I were just to judge your code, then:

JASS:
function OrderConstructionMain takes nothing returns boolean
    local real x1 = GetUnitX(GetTriggerUnit())
    local real y1 = GetUnitY(GetTriggerUnit())
    local real x2 = GetOrderPointX()
    local real y2 = GetOrderPointY()
    local real dx
    local real dy

    local integer p_num = GetPlayerId(GetTriggerPlayer())
    local unit u
    local integer i = 0
    local integer order = GetIssuedOrderId()

    loop
        exitwhen udg_BuildingOrderID[i] == 0

        if ( order == udg_BuildingOrderID[i] ) then

            set dx = x2 - x1
            set dy = y2 - y1

            if (SquareRoot(dx*dx + dy*dy) > udg_BuildRange) then
                set u = CreateUnit(Player(12), 'n000', x2, y2, 0)
                call UnitApplyTimedLife(u, 'BTLF', 0.1)
            endif

            // Orders dummy to begin construction
            call ShowUnit(udg_Builder[p_num], true)
            call SetUnitPosition(udg_Builder[p_num], x2, y2)

            call DisableTrigger(GetTriggeringTrigger())
            call IssueBuildOrderById(udg_Builder[p_num], udg_BuildingType[i], x2, y2)
            call EnableTrigger(GetTriggeringTrigger())
        endif

        set i = i + 1
    endloop

    set u = null
    return false
endfunction

And call IssueBuildOrderByIdLocBJ(udg_Builder[p_num], udg_BuildingType[i], Location(x2, y2)) should not cause any problems if used properly i.e not orderded outside playable-map bounds.

It's more efficient to increase udg_BuildRange by power of 2 instead of using SquareRoot method. You might want to use this trick.
 
It's taken from your code. I've just improved the script, nothing else.

And, udg_BuildingOrderID == null shoudln't compile in case order is an integer, rather than a handle thus comparing it to null is not appropriate.

And, as it has been written in your code, its clear that you wanted to exitloop whenever unspecified value is approached.

If it's not what you wanted, then your code proceeds in wrong way, not my "improved" version, since it's just an "improved" version. You need to know exactly what you want :)

Trigger handles left alone do leak, but since we are not storing it anywhere and just refering to it via disable/enable method its okey not to null it (we dont have the local to be nulled). Trust me, you do not want to destroy that trigger handle in case your whole script would probably stop working. We destroy/remove things we do not need, and in our situation we still want our trigger to exist.

Players, on the other hand, are not handles you do create. There is a set amount of players: up to 16 and that boundary (0 - 15) is not to be crossed. RemovePlayer() is a function rarely used, mostly, when you defeat a player and he is about to be kicked/leave.
 
I completed the map now, should work for all players and cities now.

Only remaining issue is a bug with hiding the summoner. If you order to build a farm half on blight half on normal ground the summoner will try to build there and fail and not get hidden.

*Reposted link on OP

Then use a timer to check the current order of the unit.
 
Status
Not open for further replies.
Top