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 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.