Jump to content


Photo

TobEx Wish list


  • Please log in to reply
821 replies to this topic

#501 Indral

Indral
  • Member
  • 30 posts

Posted 06 December 2011 - 12:36 AM

Would it be possible to introduce some core P&P rules involving character death?

1. Character goes unconscious when 0 or below hitpoints.
2. Character receives 1 damage per round if below 0 hitpoints.
3. Character can be bandaged or healed to stop bleeding.
4. Character dies when below 0hp for the amount of his/her constitution.

Edited by Indral, 06 December 2011 - 12:37 AM.


#502 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 10 December 2011 - 03:32 PM

Oh god.

http://forums.gibber...showtopic=23610

Any chance of making DialogueSetGlobal work as in dialogs in AI scripts? Or even better, something like
Now(Action) trigger.

To use with sendtrigger, setglobal, timers etc.

Something that executes the action in the trigger phase if as i suspect the engine is aggregating all actions and then doing them all at once, which is incompatible with actually using their changes in the current AI script execution.

Though variable substitution that works in the trigger phase would possibly be almost as good (except in the case of Timers)

You run the risk of destabilising scripts if globals are set straight away, especially if multiple scripts depend on the same global, certain scripts will process the global at one value while other process at a different value. This can produce unexpected results. Probably better not to continue and wait for the next AI update.

Would it be possible to introduce some core P&P rules involving character death?

1. Character goes unconscious when 0 or below hitpoints.
2. Character receives 1 damage per round if below 0 hitpoints.
3. Character can be bandaged or healed to stop bleeding.
4. Character dies when below 0hp for the amount of his/her constitution.

I already have a hack that prevents the ending cutscene showing if the player dies. Your suggestion should be implementable thus in soft-code.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#503 i30817

i30817
  • Member
  • 611 posts

Posted 10 December 2011 - 03:43 PM


Oh god.

http://forums.gibber...showtopic=23610

Any chance of making DialogueSetGlobal work as in dialogs in AI scripts? Or even better, something like
Now(Action) trigger.

To use with sendtrigger, setglobal, timers etc.

Something that executes the action in the trigger phase if as i suspect the engine is aggregating all actions and then doing them all at once, which is incompatible with actually using their changes in the current AI script execution.

Though variable substitution that works in the trigger phase would possibly be almost as good (except in the case of Timers)

You run the risk of destabilising scripts if globals are set straight away, especially if multiple scripts depend on the same global, certain scripts will process the global at one value while other process at a different value. This can produce unexpected results. Probably better not to continue and wait for the next AI update.



I didn't say to make it general. Some explicit trigger would be needed.

Restarting is lame, and O(N!) or something like that. And sometimes what you want is "multiple scripts depend on the same global" being affected in the same round, eg: casting party wide buffs, only 1 character casting it.

The alternative is waiting for the next AI tick, which is dangerous in combat.

Besides i am extremely leery of changing variables, and not changing them back at the same round if i can, because AI is something that can be
1) turned off.
2) interrupted.
3) go into lala land because of a higher AI script
4) makes conditional scripts harder to read and slower since they then have to be processed in two phases: first change the variables, then act on them. It duplicates the number of blocks...



Resuming i think that separating Trigger evaluation from Action Execution is a terrible, terrible idea that complicates AI code needlessly and i curse bioware for ever thinking of it (or at least not putting the actions that affect variables and timers as Triggers).
But if you think it's best not to mess with that part of the code (would lead to bugs in the code itself?), ok. But i don't agree that "people could use it badly" is a good counterargument though.


Edited to remove pointless ranting

Edited by i30817, 11 December 2011 - 02:23 PM.


#504 DavidWallace

DavidWallace
  • Validating
  • 337 posts

Posted 11 December 2011 - 04:15 AM

How complicated would it be to

(a) add additional animation slots
(b) allow editing of the size of animation foot-circles (either by externalising it to some 2DA, or - I'm guessing this is easier - just having a bunch of variables in ToBEx-tweaks.ini)

I'm aware (a) can be worked around, so it's not worth really significant work to achieve.

#505 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 11 December 2011 - 02:21 PM

I didn't say to make it general. Some explicit trigger would be needed. <etc...>

Rather than the technical example you gave on G3, do you have an actual use that you could share and we can all mull over it together?

How complicated would it be to

(a) add additional animation slots
(b) allow editing of the size of animation foot-circles (either by externalising it to some 2DA, or - I'm guessing this is easier - just having a bunch of variables in ToBEx-tweaks.ini)

I'm aware (a) can be worked around, so it's not worth really significant work to achieve.

Does Infinity Animations not give you the animation type-foot circle combination you need? Both are relatively straightforward, however, I am already extremely cautious about treading on IA's toes. Put simply, the .exe hackery of IA is extreme regarding the animation department.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#506 i30817

i30817
  • Member
  • 611 posts

Posted 11 December 2011 - 02:44 PM

I edited the post above to go to the crux of the problem.

Anyway the most annoying thing about this for the user is that responsiveness goes down if you want to do conditional work on a script, simply because you need to wait for the next turn to see the new values. Also you need to duplicate the blocks (one to change the var, another to actually do something with it).

If you really want to see a example, here is the code for my party auto buff
(not compiling because i thought i could use a new IDS for constants, which i fear i can't).

Sorry about the length (but i guess it helps the point).

http://pastebin.com/raw.php?i=N7Y1MM9M
The upper part is actually casting the spells if the Trigger "variables" were satisfied and some precedence and exclusion conditions, the lower part actually checks if it's possible to cast and if it should (already cast etc).
Both these parts could be collapsed if the variables could be set directly as a triggers (in this case, treat SendTrigger as a Trigger - unfortunate name that).

Edited by i30817, 11 December 2011 - 02:59 PM.


#507 i30817

i30817
  • Member
  • 611 posts

Posted 11 December 2011 - 07:48 PM

This is OT; but, I'm wondering if you know the reason for this:
http://forums.gibber...=0

seems very strange (and is part of the reason my code above is not working ok).
The same bizarre behavior occurs with !HotKey

Edited by i30817, 12 December 2011 - 03:50 AM.


#508 DavidWallace

DavidWallace
  • Validating
  • 337 posts

Posted 12 December 2011 - 03:58 AM

I didn't say to make it general. Some explicit trigger would be needed. <etc...>

Rather than the technical example you gave on G3, do you have an actual use that you could share and we can all mull over it together?

How complicated would it be to

(a) add additional animation slots
(b) allow editing of the size of animation foot-circles (either by externalising it to some 2DA, or - I'm guessing this is easier - just having a bunch of variables in ToBEx-tweaks.ini)

I'm aware (a) can be worked around, so it's not worth really significant work to achieve.

Does Infinity Animations not give you the animation type-foot circle combination you need? Both are relatively straightforward, however, I am already extremely cautious about treading on IA's toes. Put simply, the .exe hackery of IA is extreme regarding the animation department.


The context is my IWD-> BG2 converter, so there isn't a risk of clash with IA. Having said that, it's possible I should just be looking at IA itself, which I don't know well (and which I think has changed dramatically since I originally looked at IWD->BG2 animations 4 years ago).

#509 i30817

i30817
  • Member
  • 611 posts

Posted 12 December 2011 - 12:30 PM

After some testing because of the problem i found explained in the thread i linked above, i'm pretty sure some triggers ignore ! in one or more of the return paths.

!Trigger(2) - Without a corresponding SendTrigger - only matches the first time a script is run, or if a key is pressed. Every other normal AI tick is is false

Trigger(2) HTOH, never does match. It is always false.
This scenario is only compatible with the ! flag being ignored in one or more of the returns

Can this be fixed? I don't think anyone uses ! on these broken triggers anyway (because it doesn't work).

HotKey() has the same problem, possibly others.

I tried to see if i could work around it with
!TriggerOverride(Myself, Trigger(N))
But that didn't work... TriggerOverride is just replacing the Object argument, not wrapping right?

If messing with ! inside the trigger function is too dangerous, how about allowing
TriggerOverride to inverted the return directly instead of passing the flag? Or creating a InvertTriggerOverride that does it (better name required).



I've never been a fan of the single point of return...
UNTIL NOW!

Edited by i30817, 12 December 2011 - 12:46 PM.


#510 phordicus

phordicus
  • Member
  • 212 posts

Posted 12 December 2011 - 06:06 PM

I hate to encourage further derailing for your very specific scripting purposes, but if your goal is simply setting variables in a party buff script, why not just have the character who casts Buff X do a Shout that sets a Local on the others so they don't cast that particular one, likely even the same variable they would set if they cast it themselves?

Edited by phordicus, 12 December 2011 - 06:07 PM.

Druid Kit Enhancements 1.0 (requires Dispel Magic fix, whether ToBEx's or Taimon's)

#511 i30817

i30817
  • Member
  • 611 posts

Posted 12 December 2011 - 06:26 PM

If you think i'm derailing, you haven't payed attention.

I know i can use shouts, orders, triggers, timers or variables.

I'm just pointing out that
1) there is no actual way to change a latch variable and use it in the same ai tick because the statements that change volatile memory are actions.
2) "!" has a rather nasty bug where it is ignored in most return paths of some triggers. This means that a trigger and its "negation" may not be disjoint making it useless to use those triggers as a form of conditionals for exclusion.
I believe the Global() trigger doesn't have this problem.

Edited by i30817, 12 December 2011 - 06:42 PM.


#512 phordicus

phordicus
  • Member
  • 212 posts

Posted 12 December 2011 - 09:26 PM

I see. So basically some triggers don't have their negation coded correctly if at all. Gotcha! ;)
Druid Kit Enhancements 1.0 (requires Dispel Magic fix, whether ToBEx's or Taimon's)

#513 i30817

i30817
  • Member
  • 611 posts

Posted 13 December 2011 - 05:48 AM

I think a workaround for these problems could be made with:
!TriggerOverride wouldn't pass the "!" flag to the trigger, but invert the result (unconditional inversion). This can be done now because there are few people using TriggerOverride and fewer people using !TriggerOverride and fewer people (none i'd bet) that would expect something different from what that would do (probably unlike fixing the triggers directly where some code might be depending on !Trigger() triggering only when the game is loaded or when you press a key).

A bit of a eyesore though.

For the variables problem something like
Now(O:Actor*,A:Action*instant) returning true.
Would do. People would need to remember to put all of these at the end of the Trigger section and not in a OR (i think). But that is minor stuff compared with the problem above - if Ascension64 thinks it a bad idea, don't put it in by all means.

Edited by i30817, 13 December 2011 - 05:53 AM.


#514 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 13 December 2011 - 04:35 PM

The context is my IWD-> BG2 converter, so there isn't a risk of clash with IA. Having said that, it's possible I should just be looking at IA itself, which I don't know well (and which I think has changed dramatically since I originally looked at IWD->BG2 animations 4 years ago).

Perhaps have a look at IA first. Hacking a hack isn't very nice. :P

! for Triggers

The implementation of ! for triggers is a blanket NOT (Trigger), so !Hotkey(A) isn't 'any hotkey other than A', it is 'always do unless hotkey A is pressed'.

Not so sure about !Trigger(), Trigger() looks at old-style triggers 0x0*** that are stored in a trigger list and then purged after one script round. !Trigger() would mean 'anything other than the trigger', which would true if there was no trigger at all. It does not mean 'a trigger that is not the one that you mention in the parameters'.

TriggerOverride

!TriggerOverride isn't implemented. Anyway, the syntax you currently use is the bigg's shorthand version, which is not its implementation.

What you would want rather is:
TriggerOverride(Myself)
!Trigger(N)
...assuming that your !Trigger() is working.

If you pester the bigg, he might implement TriggerOverride(Myself,!<some trigger>)

Edited by Ascension64, 13 December 2011 - 04:35 PM.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#515 i30817

i30817
  • Member
  • 611 posts

Posted 13 December 2011 - 05:13 PM

Yeah, well:

The implementation of ! for triggers is a blanket NOT (Trigger), so !Hotkey(A) isn't 'any hotkey other than A',

Which is not what i want.

it is 'always do unless hotkey A is pressed'.


Doesn't work, and you can test it in a AI script with :
IF
  !HotKey(V)
THEN
  RESPONSE #100
    DisplayStringHead(Myself, ~I did not press V~)
END

IF
  True()
THEN
  RESPONSE #100
    DisplayStringHead(Myself, ~This should not happen~)
END
(And nothing else).
Funny enough this triggers "I did not press V" in the first round, and if you pressed any key except V. For instance N. The rest is "This should not happen".


Not so sure about !Trigger(), [...]
!Trigger() would mean 'anything other than the trigger', which would true if there was no trigger at all.


And surely also true if the sent Triggers stored in the list do not contain the checked trigger? That condition is what i want and what makes sense. But even your more restricted condition also does not work:
IF
  !Trigger(23)
THEN
  RESPONSE #100
    DisplayStringHead(Myself, ~I was not triggered~)
END

IF
  True()
THEN
  RESPONSE #100
    DisplayStringHead(Myself, ~This should not happen~)
END
(And nothing else)

Funny enough this ALSO triggers in the first round, and if you pressed any key (though trigger has nothing to do with hotkeys). A obvious case of multiple returns.

It does not mean 'a trigger that is not the one that you mention in the parameters'.

Which is not what i want, but sure, it could trigger if the previous condition was true.


It's a bug. Please test the AI code in a in the protagonist to see.

That they BOTH trigger if you press a key or in the first round shows thats it is a error in shared returns not using the "!" flag. It would be too much of a coincidence otherwise.

If you pester the bigg, he might implement TriggerOverride(Myself,!<some trigger>)

Which would be useless since the problem is inside the trigger. I know i can't use TriggerOverride. I only wish that it's implementation change to replace the ! flag argument like it replaces the Object argument. Don't pass ! and invert the result, not depend on the buggy triggers. Or you can fix them, but i don't know if there is code depending on the (frankly bizarre) current behavior.
Or... new versions of these triggers? I don't know all that have this problem, i only checked these two for now.

If you do new versions, could your new Trigger() use a bitfield instead of a list? It could be much faster for high usage than a list. And 256 slots should be enough for everything...

Edited by i30817, 13 December 2011 - 07:06 PM.


#516 i30817

i30817
  • Member
  • 611 posts

Posted 13 December 2011 - 05:50 PM

Surely i'm not going insane and am the only one that thinks that that is a bug?

#517 Dakk

Dakk
  • Member
  • 398 posts

Posted 13 December 2011 - 06:13 PM

Surely i'm not going insane and am the only one that thinks that that is a bug?

(surely the one doesn't exclude the other:devil:)

#518 Ascension64

Ascension64
  • Modder
  • 5983 posts

Posted 14 December 2011 - 03:35 AM

Yes, it does sound a bit weird. I'll look into what's going on.

--------------
Retired Modder
Note: I do not respond to profile comments/personal messages in regards to troubleshooting my modifications. Please post on the public forums instead.

Baldur's Gate Trilogy-WeiDU and Mods
Throne of Bhaal Extender (TobEx)

Contributions: (NWN2) A Deathstalker (voice acting) - (IWD2) IWD2 NPC Project (soundset editing) - (Misc) SHS PC Soundsets (voice acting)
Legacy: (BG/Tutu/BGT) Beregost Crash Fixer 1.9 (18 Jul 10) - (BG2) Enable conversations with charmed/dominated creatures (18 Jul 10) - (BG2) Experience Corrections (18 Jul 10) - (Misc) Platform Conversion Utility RC2 (13 Feb 10)


#519 i30817

i30817
  • Member
  • 611 posts

Posted 17 December 2011 - 03:48 AM

By the way, i was thinking of auto-looting, so i did a simple tests.

I don't think [0.POTION] or similar can detect objects in piles on the ground (which is what i thought that was for). No way to do that?

Instead of trying to fix "!Trigger" i'd actually prefer a local variable that wouldn't use Globals that was reset automatically (like triggers, but indexed not on a list)

Say implemented as 2* triggers and 1 actions implementing a bool array:

Get(Int Index)/Set(Int Index)

So you'd write to a write array with Set() and return the values of the read array on Get() and zero the read array and exchange them at the end of the AI tick. You'd only need to zero & exchange on end of a AI tick after a write, so a boolean on the functions would prevent unnecessary work.

(* and i'd love it if Set() could be used as a Trigger too... So make another version of Set() a trigger version that writes on the write array AND on the read one)

The size of the thing would be controlled by a IDS file max value. This ids would be appended by modders that want to use the array (would need a way to make sure of not overwriting indexes, start at max+1. Maybe a new WeiDU macro for IDS files non-overlapping appending?).

Basically a faster, "!" friendly, compile-time sized version of trigger that optionally allows simple boolean variables in the same turn in addition of the next.

edit: removed a few problems on the idea;

BTW, this mental exercise made me realize why making normal SendTrigger() usable as a trigger would be a bad idea (and by extension a Now(Action) trigger): the algorithm might not allow it. But i think this one would, what do you think?

Edited by i30817, 17 December 2011 - 04:06 PM.


#520 i30817

i30817
  • Member
  • 611 posts

Posted 17 December 2011 - 09:12 PM

Ok, new request:


Seems there is no way to access container objects ingame from script.

All of the game-object ids in general appear not be implemented for See, Detect, etc.

This action:
CopyGroundPilesTo(A:Area*, P:Point*)
Already must be finding the dynamic (piles) containers in a area at runtime.

It's almost useful to autoloot.
However
1) it only copies the items, not moves them, and into the ground, not into a inventory.
2) it copies all of the items in the area
3) no way to set the location dynamically. [0.0] is relative to the area, not the current object



So i wish for 3 actions like:

MoveVisibleGroundPilesTo(P:Point*)//point relative to the current object, not area, only visible dynamic containers

PickUpItems(O:Object*)//would use object ids like [0.WEAPON.SWORD.0.MAGIC]

PickUpItemsTo(O:Object*,S:Item*)


The first is a specialization of CopyGroundPilesTo. It would joint all loot piles in LOS and place then next to or under the object given. However it would not move them if there is only one (there's no need, and it would interfere with only using 1 hotkey for both 1 && (2||3) )

The second doesn't exist. But is inspired by PickUpItem where instead of scripting name and only one object, it would try to pick up categories. PickupItem also has the problem it picks up items on locked containers, and not trigger the npc's noticing. Maybe disallow locked containers and try to open before (for the npc's noticing/traps)?

It would move to and attempt to move all objects of type in the nearest unlocked untrapped visible container into the inventory of the current object. If it is full, drop them. If it doesn't find it in nearest, search for the next nearest.

The third would try do the same as 2, but would instead of putting in inventory, try to find the container "Item" in the inventory and try to move the item there (user should make sure the container accepts it). It should noop if the container is not in the inventory.

The first could be used to aggregate the near piles into a single one (already useful).

The second would actually filter things and move into inventory. As said before, if they also worked with normal containers (not piles) with some restrictions they'd be more useful.

Third same as second but more useful yet.

Anyway, that's a wish, i'm aware that's unlikely to be granted ;)

Edit2: refined request again
Edit3: and again!

Edited by i30817, 20 December 2011 - 03:32 PM.