Jump to content

marchitek

Members
  • Posts

    152
  • Joined

  • Last visited

Everything posted by marchitek

  1. Eh, pity there is no easy way to do this. Some hacks could probably work, but since game stability is at stake and I have some acceptable fallback I would probably resign from touching that. Thanks for clarification.
  2. It seems Die() trigger not return true when duration of summoned creature expires (what makes sense). Is there a way to get similar behavior for such case? I'm experimenting with LockScroll() action and it seems game crashes when scroll is locked on summoned creatures that is unsummoned because its duration expires. So I was hoping to solve this problem by unlock scroll in last script round.
  3. I recently found this: https://eeex-docs.readthedocs.io/en/latest/EE Game Lua Functions/index.html Not much description there, but method names are rather self explanatory.
  4. Offsets are usually referred in hexadecimal system and by convention, if you want to indicated that number is hexadecimal, you strat it with '0x', e.g hex 0xa7 = 167 in decimal, that means in WieDU code 167 and 0xa7 points to the same place in file, however it is better to use hex number since it is used like this everywhere else. Worth to note IESDP as a source of information. This contains pure technical specification of game files (and much more).
  5. If I understand correctly facts are that (1) methods that are included in WeiDU relay on transition order and (2) we have already many mods that use them so it makes sense to me that good practice would be to add new transitions on the bottom (ofc any rule can have exceptions if case justifies it, I didn't want to imply with my question that @subtledoctor is doing something wrong). I believe creating function that clones transition and add it at the end of state isn't that complicated (if it doesn't need to be super efficient). One regexp to find transition and one to find end of state and insert. Unless I'm missing something. I guess there are also many mods that extend top so I personally have a feeling that textual matching instead of relaying on order is safer (and it is easier to detect if something is wrong and act accordingly).
  6. Isn't relaying on transitions order risky if we are considering compatibility with other mods?
  7. It seems that this topic is "no one knows" type of thing. Here is couple of my findings: UI can be edited by altering UI.menu file. It can specify placement and visuals of buttons and what engine actions to perform on click, double click etc. Engine actions that are exposed are quite high level so we have something like "Infinity_OnPortraitDblClick(0)". However it is possible to execute console commands using C:{command} syntax and consequently, it can be used to execute script actions with C:Eval('..'). It is possible to extend existing behavior so replacing "Infinity_OnPortraitDblClick(0)" with "Infinity_OnPortraitDblClick(0) C:Eval('..')" would perform both actions. I haven't tested adding new button, but is seems to be possible (for sure there are mods that add button during character creation). In my case CTRL+P can be more or less replaced with C:Eval('ActionOverride(..., LockScroll())'), but it works a bit differently: for some buttons it adds lock scroll at the end of creature action list, for other buttons it overwrites action list with lock scroll action, I don't know why different buttons imply different behavior. CTRL+P seems to be more independent from creature action list. Hotkeys are stored in BGEE.lua in lines like "{ 1, 1, 'Inventory', "ASSIGN_KEYS_PAGE_INVENTORY", '', 0, 105 },", it seems that first number is kind of id. But I have no idea how to extend it so it would execute some lua function or something like this. There is also "HotKey(..)" script trigger, but no idea how I could track from scripts which creature is pointed by cursor. It would be super cool to know how to execute CTRL+P behavior with console command (or other exposed function). It would basically solve my problem (putting aside hotkey possibility). For resources I found: Tutorial of UI modding basics: https://forums.beamdog.com/discussion/48994/the-new-ui-system-how-to-use-it List of actions exposed by engine in lua files: https://eeex-docs.readthedocs.io/en/latest/EE Game Lua Functions/index.html
  8. Yes, could be. As I said, it is matter of regexp. It can be more strict but then more chance that it will not match. It can be more liberal and match something that shouldn't be matched. But you need to identify this block somehow anyway. Hoping you will find more elegant solution. Just in case, here is the code that solves example: OUTER_SPRINT s ~[%TAB% %LNL%%MNL%%WNL%]~ OUTER_SET ok = 0 COPY ~Test/in.d~ ~Test/out.d~ REPLACE_TEXTUALLY EVALUATE_REGEXP ~%s%+~ ~ ~ REPLACE_TEXTUALLY EVALUATE_REGEXP ~%s%+~ ~ ~ REPLACE_EVALUATE "BEGIN 9.*\(IF%s%*~CheckStatGT.*GOTO%s%*10\)" BEGIN SET ok = 1 // you can also access %MATCH1% here and do some trasformation END ~~~~~ %MATCH0% %MATCH1% ~~~~~ ACTION_IF (NOT ok) BEGIN WARN ~not ok~ END
  9. Character Respawn is definitely not. More Hp and View Lock should work, although I haven't tested that. It should be installed rather at the very end of whole installation. You would need to edit tp2 to remove installation restrictions. View Lock would probably not lock view after game load in SoD / BG2 portion of the game , but you can easily do it yourself CTRL+P cheat key. Proper cutscene handling, what is most impotent here, should however work for whole content.
  10. I'm far from being expert but I would ditch dialogue related actions and use DECOMPILE_AND_PATCH + REPLACE_TEXTUALLY / REPLACE_EVALUATE. The only problem is to find good regexp to match this block. Then should be easy to duplicate if you capture whole block as group you can just replace one occurrence into two occurrences in the row (or event edit second one as you like on the fly).
  11. Version 0.4 is released. Changelog: Moved Character Respawn component to Beta: fixed bug when death in polymorphed state preserve this form and make unable to return to natural form, added proper handling for all possible death scenarios including those unpresent in unmodded game, added protection against failure during escort mission in Ducal Palace. I guess for anniversary release it could be something more spectacular, but I was out from IE modding for a while. I hope there would be couple more releases before I will need break again.
  12. I'm looking for a way to make one of cheat keys (specifically CTRL+P, screen lock) more accessible during play. By this I mean things like: possibility to bind it to some hotkey making button that would invoke it applying it automatically on some condition (e.g. on character selection) I'm totally new to UI modding so I don't know if this topic is something like "sure, can be done" or "maybe with EEEx" or "no way, forget it" type of thing. BTW Can you recommend any good resources for learning UI modding? I'm targeting only EEs.
  13. Steps to reproduce: create non protagonist Avenger level up and change to Fire Salamander kill Avenger resurrect Avenger Effect: "Breathe Fireball" ability is still visible in innate abilities and can be used Expected: "Breathe Fireball" ability should not be available I guess it is missing "remove spell" effect in #rdremov. Tested on BGEE 2.6 without SoD.
  14. You are right! Works even with Player1 instead of PartySlot1. I'm quite sure I tested that with Player1 and it didn't work, but well.. I guess engine haven't changed its behavior during time in between. Thank you! You saved me 12 blocks in global script and now this synchronization between check and actual effect is exact. So internally it is something like engine for each game tick iterate over all "active" creatures (global + in active area?), checks their effects and acts accordingly (remove if duration is finished, apply when delay is finished, apply damage if this is poison opcode etc)? And for creatures in maze engine ignores in this process all opcodes besides those you mentioned. Then spell state is not recognized because it was not "applied" in this game tick, despite of being applied as effect in general (it is still visible in EEKeeper etc). I hope this is at least more or less what is happening. *** I know what makes my previous test not accurate. This. Beware for this TriggerOverride + OR pitfall.
  15. Ok, this spell state is dead end. Now I'm not surprised that such state not exists, since creatures in maze are untargetable anyway. I think I found solution for my case. Is uses variables instead of spell state. I take advantage of fact that I need to only track state of 6 specific objects in game. And even synchronization of detection and actual effect is good. It goes more or less like this: for every maze effect set local variable on object before maze effect triggers for every maze effect set delayed unset of this local variable (note: "Delayed effects that would trigger will be further delayed until this effect is removed." from IESDP) in global script synchronize local variable with global variable dedicated to creature (if Player1 local InMaze = 1 then set global Player1InMaze = 1 and other way round etc.) watch in scripts for global variables (obviously this works despite of any creature being or not in maze) In time between setting local var and triggering maze (what would make accessing local var impossible), local and global var is synchronized. Then, when creature is back form maze, delayed unset of local var is triggered and synchronization in global script removes global variable. BTW It seems that ClearAllActions() removes maze effect. Maybe it triggers this delayed freedom effect that removes maze? Hard to say. Or maybe this works like this only for my case for some particular reason.
  16. I tested that and you are right, checking spell state not work correctly for creatures in maze. It seems it returns always false. IESDP says: I tried to get desired effect with "partyslot" objects ( PartySlot1, Player1Fill etc), but no luck so far.
  17. Basically I wan to run script actions when all PCs are in maze. I do similar thing for charm, I extended global script with script block: IF StateCheck(Player1, STATE_CHARMED) OR(3) !Exists(Player2) StateCheck(Player2, STATE_REALLY_DEAD) StateCheck(Player2, STATE_CHARMED) OR(3) !Exists(Player3) StateCheck(Player3, STATE_REALLY_DEAD) StateCheck(Player3, STATE_CHARMED) OR(3) !Exists(Player4) StateCheck(Player4, STATE_REALLY_DEAD) StateCheck(Player4, STATE_CHARMED) OR(3) !Exists(Player5) StateCheck(Player5, STATE_REALLY_DEAD) StateCheck(Player5, STATE_CHARMED) OR(3) !Exists(Player6) StateCheck(Player6, STATE_REALLY_DEAD) StateCheck(Player6, STATE_CHARMED) THEN RESPONSE #100 ClearAllActions() StartCutSceneMode() StartCutSceneEx("%respawn_execution_cutscene%", TRUE) END I want to extend with with "maze" check. That's why I thought about state and spell state. On a side note: normally this situation means "Game Over", but I have "Player1 can die" flag set on area, that prevents this.
  18. I'm looking for a way to reliable detect that object is under maze effect. It seems there is not built-in state for it. There is also no spell state, but I'm thinking about adding one. Problem is that maze opcode can have dynamic duration, dependent on objects intelligence and also has some randomness in it. So, if I understand correctly, I will not be able to apply spell state with accurate duration. TBH maybe I don't need super accurate sync between spell state and actual effect, still it would be nice to have one if possible. Anyone maybe some hints regarding this?
  19. I don't have much experience with CRE files, but I think there is some sort of "death variable" aka "script name" field (offset 0x280), that should be the same for all versions of same being (so to say). For all Kivans CREs you mentioned this field is "KIVAN". So I guess long, but most proper way, would be to check all CREs in game and patch if script name is "KIVAN". At least it seems like good starting point to me. *** Roughly something like this: COPY_EXISTING_REGEXP GLOB ~.+\.CRE~ ~override~ READ_ASCII DEATHVAR "dv" (32) NULL PATCH_IF (~%dv%~ STR_EQ ~KIVAN~) BEGIN // do things here END BUT_ONLY (Prepared based on: https://github.com/K4thos/IE-code-repository/blob/master/joinable_npc_array.tpa )
  20. That's interesting. I haven't known that, could be quite error prone. I also have some "typical language" habits and what I noticed is that with WeiDU it is often required to split things into smaller steps. In this case you would like to have maybe something like this: SPRINT parameter2 EVALUATE_BUFFER "%opcode%" LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2 END You can also switch order of parameters in function invocation but this not seems like good idea.
  21. Usual reasons to prefer functions over macros. Ofc this is not type of problem that blocks me from finishing my mod. It's just technical nuisance. Still, I'm curious if someone has some trick for that. That's pity. Technically it should be possible to have it resolved dynamically, since WeiDU arrays have dynamic size. But TBH I don't have good idea how syntax of this could look like to fit into general flavor. Maybe something like `RET_ARRAYS array` when "array" is arrays of array references to return. So WeiDU could iterate over this "array" and perform `RET_ARRAY` on each of them. *** Just for the record. Simplest solution for my example since arrays are statically defined in code would be: DEFINE_ACTION_FUNCTION test_function RET_ARRAY test_arrays test_1 test_2 // <- return all arrays here BEGIN ACTION_DEFINE_ASSOCIATIVE_ARRAY test_1 BEGIN abc => 123 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_2 BEGIN abc => 234 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_arrays BEGIN 1 => test_1 2 => test_2 END END LAF test_function RET_ARRAY test_arrays test_1 test_2 END // <- get all arrays there ACTION_PHP_EACH test_arrays AS key => value BEGIN PRINT ~%key%: %value%~ ACTION_PHP_EACH ~%value%~ AS key => value BEGIN PRINT ~%key%: %value%~ END END However, I was wondering for solution that would allow this for situation when we don't know all arrays upfront (e.g. when number of nested arrays is depending on state of overwrite directory etc). *** I think I came up with some workaround. It uses fact that RET_ARRAY works for arrays with composite keys. This way we can have macro to "box" array of arrays into one array with composite key and "unbox" macro to get our original array back. Here are macros: DEFINE_ACTION_MACRO BOX_ARRAY BEGIN ACTION_CLEAR_ARRAY ~%BOX_ARRAY%_box~ ACTION_PHP_EACH ~%BOX_ARRAY%~ AS key_0 => value_0 BEGIN ACTION_PHP_EACH ~%value_0%~ AS key_1 => value_1 BEGIN ACTION_DEFINE_ASSOCIATIVE_ARRAY ~%BOX_ARRAY%_box~ BEGIN ~%key_0%~, ~%value_0%~, ~%key_1%~ => ~%value_1%~ END END END END DEFINE_ACTION_MACRO UNBOX_ARRAY BEGIN ACTION_CLEAR_ARRAY ~%UNBOX_ARRAY%~ ACTION_PHP_EACH ~%UNBOX_ARRAY%_box~ AS key => _ BEGIN ACTION_CLEAR_ARRAY ~%key_1%~ ACTION_DEFINE_ASSOCIATIVE_ARRAY ~%UNBOX_ARRAY%~ BEGIN ~%key_0%~ => ~%key_1%~ END END ACTION_PHP_EACH ~%UNBOX_ARRAY%_box~ AS key => value BEGIN OUTER_SPRINT $~%key_1%~(~%key_2%~) ~%value%~ END END Here is example of usage: DEFINE_ACTION_FUNCTION test_function RET_ARRAY test_arrays_box BEGIN ACTION_DEFINE_ASSOCIATIVE_ARRAY test_1 BEGIN abc => 123 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_2 BEGIN abc => 234 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_arrays BEGIN 1 => test_1 2 => test_2 END OUTER_SPRINT BOX_ARRAY test_arrays LAM BOX_ARRAY END LAF test_function RET_ARRAY test_arrays_box END OUTER_SPRINT UNBOX_ARRAY test_arrays LAM UNBOX_ARRAY ACTION_PHP_EACH test_arrays AS key => value BEGIN PRINT ~%key%: %value%~ ACTION_PHP_EACH ~%value%~ AS key => value BEGIN PRINT ~%key%: %value%~ END END It produces desired output: 1: test_1 abc: 123 2: test_2 abc: 234 Still hoping for some "native" method. *** On a side note. I'm thinking about performance consequences of how WeiDU handles arrays. Passing array to function is done by reference, so it is super fast. In other words, when we pass array to function we pass only string that refers to it, without coping actual array content. However when function returns array, it is returned by value, so whole array is copied. Here is some nice practical consequence of it: However, I guess it can cause some performance problem when we pass and return big array back and forth. Something to keep in mind, but I haven't tested that closely. I just noticed recently that disk operation is not that big % of whole installation time and I started to pay attention to such things. Ofc this can only make difference for mods that do mass editing of game files.
  22. Unfortunately, array definitions and loops are correct here. Both this: ACTION_DEFINE_ASSOCIATIVE_ARRAY test_1 BEGIN abc => 123 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_2 BEGIN abc => 234 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_arrays BEGIN 1 => test_1 2 => test_2 END ACTION_PHP_EACH test_arrays AS key => value BEGIN PRINT ~%key%: %value%~ ACTION_PHP_EACH ~%value%~ AS key => value BEGIN PRINT ~%key%: %value%~ END END and this: DEFINE_ACTION_MACRO test_macro BEGIN ACTION_DEFINE_ASSOCIATIVE_ARRAY test_1 BEGIN abc => 123 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_2 BEGIN abc => 234 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_arrays BEGIN 1 => test_1 2 => test_2 END END LAM test_macro ACTION_PHP_EACH test_arrays AS key => value BEGIN PRINT ~%key%: %value%~ ACTION_PHP_EACH ~%value%~ AS key => value BEGIN PRINT ~%key%: %value%~ END END prints desired output: 1: test_1 abc: 123 2: test_2 abc: 234 The problem is that function scoping, which is super cool 99% of the time, here works against me.
  23. Year has passed and I'm already quite proficient with passing arrays to functions. Now I would you like to ask you about returning arrays from functions. But not simple arrays, those are easy to return with `RET_ARRAY` keyword. I'm wondering if there is good way to return array of arrays. Here is simple example: DEFINE_ACTION_FUNCTION test_function RET_ARRAY test_arrays BEGIN ACTION_DEFINE_ASSOCIATIVE_ARRAY test_1 BEGIN abc => 123 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_2 BEGIN abc => 234 END ACTION_DEFINE_ASSOCIATIVE_ARRAY test_arrays BEGIN 1 => test_1 2 => test_2 END END LAF test_function RET_ARRAY test_arrays END ACTION_PHP_EACH test_arrays AS key => value BEGIN PRINT ~%key%: %value%~ ACTION_PHP_EACH ~%value%~ AS key => value BEGIN PRINT ~%key%: %value%~ END END This only prints: 1: test_1 2: test_2 However desired output would be: 1: test_1 abc: 123 2: test_2 abc: 234 That is because test_1 and test_2 get cleared after function ends. In this exact example I could simply return also test_1 and test_2, but I'm looking for solution that would work when exact number of nested arrays is dynamic and not known upfront. Is there any way to accomplish that?
  24. Ah, I see. This time maybe not need it, but definitely good to know. And there is even option to join them with OR or NOR. I guess I owe our dear Infinity Engine a bit of apology.
  25. Good news for me. Another problem: opcodes that have condition built-in, like op209 (Death: Kill 60HP). I guess I would somehow need to apply my EFF with special condition "145_CURRENTHP<n". But it seems there is no opcode to apply EFF with special conditions. I could maybe apply protection agains my EFF right before applying it. But it turns out there is no condition like "CURRENTHP>n". I must say, this engine is crazy. *** I missed '>' in "144_CURRENTHP>=n". My bad.
×
×
  • Create New...