AI attacks me right after start of the game-HELP

» Siedler Map Source Forum » Siedler DEdK Script Forum » AI attacks me right after start of the game-HELP

Seiten: 1

TyphonCZ
#1
19.04.2019 15:41
Beiträge: 12

AI attacks me right after start of the game-HELP

Hello, I need help. I want to play with my friend COOP( we could do that, because I already hosted a map before..The AI was idle, even though it recruited units(it wasnt attacking, only defending, because I scripted it that way.. but nvm, moving on)

I managed to edit a map really well, but when I join the game, AI recruits units and attacks me in a minute after the game starts, which I dont want it to do, of course.
One of the AI(number 5) is completely still, doesnt even recruit units
AI number 4 recruits units and attacks me right away, as well as AI number 3 does.
Here is the script:
----

Script.Load( Folders.MapTools.."Main.lua" )
IncludeGlobals("MapEditorTools"
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if XNetwork then
XNetwork.GameInformation_GetLogicPlayerTeam = function() return 1; end
XNetwork.GameInformation_GetFreeAlliancesFlag = function() return 1; end
end

function GameCallback_OnGameStart()

-- Include global tool script functions
Script.Load(Folders.MapTools.."Ai\\Support.lua"
Script.Load( Folders.MapTools.."Main.lua" )
-- Unbedingt muß für die Einbindung der Ki hier auch dieses am Anfang geladen werden
IncludeGlobals("MapEditorTools"
Script.Load( "Data\\Script\\MapTools\\Counter.lua" )
Script.Load( "Data\\Script\\MapTools\\MultiPlayer\\MultiplayerTools.lua" )
Script.Load( "Data\\Script\\MapTools\\Tools.lua" )
Script.Load( "Data\\Script\\MapTools\\WeatherSets.lua" )
IncludeGlobals("Comfort"
-- notwendig damit die Siegbedingungen greifen
gvMission = {}
gvMission.PlayerID = GUI.GetPlayerID()


--Init local map stuff
Mission_InitWeatherGfxSets()
InitWeather()
Mission_InitGroups()
Mission_InitLocalResources()

-- Init global MP stuff
--MultiplayerTools.InitResources("normal"
MultiplayerTools.InitCameraPositionsForPlayers()
MultiplayerTools.SetUpGameLogicOnMPGameConfig()
MultiplayerTools.GiveBuyableHerosToHumanPlayer( 1 )
StartSimpleJob("VictoryJob"
SetHostile(3,2)
SetHostile(3,1)
SetHostile(4,1)
SetHostile(5,1)
SetHostile(5,2)
SetHostile(4,2)
SetFriendly(1,2)
SetFriendly(3,4)
SetFriendly(3,5)
SetFriendly(4,5)

ActivateShareExploration(1,2)



if XNetwork.Manager_DoesExist() == 0 then
for i = 1, 2 do -- Für 2 Spieler eingestellt
MultiplayerTools.DeleteFastGameStuff(i)
end
local PlayerID = GUI.GetPlayerID()
Logic.PlayerSetIsHumanFlag( PlayerID, 1 )
Logic.PlayerSetGameStateToPlaying( PlayerID )
end
-- Die weiteren menschlichen Spieler müssen auf Feind gestellt werden so dies gewünscht ist zu allen KI's


LocalMusic.UseSet = MEDITERANEANMUSIC

-- Diese Zeilen kommen noch vom Karteneditor und setzen die Standardsiegbedingung vernicht die Player Id
MapEditor_SetupDestroyVictoryCondition(3)
MapEditor_CreateHQDefeatCondition()

local aiID = 3

local strength = 2
local range = 100000
local techlevel = 3

local position = "Mary's Entrance"

local aggressiveness = 1
local peacetime = 3500

MapEditor_SetupAI(aiID,strength,range,techlevel,position,aggressiveness,peacetime)
SetupPlayerAi(3,{
serfLimit = 25,
SetPlayerName( 3, "Mary" );
resources = {
gold = 40000,
wood = 20000,
clay = 20000,
iron = 20000,
stone = 20000,
sulfur = 20000
},
refresh = {
gold = 40000,
wood = 20000,
clay = 22000,
iron = 20000,
stone = 20000,
sulfur = 15000,
updateTime = 120
},
rebuild = {
delay = 0,
randomTime = 0
},
repairing = true,
constructing = true,
extracting = true,

})

local aiID = 5
local strength = 4
local range = 100000
local techlevel = 3
local position = "Kerberos' Castle"
local aggressiveness = 1
local peacetime = 5500
MapEditor_SetupAI(aiID,strength,range,techlevel,position,aggressiveness,peacetime)
SetupPlayerAi(5,{
SetPlayerName( 5, "Kerberos" );
serfLimit = 35,
resources = {
gold = 50000,
wood = 50000,
clay = 50000,
iron = 50000,
stone = 50000,
sulfur = 50000
},
refresh = {
gold = 50000,
wood = 50000,
clay = 50000,
iron = 50000,
stone = 50000,
sulfur = 50000,
updateTime = 120
},
rebuild = {
delay = 0,
randomTime = 0
},
repairing = true,
constructing = true,
extracting = true,

})
local aiID = 4
local strength = 1
local range = 100000
local techlevel = 1
local position = "4Barracks"
local aggressiveness = 1
local peacetime = 1600

MapEditor_SetupAI(aiID,strength,range,techlevel,position,aggressiveness,peacetime)
SetPlayerName( 4, "Harrassers" );
SetupPlayerAi(4,{
serfLimit = 0,
resources = {
gold = 40000,
wood = 20000,
clay = 20000,
iron = 20000,
stone = 20000,
sulfur = 20000
},
refresh = {
gold = 40000,
wood = 20000,
clay = 22000,
iron = 20000,
stone = 20000,
sulfur = 15000,
updateTime = 120
},
rebuild = {
delay = 0,
randomTime = 0
},
repairing = false,
constructing = false,
extracting = false,

})

end

function Mission_InitWeatherGfxSets()
-- Use gfx sets
SetupHighlandWeatherGfxSet()

end

--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- This function is called on game start you should setup your weather periods here
function InitWeather()
-- Hier wird der Wetterwechsel festgelegtl
-- Beispiel 4 Min Sommer, dann 2 Minuten Winter, dann wieder alles von vorne
AddPeriodicSummer(650)
AddPeriodicRain(220)


end
function
ActivateShareExploration(_player1, _player2, _both)
assert(type(_player1) == "number" and type(_player2) == "number" and _player1 <= 8 and _player2 <= 8 and _player1 >= 1 and _player2 >= 1);
if _both == false then
Logic.SetShareExplorationWithPlayerFlag(_player1, _player2, 1);
else
Logic.SetShareExplorationWithPlayerFlag(_player1, _player2, 1);
Logic.SetShareExplorationWithPlayerFlag(_player2, _player1, 1);
end
end

--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Build Groups and attach Leaders
function Mission_InitGroups()

end

--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Limit the Technologies here. For example Weathermashine.
function
Mission_InitTechnologies()
--no limitation in this map
end

--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Set local resources
function
Mission_InitLocalResources()
local HumenPlayer = XNetwork.GameInformation_GetMapMaximumNumberOfHumanPlayer()


-- Dies sind die Startresourcen für alle Spieler. Diese sollten angepasst werden
local InitGoldRaw = 3500

local InitClayRaw = 3200

local InitWoodRaw = 3200

local InitStoneRaw = 2200

local InitIronRaw = 1200

local InitSulfurRaw = 500



--Add Players Resources
for i = 1, 8 do
Tools.GiveResouces(i, InitGoldRaw , InitClayRaw,InitWoodRaw, InitStoneRaw,InitIronRaw,InitSulfurRaw)
end
end

function VictoryJob()
if IsDead("Mary's Castle" and
IsDead("Kerberos' Castle"
then

Victory();
return true;
end
end


PS: everything else works perfectly. Just this problem. Would be glad if you would reply to me ASAP <3

Dieser Beitrag wurde von TyphonCZ am 19.04.2019 um 16:15 editiert.

mcb
#2
19.04.2019 18:39
Beiträge: 1472

Ok, first thing: Put your script inside
[code]
function foo()
end
[/code]
which then looks like this:

function foo()
end



Next thing is to check all entity names you have done to include only alphanumerical characters. So "Mary's Entrance" becomes "marysEntrance" .
Then you should check if the entities you want to use as positions for the ai are all named correct and only of the type XD_ScriptEntity (so they don't get accidentally deleted by something).
You should also move your calls of SetPlayerName out of the table declarations for SetupPlayerAi, because this would include their return values into the table (if they had any).

TyphonCZ
#3
19.04.2019 19:01
Beiträge: 12

Thanks, but..

Hey, thanks for the fast response. However, the AI is still acting weird. I managed to fix AI(5) to actually play(by reducing its strength to 4) but now all come after me, including (5).
Isn't there something like Advance(_army) required? Or something similar? Because they all just come after me in 10 seconds. By the way thanks for the advice with XD_scriptentities.
I also checked the script wiki, but none of the functions set timer or delay the attack(because that is all I need). Or maybe I'm just bad at German language..
I just need to fix this one problem.. AI instantly engaging.
PS:I'm sorry for the format of the script. (Would send it again but I'm replying by using my phone, cuz our internet is down... might send it here later.. plus I already edited it.)

mcb
#4
19.04.2019 19:36
Beiträge: 1472

Your range parameter might be too high. This is the distance from the position that the ai considers its base. If something is inside this range, it gets attacked. Try reducing it to a more reasonable level (maybe by setting an additional script entity at the most outwards point of their base and then calculating the distance between these two points).

Edit: PS: No problem with the script, i already copied/autoformatted it, i just wrote this part so you can use it for the next time.

TyphonCZ
#5
19.04.2019 21:04
Beiträge: 12

Thanks

I have to say, this definitely didn't come up to my mind.. You just saved my 5 hour work of editing the map and the scripts. Because without your help it would probably stay unfinished. Anyway, everything is working perfectly, except for just a few of enemy units. They somehow "bug and split up" on many places(they are like a troop, but separated) it doesn't affect gameplay at all, just affects the grouping of units before they attack. (E.g. they are in moving animation). This isn't very needed to be solved, I'm just curious ^-^ I thank you so much! I might actually post it here someday.. ^-^
PS: I'm kind of embarrassed to ask, but.. If I ever need help again, should I post my message on your profile or Here?
I hope it won't come to that ever again though.

mcb
#6
19.04.2019 21:10
Beiträge: 1472

That is most likely a bug in the army movement control, no way to fix it, as it is coded in C++ and not accesiible per script.

For future questions it would be best to make a thread here at the forums, so others could read it or respond as well).

Play4FuN
#7
20.04.2019 10:13
Beiträge: 704

A little hint...

Hi Typhon,

as I sometimes encountered people who are new to mapping having similar issues... I want to add a tiny but important hint:

In the MapEditor, check that the playerID for ALL entites is correct! Even the walls, decorations etc. and especially for multiplayer maps also the ScriptEntities!

Two things here:

1) Whan e.g. a wall has a human player ID, then the enemy AI will consider this wall to be an enemy unit that might be in its defensive range and thus attack the player, even if the player has no (regular) unit anywhere near the AI.

2) ScriptEntities and any other entity are being deleted on map start when they belong to a player ID that could be occupied by a human player, but is not. You understand what I'm trying to say? The game assumes the entites of a certain player ID are not needed when the human player with this ID is not in the game ... and removes them at game start.

Hope that helps some ppl trying to get into mapping

____________________
LG Play4FuN

Siedler DEdK Mapping + Scripting Tutorials

TyphonCZ
#8
20.04.2019 11:26
Beiträge: 12

Thanks again

Hello Play4Fun
Thank you for this hint, I'm sure this will help me with some other maps. I'm probably going to post my map here today, after I test it with my friend.. So you can check it out if you wish. I kind of forgot about one thing though- I set the defensive range at 210(The map is like 2 islands) and it was just enough for them not to attack me when I don't cross the bridge in between. How is the defensive range measured? I looked at X, Y, Z coordinates. but I don't think it's measured by that.
PS: I'm surprised people still check these forums, because it was my last hope. And it worked so soon! I'm so glad to have you guys.
Here is the final script, for any people who could maybe use it.

--------------------------------------------------------------------------------
-- MapName: XXX
--
-- Author: XXX
--
--------------------------------------------------------------------------------

-- Include main function
Script.Load( Folders.MapTools.."Main.lua" )
IncludeGlobals("MapEditorTools")
	--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if XNetwork then
    XNetwork.GameInformation_GetLogicPlayerTeam = function() return 1; end
    XNetwork.GameInformation_GetFreeAlliancesFlag = function() return 1; end
end

function GameCallback_OnGameStart() 	
 
	-- Include global tool script functions	
	Script.Load(Folders.MapTools.."Ai\\Support.lua")
	Script.Load( Folders.MapTools.."Main.lua" )
	-- Unbedingt muß für die Einbindung der Ki hier auch dieses am Anfang geladen werden
	IncludeGlobals("MapEditorTools")
	Script.Load( "Data\\Script\\MapTools\\Counter.lua" )
	Script.Load( "Data\\Script\\MapTools\\MultiPlayer\\MultiplayerTools.lua" )	
	Script.Load( "Data\\Script\\MapTools\\Tools.lua" )	
	Script.Load( "Data\\Script\\MapTools\\WeatherSets.lua" )
	IncludeGlobals("Comfort")
	-- notwendig damit die Siegbedingungen greifen 
	gvMission = {}
	gvMission.PlayerID = GUI.GetPlayerID()
 
 
	--Init local map stuff
	Mission_InitWeatherGfxSets()
	InitWeather()
	Mission_InitGroups()	
	Mission_InitLocalResources()
 
	-- Init  global MP stuff
	--MultiplayerTools.InitResources("normal")
	MultiplayerTools.InitCameraPositionsForPlayers()	
	MultiplayerTools.SetUpGameLogicOnMPGameConfig()
	MultiplayerTools.GiveBuyableHerosToHumanPlayer( 1 )
	StartSimpleJob("VictoryJob")
SetHostile(3,2)
  SetHostile(3,1)
  SetHostile(4,1)
  SetHostile(5,1)
  SetHostile(5,2)
  SetHostile(4,2)
  SetFriendly(1,2)
  SetFriendly(3,4)
  SetFriendly(3,5)
  SetFriendly(4,5)
SetPlayerName(5,"Kerberos")
SetPlayerName(3,"Mary")
SetPlayerName(4,"Harassers")
ActivateShareExploration(1,2)

 
 
	if XNetwork.Manager_DoesExist() == 0 then		
		for i = 1, 2 do    -- Für 2 Spieler eingestellt
			MultiplayerTools.DeleteFastGameStuff(i)
		end
		local PlayerID = GUI.GetPlayerID()
		Logic.PlayerSetIsHumanFlag( PlayerID, 1 )
		Logic.PlayerSetGameStateToPlaying( PlayerID )
	end
	-- Die weiteren menschlichen Spieler müssen auf Feind gestellt werden so dies gewünscht ist zu allen KI's

 
	LocalMusic.UseSet = MEDITERANEANMUSIC
	--Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
	-- nicht vergessen das jeweils nur ein Set gesetzt sein sollte
	--LocalMusic.UseSet = EUROPEMUSIC
	--LocalMusic.UseSet = HIGHLANDMUSIC
	--LocalMusic.UseSet = MEDITERANEANMUSIC
	--LocalMusic.UseSet = DARKMOORMUSIC
	--LocalMusic.UseSet = EVELANCEMUSIC
 
    -- Diese  Zeilen kommen noch vom Karteneditor und setzen die Standardsiegbedingung vernicht die Player Id
	MapEditor_SetupDestroyVictoryCondition(3)
	MapEditor_CreateHQDefeatCondition()

 local aiID = 3

 local strength = 2
 local range = 120
 local techlevel = 3

 local position = "marysEntrance"

 local aggressiveness = 1
 local peacetime = 3500

 MapEditor_SetupAI(aiID,strength,range,techlevel,position,aggressiveness,peacetime)
  SetupPlayerAi(3,{
  serfLimit = 25,
   resources = {
    gold = 40000,
    wood = 20000,
    clay = 20000,
    iron = 20000,
    stone = 20000,
    sulfur = 20000
   },
   refresh = {
    gold = 40000,
    wood = 20000,
    clay = 22000,
    iron = 20000,
    stone = 20000,
    sulfur = 15000,
    updateTime = 120
   },
   rebuild = {
    delay = 0,
    randomTime = 0
   },
  repairing = true,
  constructing = true,
  extracting = true,

})

 local aiID = 5
 local strength = 3
 local range = 210
 local techlevel = 3
 local position = "armyKerb"
 local aggressiveness = 1
 local peacetime = 5500
 MapEditor_SetupAI(aiID,strength,range,techlevel,position,aggressiveness,peacetime)
  SetupPlayerAi(5,{
  serfLimit = 35,
   resources = {
    gold = 50000,
    wood = 50000,
    clay = 50000,
    iron = 50000,
    stone = 50000,
    sulfur = 50000
   },
   refresh = {
    gold = 50000,
    wood = 50000,
    clay = 50000,
    iron = 50000,
    stone = 50000,
    sulfur = 50000,
    updateTime = 120
   },
   rebuild = {
    delay = 0,
    randomTime = 0
   },
  repairing = true,
  constructing = true,
  extracting = true,

})
 local aiID = 4
 local strength = 1
 local range = 110
 local techlevel = 1
 local position = "armyTwo"
 local aggressiveness = 2
 local peacetime = 600

 MapEditor_SetupAI(aiID,strength,range,techlevel,position,aggressiveness,peacetime)
 SetupPlayerAi(4,{
  serfLimit = 0,
   resources = {
    gold = 40000,
    wood = 20000,
    clay = 20000,
    iron = 20000,
    stone = 20000,
    sulfur = 20000
   },
   refresh = {
    gold = 40000,
    wood = 20000,
    clay = 22000,
    iron = 20000,
    stone = 20000,
    sulfur = 15000,
    updateTime = 120
   },
   rebuild = {
    delay = 0,
    randomTime = 0
   },
  repairing = false,
  constructing = false,
  extracting = false,

})

end 

function Mission_InitWeatherGfxSets()
	-- Use gfx sets
	SetupHighlandWeatherGfxSet()
	--Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen nicht vergessen das man nur ein setzten sollte
	--SetupNormalWeatherGfxSet()
	--SetupHighlandWeatherGfxSet()
	--SetupSteppeWeatherGfxSet()
	--SetupMoorWeatherGfxSet()
	--SetupEvelanceWeatherGfxSet()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- This function is called on game start you should setup your weather periods here
function InitWeather()
	-- Hier wird der Wetterwechsel festgelegtl 
	-- Beispiel 4 Min Sommer, dann 2 Minuten Winter, dann wieder alles von vorne
	AddPeriodicSummer(650) 
  AddPeriodicRain(220)
	--Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
	--AddPeriodicSummer(600) 
    --AddPeriodicWinter(300) 
    --AddPeriodicRain(120) 
 
end
function 
ActivateShareExploration(_player1, _player2, _both)
	assert(type(_player1) == "number" and type(_player2) == "number" and _player1 <= 8 and _player2 <= 8 and _player1 >= 1 and _player2 >= 1);
	if _both == false then
		Logic.SetShareExplorationWithPlayerFlag(_player1, _player2, 1);
	else
		Logic.SetShareExplorationWithPlayerFlag(_player1, _player2, 1);
		Logic.SetShareExplorationWithPlayerFlag(_player2, _player1, 1);
	end
end

--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Build Groups and attach Leaders
function Mission_InitGroups()
 
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Limit the Technologies here. For example Weathermashine.
function
Mission_InitTechnologies()
	--no limitation in this map
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Set local resources
function
Mission_InitLocalResources()
	local HumenPlayer = XNetwork.GameInformation_GetMapMaximumNumberOfHumanPlayer()
 
 
	-- Dies sind die Startresourcen für alle Spieler. Diese sollten angepasst werden
	local InitGoldRaw 		= 3500

	local InitClayRaw 		= 3200

	local InitWoodRaw 		= 3200

	local InitStoneRaw 		= 2200

	local InitIronRaw 		= 1200

	local InitSulfurRaw		= 500

 
 
	--Add Players Resources
	for i = 1, 8 do
        Tools.GiveResouces(i, InitGoldRaw , InitClayRaw,InitWoodRaw, InitStoneRaw,InitIronRaw,InitSulfurRaw)
end
end

function VictoryJob()
    if IsDead("marysCastle") and
       IsDead("kerberosCastle")
then

        Victory();
        return true;
end
end

mcb
#9
20.04.2019 13:27
Beiträge: 1472

It should be a normal range measured in Scm (Settlers-centimeters, the same the coordinates consist of). You can put

Report = Message

into your FMA to get some debug info about your armies and see in which state it is, when attacking you. (defensive, offensive defensive or attack)
But other than that, nobody really knows what this AI is doing and tries to controll troops as directly as possible.

TyphonCZ
#10
20.04.2019 13:55
Beiträge: 12

Thanks again :D

Hello mcb, thank you for your response. To be honest, I have kind of no idea what you just said though what exactly is FMA? And also, if local range is 210 for example, does it mean that if i attack some other of their buildings thats further than this range of some scriptentity, will They just ignore me? Sorry for askin so many questions.

mcb
#11
20.04.2019 14:17
Beiträge: 1472

Oh, forgot that this is a MP script. In SP scripts there is a function called FirstMapAction, often called FMA. In your script this would be the GameCallback_OnGameStart.

The AI is supposed to work like this:
At any tick it searches the nearest enemy entity and checks its distance to the army

local pent = GetPosition(tar)
local pown = GetPosition(own)
local dist = math.sqrt((pent.X-pown.X)*(pent.X-pown.X) + (pent.Y-pown.Y)*(pent.Y-pown.Y)
if dist < range then
...


if the target is n range, the army moves there, if not it gets ignored (doesn't matter if the ais entities actually see the target entity).

TyphonCZ
#12
20.04.2019 15:42
Beiträge: 12

Good to know

Hello again mcb, this is definitely gonna be useful for me. Thank you!
By the way, should I replace the three dots (…) with something else? like FrontalAttack(armyTwo)? it would make sense to me that way.
Or should I replace it with something totally different?
Or could you maybe show me an example?
Thanks again, Typhon.

mcb
#13
20.04.2019 15:47
Beiträge: 1472

It was only to show you how simple the ai works, it would not make much sense anywhere in an actual mapscript.

TyphonCZ
#14
20.04.2019 16:04
Beiträge: 12

Oh.

Hello.. silly me. it's obvious I'm an amateur... but thanks anyway.
I better stop asking stupid questions
If I think of anything I will let u know.

TyphonCZ
#15
21.04.2019 16:16
Beiträge: 12

Map is released

Hello. Thanks to you guys, the map is finally released, and its working as intended. I want to thank you one last time. Any feedback is welcome.

Seiten: 1

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

Impressum