unit UnitMenuGenerators; interface uses SysUtils, Classes, Windows, Forms, Graphics; procedure GenerateSimpleMenu; { Yes, a part is copied from AMXX-Edit v2. I'm too lazy to rewrite everything... } { gaben } function AddOldMenu: Boolean; function AddOldPlayerMenu: Boolean; function GetFirst(eStart: String; eSearchMain: Boolean): Integer; function GetLast(eStart: String; eSearchMain: Boolean): Integer; function GetLine(eExpression: String; eAllowFunction, eBreak: Boolean): Integer; function AddIfDoesntExist(eInclude: String): Boolean; function GetColoredMenu: String; function PluginInitLine: Integer; implementation uses UnitCodeUtils, UnitfrmMain, UnitfrmMenuGenerator, UnitLanguages, UnitMainTools; function GetLine(eExpression: String; eAllowFunction, eBreak: Boolean): Integer; var i: integer; begin Result := -1; for i := 0 to frmMain.sciEditor.Lines.Count -1 do begin if IsAtStart(eExpression, frmMain.sciEditor.Lines[i], eAllowFunction) then begin Result := i; if eBreak then Break; end; end; end; procedure GenerateSimpleMenu; var eRP, eVL: Integer; // RegisterPlugin, VariableLine eStr: TStringList; eIndents, eInternalTitle: String; i: integer; begin { Get Line Numbers } eVL := GetLine('#define', False, False); if eVL = -1 then eVL := GetLine('#include', False, False); if eVL = -1 then eVL := 0; eRP := PluginInitLine; if eRP <> -1 then begin eInternalTitle := StringReplace(frmMenuGenerator.txtNTitle.Text, #32, '', [rfReplaceAll]); eStr := TStringList.Create; // Register Vars eVL := eVL +1; eIndents := GetIndents(eVL); eStr.Add(eIndents + 'new m' + eInternalTitle + ' // Menu'); eStr.Add(eIndents + 'new mcb' + eInternalTitle + ' // Menu Callback'); frmMain.sciEditor.Lines.Insert(eVL, eStr.Text); // Register function eRP := PluginInitLine; eIndents := GetIndents(eRP); eStr.Clear; eStr.Add(eIndents + '/* Menu ' + frmMenuGenerator.txtNTitle.Text + ' */'); eStr.Add(eIndents + '/* Use menu_display(id, m' + eInternalTitle + ', 0) to show the menu to an user. */'); eStr.Add(eIndents + 'm' + eInternalTitle + ' = menu_create("' + frmMenuGenerator.txtNTitle.Text + '", "mh_' + eInternalTitle + '")'); eStr.Add(eIndents + 'mcb' + eInternalTitle + ' = menu_makecallback("mcb_' + eInternalTitle + '")'); for i := 0 to frmMenuGenerator.lstNMenuItems.Items.Count -1 do eStr.Add(eIndents + 'menu_additem(m' + eInternalTitle + ', "' + frmMenuGenerator.lstNMenuItems.Items[i] + '", "ma_' + eInternalTitle + '", ' + frmMenuGenerator.cboAccess.Text + ', mcb' + eInternalTitle + ')'); eStr.Add(eIndents + '/* Menu End */'); frmMain.sciEditor.Lines.Insert(eRP, eStr.Text); // Rest eStr.Clear; eStr.Add(''); eStr.Add(''); eStr.Add('/* Menu ' + frmMenuGenerator.txtNTitle.Text + ' */'); eStr.Add(''); eStr.Add('public mh_' + eInternalTitle + '(id, menu, item) {'); eStr.Add(#9 + '/* This event is called when someone presses a key on this menu */'); eStr.Add('}'); eStr.Add(''); eStr.Add('public ma_' + eInternalTitle + '(id) {'); eStr.Add(#9 + '/* This event is called when an item was selected */'); eStr.Add('}'); eStr.Add(''); eStr.Add('public mcb_' + eInternalTitle + '(id, menu, item) {'); eStr.Add(#9 + '/* This is the callback-event, here you can set items enabled or disabled. */'); eStr.Add(#9 + '/* If you want to enable an item, use: return ITEM_ENABLED */'); eStr.Add(#9 + '/* If you want to disable an item, use: return ITEM_DISABLED */'); eStr.Add('}'); eStr.Add(''); frmMain.sciEditor.Lines.AddStrings(eStr); eStr.Free; end else MessageBox(frmMenuGenerator.Handle, PChar(lInvalidPlugin), PChar(Application.Title), MB_ICONERROR); ActiveDoc.Modified := True; frmMain.mnuModified.Caption := lModified; end; { Normal Menu } function AddOldMenu: Boolean; var eColoredMenu, DefinedKeys: String; i: integer; eStr: TStringList; begin Result := GetFirst('public Show' + frmMenuGenerator.txtMenuName.Text, True) = -1; if not Result then exit; eStr := TStringList.Create; { Transform text } eColoredMenu := GetColoredMenu; { Add functions } eStr.Add(Format('public Show%s(id) {', [frmMenuGenerator.txtMenuName.Text])); eStr.Add(' show_menu(id, Keys' + frmMenuGenerator.txtMenuName.Text + ', "' + eColoredMenu + '", -1, "' + frmMenuGenerator.txtMenuName.Text + '")'); if frmMenuGenerator.chkAddComment.Checked then eStr[eStr.Count -1] := eStr[eStr.Count -1] + ' // Display menu'; eStr.Add('}'); eStr.Add(''); eStr.Add('public Pressed' + frmMenuGenerator.txtMenuName.Text + '(id, key) {'); if frmMenuGenerator.chkAddComment.Checked then begin eStr.Add(' /* Menu:'); for i := 0 to frmMenuGenerator.rtfMenu.Lines.Count -1 do eStr.Add(' * ' + frmMenuGenerator.rtfMenu.Lines[i]); eStr.Add(' */'); eStr.Add(''); end; eStr.Add(' switch (key) {'); DefinedKeys := ''; for i := 1 to Length(frmMenuGenerator.txtKeys.Text) do begin if frmMenuGenerator.txtKeys.Text[i] = '0' then begin DefinedKeys := DefinedKeys + '|(1<<9)'; if frmMenuGenerator.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(frmMenuGenerator.txtKeys.Text[i]) -1) + ')'; if frmMenuGenerator.chkAddComment.Checked then eStr.Add(' case ' + IntToStr(StrToInt(frmMenuGenerator.txtKeys.Text[i]) -1) + ': { // ' + frmMenuGenerator.txtKeys.Text[i]) else eStr.Add(' case ' + IntToStr(StrToInt(frmMenuGenerator.txtKeys.Text[i]) -1) + ': {'); eStr.Add(' '); eStr.Add(' }'); end; end; Delete(DefinedKeys, 1, 1); if frmMenuGenerator.chkAddComment.Checked then DefinedKeys := DefinedKeys + ' // Keys: ' + frmMenuGenerator.txtKeys.Text; eStr.Add(' }'); eStr.Add('}'); // Insert AddIfDoesntExist('amxmodx'); i := GetLast('#define', True) +1; if i = 0 then i := GetLast('#include', True) +1; frmMain.sciEditor.Lines.Insert(i, Format('#define Keys%s %s', [frmMenuGenerator.txtMenuName.Text, DefinedKeys])); frmMain.sciEditor.Lines.Text := frmMain.sciEditor.Lines.Text + #13 + eStr.Text; if frmMenuGenerator.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("' + frmMenuGenerator.txtMenuName.Text + '"), Keys' + frmMenuGenerator.txtMenuName.Text + ', "Pressed' + frmMenuGenerator.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("' + frmMenuGenerator.txtMenuName.Text + '"), Keys' + frmMenuGenerator.txtMenuName.Text + ', "Pressed' + frmMenuGenerator.txtMenuName.Text + '")'); end; eStr.Free; ActiveDoc.Modified := True; frmMain.mnuModified.Caption := lModified; end; { Player Menu } function AddOldPlayerMenu: 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' + frmMenuGenerator.txtMenuName.Text, True) = -1; if not Result then begin MessageBox(frmMenuGenerator.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 := frmMenuGenerator.rtfMenu.Lines[0]; eCurLineIndex := 0; eNext := -1; eExit := -1; eStr := TStringList.Create; // Prepare Values try { Players } eCurLineIndex := GetFirst('$players', False); eCurLine := frmMenuGenerator.rtfMenu.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 := frmMenuGenerator.rtfMenu.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 := frmMenuGenerator.rtfMenu.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(frmMenuGenerator.Handle, PChar(Format('Syntax error at line %s: ' + #13 + '%s', [IntToStr(eCurLineIndex +1), frmMenuGenerator.rtfMenu.Lines[eCurLineIndex]])), 'Error', MB_ICONERROR); Result := False; exit; end; // Check Keys { Players } if (ePlayersFrom < 0) or (ePlayersFrom > ePlayersTo) then begin MessageBox(frmMenuGenerator.Handle, 'Invalid start key (players)', 'Warning', MB_ICONWARNING); Result := False; exit; end; if (ePlayersTo < 0) or (ePlayersTo > 9) then begin MessageBox(frmMenuGenerator.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(frmMenuGenerator.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(frmMenuGenerator.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) +1; if i = 0 then i := GetLast('#include', True) +1; frmMain.sciEditor.Lines.Insert(i, Format('#define Keys%s %s', [frmMenuGenerator.txtMenuName.Text, DefinedKeys])); frmMain.sciEditor.Lines.Insert(i +1, ''); frmMain.sciEditor.Lines.Insert(i +2, 'new MenuPos' + frmMenuGenerator.txtMenuName.Text); frmMain.sciEditor.Lines.Insert(i +3, 'new MenuPlayers' + frmMenuGenerator.txtMenuName.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("' + frmMenuGenerator.txtMenuName.Text + '"), Keys' + frmMenuGenerator.txtMenuName.Text + ', "Pressed' + frmMenuGenerator.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("' + frmMenuGenerator.txtMenuName.Text + '"), Keys' + frmMenuGenerator.txtMenuName.Text + ', "Pressed' + frmMenuGenerator.txtMenuName.Text + '")'); { Show Menu Functions (thx to xeroblood for code example) } eStr.Clear; eStr.Add('public Show' + frmMenuGenerator.txtMenuName.Text + '(id) {'); eStr.Add(' ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, MenuPos' + frmMenuGenerator.txtMenuName.Text + ' = 0)'); eStr.Add(' return PLUGIN_HANDLED'); eStr.Add('}'); eStr.Add(''); eStr.Add('public ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, position) {'); if frmMenuGenerator.chkAddComment.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' + frmMenuGenerator.txtMenuName.Text + ', Num)'); eStr.Add(' if (Start >= Num) { Start = position = MenuPos' + frmMenuGenerator.txtMenuName.Text + ' = 0; }'); eCurLine := GetColoredMenu; eCurLine := Copy(eCurLine, 1, Pos('$players', eCurLine) -5); Insert('\R%d/%d', 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' + frmMenuGenerator.txtMenuName.Text + '(id, ++MenuPos' + frmMenuGenerator.txtMenuName.Text + ') // More Option') else eStr.Add(' case 9: ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, ++MenuPos' + frmMenuGenerator.txtMenuName.Text + ') // More Option'); if eExit <> 0 then eStr.Add(' case ' + IntToStr(eExit -1) + ': ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, --MenuPos' + frmMenuGenerator.txtMenuName.Text + ') // Back Option') else eStr.Add(' case 9: ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, --MenuPos' + frmMenuGenerator.txtMenuName.Text + ') // Back Option'); end else begin if eNext <> 0 then eStr.Add(' case ' + IntToStr(eNext -1) + ': ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, ++MenuPos' + frmMenuGenerator.txtMenuName.Text + ')') else eStr.Add(' case 9: ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, ++MenuPos' + frmMenuGenerator.txtMenuName.Text + ')'); if eExit <> 0 then eStr.Add(' case ' + IntToStr(eExit -1) + ': ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, --MenuPos' + frmMenuGenerator.txtMenuName.Text + ')') else eStr.Add(' case 9: ShowMenu' + frmMenuGenerator.txtMenuName.Text + '(id, --MenuPos' + frmMenuGenerator.txtMenuName.Text + ')'); end; eStr.Add(' default: {'); if frmMenuGenerator.chkAddComment.Checked then eStr.Add(' // Get User ID and Username'); eStr.Add(' new PlayerID = MenuPlayers' + frmMenuGenerator.txtMenuName.Text + '[MenuPos' + frmMenuGenerator.txtMenuName.Text + ' * ' + IntToStr(ePlayersTo - ePlayersFrom) + ' + key]'); eStr.Add(' new UserName[32]'); eStr.Add(' get_user_name(PlayerID, UserName, 31)'); if frmMenuGenerator.chkAddComment.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(frmMenuGenerator.Handle, PChar('An error occured while inserting code!'), 'Warning', MB_ICONWARNING); end; eStr.Free; frmMain.mnuModified.Caption := lModified; ActiveDoc.Modified := True; 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 frmMenuGenerator.rtfMenu.Lines.Count -1 do begin if Pos(eStart, LowerCase(Trim(frmMenuGenerator.rtfMenu.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 frmMenuGenerator.rtfMenu.Lines.Count -1 do begin if Pos(eStart, LowerCase(Trim(frmMenuGenerator.rtfMenu.Lines[i]))) = 1 then Result := i; end; end; end; function AddIfDoesntExist(eInclude: String): Boolean; var i: integer; begin Result := True; eInclude := LowerCase(eInclude); for i := 0 to frmMain.sciEditor.Lines.Count -1 do begin if (Pos('<', frmMain.sciEditor.Lines[i]) <> 0) or (Pos('"', frmMain.sciEditor.Lines[i]) <> 0) then begin if LowerCase(Between(frmMain.sciEditor.Lines[i], '<', '>')) = eInclude then exit; if LowerCase(Between(frmMain.sciEditor.Lines[i], '"', '"')) = eInclude then exit; end; end; i := GetLast('#include', True); if i = -1 then i := 0; frmMain.sciEditor.Lines.Insert(i, '#include <' + eInclude + '>'); end; function GetColoredMenu: String; var i: integer; eCurColor: TColor; begin eCurColor := clWhite; Result := ''; for i := 0 to Length(frmMenuGenerator.rtfMenu.Lines.Text) -1 do begin frmMenuGenerator.rtfMenu.SelStart := i; if frmMenuGenerator.rtfMenu.SelAttributes.Color <> eCurColor then begin eCurColor := frmMenuGenerator.rtfMenu.SelAttributes.Color; case eCurColor of clWhite : Result := Result + '\w'; clYellow: Result := Result + '\y'; clRed : Result := Result + '\r'; clGray : Result := Result + '\d'; end; end; Result := Result + frmMenuGenerator.rtfMenu.Lines.Text[i+1]; end; frmMenuGenerator.rtfMenu.SelStart := 0; Result := StringReplace(Result, #13, '^n', [rfReplaceAll]); Result := StringReplace(Result, #10, '', [rfReplaceAll]); end; function PluginInitLine: Integer; begin Result := GetLine('register_concmd', True, False); if Result = -1 then Result := GetLine('register_clcmd', True, False); if Result = -1 then Result := GetLine('register_plugin', True, True); if Result = -1 then Result := GetLine('public plugin_init', True, True); end; end.