[Tote] Semi-random army generator for those that need

Maps and the art of mapmaking.
User avatar
Jonas
Conscript
Conscript
Posts: 219
Joined: 14 Jan 2009

[Tote] Semi-random army generator for those that need

Unread postby Jonas » 15 Feb 2009, 04:03

EDIT: script uppdated! Now all tiers have random uppgrades.
EDIT2:Uppdate of instructions below script.
Ok, this is what I have been enjoying my life with for a couple of days, eh, nights :tired:

I saw Asheeras random monster generator a couple of months back http://www.celestialheavens.com/forums/ ... om+monster, just when I had started to learn scripting - and it was just too complicated then :|

Now when I have a little bit more knowledge of scripting I looked at it again a couple of days ago and thought, great thing! It is just one thing, it places the monsters on the map totally random and I'm in need of control :devious: So, I decided to make myself one that suited my preferences and here it is.

The script will look messy here in the forum but just copy and paste it to your script editor. I have put some instructions and notes below the script that is important to read.

Code: Select all

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ COPY AND PASTE IN BEGINNING OF SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~






diff = GetDifficulty()+1; -- 1=easy, 2=normal, 3=hard, 4=heroic

creaturetable = {{{1,2,106},{3,4,107},{5,6,108},{7,8,109},{9,10,110},{11,12,111},{13,14,112}}, --		haven=[1]
{{15,16,131},{17,18,132},{19,20,133},{21,22,134},{23,24,135},{25,26,136},{27,28,137}}, --				inferno=[2]
{{29,30,152},{31,32,153},{33,34,154},{35,36,155},{37,38,156},{39,40,157},{41,42,158}}, --				necro=[3]
{{43,44,145},{45,46,146},{47,48,147},{49,50,148},{51,52,149},{53,54,150},{55,56,151}}, --				sylvan=[4]
{{57,58,159},{59,60,160},{61,62,161},{63,64,162},{65,66,163},{67,68,164},{69,70,165}}, --				academy=[5]
{{71,72,138},{73,74,139},{75,76,140},{77,78,141},{79,80,142},{81,82,143},{83,84,144}}, --				dungeon=[6]
{{92,93,166},{94,95,167},{96,97,168},{98,99,169},{100,101,170},{102,103,171},{104,105,172}}, --			fortress=[7]
{{117,118,173},{119,120,174},{121,122,175},{123,124,176},{125,126,177},{127,128,178},{129,130,179}}, --	stronghold=[8]
{{113,113,113},{113,113,113},{88,88,88},{87,85,86},{116,116,116},{89,115,89},{91,91,91}}}; --			neutrals=[9]



function monsterGenerator()
	local strenght = diff*0.8; -- variable for group strenght. Increase/decrease "0.8" for more/less creatures
	local groups = 9; -- Change this value to the amount of "groups" you put on map
	local factions = {}; -- stores placed creatures faction (objectName) to make right kind of addition
	local tierqty = 0; -- variable for amount of tiers that should be added (total groups divided with total tiers)
	local tier1 = 22; -- base amount of creatures/tier
	local tier2 = 16; --			''
	local tier3 = 11; --			''
	local tier4 = 7; --				''
	local tier5 = 4; --				''
	local tier6 = 2; --				''
	local tier7 = 1; --				''
	for i=1,groups do
		for j=1,9 do
			factions[i] = GetObjectCreaturesTypes("gr"..i);
			tierqty = groups/7;
			if factions[i] == creaturetable[j][1][1] then
				if i < tierqty then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					elseif i > tierqty and i < tierqty*2 then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					AddObjectCreatures("gr"..i, creaturetable[j][2][1+random(3)], tier2+intg(i/tierqty*strenght*tier2));
					elseif i > tierqty*2 and i < tierqty*3 then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					AddObjectCreatures("gr"..i, creaturetable[j][2][1+random(3)], tier2+intg(i/tierqty*strenght*tier2));
					AddObjectCreatures("gr"..i, creaturetable[j][3][1+random(3)], tier3+intg(i/tierqty*strenght*tier3));
					elseif i > tierqty*3 and i < tierqty*4 then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					AddObjectCreatures("gr"..i, creaturetable[j][2][1+random(3)], tier2+intg(i/tierqty*strenght*tier2));
					AddObjectCreatures("gr"..i, creaturetable[j][3][1+random(3)], tier3+intg(i/tierqty*strenght*tier3));
					AddObjectCreatures("gr"..i, creaturetable[j][4][1+random(3)], tier4+intg(i/tierqty*strenght*tier4));
					elseif i > tierqty*4 and i < tierqty*5 then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					AddObjectCreatures("gr"..i, creaturetable[j][2][1+random(3)], tier2+intg(i/tierqty*strenght*tier2));
					AddObjectCreatures("gr"..i, creaturetable[j][3][1+random(3)], tier3+intg(i/tierqty*strenght*tier3));
					AddObjectCreatures("gr"..i, creaturetable[j][4][1+random(3)], tier4+intg(i/tierqty*strenght*tier4));
					AddObjectCreatures("gr"..i, creaturetable[j][5][1+random(3)], tier5+intg(i/tierqty*strenght*tier5));
					elseif i > tierqty*5 and i < tierqty*6 then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					AddObjectCreatures("gr"..i, creaturetable[j][2][1+random(3)], tier2+intg(i/tierqty*strenght*tier2));
					AddObjectCreatures("gr"..i, creaturetable[j][3][1+random(3)], tier3+intg(i/tierqty*strenght*tier3));
					AddObjectCreatures("gr"..i, creaturetable[j][4][1+random(3)], tier4+intg(i/tierqty*strenght*tier4));
					AddObjectCreatures("gr"..i, creaturetable[j][5][1+random(3)], tier5+intg(i/tierqty*strenght*tier5));
					AddObjectCreatures("gr"..i, creaturetable[j][6][1+random(3)], tier6+intg(i/tierqty*strenght*tier6));
					elseif i > tierqty*6 then
					AddObjectCreatures("gr"..i, creaturetable[j][1][1+random(3)], tier1+intg(i/tierqty*strenght*tier1));
					sleep(1);
					RemoveObjectCreatures("gr"..i, creaturetable[j][1][1], 1);
					AddObjectCreatures("gr"..i, creaturetable[j][2][1+random(3)], tier2+intg(i/tierqty*strenght*tier2));
					AddObjectCreatures("gr"..i, creaturetable[j][3][1+random(3)], tier3+intg(i/tierqty*strenght*tier3));
					AddObjectCreatures("gr"..i, creaturetable[j][4][1+random(3)], tier4+intg(i/tierqty*strenght*tier4));
					AddObjectCreatures("gr"..i, creaturetable[j][5][1+random(3)], tier5+intg(i/tierqty*strenght*tier5));
					AddObjectCreatures("gr"..i, creaturetable[j][6][1+random(3)], tier6+intg(i/tierqty*strenght*tier6));
					AddObjectCreatures("gr"..i, creaturetable[j][7][1+random(3)], tier7+intg(i/tierqty*strenght*tier7));
				end;
			end;
		end;
	end;
end;	
startThread(monsterGenerator);
Instructions and notes:

This monster generator purpous is to make the script do the most time consuming work when placing armies on your map. All you have to do is to put tier 1 monsters of the lowest rank on your map on the locations you choose. When you have set it, mark it and hit the space-bar, set the the amount to custom 1 (this prevents unexpected high amounts if it's set to random). Close the box and then give the monster the script name, "gr1". Repeat this procedeur with all monsters but give the next one the name "gr2" and thereafter "gr3" and so on.

Change the local variable 'groups' in the script to the same number as your last monster (total monsters).

The theory is that the higher the number is in the monsters script names the stronger it will get when the generator runs. This feature does that you have control of the strenght of the armies. Start putting monsters at the "beginning" of your map and continue to the "end" of it.

Uppdate, more details abouth group strenght: The difference in strenght between the first and last group is always the same despite how many groups you put on map. If you want to cange the total strenght of the armies, change the strenght-variable in the script. If you want different strenght over the "timeline", change the base value variables.

You can choose any factions you want and the generator will handle the different ones, but it only put additional monters from the same faction in the army. NOTE: for neutrals (elementals etc) I have coosen the wolf as the lowest ranked creature.

All the tiers uppgrades will be randomly mixed.

Ask as many questions as you want and I'll try to help the best I can. If someone have any ideas of changes - please tell me. :-D I'm still new to this, so maybe I have overdone it in som parts.

Good luck,

Jonas
Last edited by Anonymous on 17 Feb 2009, 23:43, edited 4 times in total.
:leo: A man who carries a cat by the tail learns something he can learn in no other way.
Mark Twain

Franzy
War Dancer
War Dancer
Posts: 362
Joined: 07 Sep 2007
Location: Moscow, Russia
Contact:

Unread postby Franzy » 16 Feb 2009, 10:14

In case you don't know there is a function RemoveObjectCretures to remove that tier1 creature from the army.

I use a more advanced army generator on my new map. It gives a lot more control to the user and can form pretty interesting armies. It's based on templates and a few parameters (minimum/maximum levels, danger level, number of caster stacks (groups of 2-4 creatures that can cast buffs), etc). However, it requires a user to predefine an array that holds these parameters.

User avatar
Jonas
Conscript
Conscript
Posts: 219
Joined: 14 Jan 2009

Unread postby Jonas » 16 Feb 2009, 12:35

Franzy wrote:In case you don't know there is a function RemoveObjectCretures to remove that tier1 creature from the army.
I tried that one but it removed the whole group beacause the tier1 holds the objectName.
Franzy wrote:I use a more advanced army generator on my new map.
I knew it! :lol:

It's really fun to mess around with the scripting to see what you can do :-D . I spend a lot more time at my test-map than at my adventure project and that's not good for my time scedule. Looking forward to play your map.

Take care,

Jonas
:leo: A man who carries a cat by the tail learns something he can learn in no other way.
Mark Twain

Franzy
War Dancer
War Dancer
Posts: 362
Joined: 07 Sep 2007
Location: Moscow, Russia
Contact:

Unread postby Franzy » 16 Feb 2009, 13:21

Well, obviously you should remove the tier1 creature AFTER you add other troops. Script name is not tied to a creature, it's tied to an object. In our case the object is an army of monsters.
Looking forward to play your map.
It's not finished yet (only 30% done), still needs a lot of work. A couple of months maybe...

User avatar
Jonas
Conscript
Conscript
Posts: 219
Joined: 14 Jan 2009

Unread postby Jonas » 16 Feb 2009, 19:31

Franzy wrote:Well, obviously you should remove the tier1 creature AFTER you add other troops. Script name is not tied to a creature, it's tied to an object. In our case the object is an army of monsters.
That's exactly what I did. I let that command run between the fourth and fifth tier creature-adding so that it would be space enough for all seven tiers.

Maybe it was something wrong that I didn't see. I'll better check it again :P
:leo: A man who carries a cat by the tail learns something he can learn in no other way.
Mark Twain

User avatar
Jonas
Conscript
Conscript
Posts: 219
Joined: 14 Jan 2009

Unread postby Jonas » 16 Feb 2009, 21:18

I tried it again, but with no luck. It still removes the whole army. It seems like the the added troops doesn't adapt the objectName. :mad:

Are you using a similar method to place your armies on the map?

EDIT: this is what it says in editor documentation on RemoveObjectCreatures
If the object is a monster and all creatures that form it are removed, the monster is removed from the map.
:leo: A man who carries a cat by the tail learns something he can learn in no other way.
Mark Twain

Franzy
War Dancer
War Dancer
Posts: 362
Joined: 07 Sep 2007
Location: Moscow, Russia
Contact:

Unread postby Franzy » 17 Feb 2009, 06:20

No, actually I use CreateMonster to place the first creature on the map.

Are you sure there is a sleep(1) command between AddObjectCreatures and RemoveObjectCreatures? Without it subsequent commands affecting one object may not work.

User avatar
Asheera
Round Table Knight
Round Table Knight
Posts: 4506
Joined: 06 Jul 2008
Location: The Shadows
Contact:

Unread postby Asheera » 17 Feb 2009, 13:57

Yeah I needed to put a sleep between CreateMonster and AddObjectCreatures as well, otherwise it said: "the object doesn't exist"
No matter how powerful one becomes, there is always someone stronger. That's why I'm in a constant pursuit of power, so I can be prepared when an enemy tries to take advantage of me.

User avatar
Jonas
Conscript
Conscript
Posts: 219
Joined: 14 Jan 2009

Unread postby Jonas » 17 Feb 2009, 14:29

Strange, but I swear that I tried it in my first attempt :| . Anyway it works now :D .

Sometimes you tend to change too many things at one time in the script if something don't work. It's easy to loose track on what you've tried and not tried. I always try to avoid it, but... :ashamed:

EDIT: I have uppdated the script above with RemoveObjectCreatures. Now all tiers have random uppgrades :-D
:leo: A man who carries a cat by the tail learns something he can learn in no other way.
Mark Twain

edwin_yang
Leprechaun
Leprechaun
Posts: 10
Joined: 23 Jan 2009

Unread postby edwin_yang » 18 Feb 2009, 13:02

Sometimes I find out that you need a different sleep time depends on the performence of your PC(just have this feeling, not sure). a short period of sleep may work well on a high-performance PC,but not on a lower one ;

for example, if I set the sleep() function less than 10, the hero wont move at all when I call the MoveHeroRealTime() function ....

User avatar
Asheera
Round Table Knight
Round Table Knight
Posts: 4506
Joined: 06 Jul 2008
Location: The Shadows
Contact:

Unread postby Asheera » 18 Feb 2009, 13:35

sleep is not calculated in seconds, it's in game-segments. I'm not sure how much one game-segment is in real-life seconds though.
No matter how powerful one becomes, there is always someone stronger. That's why I'm in a constant pursuit of power, so I can be prepared when an enemy tries to take advantage of me.

edwin_yang
Leprechaun
Leprechaun
Posts: 10
Joined: 23 Jan 2009

Unread postby edwin_yang » 18 Feb 2009, 13:38

It is likely to be 1/1000 second, tha same as the ai_time_llimit commmand. I guess.

User avatar
Asheera
Round Table Knight
Round Table Knight
Posts: 4506
Joined: 06 Jul 2008
Location: The Shadows
Contact:

Unread postby Asheera » 18 Feb 2009, 14:11

No, it's a lot longer than a milisecond. sleep(10) takes a while until it finishes.
No matter how powerful one becomes, there is always someone stronger. That's why I'm in a constant pursuit of power, so I can be prepared when an enemy tries to take advantage of me.

edwin_yang
Leprechaun
Leprechaun
Posts: 10
Joined: 23 Jan 2009

Unread postby edwin_yang » 18 Feb 2009, 14:33

seems you're right :) I just feel sometimes it is difficult to decide how long that you need in the sleep() function ;|

Franzy
War Dancer
War Dancer
Posts: 362
Joined: 07 Sep 2007
Location: Moscow, Russia
Contact:

Unread postby Franzy » 18 Feb 2009, 19:48

sleep(1) is around 1/20 of a second when the system is idle. It may take more if the system is busy.

User avatar
Asheera
Round Table Knight
Round Table Knight
Posts: 4506
Joined: 06 Jul 2008
Location: The Shadows
Contact:

Unread postby Asheera » 18 Feb 2009, 21:52

It doesn't matter that much actually, does it? (except that you shouldn't set the number too high :P) If you plan carefully only with in-game segments the script will be fine. ;)
No matter how powerful one becomes, there is always someone stronger. That's why I'm in a constant pursuit of power, so I can be prepared when an enemy tries to take advantage of me.

User avatar
Jonas
Conscript
Conscript
Posts: 219
Joined: 14 Jan 2009

Unread postby Jonas » 18 Feb 2009, 23:03

When it is nessesary to use sleep, like in the script above, it's normally enough with sleep(1) and if it doesn't work, just increase with 1 until it do work. :-D

I use the sleep-command more often in game-playing related issues. For example when you have a script-controlled camera movement: the camera is supposed to move to a specific point on the map and when the camera position is set, and not until then :P, the following command is executed

In the later case the sleep-command is more of a estetical tool, to make effects and other in-game related stuff look good.
:leo: A man who carries a cat by the tail learns something he can learn in no other way.
Mark Twain


Return to “Mapmaking Guild”

Who is online

Users browsing this forum: No registered users and 0 guests