Connection ErrorBad RequestSession ExpiredSign in requiredForbiddenNot FoundToo Many RequestsServer ErrorBad GatewayService UnavailableGateway TimeoutHTTP Version Not Supported
Session Expired
Your session has expired. Please log in to continue.
Sign in required
You need an account to do that. Sign in or create one — it only takes a minute.
Request Failed
We encountered an issue while processing your request.
Please check your internet connection and try again.
In other words, you want to replace all creatures from 1 to k with a certain condition and luck, but you want this to happen a) Inconsistently b) Without repetition c) With all k elements
Then you need an interesting algorithm:
local used_indexes = {} for i=1, k do repeat N=random(k)+1 until not used_indexes[N] used_indexes[N] = 1; --Actions with the creature with number N (not k!!) end
It seems like you have some kind of error here - i is not passed anywhere. Or should it be n instead of i? I tried it in the game with your version, and the creatures spawned in the first two locations. Luckily, they have fixed spawn points, otherwise the game would crash due to lag 😆
I made a few adjustments and ran it again - now the monsters spawn in different locations, but still in the same order, i.e., I run the function a second time, and it spawns the monsters in the same locations.
Yes, and here's another question. I have this condition in the function:
local type = random( 3 ) + 1 if ( WR_luck < 3 ) and ( type == 4 ) then type = random( 2 ) + 1 end
Before I put these two conditions in parentheses, the game ignored them. Why? When should parentheses be used in conditions?
How do you define a hero then? I'm not very good with variables.
local hero = "Duncan" - here's how you define a hero. But it's better to define it at the beginning of the script and without "local" so that you can use the hero in any function of the script later.
}{0TT@6bI4
3 years ago
Auto-translated
`hero` is a very common name; it's better to make it a local variable. And you can assign it to a global variable at the beginning of the script, like this: `MAIN_HERO = "Duncan"`, as the developers did.
It seems like there’s some kind of error here – i isn’t being passed anywhere. Or should i be n instead? I tried it in the game with your version, and creatures spawned in the first two locations. Good thing they have a fixed spawn, otherwise the game would crash from lag 😆
I made a few minor adjustments, ran it again – now the monsters spawn in different locations, but still in a list, i.e., I run the function a second time, and it spawns the monsters in the same locations.
I’ve solved the problem. I wrote this:
--All sorts of things before these lines local n = random(length(creatures_positions))+1 local x = creatures_positions[n].x local y = creatures_positions[n].y
--All sorts of things after these lines, k replaced with n
And now the random function works, and creatures spawn in random saved coordinates 😇 Still, a huge thank you for correcting the function for saving coordinates and helping with the respawn function!
local hero = "Duncan" - this is how you define a hero. But it's better to define it at the beginning of the script and without "local" so that you can use "hero" in any function of the script later.
But, if "hero" in the script should be ANY hero of the player?
}{0TT@6bI4
3 years ago
Auto-translated
If your function is called by a region trigger, then specify `hero` as the accepted parameter, and you can then use `hero` everywhere.
--All sorts of things before these lines local n = random(length(creatures_positions))+1 local x = creatures_positions[n].x local y = creatures_positions[n].y
--All sorts of things after these lines, k has been replaced with n
Now the random function works, and the creatures spawn at random saved coordinates 😇 Still, a huge thank you for correcting the function that saves the coordinates and for helping with the respawn function!
I still don't understand your task, but never mind. My code iterates through all k creatures (while i is not needed) and generates a random index k until it exists in the array of indices. As soon as it doesn't, it works with the creature with the generated index k.
The reason for this check with a loop is that a simple random function (like yours) can produce duplicate values, and as I understand it, that shouldn't happen. Perhaps I misunderstood.
And in general, it's very strange that it doesn't work for you and generates in two places. I ran some test prints for k=100, and it generated a bunch of values, all different (well, I didn't scroll through all of them).
I still don't understand anything about your task, but okay. My code iterates through all k creatures (including i) and generates a random index k until it exists in the array of indices. As soon as it doesn't, it works with the creature with the generated index k.
The reason for the check with a loop is because a simple random number generator (like yours) can produce duplicate values, which, as I understand it, shouldn't happen. I might be wrong.
In general, it's very strange that it doesn't work for you and generates in two places. I ran some test prints for k=100, and it generated a lot of different values (well, I didn't scroll through all of them).
Honestly, I understand even less now. If I understood, I wouldn't ask for help 😅. Anyway, here is the final version of this script for spawning, I just finished it and moved on to something else (I'm not touching the coordinate saving anymore):
function RespawnUnitsByLuck() if ( GetDate(WEEK) == 2 ) and ( GetDate(DAY_OF_WEEK) == random(6) + 1 ) then local WR_luck = GetHeroStat(WR, STAT_LUCK) local respawns_types = { CREATURE_AIR_ELEMENTAL, CREATURE_PHOENIX, CREATURE_AIR_ELEMENTAL, CREATURE_PHOENIX } local respawns_quantities = { 100 * diff, 10 * diff, 100 * diff, 4 * diff } local respawns_mood = {3, 1, 3, 0} local respawns_courage = {1, 2, 1, 0} local respawns_num = 0 local previous_pos = {} local respawns_id = 0
--Reminder about difficulties to calculate multipliers from difficulties: diff = 0.5(easy), 2(normal), 4(veteran), 6(heroic), 10(hardcore) local CanRespawnUnitsByLuck = random(100) + ((10*(WR_luck+1)) * mod((WR_luck+1),diff)) if CanRespawnUnitsByLuck >= mod(70,(WR_luck+2)) + (60+diff) then print("The random number is "..CanRespawnUnitsByLuck, ", which is greater than or equal to the threshold. Spawning units...") elseif CanRespawnUnitsByLuck < mod(70,(WR_luck+2)) + (60+diff) then --( 50 + (10+diff) ) then print("The random number is "..CanRespawnUnitsByLuck, ", which is below the threshold. Not spawning anything, exiting the function...") return end
for i = 1, 20 + diff do local n = random(length(creatures_positions))+1 local x = creatures_positions[n].x local y = creatures_positions[n].y local floor = 0; local badpos = 0;
if IsObjectExists("m"..n) or IsObjectExists("respawns"..n) then badpos = 1 end
if ( badpos == 0 ) and ( IsTilePassable( x, y, floor ) ) then respawns_num = respawns_num + 1 if respawns_num == 20 + diff then print("Maximum number of units spawned. Exiting the spawner.") return --if more than 20+difficulty units have been spawned, then exit, otherwise there will be a huge overspawn end
local type = random( 3 ) + 1 if ( WR_luck < 3 ) and ( type == 4 ) then type = random( 2 ) + 1 end if ( WR_luck >= 5 ) then respawns_quantities = { 200 * diff, 4 * diff, 200 * diff, 4 * diff } respawns_courage = {1, 0, 1, 0} type = random( 2 ) + 2 end local creaturetype = respawns_types[ type ] local quantity = respawns_quantities[ type ] local mood = respawns_mood[ type ] local courage = respawns_courage[ type ] local respawnsname = 'respawns' .. n; CreateMonster( respawnsname, creaturetype, quantity, x, y, floor, mood, courage, random( 360 ) ); end; end; if respawns_num == 0 then print("No creatures were spawned. Probably, all spawn points are occupied.") else print("Spawning completed. Creatures spawned: "..respawns_num) end; end; end;
BlueHeavenHero
3 years ago
Auto-translated
Good day! I need help with a script. I created a special ability for a hero, so that if, during a battle, less than 30% of creatures remain in his army, Death Wraiths are summoned in the amount of HeroLevel * 0.05. But I doubt that this will work...
function Start() if GetHeroName(GetAttackerHero())=="HafadNecro" then side=ATTACKER aside=DEFENDER start_creatures=CountCreatures(side) elseif GetHeroName(GetDefenderHero())=="HafadNecro" then side=DEFENDER aside=ATTACKER start_creatures=CountCreatures(side) end end function CountCreatures(_side) local fc_count=0 for key, element in GetCreatures(_side) do fc_count=fc_count+GetCreatureNumber(element) end return fc_count end function UnitDeath(unit) sleep(4) if intg(start_creatures*0.30)<=CountCreatures(side) then for key, name in GetCreatures(aside) do SummonCreature(side, CREATURE_WRAITH, 0.05*GetHeroLevel("HafadNecro"), 12, 2) end; end; end;
}{0TT@6bI4
3 years ago
Auto-translated
I wonder how it will summon 0.05 * 8, i.e., 0.4 Banshees. You either need to add ceil or floor, otherwise it will spawn zero units. Overall, it should work.
AstralLein
3 years ago
Auto-translated
Yes, the number should definitely be higher. At least 0.3 times the hero's level. That is, at level 40, it will be approximately 12 banshees, which is quite small; it probably needs to be even higher.
SummonCreature summons creatures correctly in a free, random location, without coordinates.
Yes, the number should definitely be higher. At least 0.3 * hero level. So, at level 40, there will be approximately 12 banshees, which is quite small; it probably needs to be even more.
SummonCreature summons to a free random point without coordinates.
I will change it to a larger number.
Added 3 minutes later A problem has arisen! In the original Heroes Campaigns, in the fifth mission, after Godric frees Isabelle, Agrail attacks the Castle. I decided to implement the same function in my scenario, but the dialogue scene plays BEFORE Vittorio attacks the Castle!
function ChristianAttack() DeployReserveHero("Christian", 98, 108, 0) sleep(10) MoveHero("Christian", 126, 139, -1) if IsHeroAlive("Hafad") then if IsHeroAlive("Christian") then if GetObjectOwner("castle") == PLAYER_2 then SetObjectiveState("prim5", OBJECTIVE_FAILED, 1) sleep(10) loose() else StartDialogScene("/DialogScenes/FallenKnight/S3/DialogScene.xdb#xpointer(/DialogScene)") sleep(1) SetObjectiveState("prim5", OBJECTIVE_COMPLETED, 1) SetObjectiveState("prim6", OBJECTIVE_ACTIVE, 1) end; end; end; end;
I've encountered a problem! In the original Heroes Campaign, in the fifth mission, after Godric frees Isabelle, Agrail attacks the Castle. I decided to implement the same feature in my scenario, but the dialogue scene plays BEFORE Vittorio attacks the Castle!
This is because, according to your conditions (else), if the object (town?) "castle" does not belong to player 2, the video is triggered.
If you need it to trigger after the town is captured, you need to add a script for town capture with activation of the function through OBJECT_CAPTURE_TRIGGER, where we check who captured it and who the new owner is, and then trigger the video if the town was captured by the player who owns the hero you need. Something like this:
function TownCaptured( oldowner, newowner ) if IsHeroAlive("Hafad") then if IsHeroAlive("Christian") then if ( newowner == GetObjectOwner("Christian") ) then StartDialogScene("/DialogScenes/FallenKnight/S3/DialogScene.xdb#xpointer(/DialogScene)") sleep(1) SetObjectiveState("prim5", OBJECTIVE_COMPLETED, 1) SetObjectiveState("prim6", OBJECTIVE_ACTIVE, 1) elseif newowner == PLAYER_2 then SetObjectiveState("prim5", OBJECTIVE_FAILED, 1) sleep(10) loose() end end end end
Because, according to the condition (else), if the object (city?) "castle" does not belong to player 2, then the video is played.
If you need it to play after capturing the city, you need to add a script for capturing the city with the activation of a function through OBJECT_CAPTURE_TRIGGER, where we check that the city has been captured and who the new owner is, and then we will play the video if the city was taken by the player who owns the hero you need. Something like this:
function TownCaptured( oldowner, newowner ) if IsHeroAlive("Hafad") then if IsHeroAlive("Christian") then if ( newowner == GetObjectOwner("Christian") ) then StartDialogScene("/DialogScenes/FallenKnight/S3/DialogScene.xdb#xpointer(/DialogScene)") sleep(1) SetObjectiveState("prim5", OBJECTIVE_COMPLETED, 1) SetObjectiveState("prim6", OBJECTIVE_ACTIVE, 1) elseif newowner == PLAYER_2 then SetObjectiveState("prim5", OBJECTIVE_FAILED, 1) sleep(10) loose() end end end end
Thus, after MoveHero from the function with the hero's respawn, the conditions and actions can be removed)
You didn't quite understand me. After a human player captures the city, a quest to hold the city is activated. Vittorio is placed on the map and begins to move towards our city. If we defeat Vittorio, a video is played. If Vittorio captures the city, we lose. By the way, a similar problem arose with another function - a cutscene is played, then a battle begins, and AFTER the battle, a text message appears. But - the cutscene is played, and the text message appears BEFORE the battle. How can this be fixed?