Page 6 of 24

Re: New Dynamic Script Ideas

PostPosted: 21 Jun 2013, 09:10
by The Dark Lord
Thanks, I'll try this soon. I have already tried to copy your code into my script, but it caused an 'Identifyer expected' error if I remember correctly. By the way, could I extend the attack like the following (I assume I'll be able to change the code you wrote earlier to make it scan for the closest building B)?
  Code:
U := ClosestUnit(P, 12, 34); //Put the actual coordinates here if U <> -1 then Actions.GroupOrderAttackUnit(G, U) else Actions.GroupOrderAttackHouse(G, B);
And one more thing: which coördinates do I need to put where you wrote 12, 34? I'm guessing the coördinates of group G?

Edit: Uknown identifyer 'Sqr'

Re: New Dynamic Script Ideas

PostPosted: 22 Jun 2013, 07:15
by Lewin
Ah, sqr doesn't seem to exist in PascalScript. Try this:
  Code:
function ClosestUnit(aPlayer, X, Y: Integer): Integer; var Units: array of Integer; i, BestDistanceSqr, ThisDistanceSqr, DX, DY: Integer; begin Result := -1; Units := States.PlayerGetAllUnits(aPlayer); for i:=0 to Length(Units)-1 do begin DX := X-States.UnitPositionX(Units[i]); DY := Y-States.UnitPositionY(Units[i]); //Using squares is more efficient than square roots and gives exactly the same result (Pythagoras) ThisDistanceSqr := (DX*DX) + (DY*DY); if (Result = -1) or (ThisDistanceSqr < BestDistanceSqr) then begin BestDistanceSqr := ThisDistanceSqr; Result := Units[i]; end; end; end;
The coordinates are where "closest" is measured from. You can't have a closest thing without defining where it is close to ;)
So yes if you want closest to a unit give its coordinates.

Re: New Dynamic Script Ideas

PostPosted: 19 Jul 2013, 11:18
by Siegfried
Request:
  Code:
States.HouseCannotReachAnyMoreResources: boolean
Needed for all kind of mines, stone masons and woodcutters.

Re: New Dynamic Script Ideas

PostPosted: 19 Jul 2013, 11:48
by Krom
Good idea, I'll add it to our list

Re: New Dynamic Script Ideas

PostPosted: 19 Jul 2013, 13:41
by sado1
How about some new events:
  Code:
OnHousePlanPut(aHouseID) OnRoadPlanPut(X,Y) (also with versions for fields and wine)

Re: New Dynamic Script Ideas

PostPosted: 25 Jul 2013, 04:54
by RandomLyrics
Sleep(ticks)
Actions.HouseWareSubtract(id, ware type, amount) or HouseSetWareAmount(id, ware type, amount)

Re: New Dynamic Script Ideas

PostPosted: 02 Aug 2013, 08:05
by Bence791
New state:
GroupAtDefPos(PlayerID, X, Y)

New action:
AddDefPos(PlayerID, UnitType, X, Y, facing direction, defence radius, frontline: boolean)

And maybe a unique "GroupOrderAttack" action with the following parametres: GroupID (attacker), Target (1-closest building, 2-closest unit), From (1-center screen, 2-army), Combo: Boolean (true: repeating the attack until all possible targets are down, so they don't retreat). It would be nearly the same as we can set in the MapEd, but it would make it easier and would reduce the mistake factor imo (you can set whichever troops should attack, so you don't have to rely on those backline troops, would require "GroupAtDefPos" though).

Re: New Dynamic Script Ideas

PostPosted: 03 Aug 2013, 20:07
by Strangelove
I love Bence791 ideas. I'd have needed them a couple of times already!

Re: New Dynamic Script Ideas

PostPosted: 07 Aug 2013, 14:19
by Bence791
2 more "adapted from static" script commands (actions) I'd like to see:

"SetAITownDefence" and "SetAIAgressiveness", both 0-200 as it was :D
These 2 can only be set through a static script editor, yet impossible to do in the KMR MapEd.

Re: New Dynamic Script Ideas

PostPosted: 07 Aug 2013, 15:07
by Krom
@Bence: From what I know these two are ignored by KaM Remake since we don't know what exactly they do..

Re: New Dynamic Script Ideas

PostPosted: 07 Aug 2013, 19:12
by Bence791
Well, Town Defence should determine how "much" (or rather well?) they defend their city. On a 200 scale, 0 is the "idc" level, 200 is the "what are you doing? get away! level.

And AI Agressiveness should determine maybe how they handle the enemy attacks. If it is 0, they will only attack with 1 group of shot at or attacked in melee, if 200, all the troops attack.

Without these 2, SP missions lose their "challenge" factor :c

Re: New Dynamic Script Ideas

PostPosted: 08 Aug 2013, 05:38
by Krom
@Bence:

City defense is actually managed by defense positions radiuses ...

All attacks are scripted ...

The point is - we don't know what these 2 did in KaM.

Re: New Dynamic Script Ideas

PostPosted: 08 Aug 2013, 07:23
by Bence791
Well, there are many missions (or at least were) in the Remake (I mean SP), in which the enemy only came group by group when luring. I doubt if they had so little radiuses (<5). Anyway, radiuses aren't the good solution to it imo, since there can be a case when the AI's entrances are too far from each other that if all the frontline troops had that radius, they'd attack you even if you defend against their programmed attack.

Re: New Dynamic Script Ideas

PostPosted: 08 Aug 2013, 22:25
by Tef
I desperately need AITownDefense and AIAgressiveness :'(
In the old days, I never understood what those two did; they sometimes worked and sometimes they didn't when creating maps.

I was actually planning on creating some dynamic auto-defense scripts. I think it expands the possibilities much further since you can include aspects like the AI's current army size, gametime, distance to one of his buildings, distance between your and his groups, unit types of your army. For example, it should be relatively easy to create a dynamic script where you get attacked by horse-type units if you get your archers too close to one of his enemy units if within proximity of his base. I was planning on making such a script universally applicable, so that can be cut-pasted into any map and it only requires some simple adjustments to some parameters to make it work like you want. I don't mind sharing such a script when ready. Interested?

Re: New Dynamic Script Ideas

PostPosted: 09 Aug 2013, 00:57
by Lewin
AITownDefense and AIAgressiveness are ignored by the Remake at the moment. In TPR, soldiers which were not in a defence positions would still be used by the AI. They would guess a place to defend and use them to assist in battles. So soldiers could be used for defending/helping without placing them in a defence position. I believe AITownDefense and AIAgressiveness controlled that behavior.

In the Remake, soldiers which are not in a defence position are mostly ignored. They will be used in attacks, but other than that they will just sit there. This was because writing that part of the AI seemed very difficult compared to simple defence positions, and the standalone AI which Krom has been working on can hopefully fill that role. The campaigns still work fairly well since most missions use enough defence positions, but there are some cases (like the auto build AIs) which don't work well at all.
New state:
GroupAtDefPos(PlayerID, X, Y)

New action:
AddDefPos(PlayerID, UnitType, X, Y, facing direction, defence radius, frontline: boolean)

And maybe a unique "GroupOrderAttack" action with the following parametres: GroupID (attacker), Target (1-closest building, 2-closest unit), From (1-center screen, 2-army), Combo: Boolean (true: repeating the attack until all possible targets are down, so they don't retreat). It would be nearly the same as we can set in the MapEd, but it would make it easier and would reduce the mistake factor imo (you can set whichever troops should attack, so you don't have to rely on those backline troops, would require "GroupAtDefPos" though).
Modifying defence positions is a good idea but it could be complicated to implement. How do you address/identify a defence position from the script? A command to make launching attacks easier is a good idea, maybe even "GetClosestHouse/Unit(PlayerID, X, Y)" would be enough, then you can choose the target relative to a position and launch the attack yourself.
Sleep(ticks)
That's not how the script works, sleeping would just lock up the game for that duration then continue where it was (there's no way to pause the script on a certain line then resume it after a certain number of ticks have passed). What would happen if another event was called while the script was paused? Then we have two execution points in the script, it all gets very complicated. You need to use the OnTick event to detect when a certain amount of time has passed, you can set a global Integer to say the time when you want the script to do something (States.GameTime+ticks) and check that in OnTick.
Actions.HouseWareSubtract(id, ware type, amount) or HouseSetWareAmount(id, ware type, amount)
Sounds like a good idea, there needs to be a way to remove wares from houses.