Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const
- FlagballMap = 'htf_FB_Classic3';
- ReturnOnScore = false; // moves the flag onto it's spawn point when a team scores
- AutoStart = false;
- AutoEnd = false;
- AdminCommands = true; // admin / commands
- PublicCommandsSlash = false; // public / commands
- PublicCommandsExcla = false; // ! commands
- BotName = 'Boogie Man';
- AppOnIdleInterval = 10; // 6 times per second (60 ticks/sec) / (10)
- FoulColor = $FF00FF00;
- AccidentalScoring = false;
- ReturnMessage = false; // after score; "Head back to the 40 yard mark, <team name>"
- FlagReadyMessage = false; // once players are allowed past the 40 yard mark (flag exits goalie area)
- WelcomeColor = $FFFBDA22;
- SayColor = $FF9C9F9F;
- SuccessColor = $FF0FA0C6;
- YieldColor = $FF7FBFBF;
- ErrorColor = $FFBF7F7F;
- PublicPassword = true;
- UnpauseCounterInitial = 3;
- SayName = true;
- BigConsole = true;
- type
- TPlayer = record
- JoinGame: boolean;
- end;
- var
- ActivateVariables, Passworded, KillAfter, CheckKillAfter, Ignore, StopNext, EndGame, SayMap, AlphaAlive, BravoAlive, MapsOnOff, Scored, StartOnIdle, DoubleCaps: boolean;
- HighestID, Gamemode, UnpauseCounter, LastTouch, teami, LastKill, LastDeath, AlphaNumber, BravoNumber: byte;
- DisablePlayerScore: array[1..32] of boolean;
- Players: array[1..32] of TPlayer;
- TextWidth : array[32..127] of single;
- Captures: array[1..32] of byte;
- Kills, Deaths: array[1..32] of word;
- pmvar: integer;
- procedure Greet(const Id: byte);
- begin
- WriteConsole(Id, 'Welcome to ' + ServerName + '!', WelcomeColor);
- WriteConsole(Id, 'forums.soldatrs.com - Home of Realistic / Survival', WelcomeColor);
- WriteConsole(Id, ' - Current Admin List -', WelcomeColor);
- WriteConsole(Id, ' Bendarr, Merox, DorkeyDear, Chikka, DutchFlame, Scream', WelcomeColor);
- WriteConsole(Id, ' Ant, JRedcorn, T-Boner, Lourenzo, CharlieCypher, Richmeister24', WelcomeColor);
- end;
- Procedure SetHighestID();
- var
- i: byte;
- begin
- HighestID := 1
- for i := 1 to 32 do
- if i > HighestID then
- HighestID := i
- end;
- // by J-Factor, modified by Curt (DorkeyDear)
- procedure DrawTextCenter(const Id: byte; Text: string; const Delay: integer; const Color: longint; const Scale: single; const XCoord, YCoord: integer);
- var
- i, c : byte;
- TotalWidth, Width, Height : single;
- begin
- TotalWidth := 0;
- Width := 0;
- Height := 202;
- for i := 1 to length(Text) do begin
- c := ord(Text[i]);
- if ((c > 31) and (c < 128)) then begin
- Width := Width + TextWidth[c];
- if (Width > TotalWidth) then
- TotalWidth := Width;
- end else if (c = 13) then begin
- Height := Height + 202;
- Width := 0;
- end;
- end;
- DrawText(ID, Copy(Text, 1, 58) + iif(Length(Text) <= 3, ' ', ''), Delay, Color, Scale, XCoord - Round(TotalWidth * Scale / 2), YCoord - Round(Height * Scale / 2));
- end;
- procedure Big(const Id: byte; const Text: string; const Color: longint);
- var
- Size: single;
- begin
- Size := 3.5 / Length(Text);
- if (Size > 0.33) then
- Size := 0.33;
- DrawTextCenter(Id, Text, 9 * Length(Text) + 85, Color, Size, 320, 360);
- end;
- function StrrPos(const Substr, S: string): integer;
- begin
- for Result := Length(S) - Length(Substr) + 1 downto 1 do
- if (Copy(S, Result, Length(Substr)) = Substr) then
- exit;
- Result := 0;
- end;
- procedure Say(const Id: byte; const Text: string; const Color: longint);
- var
- Pos: integer;
- begin
- if (Length(Text) <= 72) then
- WriteConsole(Id, Text, Color)
- else begin
- Pos := StrrPos(' ', Copy(Text, 1, 72));
- if (Pos = 0) then begin
- Pos := 72;
- WriteConsole(Id, Copy(Text, 1, 72), Color);
- end else
- WriteConsole(Id, Copy(Text, 1, Pos - 1), Color);
- Say(Id, Copy(Text, Pos + 1, Length(Text)), Color);
- end;
- end;
- procedure Move(Name: string; Team: byte);
- var
- i: byte;
- begin
- Name := LowerCase(Name);
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if (((Name = '') or (ContainsString(LowerCase(GetPlayerStat(i, 'Name')), Name))) and (GetPlayerStat(i, 'Team') <> Team)) then
- Command('/setteam' + InttoStr(Team) + ' ' + InttoStr(i));
- end;
- procedure SwapTeams;
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if GetPlayerStat(i, 'Active') then
- if GetPlayerStat(i, 'Team') = 1 then
- Command('/setteam2 ' + inttostr(i))
- else
- if GetPlayerStat(i, 'Team') = 2 then
- Command('/setteam1 ' + inttostr(i));
- end;
- procedure SpectateAll;
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if GetPlayerStat(i, 'Active') then
- if GetPlayerStat(i, 'Team') <> 5 then
- if (GetPlayerStat(i, 'Human') = true) then
- Command('/setteam5 ' + inttostr(i))
- end;
- function GetBall(): byte;
- var
- i: byte;
- begin
- Result := 255;
- for i := 0 to 128 do
- if (GetObjectStat(i, 'Active') = true) then
- if (GetObjectStat(i, 'Style') = 3) then begin
- Result := i;
- exit;
- end;
- end;
- procedure ReturnFlag();
- var
- i: byte;
- begin
- i := GetBall();
- if (i <> 255) then
- KillObject(i);
- end;
- function GamemodeName(const Gamemode: byte): string;
- begin
- case (Gamemode) of
- 0:
- Result := 'Deathmatch';
- 1:
- Result := 'Pointmatch';
- 2:
- Result := 'Team Deathmatch';
- 3:
- Result := 'Capture the Flag';
- 4:
- Result := 'Rambo Match';
- 5:
- Result := 'Infiltration';
- 6:
- Result := 'Hold the Flag';
- end;
- end;
- function TeamName(const Team: byte): string;
- begin
- case (Team) of
- 0:
- Result := 'Deathmatch';
- 1:
- Result := 'Alpha';
- 2:
- Result := 'Bravo';
- 3:
- Result := 'Charlie';
- 4:
- Result := 'Delta';
- 5:
- Result := 'Spectator';
- end;
- end;
- procedure WriteConsole2(const Id: byte; const Text: string; Color: longint);
- begin
- if (Id = 0) then begin
- WriteConsole(0, Text, Color);
- WriteLn(Text);
- end else if (Id = 255) then
- WriteLn(Text)
- else if ((Id >= 1) and (Id <= 32)) then
- if (GetPlayerStat(Id, 'Active') = true) then
- WriteConsole(Id, Text, Color);
- end;
- function ScoreColor(const Team: byte): longint;
- begin
- case (Team) of
- 1:
- Result := $FFDF3131;
- 2:
- Result := $FF3131DF;
- else
- Result := $FFFFFFFF;
- end;
- end;
- function TeamScore(const Team: byte): word;
- begin
- case (Team) of
- 1:
- Result := AlphaScore;
- 2:
- Result := BravoScore;
- 3:
- Result := CharlieScore;
- 4:
- Result := DeltaScore;
- end;
- end;
- function Explode(Source: string; const Delimiter: string): array of string;
- var
- Position, DelLength, ResLength: integer;
- begin
- DelLength := Length(Delimiter);
- Source := Source + Delimiter;
- repeat
- Position := Pos(Delimiter, Source);
- SetArrayLength(Result, ResLength + 1);
- Result[ResLength] := Copy(Source, 1, Position - 1);
- ResLength := ResLength + 1;
- Delete(Source, 1, Position + DelLength - 1);
- until (Position = 0);
- SetArrayLength(Result, ResLength - 1);
- end;
- function MapsListFile(): string;
- begin
- if (Gamemode = 6) then
- Result := 'mapslistFB.txt'
- else if (Gamemode = 2) then
- Result := 'mapslistTM.txt'
- else if (Gamemode = 3) then
- Result := 'mapslist.txt';
- end;
- function GetRandomMap(forbidden: string): string;
- var
- MapList: array of string;
- n,x: integer;
- begin
- MapList:=Explode(ReadFile(MapsListFile()),#13#10);
- n := 0;
- repeat
- if (n = 50) then begin
- WriteLn('GetRandomMap fails');
- exit;
- end;
- x := Random(0, GetArrayLength(MapList) - 1);
- n := n + 1;
- until ((MapList[x] <> '') and (MapList[x] <> forbidden));
- Result := MapList[x];
- {
- n:=GetArrayLength(MapList);
- If n > 0 then
- while true do begin
- x:=random(0,n-1);
- If MapList[x] <> forbidden then begin
- result:=MapList[x];
- exit;
- end;
- end
- else
- WriteLn('GetRandomMap fails');
- }
- end;
- procedure FixScore(const Team: byte);
- var
- i: byte;
- begin
- AlphaAlive := false;
- BravoAlive := false;
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if (GetPlayerStat(i, 'Alive') = true) then begin
- if (GetPlayerStat(i, 'Team') = 1) then
- AlphaAlive := true;
- if (GetPlayerStat(i, 'Team') = 2) then
- BravoAlive := true;
- if ((AlphaAlive) and (BravoAlive)) then begin
- StopNext := false;
- exit;
- end;
- end;
- if (AlphaAlive) and (not BravoAlive) and (Team <> 5) then begin
- SetTeamScore(1, AlphaScore - 1)
- end else if (BravoAlive) and (not AlphaAlive) and (Team <> 5) then begin
- SetTeamScore(2, BravoScore - 1)
- end;
- StopNext := false
- end;
- function CountPlayers(): byte;
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) and (GetPlayerStat(i, 'Team') < 5) then
- Result := Result + 1
- end;
- procedure CountTeams();
- var
- i: byte;
- begin
- AlphaNumber := 0
- BravoNumber := 0
- for i := 1 to HighestID do begin
- if (GetPlayerStat(i, 'Active') = true) then
- if (GetPlayerStat(i, 'Alive') = true) then
- if (GetPlayerStat(i, 'Team') = 1) then
- AlphaNumber := AlphaNumber + 1
- else if (GetPlayerStat(i, 'Team') = 2) then
- BravoNumber := BravoNumber + 1
- end;
- end;
- procedure KillAlpha();
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if (GetPlayerStat(i, 'Alive') = true) then
- if i <> LastKill then
- DoDamage(i, 4000)
- end;
- procedure KillBravo();
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if (GetPlayerStat(i, 'Alive') = true) then
- if i <> LastKill then
- DoDamage(i, 4000)
- end;
- procedure AnnounceWinner();
- var
- i: byte;
- begin
- for i := 1 to HighestID do begin
- if AlphaScore > BravoScore then
- if (GetPlayerStat(i, 'Active') = true) then
- if (GetPlayerStat(i, 'Team') = 1) then
- Big(0, (GetPlayerStat(i, 'Name')) + ' has won!', $FFFF0000)
- //E15353 5353E1
- if BravoScore > AlphaScore then
- if (GetPlayerStat(i, 'Active') = true) then
- if (GetPlayerStat(i, 'Team') = 2) then
- Big(0, (GetPlayerStat(i, 'Name')) + ' has won!', $FF0000FF)
- end;
- end;
- procedure AnnounceAlpha();
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if i <> LastKill then
- if i <> LastDeath then
- Big(i, 'Alpha team wins!', $FFFF0000);
- end;
- procedure AnnounceBravo();
- var
- i: byte;
- begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if i <> LastKill then
- if i <> LastDeath then
- Big(i, 'Bravo team wins!', $FF0000FF);
- end;
- function HighestSingles(const Data: array of single): array of integer;
- var
- i: integer;
- begin
- if (GetArrayLength(Data) > 0) then begin
- Result := [0];
- if (GetArrayLength(Data) > 1) then
- for i := 1 to GetArrayLength(Data) - 1 do begin
- if (Data[i] > Data[Result[0]]) then
- Result := [i]
- else if (Data[i] = Data[Result[0]]) then begin
- SetArrayLength(Result, GetArrayLength(Result) + 1);
- Result[GetArrayLength(Result) - 1] := i;
- end;
- end;
- end;
- end;
- procedure FindMVP();
- var
- i, j: byte;
- Scores: array of single;
- PlayersScores: array of byte;
- MVPs: array of integer;
- begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then begin
- Kills[i] := GetPlayerStat(i, 'Kills');
- if (Kills[i] > 0) then begin
- Deaths[i] := GetPlayerStat(i, 'Deaths');
- Captures[i] := GetPlayerStat(i, 'Flags');
- SetArrayLength(Scores, j + 1);
- SetArrayLength(PlayersScores, j + 1);
- Scores[j] := (Captures[i] + 1.0) * (Kills[i] + 1.0) / (Deaths[i] + 1.0);
- PlayersScores[j] := i;
- j := j + 1;
- end;
- end;
- MVPs := HighestSingles(Scores);
- if (GetArrayLength(MVPs) = 0) then
- WriteConsole(0, 'No MVPs...', YieldColor)
- else begin
- if (GetArrayLength(MVPs) > 1) then
- WriteConsole(0, 'Tie for MVP!', YieldColor);
- for i := 0 to GetArrayLength(MVPs) - 1 do
- WriteConsole(0, 'MVP: ' + GetPlayerStat(PlayersScores[MVPs[i]], 'Name'), YieldColor);
- end;
- end;
- procedure Stop();
- begin
- if (not Ignore) then begin
- WriteConsole(0, 'Game stopped...', $FFFFFFFF);
- WriteConsole(0, 'Rejoin to play CTF.', $FFFFFFFF);
- end;
- Command('/loadlist mapslist');
- Command('/loadcon soldat.ini');
- Command('/password');
- if (not Ignore) then begin
- GameStyle := 3
- Password := ''
- ActivateVariables := true;
- end;
- end;
- procedure Start();
- begin
- WriteConsole(0, 'Flagball starting, please rejoin...', $FFFFFFFF);
- Ignore := true;
- Stop();
- Ignore := false;
- Command('/loadlist mapslistFB');
- Command('/loadcon flagball.ini');
- Command('/password');
- ActivateVariables := true;
- end;
- procedure StartTM();
- begin
- WriteConsole(0, 'Teammatch starting, please rejoin...', $FFFFFFFF);
- Ignore := true;
- Stop();
- Ignore := false;
- Command('/loadlist mapslistTM');
- Command('/loadcon teammatch.ini');
- Command('/password');
- ActivateVariables := true;
- end;
- function CheckPlayerLocation(const Id: byte): boolean;
- begin
- if (GetPlayerStat(Id, 'Alive') = false) then
- exit;
- case (GetPlayerStat(Id, 'Team')) of
- 1:
- Result := GetPlayerStat(Id, 'X') < -712;
- 2:
- Result := GetPlayerStat(Id, 'X') > 712;
- end;
- if (Result) then begin
- DisablePlayerScore[Id] := true;
- DoDamage(Id, 2009);
- WriteConsole(0, 'Foul! ' + GetPlayerStat(Id, 'Name') + ' inside goalie zone! Penalty: killed', FoulColor);
- end;
- end;
- function CheckFlagLocation(): byte;
- var
- Ball: byte;
- X, Y: single;
- begin
- Ball := GetBall();
- if (Ball = 255) then
- exit;
- X := GetObjectStat(Ball, 'X');
- Y := GetObjectStat(Ball, 'Y');
- if ((X >= 912) and (X <= 1072) and (Y >= 624)) then
- Result := 2
- else if ((X >= -1072) and (X <= -912) and (Y >= 624)) then
- Result := 1;
- if ((Result > 0) and (not Scored)) then begin
- if (DisablePlayerScore[LastTouch]) then
- WriteConsole(0, 'Foul! ' + GetPlayerStat(LastTouch, 'Name') + ' scored while inside the goalie zone. Score does not count.', FoulColor)
- else if ((AccidentalScoring) or (GetPlayerStat(LastTouch, 'Team') = Result)) then begin
- SetTeamScore(Result, TeamScore(Result) + 1);
- WriteConsole(0, GetPlayerStat(LastTouch, 'Name') + iif(GetPlayerStat(LastTouch, 'Team') = Result, '', ' accidentally') + ' scored for ' + TeamName(Result) + ' team!', ScoreColor(Result));
- if (TeamScore(Result) >= ScoreLimit) then begin
- WriteConsole(0, TeamName(Result) + ' won the match!', ScoreColor(Result));
- DrawTextCenter(0, TeamName(Result) + ' won the match', 300, ScoreColor(Result), 0.1875, 320, 400);
- Command('/restart');
- end else begin
- DrawTextCenter(0, 'Score for ' + TeamName(Result) + ' team!', 250, ScoreColor(Result), 0.171875, 320, 400);
- if (ReturnMessage) then
- WriteConsole(0, 'Head back to the 40 yard mark, ' + TeamName(3 - Result), FoulColor);
- if (ReturnOnScore) then
- ReturnFlag();
- end;
- end;
- end;
- if (Scored) then begin
- Scored := (X < -710) or (X > 710);
- if ((not Scored) and (FlagReadyMessage)) then
- WriteConsole(0, 'Flag is on the field!', FoulColor);
- end else
- Scored := Result > 0;
- end;
- function OnPlayerCommand(Id: byte; Text: string): boolean;
- begin
- Result := false;
- if (PublicCommandsSlash) then
- if ((LowerCase(Text) = '/start') or (LowerCase(Text) = '/start flagball')) then
- Start()
- else if (LowerCase(Text) = '/stop') then
- Stop()
- else if (LowerCase(Text) = '/reset') then
- Command('/map ' + FlagballMap);
- if (LowerCase(Copy(Text, 1, 2)) = '/ ') then begin
- for teami := 1 to HighestID do
- if GetPlayerStat(teami, 'Active') then
- if GetPlayerStat(teami, 'Team') = GetPlayerStat(Id, 'Team') then
- Say(teami, '(' + TeamName(GetPlayerStat(teami, 'Team')) + ') ' + '[' + GetPlayerStat(Id, 'Name') + '] ' + Copy(Text, 3, Length(Text)), SuccessColor)
- WriteLn('(TEAM) ' + '[' + GetPlayerStat(Id, 'Name') + '] ' + Copy(Text, 3, Length(Text)));
- end;
- if (LowerCase(Copy(Text, 1, 4)) = '/pm ') then begin
- Result := true;
- pmvar := strtoint(Copy(Text, 5, 1));
- if GetPlayerStat(pmvar, 'Active') then begin
- if pmvar <> 255 then begin
- WriteConsole2(Id, 'To: ' + '[' + IDToName(pmvar) + '] ' + Copy(Text, 7, Length(Text)), SuccessColor);
- Say(pmvar, 'From: ' + '[' + GetPlayerStat(Id, 'Name') + '] ' + Copy(Text, 7, Length(Text)), SayColor);
- WriteLn('PM To: ' + '[' + IDToName(pmvar) + ']' + ' From: ' + '[' + GetPlayerStat(Id, 'Name') + ']' + ': ' + Copy(Text, 7, Length(Text)));
- end;
- end else if pmvar = 255 then begin
- WriteLn('Error: player #' + (Copy(Text, 5, 1)) + ' does not exist.');
- end else if pmvar <> 255 then begin
- WriteConsole2(Id, 'Error: player #' + (Copy(Text, 5, 1)) + ' does not exist.', ErrorColor);
- end;
- end;
- if (LowerCase(Text) = '/info') then begin
- Result := true;
- WriteConsole2(Id, ServerName + ' (' + ServerIP + ':' + InttoStr(ServerPort) + iif(PublicPassword, '/' + Password, '') + ')', SuccessColor);
- WriteConsole2(Id, 'Server v' + ServerVersion + ' for Soldat v' + Version, SuccessColor);
- WriteConsole2(Id, 'Gamemode: ' + GamemodeName(GameStyle), SuccessColor);
- WriteConsole2(Id, 'Current Map: ' + CurrentMap + '; Next Map: ' + NextMap, SuccessColor);
- WriteConsole2(Id, 'Type /server for server info', SuccessColor);
- end;
- if (LowerCase(Text) = '/server') then
- Greet(Id);
- end;
- function OnCommand(Id: byte; Text: string): boolean;
- var
- Team, i: byte;
- Color: longint;
- begin
- Result := false;
- if (AdminCommands) then
- if ((LowerCase(Text) = '/start') or (LowerCase(Text) = '/flagball')) then
- Start()
- else if (LowerCase(Text) = '/stop') then
- Stop()
- if ((LowerCase(Text) = '/starttm') or (LowerCase(Text) = '/teammatch') or (LowerCase(Text) = '/team')) then
- StartTM()
- else if (LowerCase(Text) = '/ctf') then
- Stop()
- else if (LowerCase(Text) = '/random') then
- Command('/map ' + (GetRandomMap(CurrentMap)));
- if (LowerCase(Text) = '/mapson') then begin
- MapsOnOff := true
- WriteConsole(0, '!map functions have been turned ON by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), ErrorColor)
- end else if (LowerCase(Text) = '/killon') then begin
- KillAfter := true
- DoubleCaps := false
- WriteConsole(0, 'After-round time has been turned OFF by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), ErrorColor)
- WriteConsole(0, 'Players will be killed after-round', ErrorColor)
- WriteConsole(0, 'Double Caps are allowed', ErrorColor)
- end else if (LowerCase(Text) = '/mapsoff') then begin
- MapsOnOff := false
- WriteConsole(0, '!map functions have been turned OFF by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), ErrorColor)
- end else if (LowerCase(Text) = '/killoff') then begin
- KillAfter := false
- DoubleCaps := true
- WriteConsole(0, 'After-round time has been turned ON by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), ErrorColor)
- WriteConsole(0, 'Players will not be killed after-round', ErrorColor)
- WriteConsole(0, 'Double Caps should not be allowed', ErrorColor)
- end else if (LowerCase(Text) = '/doubleson') then begin
- DoubleCaps := false
- WriteConsole(0, 'Double Caps have been turned ON by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), ErrorColor)
- end else if (LowerCase(Text) = '/doublesoff') then
- if (not KillAfter) then begin
- DoubleCaps := true
- WriteConsole(0, 'Double Caps have been turned OFF by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), ErrorColor)
- end else
- WriteConsole(Id, 'Type /killoff if you want to disallow double captures ', ErrorColor)
- if (LowerCase(Copy(Text, 1, 7)) = '/limit ') then begin
- if (Gamemode = 3) then begin
- Result := true
- Command('/limit ' + inttostr((strtoint(Copy(Text, 8, Length(Text))) + 1)))
- WriteConsole(0, 'Capture limit changed to ' + Copy(Text, 8, Length(Text)) + ' by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), SuccessColor)
- WriteConsole(Id, 'Note to Admins: Ignore the yellow server message', ErrorColor)
- end;
- if (Gamemode <> 3) then
- WriteConsole(0, 'Capture limit changed to ' + Copy(Text, 8, Length(Text)) + ' by ' + iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), SuccessColor)
- end else if (LowerCase(Copy(Text, 1, 9)) = '/setscore') then begin
- if Copy(Text, 10, 1) = ' ' then
- if (StrToInt(Copy(Text, 13, Length(Text)))) < (ScoreLimit - 1) then
- SetTeamScore(StrToInt(Copy(Text, 11, 1)), StrToInt(Copy(Text, 13, Length(Text))))
- else
- WriteConsole(ID, 'Please enter a value less than the capture limit', ErrorColor)
- else
- if (StrToInt(Copy(Text, 12, Length(Text)))) < (ScoreLimit - 1) then
- SetTeamScore(StrToInt(Copy(Text, 10, 1)), StrToInt(Copy(Text, 12, Length(Text))))
- else
- WriteConsole(ID, 'Please enter a value less than the capture limit', ErrorColor)
- end else if (LowerCase(Copy(Text, 1, 9)) = '/password') then begin
- Result := true;
- Command(Text);
- if (LowerCase(Text) = '/password') then begin
- WriteConsole2(iif(PublicPassword, 0, Id), 'Password cleared', SuccessColor)
- Passworded := false;
- end if (LowerCase(Text) <> '/password') then begin
- WriteConsole2(iif(PublicPassword, 0, Id), 'Password ' + iif(Password = '', 'set', 'changed from ' + Password) + ' to ' + Copy(Text, 11, Length(Text)), SuccessColor)
- Passworded := true;
- end;
- end;
- if (LowerCase(Text) = '/loadwep') then begin
- Say(0, iif(Id = 255, '', 'Admin ') + iif(SayName, iif(Id = 255, 'ARSSE Admin', GetPlayerStat(Id, 'Name')), '') + ' has reloaded the weapons', ErrorColor);
- end;
- if ((LowerCase(Copy(Text, 1, 6)) = '/pause') and (not Paused)) then begin
- if (UnpauseCounter = 0) then begin
- WriteConsole2(0, 'Game paused.', SuccessColor)
- end else begin
- UnpauseCounter := 0;
- WriteConsole2(0, 'Game unpause countdown canceled.', SuccessColor)
- end;
- end else if ((LowerCase(Copy(Text, 1, 8)) = '/unpause') and (Paused)) then
- WriteConsole2(0, 'Game unpaused.', $FFE739B1)
- else if (LowerCase(Copy(Text, 1, 5)) = '/move') then begin
- try
- if (ContainsString(Text, ' ')) then
- Team := StrPos(' ', Text) - 6
- else
- Team := Length(Text);
- case (LowerCase(Copy(Text, 6, Team))) of
- '0', 'dm', 'deathmatch':
- Team := 0;
- '1', 'a', 'alpha', 'red', 'r':
- Team := 1;
- '2', 'b', 'bravo', 'blue':
- Team := 2;
- '3', 'c', 'charlie', 'yellow', 'y':
- Team := 3;
- '4', 'd', 'delta', 'green', 'g':
- Team := 4;
- '5', 's', 'spectator', 'spectater', 'spect', 'spec':
- Team := 5;
- else
- StrtoInt(' ');
- end;
- except
- WriteConsole2(Id, 'Syntax: /move<team> [text]', ErrorColor);
- exit;
- end;
- if (ContainsString(Text, ' ')) then begin
- Text := Copy(Text, StrPos(' ', Text) + 1, Length(Text))
- Move(Text, Team);
- WriteConsole2(0, 'Moved players with "' + Text + '" to ' + TeamName(Team) + ' team.', SuccessColor);
- end else begin
- Move('', Team);
- WriteConsole2(0, 'Everybody set to ' + TeamName(Team) + ' team.', SuccessColor);
- end;
- end else if (LowerCase(Copy(Text, 1, 4)) = '/pm ') or (LowerCase(Copy(Text, 1, 4)) = '/am ') then begin
- Result := true;
- pmvar := strtoint(Copy(Text, 5, 1));
- if GetPlayerStat(pmvar, 'Active') then begin
- WriteConsole2(Id, 'To: ' + '[' + IDToName(pmvar) + '] ' + Copy(Text, 7, Length(Text)), SuccessColor);
- Say(pmvar, iif(Id = 255, '', 'Admin PM: ') + '[' + iif(SayName, iif(Id = 255, 'ARSSE PM', GetPlayerStat(Id, 'Name')), '') + '] ' + Copy(Text, 7, Length(Text)), SayColor);
- WriteLn('PM To: ' + '[' + IDToName(pmvar) + ']' + ' From: ' + '[' + iif(Id = 255, 'ARSSE', GetPlayerStat(Id, 'Name')) + ']' + ': ' + Copy(Text, 7, Length(Text)));
- end else if pmvar = 255 then begin
- WriteLn('Error: player #' + (Copy(Text, 5, 1)) + ' does not exist.');
- end else if pmvar <> 255 then begin
- WriteConsole2(Id, 'Error: player #' + (Copy(Text, 5, 1)) + ' does not exist.', ErrorColor);
- end;
- end else if (LowerCase(Copy(Text, 1, 5)) = '/say ') then begin
- Result := true;
- Say(0, iif(Id = 255, '', 'Admin: ') + '[' + iif(SayName, iif(Id = 255, 'ARSSE', GetPlayerStat(Id, 'Name')), '') + '] ' + Copy(Text, 6, Length(Text)), SayColor);
- end else if (LowerCase(Copy(Text, 1, 4)) = '/big') then begin
- Team := StrPos(' ', Text);
- if (Team = 0) then
- WriteConsole(Id, 'Syntax: /big[color] <message>', ErrorColor)
- else begin
- case (LowerCase(Copy(Text, 5, Team - 5))) of
- '', 'p', 'pink', 'm', 'magenta', 'battleye', 'battleeye', 'be':
- Color := $FFE739B1;
- '0', 'black':
- Color := $FF000000;
- 'white':
- Color := $FFFFFFFF;
- '1s':
- Color := $FFFEE8E8;
- '2s':
- Color := $FFE3E8FE;
- '3s':
- Color := $FFFEFEE8;
- '4s':
- Color := $FFE8FEE8;
- '5s':
- Color := $FFDF7AB0;
- 'ts':
- Color := $FFFEDA7C;
- '1', '1j', 'red', 'r', 'alpha', 'a':
- Color := $FFE15353;
- '2', '2j', 'blue', 'b', 'bravo':
- Color := $FF5353E1;
- '3', '3j', 'yellow', 'y', 'charlie', 'c':
- Color := $FFDFDF53;
- '4', '4j', 'green', 'g', 'delta', 'd':
- Color := $FF53DF53;
- '5', '5j', 'spectator', 'spectater', 'spect', 'spec', 's':
- Color := $FF52DD52;
- 'weaponmod', 'wm':
- Color := $FFFBDA22;
- 'mode':
- Color := $FF81DA41;
- 'connectionproblem', 'cp', 'problem', 'prob':
- Color := $FFE36952;
- 'join', 'kick', 'kicked':
- Color := $FFFCD822;
- 'nextmap', 'next', 'map', 'timeleft', 'time', 'left', 'playersleft', 'players':
- Color := $FF71F981;
- 'welcome', 'wel', 'w':
- Color := WelcomeColor;
- 'say':
- Color := SayColor;
- 'success', 'suc':
- Color := SuccessColor;
- 'yield':
- Color := YieldColor;
- 'error':
- Color := ErrorColor;
- else begin
- Color := $FFE739B1;
- WriteConsole(Id, 'Invalid color, default being used. Try a team color or black or white for example.', ErrorColor);
- end;
- end;
- if (BigConsole) then
- WriteConsole2(0, iif(SayName, iif(Id = 255, '', 'Admin: ') + '[' + iif(Id = 255, 'ARSSE', GetPlayerStat(Id, 'Name')) + '] ', '') + Copy(Text, Team + 1, Length(Text)), Color);
- Big(0, Copy(Text, Team + 1, Length(Text)), Color);
- end;
- end else if (LowerCase(Copy(Text, 1, 8)) = '/killmsg') then begin
- Big(0, Copy(Text, 10, Length(Text)), $FFEF3431);
- end else if (LowerCase(Text) = '/swap') or (LowerCase(Text) = '/swapteams') then begin
- SwapTeams;
- WriteConsole2(0, 'Teams Swapped.', SuccessColor)
- end else if LowerCase(Text) = '/specall' then begin
- SpectateAll;
- WriteConsole2(0, 'All players set as Spectators.', SuccessColor)
- end;
- end;
- procedure OnPlayerSpeak(Id: byte; Text: string);
- begin
- if (PublicCommandsExcla) then
- if ((LowerCase(Text) = '!start') or (LowerCase(Text) = '!start flagball')) then
- Start()
- else if (LowerCase(Text) = '!stop') then
- Stop()
- else if (LowerCase(Text) = '!reset') then
- Command('/map ' + FlagballMap);
- if (MapsOnOff) then begin
- if (LowerCase(Text) = '!maps') or (LowerCase(Text) = '!mapslist') or (LowerCase(Text) = '!maplist') then begin
- Say(0, 'All gamestyle maps are able to be chosen in ' + ServerName, SuccessColor)
- Say(0, 'Type !mapsDM, !mapsINF, !mapsHTF, or !mapsCTF to see a complete list', SuccessColor)
- end;
- if (LowerCase(Text) = '!mapsdm') then
- Say(0, 'Airpirates Arena Arena2 Arena3 Bigfalls Blox Bridge Bunker Cambodia Daybreak DesertWind Factory Flashback HH Island2k5 Jungle Krab Lagrange Leaf MrSnowman RatCave Rok Shau Tropiccave Veoto', SuccessColor)
- else if (LowerCase(Text) = '!mapshtf') then
- Say(0, 'htf_Arch htf_Baire htf_Boxed htf_Desert htf_Dusk htf_Erbium htf_Muygen htf_Nuclear htf_Prison htf_Rubik htf_Void htf_Zajacz', SuccessColor)
- else if (LowerCase(Text) = '!mapsctf') then
- Say(0, 'ctf_Amazonia ctf_Ash ctf_AshZ ctf_B2b ctf_B2bZ ctf_Blade ctf_Cobra ctf_Conquest ctf_Crashed ctf_Crashed2 ctf_Death2 ctf_DeathZ ctf_Division ctf_Dropdown2 ctf_Equinnauxe ctf_Equinox ctf_Guardian ctf_Hormone ctf_IceBeam ctf_Kampf ctf_Lanubya ctf_Lanubya2 ctf_Lanubya3 ctf_Laos ctf_LaosZ ctf_MFM2 ctf_Maya ctf_Maya2 ctf_Maya3 ctf_Nuubia ctf_Nuubia2 ctf_Paradigm ctf_Raspberry ctf_Razer ctf_Rotten ctf_Ruins ctf_RuinsZ ctf_Run ctf_Snakebite ctf_SnakebiteZ ctf_Steel ctf_Viet ctf_VietZ ctf_Voland ctf_VolandZ ctf_X', SuccessColor)
- else if (LowerCase(Text) = '!mapsinf') then
- Say(0, 'inf_Abel inf_Argy inf_Fortress inf_Industrial inf_Messner inf_Moonshine inf_Outpost inf_Warehouse', SuccessColor)
- if (LowerCase(Text) = '!mvp') then
- FindMVP();
- if Passworded = true then begin
- if (LowerCase(Text) = '!nextmap') or (LowerCase(Text) = '!next') then
- Command('/nextmap')
- else if (LowerCase(Text) = '!res') or (LowerCase(Text) = '!restart') or (LowerCase(Text) = '!r') or (LowerCase(Text) = '!re') then
- Command('/restart')
- else if (LowerCase(Text) = '!p') or (LowerCase(Text) = '!pause') then
- Command('/pause')
- else if (LowerCase(Text) = '!up') or (LowerCase(Text) = '!unpause') then begin
- // Command('/unpause')
- if (UnpauseCounterInitial = 0) then
- WriteConsole2(0, 'Game unpaused.', $FFE739B1)
- else
- UnpauseCounter := UnpauseCounterInitial + 1;
- //end;
- end else if (Copy(LowerCase(Text), 1, 5) = '!map ') then
- Command('/' + Copy(Text, 2, Length(Text)))
- else if (LowerCase(Text) = '!random') or (LowerCase(Text) = '!rand') then
- Command('/map ' + (GetRandomMap(CurrentMap)))
- else if (LowerCase(Text) = '!swap') then begin
- SwapTeams();
- WriteConsole2(0, 'Teams Swapped.', SuccessColor)
- end;
- end;
- if (LowerCase(Text) = '!1') or (LowerCase(Text) = '!alpha') or (LowerCase(Text) = '!a') then
- Command('/setteam1 ' + IntToStr(Id))
- else if (LowerCase(Text) = '!2') or (LowerCase(Text) = '!bravo') or (LowerCase(Text) = '!b') then
- Command('/setteam2 ' + IntToStr(Id))
- else if (LowerCase(Text) = '!5') or (LowerCase(Text) = '!spec') or (LowerCase(Text) = '!spectate') or (LowerCase(Text) = '!spectator') or (LowerCase(Text) = '!s') then
- Command('/setteam5 ' + IntToStr(Id));
- if (Gamemode = 2) then begin
- if (LowerCase(Text) = '!3') or (LowerCase(Text) = '!charlie') then
- Command('/setteam3 ' + IntToStr(Id))
- else if (LowerCase(Text) = '!4') or (LowerCase(Text) = '!delta') then
- Command('/setteam4 ' + IntToStr(Id));
- end;
- end;
- end;
- procedure OnFlagScore(ID, TeamFlag: byte);
- begin
- LastKill := 0;
- LastDeath := 0;
- if (DoubleCaps) or (not KillAfter) then begin
- CountTeams();
- if (AlphaNumber > 0) then
- if (BravoNumber = 0) then begin
- SetTeamScore(1, AlphaScore - 1)
- //if CountPlayers <> AlphaNumber then begin
- if (CountPlayers > 1) then begin
- if (CountPlayers <> AlphaNumber) then
- WriteConsole(0, 'Double Captures have been disabled and have no effect', $FFFF0000)
- else
- WriteConsole(0, 'There is no enemy team', $FFFF0000)
- end else
- WriteConsole(ID, 'Stop playing with yourself loser', $FFFF0000)
- end;
- if (BravoNumber > 0) then
- if (AlphaNumber = 0) then begin
- SetTeamScore(2, BravoScore - 1)
- if CountPlayers > 1 then begin
- if CountPlayers <> BravoNumber then
- WriteConsole(0, 'Double Captures have been disabled and have no effect', $FF0000FF)
- else
- WriteConsole(0, 'There is no enemy team', $FF0000FF)
- end else
- WriteConsole(ID, 'Stop playing with yourself loser', $FF0000FF)
- end;
- end;
- end;
- procedure OnPlayerKill(Killer, Victim: byte; Weapon: string);
- begin
- If (GetPlayerStat(Killer, 'Team')) <> (GetPlayerStat(Victim, 'Team')) then begin
- LastKill := Killer
- LastDeath := Victim
- if (KillAfter) and (not CheckKillAfter) then
- CheckKillAfter := true;
- end;
- end;
- procedure AppOnIdle(Ticks: cardinal);
- var
- i: byte;
- begin
- if (ActivateVariables) then begin
- Gamemode := GameStyle
- Passworded := Password <> '';
- if (Gamemode = 3) then
- if Passworded = false then
- KillAfter := true
- if (Gamemode <> 6) then
- MapsOnOff := true
- else begin
- MapsOnOff := false
- Command('/limit 6')
- end;
- ActivateVariables := false;
- end;
- if (CheckKillAfter) and (Gamemode = 3) then begin
- if (AlphaScore < (ScoreLimit - 1)) and (BravoScore < (ScoreLimit - 1)) then
- if NumPlayers > 1 then begin
- CountTeams();
- if AlphaNumber > 0 then
- if BravoNumber = 0 then
- KillAlpha();
- if AlphaNumber = 0 then
- if BravoNumber > 0 then
- KillBravo();
- end;
- CheckKillAfter := false
- end;
- if (UnpauseCounter > 0) then begin
- UnpauseCounter := UnpauseCounter - 1;
- if (UnpauseCounter = 0) then begin
- Command('/unpause');
- WriteConsole2(0, 'Game unpaused.', $FFE739B1);
- end else
- WriteConsole2(0, 'Game unpaused in ' + InttoStr(UnpauseCounter) + '...', YieldColor);
- end;
- if (SayMap) then begin
- WriteConsole(0, 'Next Map: ' + NextMap , $FF71F981);
- SayMap := false;
- end;
- if (Gamemode = 3) then begin
- if (EndGame) then
- if (AlphaScore = 0) and (BravoScore = 0) then
- EndGame := false
- if EndGame = false then
- if (not StopNext) then begin
- if AlphaScore >= (ScoreLimit - 1) then begin
- if CountPlayers > 2 then
- AnnounceAlpha()
- else
- AnnounceWinner();
- EndGame := true;
- Command('/nextmap');
- end;
- if BravoScore >= (ScoreLimit - 1) then begin
- if CountPlayers > 2 then
- AnnounceBravo()
- else
- AnnounceWinner();
- EndGame := true
- Command('/nextmap')
- end;
- end;
- end;
- if (Gamemode = 6) then begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if ((GetPlayerStat(i, 'Human') = true) and (GetPlayerStat(i, 'Name') <> BotName) and ((GetPlayerStat(i, 'Team') = 1) or (GetPlayerStat(i, 'Team') = 2))) then
- CheckPlayerLocation(i);
- CheckFlagLocation();
- if ((AutoEnd) and (NumPlayers = 0)) then
- Stop();
- if (BotName <> '') then begin
- for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if ((GetPlayerStat(i, 'Human') = false) and (GetPlayerStat(i, 'Team') = 3) and (GetPlayerStat(i, 'Name') = BotName)) then
- exit;
- Command('/addbot3 ' + BotName);
- end;
- end else begin
- if (StartOnIdle) then
- Start()
- else for i := 1 to HighestID do
- if (GetPlayerStat(i, 'Active') = true) then
- if ((GetPlayerStat(i, 'Human') = false) and (GetPlayerStat(i, 'Team') = 3) and (GetPlayerStat(i, 'Name') = BotName)) then
- KickPlayer(i);
- end;
- end;
- function OnPlayerDamage(Victim, Shooter: byte; Damage: integer): integer;
- var
- Ticks: cardinal;
- begin
- if (BotName <> '') then begin
- if ((GetPlayerStat(Victim, 'Human') = false) and (GetPlayerStat(Victim, 'Team') = 3) and (GetPlayerStat(Victim, 'Name') = BotName)) then begin
- Result := 0;
- Ticks := GetTickCount();
- if (Ticks mod AppOnIdleInterval = 0) then
- if (Ticks mod 60 <> 0) then
- AppOnIdle(Ticks);
- end else
- Result := Damage;
- end else
- Result := Damage;
- end;
- procedure OnMapChange(NewMap: string);
- begin
- SayMap := true;
- if (Gamemode = 6) then
- if (NewMap <> FlagballMap) then
- Command('/map ' + FlagballMap);
- end;
- procedure OnFlagGrab(Id, Team: byte; Base: boolean);
- begin
- LastTouch := Id;
- end;
- procedure OnPlayerRespawn(Id: byte);
- begin
- DisablePlayerScore[Id] := false;
- end;
- procedure OnJoinGame(Id, Team: byte);
- begin
- SetHighestID();
- Players[Id].JoinGame := true;
- if (Gamemode = 3) then
- StopNext := true;
- if (Gamemode = 6) then begin
- WriteConsole(Id, 'Welcome to |D) Flagball', $FFFFFFFF);
- WriteConsole(Id, 'If you are new, read the rules located above the arena', $FFFFFFFF);
- end;
- if (Gamemode = 2) then begin
- WriteConsole(Id, 'Welcome to |D) TeamMatch R/S', $FFFFFFFF);
- WriteConsole(Id, 'Choose any map: DM, HTF, CTF, etc', $FFFFFFFF);
- WriteConsole(Id, 'Kill limit is 25', $FFFFFFFF);
- end;
- end;
- procedure AfterJoinGame(Id, Team: byte);
- begin
- Greet(Id);
- end;
- procedure OnJoinTeam(Id, Team: byte);
- begin
- if (Gamemode = 3) then
- FixScore(Team);
- if (Players[Id].JoinGame) then begin
- Players[Id].JoinGame := false;
- AfterJoinGame(Id, Team);
- end;
- end;
- procedure OnLeaveGame(Id, Team: byte; Kicked: boolean);
- begin
- if Id = HighestID then
- SetHighestID();
- Players[Id].JoinGame := false;
- end;
- procedure ActivateServer();
- begin
- ActivateVariables := true;
- TextWidth[32] := 103.20;
- TextWidth[33] := 114.67;
- TextWidth[34] := 74.53;
- TextWidth[35] := 5.73;
- TextWidth[36] := 206.40;
- TextWidth[37] := 235.07;
- TextWidth[38] := 212.13;
- TextWidth[39] := 40.13;
- TextWidth[40] := 103.20;
- TextWidth[41] := 103.20;
- TextWidth[42] := 137.60;
- TextWidth[43] := 229.33;
- TextWidth[44] := 103.20;
- TextWidth[45] := 91.73;
- TextWidth[46] := 103.20;
- TextWidth[47] := 97.47;
- TextWidth[48] := 206.40;
- TextWidth[49] := 206.40;
- TextWidth[50] := 206.40;
- TextWidth[51] := 206.40;
- TextWidth[52] := 206.40;
- TextWidth[53] := 206.40;
- TextWidth[54] := 206.40;
- TextWidth[55] := 206.40;
- TextWidth[56] := 206.40;
- TextWidth[57] := 206.40;
- TextWidth[58] := 103.20;
- TextWidth[59] := 103.20;
- TextWidth[60] := 229.33;
- TextWidth[61] := 229.33;
- TextWidth[62] := 229.33;
- TextWidth[63] := 177.73;
- TextWidth[64] := 275.20;
- TextWidth[65] := 200.67;
- TextWidth[66] := 212.13;
- TextWidth[67] := 206.40;
- TextWidth[68] := 223.60;
- TextWidth[69] := 194.93;
- TextWidth[70] := 177.73;
- TextWidth[71] := 223.60;
- TextWidth[72] := 235.07;
- TextWidth[73] := 97.47;
- TextWidth[74] := 183.47;
- TextWidth[75] := 200.67;
- TextWidth[76] := 177.73;
- TextWidth[77] := 246.53;
- TextWidth[78] := 229.33;
- TextWidth[79] := 235.07;
- TextWidth[80] := 200.67;
- TextWidth[81] := 235.07;
- TextWidth[82] := 212.13;
- TextWidth[83] := 212.13;
- TextWidth[84] := 160.53;
- TextWidth[85] := 223.60;
- TextWidth[86] := 189.20;
- TextWidth[87] := 235.07;
- TextWidth[88] := 194.93;
- TextWidth[89] := 183.47;
- TextWidth[90] := 189.20;
- TextWidth[91] := 103.20;
- TextWidth[92] := 97.47;
- TextWidth[93] := 103.20;
- TextWidth[94] := 275.20;
- TextWidth[95] := 137.60;
- TextWidth[96] := 137.60;
- TextWidth[97] := 172;
- TextWidth[98] := 172;
- TextWidth[99] := 172;
- TextWidth[100] := 200.67;
- TextWidth[101] := 160.53;
- TextWidth[102] := 149.07;
- TextWidth[103] := 183.47;
- TextWidth[104] := 189.20;
- TextWidth[105] := 74.53;
- TextWidth[106] := 154.80;
- TextWidth[107] := 166.27;
- TextWidth[108] := 149.07;
- TextWidth[109] := 206.40;
- TextWidth[110] := 189.20;
- TextWidth[111] := 189.20;
- TextWidth[112] := 166.27;
- TextWidth[113] := 189.20;
- TextWidth[114] := 166.27;
- TextWidth[115] := 177.73;
- TextWidth[116] := 143.33;
- TextWidth[117] := 183.47;
- TextWidth[118] := 160.53;
- TextWidth[119] := 200.67;
- TextWidth[120] := 160.53;
- TextWidth[121] := 154.80;
- TextWidth[122] := 172;
- TextWidth[123] := 137.60;
- TextWidth[124] := 137.60;
- TextWidth[125] := 137.60;
- TextWidth[126] := 229.33;
- TextWidth[127] := 166.27;
- StartOnIdle := AutoStart;
- end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement