Skip to content

Posts from Scripts for beginners.

4.5 (2 ratings)
In reply to Ment
User Avatar
10 years ago
Auto-translated
Ment
I didn't understand how it worked for you back then... Are you sure you were playing as the second player? ) If you were playing as the first player, nothing would happen to your quests, because the script specifies that the state changes only for the second player.

It was such an ugly workaround to make the player blue. That's why I started the game as the second player :) But I figured out the color issue - I checked your FAQ :)
Jack_of_shadows
It seems like the `proph_event` function is missing an `end` for the `if/else` statement.
We can try that. After Python, it's hard to get used to the idea that `end` statements are needed everywhere :)

Update: Thanks, Jack_of_shadows, there was indeed a missing `end` there. But now another problem arises: the quest doesn't want to complete.
path = GetMapDataPath()
function activate(obj)
SetObjectiveState(obj,OBJECTIVE_ACTIVE,PLAYER_1)
end

function complete(obj)
SetObjectiveState(obj,OBJECTIVE_COMPLETED,PLAYER_1)
MessageBox(path.."text1.txt")
end

function proph_event(hero)
if GetObjectiveState("Conquer") == OBJECTIVE_UNKNOWN then
activate("Conquer")
else
if (GetObjectiveState("Conquer") == OBJECTIVE_ACTIVE and HasArtefact(hero, ARTIFACT_ENDLESS_BAG_OF_GOLD)) then
complete("Conquer")
Trigger(OBJECT_TOUCH_TRIGGER, "Prophet", nil)
end
end
end

SetObjectEnabled("Prophet", nil)
Trigger(OBJECT_TOUCH_TRIGGER, "Prophet", "proph_event")

I tried commenting out the part that checks if the hero has the artifact, and it worked fine :)

It seems like there's a problem with
and HasArtefact(hero, ARTIFACT_ENDLESS_BAG_OF_GOLD))
Any ideas? :)
10 years ago
Auto-translated
Hey guys, I'm new to this. I wanted to know: How can I increase the number of creatures in a building?
In reply to Emris
User Avatar
10 years ago
Auto-translated
Emris
Hey guys, I'm new to this. I wanted to know something: How can I increase the number of creatures in a building?
If you're talking about dwellings on the map, unfortunately, you can only update the growth rate, meaning, if it has been purchased, you can add the usual number of creatures. For a town, there are the functions SetObjectDwellingCreatures and GetObjectDwellingCreatures, which are described in the manual.
10 years ago
Auto-translated
Dear masters "RedHeavenHero" and "Ment", I need your help! I have 2 tasks:
-1- I'm creating a map for a multiplayer game with 2 to 8 players, with teams possible. I need to implement the following condition: when a player, for example, Player 1, attacks an enemy player's Castle (Player 2) and wins the battle, that Castle should turn into a pile of ruins. Then, any player whose hero "touches/enters" this pile of ruins should receive a message: "Do you want to rebuild a Castle of your Faction for N resources?" and be offered a choice of "yes" or "no". If the answer is "yes", N resources are deducted from that player, and a Castle of that player's Faction, at the initial level, appears in place of the pile of ruins. If there are not enough resources, a message "not enough resources" should be displayed. Otherwise, it gets tedious to control Castles of alien Factions, and it's difficult to manage units and dangerous to give them to the enemy!
-2- (not entirely fair) In the very first version of Heroes 5, the "Humans" Faction could retrain units without any restrictions, as long as there was enough gold. In subsequent versions, they introduced a maximum limit of 14 units per week, which makes me very sad((((! I need to remove this limit for all players who play as the "Humans" Faction.
---- These should be 2 separate scripts, or implemented in some other way, so that I can apply them separately or together. I'm going to play on a licensed version over a home network or on one computer. It would be great if it were possible to play this modified map with a friend over the internet.
---- Since I value the time of competent/experienced people, I am willing to pay a reasonable amount for "technical support" for these tasks. As an option, you can provide a Qiwi wallet and the amount. In Heroes 4, where you could create scripts from ready-made blocks, I figured it out myself, but here it takes a long time to learn, and there are many questions. Since I have been interested in the game for a long time, there may be more questions/tasks in the future. It would be good to meet on Skype or Teamspeak for possible explanations.
In reply to Александр4444
User Avatar
9 years ago
Auto-translated
Hey everyone, good day.
I'm asking for help! I've been playing Heroes for over 7 years and I decided to try mapmaking. I specifically need help with scripts.
I understand that this thread already contains ready-made functions, but I would still like a little explanation of what each line does. Of course, you can spend an hour and, with the help of a list of functions, etc., you can "decipher" the code...
That's the idea. I can write something simple myself, but I just need some advice and a little guidance. So, here's the question: when the map loads, the hero should be given a main quest, such as reaching a certain point. How can I implement this correctly? I mean, so that he reaches a specific region on the map, and then the quest is completed.
I would be grateful for any help, and it would be even better if I could chat with an experienced scripter.
User Avatar
9 years ago
Auto-translated
The easiest way is to create a region of size 1x1 and write a trigger that activates when entering this region:

Trigger(REGION_ENTER_AND_STOP_TRIGGER,"region name","FName")

Where FName is the name of the function. And before that, what the function should actually do:

function FName(heroname)
if GetObjectOwner(heroname)==1 then
SetObjectiveState("quest name", OBJECTIVE_COMPLETED)
Trigger(REGION_ENTER_AND_STOP_TRIGGER,"region name",nil)
end;
end;

Inside the function, we first check the condition that heroname belongs to the first player (if the human player is the first, of course). Secondly, if the condition is met, we mark the quest as completed and cancel the trigger action so that it is no longer triggered.
In reply to Ment
User Avatar
9 years ago
Auto-translated
Thank you very much! It helped, and everything works.
And now, I'll ask you not to laugh out loud. You can swear at me or use other offensive language. I'm even ashamed to write about such a trivial thing...
Here's the simplest script, which each of you could write with your eyes closed, even if woken up in the middle of the night.
The hero enters a region, and a message appears with a single "Yes" button. Just a MessageBox, nothing complicated. But I've been working on it for two hours, and I'm racking my brains - what does this scripter want from me?
function quest1message ()
MessageBox ("/Maps/SingleMission/Scenario 1/quest1.txt");
end;

Trigger(REGION_ENTER_AND_STOP_TRIGGER, "quest1rg", "quest1message" );
It seems... everything is elementary... but here's the thing. One program says that everything is fine. The standard script editor complains about the function itself. And in the game, the hero stops every time he enters the region, but the message doesn't appear. I've checked all the manuals... and the function lists... and I'm still stuck.
Here are a couple of screenshots:


User Avatar
9 years ago
Auto-translated
At a minimum, the text path does not match – the “s” is missing in SingleMissions.
User Avatar
9 years ago
Auto-translated
It's better to use `
GetMapDataPath()..'quest1.txt'
And even better to use something shorter (less to write, and less room for errors):
function MsgBox(text, cb)
MessageBox(GetMapDataPath()..text..'.txt', cb);
end

MsgBox('quest1');
It's also worth figuring out more precisely whether the callback function is being called or whether it's being called but the message isn't being displayed. The console and debug messages print('bla-bla') are the primary tools for this.
User Avatar
9 years ago
Auto-translated
At the very least, the text path doesn't match – the 's' is missing in SingleMissions/.
I laughed until I was blue in the face at such a silly mistake. Thank you.
And even better would be something shorter (less to write, and less room for errors):
Could you elaborate a bit, please? Break it down into sections and explain each part, if it's not too much trouble.
Regarding the print... It's a good idea, and most importantly, it's important and useful. I'll take it into account.
User Avatar
9 years ago
Auto-translated
Could you please elaborate a bit more? Break it down into smaller parts, if possible.
This is a common approach for any programming language: if you use a complex construct multiple times (and MessageBox will definitely appear more than once on the map), you can move all the repetitive routines into a separate function and only write what changes from time to time. For example, in your case:
MessageBox("/Maps/SingleMission/Scenario 1/quest1.txt");
Each time, you will repeat:
MessageBox - a relatively short function name, but you can come up with an even shorter one.
"/Maps/SingleMission/Scenario 1/" - the path will probably be the same for all text files.
".txt" - the file extension also does not change.
As a result, everything that will be repeated is described once in a new function, with a convenient and preferably short name. Only the changing part - the file name - is passed to the function. The ".." operator concatenates the lines into one. The second parameter of the function, cb, is similar to the second parameter of the original MessageBox (I won't explain its meaning, there is documentation for that). The second parameter is optional and can be omitted.
-- a wrapper function around MessageBox. Place it somewhere at the beginning of the file:
function MsgBox(text, cb)
MessageBox(GetMapDataPath()..text..'.txt', cb);
end

-- an example of calling the message, instead of MessageBox("/Maps/SingleMission/Scenario 1/quest1.txt"); you can simply write:
MsgBox('quest1');
If you carefully examine your code, I'm sure you will find many similar places where you can optimize cumbersome constructs.

P.S. Of course, if you are planning to write 100 lines of code for the map and that's it, then you can ignore these tips.
User Avatar
9 years ago
Auto-translated
Here. Now it's clear what we're talking about. Yes... it's much simpler this way... we just specify a new text file name each time, and the function inserts it into our template, described in just one word: MsgBox, and then it executes.
The second parameter of the cb function is similar to the second parameter of the original MessageBox (I won't explain its meaning; there's documentation for that). The second parameter is optional; you can omit it.
The second parameter is responsible for calling a new function after clicking "OK" on the message. And yes, the Manuals say that you don't have to write it.
Okay, then, the next question. "Cascading task." Let's say we need to capture 3 different mines: a sawmill, an ore mine, and a sulfur mine. What's the best way to structure this? Should we set up 3 checks and change the task status after each one, or what? Or should we use a trigger that checks, for example, every day, whether we have that mine?
User Avatar
9 years ago
Auto-translated
If, besides the player, no one else can physically capture the mines, then you can change the status using a trigger that activates when the mine is touched. If computer-controlled heroes are running around, then you can check once a day or in a separate thread (using the startThread function).
update: actually, regardless of whether it's a computer-controlled hero, you can check using any of the three methods, as long as it correctly verifies who captured the mine.
User Avatar
9 years ago
Auto-translated
If computer-controlled heroes are running around, then check once a day or in a separate thread (using the startThread function).
Hmm... Yes, a separate thread would probably be more convenient. And let it check every day: whether the objective has been completed or not. Thank you.
Now, another funny problem has arisen.
It's a simple task:
- Enter a region, receive a quest to find an artifact, and complete the previous quest.
- Pick up the artifact, and the quest is completed.
I created an inactive quest, which is not initially displayed, to find artifacts. Then I simply activate it.
Trigger(REGION_ENTER_AND_STOP_TRIGGER, "quest1end", "quest1end_quest2start");
function quest1end_quest2start()
SetObjectiveState("quest1info", OBJECTIVE_COMPLETED, PLAYER_1);
MsgBox('quest1end');
sleep('5');
MsgBox('quest2start');
SetObjectiveState("artifact1", OBJECTIVE_ACTIVE, PLAYER_1);
Trigger(REGION_ENTER_AND_STOP_TRIGGER, "quest1end", nil);
end;
It seems like everything is fine, but after we pick up the artifact, the mission is immediately won. What's the problem? Is it the lack of other quests, or did I mess something up in the map properties?
User Avatar
9 years ago
Auto-translated
Since the primary objective is the only one, it’s possible that if it’s the only objective, the victory is automatically awarded upon completion. Usually, for this purpose, a main objective is created that remains active from the beginning to the end of the game (for example, not losing the main hero).
You can also experiment with the Ignore flag:
Ignore – when set to “true,” it is not taken into account when checking for victory or defeat.

Statistics

Welcome our newest member: recijeb