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