Quote:К примеру, HD-мод как-то работает с перемещённым массивом монстров вместе с Тифоном или Аметистом.
То, как работает HD (через двойной указатель) — гораздо безопаснее. И HD-мод не расширяет структуру. Ему не нужен RedirectMemoryBlock.
Quote:Если era.dll будет использовать перемещённые структуры, кроме структуры монстров, то добавить RedirectMemoryBlock в код Тифона - без проблем
Не нужно ждать. Вызов RedirectMemoryBlock → это просто извещение, которое сразу даёт кислород всем плагинам на ERM/Lua/C++/Pascal/Brainfuck.
Quote:а вот самому использовать GetRealAddr() - фигня какая-то.
Во-первых, совершенно неясно, куда его в существующей парадигме совать.
Тут два момента:
1) В вопросах скорости — экономия на спичках, даже не серьёзно.
2) Работать классически не через define, а через объявление указателя.
_CreatureInfo_ *monsterAttrs = 0xAAAAAA;
=> OnAfterStructRelocations
monsterAttrs = GetRealAddr(monsterAttrs); преобразовали адрес с оригинального в конечный.
У меня так в одном из модулей:
Code:
procedure OnAfterStructRelocations (Event: GameExt.PEvent); stdcall;
begin
ZvsIsGameLoading := GameExt.GetRealAddr(ZvsIsGameLoading);
ZvsTriggerIfs := GameExt.GetRealAddr(ZvsTriggerIfs);
ZvsTriggerIfsDepth := GameExt.GetRealAddr(ZvsTriggerIfsDepth);
ZvsChestsEnabled := GameExt.GetRealAddr(ZvsChestsEnabled);
ZvsGmAiFlags := GameExt.GetRealAddr(ZvsGmAiFlags);
IsWoG := GameExt.GetRealAddr(IsWoG);
WoGOptions := GameExt.GetRealAddr(WoGOptions);
ErmEnabled := GameExt.GetRealAddr(ErmEnabled);
ErmErrCmdPtr := GameExt.GetRealAddr(ErmErrCmdPtr);
ErmDlgCmd := GameExt.GetRealAddr(ErmDlgCmd);
MrMonPtr := GameExt.GetRealAddr(MrMonPtr);
HeroSpecsTable := GameExt.GetRealAddr(HeroSpecsTable);
HeroSpecsTableBack := GameExt.GetRealAddr(HeroSpecsTableBack);
HeroSpecSettingsTable := GameExt.GetRealAddr(HeroSpecSettingsTable);
SecSkillSettingsTable := GameExt.GetRealAddr(SecSkillSettingsTable);
SecSkillNamesBack := GameExt.GetRealAddr(SecSkillNamesBack);
SecSkillDescsBack := GameExt.GetRealAddr(SecSkillDescsBack);
SecSkillTextsBack := GameExt.GetRealAddr(SecSkillTextsBack);
MonNamesSettingsTable := GameExt.GetRealAddr(MonNamesSettingsTable);
MonNamesSingularTable := GameExt.GetRealAddr(MonNamesSingularTable);
MonNamesPluralTable := GameExt.GetRealAddr(MonNamesPluralTable);
MonNamesSpecialtyTable := GameExt.GetRealAddr(MonNamesSpecialtyTable);
MonNamesSingularTableBack := GameExt.GetRealAddr(MonNamesSingularTableBack);
MonNamesPluralTableBack := GameExt.GetRealAddr(MonNamesPluralTableBack);
MonNamesSpecialtyTableBack := GameExt.GetRealAddr(MonNamesSpecialtyTableBack);
ArtNamesSettingsTable := GameExt.GetRealAddr(ArtNamesSettingsTable);
ArtInfosBack := GameExt.GetRealAddr(ArtInfosBack);
MonNamesTables[0] := MonNamesSingularTable;
MonNamesTables[1] := MonNamesPluralTable;
MonNamesTables[2] := MonNamesSpecialtyTable;
MonNamesTablesBack[0] := MonNamesSingularTableBack;
MonNamesTablesBack[1] := MonNamesPluralTableBack;
MonNamesTablesBack[2] := MonNamesSpecialtyTableBack;
end; // .procedure OnAfterStructRelocations
procedure OnAfterStructRelocations (Event: GameExt.PEvent); stdcall;
begin
SecSkillNames := GameExt.GetRealAddr(SecSkillNames);
SecSkillDescs := GameExt.GetRealAddr(SecSkillDescs);
SecSkillTexts := GameExt.GetRealAddr(SecSkillTexts);
MonInfos := GameExt.GetRealAddr(MonInfos);
ArtInfos := ppointer(ArtInfos)^;
end;
А там, где прямой адрес был, заменил на:
Code:
NextRecruitMonsDlgOpenEventDwellingId := pbyte(Heroes.GetTownManager.Town.TownType * 2 + Context.EDI + integer(GameExt.GetRealAddr(Ptr($68A3A2))))^;
Если я берусь использовать в коде таблицу, то считаю, что навыки/монстров/тексты/героев кто-то наверняка можешь расширить. Или правильнее было бы использовать фиксированные адреса и писать, что у людей просто нерабочие плагины?