Hi,

I am trying to make a COD4 random map rotation script that not only prevents the same map from coming twice in a row but also checks if that map was played X maps ago (for instance 5). If it was played 4 maps ago, then it will not be played and another one will be picked.

So instead of things like this: Map1->Map3->Map2->Map1! (don't want map1 here because 5 maps did not pass yet since map1 was last picked). I want it like this Map1->Map4->Map7->Map2->Map3->Map5->Map1 (map1 is now allowed since 5 maps have passed since its last pick). Hope I made myself clear here.

I tried a number of things. First off, I tried using the File::functions to save the previous 5 maps. After making the script I found out that those require dev mode (and even then refused to run for some reason). After that I switched to getStat and setStat. However, these functions fail as well giving me the following error:

Code:
^1******* script compile error *******
^1Error: unknown function: (file 'code/_randommaps.gsc', line 71)
 setStat( int(tableLookup( "mp/mapMemory.csv", 1, dataName, 0 )), value ); //set value of map that was just ran, almost always set to level.mapcnt
 *
************************************
---— Server Shutdown —---

With the reason: Server fatal crashed: script compile error
unknown function
 setStat( int(tableLookup( "mp/mapMemory.csv", 1, dataName, 0 )), value ); //set value of map that was just ran, almost always set to level.mapcnt
I think it has to do something with the fact that I removed the 'self' in front of the setStat. I did that on purpose, I do not want this map memory client side but server side. Here is my script:
Code:
init(){
	level.mapPool = strtok("mp_bog;mp_carentan;mp_vacant;mp_farm;mp_overgrown;mp_pipeline;mp_convoy;mp_crash;mp_crash_snow;mp_showdown;mp_creek;mp_broadcast;mp_backlot;mp_bloc;mp_crossfire;mp_citystreets;mp_strike",";");
	level.gametypePool = strtok("dm;dom;koth;sab;sd;war",";");
	level.mapcnt = 5; //adjust to the amount of maps you want to remember. Make it bigger or equal to mapPool.size and your server crashes, looping to infinity and beyond.
	level thread randomRotation();
}

randomRotation(){
	wait 5;
	iprintln("Maps in memory:");
	wait 1;
	maps = [];
	count = 0;
	for(i = 0; i<level.mapPool.size;i++) //search for maps in memory > 0 (so not allowed to use)
	{
		temp = mapGet(level.mapPool[i]);
		if(temp > 0)
		{
			maps[count] = level.mapPool[i];
			count++;
			iprintln(level.mapPool[i]);
			wait 1;
		}
	}
	
	for(i = 0;i<maps.size;i++) //decrement values of maps in memory since a round is done
	{
		mapDecr(maps[i]);
	}
	
	mapSet(level.script,level.mapcnt); //add current map to memory as newest
	
	
	newmap = "temp";
	newmap = level.mapPool[randomInt(level.mapPool.size)-1]; //random new map
	iprintln("Randomed new map");
	wait 1;
	newgametype = "temp";
	newgametype = level.gametypePool[randomInt(level.gametypePool.size)-1]; //random new gamemode
	
	temp = mapGet(newmap);
	loopcount = 0;
	while(temp > 0) //keep randoming new map until we found one that hasent been used in level.mapcnt times
	{
		newmap = level.mapPool[randomInt(level.mapPool.size)-1]; //random new map
		iprintln("Randomed new map");
		temp = mapGet(newmap);
		loopcount++;
		wait 1;
		if(loopcount > 100)
		{
			iprintln("Tried randoming 100 times, no succes. Could be that level.mapcnt is set too big!");
			wait 10;
			break;
		}
	}
	
	while(newgametype == level.gametype) //random new gamemode while randomed one is equal to current
		newgametype = level.gametypePool[randomInt(level.gametypePool.size)-1];
	
	setDvar("sv_maprotationCurrent","gametype " + newgametype + " map " + newmap); //set new map and gamemode
}


//functions to get and set data in .csv file
mapGet( dataName ) {
	return getStat( int(tableLookup( "mp/mapMemory.csv", 1, dataName, 0 )) ); //get value of map (0 to level.mapcnt) 0 means it is free to use, >0 means it was used recently and should be skipped.
}

mapSet( dataName, value ) {
	setStat( int(tableLookup( "mp/mapMemory.csv", 1, dataName, 0 )), value ); //set value of map that was just ran, almost always set to level.mapcnt
}

mapDecr( dataName) {
	value = mapGet(dataName) - 1;
	setStat( int(tableLookup( "mp/mapMemory.csv", 1, dataName, 0 )), value );	 //decrement map value, 0 means it is free to use, >0 means it was used recently and should be skipped.
}
Please note that I added some debug info to see what the script is doing ingame but I don't even get to that point haha.

And the mapMemory.csv looking like this (the values I use are all the way at the bottom) :
Code:
3150,CHANGE_THIS_TO_USE_ME
3151,CHANGE_THIS_TO_USE_ME
3152,CHANGE_THIS_TO_USE_ME
3153,CHANGE_THIS_TO_USE_ME
3154,CHANGE_THIS_TO_USE_ME
3155,CHANGE_THIS_TO_USE_ME
3156,CHANGE_THIS_TO_USE_ME
3157,CHANGE_THIS_TO_USE_ME
3158,CHANGE_THIS_TO_USE_ME
3159,CHANGE_THIS_TO_USE_ME
3160,CHANGE_THIS_TO_USE_ME
3161,CHANGE_THIS_TO_USE_ME
3162,CHANGE_THIS_TO_USE_ME
3163,CHANGE_THIS_TO_USE_ME
3164,CHANGE_THIS_TO_USE_ME
3165,CHANGE_THIS_TO_USE_ME
3166,CHANGE_THIS_TO_USE_ME
3167,CHANGE_THIS_TO_USE_ME
3168,CHANGE_THIS_TO_USE_ME
3169,CHANGE_THIS_TO_USE_ME
3170,CHANGE_THIS_TO_USE_ME
3171,CHANGE_THIS_TO_USE_ME
3172,CHANGE_THIS_TO_USE_ME
3173,CHANGE_THIS_TO_USE_ME
3174,CHANGE_THIS_TO_USE_ME
3175,CHANGE_THIS_TO_USE_ME
3176,CHANGE_THIS_TO_USE_ME
3177,CHANGE_THIS_TO_USE_ME
3178,CHANGE_THIS_TO_USE_ME
3179,CHANGE_THIS_TO_USE_ME
3180,CHANGE_THIS_TO_USE_ME
3181,CHANGE_THIS_TO_USE_ME
3182,CHANGE_THIS_TO_USE_ME
3183,CHANGE_THIS_TO_USE_ME
3184,CHANGE_THIS_TO_USE_ME
3185,CHANGE_THIS_TO_USE_ME
3186,CHANGE_THIS_TO_USE_ME
3187,CHANGE_THIS_TO_USE_ME
3188,CHANGE_THIS_TO_USE_ME
3189,CHANGE_THIS_TO_USE_ME
3190,CHANGE_THIS_TO_USE_ME
3191,CHANGE_THIS_TO_USE_ME
3192,CHANGE_THIS_TO_USE_ME
3193,CHANGE_THIS_TO_USE_ME
3194,CHANGE_THIS_TO_USE_ME
3195,CHANGE_THIS_TO_USE_ME
3196,CHANGE_THIS_TO_USE_ME
3197,CHANGE_THIS_TO_USE_ME
3198,CHANGE_THIS_TO_USE_ME
3199,CHANGE_THIS_TO_USE_ME
3200,CHANGE_THIS_TO_USE_ME
3201,CHANGE_THIS_TO_USE_ME
3202,CHANGE_THIS_TO_USE_ME
3203,CHANGE_THIS_TO_USE_ME
3204,CHANGE_THIS_TO_USE_ME
3205,CHANGE_THIS_TO_USE_ME
3206,CHANGE_THIS_TO_USE_ME
3207,CHANGE_THIS_TO_USE_ME
3208,CHANGE_THIS_TO_USE_ME
3209,CHANGE_THIS_TO_USE_ME
3210,CHANGE_THIS_TO_USE_ME
3211,CHANGE_THIS_TO_USE_ME
3212,CHANGE_THIS_TO_USE_ME
3213,CHANGE_THIS_TO_USE_ME
3214,CHANGE_THIS_TO_USE_ME
3215,CHANGE_THIS_TO_USE_ME
3216,CHANGE_THIS_TO_USE_ME
3217,CHANGE_THIS_TO_USE_ME
3218,CHANGE_THIS_TO_USE_ME
3219,CHANGE_THIS_TO_USE_ME
3220,CHANGE_THIS_TO_USE_ME
3221,CHANGE_THIS_TO_USE_ME
3222,CHANGE_THIS_TO_USE_ME
3223,CHANGE_THIS_TO_USE_ME
3224,CHANGE_THIS_TO_USE_ME
3225,CHANGE_THIS_TO_USE_ME
3226,CHANGE_THIS_TO_USE_ME
3227,CHANGE_THIS_TO_USE_ME
3228,CHANGE_THIS_TO_USE_ME
3229,CHANGE_THIS_TO_USE_ME
3230,CHANGE_THIS_TO_USE_ME
3231,CHANGE_THIS_TO_USE_ME
3232,CHANGE_THIS_TO_USE_ME
3233,CHANGE_THIS_TO_USE_ME
3234,CHANGE_THIS_TO_USE_ME
3235,CHANGE_THIS_TO_USE_ME
3236,CHANGE_THIS_TO_USE_ME
3237,CHANGE_THIS_TO_USE_ME
3238,CHANGE_THIS_TO_USE_ME
3239,CHANGE_THIS_TO_USE_ME
3240,CHANGE_THIS_TO_USE_ME
3241,CHANGE_THIS_TO_USE_ME
3242,CHANGE_THIS_TO_USE_ME
3243,CHANGE_THIS_TO_USE_ME
3244,CHANGE_THIS_TO_USE_ME
3245,CHANGE_THIS_TO_USE_ME
3246,CHANGE_THIS_TO_USE_ME
3247,CHANGE_THIS_TO_USE_ME
3248,CHANGE_THIS_TO_USE_ME
3249,CHANGE_THIS_TO_USE_ME
3250,CHANGE_THIS_TO_USE_ME
3251,CHANGE_THIS_TO_USE_ME
3252,CHANGE_THIS_TO_USE_ME
3253,CHANGE_THIS_TO_USE_ME
3254,CHANGE_THIS_TO_USE_ME
3255,CHANGE_THIS_TO_USE_ME
3256,CHANGE_THIS_TO_USE_ME
3257,CHANGE_THIS_TO_USE_ME
3258,CHANGE_THIS_TO_USE_ME
3259,CHANGE_THIS_TO_USE_ME
3260,CHANGE_THIS_TO_USE_ME
3261,CHANGE_THIS_TO_USE_ME
3262,CHANGE_THIS_TO_USE_ME
3263,CHANGE_THIS_TO_USE_ME
3264,CHANGE_THIS_TO_USE_ME
3265,CHANGE_THIS_TO_USE_ME
3266,CHANGE_THIS_TO_USE_ME
3267,CHANGE_THIS_TO_USE_ME
3268,CHANGE_THIS_TO_USE_ME
3269,CHANGE_THIS_TO_USE_ME
3270,CHANGE_THIS_TO_USE_ME
3271,CHANGE_THIS_TO_USE_ME
3272,CHANGE_THIS_TO_USE_ME
3273,CHANGE_THIS_TO_USE_ME
3274,CHANGE_THIS_TO_USE_ME
3275,CHANGE_THIS_TO_USE_ME
3276,CHANGE_THIS_TO_USE_ME
3277,CHANGE_THIS_TO_USE_ME
3278,CHANGE_THIS_TO_USE_ME
3279,CHANGE_THIS_TO_USE_ME
3280,CHANGE_THIS_TO_USE_ME
3281,CHANGE_THIS_TO_USE_ME
3282,CHANGE_THIS_TO_USE_ME
3283,CHANGE_THIS_TO_USE_ME
3284,CHANGE_THIS_TO_USE_ME
3285,CHANGE_THIS_TO_USE_ME
3286,CHANGE_THIS_TO_USE_ME
3287,CHANGE_THIS_TO_USE_ME
3288,CHANGE_THIS_TO_USE_ME
3289,CHANGE_THIS_TO_USE_ME
3290,CHANGE_THIS_TO_USE_ME
3291,CHANGE_THIS_TO_USE_ME
3292,CHANGE_THIS_TO_USE_ME
3293,CHANGE_THIS_TO_USE_ME
3294,CHANGE_THIS_TO_USE_ME
3295,CHANGE_THIS_TO_USE_ME
3296,CHANGE_THIS_TO_USE_ME
3297,CHANGE_THIS_TO_USE_ME
3298,CHANGE_THIS_TO_USE_ME
3299,CHANGE_THIS_TO_USE_ME
3300,CHANGE_THIS_TO_USE_ME
3301,CHANGE_THIS_TO_USE_ME
3302,CHANGE_THIS_TO_USE_ME
3303,CHANGE_THIS_TO_USE_ME
3304,CHANGE_THIS_TO_USE_ME
3305,CHANGE_THIS_TO_USE_ME
3306,CHANGE_THIS_TO_USE_ME
3307,CHANGE_THIS_TO_USE_ME
3308,CHANGE_THIS_TO_USE_ME
3309,CHANGE_THIS_TO_USE_ME
3310,CHANGE_THIS_TO_USE_ME
3311,CHANGE_THIS_TO_USE_ME
3312,CHANGE_THIS_TO_USE_ME
3313,CHANGE_THIS_TO_USE_ME
3314,CHANGE_THIS_TO_USE_ME
3315,CHANGE_THIS_TO_USE_ME
3316,CHANGE_THIS_TO_USE_ME
3317,CHANGE_THIS_TO_USE_ME
3318,CHANGE_THIS_TO_USE_ME
3319,CHANGE_THIS_TO_USE_ME
3320,CHANGE_THIS_TO_USE_ME
3321,CHANGE_THIS_TO_USE_ME
3322,CHANGE_THIS_TO_USE_ME
3323,CHANGE_THIS_TO_USE_ME
3324,CHANGE_THIS_TO_USE_ME
3325,CHANGE_THIS_TO_USE_ME
3326,CHANGE_THIS_TO_USE_ME
3327,CHANGE_THIS_TO_USE_ME
3328,CHANGE_THIS_TO_USE_ME
3329,CHANGE_THIS_TO_USE_ME
3330,CHANGE_THIS_TO_USE_ME
3331,CHANGE_THIS_TO_USE_ME
3332,CHANGE_THIS_TO_USE_ME
3333,CHANGE_THIS_TO_USE_ME
3334,CHANGE_THIS_TO_USE_ME
3335,CHANGE_THIS_TO_USE_ME
3336,CHANGE_THIS_TO_USE_ME
3337,CHANGE_THIS_TO_USE_ME
3338,CHANGE_THIS_TO_USE_ME
3339,CHANGE_THIS_TO_USE_ME
3340,CHANGE_THIS_TO_USE_ME
3341,CHANGE_THIS_TO_USE_ME
3342,CHANGE_THIS_TO_USE_ME
3343,CHANGE_THIS_TO_USE_ME
3344,CHANGE_THIS_TO_USE_ME
3345,CHANGE_THIS_TO_USE_ME
3346,CHANGE_THIS_TO_USE_ME
3347,CHANGE_THIS_TO_USE_ME
3348,CHANGE_THIS_TO_USE_ME
3349,CHANGE_THIS_TO_USE_ME
3350,CHANGE_THIS_TO_USE_ME
3351,CHANGE_THIS_TO_USE_ME
3352,CHANGE_THIS_TO_USE_ME
3353,CHANGE_THIS_TO_USE_ME
3354,CHANGE_THIS_TO_USE_ME
3355,CHANGE_THIS_TO_USE_ME
3356,CHANGE_THIS_TO_USE_ME
3357,CHANGE_THIS_TO_USE_ME
3358,CHANGE_THIS_TO_USE_ME
3359,CHANGE_THIS_TO_USE_ME
3360,CHANGE_THIS_TO_USE_ME
3361,CHANGE_THIS_TO_USE_ME
3362,CHANGE_THIS_TO_USE_ME
3363,CHANGE_THIS_TO_USE_ME
3364,CHANGE_THIS_TO_USE_ME
3365,CHANGE_THIS_TO_USE_ME
3366,CHANGE_THIS_TO_USE_ME
3367,CHANGE_THIS_TO_USE_ME
3368,CHANGE_THIS_TO_USE_ME
3369,CHANGE_THIS_TO_USE_ME
3370,CHANGE_THIS_TO_USE_ME
3371,CHANGE_THIS_TO_USE_ME
3372,CHANGE_THIS_TO_USE_ME
3373,CHANGE_THIS_TO_USE_ME
3374,CHANGE_THIS_TO_USE_ME
3375,CHANGE_THIS_TO_USE_ME
3376,CHANGE_THIS_TO_USE_ME
3377,CHANGE_THIS_TO_USE_ME
3378,CHANGE_THIS_TO_USE_ME
3379,CHANGE_THIS_TO_USE_ME
3380,CHANGE_THIS_TO_USE_ME
3381,CHANGE_THIS_TO_USE_ME
3382,CHANGE_THIS_TO_USE_ME
3383,CHANGE_THIS_TO_USE_ME
3384,CHANGE_THIS_TO_USE_ME
3385,CHANGE_THIS_TO_USE_ME
3386,CHANGE_THIS_TO_USE_ME
3387,CHANGE_THIS_TO_USE_ME
3388,CHANGE_THIS_TO_USE_ME
3389,CHANGE_THIS_TO_USE_ME
3390,CHANGE_THIS_TO_USE_ME
3391,CHANGE_THIS_TO_USE_ME
3392,CHANGE_THIS_TO_USE_ME
3393,CHANGE_THIS_TO_USE_ME
3394,CHANGE_THIS_TO_USE_ME
3395,CHANGE_THIS_TO_USE_ME
3396,CHANGE_THIS_TO_USE_ME
3397,CHANGE_THIS_TO_USE_ME
3398,CHANGE_THIS_TO_USE_ME
3399,CHANGE_THIS_TO_USE_ME
3400,CHANGE_THIS_TO_USE_ME
3401,CHANGE_THIS_TO_USE_ME
3402,CHANGE_THIS_TO_USE_ME
3403,CHANGE_THIS_TO_USE_ME
3404,CHANGE_THIS_TO_USE_ME
3405,CHANGE_THIS_TO_USE_ME
3406,CHANGE_THIS_TO_USE_ME
3407,CHANGE_THIS_TO_USE_ME
3408,CHANGE_THIS_TO_USE_ME
3409,CHANGE_THIS_TO_USE_ME
3410,CHANGE_THIS_TO_USE_ME
3411,CHANGE_THIS_TO_USE_ME
3412,CHANGE_THIS_TO_USE_ME
3413,CHANGE_THIS_TO_USE_ME
3414,CHANGE_THIS_TO_USE_ME
3415,CHANGE_THIS_TO_USE_ME
3416,CHANGE_THIS_TO_USE_ME
3417,CHANGE_THIS_TO_USE_ME
3418,CHANGE_THIS_TO_USE_ME
3419,CHANGE_THIS_TO_USE_ME
3420,CHANGE_THIS_TO_USE_ME
3421,CHANGE_THIS_TO_USE_ME
3422,CHANGE_THIS_TO_USE_ME
3423,CHANGE_THIS_TO_USE_ME
3424,CHANGE_THIS_TO_USE_ME
3425,CHANGE_THIS_TO_USE_ME
3426,CHANGE_THIS_TO_USE_ME
3427,CHANGE_THIS_TO_USE_ME
3428,CHANGE_THIS_TO_USE_ME
3429,CHANGE_THIS_TO_USE_ME
3430,CHANGE_THIS_TO_USE_ME
3431,CHANGE_THIS_TO_USE_ME
3432,CHANGE_THIS_TO_USE_ME
3433,CHANGE_THIS_TO_USE_ME
3434,CHANGE_THIS_TO_USE_ME
3435,CHANGE_THIS_TO_USE_ME
3436,CHANGE_THIS_TO_USE_ME
3437,CHANGE_THIS_TO_USE_ME
3438,CHANGE_THIS_TO_USE_ME
3439,CHANGE_THIS_TO_USE_ME
3440,CHANGE_THIS_TO_USE_ME
3441,CHANGE_THIS_TO_USE_ME
3442,CHANGE_THIS_TO_USE_ME
3443,CHANGE_THIS_TO_USE_ME
3444,CHANGE_THIS_TO_USE_ME
3445,CHANGE_THIS_TO_USE_ME
3446,CHANGE_THIS_TO_USE_ME
3447,CHANGE_THIS_TO_USE_ME
3448,CHANGE_THIS_TO_USE_ME
3449,CHANGE_THIS_TO_USE_ME
3450,CHANGE_THIS_TO_USE_ME
3451,CHANGE_THIS_TO_USE_ME
3452,CHANGE_THIS_TO_USE_ME
3453,CHANGE_THIS_TO_USE_ME
3454,CHANGE_THIS_TO_USE_ME
3455,CHANGE_THIS_TO_USE_ME
3456,CHANGE_THIS_TO_USE_ME
3457,CHANGE_THIS_TO_USE_ME
3458,CHANGE_THIS_TO_USE_ME
3459,CHANGE_THIS_TO_USE_ME
3460,CHANGE_THIS_TO_USE_ME
3461,CHANGE_THIS_TO_USE_ME
3462,CHANGE_THIS_TO_USE_ME
3463,CHANGE_THIS_TO_USE_ME
3464,CHANGE_THIS_TO_USE_ME
3465,CHANGE_THIS_TO_USE_ME
3466,CHANGE_THIS_TO_USE_ME
3467,CHANGE_THIS_TO_USE_ME
3468,CHANGE_THIS_TO_USE_ME
3469,CHANGE_THIS_TO_USE_ME
3470,CHANGE_THIS_TO_USE_ME
3471,CHANGE_THIS_TO_USE_ME
3472,CHANGE_THIS_TO_USE_ME
3473,CHANGE_THIS_TO_USE_ME
3474,CHANGE_THIS_TO_USE_ME
3475,CHANGE_THIS_TO_USE_ME
3476,CHANGE_THIS_TO_USE_ME
3477,CHANGE_THIS_TO_USE_ME
3478,CHANGE_THIS_TO_USE_ME
3479,CHANGE_THIS_TO_USE_ME
3480,CHANGE_THIS_TO_USE_ME
3481,mp_strike
3482,mp_citystreets
3483,mp_crossfire
3484,mp_bloc
3485,mp_backlot
3486,mp_broadcast
3487,mp_creek
3488,mp_showdown
3489,mp_crash_snow
3490,mp_crash
3491,mp_convoy
3492,mp_pipeline
3493,mp_overgrown
3494,mp_farm
3495,mp_vacant
3496,mp_carentan
3497,mp_bog
I have also looked into the SQL database solution but that creates an issue since my server runs Windows instead of linux (required too much maintenance). Ideally would be to run the SQL database on windows but I don't know if that is possible.

Help to achieve what I am trying to do would be much appreciated. Thanks!