1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Dismiss Notice
  5. The Highway to Hell has been laid open. Come along and participate in the 5th Special Effect Contest.
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] Rematch Trigger

Discussion in 'Triggers & Scripts' started by chaoslord301, Dec 24, 2012.

  1. chaoslord301

    chaoslord301

    Joined:
    Sep 18, 2007
    Messages:
    105
    Resources:
    0
    Resources:
    0
    I haven't touched WC3 in a while but decided to give it a whirl after some friends got back on. I decided to dust off an old project (make it compatible with 1.24+). When I was working on this project I knew a little bit of JASS, but now not so much. I also decided to make a Rematch function because the map is such a short battle and I thought it would be a be a good way to get back into scripting. I also decided to try to make this trigger easily transferrable to other maps.

    The type of maps that this trigger is intended for is the basic "Two Armies facing each other; you win by killing their commander type."

    This is the first idea I had when I thought of how to go about this, but I realize it probably is quite inefficient and full of leaks.

    I used arrays to save information about the unit (position, type, owner) and the code is mostly commented to tell what is supposed to happen (and random comments to myself). Here is the code:

    Code (vJASS):
    library Rematch initializer init requires UnitRecycler
    globals
        constant integer LeaderType1 = 'H000' //Unit Type Id for Leader 1 (Cao Cao)
        constant integer LeaderType2 = 'H007' //Unit Type Id for Leader 2 (Ma Chao)
       
        real array UnitX
        real array UnitY
        real array UnitF
        integer array GameId //Type of unit
        integer array UnitOwner
       
        integer loopsave = 0 //used later on for creating units
        integer loopnum = 0 //will become how many intial units there are
        constant integer time = 10 //time between units being created (EX:) Player 1 Units, Wait 10 sec, Player 2 Units
        constant boolean SwitchSides = true //work this in
        group iGroup = CreateGroup() //group that initial units are added to (or maybe just hereos)
    endglobals
    //---
    function HeroIndex takes nothing returns boolean
        return IsUnitType(GetEnumUnit(), UNIT_TYPE_HERO)
    endfunction

    function RematchIndex takes nothing returns nothing //does not index heroes
        call GroupAddGroup(GetUnitsInRectAll(bj_mapInitialPlayableArea), iGroup)
        loop
        exitwhen loopnum > CountUnitsInGroup(iGroup)
            set UnitX[loopnum] = GetUnitX(GetEnumUnit())
            set UnitY[loopnum] = GetUnitY(GetEnumUnit())
            set UnitF[loopnum] = GetUnitFacing(GetEnumUnit())
            set GameId[loopnum] = S2I(GetUnitName(GetEnumUnit()))
            set UnitOwner[loopnum] = GetPlayerId(GetOwningPlayer(GetEnumUnit()))
            set loopnum = loopnum + 1
        endloop
    endfunction

    private function init takes nothing returns nothing
        local trigger Rematch = CreateTrigger()
        call TriggerRegisterTimerEvent(Rematch, 0.1, false)
        call TriggerAddAction( Rematch, function RematchIndex)
        set Rematch = null
    endfunction
    //---

    function RematchActions takes nothing returns nothing
        //Create the units
        local integer i = loopsave
        loop
            exitwhen loopsave > loopsave + 30 //only 30 units will be created at one time
            exitwhen loopsave > loopnum
            call CreateUnitEx(Player(UnitOwner[i]), GameId[i], UnitX[i], UnitY[i], UnitF[i])
            set loopsave = loopsave + 1
            set i = i+1
        endloop
        set i = 0
        if (loopsave > loopnum) then //check to see if all units have been created
            set loopsave = 0
        endif
    endfunction

    function RematchTimeOut takes nothing returns nothing //change so maybe wait is outside loop
        //Wait between players getting their units created
        loop
            exitwhen loopsave > loopnum
            call RematchActions()
            call TriggerSleepAction(time)
        endloop
    endfunction

    function RecycleActions takes nothing returns nothing
        call RemoveUnitEx(GetEnumUnit())
    endfunction

    function RecycleSetUp takes nothing returns nothing
        //Recycle All Units in map
        call ForGroupBJ(GetUnitsInRectAll(bj_mapInitialPlayableArea), function RecycleActions)
        call RematchActions()
    endfunction

    function LeaderCheck takes nothing returns nothing
        local integer uId = GetUnitTypeId(GetDyingUnit())
        if uId == LeaderType1 or uId == LeaderType2 then
            call RecycleSetUp()
        endif
    endfunction

    //===========================================================================
    function InitTrig_Rematch_Lib takes nothing returns nothing
        local trigger Rematch = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( Rematch, EVENT_PLAYER_UNIT_DEATH )
        call TriggerAddAction( Rematch, function LeaderCheck )
        //set Rematch = null
    endfunction

    endlibrary
     


    I combined 2 trigs into one (I was working on two different ways of trying this, but decided to ditch one of them but wanted some of the code for the one you see now.

    Now for the actual problems: I get most of the units "indexed", just not the heroes (as far as I know). When one of the commanders die, the Recycling kicks in and all normal units are "removed from the map" (again, not heroes), but the units don't ever get created. The map has about 320 units (and it is considered small for this type of map) so I didn't want to create all 320 at once for fear of lag. I decided that incrementing in 30 unit groups or so would be the best bet. The "time" variable dictates how much time is elapsed before each interval of unit creation. The boolean variable is whether or not the map maker wants teams to "switch sides", but I haven't written the code for that yet.

    As I said earlier I am rusty (and really never good to begin with) and I know this code is inefficient and leaky (I will wory about the leaks after I get it actually working). I am sure there are still some things I forgot to explain so just ask (uses moyack's Unit Recycler Library). Thanks in advance.
     
  2. deathismyfriend

    deathismyfriend

    Joined:
    Oct 24, 2012
    Messages:
    6,528
    Resources:
    14
    Spells:
    12
    Tutorials:
    2
    Resources:
    14
    im new to this so im not the best at this but i do have a few things tht i saw tht might help u if they cant solve ur problem mybe the can make it a little more efficient and hopefully someone can help u umm first major thing i noticed

    Code (vJASS):
      exitwhen loopsave > loopsave + 30 //only 30 units will be created at one time


    i would take tht line out of there it might be crashing the loop because tht condition can never be met (when u do loopsave = loopsave + 1 like at the end of ur loop its changing the variable so say its 1 to start itll be like this (1>1+30)
    but when u add like at the end of the loop itll be (2>2+30) so it will never end
    i would change it to this

    Code (vJASS):
      exitwhen loopsave > 30 //only 30 units will be created at one time
    and take out the line below it tht says exitwhen

    other thing is the call triggersleep action change tht to a polledwait (its faster and i believe less bugged up ( i may be wrong about less bugs tho))

    the unit facing variable u have i would just get rid of tht and make them face 0 every time but tht is preference i guess

    to set loopsave back to 0 just when u create loopsave do integer loopsave = 0 tht way whenever the trigger fires it will hit 0 so the loop after the unit spawn is not needed

    ok for the last ( i believe its the last ) thing i would change

    Code (vJASS):
    function RematchTimeOut takes nothing returns nothing //change so maybe wait is outside loop
        //Wait between players getting their units created
        loop
            exitwhen loopsave > loopnum
            call RematchActions()
            call TriggerSleepAction(time)
        endloop
    endfunction


    i would get rid of tht and just change the event time for the whole trigger to a periodic time and just create a condition tht says units on map = 330 then set true and let the condition only run the trigger if its true ( this way will let the trigger run as soon as the units on map get below 330 so there will always be over 330 units )

    i hope this helped if u need any more debugging u could always try to generate messages for urself in the code so u can see wat is working and wat isnt working and gl