• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Unit entering terrain type gets slowed and damaged

Status
Not open for further replies.
Level 14
Joined
Mar 27, 2008
Messages
1,003
Well basically, I need help a trigger that makes it so whenever a unit enters the "ice" tile from the underground tileset, it slows down to 50% speed while on the tile and takes one damage per second.

I have multiple requirements for this trigger.

1. It needs to apply to "Ice (Unbuildable)" from the Underground tileset, and only that.
2. It needs to apply to any Ice that's there when the map first starts up, and any ice that is spawned later in the game. (There is a unit that leaves a trail of ice behind it, that's why)
3. The only conditions are that it not affect Player 12 (Brown), Neutral Hostile or Neutral Passive (the other conditions are specific to my map and I'll have to add them in myself)

The terrain kill systems didn't work when I attempted to implement them, so if anyone would be willing to help, that would be great!
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,207
Dynamically altering regions might be a good way to do it. You can fill a region with all map cells containing the ice and then add and remove cells as required.

As entering and exiting events are handled natively it should be faster than any other trigger solution. Only possible problem is if the entry and exit events do not handle dynamic regions well or if dynamic regions are not supported by the event at all.
 
Level 30
Joined
Nov 29, 2012
Messages
6,637
Well basically, I need help a trigger that makes it so whenever a unit enters the "ice" tile from the underground tileset, it slows down to 50% speed while on the tile and takes one damage per second.

I have multiple requirements for this trigger.

1. It needs to apply to "Ice (Unbuildable)" from the Underground tileset, and only that.
2. It needs to apply to any Ice that's there when the map first starts up, and any ice that is spawned later in the game. (There is a unit that leaves a trail of ice behind it, that's why)
3. The only conditions are that it not affect Player 12 (Brown), Neutral Hostile or Neutral Passive (the other conditions are specific to my map and I'll have to add them in myself)

The terrain kill systems didn't work when I attempted to implement them, so if anyone would be willing to help, that would be great!

Or you can put up in the trigger that when the unit entered the *name of tile*, then make an passive ability that slows enemy by 50% then give that ability to entering unit in the tile.

And if you donw want that to apply to oter players, dont give them the passive ability that slows when entering the ice tile.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,207
There is no "unit entered the *name of tile*" event. The approach I described might let you make one by using the standard unit enters region event (not GUI region as those are actually rects) but that is only if the event behaves well and allows dynamic region adjustments.
 
Level 30
Joined
Nov 29, 2012
Messages
6,637
There is no "unit entered the *name of tile*" event. The approach I described might let you make one by using the standard unit enters region event (not GUI region as those are actually rects) but that is only if the event behaves well and allows dynamic region adjustments.

What I do mean when entering on a terrain type, but if there is none. I'll will have a check on my WE for experimenting on doing this.
 
Level 20
Joined
Jun 27, 2011
Messages
1,864
Would this help?
  • Events
    • Time - Every 0.03 seconds of game time
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      • Loop - Actions
        • Set Temp_Point = (Position of (Picked unit))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Terrain type at Temp_Point) Equal to Underground - Ice
          • Then - Actions
            • *DO ACTIONS HERE*
          • Else - Actions
        • Custom script: call RemoveLocation( udg_Temp_Point )
 
Level 30
Joined
Nov 29, 2012
Messages
6,637
Would this help?
  • Events
    • Time - Every 0.03 seconds of game time
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      • Loop - Actions
        • Set Temp_Point = (Position of (Picked unit))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Terrain type at Temp_Point) Equal to Underground - Ice
          • Then - Actions
            • *DO ACTIONS HERE*
          • Else - Actions
        • Custom script: call RemoveLocation( udg_Temp_Point )

Yeah and in the action add an ability that slows by 50% to the units who will enter the terrain type. And remove slow when out of the terrain type. That will be the action of the trigger.:thumbs_up:
 
Level 14
Joined
Mar 27, 2008
Messages
1,003
Would this help?
  • Events
    • Time - Every 0.03 seconds of game time
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      • Loop - Actions
        • Set Temp_Point = (Position of (Picked unit))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Terrain type at Temp_Point) Equal to Underground - Ice
          • Then - Actions
            • *DO ACTIONS HERE*
          • Else - Actions
        • Custom script: call RemoveLocation( udg_Temp_Point )

Yep, this did the trick! Thank you so much! + Rep
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Would this help?
  • Events
    • Time - Every 0.03 seconds of game time
  • Conditions
  • Actions
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
      • Loop - Actions
        • Set Temp_Point = (Position of (Picked unit))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Terrain type at Temp_Point) Equal to Underground - Ice
          • Then - Actions
            • *DO ACTIONS HERE*
          • Else - Actions
        • Custom script: call RemoveLocation( udg_Temp_Point )

A few comments.

The interval could be adjusted to 0.1 or something like that, it might not need to update that often.
Null the location after removing it:
  • Custom script: set udg_Temp_Point = null
The *Do actions here* could give the unit the buff if the unit doesn't have it already.
The empty else could remove the buff if the unit has it.
  • Custom script: call UnitRemoveAbility(GetEnumUnit(), 'B000')
Replace the B000 with the raw code of the buff to remove it instantly.
Finally, you might not need to pick every unit in the map periodically, only units you want to check.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,207
Null the location after removing it:
This is a pointless operation that wastes thousands of CPU cycles.

The only time you may want to null it is at the end of the function (the trigger) but even then any kind of nulling is totally unnecessary as the maximum possible handle leak is 1 and only if 0 valid units exist on the map (in which case the disabling trigger could null it). Otherwise a single handle will be blocked from being recycled for 0.03 (or 0.1) seconds which is not a leak.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
DSG, then how would you explain that the the memory usage of WC3 constantly increases when I don't null the loc here, but it doesn't increase at all if I do null it.

JASS:
library leakTest initializer onInit
    globals
        private timer t = CreateTimer()
        private constant integer LOCS = 5
        private integer c = 0
    endglobals

    private function leaks takes nothing returns nothing
        local integer i = LOCS
        
        loop
            exitwhen i == 0
            set udg_loc = Location(0,0)
            call RemoveLocation(udg_loc)
            set c = c + 1
            set i = i - 1
        endloop
        //set udg_loc = null
    endfunction
    
    private function pauseResume takes nothing returns nothing
        if ModuloInteger(GetTriggerExecCount(GetTriggeringTrigger()) , 2) == 1 then
            call BJDebugMsg("started")
            call TimerStart(t, 0.01, true, function leaks)
        else
            call BJDebugMsg("paused, " + "locs created: " + I2S(c))
            call PauseTimer(t)
        endif
    endfunction

    private function onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterPlayerEvent(t, Player(0), EVENT_PLAYER_END_CINEMATIC)
        call TriggerAddAction(t, function pauseResume)
    endfunction
endlibrary

EDIT: I might have worder myself badly as the loc doesn't need to be nulled after each removeLoc, but at the end of the trigger.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,207
DSG, then how would you explain that the the memory usage of WC3 constantly increases when I don't null the loc here, but it doesn't increase at all if I do null it.
If the leak is really caused by a garbage collection error then that script should not. If it still does leak then a lot of vJASS systems that are approved in the spell section must also leak.

The big question to ask is "surely someone would have noticed by now?".

EDIT: I might have worder myself badly as the loc doesn't need to be nulled after each removeLoc, but at the end of the trigger.
That would be the optimum time to perform it. However as global variables are persistent there is no reason why it should make a difference being performed at any time.

If what you say is true, that raises the huge question "What is JASS doing to make it true?". It clearly cannot be a garbage collector reference counter bug like locals suffer from.
 
Status
Not open for further replies.
Top