Skip to content

Posts from Scripts

4.8 (8 ratings)
In reply to RedHeavenHero
User Avatar
13 years ago
Auto-translated
RedHeavenHero

array = {Chupa = 0, Lapa = 2, Nuba = 0, Roma = 2}
So, without quotes, it recognizes it as a string? Or is this only for the second case? Interesting...
In reply to Dyrman
User Avatar
13 years ago
Auto-translated
Dyrman
So, without any special characters, it recognizes it as a string? Or is this only applicable to the second case? Interesting...
Yes, it recognizes it.
User Avatar
13 years ago
Auto-translated
Is there any way to specify a dynamic function name in startThread (it doesn't like quotes)? For example:

for i,e in mass
startThread(oops_..i.._F)
end;
The above is just an example)

Added after 4 minutes
RedHeavenHero
Yes, it recognizes it.
Excellent. Let's try to push it. Thanks.

Added after 4 minutes
And is a composite index possible? Or an alias? Like, you access it by two different string names, but get the same value.
In reply to Dyrman
User Avatar
13 years ago
Auto-translated
Dyrman
Is it possible to specify a variable function name in startThread (it doesn't like quotes)? For example:

for i,e in mass
startThread(oops_..i.._F)
end;
The above is just an example)
You can create an array of functions:
array = {
[1] = function()
end, -- semicolons should be placed inside the array, following tradition :)
[2] = function() -- they are there for another purpose
end,
}
and access it like this: array[1](arg1, arg2)

or
function oops_1_F()end
function oops_2_F()end

for i=1,2 do
startThread(parse('oops_'..i..'_F()'))
end
Added 4 minutes later
[/U]
Excellent. I'll try it out. Thank you.
But they cannot be concatenated or replaced with variables. Only in the first case is this possible.
In reply to RedHeavenHero
User Avatar
13 years ago
Auto-translated
RedHeavenHero

function oops_1_F()end
function oops_2_F()end

for i=1,2 do
startThread(parse('oops_'..i..'_F()'))
end
I forgot about the magic `parse` function :o That's great!
In reply to Dyrman
User Avatar
13 years ago
Auto-translated
Dyrman
Is a composite index possible? Or an alias? Like, you access it using two different string names, but you get the same value.
You can create a multidimensional array or concatenate indices, but it all becomes complicated when the purpose is unknown.
In reply to RedHeavenHero
User Avatar
13 years ago
Auto-translated
RedHeavenHero
You can create a multidimensional array or concatenate indices, but it's all complicated when the goal is unknown.
The goal is also unknown to me :D, but it might be needed. It's better to find out everything right away.
In reply to Dyrman
User Avatar
13 years ago
Auto-translated
Well, in general, any element can be an array (and not only that); accessing it is simple:
array[index1][index2]
mass[index1][index2][index3]

but array[index1], mass[index1], and mass[index1][index2] must be arrays, otherwise, there will be an error.

Assignment is done step by step, if it's the first time:
array = {}
array[ind1] = {}
array[ind1][ind2] = ""

concatenating indices looks like concatenating strings:
hero1 = 'Brem' -- implicit variables obtained as a result of something
hero2 = 'Grok'

array[hero1..hero2] = element

but, if you don't access array[hero1..hero2], but array[hero2..hero1], it will return nil. Therefore, it's better to COMPARE strings before assigning.
if hero1 >= hero2 then
array[hero1..hero2] = element
else
array[hero2..hero1] = element
end
The same applies when accessing the array.
User Avatar
13 years ago
ARTIFACT_DRAGON_SCALE_ARMOR = 36
ARTIFACT_DRAGON_SCALE_SHIELD = 37
ARTIFACT_DRAGON_BONE_GRAVES = 38
ARTIFACT_DRAGON_WING_MANTLE = 39
ARTIFACT_DRAGON_TEETH_NECKLACE = 40
ARTIFACT_DRAGON_TALON_CROWN = 41
ARTIFACT_DRAGON_EYE_RING = 42
ARTIFACT_DRAGON_FLAME_TONGUE = 43
User Avatar
13 years ago
Auto-translated
How can I implement the following using scripts? 1) Restructuring cities at the start of the game. Purpose: Heroes of Might and Magic generates unattractive maps, and the standard map generator creates all cities at level 2 with a tavern built. Needed: - The first player's starting city should be level 4 (e.g., fort, tavern, and dwelling-1). - All subsequent players' starting cities should be level 4 plus, possibly, an additional building (dwelling-2) - up to level 5; the chance depends on the player number and is 100% for the last player. - All neutral cities should be level 6 (e.g., fort-citadel, dwelling-1, 2, 3). Problem: - How to iterate through the cities that exist on the map if their names are unknown in advance? - Will I have to iterate through all existing city names listed in the game's resources to check for their presence on the map? 2) Taking turns away from heroes upon encounter or after battle. Purpose: to prevent chaining, limit battles. Needed: - Take 50% of the hero's total remaining turns after a battle (like in Disciples 2); if the hero's remaining turns are less than that, take all remaining turns. Ideally, only take turns if the neutrals were not released without a fight. - When friendly heroes meet, equalize their remaining turns to the minimum (i.e., set the remaining turns of both heroes to the lowest remaining turn value among them). When a hero visits mine garrisons, reset their turn to zero (ideally, only reset the turn for garrisons, so the turn is not lost when capturing a mine) - to prevent mine chaining. Problems: - How to track the fact that a battle has taken place (something like a trigger)? - How to track the fact that heroes have met or visited a garrison?
User Avatar
13 years ago
Auto-translated
Will it be necessary to go through all the existing town names listed in the game's resources to check if they are present on the map?
No, it's simpler than that. I need to be at home to write it. Perhaps Dyrman or RedHaven will manage to do it before me, and if not, then I will do it.
Regarding the second point: there is a trigger for contact. Although attaching triggers to all heroes might not be ideal, I don't see another way.
User Avatar
13 years ago
Auto-translated
HELP:smile45:
I have a map and a script:
function obj()
while 1 do
local heroes = {};
local m = 0;
local h = 0;
local count = 0;
heroes = GetPlayerHeroes(PLAYER_1);
--for m, h in heroes do
h = "Muscip";
if HasArtefact(h, 36) then
count = count + 1;
end;
if HasArtefact(h, 37) then
count = count + 1;
end;
if HasArtefact(h, 38) then
count = count + 1;
end;
if HasArtefact(h, 39) then
count = count + 1;
end;
if HasArtefact(h, 40) then
count = count + 1;
end;
if HasArtefact(h, 41) then
count = count + 1;
end;
if HasArtefact(h, 42) then
count = count + 1;
end;
if HasArtefact(h, 43) then
count = count + 1;
end;
end;
local sl = GetPlayerHeroes(PLAYER_1);
local res
if count == 8 then
print("Player 1 has all artifacts");
SetObjectiveState("obj", OBJECTIVE_COMPLETED);
Win ();
break;
end;
sleep(5);
end;
end;

startThread (obj);
I made some adjustments to it:
function obj()
while 1 do
local heroes = {};
local o = 0;
local h = 0;
local count = 0;
heroes = GetPlayerHeroes(PLAYER_1);
--for o, h in heroes do
h = "Muscip";
if HasArtefact(h, 36) then
count = count + 1;
end;
if HasArtefact(h, 37) then
count = count + 1;
end;
if HasArtefact(h, 38) then
count = count + 1;
end;
if HasArtefact(h, 39) then
count = count + 1;
end;
if HasArtefact(h, 40) then
count = count + 1;
end;
if HasArtefact(h, 41) then
count = count + 1;
end;
if HasArtefact(h, 42) then
count = count + 1;
end;
if HasArtefact(h, 43) then
count = count + 1;
end;
end;
o = "obj"
local sl = GetPlayerHeroes(PLAYER_1);
if count == 1 then
print("Player 1 has 1/8 artifacts");
SetObjectiveProgress(o, 1);
end;
if count == 2 then
print("Player 1 has 2/8 artifacts");
SetObjectiveProgress(o, 2);
end;
if count == 3 then
print("Player 1 has 3/8 artifacts");
SetObjectiveProgress(o, 3);
end;
if count == 4 then
print("Player 1 has 4/8 artifacts");
SetObjectiveProgress(o, 4);
end;
if count == 5 then
print("Player 1 has 5/8 artifacts");
SetObjectiveProgress(o, 5);
end;
if count == 6 then
print("Player 1 has 6/8 artifacts");
SetObjectiveProgress(o, 6);
end;
if count == 7 then
print("Player 1 has 7/8 artifacts");
SetObjectiveProgress(o, 7);
end;
if count == 8 then
print("Player 1 has all artifacts");
SetObjectiveState(o, OBJECTIVE_COMPLETED);
Win ();
break;
end;
sleep(5);
end;
end;

startThread (obj);

And the script stopped working. The console displays something like this:
(Script) ERROR: no loop break
... ... (I don't remember:( something was written about line 72.)

What does this mean?
In reply to Warrior777
User Avatar
13 years ago
Auto-translated
This can be fit into 23 lines.:)
function obj()
local old = 0
while 1 do
local count = 0
for i=36,43 do
count = count + (HasArtefact("Muscip", i) or 0)
end
if count == 8 then
print("Player 1 has all artifacts")
SetObjectiveState("obj", OBJECTIVE_COMPLETED)
Win()
break
end
if count ~= old then
print("Player 1 has "..count.."/8 artifacts")
SetObjectiveProgress("obj", count)
old = count
end
sleep(5)
end
end

startThread (obj)


Added after 4 minutes
How do you iterate through the cities existing on the map if their names are not known in advance?
Will I have to iterate through all existing city names defined in the game resources to check for their presence on the map?
GetObjectNamesByType('TOWN') will return an array with the names of all cities on the map.
User Avatar
13 years ago
Auto-translated
Will this work in version 1.6?
In reply to Warrior777
User Avatar
13 years ago
Auto-translated
It should. There’s nothing complicated there that wouldn’t already exist in 1.6.

Added 5 minutes later
Problems:
- How to track the fact that a battle has taken place (something like a trigger)?
- How to track the fact that heroes have met or visited a garrison?
1. GetLastSavedCombatIndex() will return the number of battles fought on the current map.
2. Use a trigger (16), as Ment suggested. It is practically impossible to track a hero touching a garrison.

Statistics

Welcome our newest member: recijeb