• 🏆 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!

Creating A Point Using Players Camera Bound

Status
Not open for further replies.
Level 5
Joined
Mar 24, 2020
Messages
80
Hi guys,

I would like to create a creep spawn system that creates points that are always outside of all players current camera bounds. Is this possible?
Also there must also be a condition where the the spawned creep isn't within 512 distance from any of the players units either.

Is there a way to do the below in GUI?

Event: Every 30 Seconds.
Action: Create Point
If Any Conditions:
- Point is in any players camera bounds
- Point is within X distance of any unit owned by any player in Players
Then: re-run trigger and skip remaining actions
Else: Create unit at Point.

Cheers
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
Alright, there may be a better way, but I figured I'd give it a shot.

Tasyen made this camera code:
vJASS:
function SyncCamDataRead takes nothing returns nothing
   if BlzGetTriggerSyncPrefix() == "SyncCamX" then
       set udg_PlayerCamX[GetConvertedPlayerId(GetTriggerPlayer())] = S2R(BlzGetTriggerSyncData())
   else
       set udg_PlayerCamY[GetConvertedPlayerId(GetTriggerPlayer())] = S2R(BlzGetTriggerSyncData())
   endif
endfunction
function SyncCamDataSend takes nothing returns nothing
   call BlzSendSyncData("SyncCamX", R2S(GetCameraTargetPositionX()))
   call BlzSendSyncData("SyncCamY", R2S(GetCameraTargetPositionY()))
endfunction
function SyncCamDataInit takes nothing returns nothing
   local integer playerIndex = 0
   local trigger trig = CreateTrigger()
   call TriggerAddAction(trig, function SyncCamDataRead)
   loop
       call BlzTriggerRegisterPlayerSyncEvent(trig, Player(playerIndex), "SyncCamX", false)
       call BlzTriggerRegisterPlayerSyncEvent(trig, Player(playerIndex), "SyncCamY", false)
       set playerIndex = playerIndex + 1
       exitwhen playerIndex == bj_MAX_PLAYER_SLOTS
   endloop
   //call TimerStart(CreateTimer(), 1, true, function SyncCamDataSend) // I disabled the timer
endfunction
vJASS:
function GetCreepSpawns takes integer h, integer v, real radius returns nothing
    local rect r
    local real basex = GetRectMinX(gg_rct_CreepTopLeftCorner)
    local real basemaxx = GetRectMaxX(gg_rct_CreepTopLeftCorner)
    local real minx = GetRectMinX(gg_rct_CreepTopLeftCorner)
    local real maxx = GetRectMaxX(gg_rct_CreepTopLeftCorner)
    local real miny = GetRectMinY(gg_rct_CreepTopLeftCorner)
    local real maxy = GetRectMaxY(gg_rct_CreepTopLeftCorner)
    local real dist
    local real x1
    local real y1
    local real x2
    local real y2
    local integer a = 1
    local integer b = 1
    local integer c = 1
    local integer d = 0
    local boolean success
    loop
        exitwhen (a > v)
            loop
                exitwhen (b > h)
                    set r = Rect(minx, miny, maxx, maxy)
                    set success = true
                    set c = 1
                    loop
                        exitwhen (c > udg_Creep_Index)
                            set x1 = GetRectCenterX(r)
                            set y1 = GetRectCenterY(r)
                            set x2 = GetLocationX(udg_Creep_Points[c])
                            set y2 = GetLocationY(udg_Creep_Points[c])
                            if SquareRoot(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))) <= radius then
                                set success = false
                                set c = udg_Creep_Index
                            endif
                            set c = c + 1
                    endloop
                    if success then
                        set d = d + 1
                        set udg_Creep_Spawns[d] = GetRandomLocInRect(r)
                    endif
                    call RemoveRect(r)
                    set minx = minx + 512
                    set maxx = maxx + 512
                set b = b + 1
            endloop
        set a = a + 1
        set b = 1
        set minx = basex
        set maxx = basemaxx
        set miny = miny - 512
        set maxy = maxy - 512
    endloop
    set udg_Creep_Spawn_Index = d
    set r = null
 endfunction

  • Setup SyncPlayerCamera
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • -------- IMPORTANT - Don't forget to create a Region in the top left corner of the map called "CreepTopLeftCorner" --------
      • -------- This creates the triggers needed for the SyncPlayerCamera system to work --------
      • Custom script: call SyncCamDataInit()
  • Spawn Creeps Interval
    • Events
      • Time - Every 30.00 seconds of game time
    • Conditions
    • Actions
      • -------- get each player's center camera and save it as PlayerCamX/Y. It needs a moment to sync first, which is why I use a Wait --------
      • Custom script: call SyncCamDataSend()
      • -------- --------
      • Wait 0.00 seconds
      • -------- --------
      • Set VariableSet Creep_Index = 0
      • -------- --------
      • -------- find unwanted areas in the playable map area and mark them with points --------
      • Set VariableSet Creep_Group = (Units in (Playable map area))
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Set VariableSet Creep_PN = (Player number of (Picked player))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point(PlayerCamX[Creep_PN], PlayerCamY[Creep_PN]))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point((PlayerCamX[Creep_PN] + 512.00), (PlayerCamY[Creep_PN] + 512.00)))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point((PlayerCamX[Creep_PN] + 512.00), (PlayerCamY[Creep_PN] - 512.00)))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point((PlayerCamX[Creep_PN] - 512.00), (PlayerCamY[Creep_PN] - 512.00)))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point((PlayerCamX[Creep_PN] - 512.00), (PlayerCamY[Creep_PN] + 512.00)))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point((PlayerCamX[Creep_PN] + 512.00), PlayerCamY[Creep_PN]))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point((PlayerCamX[Creep_PN] - 512.00), PlayerCamY[Creep_PN]))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point(PlayerCamX[Creep_PN], (PlayerCamY[Creep_PN] + 512.00)))
          • Set VariableSet Creep_Index = (Creep_Index + 1)
          • Set VariableSet Creep_Points[Creep_Index] = (Point(PlayerCamX[Creep_PN], (PlayerCamY[Creep_PN] - 512.00)))
          • Unit Group - Pick every unit in Creep_Group and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Owner of (Picked unit)) Equal to (Picked player)
                  • ((Picked unit) is alive) Equal to True
                • Then - Actions
                  • Set VariableSet Creep_Index = (Creep_Index + 1)
                  • Set VariableSet Creep_Points[Creep_Index] = (Position of (Picked unit))
                  • Unit Group - Remove (Picked unit) from Creep_Group.
                • Else - Actions
      • Custom script: call DestroyGroup (udg_Creep_Group)
      • -------- --------
      • -------- You need to pass 3 important pieces of information into the GetCreepSpawns() function: --------
      • -------- 1st Value = Horizontal number of tiles from left to right (512 units in size) --------
      • -------- 2nd Value = Vertical number of tiles from top to bottom (512 units in size) --------
      • -------- 3rd Value = Radius for excluding Spawn Points (The bigger the radius, the more strict the system is) --------
      • Custom script: call GetCreepSpawns(12, 13, 1024)
      • -------- --------
      • -------- CREATE YOUR CREEPS using the newly created points -> Creep_Spawns --------
      • -------- You can reference Creep_Spawn_Index to get the total number of Creep_Spawns that were created --------
      • For each (Integer Creep_Loop) from 1 to 25, do (Actions)
        • Loop - Actions
          • Unit - Create 1 Dark Troll Shadow Priest for Neutral Hostile at Creep_Spawns[(Random integer number between 1 and Creep_Spawn_Index)] facing Default building facing degrees
          • Unit - Pause (Last created unit)
      • -------- --------
      • -------- clean up points (DO THIS AFTER YOU CREATE YOUR CREEPS) --------
      • For each (Integer Creep_Loop) from 1 to Creep_Index, do (Actions)
        • Loop - Actions
          • Custom script: call RemoveLocation (udg_Creep_Points[udg_Creep_Loop])
      • For each (Integer Creep_Loop) from 1 to Creep_Spawn_Index, do (Actions)
        • Loop - Actions
          • Custom script: call RemoveLocation (udg_Creep_Spawns[udg_Creep_Loop])

There's a bit to it...

To get the system up and running you need to count how many 512 unit-sized Grid Tiles your map has starting from left to right, and do the same for top to bottom (see my "ex" picture for more details). Remember these numbers! In my map there were 12 horizontal tiles and 13 vertical tiles.

This info is used for when we call this function:
  • Custom script: call GetCreepSpawns(12, 13, 1024)
You need to type your information into the function. 1st value = # of horizontal tiles, 2nd value = # of vertical tiles, and 3rd value = Radius in which you'll exclude Creep Spawns. 1024 is actually a pretty good starting value for the radius, 512 sometimes lets Creeps slip by the system.

Important! - Don't forget to create a Region and place it in the top left corner of the map. You MUST name this region "CreepTopLeftCorner".

After running the GetCreepSpawns() function, the system will place a bunch of points "randomly" around the map (not completely random since I don't want to create them near units/cameras). These Points are called "Creep_Spawns", and can be referenced like so:
  • -------- CREATE YOUR CREEPS using the newly created points -> Creep_Spawns --------
  • -------- You can reference Creep_Spawn_Index to get the total number of Creep_Spawns that were created --------
  • For each (Integer Creep_Loop) from 1 to 25, do (Actions)
    • Loop - Actions
      • Unit - Create 1 Dark Troll Shadow Priest for Neutral Hostile at Creep_Spawns[(Random integer number between 1 and Creep_Spawn_Index)] facing Default building facing degrees
So I'm creating 25 Dark Troll Priests scattered across random Creep_Spawns. Each Creep_Spawn will be far away from any Player Units/Cameras.
 

Attachments

  • Creep Spawn Itachi 1.w3m
    23.4 KB · Views: 31
  • ex.png
    ex.png
    1.5 MB · Views: 27
Last edited:
Level 5
Joined
Mar 24, 2020
Messages
80
That's a very useful system, Uncle! Thanks so much for spending the time creating it, putting it into a map and then also explaining how it works. You really do provide great support.

This system would work perfectly for any form of wilderness survival maps. I've begun trying to build a good random terrain system and having this complimenting it would allow all forms of games to be produced.
 
Status
Not open for further replies.
Top