Well whaddya know?

Discussion in 'ToEE Toolset Project Documentation' started by Shiningted, Jul 2, 2005.

Remove all ads!
  1. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,740
    Likes Received:
    374
    Fact: You can have female characters with male models who still wear female clothes. Yup, guys in drag! Simply set the model to 100 but the sex to female (who'da thunk it would be that easy? Well ok, everyone ;) )

    Here's a butch Riana in a bicorne for some reason.
     

    Attached Files:

  2. Kalshane

    Kalshane Local Rules Geek

    Joined:
    Aug 6, 2004
    Messages:
    1,653
    Likes Received:
    4
    NPC Spellcasting

    It seems to me sorcerers are bugged where the strategy.tab is concerned. No matter what I put in, a sorcerer will keep casting the first spell in the strategy until all spell slots are spent.

    However, I did discover you can assign class_wizard spells to NPCs without wizard levels and the game will cast them normally. (Proper Save DC of 10+Spell Level+Intelligence Modifier+Applicable Feats.) However, it will act as though the caster had a caster level of 0 for things like duration and damage. (A fireball will only do 1 point of damage if the character doesn't have any Wizard levels.) For spells that don't have any level-based effects, however, this could be useful.

    The domain_special spells work better for things with level-dependant effects, as they seem to use the creature's HD as caster level. However, no matter what level you set the spell as, the game only requires 10+Wisdom modifier for the saving throw, which means these spells are going to be a lot easier to save against than they should be, especially if the creature in question has a low Wisdom (most spell-like abilities run off of Charisma, so such an ability is getting shorted twice.)
     
  3. krunch

    krunch moving on in life

    Joined:
    Aug 9, 2005
    Messages:
    3,280
    Likes Received:
    0
    ToEEWB: EDITING FACTIONS IN MOB FILES

    Factions can now be set and, or edited in MOB files, properly, in ToEEWB without causing a game session CTD. When you make a mob for a monster or a NPC, any and all factions associated with the monster or NPC from its prototype are completely removed by ToEEWB in the saved mob. Typically, what was done before was a modder would script monsters and, if needed, script the appropriate or desired factions.

    If a prototype has a monster or NPC listed as having a faction of 8 and you want to make a new mob for a map where the monster or the NPC will continue to have a faction of 8, plus you also want the monster or NPC to have an additional faction of 19, in ToEEWB you can add both the 8 and 19 as two factions for the monster or NPC. However, to do this in ToEEWB, you must add four separate entries for the two factions. You must add a trailing zero after each faction. In this example, you would add a faction of 8, add a trailing 0, add a faction of 19, and add a trailing 0. Treat adding a trailing zero as like entering a faction of zero, just remember that it is a trailing zero - not a faction. And, do not forget to save the changes.

    four entries in the factions list window in ToEEWB:
    8
    0
    19
    0
    Make the entries in that order, remembering a trailing zero follows each faction to make a monster or NPC have factions of 8 and 19.

    two entries in the factions list window in ToEEWB:
    0
    0
    Make the two zero entries, remembering a trailing zero follows the faction zero to make a monster or NPC have a faction of 0.

    Finally, you can also edit an existing mob for a monster or a NPC [with factions already set]. And, lastly, don't forget to save the changes.

    Note: Thnx, Agetian!..

    krunch

    [EDIT] Techically, the total faction data is 64-bits. The faction, itself, is 32-bit and is followed by a 32-bit zero trailer in the game code. Thus, when you make a new mob and add a faction to a monster or NPC in its mob using ToEEWB, you must add a 32-bit faction followed by a 32-bit zero trailer for the total faction data to be 64-bits that can be read and used by the game engine. If you do not add a following 32-bit zero trailer after the faction, the final result saved in a mob is a 32-bit faction that will cause the game engine to crash [CTD].
     
    Last edited: Jun 30, 2006
  4. krunch

    krunch moving on in life

    Joined:
    Aug 9, 2005
    Messages:
    3,280
    Likes Received:
    0
    When the ToEE game loads [the black screen loading portion just before it plays the opening cinematic showing what happened Zuggtmoy at Emridy Meadows], it checks all of the files in 'rules' folder. If you have even just one of the rules files located in the data\rules folder that is formated improperly, has an illegal character or something similarly wrong, the ToEE game will experience a crash to desktop [a CTD].
     
  5. Cerulean the Blue

    Cerulean the Blue Blue Meanie Veteran

    Joined:
    Apr 23, 2005
    Messages:
    1,962
    Likes Received:
    0
    The difference between game.party and pc.group_list()

    For a while I thought these two were interchangeable, but there is a slight difference. game.party is a list of all the characters in your party line up at the bottom of the screen. Thus game.party[0] is the first item on that list, which is the leftmost character in the party line up.

    pc.group() list is slightly different. It is a python function requires that pc be defined as a member of the party (game.party[x], or any call from a dialog that passes pc). It returns a list of all the characters in your party line up at the bottom of the screen plus anything that is an ai_follower to the party, such as summoned creatures, rebuked undead, charmed creatures, etc.

    As an example, lets look at a function in utilities.py called group_percent_hp.
    Code:
    def group_percent_hp( pc ):
    	percent = 0
    	cnt = 0
    	for obj in pc.group_list():
    		percent = percent + obj_percent_hp(obj)
    		cnt = cnt + 1
    	if (cnt == 0):
    		percent = 100
    	elif (percent < 0):
    		percent = 0
    	else:
    		percent = percent / cnt
    	return percent
    
    This function returns the percentage of total hp that the party has remaining. Notice that pc is passed to the function at the time it is called. It uses pc.group_list(), so it sums up the percentage of total hp of all the party members and all creatures attached to the party (i.e. summoned. charmed or rebuked creatures). If the line read
    Code:
    for obj in game.party:
    it would only return the percent of total hp for the party members in the line up at the bottom of the screen.


    Edit by Sitra Achara:
    I have found this to be inaccurate. At least, I've verified in one game with 5 PCs that summoning a monster does append it to game.party.

    If you want to exclude summons you should bulletproof it by:
    1. Checking with the leader_get() function e.g.:
    Code:
    attachee.leader_get() != OBJ_HANDLE_NULL()
    2. Specifically for summons and animal companions (but not for rebuked undead or charmed NPCs) - you can test with d20_query(Q_ExperienceExempt). e.g.

    Code:
    if attachee.d20_query(Q_ExperienceExempt):
    etc
     
    Last edited by a moderator: Sep 24, 2013
  6. krunch

    krunch moving on in life

    Joined:
    Aug 9, 2005
    Messages:
    3,280
    Likes Received:
    0
    ToEEWB: chest and barrel inventory containers

    In ToEEWB, for a new inventory container object on its Container tab page, there is a flag checkbox option for "inven. spawn once". Not selecting that option can cause issues with inventory objects not spawning correctly in a chest or barrel inventory. However, those same improperly spawned objects would all/each transfer to a characters inventory if you click the "Take All" button. It's strange, but true. Anyway, using the "inven. spawn once" flag stabilizes chest and barrel inventory when items, weapons, and armor are spawned in to a chest or a barrel inventory.

    To make a new locked chest, use these options.
    On the Objects tab page, click the New button and click Yes when prompted; click the Prototype dropdown button - scroll to and select the prototype chest object, type your X and Y coordinates in the two Location fields listed as X= and Y=, select Rotation and type a number. (can be 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, or 5.5 - circularly clockwise, 0 is up, 3 is down, 1.5 is to the right, and 4.5 is to the left). Use the tab scroll right arrow, scroll right and click the Container tab.
    Note: If you do NOT want to apply a rotation to a chest, then, do NOT click the Rotation option and leave that option to type a value greyed out.
    * On the Container tab page, use these options [for a locked chest].
    Select Lock DC and type a value [ = or > 15 for technical reasons], select Key ID and type a value; select flags; select Locked; and select inven. spawn once. Add items by using the Load Invensource button or by manually adding items. When done adding items, click the Save button.
    ** Don't be lazy! Determine what key you want to have open your new chest. Things like the Key ID of a Key to open a locked chest can be found by searching the protos, for example
    - Tools|Prototye Search > type "key" and click the Search Now button.
    Scroll the list of keys displayed, select a key and click the X close button. Scroll the Prototypes tab page and look for a field named Key ID. The value of Key ID is the number you will need to use for the "select Key ID and type a value" option, listed above in * On the container tab page,...

    To make a new barrel, use these options.
    On the Objects tab page, click the New button and click Yes when prompted; click the Prototype dropdown button - scroll to and select the prototype barrel object, type your X and Y coordinates in the two Location fields listed as X= and Y=. Use the tab scroll right arrow, scroll right and click the Container tab.
    Note: Barrels are round, circular in shape. You do not need to click the Rotation option; leave that option to type a value greyed out. (..unless you are very detailed like me)
    * On the Container tab page, use these options [for a barrel].
    Select flags; select inven. spawn once. Add items by using the Load Invensource button or by manually adding items. When done adding items, click the Save button.
    ** Barrels are not locked. Thus, the options to have Lock DC and Key ID are not needed, and as well, the Locked flag option is not needed, either. However, you will need to select the "inven. spawn once" flag.
     
    Last edited: Aug 14, 2006
  7. krunch

    krunch moving on in life

    Joined:
    Aug 9, 2005
    Messages:
    3,280
    Likes Received:
    0
    I have done a lot of testing with the AI Strategies from the strategy.tab file. One thing I noticed during testing of AI Strategies is that if a Spiritual Weapon spell is used, things like monsters changing targets and proceeding to use the next action of an AI Strategy can possibly be impacted or interrupted until the Spiritual Weapon is killed or vanishes from combat. In this case, the AI Strategy is, in effect, put on hold for the next change listed in an AI Strategy until the Spiritual Weapon is gone and, then, the AI Strategy continues as normally expected with the Spiritual Weapon gone from combat.
     
    Last edited: Aug 8, 2007
  8. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,740
    Likes Received:
    374
    The skill Survival is NOT accessed by:
    Code:
    pc.skill_level_get(npc, skill_survival)
    or anything similar but rather by a call to wilderness_lore, as follows:
    Code:
    obj.skill_level_get(skill_wilderness_lore)
    Thanks to Blue for pointing this out (its in Utilities.py), and may I say, STUPID GAME!

    EDIT: Along the same lines, the Sleight of Hand skill is accessed by:
    Code:
    obj.skill_level_get(skill_pick_pocket)
    Also, if you are changing daynight.nxd with ToEEWB, you will have to start a new game to see these changes take effect. Thanks to Allyx and Ag for this.
     
    Last edited: Aug 2, 2008
  9. Cerulean the Blue

    Cerulean the Blue Blue Meanie Veteran

    Joined:
    Apr 23, 2005
    Messages:
    1,962
    Likes Received:
    0
    The game.time Method

    Sitra asked if it was possible to access the time in the game from a Python script. Here is what I have found:


    These first five functions relate to game time in years, months, days, hours and minutes. They give you the same info you see when you hover your cursor over the little "Time of day" graphic at the bottom right corner of your game screen,

    game.time.time_game_in_days(game.time)
    Returns the day of the month of game time. There are 28 days per month, so this will run from 1 to 28, and then reset to 1 with the month being incremented. At game start this is 15.

    game.time.time_game_in_hours(game.time)
    Returns the hour of the day in game time. There are 24 hours per day, so this runs from 0 to 23 then resets to 0, with the day being incremented. At the game start this is 15.

    game.time.time_game_in_minutes(game.time)
    Returns the minute of the hour in game time. There are 60 minutes per hour, so this runs from 0 to 59 then resets to 0, with the hour being incremented. At game start this is 0.

    game.time.time_game_in_months(game.time)
    Returns the month of the year in game time. There are 13 months in the year, so this runs from 1 to 13 then resets to 1, with the year being incremented. At game start this is 4.

    game.time.time_game_in_years(game.time)
    Returns the year in game time. At game start this is 579.


    These next six functions return total elapsed time in the game.

    game.time.time_game_in_hours2(game.time)
    Returns total elapsed hours from the game start in game time + 2367.

    game.time.time_game_in_seconds(game.time)
    Returns total elapsed seconds from the game start in game time + 8521200 (2367 hours).

    game.time.time_game_in_seconds_float(game.time)
    Returns the same as the last one, only as a floating point decimal.

    game.time.time_game_in_seconds_elapsed(<int>)
    Returns the same yet again. Note that this one takes an int as the argument rather than game.time. It appears to return the same value no matter what the int is.

    game.time.time_in_game_in_days(game.time)
    Returns the total elapsed days from game start in game time + 98.

    game.time.time_in_game_in_seconds(game.time)
    The same as game.time.time_game_in_seconds(game.time).


    These last two I couldn't get to work.

    game.time.time_elapsed(<PyTimeStamp Object>)

    game.time.time_in_game(<PyTimeStamp Object>)
    I have know idea what PyTimeStamp Object they need, but it's not game.time like the others.


    Credit goes to Spellslinger for helping me figure out putting game.time as the arguement to most of these functions. I would never have figured it out without him. :)

    Please post questions, comments and discussion in this thread.


    Up Next: Using these to make long interval time events work, posted here.
     
    Last edited: Dec 28, 2006
  10. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,740
    Likes Received:
    374
    Interactive Objects and san_use

    This sent me insane on no less than 2 seperate occasions.

    To get an interactive scenery object (Eg Sitra's signpost) working with a san_use script (vile b*****d that it is) it appears to have to have a render height in its mob. A render height in the prototype alone doesn't do it, raising it up the z axis won't do it either. You have to actually lift it off the ground by setting a value in the '3d render height' box of ToEEWB when making the object.

    Exhaustively and painfully tested.
     
  11. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,740
    Likes Received:
    374
    I've gone back and changed a few things that are in error in here (we are bound to make some mistakes along the way, I know I have!) Would people maybe like to have a look at some of their contributions in this forum to make sure we are not perpetuating myths? I for one still use the info here, and I dare say future generations of modders will too.
     
  12. Gaear

    Gaear Bastard Maestro Administrator

    Joined:
    Apr 27, 2004
    Messages:
    11,038
    Likes Received:
    42
    SoundScheme files and their friends

    Supposed fact: the 'soundscheme' - or information about what music/fx plays on any particular map - appears to be retained in saved games. Thus, if you save a game, then modify a map's soundscheme file* to play different music or fx, the saved game will still heedlessly play whatever the scheme was when it was saved.

    This nearly drove me mad. My soundschemes for KotB simply wouldn't work. Every time I tried something new, the familiar strains of ToEE's main Hommlet tune would greet me when I expected to hear the KotB stuff. Worse, little tweety birds that I had not put into my own soundschemes would mockingly tweet away at my folly when I tested various maps. Even interior maps. The schemelist.mes and schemeindex.mes files were as right as they could be. So after having tweaked every little thing trying to get my soundschemes going (and I mean everything - even capitalizing the frigging file names) I had finally booked a one way airline ticket to Chicago, where I planned to jump off the Sears tower, having had no choice but to conclude that every assumption I had ever made about logic and the way of the world through my life experiences was somehow in error. Given this, I could not go on functioning like I had become accustomed to, and a swift death was easily the best answer to my disillusionment.

    Then I thought to test a new game instead of a save, and bingo-bango, I had a new lease on life! This is probably not an area that a lot of people fiddle in, but if this post saves even one other wayward soul from my own near-fate, it will be worth it.

    Why, Troika, why??? :shame:

    *this is actually the 'mapinfo.txt' file that can be found in a module's 'maps' folders.
     
    Last edited: May 23, 2007
  13. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,740
    Likes Received:
    374
    Here's a vile bug that has hit me from a couple of different directions.

    Say you have a dlg script:

    {1}{Hi.}{Hi.}{}{}{}{}
    {2}{Hello.}{}{1}{game.party_alignment == LAWFUL_GOOD}{10}{}
    {3}{G'day.}{}{1}{game.party_alignment = TRUE_NEUTRAL}{20}{}
    {4}{Piss off.}{}{1}{game.party_alignment == CHAOTIC_EVIL}{30}{}

    Now... let's say you totally stuff up one of the comparatives, as has happened in line 3 (i didn't put the '==' necessary to make this work).

    In a .py file, this will break the file and it won't compile, and you will realise there is a bug preeetty kwik and fix it. In a dlg file, it seems things are more complicated.

    What will happen (it appears) is the file will continue to work in the most superficial way - that is, you can still navigate around it, line by line. Quite possibly you will be able to have normal conversations, up to a point. The broken line won't show as an option but if u r not using that particular option (like a True Nuetral party here) u may never even realise.

    However, it seems the game will no longer reliably parse python stuff in the dlg file: thus, both comparatives and executables will not work. I say 'reliably' because its not like every single thing stops working: but some do, most definitely, some do. Probably there is some logic behind it, but I have not found it. What I have found is simply that simple scripts (both comparatives and executables) that inexplicably didn't work would start working if earlier bugs were fixed. Sounds common-sensical now, but was hours of hair-wrenching agony at the time.

    This also means (btw) that simply putting something nonsensical in the comparative section in the happy knowledge that it would stop it from appaering is NOT a good idea. For instance.

    {50}{Yes?}{Yes?}{}{}{}{}
    {51}{I have found the missing goblet!}{}{8}{when you find it}{400}{}

    is not a good idea. I had a few of those in KotB for future expansion - now I regret it :( I now use a call to flag 900 for all such moments.
     
  14. Shiningted

    Shiningted I changed this damn title, finally! Administrator

    Joined:
    Oct 23, 2004
    Messages:
    12,740
    Likes Received:
    374
    Portal Flags

    The Portal Flags: OPF_ETC

    Having extensively tested OPF_LOCKED and OPF_OPEN, I must report, sadly, that these do NOT reflect the current state of the door but rather, the state the door is designed to be in. Hence a door flagged OPF_LOCKED will always return a 1 for that flag (unless manually unflagged) even after the lock is picked and the door is opened. This persumably explains why and how doors re-lock themselves.

    It seriously reduces the effectiveness of san_unlock_attempt to distinguish between a genuine attempt to pick a lock or go through a door, and a passing PC who has bumped the door by mistake. :(

    Edit by Sitra Achara:

    I did find one use for OPF_OPEN - it makes the door see-through (and vice versa I think). The party will have to move to update the visibility though.
     
    Last edited by a moderator: Sep 24, 2013
  15. Gaear

    Gaear Bastard Maestro Administrator

    Joined:
    Apr 27, 2004
    Messages:
    11,038
    Likes Received:
    42
    /scatter audio effect

    ToEE doesn't like to play custom added ambient sound files (placed in data\sound\ambient) with the /scatter command applied to them, as referenced in schemelist.mes. Sometimes it will; most of the time it won't. Sometimes it won't even play stock ambient sound files with this command applied. Normally the /scatter command is used to distribute the sound effect across the sound field at varying volumes and ranges. You can achieve this effect manually by replacing the /scatter command with the following code to the appropriate line in schemelist.mes:

    Code:
    /BAL:0-100 /VOL:25-75
    This will 'scatter' the effect all the way left and right, with volumes ranging from fairly quiet to fairly loud. The best part is, it always works. :thumbsup:
     
Our Host!