Closed borsuczyna closed 1 year ago
as I mentioned on Discord you can iterate pool using existing Memory command (not in DE for now).
Example script creating blips over police cars in GTA 3 1.0
/// <reference path=".config/gta3.d.ts" />
// wrapper over CPool class providing common interface for storing dynamically created entities (ped, vehicles, objects, etc)
function Pool(addr, entitySize) {
this.addr = addr;
this.entities = Memory.ReadU32(addr + 0, false);
this.flags = Memory.ReadU32(addr + 4, false);
this.size = Memory.ReadI32(addr + 8, false);
this.entitySize = entitySize;
}
Pool.prototype = {
getFlag: function (index) {
return Memory.ReadU8(this.flags + index, false);
},
getIndex: function (struct) {
return (struct - this.entities) / this.entitySize;
},
isFree: function (index) {
return this.getFlag(index) & 0x80;
},
getHandle: function (struct) {
var index = this.getIndex(struct);
return (index << 8) + this.getFlag(index);
},
getEntity: function (index) {
return this.entities + index * this.entitySize;
},
getEntities: function () {
var result = [];
for (var i = 0; i < this.size; i++) {
if (!this.isFree(i)) {
result.push(this.getEntity(i));
}
}
return result;
},
};
var BLIPS = 0x006ed5e0;
var MI_POLICE = 116;
function findThisEntityBlip(handle) {
var COUNT = 32;
var SIZE = 0x30;
for (var i = 0; i < COUNT; i++) {
var inUse = Memory.ReadU8(BLIPS + i * SIZE + 0x23, false);
if (inUse) {
var h = Memory.ReadU32(BLIPS + i * SIZE + 0x8, false);
if (handle == h) {
var blipIndex = Memory.ReadU16(BLIPS + i * SIZE + 0x20, false);
/// blipArrId | (CRadar::ms_RadarTrace[_index].m_nBlipIndex << 16);
return i | (blipIndex << 16);
// return blipIndex;
}
}
}
}
if (GAME !== "gta3") {
log("Sorry, this script is for GTA III only");
} else {
// create a function to get the vehicle pool address
var GetVehiclePool = Memory.Fn.CdeclU32(0x00545300);
// create a wrapper over the vehicle pool object
var vehPool = new Pool(GetVehiclePool(), 0x5a8);
while (true) {
wait(500);
// iterate over all created vehicles
vehPool.getEntities().forEach(function (vehicle) {
// create a new instance of a script vehicle
var handle = vehPool.getHandle(vehicle);
var v = new Car(handle);
// v now can be used with script commands defined for Vehicle class
// check that v is a police car with a driver and it has no blip yet
if (
!Car.IsDead(v) &&
v.getModel() === MI_POLICE &&
!Char.IsDead(v.getDriver()) &&
!findThisEntityBlip(handle)
) {
Blip.AddForCarOld(v, 2, 2);
}
});
}
}```
Idea to create callbacks/hooks was briefly discussed here https://github.com/cleolibrary/CLEO-Redux/discussions/1#discussioncomment-1217851
some ideas:
addEventListener("onMount", () => { log("script has been reloaded") })
addEventListener("onUnMount", () => { log("script is about to be unloaded") })
WIP
addEventListener("OnVehicleCreate", ({ data }) => {
let { address } = data;
let handle = vehPool.getHandle(address);
let c = new Car(handle);
if (c.isModel(POLICE_MI)) {
Blip.AddForCarOld(c, 2, BlipDisplay.BlipOnly);
}
});
https://media.discordapp.net/attachments/914958450667175977/1053787400855359508/image.png
Pools are available in scm.ts library https://github.com/x87/scm.ts
Events are supported since 1.0.6 https://re.cleo.li/docs/en/events.html
Pools are most Important thing to make good mod tool, really hope for them, example:
Also I really hope replacing existing GTA callbacks, that game will call intead of default ones, for example replacing add wanted level callback:
Greetings! #