path = '/'..GetMapDataPath()
main_hero = 'Raelag'
print("The main character is named");
SetHeroCombatScript('Raelag', path.."CombatScript.xdb#xpointer(/Script)");
print("combat script started");
and in addition, there are typos in the names of functions in the combat script, and the targets for casts are not specified in the UnitCastAimedSpell function. Here is your map with fixed paths, but in order for Raelag to cast spells correctly, you need to define who these spells should be cast on.
Posts from Scripts
My combat script.xdb doesn't lead to combat script.lua, but to map script.lua. I wonder how that happened. I'll go fix it.
Gerter – thank you separately.
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
Hottabych, but now I have a different error).
I rewrote the scripts on the untouched version of the map, which previously had no scripts.
And now, during a battle, I get the following message:
Value was NIL when getting global with name 'GetUntiManaPoints'
attempt to call a nil value
What else doesn't it like, when there is main_hero = 'Raelag'?
Added 12 minutes later
Yes, mana is now being added correctly, thank you very much. "Attempt to call a nil value" - does the console display this message when there is no target for the spell? And how do I add this target? The idea was to replicate Elva's spell from the "Uninvited Guests" map, but not with lightning, but with cold, and I don't need as many heroes as there are in that map yet.
function Start()
if GetHeroName(GetAttackerHero()) == 'Raelag' then
print("if the main character is the attacker");
local mana = GetUnitManaPoints(GetAttackerHero()) --Otherwise, we'll leave the player with 200 mana for no reason!
SetUnitManaPoints(GetAttackerHero(), 200);
repeat sleep(1) until GetUnitManaPoints(GetAttackerHero())==200 --Sleep until the mana is added
for i, creature in GetDefenderCreatures() do
startThread(UnitCastAimedSpell, GetAttackerHero(), 4, creature)
end
SetUnitManaPoints(GetAttackerHero(), mana); --Return the mana to the amount it was!
print("casting");
elseif GetHeroName(GetDefenderHero()) == 'Raelag' then
print("if the main character is the attacker");
local mana = GetUnitManaPoints(GetDefenderHero()) --Otherwise, we'll leave the player with 200 mana for no reason!
SetUnitManaPoints(GetDefenderHero(), 200);
repeat sleep(1) until GetUnitManaPoints(GetDefenderHero())==200 --Sleep until the mana is added
for i, creature in GetAttackerCreatures() do
startThread(UnitCastAimedSpell, GetDefenderHero(), 4, creature)
end
SetUnitManaPoints(GetDefenderHero(), mana); --Return the mana to the amount it was!
print("casting");
end;
end
Added 4 minutes ago
P.S. Yes, everything finally works. Thanks again.
Added 3 minutes ago
Hottabych, thank you too. I'll try to carefully study your manual, but for now, I don't understand much of it – it's something like magic).
Added 5 hours 31 minutes ago
Gentlemen, I have a new question for you – as always, one might say. How do I pass information about my hero's level to combat mode? Here is what is written in this topic: https://forum.heroesworld.ru/showthread. ... page=247 "You can save the hero's level in a global game variable using SetGameVar and get its value in battle using GetGameVar"(c) ------------------------------------------------------------- In MapScript, I write: path = '/'..GetMapDataPath() main_hero = 'Raelag' SetHeroCombatScript('Raelag', path.."CombatScript.xdb#xpointer(/Script)"); SetGameVar("LevR", 1); print("We set LevR to be a Set Game Var"); LevR = GetHeroLevel('Raelag'); print("LevR is set as an identifier of Raelag's level"); function ProbaF() -- I only write it to check that LevR works correctly - and it does. if LevR < 20 then print("level is less than 20"); else print("level is 20 or more"); end; end; Trigger(OBJECT_TOUCH_TRIGGER, "Proba", "ProbaF" ); ------------------------------------------------------------- In CombatScript, I write: function Start() Level_R = GetGameVar("LevR") + 0; print("Level_R is set as an identifier of Raelag's level in combat and depends on LevR through Set and Get Game Var"); if GetHeroName(GetAttackerHero()) == 'Raelag' then print("if the hero is the attacker"); local mana = GetUnitManaPoints(GetAttackerHero()); SetUnitManaPoints(GetAttackerHero(), 200); repeat sleep(1) until GetUnitManaPoints(GetAttackerHero())==200; sleep(1); if Level_R < 20 then print("if the level is less than 20, then"); for i, creature in GetDefenderCreatures() do startThread(UnitCastAimedSpell, GetAttackerHero(), 4, creature); print("we cast ice block"); SetUnitManaPoints(GetAttackerHero(), mana); print("we restore mana"); end; else print("if the level is 20 or more"); for i, creature in GetDefenderCreatures() do startThread(UnitCastAimedSpell, GetAttackerHero(), 5, creature); print("we cast a ball"); SetUnitManaPoints(GetAttackerHero(), mana); print("we restore mana"); end; end; ------------------------------------------------------------- But Raelag stubbornly casts not a ball, but an ice block, even though he is level 20! And the console says that he is less than level 20. That is, CombatScript simply does not see GetGameVar? Or it sees it – because Raelag casts – but why doesn't it see if Level_R < 20 then? How can I let combat mode know that the hero is already level 20? And one more question - how do you all insert such colorful scripts here? It's hard to figure out my monotonous mess, I need to format it differently.
SetGameVar("LevR", 1);
print("We set LevR to be a Set Game Variable");
LevR = GetHeroLevel('Raelag');
You are setting the in-game variable "LevR" to 1, so you have no reason to complain – you are not changing it anywhere else.
And the next line, LevR = GetHeroLevel("Raelag"), simply assigns the hero's level (the first one) to a completely different variable.
It should be done like this:
function HeroLevelSave()
SetGameVar("LevR", GetGameVar("LevR")+1)--We increase the variable with the hero's level by 1
end
SetGameVar("LevR", 1)
Trigger(HERO_LEVELUP_TRIGGER, "Raelag")
In the Combat script, it's also a little different:
function Start()
Level_R = GetGameVar("LevR") + 0;
print("Level_R is set as a level identifier for Raelag in combat and depends on LevR through Set and Get Game Var");
if GetHeroName(GetAttackerHero()) == 'Raelag' then
print("if the player's hero is the attacker");
local mana = GetUnitManaPoints(GetAttackerHero());
SetUnitManaPoints(GetAttackerHero(), 200);
repeat sleep(1) until GetUnitManaPoints(GetAttackerHero())==200;
if Level_R < 20 then
print("If the level is less than 20, then");
for i, creature in GetDefenderCreatures() do
startThread(UnitCastAimedSpell, GetAttackerHero(), 4, creature);
print("cast Stone Skin");
end;
SetUnitManaPoints(GetAttackerHero(), mana);
print("restore mana");
else
print("If the level is 20 or more, then");
for i, creature in GetDefenderCreatures() do
startThread(UnitCastAimedSpell, GetAttackerHero(), 5, creature);
print("cast Magic Bolt");
end;
SetUnitManaPoints(GetAttackerHero(), mana);
print("restore mana");
end
end
end;You were missing some "end" statements; I've added the necessary number. Also, your script (if it's as shown above) will only work if *we* attack, not if *we* are attacked.
You were missing one "end".
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
Of course, this is only half of the script — for the attacker — I decided not to clutter the forum and your feed with extra unreadable scripts. I'll make the defender's one based on the attacker's template.
Added 1 hour 31 minutes later
Something isn't working.
MapScript is complaining (Script) ERROR: Parameter lost: function name.
path = '/'..GetMapDataPath()
main_hero = 'Raelag'
print("Main Hero named");
SetHeroCombatScript('Raelag', path.."CombatScript.xdb#xpointer(/Script)");
print("Combat script launched");
LevR = GetHeroLevel('Raelag');
print("LevR set as Raelag's level determiner");
function HeroLevelSaveF()
SetGameVar("LevR", GetGameVar("LevR")+1); --Increment the hero level variable by 1
print("Set that LevR is SetGameVar");
end
SetGameVar("LevR", 1)
Trigger(HERO_LEVELUP_TRIGGER, "Raelag")I tried changing the function name — nothing changes.
I tried removing LevR = GetHeroLevel('Raelag'); (it seemed to me that Trigger(HERO_LEVELUP_TRIGGER, "Raelag") is quite sufficient, and maybe that's the case. Should I remove LevR = GetHeroLevel('Raelag') or not?) — nothing changed either, (Script) ERROR: Parameter lost: function name.
The combat script seems correct, but Raelag still casts Rock, and the game doesn't see that he is level 20. Here is the script, just in case:
function Start()
Level_R = GetGameVar("LevR") + 0;
print("Level_R óñòàíîâëåí êàê îïðåäåëèòåëü óðîâíÿ Ðàèëàãà ìàòü åãî â áîþ è çàâèñèò îò LevR");
if GetHeroName(GetAttackerHero()) == 'Raelag' then
print("åñëè ÃÃ àãðåññîð");
local mana = GetUnitManaPoints(GetAttackerHero());
SetUnitManaPoints(GetAttackerHero(), 200);
repeat sleep(1) until GetUnitManaPoints(GetAttackerHero())==200;
sleep(1);
if Level_R < 20 then
print("åñëè óðîâåíü ìåíüøå 20, òî");
for i, creature in GetDefenderCreatures() do
startThread(UnitCastAimedSpell, GetAttackerHero(), 4, creature);
print("êàñòóåì ãëûáó");
end;
SetUnitManaPoints(GetAttackerHero(), mana);
print("âîçâðàùàåì ìàíó");
else
print("åñëè óðîâåíü 20 è áîëüøå, òî");
for i, creature in GetDefenderCreatures() do
startThread(UnitCastAimedSpell, GetAttackerHero(), 5, creature);
print("êàñòóåì øàð");
end
SetUnitManaPoints(GetAttackerHero(), mana);
print("âîçâðàùàåì ìàíó");
end
else
if GetHeroName(GetDefenderHero()) == 'Raelag' then
print("åñëè ÃÃ àãðåññîð");
local mana = GetUnitManaPoints(GetDefenderHero())
SetUnitManaPoints(GetDefenderHero(), 200);
repeat sleep(1) until GetUnitManaPoints(GetDefenderHero())==200
sleep(1);
if Level_R < 20 then
print("åñëè óðîâåíü ìåíüøå 20, òî");
for i, creature in GetAttackerCreatures() do
startThread(UnitCastAimedSpell, GetDefenderHero(), 4, creature);
print("êàñòóåì ãëûáó");
end;
SetUnitManaPoints(GetDefenderHero(), mana);
else
print("åñëè óðîâåíü 20 è áîëüøå, òî");
for i, creature in GetAttackerCreatures() do
startThread(UnitCastAimedSpell, GetDefenderHero(), 5, creature);
print("êàñòóåì øàð");
end;
SetUnitManaPoints(GetDefenderHero(), mana);
print("âîçâðàùàåì ìàíó");
end
end;
end;
end;Sorry if the Russian text doesn't display, but everything seems clear anyway.Added 3 minutes later
Maybe there's a mistake in the Map script here? Or some extra brackets or quotes?
SetGameVar("LevR", GetGameVar("LevR")+1);
Trigger(HERO_LEVELUP_TRIGGER, "Raelag")
and it should be:
Trigger(HERO_LEVELUP_TRIGGER, "Raelag", "HeroLevelSaveF")
function HeroLevelSaveF()
SetGameVar("LevR", ceil(GetHeroLevel('Raelag')); --Increases the hero level variable by 1
print("We set LevR to Set Game Var");
end
also, fireball is not a targeted spell, but an area-of-effect spell, so it needs to be cast differently:
for i, creature in GetDefenderCreatures() do
local x, y = pos(creature)
startThread(UnitCastAreaSpell, GetAttackerHero(), 5, x, y);
print("Casting fireball");
end
Added 7 minutes later
ScriptEditor complains about the line SetGameVar("LevR", ceil(GetHeroLevel('Raelag'));
I'll have to draw the third parenthesis, like this?
SetGameVar("LevR", ceil(GetHeroLevel('Raelag')));
I'll try it now. Regarding the sphere, you're right, but I placed it here just to make it different from the rock; otherwise, the rock and the improved rock look the same, and I can't tell in battle what Raelag is casting. Thank you, though, for the tip; it will be useful. I'll change the sphere to a lightning bolt now; it's not area-based.
Added 7 minutes later
ScriptEditor complains about the line SetGameVar("LevR", ceil(GetHeroLevel('Raelag'));
I'll have to draw the third parenthesis; is it like this?
SetGameVar("LevR", ceil(GetHeroLevel('Raelag')));