0 Members and 1 Guest are viewing this topic.
GOOD = $66CC66; BAD = $B22222; Nearby_Spawn_Max_Dist = 50;
unit Respawn_Controls;interfaceconst GOOD = $66CC66; BAD = $B22222; Nearby_Spawn_Max_Dist = 50;type TMap_Spawns = record Active: boolean; Style: byte; X, Y: LongInt;end;var Map_Data: array of TMap_Spawns; Active_Display: array[1..32] of boolean; Used_Spawns: array of boolean; Map_Is_Change: boolean; implementationfunction GetPieceSC3(Str, Reg: string; Number: Word): string;var Res: TStringList;begin try Res := File.CreateStringList; SplitRegExpr(QuoteRegExprMetaChars(Reg), Str, Res); Result := Res.Strings[Number]; except Result := ''; finally Res.Free; end;end;procedure LeaveGame(Player: TActivePlayer; Kicked: Boolean);begin Active_Display[Player.ID] := false;end;function Admins_Commands(Player: TActivePlayer; Text: string): boolean;var New_Spawn: TNewSpawnPoint; Data: TStringList; Lower_Case_Text: String; Temp_Dist, Last_Min_Dist: Single; i, Temp_Byte: byte; Found_Data: array[0..4] of byte;begin Result := false; Lower_Case_Text := LowerCase(Text); if Lower_Case_Text = '/displayspawns' then begin if Active_Display[Player.ID] then begin Active_Display[Player.ID] := false; Player.WriteConsole('displayspawns = false', BAD); for i := 1 to 254 do Player.WorldText(i+30, ' ', 1, $808080, 0.001, 0, 0); end else begin Active_Display[Player.ID] := true; Player.WriteConsole('displayspawns = true', GOOD); end; exit; end; if Lower_Case_Text = '/removeallspawn' then begin for i := 1 to 254 do if Map.Spawns[i].Active then begin if (Map.Spawns[i].Style = 0) or (Map.Spawns[i].Style = 1) or (Map.Spawns[i].Style = 2) or (Map.Spawns[i].Style = 3) or (Map.Spawns[i].Style = 4) then Map.Spawns[i].Active := false; inc(Temp_Byte, 1); end; Player.WriteConsole('Remove all '+inttostr(Temp_Byte)+' players spawnpoints.',GOOD); exit; end; if Lower_Case_Text = '/removenearspawn' then begin Last_Min_Dist := Nearby_Spawn_Max_Dist; for i := 1 to 254 do if Map.Spawns[i].Active then begin if (Map.Spawns[i].Style = 0) or (Map.Spawns[i].Style = 1) or (Map.Spawns[i].Style = 2) or (Map.Spawns[i].Style = 3) or (Map.Spawns[i].Style = 4) then begin Temp_Dist := Distance(Map.Spawns[i].X, Map.Spawns[i].Y, Player.X, Player.Y); if Temp_Dist < Nearby_Spawn_Max_Dist then if Temp_Dist < Last_Min_Dist then begin Last_Min_Dist := Temp_Dist; Temp_Byte := i; end; end; end; if Temp_Byte <> 0 then begin Player.WriteConsole('Remove player spawnpoint ID: '+inttostr(Temp_Byte)+', X: '+inttostr(Map.Spawns[Temp_Byte].X)+', Y: '+inttostr(Map.Spawns[Temp_Byte].Y),GOOD); Map.Spawns[Temp_Byte].Active := false; end else Player.WriteConsole('No player spawnpoints found nearby.',BAD); exit; end; if ExecRegExpr('^(\/createspawn\s[0-4]|\/createspawn)$',Lower_Case_Text) then begin try New_Spawn := TNewSpawnPoint.Create; New_Spawn.Active := true; New_Spawn.X := Round(Player.X); New_Spawn.y := Round(Player.Y-15); if Length(Lower_Case_Text) > 12 then New_Spawn.Style := strtoint(GetPieceSC3(Lower_Case_Text,' ', 1)) else New_Spawn.Style := 0; Map.AddSpawnPoint(New_Spawn); except Player.WriteConsole('Failed to add player spawnpoint!',BAD); finally New_Spawn.Free; Player.WriteConsole('Add player spawnpoint X: '+inttostr(Round(Player.X))+', Y: '+inttostr(Round(Player.Y)),GOOD); end; exit; end; if Lower_Case_Text = '/countspawns' then begin for i := 1 to 254 do if Map.Spawns[i].Active then begin if Map.Spawns[i].Style = 0 then inc(Found_Data[0],1); if Map.Spawns[i].Style = 1 then inc(Found_Data[1],1); if Map.Spawns[i].Style = 2 then inc(Found_Data[2],1); if Map.Spawns[i].Style = 3 then inc(Found_Data[3],1); if Map.Spawns[i].Style = 4 then inc(Found_Data[4],1); end; if Found_Data[0] + Found_Data[1] + Found_Data[2] + Found_Data[3] + Found_Data[4] > 0 then begin Player.WriteConsole('Found on this map '+Game.CurrentMap+' active player spawns: ', GOOD); Player.WriteConsole('No team spawns: '+inttostr(Found_Data[0]), GOOD); Player.WriteConsole('Alpha spawns: '+inttostr(Found_Data[1]), GOOD); Player.WriteConsole('Bravo spawns: '+inttostr(Found_Data[2]), GOOD); Player.WriteConsole('Charlie spawns: '+inttostr(Found_Data[3]), GOOD); Player.WriteConsole('Delta spawns: '+inttostr(Found_Data[4]), GOOD); end else Player.WriteConsole('No found player spawnpoint on this map '+Game.CurrentMap+'.', BAD); end; if Lower_Case_Text = '/saveallspawns' then begin Data := File.CreateStringList(); for i := 1 to 254 do if Map.Spawns[i].Active then begin if (Map.Spawns[i].Style = 0) or (Map.Spawns[i].Style = 1) or (Map.Spawns[i].Style = 2) or (Map.Spawns[i].Style = 3) or (Map.Spawns[i].Style = 4) then begin Data.Append('true'); Data.Append(inttostr(Map.Spawns[i].Style)); Data.Append(inttostr(Map.Spawns[i].X)); Data.Append(inttostr(Map.Spawns[i].Y)); end; end; if Data.Count > 0 then begin Data.SaveToFile(Script.Dir+'\data\'+Game.CurrentMap); Player.WriteConsole('New '+inttostr(Data.Count/4)+' player spawnpoints layout has been saved.', GOOD); end else Player.WriteConsole('No players spawn points to save.', BAD); Data.Free; end;end;procedure Timers(Ticks: integer);var i, c: byte;begin for i := 1 to 32 do if Players[i].Active then if Active_Display[i] then for c := 1 to 254 do if Map.Spawns[c].Active then begin case Map.Spawns[c].Style of 0: Players[i].WorldText(c+30, '+', 80, $808080, 0.08, Map.Spawns[c].X, Map.Spawns[c].Y); 1: Players[i].WorldText(c+30, '+', 80, $FF0000, 0.08, Map.Spawns[c].X, Map.Spawns[c].Y); 2: Players[i].WorldText(c+30, '+', 80, $0000FF, 0.08, Map.Spawns[c].X, Map.Spawns[c].Y); 3: Players[i].WorldText(c+30, '+', 80, $FFFF00, 0.08, Map.Spawns[c].X, Map.Spawns[c].Y); 4: Players[i].WorldText(c+30, '+', 80, $00FF00, 0.08, Map.Spawns[c].X, Map.Spawns[c].Y); end; end;end;procedure After_Change(NewMap: string);var New_Spawn: TNewSpawnPoint; i: byte; begin if Length(Map_Data) > 0 then begin for i := 1 to 254 do if Map.Spawns[i].Active then begin if (Map.Spawns[i].Style = 0) or (Map.Spawns[i].Style = 1) or (Map.Spawns[i].Style = 2) or (Map.Spawns[i].Style = 3) or (Map.Spawns[i].Style = 4) then Map.Spawns[i].Active := false; end; for i := 0 to Length(Map_Data)-1 do begin try New_Spawn := TNewSpawnPoint.Create; New_Spawn.Active := true; New_Spawn.X := Map_Data[i].X; New_Spawn.y := Map_Data[i].Y; New_Spawn.Style := Map_Data[i].Style; Map.AddSpawnPoint(New_Spawn); except Players.WriteConsole('Failed to add player spawnpoint! (ID: '+inttostr(i)+')',BAD); finally New_Spawn.Free; end; end; for i := 1 to 32 do if Players[i].Active then Players[i].ChangeTeam(0, TJoinSilent); end; Map_Is_Change := false;end;procedure Before_Change(NewMap: string);var Data: TStringList; Spawnpoints_Counts, i, Temp_Data_ID, Counts: byte;begin Map_Is_Change := true; SetLength(Map_Data, 0); if File.Exists(Script.Dir+'\data\'+NewMap) then begin Data := File.CreateStringListFromFile(Script.Dir+'\data\'+NewMap); if Data.Count > 0 then begin Spawnpoints_Counts := Data.Count/4; for i := 0 to Spawnpoints_Counts - 1 do if Data[Temp_Data_ID] = 'true' then begin SetLength(Map_Data, Counts + 1); SetLength(Used_Spawns, Counts + 1); Used_Spawns[Counts] := false; Map_Data[Counts].Active := true; Map_Data[Counts].Style := strtoint(Data[Temp_Data_ID+1]); Map_Data[Counts].X := strtoint(Data[Temp_Data_ID+2]); Map_Data[Counts].Y := strtoint(Data[Temp_Data_ID+3]); Temp_Data_ID := Temp_Data_ID + 4; inc(Counts, 1); end; end; Data.Free; end;end;function OnDamage(Shooter, Victim: TActivePlayer; Damage: Single; BulletId: byte): Single;begin if Map_Is_Change then result := 0 else Result := Damage;end;procedure ScriptDecl();var i:byte;begin Game.OnLeave := @LeaveGame; Game.OnAdminCommand := @Admins_Commands; Game.TickThreshold := 5; Game.OnClockTick := @Timers; Map.OnBeforeMapChange := @Before_Change; Map.OnAfterMapChange := @After_Change; for i := 1 to 32 do Players[i].OnDamage := @OnDamage;end;initializationbegin ScriptDecl();end;end.