AI PLAYER, TROOP SPAWN SCRIPT AND MORE

» Siedler Map Source Forum » Siedler DEdK Script Forum » AI PLAYER, TROOP SPAWN SCRIPT AND MORE

Seiten: Zurück 1 2 3 4 5 6 Nächste Seite

polaster64
#26
24.02.2018 22:29
Beiträge: 184

Zitat von polaster64:

Zitat von polaster64:

Zitat von mcb:
Just use the briefing function as callback at the NPC:

function CreateNpcScout()
    local npc = {
        name     = "scout", -- name of the npc
        callback = SpecialBriefing, -- what should be called, when the npc gets spoken with
    }
    CreateNPC(npc)
end



function SpecialBriefing()
    -- this contains all data for the briefing
    local briefing = {};
    -- AddPage / AddShortPage functions, used to fill the briefing
    local AP, ASP = AddPages(briefing);
    
    -- ASP( _name, _title, _text, _dialog);
    -- _name: Script name of the target entity. camera will centered at this entity
    -- _title: Page title
    -- _text: Page text
    -- _dialog: set to true to move the camera closer, else just leave it out
    ASP("scout","Scout","I heared you destroyed this tower?", true);
    ASP("erec","Erec","Yes, that was planned.");
    ASP("scout","Scout","Ok, then its fine!", true);
    -- just add as many pages as you need
    
    StartBriefing(briefing); -- starts the briefing (dont forget this)
end

You need this functions in your script:
[code]function AddPages( _briefing )
    local AP = function(_page) table.insert(_briefing, _page); return _page; end
    local ASP = function(_entity, _title, _text, _dialog) return AP(CreateShortPage(_entity, _title, _text, _dialog)); end
    return AP, ASP;
end
function CreateShortPage( _entity, _title, _text, _dialog) 
    local page = {
        title = _title,
        text = _text,
        position = GetPosition( _entity ),
        dialogCamera = _dialog
    };
    return page;
end



can I create

function SpecialBriefing1()
function SpecialBriefing2()


et cetera? Or it will only work with

function SpecialBriefing()


hmm?
Because I wanna do over a dozen or so briefings, so here is the question:

Will it work?



https://imgur.com/a/SyOke
Look here. Everytime I use CreateArmyOne() or CreateANYFUNCTION
there goes an error and I dont know where is the problem because down below the function is called without any mistakes so I dont really know where is the problem god damnit



And I also see that function CreateNPC doesnt work. The yellow "!" doesnt appear at the NPC head, what might be the problem?

mcb
#27
24.02.2018 22:46
Beiträge: 1472

Ok, that error comes from calling a function that doesn't exist. (and i think everything other comes from that).

Maybe read something about Lua first? Especially about functions?

It is completely irrelevant how you name them, you just have to use the same name when you call them.

polaster64
#28
24.02.2018 23:03
Beiträge: 184

Zitat von mcb:
Ok, that error comes from calling a function that doesn't exist. (and i think everything other comes from that).

Maybe read something about Lua first? Especially about functions?

It is completely irrelevant how you name them, you just have to use the same name when you call them.


And I did that. As u can see
CreateSpecialBriefing()
function SpecialBriefing()

I really cant see the mistake here, it matches perfectly, doesnt it?

polaster64
#29
24.02.2018 23:25
Beiträge: 184

Zitat von polaster64:

Zitat von mcb:
Ok, that error comes from calling a function that doesn't exist. (and i think everything other comes from that).

Maybe read something about Lua first? Especially about functions?

It is completely irrelevant how you name them, you just have to use the same name when you call them.


And I did that. As u can see
CreateSpecialBriefing()
function SpecialBriefing()

I really cant see the mistake here, it matches perfectly, doesnt it?


Okay I found out what should I do, the solution was really strange and funny but simple, nevermind.

mcb
#30
24.02.2018 23:41
Beiträge: 1472

I see 2 errors there:
1) You call CreateSpecialBriefing() but you define SpecialBriefing()
2) You call it before you define it

polaster64
#31
24.02.2018 23:47
Beiträge: 184

Zitat von mcb:
I see 2 errors there:
1) You call CreateSpecialBriefing() but you define SpecialBriefing()
2) You call it before you define it



So should I define it as function CreateSpecialBriefing()?

Well the fix I did to my script was to just

function FirstMapAction()


local VictoryConditionType = 1

	if VictoryConditionType == 1 then
		MapEditor_SetupResourceVictoryCondition(	
													200000,
													7000,
													5000,
													6000,
													4000,
													3000 ) 
	elseif VictoryConditionType == 2 then
		MapEditor_SetupDestroyVictoryCondition(2)
	end

	-- Level 0 is deactivated...ignore
	MapEditor_SetupAI(2, 0, 0, 0, "", 0, 0)
	MapEditor_SetupAI(3, 0, 0, 0, "", 0, 0)
	MapEditor_SetupAI(4, 0, 0, 0, "", 0, 0)
	MapEditor_SetupAI(5, 0, 0, 0, "", 0, 0)
	MapEditor_SetupAI(6, 0, 0, 0, "", 0, 0)
	MapEditor_SetupAI(7, 0, 0, 0, "", 0, 0)
	MapEditor_SetupAI(8, 1, 4000, 0, "nic", 0, 0)

	-- HQ Defeat Condition
	MapEditor_CreateHQDefeatCondition()

CreateNpcGuard()    -- I moved it here 
CreatePreludeBriefing() -- I moved it here
CreateNpcBurmistrz() -- I moved it here
end
-- instead of here
function CreateNpcGuard()
    local npc = {
        name     = "Guard", -- name of the npc
        callback = BriefingGuard, -- what should be called, when the npc gets spoken with
    }
    CreateNPC(npc)
end

mcb
#32
25.02.2018 00:03
Beiträge: 1472

That move seems correct.

Functions work like this:
When the Programm comes to a function call, it jumps to this function (so it has to be the exact same name). When the function finishes (at the end or a return statement) the Program jumps back to where the Function was called.
Example:

function foo()
   Message("foo 1")
   bar()
   Message("foo 2")
end
Message("root")
function bar()
   Message("bar")
end
foo()
CreateFoo()


The output is this:
"root"
"foo 1"
"bar"
"foo 2"
error, CreateFoo does not exist

What happens:

-- execution starts here
-- first, foo gets defined
function foo()
   Message("foo 1")
   bar()
   Message("foo 2")
end
-- output "root"
Message("root")
-- then bar gets defined
function bar()
   Message("bar")
end
foo()
CreateFoo()


When foo gets called:

function foo()
   -- output "foo 1"
   Message("foo 1")
   -- call bar, execution jumps to bar, bar outputs "bar" and returns
   bar()
   -- after bar returned, fo resumes execution
   -- outputs "foo 2"
   Message("foo 2")
   -- now foo also returns
end
Message("root")
function bar()
   Message("bar")
end
foo()
-- and after foo returns, execution resumes here
CreateFoo() -- and tries to call CreateFoo (which does not exist)

polaster64
#33
25.02.2018 00:29
Beiträge: 184

Zitat von mcb:
That move seems correct.

Functions work like this:
When the Programm comes to a function call, it jumps to this function (so it has to be the exact same name). When the function finishes (at the end or a return statement) the Program jumps back to where the Function was called.
Example:

function foo()
   Message("foo 1")
   bar()
   Message("foo 2")
end
Message("root")
function bar()
   Message("bar")
end
foo()
CreateFoo()


The output is this:
"root"
"foo 1"
"bar"
"foo 2"
error, CreateFoo does not exist

What happens:

-- execution starts here
-- first, foo gets defined
function foo()
   Message("foo 1")
   bar()
   Message("foo 2")
end
-- output "root"
Message("root")
-- then bar gets defined
function bar()
   Message("bar")
end
foo()
CreateFoo()


When foo gets called:

function foo()
   -- output "foo 1"
   Message("foo 1")
   -- call bar, execution jumps to bar, bar outputs "bar" and returns
   bar()
   -- after bar returned, fo resumes execution
   -- outputs "foo 2"
   Message("foo 2")
   -- now foo also returns
end
Message("root")
function bar()
   Message("bar")
end
foo()
-- and after foo returns, execution resumes here
CreateFoo() -- and tries to call CreateFoo (which does not exist)


Ah thank you for that explanation, now I will know what to do, really appreciate that sir.
I have another question.

How to set a dissapear position for npc? I mean we ended the talk with him and then he goes to the location "X" and dissapears forever.

And um like how to create troops without using CreateArmyX function?
Just like a one or two leaders with for example 6 troops and that all?
I've seen that it was similar to CreateEtnity but I forgot where I saw that and couldnt find it till now so thats why I am asking.

CreateMilitaryGroup(3, Entities.PU_LeaderBow4, 8, GetPosition("tower2"),"ErecTruppe6")


Nevermind. Thats what I was searching for.

Dieser Beitrag wurde von polaster64 am 25.02.2018 um 00:47 editiert.

mcb
#34
25.02.2018 00:48
Beiträge: 1472

You could use MoveAndVanish(entity, pos) . But it only Destroys the entity when it is inside the fog of war.

polaster64
#35
25.02.2018 11:49
Beiträge: 184

Zitat von mcb:
You could use MoveAndVanish(entity, pos) . But it only Destroys the entity when it is inside the fog of war.


Thats no problem for me, I planned the entity to go to the opposite location of the quest locaton.

polaster64
#36
25.02.2018 12:54
Beiträge: 184


function CreateMilitaryGroup()
CreateMilitaryGroup(4, Entities.CU_Barbarian_LeaderClub1, 4, GetPosition ("E2"))
CreateMilitaryGroup(4, Entities.CU_Barbarian_LeaderClub1, 4, GetPosition ("E1"))
CreateMilitaryGroup(8, Entities.PU_LeaderPoleArm1, 4, GetPosition ("E3"))
end


I have a problem over here. The entities dont spawn, what might be the problem, luadebugger doesnt show any errors.

mcb
#37
25.02.2018 13:37
Beiträge: 1472

Most likely that you define a function CreateMilitaryGroup which overrides the BB definition of CreateMilitaryGroup. So your function just calls itself -> stack overflow

polaster64
#38
25.02.2018 13:46
Beiträge: 184

Well now I have bigger problem. The game crashes and says system access violation exception. Dont know what happened, and Im really sad about it because I dont know how to copy my whole map phisics.

polaster64
#39
25.02.2018 14:17
Beiträge: 184

Alright, somehow I did it and we can get back to our discussion ;p

polaster64
#40
25.02.2018 14:18
Beiträge: 184

Zitat von polaster64:



CreateMilitaryGroup(4, Entities.CU_Barbarian_LeaderClub1, 4, GetPosition ("E2"))
CreateMilitaryGroup(4, Entities.CU_Barbarian_LeaderClub1, 4, GetPosition ("E1"))
CreateMilitaryGroup(8, Entities.PU_LeaderPoleArm1, 4, GetPosition ("E3"))



I have a problem over here. The entities dont spawn, what might be the problem, luadebugger doesnt show any errors.


When I put this alone it also doesnt work
I made completely new map, somehow copied the physics and here we go, everything works perfectly. I feel really strange now, that something like that can fix whole map.

Dieser Beitrag wurde von polaster64 am 25.02.2018 um 14:39 editiert.

mcb
#41
25.02.2018 15:17
Beiträge: 1472

Sounds like you try to create an entity of a not existing type or in an invalid position.

polaster64
#42
25.02.2018 23:34
Beiträge: 184

function UsunSkaly()
if IsDestroyed("Skaly1" ) then -- jezeli objekt "Kamien" zostanie zniszczony to...

StartSimpleJob("Zasadzka")
StartSimpleJob("UsunSkaly1")
CreateArmyOne()

return true
else --jezeli nie to...
    Message("Go to the stones, village needs resources!") -- zostanie wyswietlona informacja, ale ze jest pusta to nie zostanie wyswietlona (mialem problem bo skrypt wariowal gdy nie bylo tutaj zupelnie nic)
		return false -- false/true oznacza czy funkcja ma zostac zakonczona
	end
end
function UsunSkaly1()

if IsDestroyed("Skaly2") then -- jezeli objekt "Kamien" zostanie zniszczony to...
ChangePlayer("b1", 1)
ChangePlayer("b2", 1)
ChangePlayer("b3", 1)
ChangePlayer("b4", 1)
ChangePlayer("b5", 1)
ChangePlayer("b6", 1)
ChangePlayer("b7", 1)
ChangePlayer("b8", 1)
ChangePlayer("b9", 1)
ChangePlayer("b10", 1)
ChangePlayer("b11", 1)
ChangePlayer("b12", 1)
ChangePlayer("b13", 1)
ChangePlayer("b14", 1)
ChangePlayer("b15", 1)
ChangePlayer("b16", 1)
ChangePlayer("b17", 1)
ChangePlayer("b18", 1)
ChangePlayer("b19", 1)
ChangePlayer("b20", 1)
ChangePlayer("b21", 1)
ChangePlayer("HQ1", 1)
AddGold(1500)
AddClay(900)
AddWood(800)
AddStone(1000)
AddIron(1000)
AddSulfur(700)
CreatePreludeBriefing3()

return true
else
    Message("Destroy all the stones")
    return false
  end 

end



function CreatePreludeBriefing3()
PreludeBriefing = {}



	PreludeBriefing.finished = PreludeBriefingFinished3



	page = 0

	--	page #1

	
		page = page + 1

		
		PreludeBriefing[page] 				= 	{}

	
		PreludeBriefing[page].title		= 	"Burmistrz"
		PreludeBriefing[page].text			=	"Very nice, the village is yours, good luck!"

		
     PreludeBriefing[page].position 	= 	GetPosition("Burmistrz")



		PreludeBriefingShowBurmistrz			= PreludeBriefing[page]
end
function PreludeBriefingFinished3()

	ResolveBriefing(PreludeBriefingShowBurmistrz)


end


I have a problem with that script. When object Skaly2 gets destroyed the prelude briefing doesnt start and I have no idea why.

And second problem. The message destroy the stones appears every second, is there any way to change it to appear every for example 15 seconds?


And third problem is the "explore" function work. When the briefing starts, the talk is going on and on, and finally when there is this point where we are getting showed our new objective position for the time of the end of the briefing, then after the briefing this position is still showed for unlimited amount of time and is there any way to change it to be showed for like 30s seconds?

I know i wrote it very chaotish so let me explain it in script.

AP = AP{
		tilte			= "Burmistrz",
		text			= "Spojrzcie tam, wlasnie tam znajduja sie nasze surowce pogrzebane przez bandytow, Pielgrzymie czy moglbys je dla nas oczyscic?Jezeli wam sie to uda to wioska jest wasza, powodzenia!",
		position		= GetPosition("Skaly1"),
		dialogCamera	= false,
		explore			= 1500, } -- this is the moment when the camera shows us the area and I even tried to do something like exploreTime = 1 * 20 but it didnt work, so here goes the question - how to do it?

Play4FuN
#43
26.02.2018 07:46
Beiträge: 704

You can use this:

StartSimpleJob("MyJob1")

function MyJob1()
 if Counter.Tick2("MyJob1", 15) then
  --your code; once every 15 seconds (until return true)
 end

 --code that should be executed every second (until return true)

end



Why use the "ugly" old style code?

CreateMilitaryGroup: try making it for player 1, so you can see if the group is not created at all OR just at position (0,0)!
Maybe you have duplicated entities on your map with the same name, then your map will not know where to create the group.

You can select all entities in the MapEditor with the button in the selection view and then sort them by their names to check if there are any names twice.

(Also, you should be able to leave out the "return false" in your SimpleJobs - only the return true is important here.)

____________________
LG Play4FuN

Siedler DEdK Mapping + Scripting Tutorials

Dieser Beitrag wurde von Play4FuN am 26.02.2018 um 07:56 editiert.

polaster64
#44
26.02.2018 12:15
Beiträge: 184

Zitat von Play4FuN:
You can use this:

StartSimpleJob("MyJob1")

function MyJob1()
 if Counter.Tick2("MyJob1", 15) then
  --your code; once every 15 seconds (until return true)
 end

 --code that should be executed every second (until return true)

end



Why use the "ugly" old style code?

CreateMilitaryGroup: try making it for player 1, so you can see if the group is not created at all OR just at position (0,0)!
Maybe you have duplicated entities on your map with the same name, then your map will not know where to create the group.

You can select all entities in the MapEditor with the button in the selection view and then sort them by their names to check if there are any names twice.

(Also, you should be able to leave out the "return false" in your SimpleJobs - only the return true is important here.)




Well this is the style I understand and dont have a problem with, your way is strange for me, I dont really get it. And I have never seen it in scripts from other maps. Because mostly I learn from other maps scripts and could you give the bigger example? Like all of this but also add the code.

And I really dont know any other way to create briefing that doesnt need any npc to right click on it to start the briefing. Prelude briefing is the only function I found out that can do this. If there is a possibility to do the briefing with the new style that does not require any NPC then please give me an example. It would be really nice if you could explain this to me. I tried it different ways and there was always a mistake or error.

mcb
#45
26.02.2018 14:31
Beiträge: 1472

You remember this:

function SpecialBriefing()
    -- this contains all data for the briefing
    local briefing = {};
    -- AddPage / AddShortPage functions, used to fill the briefing
    local AP, ASP = AddPages(briefing);
    
    -- ASP( _name, _title, _text, _dialog);
    -- _name: Script name of the target entity. camera will centered at this entity
    -- _title: Page title
    -- _text: Page text
    -- _dialog: set to true to move the camera closer, else just leave it out
    ASP("scout","Scout","I heared you destroyed this tower?", true);
    ASP("erec","Erec","Yes, that was planned.");
    ASP("scout","Scout","Ok, then its fine!", true);
    -- just add as many pages as you need

    -- now we add a page with explore
    local resolve1 = AP{
       title = "Erec",
       text = "Next, we have to destroy another tower!",
       position = GetPosition("tower2),
       explore = 2000,
    }

    -- now remove the exploration
    briefing.finished = function()
       ResolveBriefing(resolve1) -- resolve1 is a local varable in SpecialBriefing (so should not be visible in another function), but briefing.finished is declared inside SpecialBriefing so resolve1 is an upvalue here and you can acces it. (This only works for Lua) But be careful, upvalues are not saved! Every script that uses them breaks, when saved and loaded! Inside a Briefing, this is fine, as you can not save here.
    end
    
    StartBriefing(briefing); -- starts the briefing (dont forget this)
end



I just added a page with explore and a finished function. This briefing does't have to be attached to a NPC, but it can be. If you just call SpecialBriefing() from your job, the briefing starts without a NPC.

Edit: In your old style briefing, you forgot the StartBriefing call, which is the reason it didn't work.

polaster64
#46
26.02.2018 17:49
Beiträge: 184

Zitat von mcb:
You remember this:

function SpecialBriefing()
    -- this contains all data for the briefing
    local briefing = {};
    -- AddPage / AddShortPage functions, used to fill the briefing
    local AP, ASP = AddPages(briefing);
    
    -- ASP( _name, _title, _text, _dialog);
    -- _name: Script name of the target entity. camera will centered at this entity
    -- _title: Page title
    -- _text: Page text
    -- _dialog: set to true to move the camera closer, else just leave it out
    ASP("scout","Scout","I heared you destroyed this tower?", true);
    ASP("erec","Erec","Yes, that was planned.");
    ASP("scout","Scout","Ok, then its fine!", true);
    -- just add as many pages as you need

    -- now we add a page with explore
    local resolve1 = AP{
       title = "Erec",
       text = "Next, we have to destroy another tower!",
       position = GetPosition("tower2),
       explore = 2000,
    }

    -- now remove the exploration
    briefing.finished = function()
       ResolveBriefing(resolve1) -- resolve1 is a local varable in SpecialBriefing (so should not be visible in another function), but briefing.finished is declared inside SpecialBriefing so resolve1 is an upvalue here and you can acces it. (This only works for Lua) But be careful, upvalues are not saved! Every script that uses them breaks, when saved and loaded! Inside a Briefing, this is fine, as you can not save here.
    end
    
    StartBriefing(briefing); -- starts the briefing (dont forget this)
end



I just added a page with explore and a finished function. This briefing does't have to be attached to a NPC, but it can be. If you just call SpecialBriefing() from your job, the briefing starts without a NPC.

Edit: In your old style briefing, you forgot the StartBriefing call, which is the reason it didn't work.


Haha, its so funny I didnt see it so simple mistake causing so many problems, thank you very much!


I have another question here
How to create chests like with gold, wood et cetera.

And another question.
How does exactly function IsNear work?
I tried it and didnt get good results.

function Treasure()
if IsNear("Dario"-- its the hero, "treasure"-- its the entity, 500) then

StartSimpleJob("exampleofbriefing")
    return true
  end
end


When I was walking with Dario on the exact point where the script entity was it didnt work but when I was going really far it started working, how should I set the range, how does the range work in this exact script?
I really dont have any idea about it.

mcb
#47
26.02.2018 18:07
Beiträge: 1472

IsNear: I think your problem are the comments. -- marks the rest of the line as comment.

function foo()
   if bar(1, -- something 2) then
      somethingOther()
   end
end


causes some syntax errors.
This would be better:

function foo()
   if bar(1, 2) then -- something
      somethingOther()
   end
end



Chests:

CreateChestOpener("dario") --first define who can open the chests
CreateChestOpener("erec") -- call it again with all other heroes you need
CreateRandomGoldChest(GetPosition("randomGoldChest")) -- creates a chest with random amount of gold
CreateGoldChest(GetPosition("goldChest")) -- creates a chest with 2000 gold
CreateIronChest(GetPosition("ironChest")) -- creates a chest with 2000 iron
CreateChest(GetPosition("randomChest")) -- creates a chest with 1000 of one random resource or nothing
StartChestQuest() -- start the job that opens the chests, when one defined entity is near a chest

polaster64
#48
26.02.2018 18:27
Beiträge: 184

Zitat von mcb:
IsNear: I think your problem are the comments. -- marks the rest of the line as comment.

function foo()
   if bar(1, -- something 2) then
      somethingOther()
   end
end


causes some syntax errors.
This would be better:

function foo()
   if bar(1, 2) then -- something
      somethingOther()
   end
end



Chests:

CreateChestOpener("dario") --first define who can open the chests
CreateChestOpener("erec") -- call it again with all other heroes you need
CreateRandomGoldChest(GetPosition("randomGoldChest")) -- creates a chest with random amount of gold
CreateGoldChest(GetPosition("goldChest")) -- creates a chest with 2000 gold
CreateIronChest(GetPosition("ironChest")) -- creates a chest with 2000 iron
CreateChest(GetPosition("randomChest")) -- creates a chest with 1000 of one random resource or nothing
StartChestQuest() -- start the job that opens the chests, when one defined entity is near a chest


No no, I added those comments just for now, usually they are never in the script. The problem is that I dont know how does that function work I mean the range of the function. What is the max range and best range?

mcb
#49
26.02.2018 19:25
Beiträge: 1472

Range is in Scm (Settler-centimeter) . Attack range from most ranged attacks is around 2700 Scm.
Which one you want to choose depends on what to use it for. The Chests use 250. I don't think there s a maximum (except from the obviois max value of the datatype).

It works simple:

function IsNear(entity1, entity2, range)
   local p1 = GetPosition(entity1)
   local p2 = GetPosition(entity2)
   local dx = p1.X - p2.X
   local dy = p1.Y - p2.Y
   return math.sqrt(dx*dx + dy*dy) < range
end



(But it is coded in C++ and im not sure that < is not a <=)

polaster64
#50
26.02.2018 19:54
Beiträge: 184

Zitat von polaster64:

Zitat von mcb:
IsNear: I think your problem are the comments. -- marks the rest of the line as comment.

function foo()
   if bar(1, -- something 2) then
      somethingOther()
   end
end


causes some syntax errors.
This would be better:

function foo()
   if bar(1, 2) then -- something
      somethingOther()
   end
end



Chests:

CreateChestOpener("dario") --first define who can open the chests
CreateChestOpener("erec") -- call it again with all other heroes you need
CreateRandomGoldChest(GetPosition("randomGoldChest")) -- creates a chest with random amount of gold
CreateGoldChest(GetPosition("goldChest")) -- creates a chest with 2000 gold
CreateIronChest(GetPosition("ironChest")) -- creates a chest with 2000 iron
CreateChest(GetPosition("randomChest")) -- creates a chest with 1000 of one random resource or nothing
StartChestQuest() -- start the job that opens the chests, when one defined entity is near a chest


No no, I added those comments just for now, usually they are never in the script. The problem is that I dont know how does that function work I mean the range of the function. What is the max range and best range?



How to create the chest with exact amount of something for example 4213 gold. The exact number.

Seiten: Zurück 1 2 3 4 5 6 Nächste Seite

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

Impressum