mahlendur/_work/Data/Scripts/Content/neclib/Telekinesis.d
Daniel Heße 892a40ff0f Initial commit with Subversion-codebase from 13/05/2022.
Cleaned up the mess, at this time, only viable data get synced (_work directory for Gothic-data, miranda for mdc-scripts.
Need to symlink files to a working directory.
2022-05-13 17:38:52 +02:00

236 lines
No EOL
7.8 KiB
D

/**
* Neclib telekinesis module
*/
//const int TARGET_TYPE_ITEM_TELEKINESIS = 256;
/**
* Creates a new telekinesis interpolator object.
* @param pVobPosition : (pointer to a zVEC3) position of the vob that should be moved.
* @param pNpcPosition : (pointer to a zVEC3) position where the vob should travel to.
* @param upMoveAmount : (in cm) before the vob travels, it is moved upwards.
* @param speed : The travelling speed.
*/
func int TELEKINESIS_CreateInterpolator(var int pVobPosition, var int pNpcPosition, var int upMoveAmount, var int speed) {
if (!(NEC_Init_Modules & NEC_TELEKINESIS)) {
MEM_Warn("neclib: TELEKINESIS_CreateInterpolator: Telekinesis module isn't initialized!");
return 0;
};
var int ret;
var int adr;
adr = GetProcAddress (LoadLibrary (NEC_relativeLibraryPath), "TELEKINESIS_CreateInterpolator");
CALL_IntParam(speed);
CALL_IntParam(upMoveAmount);
CALL_IntParam(pNpcPosition);
CALL_IntParam(pVobPosition);
CALL_PutRetValTo(_@(ret));
CALL__cdecl(adr);
return +ret;
};
/**
* Provides the current calculated position for a travelling vob.
* @param pTelekinesisInterpolator : (pointer to a telekinesis interpolator)
* @param pDestVec3 : (pointer to zVEC3) will hold the calculated position.
*/
func void TELEKINESIS_GetInterpolatedVec(var int pTelekinesisInterpolator, var int pDestVec3) {
if (!(NEC_Init_Modules & NEC_TELEKINESIS)) {
MEM_Warn("neclib: TELEKINESIS_GetInterpolatedVec: Telekinesis module isn't initialized!");
return;
};
var int ret;
var int adr;
adr = GetProcAddress (LoadLibrary (NEC_relativeLibraryPath), "TELEKINESIS_GetInterpolatedVec");
CALL_IntParam(pDestVec3);
CALL_IntParam(pTelekinesisInterpolator);
CALL__cdecl(adr);
};
/**
* Deletes a telekinesis interpolator.
* @param pTelekinesisInterpolator : (pointer to a telekinesis interpolator)
*/
func void TELEKINESIS_DeleteInterpolator(var int pTelekinesisInterpolator) {
if (!(NEC_Init_Modules & NEC_TELEKINESIS)) {
MEM_Warn("neclib: TELEKINESIS_DeleteInterpolator: Telekinesis module isn't initialized!");
return;
};
var int ret;
var int adr;
adr = GetProcAddress (LoadLibrary (NEC_relativeLibraryPath), "TELEKINESIS_DeleteInterpolator");
CALL_IntParam(pTelekinesisInterpolator);
CALL__cdecl(adr);
};
/**
* Sets the position of a zCVob to the currently calculated position of a telekinesis interpolator.
* @param pTelekinesisInterpolator : (pointer to a telekinesis interpolator)
* @param vobPtr : (pointer to zCVob)
*/
func void TELEKINESIS_Interpolate(var int pTelekinesisInterpolator, var int vobPtr) {
if (!(NEC_Init_Modules & NEC_TELEKINESIS)) {
MEM_Warn("neclib: TELEKINESIS_Interpolate: Telekinesis module isn't initialized!");
return;
};
var int adr;
adr = GetProcAddress (LoadLibrary (NEC_relativeLibraryPath), "TELEKINESIS_Interpolate");
CALL_IntParam(vobPtr);
CALL_IntParam(pTelekinesisInterpolator);
CALL__cdecl(adr);
};
/**
* Checks if the vob is seeable (by a npc) for starting telekinesis spell.
* @param pNpc : (pointer to oCNpc) the npc
* @param vobPtr : (pointer to zCVob) the vob
* @return : TRUE if the vob is seeable.
*/
func int TELEKINESIS_IsVobSeeable(var int pNpc, var int pVob) {
if (!(NEC_Init_Modules & NEC_TELEKINESIS)) {
MEM_Warn("neclib: TELEKINESIS_IsVobSeeable: Telekinesis module isn't initialized!");
return 0;
};
var int ret;
var int adr;
adr = GetProcAddress (LoadLibrary (NEC_relativeLibraryPath), "TELEKINESIS_IsVobSeeable");
CALL_IntParam(pVob);
CALL_IntParam(pNpc);
CALL_PutRetValTo(_@(ret));
CALL__cdecl(adr);
return +ret;
};
/**
* Clears any not deleted interpoaltors.
*/
func void TELEKINESIS_ClearInterpolators() {
if (!(NEC_Init_Modules & NEC_TELEKINESIS)) {
MEM_Warn("neclib: TELEKINESIS_ClearInterpolators: Telekinesis module isn't initialized!");
return;
};
var int adr;
adr = GetProcAddress (LoadLibrary (NEC_relativeLibraryPath), "TELEKINESIS_ClearInterpolators");
CALL__cdecl(adr);
};
/*
* Enable focusing mob when using the spell
*/
func void Spell_Telekinesis_Prio() {
var int caster; caster = MEM_ReadInt(ESP+4);
if (!caster) {
return;
};
var C_Npc slf; slf = _^(caster);
if (!Npc_IsPlayer(slf)) {
return;
};
const int npc_prio_backup = 42; // 42 == not initialized yet
const int item_range2_backup = 42; // 42 == not initialized yet
const int item_azi_backup = 42; // 42 == not initialized yet
const int item_elevup_backup = 42; // 42 == not initialized yet
const int item_elevdo_backup = 42; // 42 == not initialized yet
const int item_prio_backup = 42; // 42 == not initialized yet
if (item_prio_backup == 42) {
npc_prio_backup = Focus_Magic.npc_prio;
item_range2_backup = castToIntf(Focus_Magic.item_range2);
item_azi_backup = castToIntf(Focus_Magic.item_azi);
item_elevup_backup = castToIntf(Focus_Magic.item_elevup);
item_elevdo_backup = castToIntf(Focus_Magic.item_elevdo);
item_prio_backup = Focus_Magic.item_prio;
};
var int spellID; spellID = MEM_ReadInt(/*oCSpell*/ECX+/*spellID*/84);
if (spellID == SPL_Telekinesis) {
// Adjust the global(!) focus priorities temporarily(!)
// Note: item_range1 and item_range2 are stored in squared
//Focus_Magic.item_range2 = castFromIntf(mulf(castToIntf(3500.0), castToIntf(3500.0)));
Focus_Magic.npc_prio = -1;
Focus_Magic.item_azi = 90.0;
Focus_Magic.item_elevup = 90.0;
Focus_Magic.item_elevdo = -89.0;
Focus_Magic.item_prio = 1;
MEM_Info("neclib: Spell_Telekinesis_Prio: changed Focus_Magic");
} else if (item_prio_backup != 42) {
// Reset the focus priorities for all other spells!
Focus_Magic.npc_prio = npc_prio_backup;
Focus_Magic.item_range2 = castFromIntf(item_range2_backup);
Focus_Magic.item_azi = castFromIntf(item_azi_backup);
Focus_Magic.item_elevup = castFromIntf(item_elevup_backup);
Focus_Magic.item_elevdo = castFromIntf(item_elevdo_backup);
Focus_Magic.item_prio = item_prio_backup;
};
var int range1; range1 = truncf(castToIntf(Focus_Magic.item_range1));
var int range2; range2 = truncf(castToIntf(Focus_Magic.item_range2));
};
/*
* Make the focus check mob specific (disallow NPC)
*/
/*func void Spell_Telekinesis_Focus() {
// Constructed case that will only happen for Spell_Telekinesis
if (ECX == TARGET_TYPE_ITEM_TELEKINESIS) {
//MEM_Info("Spell_Telekinesis_Focus: called");
var int vobPtr; vobPtr = MEM_ReadInt(ESP+4);
var C_Item itm; itm = _^(vobPtr);
if (Hlp_IsValidItem(itm)) {
MEM_Info(ConcatStrings("Spell_Telekinesis_Focus: itm.name = ", itm.name));
ECX = 1;
};
};
};*/
/**
* Inits the telekinesis module.
*/
func void TELEKINESIS_Init()
{
const int oCSpell__Setup_G1 = 4703664; //0x47C5B0
const int oCSpell__Setup_G2 = 4737328; //0x484930
const int oCSpell__IsTargetTypeValid_G1 = 4709316; //0x47DBC4
const int oCSpell__IsTargetTypeValid_G2 = 4743108; //0x485FC4
HookEngineF(oCSpell__Setup_G2, 7, Spell_Telekinesis_Prio);
//HookEngineF(+MEMINT_SwitchG1G2(oCSpell__IsTargetTypeValid_G1,
// oCSpell__IsTargetTypeValid_G2), 5, Spell_Telekinesis_Focus);
// Make sure Focus_Magic is initialized (necessary for Spell_Telekinesis_Prio). For details see GothicFreeAim
const int oCNpcFocus__focuslist_G1 = 9283120; //0x8DA630
const int oCNpcFocus__focuslist_G2 = 11208440; //0xAB06F8
var int fMagicPtr; fMagicPtr = MEM_ReadIntArray(+MEMINT_SwitchG1G2(oCNpcFocus__focuslist_G1,
oCNpcFocus__focuslist_G2), 5); ///Focus_Magic
if (fMagicPtr) {
MEM_Info("neclib: TELEKINESIS_Init: Reinitializing Focus_Magic instance");
Focus_Magic = _^(fMagicPtr);
};
TELEKINESIS_ClearInterpolators();
MEM_Info("neclib: TELEKINESIS_Init: done.");
};