noxworld-dev / opennox

OpenNox main repository.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FindObject cannot find any missiles

Ephreaym opened this issue · comments

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.

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.

opennox/src/server/map.go

Lines 240 to 270 in 6f232cc

func (s *serverMap) AddMissileXxx(obj *Object) {
if f := obj.Flags(); f.Has(object.FlagDestroyed) || f.Has(object.FlagPartitioned) || !f.Has(object.FlagActive) {
return
}
if !obj.Class().Has(object.ClassMissile) {
obj.UpdateCollider(obj.NewPos)
sp := RoundPos(obj.CollideP1)
ep := RoundPos(obj.CollideP2)
if sp.X < 0 {
sp.X = 0
}
if sp.Y < 0 {
sp.Y = 0
}
if ep.X >= s.indexSize {
ep.X = s.indexSize - 1
}
if ep.Y >= s.indexSize {
ep.Y = s.indexSize - 1
}
obj.ObjIndexCur = 0
for y := sp.Y; y <= ep.Y; y++ {
for x := sp.X; x <= ep.X; x++ {
s.addObjToMap(true, image.Pt(x, y), obj)
}
}
}
pi := RoundPos(obj.NewPos)
s.addObjToMap(false, pi, obj)
obj.ObjFlags |= uint32(object.FlagPartitioned)
}

Needs a workaround method, probably using 0x750700 (UpdatableList, non-missile global object table) and 0x750704 (UpdatableList2, missile global object table)

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.

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(...)

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.