Skip to content

Posts from Scripts

4.8 (8 ratings)
#4023
Auto-translated
When I click on "check" in the editor, it says "Function FightUnitExp not defined, line 1." But since it works in the vanilla version, I'll just ignore it.
In reply to CetusSantis
User Avatar
#4024
Auto-translated
Copy and paste this directly into the main map script (not the unit script, not the combat script):

function FightUnitExp(hero, unit)
 while IsObjectExists(hero) == not nil and IsObjectExists(unit) == not nil do
  sleep(5)
 end
 if IsObjectExists(unit) == nil then
  ChangeHeroStat(hero, 0, 999999999)
 end
end
Trigger(OBJECT_TOUCH_TRIGGER, "UnitExp", "FightUnitExp")

and check it in the game.
Мои карты: Белый Храм, Поменяться местами, Судьба королевства, Стихийные острова.
In reply to Долгий
#4025
Auto-translated
It all worked out! And it also works with the mod! Thank you very much!

Added 22 hours and 28 minutes ago
One more thing, if I want to place several of these units on the map, do they all need their own names and their own function? I tried simply placing another unit with the same name, but the script only triggers when the first one is killed.
In reply to CetusSantis
User Avatar
#4026
Auto-translated
CetusSantis
It worked! And it also works with the mod! Thank you very much!

Added 22 hours 28 minutes ago
One more thing, if I want to place several of these units on the map, do they all need their own names and their own function? I tried simply placing another unit with the same name, but the script only works when the first one is killed.

The 'Name' parameter must be unique for each object.

If the functionality after victory is always the same (give the hero 999999999 experience), then it is enough to number the names of all the units (UnitExp1, UnitExp2, UnitExp3, etc.) and place the line with the trigger Trigger(OBJECT_TOUCH_TRIGGER, "UnitExp", "FightUnitExp") in a for loop.

for i = 1,5 do --5 for 5 objects
 Trigger(OBJECT_TOUCH_TRIGGER, "UnitExp"..i , "FightUnitExp")
end

Now, each object with the name UnitExp from 1 to 5 will have a trigger that, when touched, will launch the FightUnitExp function
Мои карты: Белый Храм, Поменяться местами, Судьба королевства, Стихийные острова.
User Avatar
#4028
Auto-translated

Hello everyone. I have a question about this script (in the screenshot). I don't know what else to do to make it work; the trigger doesn't activate it.

Attachment 73917

Also, is it possible to create a script that would automatically skip Player 2's turn on the first day? I couldn't find anything similar in the manuals, so I tried changing Player 2's MP value.

Please advise.

Attachments 1
1 file attached • Total size: 12.4 KB
In reply to Dogenator
User Avatar
#4029
Auto-translated
Dogenator

Hello everyone. I have a question about the script (in the screenshot). I don't know what else to do to make it work; the trigger doesn't activate it.

Attachment 73917

And is it possible to create a script that would automatically skip Player 2's turn on the first day? I couldn't find anything similar in the manuals, so I tried changing Player 2's MP value.

Please advise.

Okay, so what error does it display? Or are there no errors? Add debug printing to the new day function and see what GetTownRace(...) outputs. Also, please attach the code as text within a code block instead of a screenshot:
function MyFunc(var)
-- Some Lua code
print("Hello, ", var);
end

You can enable cheats from the script and skip the turn:

consoleCmd("enable_cheats")
consoleCmd("eot")

A simpler way is to take away movement points from the hero:

ChangeHeroStat("Hero", HERO_STAT_MOVE_POINTS, -GetHeroStat("hero", HERO_STAT_MOVE_POINTS)
С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
In reply to }{0TT@6bI4
User Avatar
#4030
Auto-translated

I haven't quite figured out all the forum's features and how to insert code snippets here... Please excuse me.

There are no syntax errors, but it still doesn't work.

I did as you suggested, adding debug printing, but nothing appears in the console.

Regarding the method using cheats and skipping a turn, cheats don't seem to work in multiplayer games (and the map is specifically for multiplayer), so this option isn't suitable.
I've added debug printing to the first day function:

function first_day ()
if GetDate (0) == 1 then -----Check the day of the week (Monday)
startThread (day_1);
print("hello,");
elseif GetDate (0) == 3 then -----Check the day of the week (Wednesday)
startThread (day_3rd);
end;
end;

The entire script:

function first_day ()
if GetDate (0) == 1 then -----Check the day of the week (Monday)
startThread (day_1);
print("hello,");
elseif GetDate (0) == 3 then -----Check the day of the week (Wednesday)
startThread (day_3rd);
end;
end;

function day_1 ()
ChangeHeroStat ('Brem', 7, -999999999); -----Reduces movement points for player 2
end;

function day_3rd ()
if GetTownRace ('player_1') == 1 then -----Check the Faction of player 1's town
sleep(5);
startThread (zaclyatye_1);
end;
if GetTownRace ('player_2') == 1 then -----Check the Faction of player 2's town
sleep(5);
startThread (zaclyatye_2);
end;
end;

function zaclyatye_1 ()
if GetTownRace ('player_2') == 0 then SetObjectPosition('zaclyatye_humy_1', 125, 15);
elseif GetTownRace ('player_2') == 1 then SetObjectPos('zaclyatye_elfy_1_1', 125, 15);
elseif GetTownRace ('player_2') == 2 then SetObjectPos('zaclyatye_magi_1', 125, 15);
elseif GetTownRace ('player_2') == 3 then SetObjectPos('zaclyatye_liga_1', 125, 15);
elseif GetTownRace ('player_2') == 4 then SetObjectPos('zaclyatye_nekry_1', 125, 15);
elseif GetTownRace ('player_2') == 5 then SetObjectPos('zaclyatye_demony_1', 125, 15);
elseif GetTownRace ('player_2') == 6 then SetObjectPos('zaclyatye_gnomy_1', 125, 15);
elseif GetTownRace ('player_2') == 7 then SetObjectPos('zaclyatye_orki_1', 125, 15);
end;
end;

function zaclyatye_2 ()
if GetTownRace ('player_1') == 0 then SetObjectPosition('zaclyatye_humy_1', 8, 122);
elseif GetTownRace ('player_1') == 1 then SetObjectPos('zaclyatye_elfy_1_2', 8, 122);
elseif GetTownRace ('player_1') == 2 then SetObjectPos('zaclyatye_magi_1', 8, 122);
elseif GetTownRace ('player_1') == 3 then SetObjectPos('zaclyatye_liga_1', 8, 122);
elseif GetTownRace ('player_1') == 4 then SetObjectPos('zaclyatye_nekry_1', 8, 122);
elseif GetTownRace ('player_1') == 5 then SetObjectPos('zaclyatye_demony_1', 8, 122);
elseif GetTownRace ('player_1') == 6 then SetObjectPos('zaclyatye_gnomy_1', 8, 122);
elseif GetTownRace ('player_1') == 7 then SetObjectPos('zaclyatye_orki_1', 8, 122);
end;
end;

Trigger(NEW_DAY_TRIGGER, 'first_day' );

And another question arose: I have two scripts that depend on Trigger(NEW_DAY_TRIGGER), but I read that using two functions for the same trigger cancels out the second function. That is, I have...

function Spawn_army()
....
....
....
Trigger(NEW_DAY_TRIGGER, 'Spawn_army' );

How can I run 2 scripts so that they both start on the same day? For example, on Wednesday - spawn an army in caravans and move a stack of creatures to the player's coordinates (for the Elf to place the summoned creatures).

User Avatar
#4031
Auto-translated
Dogenator, I answered both questions in my FAQ. 1. The script starts executing at the beginning of the first day, so the NEW\_DAY\_TRIGGER will not work for the first turn; it is not yet set at that moment. You can simply add a manual call to the first\_day() function at the end of the entire script. 2. When checking the day of the week, you can call not one function, but several: ```lua function first_day () if GetDate (0) == 3 then -----Checking the day of the week (Wednesday) function_1(); function_2(); end; end; ``` 3. And as a bonus: calling all functions in a new thread using startThread(day\_1) will work in this case, but if you are not sure why you are doing this, and you just saw it somewhere, then this is potentially a source of bugs, for example, if there is code like this: ```lua startThread(function_1) -- some code startThread(function_2) -- another code that assumes the code from function_1 has already been executed ``` then it will not work (or even worse, it will not always work), since these two functions are actually launched in parallel, and it is impossible to say for sure which of them will be executed first. You can simply do this: ```lua function_1(); function_2();
РПГ-сценарий для HoMM5: Путь героя
ЧаВо по созданию карт для HoMM5: ЧаВо
In reply to Jack_of_shadows
User Avatar
#4032
Auto-translated
Jack, thank you for your response. I read your document, and it contains a lot of useful information. Regarding point 2, I don't quite understand what you mean by "function_1" and "function_2"... Are you referring to the names of the functions themselves? Or are these functions similar to `first_day`, but for checking other days? Regarding point 3, I took part of the code from another map where everything works as it is, and that's how I initially tried to copy it into my map. But it doesn't work for me. And regarding the last point, I don't quite understand what you mean. I've already tried calling the function through a trigger when touching an object, but that didn't work either. I don't know what else to do; in theory, it seems clear, but in practice, I feel like "a monkey with a grenade."
In reply to Dogenator
User Avatar
#4033
Auto-translated
Dogenator
Regarding point 2, I didn't quite understand what you mean by "function_1" and "function_2"... Are these the names of the functions themselves? Or are they functions similar to function first_day, but for checking other days?
These are just function names, for example. Let's say you want to create two events for one trigger:
function first_day ()
...
end;
Trigger(NEW_DAY_TRIGGER, 'first_day' );

function Spawn_army()
....
end;
Trigger(NEW_DAY_TRIGGER, 'Spawn_army' );

The second trigger will overwrite the first, and it won't work. An equivalent of this structure:

function NewDayTrigger()
first_day();
Spawn_army();
end
Trigger(NEW_DAY_TRIGGER, 'NewDayTrigger' );

That is, to execute a function, you don't necessarily need Triggers, startThread's, etc.; you just write the function name and parentheses. Anywhere, in any quantity. Your functions are no different from built-in functions, like print().

If something doesn't work, you need to debug it step by step. Probably, everyone has encountered a situation where they added a lot of code, made a syntax error in it, for example, wrote pint() instead of print(), and it's almost unnoticeable. The game engine simply executes the map script line by line - it reaches an incorrect function name, doesn't understand what it is, and crashes. That's it, the script is no longer executed. You don't understand what's wrong, and you start trying to write some other code, but it doesn't work either. You can rack your brains thinking about what you're doing wrong, but in reality, the script execution didn't even reach your new code; it crashed earlier. Therefore, it is very important to put print statements everywhere to understand which section of the code was executed and which was not. I guarantee that if you copy a specific piece of code from the FAQ and paste it into the map (and don't make mistakes in the names of objects and files), it will definitely work.

РПГ-сценарий для HoMM5: Путь героя
ЧаВо по созданию карт для HoMM5: ЧаВо
In reply to Jack_of_shadows
User Avatar
#4034
Auto-translated
I did as you said, and here is the result:
After performing a debug print, it turned out that part of this code simply doesn't work on its own, even though there are no errors.


The screenshot shows that function day_3rd cuts off from the moment:
if GetTownRace ('player_1') == 1 then
sleep(5);
zaclyatye_1 ()
end;
if GetTownRace ('player_2') == 1 then
sleep(5);
zaclyatye_2 ()
end;
end;

That is, for some reason, this part does not work in my code. What could be the cause? And what is the sleep function used for in this script?

And yes, I did as you said, specifically:

function new_day_trigger()
Spawn_army()
day_3rd()
end

Trigger(NEW_DAY_TRIGGER, 'new_day_trigger' );

This worked for me; now I just need to solve the problem with function day_3rd. Do you have any ideas?

Attachments 1
1 file attached • Total size: 256.4 KB
User Avatar
#4035
Auto-translated
Dogenator, it's clearly necessary to check the correctness of the GetTownRace function: 1. Are the town names definitely 'player_1' and 'player_2'? 2. Does the race you need actually have the ID 1? And what exactly does this function return? According to the documentation, it returns RaceID, where 1 is RACE_RANDOM_TYPE, but I haven't used it myself, so I'm not entirely sure. In general, using numbers instead of clear identifiers is a path to debugging hell. You can write print(GetTownRace('player_1')) in the console and see what it actually returns. The sleep() function is used unnecessarily in this script. The two main cases for its use are: 1. Almost all functions that work with map objects (monsters, buildings, heroes, etc.) are executed, let's say, not instantaneously. For example, you want to attach a touch handler to an enemy hero. To do this, you must disable the standard handler and only then attach your own; these are the rules of the game. But if you write: ```lua SetObjectEnabled(hero, nil); -- disabling the standard hero touch trigger Trigger(HERO_TOUCH_TRIGGER, hero, func); -- setting your own touch trigger ``` It won't work because SetObjectEnabled(hero, nil); is not executed instantaneously and won't complete before the trigger (this is a simplified explanation; the reasons are slightly different). In such cases, you should always use sleep(): ```lua SetObjectEnabled(hero, nil); -- disabling the standard hero touch trigger sleep(1); -- minimal delay, usually 1 is enough Trigger(HERO_TOUCH_TRIGGER, hero, func); -- setting your own touch trigger ``` 2. And, of course, when various animations, effects, and pop-up messages are created on the map, sleep() is used to set delays for them.
РПГ-сценарий для HoMM5: Путь героя
ЧаВо по созданию карт для HoMM5: ЧаВо
In reply to Jack_of_shadows
User Avatar
#4036
Auto-translated
Indeed, I rechecked the city names in the map editor and found that they are not named 'player_1', but 'castle1'. That's why it wasn't working. Although I initially thought that this function depended on the player's affiliation with the castle (PlayerID).
In the end, I entered the names into the castles, and, lo and behold, the creatures appear the next day, and the script works as intended.

Thank you very much for your help and useful information; you really helped me out😅.
User Avatar
#4037
Auto-translated
Just in case, 'player_1' is a string, PLAYER_1 is a numerical variable, and there is case sensitivity, meaning PLAYER_1 is not the same as player_1, and neither of them is the same as 'player_1'.
РПГ-сценарий для HoMM5: Путь героя
ЧаВо по созданию карт для HoMM5: ЧаВо
User Avatar
#4040
Auto-translated

Hello everyone!

I'm having this issue:

I installed a script to change the day-night cycle, and it works, but...

When switching from daytime lighting to nighttime, the hero menu becomes unavailable, and only for player #1.

What could be the problem?

Here's the code:

curr_light = 'day'

function DayNight()
if curr_light == 'day' then
SetAmbientLight(GROUND, 'NIGHT', 1, 5.0)
curr_light = 'night'
else
SetAmbientLight(GROUND, 'DAY', 1, 5.0)
curr_light = 'day'
end
end

Statistics

Welcome our newest member: Emil

Users Online 1 users 1065 guests