Мне нужно вызвать обработчик события, чтобы указать пользователю выбрать TCard
или TLabel
, а затем вернуть это значение в качестве параметра.Настройка eventHandler с возвращаемым значением
У меня есть две единицы GAME
, SS_SPELL
Это как код в SS_SPEll работает.
// TSPELL
// ======
// The chronology is:
// 1. At appropriate points in the game (such as before turn, after cast etc aka trigger points)
// the game calls the SpellMeister's RunSpells method.
// 2. RunSpells checks the database for spells matching the card that
// initiated the spell action, and the trigger point at which it did so.
// For each one that it finds it will create an appropriate object, which
// could be a TSpell descendent or a TSpellAdjuster descendent.
// For each TSpell it finds it fires off an onFindSpell event.
// See below for details of how TSpellAdjusters are handled.
// 3. The handler for the onFindSpell events can (should) call the spells'
// AimAt method for each potential target. A potential target is a card
// or a player.
// 4. A spell's AimAt method checks if the potential target is a legitimate
// target for that spell and if so it calls its ApplySpellTo method to
// actually do the dirty deed.
Так что мне нужно, как только RunSpells получает информация о БД будет проверять, если needs2ndtarget: = 1, если да, то я знаю, что нужна вторая цель для этого заклинания.
Здесь TSpellBase
это класс TSpell
. В попытке создать это событие я добавил FOnSeek2ndTarget
в приватном разделе и FNeed2Target
в охраняемой и общественной собственности OnSeek2ndTarget
. Вы также увидите TTargetEvt
, в настоящее время его настройку для восстановления TCARD, но мне нужно, чтобы он получал TCard или TLAbel, не представляя, как это сделать.
TTargetEvt = procedure (Card : TCard) of Object;
TSpellBase = class
private
FOnManaChange: TManaEvt;
FOnSeek2ndTarget: TTargetEvt;
protected
FCardType : TCardType;
FOriginator : TCard;
FNeed2Target : integer;
function LegitimateTarget (Candidate : TObject) : boolean; virtual;
public
constructor Create; virtual;
property CardType : TCardType read FCardType write FCardType; // ctLava, ctNature, ctWizard, etc etc
property Originator : TCard read FOriginator write FOriginator;
property Need2Target : integer read FNeed2Target write FNeed2Target;
property OnManaChange : TManaEvt read FOnManaChange write FOnManaChange;
property OnSeek2ndTarget : TTargetEvt read FonSeek2ndTarget write FOnSeek2ndTarget;
end;
Сейчас в TSpell, я не думаю, что мне нужно что-нибудь chnaged здесь, но его необходимо для процедуры spellmiester.runspell
TSpell = class(TSpellBase)
private
protected
FCategory : TCategory;
FLifeToAdd : Byte;
FMaxRandom : Byte;
FReplaceDmg : Byte;
FReplacement : string;
FStatTarget : Byte;
FTrigger : TTrigger;
procedure ApplySpellTo(Target : TObject); virtual; abstract; // Apply the spell to the target
public
procedure AimAt(Candidate: TObject); virtual;
property Category : TCategory read FCategory write FCategory;
property LifeToAdd : Byte read FLifeToAdd write FLifeToAdd;
property MaxRandom : Byte read FMaxRandom write FMaxRandom;
property ReplaceDmg : Byte read FReplaceDmg write FReplaceDmg;
property Replacement : string read FReplacement write FReplacement;
property StatTarget : Byte read FStatTarget write FStatTarget;
property Trigger : TTrigger read FTrigger write FTrigger;
end;
Здесь я добавил FOnSeek2ndTarget
в приватной секции. и свойство Итак, теперь, когда заклинание забрасывается, оно будет , и теперь вызывается runsspells.
TSpellMeister = class
private
FonFindSpell : TRcvSpell;
FOnManaChange : TManaEvt;
FOnSeek2ndTarget : TTargetEvt;
// FonNewAdjuster : TRcvSpell;
protected
FAdjusters : TAdjusters;
FQuery : TADOQuery;
public
constructor Create(DBCon: TADOConnection);
destructor Destroy; override;
function IfNull(const Value, Default : OleVariant) : OleVariant;
procedure Adjust(Attacker : TCard; Victim : TObject; var TheDamage : integer); overload;
procedure Adjust(Attacker : TCard; var TheCost : integer); overload;
procedure RunSpells(Card : TCard; Trigger : TTrigger);
property onFindSpell : TRcvSpell read FonFindSpell write FonFindSpell;
property OnManaChange : TManaEvt read FOnManaChange write FOnManaChange;
property OnSeek2ndTarget: TTargetEvt read FOnSeek2ndTarget write FOnSeek2ndTarget;
// property onNewAdjuster : TRcvSpell read FonNewAdjuster write FonNewAdjuster;
end;
Это где проблема, я добавил foundspell.Need2ndTarget
это получает данные из базы данных, если это 1, то для этого нужно пользователю выбрать другую цель для заклинания. В настоящее время я добавил
если FoundSpell.Need2Target = 1 then FOnSeek2ndTarget (Карта);
, но я уверен, что это не правильно ...
//**************************************************************************
procedure TSpellMeister.RunSpells(Card: TCard; Trigger: TTrigger);
//**************************************************************************
var
OneSpell : TSpellBase;
FoundSpell : TSpell; // Just so only have to cast once
begin
assert(assigned(FonFindSpell),'TSpellMeister.RunSpells : No onFindSpell event handler!');
// Search the database
FQuery.Active := FALSE;
FQuery.Parameters.ParamByName(SQL_PARAM_SPELL_ORIGINATOR).Value := Card.CName;
FQuery.Parameters.ParamByName(SQL_PARAM_SPELL_TRIGGER ).Value := Trigger;
FQuery.Active := TRUE;
// Iterate through the spell records. For each one, create a category-specific
// TSpell descendant and fire off an onFindSpell event.
if FQuery.RecordCount > 0 then
begin
FQuery.Recordset.MoveFirst;
while not FQuery.Recordset.EOF do
begin
case TCategory(FQuery.Recordset.Fields[DB_FLD_CATEGORY].Value) of
caAboveLife : OneSpell := TSpellAboveLife.Create;
caDamage : OneSpell := TSpellDamage.Create;
caDamagePlus : OneSpell := TSpellDamagePlus.Create;
caDamagePlusPercent : OneSpell := TSpellDamagePlusPercent.Create;
caDamagePercentIncrease : OneSpell := TSpellDamagePercentIncrease.Create;
caDamagePercentDecrease : OneSpell := TSpellDamagePercentDecrease.Create;
caDamageSpells : OneSpell := TSpellDamageSpells.Create;
caDestroy : OneSpell := TSpellDestroy.Create;
.....
else raise ERangeError.CreateFmt(ERROR_INVALID_DB_NUMBER,[DB_FLD_CATEGORY,FQuery.Recordset.Fields[DB_FLD_CATEGORY].Value]);
end;
try
if assigned(OneSpell) then
begin
OneSpell.CardType := TCardType (IfNull(FQuery.Recordset.Fields[ DB_FLD_CARD_TYPE ].Value,0));
OneSpell.Originator := Card;
OneSpell.OnManaChange := Self.OnManaChange;
OneSpell.OnSeek2ndTarget := self.OnSeek2ndTarget;
assert(OneSpell.Originator.COwner is TPlayer,'TSpellMeister.RunSpells : OneSpell.Originator.COwner not a player: ' + OneSpell.Originator.COwner.ClassName);
try
FoundSpell := TSpell(OneSpell);
FoundSpell.Originator := Card;
FoundSpell.Trigger := Trigger;
FoundSpell.CardType := TCardType (FQuery.Recordset.Fields[ DB_FLD_CARD_TYPE ].Value);
FoundSpell.Category := TCategory (FQuery.Recordset.Fields[ DB_FLD_CATEGORY ].Value);
FoundSpell.LifeToAdd := IfNull(FQuery.Recordset.Fields[ DB_FLD_LIFE_TO_ADD ].Value,0);
FoundSpell.MaxRandom := IfNull(FQuery.Recordset.Fields[ DB_FLD_MAX_RANDOM ].Value,0);
FoundSpell.PerCent := IfNull(FQuery.Recordset.Fields[ DB_FLD_PER_CENT ].Value,0);
FoundSpell.Plus := IfNull(FQuery.Recordset.Fields[ DB_FLD_PLUS ].Value,0);
FoundSpell.ReplaceDmg := IfNull(FQuery.Recordset.Fields[ DB_FLD_REPLACE_DMG ].Value,0);
FoundSpell.Replacement := IfNull(FQuery.Recordset.Fields[ DB_FLD_REPLACEMENT ].Value,0);
FoundSpell.StatTarget := IfNull(FQuery.Recordset.Fields[ DB_FLD_STAT_TARGET ].Value,0);
FoundSpell.Target := TTargetType(IfNull(FQuery.Recordset.Fields[ DB_FLD_TARGET ].Value,0));
FoundSpell.Need2Target := IfNull(FQuery.Recordset.Fields[ DB_FLD_NEED2TARGET ].Value,0);
assert(FoundSpell.Originator.COwner is TPlayer,'TSpellMeister.RunSpells : FoundSpell.Originator.COwner not a player: ' + OneSpell.Originator.COwner.ClassName);
if FoundSpell.Need2Target = 1 then
FOnSeek2ndTarget(Card);
FonFindSpell(FoundSpell);
finally
FreeAndNil(OneSpell);
end;
end;
except // I think this is OK but is there a possible bug if
FreeAndNil(OneSpell); // spell adjuster added to list then destroyed?
end; // List item would then be invalid.
FQuery.Recordset.MoveNext;
end;
end;
end;
Таким образом, все, что есть блок ss_spells, ныне game
блок, который использует ss_spells блок в forum.create
я есть
FSpellMeister.OnSeek2ndTarget := self.Handle2ndTarget;
без понятия, что положить в Handle2ndTarget в настоящее время его просто
//****************************************************************************
procedure TFGame.Handle2ndTarget(Card : TCard);
begin
showmessage('Select a target HANDLE2ndTARGET');
end;
просто чтобы увидеть, если я мог бы по крайней мере, получить здесь ..
Так с этим мой вопрос, если вы не можете сделать это, Как я установить вар в ss_Spells к TObject (tcard или TLabel), когда foundspell.Need2ndTarget := 1
с помощью событие FOnSeek2ndTarget();
Я действительно нет идея вообще не то, что вы просите. Здесь слишком много кода. Прежде всего вам нужно будет решить, что ваш вопрос, и спросить об этом. Не стоит публиковать весь ваш код и надеяться, что мы сможем решить, каков ваш вопрос. Вы хотите, чтобы событие возвращало значение? Сделать возвращаемое значение параметром 'var'. Это оно? –
Да, я попытался показать код, который перегружен вопросом. Я удалил много. жаль, что это так долго .. Но да, мне нужно знать, как использовать событие, чтобы вернуть параметр var –
'FNeed2Target: Integer'. Не используйте '0' и' 1' для указания логического состояния. Объявите переменную как 'Boolean'. –