Page 12 of 24

Re: New Dynamic Script Ideas

PostPosted: 05 Dec 2013, 11:15
by RandomLyrics
When a unit is inside a house its XY position is at the door, so you can tell if somebody is in the inn by using something like:
if States.HouseType(States.HouseAt(States.UnitPositionX(U), States.UnitPositionY)) = 27 then
Hmm im checking if the unit is in house and always get ' -1 ' . Heres the code:
UnitAt does not give you units that are inside a house, since there can be many units inside a house at once (e.g. barracks, storehouse, serfs collecting bread from baker, etc.). However, UnitPosition will be the same as HousePosition when a unit is inside a house.
Could you tell me how ill check it? I need to 'respawn' the unit after Action.HouseDestroy - or upgrade this in kam code: Actions.HouseDestroy(aHouse, Silent, KillOccupant: boolean) - true if you want to also kill the occupant, false if you want to resapwn him at the house.

Re: New Dynamic Script Ideas

PostPosted: 06 Dec 2013, 11:14
by Lewin
UnitAt does not give you units that are inside a house, since there can be many units inside a house at once (e.g. barracks, storehouse, serfs collecting bread from baker, etc.). However, UnitPosition will be the same as HousePosition when a unit is inside a house.
Could you tell me how ill check it? I need to 'respawn' the unit after Action.HouseDestroy - or upgrade this in kam code: Actions.HouseDestroy(aHouse, Silent, KillOccupant: boolean) - true if you want to also kill the occupant, false if you want to resapwn him at the house.
Destroying a house does not kill the occupant. Any unit that is inside the house will be placed in the ruins or nearby if there is no space.

But you're right, we need a way for the script to know which unit owns (occupies) which house. Internally we only keep that link from Unit to House. That is, the unit has a property "Home", but the house does not have a property "Occupant" (because in our code the house never needs to know which exact unit lives there, but the unit often needs to know where his home is). This means we can't really provide a function HouseOccupant since the house does not know, but we can provide UnitHome. I implemented this today. That means if you want to kill the occupant of a specific house you should check all units of the player until you find one where UnitHome = TheHouse, then kill that unit.

Re: New Dynamic Script Ideas

PostPosted: 06 Dec 2013, 11:43
by RandomLyrics
Okey ill checked, and yea HouseDestroy dosnt kill occupant and guests serf, but they spawn with lag, from that i cant use this code to change owner or substract wares:
  Code:
Actions.HouseDestroy(aHouse, true); Actions.GiveHouse(toPlayer, States.HouseType(aHouse), States.HousePositionX(aHouse), States.HousePositionY(aHouse));
- after that they magicly disappear.
evan i cant spawn missing workers based on unit count before and after this ownerChange, coz its kinda wierd, it removes unit but the unit isint alive or dead ( but still counts) so the "UnitDead" desont work, only after some ticks its working correctly.
Okey i think i can use this what you are talking about, Ill check all units and if UnitHome is my specific house then after ChangeOwner ill respawn it. Thanks Lewin.
Beferoe(top pig) and after script run ( only this 2 lines of code) (bottom pig):
Image
Before(serf entering) and after script run ( only this 2 lines of code)(while serf and worker is in da house):
Image
it desont show any log errors etc.

Re: New Dynamic Script Ideas

PostPosted: 06 Dec 2013, 12:07
by Lewin
Yes the units will realise the house was destroyed and appear after 1 tick. That's to do with the way our code is structured. But it shouldn't matter if a new house has been created before they reappear, they should be placed outside the new house.

On a side note that code shouldn't work, once the house is destroyed you should not be allowed to use States like HouseType and HousePosition. There was a bug in our caching code which let you use them that I have now fixed.

Could you please send that bug report so I can take a look? That shouldn't be happening (you should not be able to crash the game from the script, we always put checks to try and prevent that). Also can you send me a zip of the entire mission folder you are using to test there? Thanks.

Re: New Dynamic Script Ideas

PostPosted: 06 Dec 2013, 12:11
by RandomLyrics

Re: New Dynamic Script Ideas

PostPosted: 06 Dec 2013, 12:38
by Lewin
You uncovered quite a few bugs there, which I've now fixed :) Thanks for your help. I'll upload a new nightly later today, you can compile it yourself if you want to test it right now. Note that you'll need to stop using States.HouseType/Position after calling HouseDestroy because that is a consequence of one of the bugs I fixed (it should have been that way all along). You can store them in variables to use them after.

Re: New Dynamic Script Ideas

PostPosted: 06 Dec 2013, 13:17
by RandomLyrics
Note that you'll need to stop using States.HouseType/Position after calling HouseDestroy because that is a consequence of one of the bugs I fixed (it should have been that way all along). You can store them in variables to use them after.
yea, i was thinking about that, but it worked so i use it :P
I checkd, works perfectly :)
  Code:
function HouseChangeOwner(aHouse, toPlayer: integer): integer; var t, x, y: integer; begin if (aHouse > 0) and InRange(toPlayer, 0, MAX_PLAYERS-1) then begin t:= States.HouseType(aHouse); x:= States.HousePositionX(aHouse); y:= States.HousePositionY(aHouse); Actions.HouseDestroy(aHouse, true); result:= Actions.GiveHouse(toPlayer, t, x, y); end else result:= -1; end;

Re: New Dynamic Script Ideas

PostPosted: 10 Dec 2013, 13:17
by RandomLyrics
States.GetCarryingUnitTargetHouse(aUnit: integer); - returns ID of targeted house of serf. for example, serf carrying Vine to Inn - returns ID of Inn. or serf carrying Vine to storehouse.
or
States.GetSerfTargetHouse(aUnit: integer); - returns ID of house that serf coming to.

Re: New Dynamic Script Ideas

PostPosted: 10 Dec 2013, 13:59
by Lewin
States.GetCarryingUnitTargetHouse(aUnit: integer); - returns ID of targeted house of serf. for example, serf carrying Vine to Inn - returns ID of Inn. or serf carrying Vine to storehouse.
That can be done, but it seems like an unlikely thing to need in a script. What do you want to do with it?

Re: New Dynamic Script Ideas

PostPosted: 10 Dec 2013, 14:26
by RandomLyrics
Im selling goods from storehouse(remove and give house), and to prevent Ware disappear (from serfs) i check UnitCarrying and sell wares directly from them, but when they carrying something to other buildings it still sales - give 'money' , but wares dont disappear coz their not carrying it to storehouse.
I need to check if the carrying unit coming to MY storehouse then just sell wares from him or hes carrying to other building then do nothing.

Or you can repair this kind of bug, and force serf to wait for new storehouse about 5 sec till he lose his ware and go do anytinhg else

PS: Lewin, did you get my bug report on skype?

Re: New Dynamic Script Ideas

PostPosted: 15 Jan 2014, 23:04
by RandomLyrics
event OnHouseAfterDestroyed(Type, Owner, X, Y: Integer);
event OnUnitAfterKilled(Type, Owner, X, Y: Integer);
States.HouseHealth(hID: integer); - (if its easy to implement) ; its complicate to get househealth by HouseDamge coz you need HouseTypeToHouseHealth
Actions.DisableTowerRoadBlock(aPlayer: integer) - or just global action
ill be very greatefull :)

Re: New Dynamic Script Ideas

PostPosted: 16 Jan 2014, 04:33
by Krom
Actions.DisableTowerRoadBlock(aPlayer: integer) - or just global action
Are you referring to Towers blocking enemy builders from walking near them?
We would not want to implement scripts that affect core game mechanics. That one is one of them.

Re: New Dynamic Script Ideas

PostPosted: 16 Jan 2014, 07:35
by Lewin
I implemented OnHouseAfterDestroyed, that was fairly easy. It doesn't provide you with any parameters since you know that it will relate to the last call of OnHouseDestroyed, so you can store everything you need in global variables. We could provide some basic parameters like HouseType, X, Y, Owner, etc., but I want to make it clear that OnHouseAfterDestroyed is for special cases only and OnHouseDestroyed is the main one you should use, since you can still use the HouseID as normal (because the house has not yet been destroyed).

However, I've been looking at OnUnitAfterKilled and there are some problems. With houses there is no delay between OnHouseDestroyed and OnHouseAfterDestroyed (the code goes something like: OnHouseDestroyed, DestroyHouse, OnHouseAfterDestroyed) since destroying a house is very straight forward and instant. But killing a unit is complicated since there is (usually) a death animation after OnUnitKilled. The Unit ID will be invalid as soon as the death animation starts but the unit is only removed from the game (so you are able to place a new one on the same tile) after the death animation finishes. So OnUnitAfterKilled may happen a few ticks after OnUnitKilled, and if a few units are killed at once you won't know which one it is referring to after those few ticks...

I guess we'll have to provide some basic parameters like UnitType, X, Y, Owner. But then this is very inconsistent with OnHouseAfterDestroyed and will probably confuse people. I'd prefer the two "After" events to be consistent and for it to be clear that they are designed for special cases when you need to replace the unit/house, since the normal Destroyed/Killed events are much more powerful as you are given the Unit/House ID. I'm not sure how to resolve this yet :(

Re: New Dynamic Script Ideas

PostPosted: 16 Jan 2014, 08:12
by Krom
I think we can have OnHouseAfterDestroyed with all the parameters. There's no reasons why OnHouseDestroyed and OnHouseAfterDestroyed could not be used separately? It's just that the first one can have HouseID and later one is better not.

Re: New Dynamic Script Ideas

PostPosted: 16 Jan 2014, 09:58
by Lewin
I think we can have OnHouseAfterDestroyed with all the parameters. There's no reasons why OnHouseDestroyed and OnHouseAfterDestroyed could not be used separately? It's just that the first one can have HouseID and later one is better not.
You're right, there's no harm in scripters using either one (the non-"After" versions are needed if you want to check anything advanced like the number of resources that were in the house). I implemented it like you suggested (check the wiki page for more info).