amxmodx/editor/editor2/UnitAddMenu.pas

437 lines
17 KiB
ObjectPascal
Executable File

unit UnitAddMenu;
interface
uses SysUtils, Classes, Graphics, Dialogs, Windows;
function AddMenu: Boolean;
function AddPlayerMenu: Boolean;
function GetFirst(eStart: String; eSearchMain: Boolean): Integer;
function GetLast(eStart: String; eSearchMain: Boolean): Integer;
function AddIfDoesntExist(eInclude: String): Boolean;
implementation
uses UnitfrmMenuMaker, UnitfrmMain, UnitTextAnalyze, UnitFunc;
{ Normal Menu }
function AddMenu: Boolean;
var eColoredMenu, DefinedKeys: String;
i: integer;
eStr: TStringList;
begin
Result := GetFirst('public Show' + frmMenuMaker.txtMenuName.Text, True) = -1;
if not Result then
exit;
eStr := TStringList.Create;
{ Transform text }
eColoredMenu := frmMenuMaker.GetColoredMenu;
if frmMenuMaker.chkAppendOnlyMenuText.Checked then begin
frmMain.sciEditor.Lines.Add('// Created menu: ' + eColoredMenu);
exit;
end;
{ Add functions }
eStr.Add(Format('public Show%s(id) {', [frmMenuMaker.txtMenuName.Text]));
eStr.Add(' show_menu(id, Keys' + frmMenuMaker.txtMenuName.Text + ', "' + eColoredMenu + '", -1, "' + frmMenuMaker.txtMenuName.Text + '")');
if frmMenuMaker.chkAddComment.Checked then
eStr[eStr.Count -1] := eStr[eStr.Count -1] + ' // Display menu';
eStr.Add('}');
eStr.Add('');
eStr.Add('public Pressed' + frmMenuMaker.txtMenuName.Text + '(id, key) {');
if frmMenuMaker.chkAddComment.Checked then begin
eStr.Add(' /* Menu:');
for i := 0 to frmMenuMaker.rtfEditor.Lines.Count -1 do
eStr.Add(' * ' + frmMenuMaker.rtfEditor.Lines[i]);
eStr.Add(' */');
eStr.Add('');
end;
eStr.Add(' switch (key) {');
DefinedKeys := '';
for i := 1 to Length(frmMenuMaker.txtKeys.Text) do begin
if frmMenuMaker.txtKeys.Text[i] = '0' then begin
DefinedKeys := DefinedKeys + '|(1<<9)';
if frmMenuMaker.chkAddComment.Checked then
eStr.Add(' case 9: { // 0')
else
eStr.Add(' case 9: {');
eStr.Add(' ');
eStr.Add(' }');
end
else begin
DefinedKeys := DefinedKeys + '|(1<<' + IntToStr(StrToInt(frmMenuMaker.txtKeys.Text[i]) -1) + ')';
if frmMenuMaker.chkAddComment.Checked then
eStr.Add(' case ' + IntToStr(StrToInt(frmMenuMaker.txtKeys.Text[i]) -1) + ': { // ' + frmMenuMaker.txtKeys.Text[i])
else
eStr.Add(' case ' + IntToStr(StrToInt(frmMenuMaker.txtKeys.Text[i]) -1) + ': {');
eStr.Add(' ');
eStr.Add(' }');
end;
end;
Delete(DefinedKeys, 1, 1);
if frmMenuMaker.chkAddComment.Checked then
DefinedKeys := DefinedKeys + ' // Keys: ' + frmMenuMaker.txtKeys.Text;
eStr.Add(' }');
eStr.Add('}');
// Insert
AddIfDoesntExist('amxmodx');
i := GetFirst('#define', True) +2;
if i = 1 then
i := GetFirst('#include', True) +2;
if i = 1 then
i := 0;
frmMain.sciEditor.Lines.Insert(i, Format('#define Keys%s %s', [frmMenuMaker.txtMenuName.Text, DefinedKeys]));
frmMain.sciEditor.Lines.Text := frmMain.sciEditor.Lines.Text + #13 + eStr.Text;
if frmMenuMaker.chkRegisterMenuCommand.Checked then begin
i := GetFirst('register_plugin', True) +2;
if i = 1 then
i := GetFirst('public plugin_init()', True) +2;
if i = 1 then begin
eStr.Clear;
eStr.Add('public plugin_init() {');
eStr.Add(' register_menucmd(register_menuid("' + frmMenuMaker.txtMenuName.Text + '"), Keys' + frmMenuMaker.txtMenuName.Text + ', "Pressed' + frmMenuMaker.txtMenuName.Text + '")');
eStr.Add('}');
frmMain.sciEditor.Lines.Insert(GetFirst('#define', True) +2, '');
frmMain.sciEditor.Lines.Insert(GetFirst('#define', True) +3, eStr.Text);
end
else
frmMain.sciEditor.Lines.Insert(i, ' register_menucmd(register_menuid("' + frmMenuMaker.txtMenuName.Text + '"), Keys' + frmMenuMaker.txtMenuName.Text + ', "Pressed' + frmMenuMaker.txtMenuName.Text + '")');
end;
frmMain.SetModified;
eStr.Free;
UpdateList(frmMain.sciEditor.Lines.Text);
end;
{ Player Menu }
function AddPlayerMenu: Boolean;
function PrepareItem(eItem: String; eDisabled: Boolean): String; // Remove colors etc.
begin
eItem := StringReplace(eItem, '\w', '', [rfReplaceAll, rfIgnoreCase]);
eItem := StringReplace(eItem, '\y', '', [rfReplaceAll, rfIgnoreCase]);
eItem := StringReplace(eItem, '\r', '', [rfReplaceAll, rfIgnoreCase]);
eItem := StringReplace(eItem, '\d', '', [rfReplaceAll, rfIgnoreCase]);
eItem := StringReplace(eItem, '%n', '%i', [rfIgnoreCase]);
eItem := StringReplace(eItem, '%v', '%s', [rfIgnoreCase]);
if eDisabled then
eItem := '\d' + eItem
else
eItem := '\w' + eItem;
Result := eItem + '^n';
end;
var i: integer;
eStr: TStringList;
ePlayersFrom, ePlayersTo: Integer; // Players
ePlayerFormat: String;
eNext, eExit: Integer; // Next and Back/Exit
eNextText, eBackText, eExitText: String;
eCurLineIndex: Integer; // Current ..
eCurLine: String; // .. line
DefinedKeys: String; // Action Keys
begin
Result := GetFirst('public Show' + frmMenuMaker.txtMenu.Text, True) = -1;
if not Result then begin
MessageBox(frmMenuMaker.Handle, 'Menu already exists. Please choose another name.', 'Warning', MB_ICONWARNING);
exit;
end;
{
Kick player
$players(1,8,%n. %v)
$next(9,9. Next)
$exitorback(0, 0. Exit, 0. Back)
}
eCurLine := frmMenuMaker.rtfEditor.Lines[0];
eCurLineIndex := 0;
eNext := -1;
eExit := -1;
eStr := TStringList.Create;
// Prepare Values
try
{ Players }
eCurLineIndex := GetFirst('$players', False);
eCurLine := frmMenuMaker.rtfEditor.Lines[eCurLineIndex];
ePlayersFrom := StrToInt(Between(LowerCase(Trim(eCurLine)), '$players(', ','));
ePlayersTo := StrToInt(Between(Trim(LowerCase(eCurLine)), ',', ','));
while CountChars(eCurLine, ',') > 1 do
Delete(eCurLine, 1, 1);
ePlayerFormat := Between(LowerCase(eCurLine), ',', ')');
{ Next }
if GetFirst('$next', False) <> -1 then begin
eCurLineIndex := GetFirst('$next', False);
eCurLine := frmMenuMaker.rtfEditor.Lines[eCurLineIndex];
eNext := StrToInt(Trim(Between(eCurLine, '(', ',')));
eNextText := Between(eCurLine, ',', ')');
end;
{ Exit or Back }
if GetFirst('$exitorback', False) <> -1 then begin
eCurLineIndex := GetFirst('$exitorback', False);
eCurLine := frmMenuMaker.rtfEditor.Lines[eCurLineIndex];
eExit := StrToInt(Trim(Between(eCurLine, '(', ',')));
eExitText := Between(eCurLine, ',', ',');
while CountChars(eCurLine, ',') > 1 do
Delete(eCurLine, 1, 1);
eBackText := Between(eCurLine, ',', ')');
end;
except
MessageBox(frmMenuMaker.Handle, PChar(Format('Syntax error at line %s: ' + #13 + '%s', [IntToStr(eCurLineIndex +1), frmMenuMaker.rtfEditor.Lines[eCurLineIndex]])), 'Error', MB_ICONERROR);
Result := False;
exit;
end;
// Check Keys
{ Players }
if (ePlayersFrom < 0) or (ePlayersFrom > ePlayersTo) then begin
MessageBox(frmMenuMaker.Handle, 'Invalid start key (players)', 'Warning', MB_ICONWARNING);
Result := False;
exit;
end;
if (ePlayersTo < 0) or (ePlayersTo > 9) then begin
MessageBox(frmMenuMaker.Handle, 'Invalid stop key (players)', 'Warning', MB_ICONWARNING);
Result := False;
exit;
end;
{ Next, Exit and Custom keys}
eCurLine := '';
for i := ePlayersFrom to ePlayersTo do
eCurLine := eCurLine + IntToStr(i);
if Pos(IntToStr(eNext), eCurLine) > 0 then begin
MessageBox(frmMenuMaker.Handle, PChar(Format('"Next" key already in use (%s). Delete it or choose another one and try again.', [IntToStr(eNext)])), 'Warning', MB_ICONWARNING);
Result := False;
exit;
end;
if Pos(IntToStr(eExit), eCurLine) > 0 then begin
MessageBox(frmMenuMaker.Handle, PChar(Format('"Exit" key already in use (%s). Delete it or choose another one and try again.', [IntToStr(eExit)])), 'Warning', MB_ICONWARNING);
Result := False;
exit;
end;
eCurLine := eCurLine + IntToStr(eNext);
eCurLine := eCurLine + IntToStr(eExit);
// Insert Code
try
{ Includes }
AddIfDoesntExist('amxmodx');
AddIfDoesntExist('amxmisc');
{ Define Keys }
DefinedKeys := '';
if Length(eCurLine) <> 0 then begin
for i := 1 to Length(eCurLine) do begin
if eCurLine[i] = '0' then
DefinedKeys := DefinedKeys + '|(1<<9)'
else begin
eCurLine[i] := IntToStr(StrToInt(eCurLine[i]) -1)[1];
DefinedKeys := DefinedKeys + '|(1<<' + eCurLine[i] + ')';
end;
end;
Delete(DefinedKeys, 1, 1);
end;
i := GetLast('#define', True) +2;
if i = 1 then
i := GetLast('#include', True) +2;
if i = 1 then
i := 0;
frmMain.sciEditor.Lines.Insert(i, Format('#define Keys%s %s', [frmMenuMaker.txtMenu.Text, DefinedKeys]));
frmMain.sciEditor.Lines.Insert(i +1, 'new MenuPos' + frmMenuMaker.txtMenu.Text);
frmMain.sciEditor.Lines.Insert(i +2, 'new MenuPlayers' + frmMenuMAker.txtMenu.Text + '[32]');
{ Register }
i := GetFirst('register_plugin', True) +2;
if i = 1 then
i := GetFirst('public plugin_init()', True) +2;
if i = 1 then begin
eStr.Clear;
eStr.Add('public plugin_init() {');
eStr.Add(' register_menucmd(register_menuid("' + frmMenuMaker.txtMenu.Text + '"), Keys' + frmMenuMaker.txtMenu.Text + ', "Pressed' + frmMenuMaker.txtMenu.Text + '")');
eStr.Add('}');
frmMain.sciEditor.Lines.Insert(GetFirst('#define', True) +2, '');
frmMain.sciEditor.Lines.Insert(GetFirst('#define', True) +3, eStr.Text);
end
else
frmMain.sciEditor.Lines.Insert(i, ' register_menucmd(register_menuid("' + frmMenuMaker.txtMenu.Text + '"), Keys' + frmMenuMaker.txtMenu.Text + ', "Pressed' + frmMenuMaker.txtMenu.Text + '")');
{ Show Menu Functions (thx to xeroblood for code example) }
eStr.Clear;
eStr.Add('public Show' + frmMenuMaker.txtMenu.Text + '(id) {');
eStr.Add(' ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, MenuPos' + frmMenuMaker.txtMenu.Text + ' = 0)');
eStr.Add(' return PLUGIN_HANDLED');
eStr.Add('}');
eStr.Add('');
eStr.Add('public ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, position) {');
if frmMenuMaker.chkComments.Checked then
eStr.Add(' // Menu stuff //');
eStr.Add(' if (position < 0) { return 0; }');
eStr.Add(' ');
eStr.Add(' new i, k');
eStr.Add(' new MenuBody[255]');
eStr.Add(' new CurrentKey = ' + IntToStr(ePlayersFrom -1));
eStr.Add(' new Start = position * ' + IntToStr(ePlayersTo - ePlayersFrom));
eStr.Add(' new Num');
eStr.Add(' new UserName[32]');
eStr.Add(' ');
eStr.Add(' get_players(MenuPlayers' + frmMenuMaker.txtMenu.Text + ', Num)');
eStr.Add(' if (Start >= Num) { Start = position = MenuPos' + frmMenuMaker.txtMenu.Text + ' = 0; }');
eCurLine := frmMenuMaker.GetColoredMenu;
eCurLine := Copy(eCurLine, 1, Pos('$players', eCurLine) -3);
Insert('\R%d/%d^n\w', eCurLine, Pos('^n', eCurLine));
eStr.Add(' new Len = format(MenuBody, 255, "' + eCurLine + '", position+1, (Num / ' + IntToStr(ePlayersTo - ePlayersFrom) + ' + ((Num % ' + IntToStr(ePlayersTo - ePlayersFrom) + ') ? 1 : 0 )) )');
eStr.Add(' new End = Start + ' + IntToStr(ePlayersTo - ePlayersFrom));
if eExit = 0 then
eStr.Add(' new Keys = (1<<9)')
else
eStr.Add(' new Keys = (1<<' + IntToStr(eExit -1) + ')');
eStr.Add(' if (End > Num) { End = Num; }');
eStr.Add(' ');
eStr.Add(' for(i=Start;i<End;i++) {');
eStr.Add(' k = MenuPlayers' + frmMenuMaker.txtMenu.Text + '[i]');
eStr.Add(' get_user_name(k, UserName, 31)');
// Any conditions?
if (frmMenuMaker.chkImmunity.Checked) and (frmMenuMaker.chkAlive.Checked) then
eStr.Add(' if ((get_user_flags(k) & ADMIN_IMMUNITY) || !is_user_alive(k)) {')
else if (frmMenuMaker.chkImmunity.Checked) then
eStr.Add(' if (get_user_flags(k) & ADMIN_IMMUNITY) {')
else if (frmMenuMaker.chkAlive.Checked) then
eStr.Add(' if (!is_user_alive(k)) {');
if (frmMenuMaker.chkImmunity.Checked) or (frmMenuMaker.chkAlive.Checked) then begin
eStr.Add(' CurrentKey++');
eStr.Add(' Len += format(MenuBody[Len], (255-Len), "' + PrepareItem(ePlayerFormat, True) + '", CurrentKey, UserName)');
eStr.Add(' }');
eStr.Add(' else {');
eStr.Add(' Keys |= (1<<CurrentKey++)');
eStr.Add(' Len += format(MenuBody[Len], (255-Len), "' + PrepareItem(ePlayerFormat, False) + '", CurrentKey, UserName)');
eStr.Add(' }');
end
else begin
eStr.Add(' Keys |= (i<<CurrentKey++)');
eStr.Add(' Len += format(MenuBody[Len], (255-Len), "' + PrepareItem(ePlayerFormat, False) + '", CurrentKey, UserName)');
end;
eStr.Add(' }');
eStr.Add(' if (End != Num) {');
eStr.Add(' format(MenuBody[Len], (255-Len), "^n\w' + eNextText + '^n%s", position ? "\w' + eBackText + '" : "\w' + eExitText + '")');
eStr.Add(' Keys |= (1<<' + IntToStr(eNext -1) + ')');
eStr.Add(' }');
eStr.Add(' else {');
eStr.Add(' format(MenuBody[Len], (255-Len), "^n%s", position ? "\w' + eBackText + '" : "\w' + eExitText + '")');
eStr.Add(' }');
eStr.Add(' show_menu(id, Keys, MenuBody, -1)');
eStr.Add(' return 0');
eStr.Add('}');
eStr.Add('');
eStr.Add('public Pressed' + frmMenuMaker.txtMenu.Text + '(id, key) {');
eStr.Add(' switch (key) {');
if frmMenuMaker.chkComments.Checked then begin
if eNext <> 0 then
eStr.Add(' case ' + IntToStr(eNext -1) + ': ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, ++MenuPos' + frmMenuMaker.txtMenu.Text + ') // More Option')
else
eStr.Add(' case 9: ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, ++MenuPos' + frmMenuMaker.txtMenu.Text + ') // More Option');
if eExit <> 0 then
eStr.Add(' case ' + IntToStr(eExit -1) + ': ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, --MenuPos' + frmMenuMaker.txtMenu.Text + ') // Back Option')
else
eStr.Add(' case 9: ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, --MenuPos' + frmMenuMaker.txtMenu.Text + ') // Back Option');
end
else begin
if eNext <> 0 then
eStr.Add(' case ' + IntToStr(eNext -1) + ': ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, ++MenuPos' + frmMenuMaker.txtMenu.Text + ')')
else
eStr.Add(' case 9: ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, ++MenuPos' + frmMenuMaker.txtMenu.Text + ')');
if eExit <> 0 then
eStr.Add(' case ' + IntToStr(eExit -1) + ': ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, --MenuPos' + frmMenuMaker.txtMenu.Text + ')')
else
eStr.Add(' case 9: ShowMenu' + frmMenuMaker.txtMenu.Text + '(id, --MenuPos' + frmMenuMaker.txtMenu.Text + ')');
end;
eStr.Add(' default: {');
if frmMenuMaker.chkComments.Checked then
eStr.Add(' // Get User ID and Username');
eStr.Add(' new PlayerID = MenuPlayers' + frmMenuMaker.txtMenu.Text + '[MenuPos' + frmMenuMaker.txtMenu.Text + ' * ' + IntToStr(ePlayersTo - ePlayersFrom) + ' + key]');
eStr.Add(' new UserName[32]');
eStr.Add(' get_user_name(PlayerID, UserName, 31)');
if frmMenuMaker.chkComments.Checked then
eStr.Add(' // Do actions here')
else
eStr.Add(' ');
eStr.Add(' }');
eStr.Add(' }');
eStr.Add(' return PLUGIN_HANDLED');
eStr.Add('}');
frmMain.sciEditor.Lines.Text := frmMain.sciEditor.Lines.Text + #13 + eStr.Text;
except
MessageBox(frmMenuMaker.Handle, PChar('An error occured while inserting code!'), 'Warning', MB_ICONWARNING);
end;
frmMain.SetModified;
eStr.Free;
end;
{ Functions }
function GetFirst(eStart: String; eSearchMain: Boolean): Integer;
var i: integer;
begin
eStart := LowerCase(Trim(eStart));
Result := -1;
if eSearchMain then begin
for i := 0 to frmMain.sciEditor.Lines.Count -1 do begin
if Pos(eStart, LowerCase(Trim(frmMain.sciEditor.Lines[i]))) = 1 then begin
Result := i;
exit;
end;
end;
end
else begin
for i := 0 to frmMenuMaker.rtfEditor.Lines.Count -1 do begin
if Pos(eStart, LowerCase(Trim(frmMenuMaker.rtfEditor.Lines[i]))) = 1 then begin
Result := i;
exit;
end;
end;
end;
end;
function GetLast(eStart: String; eSearchMain: Boolean): Integer;
var i: integer;
begin
eStart := LowerCase(Trim(eStart));
Result := -1;
if eSearchMain then begin
for i := 0 to frmMain.sciEditor.Lines.Count -1 do begin
if Pos(eStart, LowerCase(Trim(frmMain.sciEditor.Lines[i]))) = 1 then
Result := i;
end;
end
else begin
for i := 0 to frmMenuMaker.rtfEditor.Lines.Count -1 do begin
if Pos(eStart, LowerCase(Trim(frmMenuMaker.rtfEditor.Lines[i]))) = 1 then
Result := i;
end;
end;
end;
function AddIfDoesntExist(eInclude: String): Boolean;
var i: integer;
eLine: String;
begin
Result := True;
eInclude := RemoveSpaces(LowerCase(eInclude));
for i := 0 to frmMain.sciEditor.Lines.Count -1 do begin
eLine := LowerCase(RemoveSpaces(frmMain.sciEditor.Lines[i]));
eLine := StringReplace(eLine, '<', '', [rfReplaceAll]);
eLine := StringReplace(eLine, '>', '', [rfReplaceAll]);
eLine := StringReplace(eLine, '"', '', [rfReplaceAll]);
if eLine = '#include' + eInclude then begin
Result := False;
exit;
end;
end;
i := GetLast('#include', True);
if i = -1 then
i := 0;
frmMain.sciEditor.Lines.Insert(i, '#include <' + eInclude + '>');
end;
end.