123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- unit effectlistframeunit;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, Forms, Controls, StdCtrls, Menus, database, fpjson,
- LCLTranslator;
- type
- { TEffectListFrame }
- TEffectListFrame = class(TFrame)
- CopyEffectMenuItem: TMenuItem;
- CutEffectMenuItem: TMenuItem;
- DeleteEffectMenuItem: TMenuItem;
- EditEffectMenuItem: TMenuItem;
- EffectListBox: TListBox;
- PasteEffectMenuItem: TMenuItem;
- EffectPopupMenu: TPopupMenu;
- procedure CopyEffectMenuItemClick(Sender: TObject);
- procedure CutEffectMenuItemClick(Sender: TObject);
- procedure DeleteEffectMenuItemClick(Sender: TObject);
- procedure EditEffectMenuItemClick(Sender: TObject);
- procedure EffectListBoxDblClick(Sender: TObject);
- procedure EffectListBoxKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure EffectListBoxMouseUp(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure PasteEffectMenuItemClick(Sender: TObject);
- private
- { This is handled never disposed, handled by outer object. }
- Db: TDatabase;
- { This is disposed by the JSON object in the database, it's NOT handled
- by TEffectListFrame }
- EffectList: TJSONArray;
- procedure UpdateEffects;
- function EffectToText(Effect: TJSONObject): String;
- function IsRealEffectSelected: Boolean;
- procedure AddNewEffect;
- procedure EditSelectedEffect;
- procedure ShowPopupMenu;
- procedure PasteFromClipboard;
- procedure CopySelectedToClipboard;
- procedure DeleteSelectedEffects;
- public
- procedure SetDatabase(ADb: TDatabase);
- procedure SetEffectList(AEffectList: TJSONArray);
- end;
- resourcestring
- AddNewEffectStr = '<Add new effect>';
- EffectRecoverHp = 'Recover HP: ';
- EffectRecoverMp = 'Recover MP: ';
- EffectGainTp = 'Gain TP: ';
- EffectAddState = 'Add state: ';
- EffectRemoveState = 'Remove state: ';
- EffectAddBuff = 'Add buff: ';
- EffectAddDebuff = 'Add debuff: ';
- EffectRemoveBuff = 'Remove buff: ';
- DurationTurns = ' turns'; {TODO: add correct language-dependent form}
- EffectRemoveDebuff = 'Remove debuff: ';
- EffectSpecialEscape = 'Escape from battle';
- EffectSpecialUnknown = 'Special: (unknown)';
- EffectGrow = 'Increase param: ';
- EffectLearnSkill = 'Learn skill: ';
- EffectCommonEvent = 'Common event: ';
- EffectUnknownEffect = '(Unknown effect)';
- EditEffectMenuItemStr = 'Edit';
- AddNewEffectMenuItemStr = 'Add new effect';
- implementation
- uses
- effectselector, clipboardhelper, listboxhelper, LCLType;
- {$R *.lfm}
- { TEffectListFrame }
- procedure TEffectListFrame.EffectListBoxDblClick(Sender: TObject);
- begin
- if not IsRealEffectSelected then
- AddNewEffect
- else
- EditSelectedEffect
- end;
- procedure TEffectListFrame.EffectListBoxKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- begin
- begin
- if Key = VK_DELETE then
- DeleteSelectedEffects;
- if Key = VK_RETURN then
- EffectListBoxDblClick(Sender);
- end;
- end;
- procedure TEffectListFrame.EditEffectMenuItemClick(Sender: TObject);
- begin
- if not IsRealEffectSelected then
- AddNewEffect
- else
- EditSelectedEffect
- end;
- procedure TEffectListFrame.CutEffectMenuItemClick(Sender: TObject);
- begin
- CopySelectedToClipboard;
- DeleteSelectedEffects
- end;
- procedure TEffectListFrame.DeleteEffectMenuItemClick(Sender: TObject);
- begin
- DeleteSelectedEffects
- end;
- procedure TEffectListFrame.CopyEffectMenuItemClick(Sender: TObject);
- begin
- CopySelectedToClipboard
- end;
- procedure TEffectListFrame.EffectListBoxMouseUp(Sender: TObject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if Button = mbRight then begin
- ShowPopupMenu;
- end;
- end;
- procedure TEffectListFrame.PasteEffectMenuItemClick(Sender: TObject);
- begin
- PasteFromClipboard
- end;
- procedure TEffectListFrame.UpdateEffects;
- var
- I: Integer;
- begin
- Assert(Db <> nil, 'Database must be set before setting effect list!');
- with EffectListBox.Items do begin
- BeginUpdate;
- Clear;
- if EffectList <> nil then begin
- for I := 0 to EffectList.Count -1 do begin
- EffectListBox.Items.Add(EffectToText(EffectList.Objects[I]));
- end;
- end;
- Add(AddNewEffectStr);
- EndUpdate;
- end;
- end;
- function TEffectListFrame.EffectToText(Effect: TJSONObject): String;
- var
- Code: Integer = 0;
- DataId: Integer = 0;
- Value1: Double = 0;
- Value2: Double = 0;
- CodeJson, DataIdJson, Value1Json, Value2Json: TJSONNumber;
- function PercentsPlusConst: String;
- var
- Percents, ConstVal: Integer;
- begin
- Percents := Round(Value1 * 100);
- ConstVal := Round(Value2);
- if (Percents <> 0) and (ConstVal <> 0) then
- PercentsPlusConst := Format('%d%% + %d', [Percents, ConstVal])
- else if (Percents <> 0) then
- PercentsPlusConst := IntToStr(Percents) + '%'
- else
- PercentsPlusConst := IntToStr(ConstVal)
- end;
- begin
- if (Effect <> nil) and Effect.Find('code', CodeJson) then
- Code := CodeJson.AsInteger;
- if (Effect <> nil) and Effect.Find('dataId', DataIdJson) then
- DataId := DataIdJson.AsInteger;
- if (Effect <> nil) and Effect.Find('value1', Value1Json) then
- Value1 := Value1Json.AsFloat;
- if (Effect <> nil) and Effect.Find('value2', Value2Json) then
- Value2 := Value2Json.AsFloat;
- case Code of
- EFFECT_RECOVER_HP:
- EffectToText := EffectRecoverHp + PercentsPlusConst;
- EFFECT_RECOVER_MP:
- EffectToText := EffectRecoverMp + PercentsPlusConst;
- EFFECT_GAIN_TP:
- EffectToText := EffectGainTp + IntToStr(Round(Value1));
- EFFECT_ADD_STATE:
- EffectToText := EffectAddState + Db.GetStateName(DataId) + ' '
- + IntToStr(Round(Value1 * 100)) + '%';
- EFFECT_REMOVE_STATE:
- EffectToText := EffectRemoveState + Db.GetStateName(DataId) + ' '
- + IntToStr(Round(Value1 * 100)) + '%';
- EFFECT_ADD_BUFF:
- EffectToText := EffectAddBuff + Db.GetParamName(DataId) + ' '
- + IntToStr(Round(Value1)) + DurationTurns;
- EFFECT_ADD_DEBUFF:
- EffectToText := EffectAddDebuff + Db.GetParamName(DataId) + ' '
- + IntToStr(Round(Value1)) + DurationTurns;
- EFFECT_REMOVE_BUFF:
- EffectToText := EffectRemoveBuff + Db.GetParamName(DataId);
- EFFECT_REMOVE_DEBUFF:
- EffectToText := EffectRemoveDebuff + Db.GetParamName(DataId);
- EFFECT_SPECIAL:
- if dataId = SPECIAL_EFFECT_ESCAPE then
- EffectToText := EffectSpecialEscape
- else
- EffectToText := EffectSpecialUnknown;
- EFFECT_GROW:
- EffectToText := EffectGrow + Db.GetParamName(DataId) + ' +'
- + IntToStr(Round(Value1));
- EFFECT_LEARN_SKILL:
- EffectToText := EffectLearnSkill + Db.GetSkillName(DataId);
- EFFECT_COMMON_EVENT:
- EffectToText := EffectCommonEvent + Db.GetCommonEventName(DataId);
- else
- EffectToText := EffectUnknownEffect;
- end;
- end;
- function TEffectListFrame.IsRealEffectSelected: Boolean;
- var
- LastIsSelected, NoneSelected: Boolean;
- begin
- LastIsSelected := EffectListBox.ItemIndex = EffectListBox.Items.Count - 1;
- NoneSelected := EffectListBox.ItemIndex < 0;
- IsRealEffectSelected := not LastIsSelected and not NoneSelected;
- end;
- procedure TEffectListFrame.AddNewEffect;
- var
- NewEffect: TJSONObject;
- begin
- if EffectSelectorForm.ShowEffectSelection(Db) then begin
- NewEffect := TJSONObject.Create;
- NewEffect.Add('code', EffectSelectorForm.SelectedCode);
- NewEffect.Add('dataId', EffectSelectorForm.SelectedDataId);
- NewEffect.Add('value1', EffectSelectorForm.SelectedValue1);
- NewEffect.Add('value2', EffectSelectorForm.SelectedValue2);
- EffectList.Add(NewEffect);
- with EffectListBox do begin
- Items.BeginUpdate;
- Items[Items.Count -1] := EffectToText(NewEffect);
- Items.Add(AddNewEffectStr);
- Items.EndUpdate;
- end;
- end;
- end;
- procedure TEffectListFrame.EditSelectedEffect;
- var
- Effect: TJSONObject;
- CodeJson, DataIdJson, Value1Json, Value2Json: TJSONNumber;
- Code: Integer = 0;
- DataId: Integer = 0;
- Value1: Double = 0;
- Value2: Double = 0;
- begin
- Effect := EffectList.Objects[EffectListBox.ItemIndex];
- if Effect.Find('code', CodeJson) then
- Code := CodeJson.AsInteger;
- if Effect.Find('dataId', DataIdJson) then
- DataId := DataIdJson.AsInteger;
- if Effect.Find('value1', Value1Json) then
- Value1 := Value1Json.AsFloat;
- if Effect.Find('value2', Value2Json) then
- Value2 := Value2Json.AsFloat;
- if EffectSelectorForm.ShowEffectSelection(Db, Code, DataId, Value1, Value2) then begin
- Effect.Integers['code'] := EffectSelectorForm.SelectedCode;
- Effect.Integers['dataId'] := EffectSelectorForm.SelectedDataId;
- Effect.Floats['value1'] := EffectSelectorForm.SelectedValue1;
- Effect.Floats['value2'] := EffectSelectorForm.SelectedValue2;
- EffectListBox.Items[EffectListBox.ItemIndex] := EffectToText(Effect);
- end
- end;
- procedure TEffectListFrame.ShowPopupMenu;
- var
- IsForRealEffect: Boolean;
- begin
- IsForRealEffect := IsRealEffectSelected;
- DeleteEffectMenuItem.Enabled := ListboxSelectionNotEmpty(EffectListBox);
- if IsForRealEffect then
- EditEffectMenuItem.Caption := EditEffectMenuItemStr
- else
- EditEffectMenuItem.Caption := AddNewEffectMenuItemStr;
- EffectPopupMenu.PopUp;
- end;
- procedure TEffectListFrame.PasteFromClipboard;
- var
- PastedArray: TJSONArray;
- I: Integer;
- StartId: Integer;
- begin
- StartId := EffectListBox.ItemIndex;
- PastedArray := GetJsonArrayFromClipboard('application/rpgmv-effects');
- if PastedArray = nil then
- Exit;
- try
- for I := 0 to PastedArray.Count -1 do begin
- if PastedArray[I].JSONType = jtObject then begin
- EffectList.Insert(StartId + I, PastedArray.Objects[I].Clone as TJSONObject);
- end;
- end;
- finally
- PastedArray.Free;
- end;
- UpdateEffects;
- end;
- procedure TEffectListFrame.CopySelectedToClipboard;
- var
- ArrSrl: TClipboardArraySerializer;
- I, NumCopied: Integer;
- begin
- ArrSrl := TClipboardArraySerializer.Create(DataTypeIds[DATA_TYPE_ID_EFFECTS]);
- try
- NumCopied := 0;
- for I := 0 to EffectListBox.Count -1 do begin
- if EffectListBox.Selected[I] then begin
- ArrSrl.AddItem(EffectList.Objects[I]);
- Inc(NumCopied)
- end
- end;
- if NumCopied > 0 then
- ArrSrl.CopyToClipboard
- finally
- ArrSrl.Free;
- end;
- end;
- procedure TEffectListFrame.DeleteSelectedEffects;
- var
- I: Integer;
- begin
- for I := EffectListBox.Count -1 downto 0 do begin
- if EffectListBox.Selected[I] then begin
- EffectList.Delete(I);
- end
- end;
- UpdateEffects
- end;
- procedure TEffectListFrame.SetDatabase(ADb: TDatabase);
- begin
- Db := ADb;
- end;
- procedure TEffectListFrame.SetEffectList(AEffectList: TJSONArray);
- begin
- EffectList := AEffectList;
- UpdateEffects
- end;
- end.
|