Welcome to Open Carnage

A resource for modders and technology enthusiasts; have a wander to see why we're worth the time! EST. 2012

Sign in to follow this  
Followers 0
jasecon

Random Map Order

Hey, Is it possible to get a script made which would randomize the map-cycle list, and randomize it upon each time the randomized map-cycle is completed?

Share this post


Link to post
Share on other sites

Members of Open Carnage never see off-site ads.

Hey, Is it possible to get a script made which would randomize the map-cycle list, and randomize it upon each time the randomized map-cycle is completed?

You want random maps with random gametypes or you want a random order? And is this for SAPP or Phasor? I know a way I could probably manage something like this quickly with SAPP's mapcycle.

Share this post


Link to post
Share on other sites

Random order, I have the game-types how I want them I just want the order of the maps to be a mystery.

for example If i have my map cycle list:

 

Lets say this is my mapcycle:

 

bloodgulch:pingas:4:16
ratrace:are:0:12
sidewinder:bad:4:16
carousel:kids:0:12

 

I want to script to read it then scramble the order of these maps when its loaded.

NeX likes this

Share this post


Link to post
Share on other sites

tbh a quick easy way would just be to use an external file, write to it all four maps, then have some simple conditionals that pick a random number between 1 and 4 to start the cycle. Once a map is played, just remove it from that text list, and then pick a random number between 1 and 3. 

 

Make some variable like "map_num" so each time you remove a map from there, you can just read in the remaining maps into variables and count how many you have left.

 

So:

 

Start the server, check the file (or make it if first time). If the file has 4 maps in it, map_num = 4, first_map  = map1, second_map = map2,  And so on.

 

Generate a random number from (0, map_num] 

 

Then, a quick if/else block like:

 

if random == 1, server command (play map 1)

remove map 1 from file

 

if random == 2, server command (play map 2)

remove map 2 from file

 

 

So this way you would randomly pick the first map to play (per cycle), and then randomly switch between the others as they tick down to 0. This should prevent repeating maps except when the first of a cycle is randomly the last of a cycle. Theoretically, this would happen ~25% of the time. You could easily keep track of that though, with the same type of method.

 

Got most of the way through that and realized you can probably just use I/O on the mapcycle.txt and randomize the list, since SAPP releases it.

You could also just use a file with the maps/gametypes in it as a string to randomize and feed into SAPP by commands.

 

So you'd have a file in the root server directory like: randomcycle.txt

 

bloodgulch:pingas:4:16
ratrace:are:0:12
sidewinder:bad:4:16
carousel:kids:0:12

4

 

Read it into a table or individual variables, and then use a simple randomization function on it.

 

So, in pseudocode:

local maptable

for each line in file("randomcycle.txt") {
    if(line == "1" or "2" or "3"){
        parse number and increase
        overwrite the number in the file
        gamenum = number
    } else if (line == "4") {
        parse number
        gamenum = number
        overwrite file number to 1 for reset
    } else {
        maptable.insert(line)
    }
    
} //end loop -- here maptable should be 4 maps/gametypes and you know what game this is and have set it for the next one

if(number == 4){ //this is the last game until a new random cycle is needed
    for each map/gametype in mapcycle {
        delete entry
    }
    randomize(maptable) //leave this up to you, there are 1000000 ways to do this
    for each item in maptable {
        add item to server mapcycle //no need to overwrite the file since we're randomizing it internally
    }//the server should now have a randomized map cycle
} else { //this isn't the last game, so just increase the game number and go about yer bizniss
    return
}
jasecon likes this

KsqHutE.png

Share this post


Link to post
Share on other sites

If your server is set up with a variant path inside your haloceded directory, you can more easily read from the existing mapcycle file which enables you to use map_spec to jump around the cycle. Here's some (untested) code to read from the mapcycle to find how many entries there are and generate a random order to run through it in. You can call map_spec after game end to override the automatically defined next map (whether the sapp mapcycle is running or not).

 
api_version = "1.9.0.0"


local mapcycle_path = "./variants/sapp/mapcycle.txt"
local cycle_order = {}
local current_position = 1

function OnScriptLoad()
  RandomizeCycle()
  register_callback(cb['EVENT_GAME_END'], "OnGameEnd")
end
function OnScriptUnload() end

function RandomizeCycle()
  local mapcycle_size = 0
  local mapcycle_file = assert(io.open(mapcycle_path, "r"))


  while true do
    mapcycle_entry = mapcycle_file:read()
    if mapcycle_entry == nil then break end
    mapcycle_size = mapcycle_size + 1
  end


  mapcycle_file:close()


  local positions = {}
  for i=1, mapcycle_size do table.insert(positions, i) end
  while #positions > 0 do
    table.insert(cycle_order, table.remove(positions, rand(1, #positions)))
  end
end

function OnGameEnd()
  current_position = current_position + 1
  execute_command("map_spec "..(cycle_order[current_position] - 1)) --SAPP's mapcycle is 0-based
  if current_position >= #cycle_order then
    current_position = 1
    RandomizeCycle()
  end
end
Edited by SonicXVe
jasecon likes this

Share this post


Link to post
Share on other sites

If your server is set up with a variant path inside your haloceded directory, you can more easily read from the existing mapcycle file which enables you to use map_spec to jump around the cycle. Here's some (untested) code to read from the mapcycle to find how many entries there are and generate a random order to run through it in. You can call map_spec after game end to override the automatically defined next map (whether the sapp mapcycle is running or not).

api_version = "1.9.0.0"


local mapcycle_path = "./variants/sapp/mapcycle.txt"
local cycle_order = {}
local current_position = 1

function OnScriptLoad()
  RandomizeCycle()
  register_callback(cb['EVENT_GAME_END'], "OnGameEnd")
end
function OnScriptUnload() end

function RandomizeCycle()
  local mapcycle_size = 0
  local mapcycle_file = assert(io.open(mapcycle_path, "r"))


  while true do
    mapcycle_entry = mapcycle_file:read()
    if mapcycle_entry == nil then break end
    mapcycle_size = mapcycle_size + 1
  end


  mapcycle_file:close()


  local positions = {}
  for i=1, mapcycle_size do table.insert(positions, i) end
  while #positions > 0 do
    table.insert(cycle_order, table.remove(positions, rand(1, #positions)))
  end
end

function OnGameEnd()
  current_position = current_position + 1
  execute_command("map_spec "..(current_position - 1)) --SAPP's mapcycle is 0-based
  if current_position >= #cycle_order then
    current_position = 1
    RandomizeCycle()
  end
end

 

Looking over it, all I see that you're doing is just counting up from 1. The cycle_order variable isn't even used outside of RandomizeCycle().

Share this post


Link to post
Share on other sites

Looking over it, all I see that you're doing is just counting up from 1. The cycle_order variable isn't even used outside of RandomizeCycle().

 

Lol whoops, I fixed it I think.

Share this post


Link to post
Share on other sites

Lol whoops, I fixed it I think.

 

Nice! Another thing that might be useful is EVENT_ECHO if you don't want to open mapcycle.txt.

function GetMapcycleCount()
    local mapcycle_count = 0
    function OnEcho() mapcycle_count = mapcycle_count + 1 end
    register_callback(cb['EVENT_ECHO'],"OnEcho")
    execute_command("mapcycle",0,true)
    unregister_callback(cb['EVENT_ECHO'])
    return mapcycle_count
end

Up to you. Nothing wrong with what you're doing.

Share this post


Link to post
Share on other sites

Nice! Another thing that might be useful is EVENT_ECHO if you don't want to open mapcycle.txt.

function GetMapcycleCount()
    local mapcycle_count = 0
    function OnEcho() mapcycle_count = mapcycle_count + 1 end
    register_callback(cb['EVENT_ECHO'],"OnEcho")
    execute_command("mapcycle",0,true)
    unregister_callback(cb['EVENT_ECHO'])
    return mapcycle_count
end

Up to you. Nothing wrong with what you're doing.

That's brilliant, I'll see about updating it with that if I get the time. It's quite late here now. I might release it in another thread too, I would like to use this myself lol.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0
  • Recently Browsing   0 members

    No registered users viewing this page.