GetClosestEntity

» Siedler Map Source Forum » Siedler DEdK Script Forum » GetClosestEntity

Seiten: 1

Ludwig
#1
04.07.2018 18:11
Beiträge: 439

GetClosestEntity

Habe mal versucht etwas mit der Funktion

GetClosestEntity(army1,30000)


zu machen. Leider ist das Ergebnis immer 0.
Habe verschiedene varianten versucht.
Hat jemand schon mal mit dieser Funktion gearbeitet ?
Gruß
Ludwig

mcb
#2
04.07.2018 21:24
Beiträge: 1472

Die verwendet AI.Army_SearchClosestEnemy, du musst also die AI für den entsprechenden Spieler anschalten.

Ludwig
#3
04.07.2018 22:00
Beiträge: 439

Danke für den Hinweis, werde ich probieren.
Leider hilft mir das mit AI nicht weiter. Ich bastel an einer Armeefunktion ähnlich der RobArmee aber wesentlich schlanker.
Da kann ich dann die AI aber nicht aktivieren.
Habe da schon eine lösung die ist aber nicht optimal.
Gruß
Ludwig

mcb
#4
04.07.2018 23:53
Beiträge: 1472

Hilft sowas:

mcbPacker.require("comfort/entity/getEntityTypesInCategory")

-- nächster feind in kategorie
function getNextEnemyInCategoryInArea(player, pos, range, cat)
	local tid, ran = 0, range + 1000000
	cat = (type(cat)=="table") and cat or getEntityTypesInCategory(cat)
	for i = 1,8 do
		if Logic.GetDiplomacyState(player, i) == Diplomacy.Hostile then
			for _,et in ipairs(cat) do
				local ids = {Logic.GetPlayerEntitiesInArea(i, et, pos.X, pos.Y, range, 5)}
				table.remove(ids, 1)
				for _,id in ipairs(ids) do
					if IsAlive(id) then
						local d = GetDistance(pos, id)
						if d < ran then
							tid = id
							ran = d
						end
					end
				end
			end
		end
	end
	return tid
end



(Hab meine eigene Armeefunktion die genau dasselbe gebraucht hat)

Ludwig
#5
05.07.2018 07:25
Beiträge: 439

Habe meine Funktion ähnlich aufgebaut, das Ergebnis wird den Trupps als Ziel übergeben.

function FeindDa(i)
	_player = TruppTab[i].Player
	_position = GetPosition(TruppTab[i].ID)
	_range = TruppTab[i].Range
    for n = 1,8 do	
		if Logic.GetDiplomacyState( _player, n) == Diplomacy.Hostile then
			Data = {Logic.GetPlayerEntitiesInArea( n, 0, _position.X, _position.Y, _range, 10)}
			for d = table.getn(Data), 1, -1 do
				if Logic.GetEntityType(Data[d]) == 631 then
					table.remove(Data,d)
				end
			end				
			for m= 2, Data[1]+1 do
				if Logic.IsHero(Data[m]) == 0 then
					if Logic.IsBuilding(Data[m]) == 1 or Logic.IsLeader(Data[m]) == 1 then
						_ty = Logic.GetEntityType(Data[m])
						_id = GetEntityId( Data[m])
						_typ = Logic.GetEntityTypeName(_ty)
						table.insert(TruppTab[i].Ziel,Data[m])
					end
				end
			end
		end
	end	
	for z = 1, table.getn(TruppTab) do 
		if table.getn(TruppTab[z].Ziel) == 0 then 
			Attack(TruppTab[z].ID, GetPosition(TruppTab[z].Epos))
		end
	end
end


Folgende Probleme herausgefiltert:
- Auch ein toter Held wird als Ziel erkannt, deshalb Helden raus.
Sonst bleibt der Trupp bei dem toten stehen da er als Ziel vorhanden ist.
- Diebe werden als Ziel übergeben und verlieren dadurch ihre Fähigkeit
unerkannt im Feindgebiet zu agieren.

Noch bestehendes Problem:
Wird ein nicht erreichbares Ziel übergeben, dann bleibt die Truppe stehen und greift nicht an.
Es müssten also Ziele die nicht erreichbar sind ebenfalls raus, dafür habe ich noch keine Lösung gefunden.

Ich bastel weiter.
Gruß
Ludwig

mcb
#6
05.07.2018 11:30
Beiträge: 1472

Ob ein Held tot ist oder nicht kannst du mit IsDead prüfen.
Und um die Unsichtbarkeit von Dieben/Ari auszulesen hab ich Funktionen in mcbEMan geschrieben.
Die Erreichbarkeit solltest du mit Logic.GetSector (oder so ähnlich) prüfen können. Ist die Rückgabe davon für beide entities gleich und ungleich 0 können sie sich erreichen.
Außerdem solltest du vielleicht die Variablen _player, _position und _range local machen und statt 631 Entities.XXX nehmen

Ludwig
#7
05.07.2018 15:20
Beiträge: 439

- Das Problem bei den Dieben ist, dass sie immer angegriffen werden wenn sie als Ziel eingefügt wurden. Jetzt geht es.
- Variable nicht auf local gesetzt, da Script im Test ist und so die Werte im Debugger ausgelesen werden können.
- GetSector habe ich bisher nicht verwendet da mir das Ergebnis des Befehls nicht klar ist. Das Problem ist, die Enties sind ja dicht beieinander aber es ist ein Hinderniss dazwischen (Fluß, Mauer ).
- Die Zahlen für Enties sind reine Schreibfaulheit geht schneller.

mcb
#8
05.07.2018 15:33
Beiträge: 1472

Diebe: ich filtere über mcbEMan die entities raus die unsichtbar sind und nutze die, die es nicht sind.

local: Wenn irgendwas nicht funktioniert, pack ich ein LuaDebugger.Break() rein, dann kann ich die Funktion Schritt für Schritt durchgehen und mir die lokalen Variablen ansehen.

GetSector: Siedler teilt die Map in verschiedene zusammenhängende Gebiete (Sector) ein und die Funktion gibt zurück, in welchem davon sich ein entity befindet. Ist die Zahl gleich, befinden sich die entities im selben Sector und können sich zueinander bewegen. Dabei ist Sector 0 alles geblockte Gebiet und daher musst du darauf noch extra testen. (Der Hook kann auch an den Sector einer beliebigen Position kommen, ohne extra ein entity dort zu erstellen.)

Ludwig
#9
06.07.2018 09:35
Beiträge: 439

Danke für Deine Unterstützung. Da habe ich nun einiges zum probieren. Aber jetzt geht es erst einmal ab in den Urlaub. 3 Wochen ohne Internet und Computer.
Gruß
Ludwig

Seiten: 1

SiteEngine v1.5.0 by nevermind, ©2005-2007
Design by SpiderFive (www.siedler-games.de) - English translation by juja

Impressum