Rect Problem (Basic vJass)

WarLuvr3393

Hmmm...too many things to play (WoW, COD4, WC3)
Reaction score
54
Hello everyone. I'm creating a type of infantry map that has two sides. When a unit of that side is created, control is transferred to the computer of that team and is sent to attack 1 of 3 locations: west side, east side and center. The default attack location is the center. Now, using a command, a player can either type in "-attack left", "-attack right", or "attack middle". Now, when I type in "-attack left/right", the units travel to their respective locations. However, whenever I type nothing or "-attack middle" the footman go to the center of the map and then run back to their barracks. Here is this script:

JASS:
globals
  rect North_Attack = gg_rct_Blue_Castle
endglobals

function North_Attack_Order takes nothing returns nothing
local string s = GetEventPlayerChatString()

  if SubString(s, 8, 12) == "left" then
    set North_Attack = gg_rct_South_Left
    call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "|cff80CC33All trained units will now attack the west side of the Southern Empire.")
  elseif SubString(s, 8, 13) == "right" then
    set North_Attack = gg_rct_South_Right
    call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "|cff80CC33All trained units will now attack the east side of the Southern Empire.")
  elseif SubString(s, 8, 14) == "middle" then
    set North_Attack = gg_rct_Blue_Castle
    call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "|cff80CC33All trained units will now attack the center of the Southern Empire.")
  endif
endfunction

function North_Unit_Movement takes nothing returns nothing
local location l
  call SetUnitOwner(GetTrainedUnit(),Player(0),false)
  set l = GetRectCenter(North_Attack)
  call IssuePointOrderLoc(GetTrainedUnit(), "attack", l)
  call RemoveLocation(l)
  set l = null
endfunction

function InitTrig_North_Sending takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger s = CreateTrigger()
local integer i = 2
  loop
    exitwhen i > 6
    call TriggerRegisterPlayerUnitEventSimple(t,Player(i),EVENT_PLAYER_UNIT_TRAIN_FINISH)
    call TriggerRegisterPlayerChatEvent(s, Player(i), "-attack", false)
    set i = i + 1
  endloop
  call TriggerAddAction(t, function North_Unit_Movement)
  call TriggerAddAction(s, function North_Attack_Order)
endfunction


I did this for both sides so this may not work for the other side as well. The "gg_rct_Blue_Castle" is a region around the blue castle, or in the case, the place where the footman attack the center.

Any ideas? Thanks in advanced.

~Spiky (WarLuvr)
 

Sooda

Diversity enchants
Reaction score
318
JASS looks fine, player 1 units should not run back if you haven't set their acquisition range huge so they spot enemy and try to attack it. Don't you have triggers which reorders units when they enter region 'North_Attack'?

EDIT:
Wanted to make my own version of it:
JASS:
 scope SetUnitRallyPoint initializer Init
      globals
           private constant string msgStart = "|cff80CC33All trained units will now attack the "
           private constant string msgEnd = " of the Southern Empire.|r"

           private string msg = ""
           private string subMsg = ""
           private string array path

           private unit whichUnit = null
           private integer rectIndex = 0

           private real array rectX
           private real array rectY
      endglobals

      private function OrderUnit takes nothing returns boolean
           set whichUnit = GetTrainedUnit()

           call SetUnitOwner(whichUnit,Player(0),false)
           call IssuePointOrder(whichUnit,"attack",rectX[rectIndex],rectY[rectIndex])
      endfunction



      private function SetUnitRallyPoint takes nothing returns boolean          
           set msg = GetEventPlayerChatString()
           set subMsg = SubString(msg,7,StringLength(msg))
      

           if subMsg == "left" then
                set North_Attack = gg_rct_South_Left
                set rectIndex = 0
           elseif subMsg == "right" then
                set North_Attack = gg_rct_South_Right
                set rectIndex = 1
           elseif subMsg == "middle" then
                set North_Attack = gg_rct_Blue_Castle
                set rectIndex = 2
           else
                call BJDebugMsg("Bad string: " + subMsg)
                return false
           endif

           call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, msgStart + subMsg + msgEnd)
           return false
      endfunction
      
      private constant function SafeBoolexpr takes nothing returns boolean
           return true
      endfunction

      private function Init takes nothing returns nothing
           local trigger chatTrig = CreateTrigger()
           local trigger orderTrig = CreateTrigger()

           local boolexpr whichBoolexpr = Condition( function SafeBoolexpr)
           local integer index = 2

           loop
                     call TriggerRegisterPlayerUnitEvent(orderTrig, Player(index), EVENT_PLAYER_UNIT_TRAIN_FINISH, whichBoolexpr)
                     call TriggerRegisterPlayerChatEvent(chatTrig, Player(index), "-attack ", false)
                exitwhen index == 6
                set index = index + 1
           endloop

           call TriggerAddAction(orderTrig, function OrderUnit)
           call TriggerAddCondition(chatTrig, Condition( function SetUnitRallyPoint))

           set path[0] = "west side"
           set path[1] = "east side"
           set path[2] = "center"

           set rectX[0] = GetRectCenterX(gg_rct_South_Left)
           set rectY[0] = GetRectCenterY(gg_rct_South_Left)

           set rectX[1] = GetRectCenterX(gg_rct_South_Right)
           set rectY[1] = GetRectCenterY(gg_rct_South_Right)

           set rectX[2] = GetRectCenterX(gg_rct_Blue_Castle)
           set rectY[2] = GetRectCenterY(gg_rct_Blue_Castle)
      endfunction
endscope

String display could be optimized even more (like you did), but currently it looks nicer. I made it freehand and hope there aren't any syntax errors, maybe constant and private need to be other way around, don't remember exactly.
 

WarLuvr3393

Hmmm...too many things to play (WoW, COD4, WC3)
Reaction score
54
JASS looks fine, player 1 units should not run back if you haven't set their acquisition range huge so they spot enemy and try to attack it. Don't you have triggers which reorders units when they enter region 'North_Attack'?

EDIT:
Wanted to make my own version of it:
JASS:
 scope SetUnitRallyPoint initializer Init
      globals
           private constant string msgStart = "|cff80CC33All trained units will now attack the "
           private constant string msgEnd = " of the Southern Empire.|r"

           private string msg = ""
           private string subMsg = ""
           private string array path

           private unit whichUnit = null
           private integer rectIndex = 0

           private real array rectX
           private real array rectY
      endglobals

      private function OrderUnit takes nothing returns boolean
           set whichUnit = GetTrainedUnit()

           call SetUnitOwner(whichUnit,Player(0),false)
           call IssuePointOrder(whichUnit,"attack",rectX[rectIndex],rectY[rectIndex])
      endfunction



      private function SetUnitRallyPoint takes nothing returns boolean          
           set msg = GetEventPlayerChatString()
           set subMsg = SubString(msg,7,StringLength(msg))
      

           if subMsg == "left" then
                set North_Attack = gg_rct_South_Left
                set rectIndex = 0
           elseif subMsg == "right" then
                set North_Attack = gg_rct_South_Right
                set rectIndex = 1
           elseif subMsg == "middle" then
                set North_Attack = gg_rct_Blue_Castle
                set rectIndex = 2
           else
                call BJDebugMsg("Bad string: " + subMsg)
                return false
           endif

           call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, msgStart + subMsg + msgEnd)
           return false
      endfunction
      
      private constant function SafeBoolexpr takes nothing returns boolean
           return true
      endfunction

      private function Init takes nothing returns nothing
           local trigger chatTrig = CreateTrigger()
           local trigger orderTrig = CreateTrigger()

           local boolexpr whichBoolexpr = Condition( function SafeBoolexpr)
           local integer index = 2

           loop
                     call TriggerRegisterPlayerUnitEvent(orderTrig, Player(index), EVENT_PLAYER_UNIT_TRAIN_FINISH, whichBoolexpr)
                     call TriggerRegisterPlayerChatEvent(chatTrig, Player(index), "-attack ", false)
                exitwhen index == 6
                set index = index + 1
           endloop

           call TriggerAddAction(orderTrig, function OrderUnit)
           call TriggerAddCondition(chatTrig, Condition( function SetUnitRallyPoint))

           set path[0] = "west side"
           set path[1] = "east side"
           set path[2] = "center"

           set rectX[0] = GetRectCenterX(gg_rct_South_Left)
           set rectY[0] = GetRectCenterY(gg_rct_South_Left)

           set rectX[1] = GetRectCenterX(gg_rct_South_Right)
           set rectY[1] = GetRectCenterY(gg_rct_South_Right)

           set rectX[2] = GetRectCenterX(gg_rct_Blue_Castle)
           set rectY[2] = GetRectCenterY(gg_rct_Blue_Castle)
      endfunction
endscope

String display could be optimized even more (like you did), but currently it looks nicer. I made it freehand and hope there aren't any syntax errors, maybe constant and private need to be other way around, don't remember exactly.

Why are you using scopes? Is it really even necessary?
 

Vexorian

Why no custom sig?
Reaction score
187
rect North_Attack = gg_rct_Blue_Castle

A whole init function initializes the gg_rct_Blue_Castle rect, you can't just use it in the globals initialization stage.
 

Sooda

Diversity enchants
Reaction score
318
> Why are you using scopes? Is it really even necessary?

Scopes seems cool, it will move all these functions in scope to down in a function list (map header). Library for this is overkill, just my personal choice.
Vexorian solved your problem. Set 'North_Attack' equal to 'gg_rct_Blue_Castle ' in your initialize function (InitTrig_North_Sending).
 

quraji

zap
Reaction score
144
If there's not a reason not to, you should code within scope blocks. They enable you to declare variables and functions inside a private scope, allowing you to easily reuse function and variable names between scope blocks. Also, you can use an initializer which comes in handy.

The whole point is encapsulation, meaning that if you don't need certain variables or functions to be accessed by code outside the scope, then make them private, so they can't be used outside the scope.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top