mirror of
https://github.com/Jackzmc/sourcemod-plugins.git
synced 2025-05-06 11:53:21 +00:00
134 lines
No EOL
5.1 KiB
SourcePawn
134 lines
No EOL
5.1 KiB
SourcePawn
enum struct LocationMeta {
|
|
float pos[3];
|
|
float ang[3];
|
|
bool runto;
|
|
bool jump;
|
|
int attempts; // # of attempts player has moved until they will try to manage
|
|
}
|
|
|
|
// Game settings
|
|
LocationMeta activeBotLocations[MAXPLAYERS+1];
|
|
|
|
methodmap MovePoints < ArrayList {
|
|
public MovePoints() {
|
|
return view_as<MovePoints>(new ArrayList(sizeof(LocationMeta)));
|
|
}
|
|
|
|
public bool SaveMap(const char[] map, const char[] set = "default") {
|
|
char buffer[256];
|
|
// guesswho folder should be created by ReloadMapDB
|
|
BuildPath(Path_SM, buffer, sizeof(buffer), "data/guesswho/%s", map);
|
|
CreateDirectory(buffer, FOLDER_PERMS);
|
|
BuildPath(Path_SM, buffer, sizeof(buffer), "data/guesswho/%s/%s.txt", map, set);
|
|
File file = OpenFile(buffer, "w+");
|
|
if(file != null) {
|
|
file.WriteLine("px\tpy\tpz\tax\tay\taz");
|
|
LocationMeta meta;
|
|
for(int i = 0; i < movePoints.Length; i++) {
|
|
movePoints.GetArray(i, meta);
|
|
file.WriteLine("%.1f %.1f %.1f %.1f %.1f %.1f", meta.pos[0], meta.pos[1], meta.pos[2], meta.ang[0], meta.ang[1], meta.ang[2]);
|
|
}
|
|
PrintToServer("[GuessWho] Saved %d locations to %s/%s.txt", movePoints.Length, map, set);
|
|
file.Flush();
|
|
delete file;
|
|
return true;
|
|
}
|
|
PrintToServer("[GuessWho] OpenFile(w+) returned null for %s", buffer);
|
|
return false;
|
|
}
|
|
|
|
public static MovePoints LoadMap(const char[] map, const char[] set = "default") {
|
|
char buffer[256];
|
|
BuildPath(Path_SM, buffer, sizeof(buffer), "data/guesswho/%s/%s.txt", map, set);
|
|
LoadConfigForMap(map);
|
|
File file = OpenFile(buffer, "r+");
|
|
if(file != null) {
|
|
char line[64];
|
|
char pieces[16][6];
|
|
file.ReadLine(line, sizeof(line)); // Skip header
|
|
float min = L4D2Direct_GetMapMaxFlowDistance();
|
|
float max = 0.0;
|
|
MovePoints points = new MovePoints();
|
|
while(file.ReadLine(line, sizeof(line))) {
|
|
ExplodeString(line, " ", pieces, 6, 16, false);
|
|
LocationMeta meta;
|
|
meta.pos[0] = StringToFloat(pieces[0]);
|
|
meta.pos[1] = StringToFloat(pieces[1]);
|
|
meta.pos[2] = StringToFloat(pieces[2]);
|
|
meta.ang[0] = StringToFloat(pieces[3]);
|
|
meta.ang[1] = StringToFloat(pieces[4]);
|
|
meta.ang[2] = StringToFloat(pieces[5]);
|
|
|
|
// Calculate the flow bounds
|
|
Address nav = L4D2Direct_GetTerrorNavArea(meta.pos);
|
|
if(nav == Address_Null) {
|
|
nav = L4D_GetNearestNavArea(meta.pos);
|
|
if(nav == Address_Null) {
|
|
PrintToServer("[GuessWho] WARN: POINT AT (%f,%f,%f) IS INVALID (NO NAV AREA); skipping", meta.pos[0], meta.pos[1], meta.pos[2]);
|
|
continue;
|
|
}
|
|
}
|
|
float flow = L4D2Direct_GetTerrorNavAreaFlow(nav);
|
|
if(flow < min) min = flow;
|
|
else if(flow > max) max = flow;
|
|
|
|
points.AddPoint(meta);
|
|
}
|
|
// Give some buffer space, to not trigger TOO FAR
|
|
min -= FLOW_BOUND_BUFFER;
|
|
max += FLOW_BOUND_BUFFER;
|
|
|
|
movePoints.SetBounds(min, max);
|
|
|
|
PrintToServer("[GuessWho] Loaded %d locations with bounds [%.0f, %.0f] for %s/%s", points.Length, min, max, map, set);
|
|
delete file;
|
|
return points;
|
|
}
|
|
PrintToServer("[GuessWho] No point data for %s/%s", map, set);
|
|
return null;
|
|
}
|
|
|
|
property float MinFlow {
|
|
public get() { return flowMin; }
|
|
}
|
|
property float MaxFlow {
|
|
public get() { return flowMax; }
|
|
}
|
|
|
|
public void SetBounds(float min, float max) {
|
|
flowMin = min;
|
|
flowMax = max;
|
|
}
|
|
|
|
public void GetRandomPoint(LocationMeta meta) {
|
|
if(this.Length == 0) return;
|
|
meta.runto = GetURandomFloat() < BOT_MOVE_RUN_CHANCE;
|
|
meta.attempts = 0;
|
|
this.GetArray(GetURandomInt() % this.Length, meta);
|
|
#if defined DEBUG_SHOW_POINTS
|
|
Effect_DrawBeamBoxRotatableToAll(meta.pos, DEBUG_POINT_VIEW_MIN, DEBUG_POINT_VIEW_MAX, NULL_VECTOR, g_iLaserIndex, 0, 0, 0, 150.0, 0.1, 0.1, 0, 0.0, {255, 0, 255, 120}, 0);
|
|
#endif
|
|
}
|
|
|
|
public bool GetRandomPointFar(const float src[3], float pos[3], float distanceAway = 100.0, int tries = 3) {
|
|
while(tries-- > 0) {
|
|
this.GetArray(GetURandomInt() % this.Length, pos);
|
|
if(FloatAbs(GetVectorDistance(src, pos)) > distanceAway) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool AddPoint(LocationMeta meta) {
|
|
bool hitLimit = false;
|
|
if(this.Length + 1 > MAX_VALID_LOCATIONS) {
|
|
PrintToServer("[GuessWho] Hit MAX_VALID_LOCATIONS (%d), clearing some locations", MAX_VALID_LOCATIONS);
|
|
this.Sort(Sort_Random, Sort_Float);
|
|
this.Erase(RoundFloat(MAX_VALID_LOCATIONS * MAX_VALID_LOCATIONS_KEEP_PERCENT));
|
|
hitLimit = true;
|
|
}
|
|
this.PushArray(meta);
|
|
return hitLimit;
|
|
}
|
|
} |