Jump to content

osnola

Member
  • Posts

    96
  • Joined

  • Last visited

Posts posted by osnola

  1. If I remember correctly, I think I managed to kill them all one by one by playing a "fake pacifist" (helped by cryoas) in torment mode, detonating mines, before rushing to the exit, the cryoas blocking the way and using their passive frost ability to sometimes finish off a Sholai. But that was at the end of the game, I was very strong, and I got killed a lot, really a lot...

  2. 7 hours ago, xenogears said:

    It sounds like you were able to open up these scenarios in the editor. I'm curious how you managed it! When I try to open them, I get a password prompt.

    I use the new version of BOE https://github.com/calref/cboe which allows to import old scenarios ( without checking the password ) or rather a personal version which I modified a lot. But I believe (to be checked) that the editor of Blades of Avernum does the same thing.

     

    Just as a note, I also have a piece of code that allows me to retrieve the password of a scenario; I sometimes use it to reopen a scenario in the old editor and check that BOE didn't make a mistake when importing a scenario.

  3. Concerning Chains, I just looked at the scenario code:

    Quote

    I found Zankozzie and received his upgraded Piercing Crystal, which I assume is meant to be used on the red barrier in Fedoric's room,...

    normally the special at 53x62 in Over Harker looks at whether the Enhanced Crystal Piercing is dropped on the special barrier tile (53x62). So I guess you have to drop it there and then try to look at or use the special barrier tile to activate this special...

     

    Quote

    the password-protected painting in Linda's room (no clue)

    Spoiler

    Look for a clue in the same room

     

    Quote

    Vark will help me find Zephirius' disciple if I can find a piece of his clothing (where could that be?)

    Spoiler

    You must obtain the Tattered Robes which can be found in the Zephrius Room at Avondale Memorial.

     

    Quote

    * find Linda's contract (hoped it would be on or around her parents' graves in the Avendale memorial, but no such luck)

    * rumors of Linda passing through a wall in the northwest when wearing a special robe - found the building, but can't get in

    Normally, you will find the contract/special robe a little later.

     

    Quote

    * a coordinate-based portal in the southwest of town, which I obtained permission to use, but says there's "no reason to enter it" when I use it.

    You will need to use it much later.

    Spoiler

    It will be necessary to indicate the coordinates of a particular point: 8.6

     

  4. Hello, regarding Shadow of the Stranger, look for hidden passages in the two walls: normally when when you step on the 4x14 square a message is displayed the first time:

    Something seems strange about this passage.  You don't seem to be getting anywhere. 

    If you are in 4x14 and you pressed the hidden stalagmite button, there must be secret passages ( not sure, but I think you can go to safety W, N, NE, N, NE, NW, ... ).

     

    Note: If a click message appears, I think we have to start all over again: stalagmite, ...

  5. Hi, if my notes are correct, the replacement for Gov. Yvette is stored in the sdf(80,9) 3 means that Gov. Yvette is confirmed, 4 means that Gov. Yvette is replaced.

     

    Spoiler

    So if you type "gsdf 80 9" in the cheat box (hold down the Shift key and type 'd'), you can check the value of this flag. If you are adventurous, you can also type "sdf 80 9 4" to indicate that Gov. Yvette has been replaced.

     

  6. On 10/2/2022 at 5:25 AM, handle with air said:

    I agree with CM.  Having two separate interpretation engines is asking for trouble.  Compiling scripts down into nodes is going to be much more sustainable.

    The changes in this branch are more important, the game no longer knows the old format of special nodes(*). So writing a complicated assembler to produce nodes that would then have to be converted back into scripts seems like an inefficient idea...

     

    (*) there are two exceptions:

     

    • when a legacy scenario is loaded, all its special nodes are converted to scripts,
    • the code I just added in Scenario Editor to allow the user to use the old interface (slightly modified) to write code. But these intermediate nodes are converted back to script as soon as the user has modified them.

     

    On 10/1/2022 at 10:08 PM, Celtic Minstrel said:

    I don't think any amount of working with a scripting system (templates or whatever) will give something as nice as vanilla BoE uses. ...

     

    I'm not really sure about this, i.e. with a little modification of my current code, it would even be possible to present the user with the old interface that allows users to enter their code as nodes and modify them (hiding the fact that the game runs as scripts behind it). But I find that not hiding it allows :

     

    • novice users to code almost as before and then decide whether or not they want to start writing code directly,
    • to the others to work as they want, including through their favorite code editor (probably using from time to time the syntax checking tools I added and the mini editor to correct typos).
  7. Ok. Unfortunately there are another ending codes where my formula is one point off, for instance, when I look at the code qw2cabbdddpgcdm, my formula gives 1+(4: rebellion crush utterly), ie 'f' not 'g' :-~

     

    Spoiler

    If someone wants to test, here are the sdf I know:

     

    • sdf(7,18): answer to Miranda (1: crush utterly, 2: crush slowly, 3: do nothing)
    • sdf(80,9): governor Yvette (3: confirmed, 4: replaced)
    • sdf(80,11): governor Aato (3: confirmed, 4: replaced)

    Just press Shift+D to enter the cheat code mode and type SDF 80 9 3 to change the value of sdf(80,9) to 3, i.e. say that governor Yvette is confirmed

     

  8. 17 hours ago, TheUmbra said:

    Nicely done @osnola. It looks correct for me for letters 1, 3, 5 and 7 with my codes.

    Yes, I have seen that sometimes my formula for letter 9 was one off (that's why I added ... at the end the formula).

     

    It is possible that another term or others are added (maybe some action in High Litha). Or that the formula for governor replacement are more complicated, for example it could be :
    - if gov. Yvette not replaced: 0
    - if gov. Yvette replaced: 1 + ( if action1 performed: 1) + (if ... : 1) 

  9. I just did some more tests, here is what I found:

     

    • letter 1 (Nisse): c': discovered, d': a wish, life of comfort and leisure, e': a wish, life of power, ..., g': a wish, crown.
    • letter 5 (Sacramentum) : c' : no QW1 code, 'd' last answer to the reward : back to Sacramentum, 'e' last answer to the reward: ....
    • letter 7 (Queen's favor) : 'a' : very low, 'b' : low, 'c' : high, 'd' : very high
    • letter 9 (final status of Rokaj) : challenge not answered : 'a'

          otherwise, the formula looks like (with 'a'=0, 'b'=1', c='2', ...)

                 1 + (gov Yvette replaced:2) + (gov Aato replaced:2) + (Miranda's answer, 0=do nothing, 3=crush the rebellion slowly, 4=crush the rebellion completely)+ ...

     

    Concerning the letter 3, I didn't make much progress, a hypothesis could be that it corresponds to Slutter favour, in this case, 'a' : very-low, ..., 'd' : very-high and 'q' : insulted

     

    Next: I did some more tests. In fact, regarding the letter 9, the reputation with the Rokaj seems to play: if it is too low, no extra points are added when replacing governors. In one game I also got 1 extra point while confirming Governor Yvette but I don't understand why, so (gov Yvette replaced:2) should be replaced by (gov Yvette replaced:2 otherwise 0 or 1).

     

     

  10. Hello,
    I just tried to get several codes, here they are:

    1 cc bi cb ab ihtn
    2 cu bl co au alif
    3 ci br ce ap avjv
    4 ck ql ca ab aqif
    5 ce qh ce ap aovg
    6 cp qh cy aw auif
    7 cu qc cy aj antv
    8 cx qb cj ac ayai
    9 ce qa ci av admf
    10 ce bu cw ad afla
    11 cd bl cr af itra
    12 cr qr co at flnr
    13 cv bf ci aj jary
    14 cy qd cs ay idyl
    15 cs qo cd qc icai
    16 ch qx ca aj ivwc
    17 ci qt ce ab ibqh
    18 ct ql cd ay idpx
    19 cq qy cv al imxo

    In all these games, I have acquired a high favor on the Rokaj side and a low favor on the Haven side. 
    The code 1 corresponds to a game where I played a group in normal difficulty, the codes 2 to 19 a singleton in casual difficulty.
    For the codes 2 to 1O, I went out before accepting the challenge, the others, the challenge was accepted, ...
    Codes 4 to 7 correspond to the same game: I saved before the last dialog and gave the same answers; the same for codes 16-19.

     

    Looking at these results, I have the impression that:

     

    • letters 1,3,5,7,9 are important,
    • letters 2,4,6,8,10 seem random,
    • letters 11-12 are maybe used to store a checksum.

    Concerning the letter 3, I obtained 'b' except when I answered in the last dialogue, that there was another pretender to the throne 'q'.
    Concerning the letter 9, it seems to depend on the last choice with Miranda and if the challenge was done or not, I got :
    'a' (no challenge), 'f' (challenge, do nothing), 'i' (challenge, slow response to rebellion), 'j' (challenge, crush rebellion).

  11. On 9/8/2022 at 4:37 PM, osnola said:
    Quote

    It may be better to keep them around for compatibility reasons, if nothing else. Although, admittedly, pointers are not used in any extant scenario… but global text certainly is.

    I will try to find the time to do that...

    I just added some functions : see the end of  https://github.com/fosnola/cboe/blob/monsterCode/doc/HowToWriteSpecial.md .

     

    Note:

    - monsterCode is a temporary branch, I usually create such branch to test something before deciding to keep them or not; here as I play a singleton, at the same time in Queen's Wish 2, the only thing I test is if this branch compiles, ...

  12. Just for note, if we choose to have scripts and also add basic templates to help build pieces of code, for example, a template for "Stuff Done Flag", we can generate the script:

    //----start_template("Stuff Done Flag",7,5,1,4,-1,-1,6)----
    if (sdf(7,5)>=1)
        jump(4);
    jump(6);
    //----end_template("Stuff Done Flag",7,5,1,4,-1,-1,6)----

    then it will be enough to look if the player clicks in a template zone; in this case, we reopen the dialog which corresponds to "Stuff Done Flag" (verifying first if the intermediate code was modified or not).

  13. Quote

    It's not meant to be readable. It's meant to be interpreted by the game engine.

    It remains that even incredibly difficult to do. For example, if someone writes:

    [int] hidden_towns=get_list_towns(town:hidden);
    if (hidden_towns.empty())
        return();
    if (hidden_towns[0]<3) {
        [string] hints=["Hint1","Hint2","Hint3"];
        dialog_message(["You receive an hint about town "+to_string(hidden_towns[0]),hints[hidden_towns[0]]]);
        set_town_visibility(hidden_towns[0],true);
    }
    ...

    I'm not sure if it's worth the hassle to translate it and/or how to do it.

     

    Quote

    It may be better to keep them around for compatibility reasons, if nothing else. Although, admittedly, pointers are not used in any extant scenario… but global text certainly is.

    I will try to find the time to do that...

  14. Quote

    ?

     

    The special node syntax I designed was intended to evoke assembly languages. Compiling complex code down to an assembly language (technically, machine language) is a fairly normal thing to do. I think in theory, anything you write in your scripting language should be able to be reduced to a series of nodes (unless of course you've added new features that don't have corresponding node types). There are certainly some complications, such as variables, that might make that trickier, but I believe it should be doable, and it means both systems can sit side-by-side without needing two separate interpretation engines in the actual game.

    Yes, this is probably possible, but I'm afraid that without complex mechanisms to simplify the result, it will generate a lot of special nodes and the result will become totally unreadable.

     

    Quote

    By the way, does your scripting include the concept of "pointers" that I introduced in the node engine, or is that removed in favour of variables or something?

    I remove it in favour of variables because it is possible to write directly "jump(sdf(2,3)+4);", ... and define static variables of type int (or string, list of int, list of string) that are persistent. Ie. if necessary, it can be simulated with static scenario variables: s_int0, s_int1, ... that can be accessed anywhere (using scenario.s_int0 if you are not in the scenario context).

     

    I also did not implement the part about global strings as it is now possible to write:

    print_string(["The terrain name is "+get_terrain_name(get_special_terrain()),"The ..."]);

    and/or use string's variables to store/modify string.

     

    Notes:
    - if necessary, I can reimplement these mechanisms, but I'm not sure how often they are used but I fear that when they are, the code quickly becomes unreadable (ie. using static variables probably makes the code longer, but it can remain readable).

    - using a static list of int is probably better [int] s_params; then the code can be s_params=[2,4,5]; jump(8);  and in label8: if (s_params.empty()) do_A(); elif (s_params.size()==1) do_B(s_params[0]); ...

    - the right solution is probably to allow to define in the code new functions, it's possible but I didn't have the courage to implement it.

  15. Quote

    But in my mind, the point of the existing node system is the ease of use for people who aren't used to coding. A written scripting language presents a higher barrier to entry. The node system could certainly be improved, but I don't think replacing it with scripting is desirable for the most part.

    As for the complexity between the two methods, it's true that it's different; at the beginning, the special nodes mechanism is surely the easiest, but as soon as you want to do non-basic things, I'm not so sure (you have to create 5 or 6 specials to do this, ...). 

     

    The only thing I can really talk about is the readability of the result: when I search for something, and I find° :

    if (sdf(2,3)==3)
       jump(9);
    display_message([mess(3),mess(4)]);
    ...

    I quickly understand what it is about, I make a shift click on the mess(3) to see the message 3, then on 'jump(9)' to see the special with number 9.
    On the other hand, when I was doing the same thing with the old version of the editor, I was always a bit lost, I had to look at the type of the special, search in the list of parameters, those that are potentially important, ...

     

    ° in the mini editor of Scenario Editor that I added and that needs to be improved. For those who have a Mac and want to test, there is a compiled version of the special_code branch in https://github.com/fosnola/cboe-distrib/tree/main/MacOsXExperimental

     

    Notes:

    - I add some mechanisms to make the writing of code easier in the mini-editor : a button to check that the syntax of a code is ok, you can choose the enum, picture, sound as before or using a enum name button:no, pict:terrain, ... The functions can have default parameters. You can also click on the name of a function and see what it does (in broken English :-~ ).

    - The main remaining problem is that will have to work on the list of functions we want, their names, their arguments. I tried to do my best, but ...

     

    Quote

    That said, I don't think it's bad to have scripting as an option; in particular, if you actually compile the scripts down to my existing special node syntax, then scripting could exist as a design-time auxiliary tool.

     

    Even ignoring the fact that I added a lot of functions, converting a script to special nodes doesn't make much sense in my opinion, scripts allow to write code in a too flexible way.

     

    What may be feasible, is to propose to users to automatically write code snippets by calling the old interface, i.e. clicking on a "Generic Starway" button, ... which displays the old dialog, ..., and ends up inserting the corresponding code at the current location .

     

    Quote

    (Scripting also makes it more difficult to create a tool that will list references to an SDF or special node.)

     To find the sdf, the calls to the special, yes it's true that it's more complicated to write ( even if I've already created a function that checks the existence of the calls of specials that are in the scripts : check_unavailable_codes ).

  16. 10 hours ago, Celtic Minstrel said:

    Doesn't this kinda defeat the point of the special node system…?

    This replaces it with something more powerful, that is, 

     

    • if I'm not mistaken, you can do at least the same things as with the old and new special node system,
    • you can code complex things in one block (instead of having to write k small specials)
    • I try to add some new functions° and it is relatively easier to add a new one,

    a similar change that appears in Blades of Avernum except that Jeff does this for all specials while in my code there are still a few integers for terrain/objects/monsters that remain and mean calling a local/global special.

     

    Quote

    I gather that you consider it useful for determining where SDFs are used, which is actually another good enhancement to add, but we were talking about where special nodes are called.

    Oops, using scripts helps a bit, i.e. I usually open in an editor the town/outdoor .code file, then look for "jump(8)" if I want to know where the special 8 is called. I also use the "<special ..." command in the town/outdoor xml files. But of course, that doesn't solve all cases. 
    To summarize, adding a function to do this, is indeed a good idea.

     

    ° I try to maintain in bad english (ie. frenglish) a small doc https://github.com/fosnola/cboe/blob/special_code/doc/HowToWriteSpecial.md  .

  17. Hi, just for information,
    I have a special branch of cboe : https://github.com/fosnola/cboe/tree/special_code ° where I replaced the old methods to define specials by scripts¹. It allows to load an old scenario, then you can save it in "my" new format, unzip the scenario and look for the "sdf(...)" strings. I often use this method when I test an unknown scenario and I'm stuck ( even if there are some sdfs that are stored elsewhere : sdf to set to 1 when a creature dies, ... )  

     

    Note:

    ° I work on Mac, so it must be easily compilable on OsX ; for other platforms, it will be necessary to rework the platform projects :-~
    ¹ You should not use it to create new scenarios.

     

    For instance, a few lines taken from grep -r "sdf(" valleydy

    ./out/out0~2.code:if (!once_set_sdf(206,4)) return();
    ./out/out0~2.code:if(i0==0) sdf(206,4)=0;
    ./out/out0~2.code:if (!once_set_sdf(206,5)) return();
    ./out/out0~2.code:if (!once_set_sdf(206,6)) return();
    ./out/out0~2.code:      sdf(206,6)=0;
    ./out/out0~2.code:if (!once_set_sdf(206,7)) return();
    ./out/out0~2.code:      sdf(206,7)=0;
    ./scenario.code:if(sdf(2,5)==1) jump(1);
    ./scenario.code:if (!once_set_sdf(100,6)) return();
    ./personalities/talk4.xml:                <![CDATA[int res=buy_sdf(500,4,2,1);
    ./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
    ./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
    ./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
    ./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
    ./personalities/talk2.xml:                <![CDATA[select_talk_msg(sdf(2,3)<=0);
    ./personalities/talk3.xml:                <![CDATA[select_talk_msg(sdf(3,2)<=0);
    ./personalities/talk3.xml:                <![CDATA[select_talk_msg(sdf(3,2)<=0);
    ./personalities/talk3.xml:                <![CDATA[select_talk_msg(sdf(3,2)<=0);
    ./towns/town8.code:if (!once_set_sdf(8,0)) return();
    ./towns/town8.code:if (!once_set_sdf(8,1)) return();
    ./towns/town8.code:if (!once_set_sdf(8,2)) return();
    ./towns/town8.code:if (!once_set_sdf(8,3)) return();
    ./towns/town8.code:if (!once_set_sdf(8,4)) return();
    ./towns/town8.code:if(i0==0) sdf(8,4)=0;

     

  18. Hello, in old games, strings are stored in a complicated way (together with other data: city maps, ...), which makes modifications complicated. In more recent games, they are rather stored in separate text's files which allows to translate them more easily (provided that you limit yourself to languages which use basic roman characters, no accented letters, ...)

     

    I just downloaded an old demo of Nethergate, I have the impression that it is the first method that is used ; I could be wrong, but I have the impression that for this game, a hexadecimal editor will be necessary (as well as a minimum understanding of the format of the data files).

     

  19. Hello,
    concerning Blades Of Exile, the project Classic Blades of Exile https://github.com/calref/cboe allows to dump all the text of a scenario in a file. 
    Regarding doing a translation, it is possible to use the BoE scenario editor to translate the text of a scenario (or to unzip/untar the new scenario format and edit the text files directly) ; there remain two/three main problems ( that I have tried to fix in my fork which diverged strongly 😒, in the floor branch )

    • the code uses basic strings, so if you need to use non-ascii characters : à, é, è, ñ, ... 😒
    • there are a lot of strings that are hard-coded in the code; so without changing the code, it is not possible to translate them,
    • the provided fonts allow to display only some basic characters, most of them western characters ( I haven't solved this problem, but it seems possible to replace the provided fonts with others ).
  20. Hello, in Blades of Exile, strength seems mainly used to bash a door and define the maximum weight you can carry, while dexterity is used for many things.

     

    The weapon skill is used to choose which pc skill to use to calculate the probability of hitting a monster:

    int skill;
    if(weap.weap_type == eSkill::INVALID)
    	skill = attacker.skill(eSkill::EDGED_WEAPONS);
    	...
    else skill = attacker.skill(weap.weap_type);
    
    int r1 = get_ran(1,1,100) + hit_adj - 5 * weap.bonus;
    	r1 += 5 * (attacker.status[eStatus::WEBS] / 3);
    ...
    
    if (r1 <= hit_chance[skill]) {
        // do damage
    }

     

    Luck is used to escape death:

    if (... && luck > 0 && get_ran(1,1,100) < hit_chance[luck]) {
            add_string_to_buf("  But you luck out!");
    		which_pc.cur_health = 0;
    }

    but also to disarm a trap (but not lock picking) and to define the probability of finding objects/treasure.

     

  21. Hi, I finished a lot of scenarios with the version I modified; the graphics need to be rejuvenated, but otherwise I find the game stable and playable (maybe because I got used to the remaining defects). 

     

    After that I would advise to recompile a version from my sources or to integrate some of my commits, because I corrected several problems ( some very annoying )...

×
×
  • Create New...