noxworld-dev / opennox

OpenNox main repository.
GNU General Public License v3.0
446 stars 24 forks source link

FindObject cannot find any missiles #646

Closed Ephreaym closed 7 months ago

Ephreaym commented 8 months ago

object.ClassMissile seems not to be implemented?

if (ns.InCirclef{Center: wiz.unit, R: 200}).Matches(ns.FindClosestObject(wiz.unit, ns.HasClass(object.ClassMissile))) {
        wiz.unit.ChatStr("INVERT")
    }

I'm trying to add an inversion script. Script works fine on other classes, look a door. But I can't use ClassMissile.

angrykirc commented 7 months ago

This problem occurs because of the way the game engine treats these Missile objects. They are not stored in the bucketByPos table, the one FindClosestObject function uses internally. https://github.com/noxworld-dev/opennox/blob/6f232cc4c4adb33c90fdde995cdf81e32f0f6142/src/server/map.go#L240-L270 Needs a workaround method, probably using 0x750700 (UpdatableList, non-missile global object table) and 0x750704 (UpdatableList2, missile global object table)

dennwc commented 7 months ago

Sorry, this is a known issue, forgot to open a ticket for it.

As @angrykirc pointed out, script searches the list that does not contain missiles. Will fix for the next Alpha.

Ephreaym commented 7 months ago

Getting a lot of errors. Script does run when a missile is detected.

package test

import (
    "github.com/noxworld-dev/noxscript/ns/v4"
    "github.com/noxworld-dev/opennox-lib/object"
)

var initReady bool
var Bot ns.Obj

func init() {
    initReady = false
    ns.NewTimer(ns.Seconds(2), func() {
        spawnBot()
    })

}

func spawnBot() {
    Bot = ns.CreateObject("NPC", ns.Ptf(2771, 3067))
    Bot.HasTeam(ns.GetHost().Team())
    initReady = true
}
func OnFrame() {
    if initReady {
        if (ns.InCirclef{Center: Bot, R: 200}).Matches(ns.FindClosestObject(Bot, ns.HasClass(object.ClassMissile))) {
            Bot.ChatStr("INVERT")
        } else {

        }
    }

}

2024/01/02 08:21:33 [script]: panic in OnFrame: runtime error: invalid memory address or nil pointer dereference 2024/01/02 08:21:33 [console]: V:\src\test\test.go:25:5: panic: test.OnFrame(...)

dennwc commented 7 months ago

That's likely because there's no spells to invert most of the time. Try this:

if sp := ns.FindClosestObject(wiz.unit, ns.HasClass(object.ClassMissile), ns.InCirclef{Center: wiz.unit, R: 200}); sp != nil {
        wiz.unit.ChatStr("INVERT")
}

In your case FindClosestObject returns nil most of the time and then Matches panics because it doesn't accept nil.