• 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.

[Trigger] oil trigger

Status
Not open for further replies.
Level 13
Joined
Sep 24, 2007
Messages
1,023
well i ahve a few questions they are:
can u make it so that mana drians whenever a unit is moving


secondly
can u make it so that if a unit has mana it gives mana to other units while drianing its own

and lastly
can u make it so if a unit has no mana it cant move??

if u could answer my question it would be very much liked. btw the mana is the oil
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
There's probably a more efficient way, but here's my first thought:

Object data required:
Speed bonus ability with 2 levels: level 1 does nothing, level 2 gives a LOT of speed bonus
Set all units that require oil movement speed to zero. Add the Speed Bonus ability to their abilities.

Gameplay constants:
Change the minimum speed allowed to 0, maximum speed can be at 522.

Triggers required:
  • Turn off movement
  • Events
    • Game - every 1 second of gametime
  • Conditions
  • Actions
    • Set "TempUnitGroup" = Units on playable map area matching: matching unit is mechanical (I'm assuming organic creatures don't use oil... duh) equal to true
    • Unit Group - pick every unit in unit group and do multiple actions
      • Loop - actions
        • If (all conditions are true) then do...
          • If - Conditions
            • (picked unit)'s mana is 0
          • Then - Actions
            • set level of (SpeedBonusAbility) on (picked unit) to 1
          • Else - Actions
            • set level of (SpeedBonusAbility) on (picked unit) to 2
    • Custom script: call DestroyGroup(udg_TempUnitGroup)
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
  • Untitled Trigger 003
    • Events
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • ((Triggering unit) is Mechanical) Equal to True
      • (Mana of (Triggering unit)) Equal to 0.00
    • Actions
      • Unit - Order (Triggering unit) to Stop
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Right, so instead make something liek this

  • Untitled Trigger 003
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Custom script: set bj_wantDestoryGroup = true
      • Unit Group - Pick every unit in (Units in (Playable map area) matching ((((Matching unit) is Mechanical) Equal to True) and ((Mana of (Matching unit)) Equal to 0.00))) and do (Actions)
        • Loop - Actions
          • Unit - Order (Picked unit) to Stop
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Questions 1 and 3 were answerd.

For 2 we need more info.
Will it always drain mana, even if no unit is nearby ?
Will it drain mana baised on how much units are nearby ?

The custom script destroys the group (which leak) right after it finishes it actions and thus removing the leak.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Oh im sorry, I didn't notice Eleandor answerd the same question (by the way, his sollution is way better).

Taking oil when moving will require some calculations and timers (and JASS...).
Something like - every 0.02 get the location the unit was last 0.02, get the new location, if it is bigger then 0 then set mana to -distance between them.

Maybe I will make it soon, I kinda wanna play now though (thats really special this last few weeks lol...).

Another question, would giving mana (by a oil truck or whatever it is) need to be enabled with a ability or will it automaticly give it ? In my opinion it will kinda be stupid if its automatic but its your map.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
ok, this is the code that will reduce mechanic units mana when they move.
Im not sure if it works, it didn't give me any compile errors and I don't see any reason it won't work though.

Try it out.

Warning! this code requires Kattana's Handle Vars code and a little script I made, they are both down after my code.
You will need to put them inside your header.

Create a trigger called "NewTrigger", now change it to custom script, delete whats there and copy the code below, then you can name that trigger with whatever name you want.

JASS:
// This will reduce the mana of any mechanical unit on the map upon moving.
// The actual value is the distance that unit moves within 0.2 seconds.
// If you want to change that value, see the comment in 13 lines.

function mechanicCon takes nothing returns boolean
    return IsUnitType(GetEnumUnit(),UNIT_TYPE_MECHANICAL)    
endfunction
function mecahnictimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit whichUnit = GetHandleUnit(t, "whichUnit")
    local real x = GetHandleReal(t, "x")
    local real y = GetHandleReal(t, "y")
    local real newx = GetUnitX(whichUnit)
    local real newy = GetUnitY(whichUnit)
    local real distance = DistanceBetweenPointsXY(x, y, newx, newy)
    local real mana = GetUnitStatePercent(whichUnit, UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
    call SetUnitState(whichUnit, UNIT_STATE_MANA, mana-distance) // if you want to reduce or raise the value, just make it something like "mana-distance*20" or "mana-distance/20"
    call FlushHandleLocals(t)
    call DestroyTimer(t) 
    set t = null
    set whichUnit = null
endfunction
function mechanic takes nothing returns nothing
    local timer t = CreateTimer()
    local group g = CreateGroup()
    local unit whichUnit
    local real x
    local real y
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Condition(function mechanicCon)) 
    loop
        set whichUnit = FirstOfGroup(g)
        exitwhen whichUnit == null
        call GroupRemoveUnit(g, whichUnit)
        set x = GetUnitX(whichUnit)
        set y = GetUnitY(whichUnit)
        call SetHandleReal(t, "x", x)
        call SetHandleReal(t, "y", y)
        call SetHandleHandle(t, "whichUnit", whichUnit)
        call TimerStart(t, 0.2, true, function mecahnictimer)
    endloop
    set t = null
    call DestroyGroup(g)
    set g = null
    set whichUnit = null 
endfunction

//==== Init Trigger NewTrigger ====
function InitTrig_NewTrigger takes nothing returns nothing
    set gg_trg_NewTrigger = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic( gg_trg_NewTrigger, 0.20 )
    call TriggerAddAction(gg_trg_NewTrigger, function mechanic)
endfunction


Kattanas Handle Vars

JASS:
// ===========================
function H2I takes handle h returns integer
    return h
    return 0
endfunction

// ===========================
function LocalVars takes nothing returns gamecache
    // Replace InitGameCache("jasslocalvars.w3v") with a global variable!!
    return InitGameCache("jasslocalvars.w3v")
endfunction

function SetHandleHandle takes handle subject, string name, handle value returns nothing
    if value==null then
        call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreInteger(LocalVars(), I2S(H2I(subject)), name, H2I(value))
    endif
endfunction

function SetHandleInt takes handle subject, string name, integer value returns nothing
    if value==0 then
        call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreInteger(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function SetHandleBoolean takes handle subject, string name, boolean value returns nothing
    if value==false then
        call FlushStoredBoolean(LocalVars(),I2S(H2I(subject)),name)
    else
        call StoreBoolean(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function SetHandleReal takes handle subject, string name, real value returns nothing
    if value==0 then
        call FlushStoredReal(LocalVars(), I2S(H2I(subject)), name)
    else
        call StoreReal(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function SetHandleString takes handle subject, string name, string value returns nothing
    if value==null then
        call FlushStoredString(LocalVars(), I2S(H2I(subject)), name)
    else
        call StoreString(LocalVars(), I2S(H2I(subject)), name, value)
    endif
endfunction

function GetHandleHandle takes handle subject, string name returns handle
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleInt takes handle subject, string name returns integer
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleBoolean takes handle subject, string name returns boolean
    return GetStoredBoolean(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleReal takes handle subject, string name returns real
    return GetStoredReal(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleString takes handle subject, string name returns string
    return GetStoredString(LocalVars(), I2S(H2I(subject)), name)
endfunction

function GetHandleUnit takes handle subject, string name returns unit
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleTimer takes handle subject, string name returns timer
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleTrigger takes handle subject, string name returns trigger
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleEffect takes handle subject, string name returns effect
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleGroup takes handle subject, string name returns group
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleLightning takes handle subject, string name returns lightning
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction
function GetHandleWidget takes handle subject, string name returns widget
    return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
    return null
endfunction

function FlushHandleLocals takes handle subject returns nothing
    call FlushStoredMission(LocalVars(), I2S(H2I(subject)) )
endfunction


Distance between coordinates (put also this in your header)

JASS:
//****************************************************************************************
//               Distance between two points using coordinates
// call DistanceBetweenPointsXY(real x1, real y1, real x2, real y2)

function DistanceBetweenPointsXY takes real x1, real y1, real x2, real y2 returns real
    local real dx = oldx - x
    local real dy = oldy - y
    return SquareRoot(dx * dx + dy * dy)
endfunction


I hope this works.


Oh and what last question, if for example the oil truck has 200 mana and 20 units around it, now it would want to give 20 mana to each but ot hasn't enough.
Should it give to as much units as it can 20 mana, or should it give all the units mana but less (10 in this case) ?
 
Level 19
Joined
Sep 4, 2007
Messages
2,826
I've had a problem simulare to yours. Here was my solution:
If you are making a tank which uses fuel. You could add make when turned an ability which turns off the engine saving fuel and makes the unit stop. And add an ability which turns the engine on again which makes the engine use fuel again.
  • Save Fuel
    • Events
      • Unit - A unit Begins channeling an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to |Cffff0000Shut down the engine
          • (Ability being cast) Equal to |Cff00ff00Turn on the engine
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to |Cffff0000Shut down the engine
        • Then - Actions
          • Unit - Remove |Cffff0000Shut down the engine from (Triggering unit)
          • Unit - Add |Cff00ff00Turn on the engine to (Triggering unit)
          • Unit - Remove classification of An Ancient from (Triggering unit)
          • Unit - Set (Triggering unit) movement speed to 1.00
        • Else - Actions
          • Unit - Remove |Cff00ff00Turn on the engine from (Triggering unit)
          • Unit - Add |Cffff0000Shut down the engine to (Triggering unit)
          • Unit - Add classification of An Ancient to (Triggering unit)
          • Unit - Set (Triggering unit) movement speed to 120.00
To bad you can't set Unit - Set (Triggering unit) movement speed to 0.00 :(

  • Refresh Multiboard Fuel
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) matching ((((Matching unit) is Mechanical) Equal to True) and (((Matching unit) is An Ancient) Equal to True))) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • MultiboardFuel[(Player number of (Owner of (Picked unit)))] Greater than 0
            • Then - Actions
              • Unit - Set (Picked unit) movement speed to 120.00
              • Set MultiboardFuel[(Player number of (Owner of (Picked unit)))] = (MultiboardFuel[(Player number of (Owner of (Picked unit)))] - 1)
              • Multiboard - Set the text for (Last created multiboard) item in column 7, row ((Player number of (Owner of (Picked unit))) + 1) to (MultiboardColor[(Player number of (Owner of (Picked unit)))] + (String(MultiboardFuel[(Player number of (Owner of (Picked unit)))])))
            • Else - Actions
              • Unit - Set (Picked unit) movement speed to 1.00
              • Multiboard - Set the text for (Last created multiboard) item in column 7, row ((Player number of (Owner of (Picked unit))) + 1) to (MultiboardColor[(Player number of (Owner of (Picked unit)))] + (String(MultiboardFuel[(Player number of (Owner of (Picked unit)))])))
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Hm.. That is strange... I am using the trigger for a civilization map I made, with a lot of units and it works perfectly-

Then I don't think it works like you told it to work.

This line "Set MultiboardFuel[(Player number of (Owner of (Picked unit)))]" allows you to assign a variable for each player, not for each unit.


Ghostwolf, In my experience (though I can be wrong), using kattana's handle vars make a system perform badly when used on huge scale, such as all mechanical units on the map...

It does because its using Game Cache (don't ask my why using it is slow though, I won't have any answer ^^), I guess I could just use a wait of 0.3 instead of a timer :p

[Important-Edit] I got it fixed, just going to check a little what can be done better and then ill upload here the map.

Oh and about using Waits, thats actually not possible because they stop the code from working untill the wait is finished, which seems to not be the case with timers.
 
Last edited:
Level 19
Joined
Sep 4, 2007
Messages
2,826
Then I don't think it works like you told it to work.

This line "Set MultiboardFuel[(Player number of (Owner of (Picked unit)))]" allows you to assign a variable for each player, not for each unit.

Because I want to show on the multiboard the amount of value of the fuel variable - the amount of picked units owner of the variable every 1 second.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
I don't think you got what the question is.

Mana = Fuel, if the unit moves, decrease Fuel (mana) according to how much he moves.

Therefor, Fuel is a diffrent variable for each unit that you want (mechanical in this case). Now, this can't be done with globals unless you make them arrayed and make a very annoying trigger such as this (it will still not remove the mana, only assign variables)

  • Set unitGroup = (Units of type Footman)
  • For each (Integer A) from 1 to (Number of units in unitGroup), do (Actions)
    • Loop - Actions
      • Set Unit[(Integer A)] = (Random unit from unitGroup)
      • Unit Group - Remove Unit[(Integer A)] from unitGroup

Now you need to compare distances between a point where the unit is, to a point where he will be in some time (lets say in half a second), how exacly would you do that ?

It would require so much triggers and work im not even going to try to think about it.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Ok the code now works perfectly.

You would probably like to change the mana values going down though (it goes down pretty fast at the moment), there is a line inside telling you what to change.
I think "mana-distance/50" or something around it would suit your needs.

You still need those 2 codes I put in my previous code-giving.
I also put it in a map, it is attached to this post (look down).

JASS:
// This will reduce the mana of any mechanical unit on the map upon moving.
// The actual value is the distance that unit moves within 0.2 seconds.
// If you want to change that value, see the comment in 13 lines.

function mechanicCon takes nothing returns boolean
    return IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL) == true    
endfunction
function mecahnictimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit whichUnit = GetHandleUnit(t, "whichUnit")
    local real x = GetHandleReal(t, "x")
    local real y = GetHandleReal(t, "y")
    local real distance = DistanceBetweenPointsXY(x, y, GetUnitX(whichUnit), GetUnitY(whichUnit))
    local real mana = GetUnitState(whichUnit, UNIT_STATE_MANA )
    if distance > 0 then
        call SetUnitState(whichUnit, UNIT_STATE_MANA, mana-distance/20) // if you want to reduce or raise the value, just make it something like "mana-distance*20" or "mana-distance/20"
    endif
    call FlushHandleLocals(t)
    call DestroyTimer(t) 
    set t = null
    set whichUnit = null
endfunction
function mechanic takes nothing returns nothing
    local timer t = CreateTimer()
    local group g = CreateGroup()
    local unit whichUnit
    local real x
    local real y
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Condition(function mechanicCon)) 
    loop
        set t = null
        set whichUnit = FirstOfGroup(g)
        exitwhen whichUnit == null
        call GroupRemoveUnit(g, whichUnit)
        set t = CreateTimer()
        call SetHandleReal(t, "x", GetUnitX(whichUnit))
        call SetHandleReal(t, "y", GetUnitY(whichUnit))
        call SetHandleHandle(t, "whichUnit", whichUnit)
        call TimerStart(t, 0.2, false, function mecahnictimer)
    endloop
    call DestroyGroup(g)
    set g = null
    set whichUnit = null 
endfunction

//==== Init Trigger NewTrigger ====
function InitTrig_NewTrigger takes nothing returns nothing
    set gg_trg_NewTrigger = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic( gg_trg_NewTrigger, 0.20 )
    call TriggerAddAction(gg_trg_NewTrigger, function mechanic)
endfunction
 

Attachments

  • Mechanic Mana reducer.w3x
    15.5 KB · Views: 40
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
Well whatever, here's the new code (if you want diffrent speed for diffrent unit types tell me).

JASS:
// This will reduce the mana of any mechanical unit on the map upon moving.
// The actual value is the distance that unit moves within 0.2 seconds.
// If you want to change that value, see the comment in 13 lines.

function mechanicCon takes nothing returns boolean
    return IsUnitType(GetFilterUnit(),UNIT_TYPE_MECHANICAL) == true    
endfunction
function mecahnictimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit whichUnit = GetHandleUnit(t, "whichUnit")
    local real x = GetHandleReal(t, "x")
    local real y = GetHandleReal(t, "y")
    local real distance = DistanceBetweenPointsXY(x, y, GetUnitX(whichUnit), GetUnitY(whichUnit))
    local real mana = GetUnitState(whichUnit, UNIT_STATE_MANA )
    if distance > 0 then
        call SetUnitState(whichUnit, UNIT_STATE_MANA, mana-distance/20) // if you want to reduce or raise the value, just make it something like "mana-distance*20" or "mana-distance/20"
    endif 
    if GetUnitState(whichUnit, UNIT_STATE_MANA ) <= 0 then
        call SetUnitMoveSpeed(whichUnit, 0)    
    else
        call SetUnitMoveSpeed(whichUnit, 100) // change this 100 to the speed you want
    endif 
    call FlushHandleLocals(t)
    call DestroyTimer(t) 
    set t = null
    set whichUnit = null
endfunction
function mechanic takes nothing returns nothing
    local timer t = CreateTimer()
    local group g = CreateGroup()
    local unit whichUnit
    local real x
    local real y
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Condition(function mechanicCon)) 
    loop
        set t = null
        set whichUnit = FirstOfGroup(g)
        exitwhen whichUnit == null
        call GroupRemoveUnit(g, whichUnit)
        set t = CreateTimer()
        call SetHandleReal(t, "x", GetUnitX(whichUnit))
        call SetHandleReal(t, "y", GetUnitY(whichUnit))
        call SetHandleHandle(t, "whichUnit", whichUnit)
        call TimerStart(t, 0.2, false, function mecahnictimer)
    endloop
    call DestroyGroup(g)
    set g = null
    set whichUnit = null 
endfunction

//==== Init Trigger NewTrigger ====
function InitTrig_NewTrigger takes nothing returns nothing
    set gg_trg_NewTrigger = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic( gg_trg_NewTrigger, 0.20 )
    call TriggerAddAction(gg_trg_NewTrigger, function mechanic)
endfunction


[Edit] Ok this doesn't work for some unknown reason.
 
Status
Not open for further replies.
Top