Skip to content

Commit efa7b37

Browse files
committed
Border region check in teleport function
1 parent 22579db commit efa7b37

File tree

5 files changed

+119
-71
lines changed

5 files changed

+119
-71
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ In fact it already won't work with current version (see supported versions secti
2525

2626
### Supported versions
2727
* 1.10.40
28-
* 1.10.26
28+
* 1.10.26 (broken)
2929

3030
### How it works
3131
There are two dll files:

code/f4/functions.cpp

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ OTHER DEALINGS IN THE SOFTWARE.
2929
Compile as x64 code
3030
*/
3131

32+
/*
33+
Get cell regions:
34+
1) Call TESCell__sub_1403B4A10
35+
2) [eax + 0x8] - first region
36+
3) [eax + 0x10] - pointer to RegionUnk struct
37+
38+
struct RegionUnk {
39+
TESRegion *region;
40+
RegionUnk *nextRegionUnk;
41+
};
42+
*/
43+
44+
/*
45+
Check if cell is within region border:
46+
1) Get cell regions
47+
2) If there's border region the cell is within border region,
48+
otherwise it is outside.
49+
*/
50+
3251
/*
3352
Is current cell interior or exterior check:
3453
1) Get ObjectReference pointer (rax)
@@ -165,6 +184,13 @@ internal _TESObjectReference_MoveToCell TESObjectReference_MoveToCell;
165184
internal _TESObjectReference_GetCurrentLocation TESObjectReference_GetCurrentLocation;
166185
// ------ #TESObjectReference ------
167186

187+
// ------ TESCell ------
188+
typedef TESCellUnk * (__fastcall *_TESCell_GetUnk)
189+
(TESCell *cell, bool flag);
190+
191+
internal _TESCell_GetUnk TESCell_GetUnk;
192+
// ------ #TESCell ------
193+
168194
// ------ TESWorldSpace ------
169195
typedef TESCell * (__fastcall *_TESWorldSpace_FindExteriorCellByCoordinates)
170196
(TESWorldSpace *tesWorldSpace, unsigned int cellX, unsigned int cellY);
@@ -233,6 +259,8 @@ extern "C" {
233259
uint64 TESObjectReferenceMoveToCellAddress;
234260
uint64 TESObjectReferenceGetCurrentLocationAddress;
235261

262+
uint64 TESCellGetUnkAddress;
263+
236264
uint64 TESWorldSpaceFindExteriorCellByCoordinatesAddress;
237265

238266
uint64 TESFindInteriorCellByNameAddress;
@@ -277,6 +305,8 @@ internal void DefineAddresses()
277305
TESObjectReferenceMoveToCellAddress = 0x00E9A330;
278306
TESObjectReferenceGetCurrentLocationAddress = 0x0040EE70;
279307

308+
TESCellGetUnkAddress = 0x003B4A30;
309+
280310
TESWorldSpaceFindExteriorCellByCoordinatesAddress = 0x004923E0;
281311

282312
TESFindInteriorCellByNameAddress = 0x00152EB0;
@@ -317,6 +347,8 @@ internal void DefineAddresses()
317347
TESObjectReferenceMoveToCellAddress = 0x00E989E0;
318348
TESObjectReferenceGetCurrentLocationAddress = 0x0040EE50;
319349

350+
TESCellGetUnkAddress = 0x003B4A10;
351+
320352
TESWorldSpaceFindExteriorCellByCoordinatesAddress = 0x004923C0;
321353

322354
TESFindInteriorCellByNameAddress = 0x00152EB0;
@@ -365,6 +397,8 @@ internal void ShiftAddresses()
365397
TESObjectReference_MoveToCell = (_TESObjectReference_MoveToCell)(TESObjectReferenceMoveToCellAddress + baseAddress);
366398
TESObjectReference_GetCurrentLocation = (_TESObjectReference_GetCurrentLocation)(TESObjectReferenceGetCurrentLocationAddress + baseAddress);
367399

400+
TESCell_GetUnk = (_TESCell_GetUnk)(TESCellGetUnkAddress + baseAddress);
401+
368402
TESWorldSpace_FindExteriorCellByCoordinates = (_TESWorldSpace_FindExteriorCellByCoordinates)(TESWorldSpaceFindExteriorCellByCoordinatesAddress + baseAddress);
369403

370404
TESFindInteriorCellByName = (_TESFindInteriorCellByName)(TESFindInteriorCellByNameAddress + baseAddress);
@@ -422,7 +456,7 @@ internal TESWorldSpace * GetPlayerCurrentWorldSpace()
422456
TESWorldSpace *worldspace = 0;
423457

424458
TESPlayer *player = TES_GetPlayer();
425-
TESCell *playerCell = player->objectReference.parentCell;
459+
TESCell *playerCell = player->tesActor.objectReference.parentCell;
426460

427461
if( playerCell ) {
428462
worldspace = playerCell->worldSpace;
@@ -463,6 +497,30 @@ internal TESWorldSpace * GetPlayerCurrentWorldSpace()
463497

464498
return worldspace;
465499
}
500+
501+
internal bool IsCellWithinBorderRegion(TESCell *cell)
502+
{
503+
bool result = false;
504+
505+
TESCellUnk *cellUnk = TESCell_GetUnk(cell, 1);
506+
507+
if( cellUnk ) {
508+
RegionUnk *regionUnk = (RegionUnk *)(&cellUnk->region);
509+
if( regionUnk ) {
510+
while( regionUnk ) {
511+
TESRegion *region = regionUnk->region;
512+
if( !region ) break;
513+
514+
result = ((region->tesForm.flags) >> 6) && 1;
515+
if( result ) break;
516+
517+
regionUnk = regionUnk->nextRegionUnk;
518+
}
519+
}
520+
}
521+
522+
return result;
523+
}
466524
// ------ #Functions ------
467525

468526
#endif

0 commit comments

Comments
 (0)