Now a conversion of this plugin would be cool. *note* This plugin was given to me by the geat Ludwig van so I may learn from it and with permissions from lud I am giving it out so people may use it.
Code:
/*
Welcome to the EJL map checker. A simple plugin by Ludwig van to
check the following:
Number of player spawns, approximate balance of player spawns per team,
distances between player spawns, if there can be bullet trace paths
between spawn points for opposing teams.
To use: install the plugin on the server you use to test maps, start
the map. As soon as the map is done loading it is checked and instantly
dumps a file in your amx folder ... self explanatory.
Requirements : AMXMOD 0.9.3 and see #include's below. If you dont know
what that means, then you are not allowed to use this plugin.
*/
#include <amxmod>
#include <amxmisc>
#include <xtrafun>
#include <Vexd_Utilities>
#define MIN_DIST 128
#define MIN_SPAWNS 20
#define COVER_TOLLERANCE 100
new spawns[100][3]
new spawnsteam[100]
new counter = 1,last = 0,lastt = 0
new t1,t2
do_check(){
new ThisMap[32]
get_mapname(ThisMap, 31)
new filename[80],text[128]
format(filename,79,"addons/amx/SPAWNCHECK_OUTPUT_FOR_%s.txt",ThisMap)
if(file_exists(filename))
delete_file(filename)
write_file(filename,"Welcome to the EJL map checker. This plugin checks the following:",-1)
write_file(filename,"",-1)
write_file(filename," Number of player spawns, approximate balance of player spawns per team,",-1)
write_file(filename," distances between player spawns, if there can be bullet trace paths",-1)
write_file(filename," between spawn points for opposing teams.",-1)
write_file(filename,"",-1)
write_file(filename,"",-1)
format(text,127,"Now reading player spawns for ... %s",ThisMap)
write_file(filename,text,-1)
write_file(filename,"",-1)
new total = current_num_ents()
new Float:fl_vExplodeAt[3]
for(new pToucher=1;pToucher<total;pToucher++){
if( (FindEntity(pToucher, "info_player_start") >0) || (FindEntity(pToucher, "info_player_deathmatch") >0) ) {
new szClassName[500]
Entvars_Get_String(pToucher, EV_SZ_classname, szClassName, 499)
if(equal(szClassName, "info_player_deathmatch")) {
Entvars_Get_Vector(pToucher, EV_VEC_origin, fl_vExplodeAt)
spawns[counter][0] = floatround(fl_vExplodeAt[0])
spawns[counter][1] = floatround(fl_vExplodeAt[1])
spawns[counter][2] = floatround(fl_vExplodeAt[2])
spawnsteam[counter] = 2
format(text,127," Player Spawn #%d Vec: %d %d %d Team: %d",counter,spawns[counter][0],spawns[counter][1],spawns[counter][2],spawnsteam[counter])
write_file(filename,text,-1)
counter++
last = pToucher+1
lastt = 2
t1++
}
else if(equal(szClassName, "info_player_start")) {
Entvars_Get_Vector(pToucher, EV_VEC_origin, fl_vExplodeAt)
spawns[counter][0] = floatround(fl_vExplodeAt[0])
spawns[counter][1] = floatround(fl_vExplodeAt[1])
spawns[counter][2] = floatround(fl_vExplodeAt[2])
spawnsteam[counter] = 1
format(text,127," Player Spawn #%d Vec: %d %d %d Team: %d",counter,spawns[counter][0],spawns[counter][1],spawns[counter][2],spawnsteam[counter])
write_file(filename,text,-1)
counter++
last = pToucher+1
lastt = 1
t2++
}
}
}
Entvars_Get_Vector(last, EV_VEC_origin, fl_vExplodeAt)
spawns[counter][0] = floatround(fl_vExplodeAt[0])
spawns[counter][1] = floatround(fl_vExplodeAt[1])
spawns[counter][2] = floatround(fl_vExplodeAt[2])
spawnsteam[counter] = lastt
if(spawns[counter][0] || spawns[counter][1] || spawns[counter][2]){
format(text,127," Player Spawn #%d Vec: %d %d %d Team: %d",counter,spawns[counter][0],spawns[counter][1],spawns[counter][2],spawnsteam[counter])
write_file(filename,text,-1)
}
write_file(filename,"",-1)
write_file(filename,"",-1)
format(text,127,"Now calculating distances between player spawns for ... %s",ThisMap)
write_file(filename,text,-1)
write_file(filename,"",-1)
new dist,err_count,err[100]
for(new a = 1;a<counter+1;a++){
for(new b = 1;b<counter+1;b++){
if(a!=b){
dist = get_distance(spawns[a],spawns[b])
if(dist < MIN_DIST && !(err[a] && err[b]) ){
err[a] = 1
err[b] = 1
err_count++
format(text,127," ERROR: #%d %d %d %d and #%d %d %d %d are only %d units apart.",
a,spawns[a][0],spawns[a][1],spawns[a][2],b,spawns[b][0],spawns[b][1],spawns[b][2],dist)
write_file(filename,text,-1)
}
}
}
}
write_file(filename,"",-1)
if(err_count){
format(text,127," Spawn points need to be at least %d units apart.",MIN_DIST)
write_file(filename,text,-1)
write_file(filename,"",-1)
format(text,127," %d spawn point proximity errors found for ... %s",err_count,ThisMap)
write_file(filename,text,-1)
}else{
format(text,127," NO spawn point proximity errors found for ... %s",ThisMap)
write_file(filename,text,-1)
}
write_file(filename,"",-1)
write_file(filename,"",-1)
if(counter < MIN_SPAWNS){
format(text,127,"Error: Not enough player spawns. Need at least %d, only found %d",MIN_SPAWNS,counter)
write_file(filename,text,-1)
write_file(filename,"",-1)
write_file(filename,"",-1)
}
if(t1 < (counter / 3) || t2 < (counter / 3) ){
format(text,127,"Error: Not balanced. Each team should have about the same amount of spawns")
write_file(filename,text,-1)
write_file(filename,"",-1)
write_file(filename,"",-1)
}
format(text,127,"Now calculating bullet paths between spawns for ... %s",ThisMap)
write_file(filename,text,-1)
write_file(filename,"",-1)
new err1[100],err_count1
new dist1,dist2
for(new a = 1;a<counter+1;a++){
for(new b = 1;b<counter+1;b++){
if(a!=b){
new ent
new Float:fl_infront[3]
new Float:fl_spawnsa[3]
new Float:fl_spawnsb[3]
fl_spawnsa[0] = float(spawns[a][0])
fl_spawnsa[1] = float(spawns[a][1])
fl_spawnsa[2] = float(spawns[a][2])
fl_spawnsb[0] = float(spawns[b][0])
fl_spawnsb[1] = float(spawns[b][1])
fl_spawnsb[2] = float(spawns[b][2])
TraceLn(ent, fl_spawnsa, fl_spawnsb, fl_infront)
dist1 = get_distance(spawns[a],spawns[b])
new infront[3]
infront[0] = floatround(fl_infront[0])
infront[1] = floatround(fl_infront[1])
infront[2] = floatround(fl_infront[2])
dist2 = get_distance(spawns[a],infront)
if( dist1 < dist2 +COVER_TOLLERANCE && !(err1[a] && err1[b]) && spawnsteam[a] != spawnsteam[b] ){
err1[a] = 1
err1[b] = 1
err_count1++
format(text,127," ERROR: Spawn cover issue: #%d and #%d on opposite teams see eachother",a,b)
write_file(filename,text,-1)
}
}
}
}
if(err_count1){
write_file(filename,"",-1)
format(text,127," %d or more spawn point cover issues found for ... %s",err_count1,ThisMap)
write_file(filename,text,-1)
}else{
format(text,127," NO spawn point cover issues found for ... %s",ThisMap)
write_file(filename,text,-1)
}
write_file(filename,"",-1)
write_file(filename,"",-1)
format(text,127,"Done checking ... %s",ThisMap)
write_file(filename,text,-1)
return PLUGIN_HANDLED
}
public plugin_init(){
register_plugin("CHECK MAP SPAWNS","0.1","EJL")
do_check()
return PLUGIN_CONTINUE
}