Problem mit Trigger

» Siedler Map Source Forum » Siedler DEdK Script Forum » Problem mit Trigger

Seiten: 1

Ghoul
#1
21.05.2019 23:02
Beiträge: 284

Problem mit Trigger

Hey, stehe grade ein wenig auf dem Schlauch...
Kann mir iwer sagen, wo hier der Fehler liegt:

 
function Abfragen()
--  verbesserte Nebelkrieger
 local entityNeK = Event.GetEntityID()
	local entityTypeNeK = Logic.GetEntityTypeName(Logic.GetEntityType(entityNeK))
     local humanPlayerNeK = GUI.GetPlayerID()
    local playerNeK = GetPlayer(entityNeK)		
		if entityTypeNeK == "CU_Evil_LeaderBearman1" and playerNeK == humanPlayerNeK and TruppenUpgrade >= 1 then
      Message("Upgrade erfolgreich!")
			mcbEMan.SetEntityDamage(entityNeK, 22)
			mcbEMan.SetEntityArmor(entityNeK, 7)			
			end
-- verbesserte Speerwerfer
local entitySpW = Event.GetEntityID()
	local entityTypeSpW = Logic.GetEntityTypeName(Logic.GetEntityType(entitySpW))
     local humanPlayerSpW = GUI.GetPlayerID()
    local playerSpW = GetPlayer(entitySpW)		
		if entityTypeSpW == "CU_Evil_LeaderSkirmisher1"  and playerSpW == humanPlayerSpW and TruppenUpgrade >= 1 then
 Message("Upgrade erfolgreich!")
    mcbEMan.SetEntityExploration(entitySpW, 2600)			
    mcbEMan.SetEntityMaxRange(entitySpW, 2350)						
		end
                   end


Aufgerufen wird das ganze mit

Trigger.RequestTrigger(Events.LOGIC_EVENT_ENTITY_CREATED, "", "Abfragen", 1)



Die ganzen anderen Gebäude/Einheiten werden korrekt abgefragt (hab hier jetzt nur den nicht funktionierenden Teil gezeigt. TruppenUpgrade ist einfach nur ein Parameter, der beim Bau eines bestimmten Gebäudes um 1 steigt.
An einer anderen Stelle verändere ich die Kosten von Gebäuden mittels mcbEMan ohne Probleme; daran sollte es also nicht liegen

mcb
#2
22.05.2019 14:55
Beiträge: 1472

Was genau ist denn das Problem?
Tauchen die Messages auf, wenn du neue Entities erstellst?
Ist dir klar, das diese mcbEMan Funktionen ein paar Sekunden brauchen können, um einen effekt zu haben?

Ghoul
#3
22.05.2019 15:47
Beiträge: 284

Die Messages sind ja nur zu Testzwecken drin, tauchen aber leider gar nicht erst auf..
Dass die Funktionen ein paar Sek brauchen ist mir klar, aber trotzdem tut sich leider nichts.
Habs grade mal im Debugger gestartet und bekomme die Meldung:

 Trigger 18 action test invalid 

mcb
#4
22.05.2019 16:16
Beiträge: 1472

Klingt eher so, als wäre irgendwas mit dem starten des Jobs schiefgegangen. Der Aufruf da unten sieht allerdings korrekt aus.

Ghoul
#5
22.05.2019 17:43
Beiträge: 284

Daran kann´s eigentlich nicht liegen, weil ja auch alles darunter problemlos funktioniert. Nur eben diese beiden mit den Bärenmenschen und Speerwerfern nicht :/
Hab mal eine der restlichen Entitys mit rüberkopiert (immer noch nur ein kleiner Auszug)

function Abfragen()
    local entitySE = Event.GetEntityID()
    local entityTypeSE = Logic.GetEntityTypeName(Logic.GetEntityType(entitySE))
    local humanPlayerSE = GUI.GetPlayerID()
    local playerSE = GetPlayer(entitySE)
    if entityTypeSE == "PB_DarkTower1" and playerSE == humanPlayerSE then
       
    Logic.SetModelAndAnimSet(entitySE, Models.XD_BoneAnimal7)
GoldBonus = GoldBonus +1
end
end

mcb
#6
22.05.2019 18:26
Beiträge: 1472

Funktioniert es, wenn du den Test auf TruppenUpgrade rausnimmst?

Ghoul
#7
22.05.2019 21:35
Beiträge: 284

Nein auch ohne geht es nicht. Kann es sein, dass es am Entity type liegt??

mcb
#8
22.05.2019 21:49
Beiträge: 1472

Hm, du könntest dir mal Ausgeben lassen, was die entsprechenden Variablen sind. Entweder mit Messages oder indem du ein LuaDebugger.Break an die entsprechende Stelle setzt.

Ghoul
#9
23.05.2019 12:41
Beiträge: 284

Habe einen Teil des Fehlers gefunden... Die einzelnen Skripte wurden in falscher Reihenfolge geladen.. Die Bärenmenschen bekommen jetzt den gewünschten Dmg und Rüssi Buff. Allerdings crasht das Spiel, wenn ich die Reichweiten der Speerwerfer erhöhe..
Der Debugger sagt mir

 assertion failed! 

bei

 function GetPlayer(_entity)
	local entityId = GetEntityId(_entity)
	assert(IsValid(entityId))
	return Logic.EntityGetPlayer(entityId)
	end 



Würde mich jetzt wundern, wenn das mit Speerwerfern explizit nicht geht?
Vertippt habe ich mich ja auch nicht beim entityType
edit: Schadenswerte von den Speerwerfern kann ich problemlos ändern, scheint also an der Änderung der Range zu liegen. Muss ich dafür noch einen zusätzlichen Aufruf im Skript vornehmen?
Nebenbei mal so am Rand: mit den Funktionen ändere ich ja nur die Werte des Leaders. Werden die Werte der Soldiers automatisch mit verändert oder muss ich die auch in die Triggerfunktion abfragen?

Dieser Beitrag wurde von Ghoul am 23.05.2019 um 13:09 editiert.

mcb
#10
23.05.2019 15:10
Beiträge: 1472

Das hört sich eher an als wäre irgendwo ein Parameter falsch übergeben worden.
Am einfachsten findest du sowas mit dem Debugger raus: Provoziere den Fehler und sieh dir dann im Funktionsstack die Funktionen und deren übergebene Parameter an.

Und ja, das ganze gilt nur für die Hauprmänner, für deren Soldaten muss es extra eingestellt werden.

Ghoul
#11
23.05.2019 16:54
Beiträge: 284

Mit deinen Funktionen kann ich aber doch nicht die Werte der Soldier ändern, oder? Die gehen alle nur für Leader oder täusche ich mich?

 function mcbEMan.SetEntityDamage(id, dmg)
	id = GetID(id)
	assert(IsAlive(id) and Logic.IsLeader(id)==1)
	dmg = round(dmg)
	if dmg < 0 then
		mcbEMan.Inter_RemoveBattleValue(id, 33)
		return
	end
	mcbEMan.Inter_AddBattleValue(id, 33, dmg, 12)
end

function mcbEMan.SetEntityMaxRange(id, range)
	id = GetID(id)
	assert(IsAlive(id) and Logic.IsLeader(id)==1)
	assert(type(range)=="number")
	if S5Hook.GetEntityMem(id)[58+49]:GetFloat()==-1 then
		mcbEMan.Inter_QuickFakeAttack(id)
	end
	if range < 0 then
		mcbEMan.Inter_RemoveBattleValue(id, 49)
		return
	end
	mcbEMan.Inter_AddBattleValue(id, 49, range, 44)
end

function mcbEMan.SetEntityExploration(id, explor)
	id = GetID(id)
	assert(IsAlive(id) and Logic.IsLeader(id)==1)
	assert(type(explor)=="number")
	if explor < 0 then
		mcbEMan.Inter_RemoveBattleValue(id, 47)
		return
	end
	mcbEMan.Inter_AddBattleValue(id, 47, explor, 40)
end

function mcbEMan.SetEntityArmor(id, def)
	id = GetID(id)
	assert(IsAlive(id) and Logic.IsLeader(id)==1)
	def = round(def)
	if def < 0 then
		mcbEMan.Inter_RemoveBattleValue(id, 39)
		return
	end
	mcbEMan.Inter_AddBattleValue(id, 39, def, 24)
end


Bekomme bei Solis wieder dieselben Fehler bei der Übergabe der Entity Id (weil angeblich ungültig)

mcb
#12
23.05.2019 17:17
Beiträge: 1472

Die hab ich nie für die soldiers getestet, und deswegen ist da ein test für die Leader drin. Du kannst mal versuchen den test einfach durch Logic.IsSettler==1 zu ersetzen und es ausprobieren.

Ghoul
#13
23.05.2019 18:31
Beiträge: 284

Geht tatsächlich auch mit soldiers
Für die Veränderung der Range scheint mir noch eine Funktion o.Ä. zu fehlen, denn das krieg ich immer noch nicht zum Laufen (dass der Debugger mir invalid Entity type übermittelt, kann auch nicht stimmen..)

mcb
#14
23.05.2019 19:30
Beiträge: 1472

Ok, was genau sagt denn der debugger? Am besten wäre die genaue Fehlermeldung sowie der call-stack (das heißt die Reihenfolge der aufgerufenen Funktionen die der Debugger anzeigt).

Ghoul
#15
24.05.2019 15:27
Beiträge: 284

unterste Ebene:

 [string "Data\Script\MapTools\Comfort.lua"]:744: assertion failed! 

bei Game Engine (direct call) Source: unavailable line 0

darüber:

 function GetPlayer(_entity)
	local entityId = GetEntityId(_entity)
	assert(IsValid(entityId))
	return Logic.EntityGetPlayer(entityId)
	end 

Err bei assert(IsValid(entityId))
bei global GetPlayer() Source: Data\Script\Map Tools\Comfort.lua line 744

darüber:

 local entitySpWSol = Event.GetEntityID()
	local entityTypeSpWSol = Logic.GetEntityTypeName(Logic.GetEntityType(entitySpWSol))
     local humanPlayerSpWSol = GUI.GetPlayerID()
    local playerSpWSol = GetPlayer(entitySpWSol)		
		if entityTypeSpWSol == "CU_Evil_SoldierSkirmisher1"  and playerSpWSol == humanPlayerSpWSol and TruppenUpgrade >= 1 then
 --Message("Upgrade erfolgreich!")
    mcbEMan.SetEntityExploration(entitySpWSol, 3200)			
    mcbEMan.SetEntityMaxRange(entitySpWSol, 2850)		
       mcbEMan.SetEntityDamage(entitySpWSol, 17)
			mcbEMan.SetEntityArmor(entitySpWSol, 4)					
		end 


Err bei GetPlayer(entitySpWSol)
bei local f() Source: maps\user\NVMod\NVMod_SP_Main.lua line 1284

darüber:

 function mcbTrigger.act(vtid)
	local tab = mcbTrigger.vtrigger[vtid]
	local f = tab.act
	if type(f)=="string" then
		f = _G[f]
	end
	if type(f)~="function" then
		mcbTrigger.err("Trigger "..tab.tid.." action "..tostring(tab.act).." invalid!")
		return false
	end
	local r = nil
	if mcbTrigger.isDebuggerActive() and not tab.noDebug then
		r = {true, f(unpack(tab.aact))}
	else
		r = {xpcall(function() return f(unpack(tab.aact)) end, mcbTrigger.err)}
	end
	local e = table.remove(r, 1)
	if not e then
		return false
	end
	if r[1] == true then
		mcbTrigger.vtrigger[tab.vtid] = nil
		mcbTrigger.trigger[tab.tid] = nil
	end
	mcbTrigger.errtid = nil
	return unpack(r)
end 


Err bei r = {true, f(unpack(tab.aact))}
bei global mcb Trigger_action() Source: maps\user\NVMod\triggerfix.lua line 310

mcb
#16
24.05.2019 15:57
Beiträge: 1472

Ich glaube das Problem ist, das du Event.GetEntityID() mehrmals aufrufst und zwischendurch von mcbEMan neue entities erstellt werden, was den Rückgabewert davon auf nil setzt.
Ich denke die neueste Version von mcbTrigger fixt das Problem: https://github.com/mcb5637/s5CommunityLib/blob/master/fixes/mcbTrigger.lua

Ghoul
#17
24.05.2019 16:36
Beiträge: 284

Hat leider nichts geändert... Der Debugger spuckt das gleiche wie vorher aus. Dazu gekommen ist eine weitere Ebene: Lua Code Source: unavailable line 0. Außerdem wird jetzt beim Erstellen der Truppen die ganze Map aufgedeckt?!?!

mcb
#18
24.05.2019 17:53
Beiträge: 1472

Das die ganze Map aufgedeckt wird liegt wahrscheinlich daran, das dein exploration Wert zu hoch ist. Versuchs mal mit 32 (passt mehr zu den Werten in den xmls).

Und ich glaube ich weiß, warum der Fehler immer noch auftaucht: du verwendest Event.GetEntityID immer noch mehrmals in der Funktion. Versuch es mal so:

function Abfragen()
   local id = Event.GetEntityID()
   if GetPlayer(id)~=GUI.GetPlayerID()
      return
   end
   local ty = Logic.GetEntityType(id)
   if ty==Entities.CU_Evil_LeaderBearman1 then
      mcbEMan.SetEntityDamage(id, 22)
      mcbEMan.SetEntityArmor(id, 7)
   elseif ty == Entities.CU_Evil_LeaderSkirmisher1 then
      mcbEMan.SetEntityExploration(id, 32)
      mcbEMan.SetEntityMaxRange(id, 2350)
   -- weitere typen...
   end
end

Ghoul
#19
24.05.2019 18:39
Beiträge: 284

ok danke versuche ich mal so. Wundert ich nur, weil ich bei den Gebäudetypen ja auch mehrfach Event.GetEntityID verwende und alles reibungslos klappt. Mit der range: dachte die ist standardmäßig in Siedler cm angegeben.
Edit: Funktioniert jetzt. Vielen Dank für die Hilfe

Dieser Beitrag wurde von Ghoul am 24.05.2019 um 19:28 editiert.

mcb
#20
24.05.2019 21:17
Beiträge: 1472

Das Problem mit Event.GetEntityID ist ja, das es nur nicht funktioniert, wenn zwischendurch ein anderer Trigger ausgeführt wird. Und mcbEMan.SetEntityMaxRange erstellt und zerstört ein entity, um die maxrange im entity zu initialisieren.

Und ja, für den nachfolger von mcbEMan sollte ich eigentlich alle werte auf einen Standard ändern.

Seiten: 1

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

Impressum