As I learn to mod, I will put my questions in this thread so I dont make multiple threads. The WB tutorial is great, but outdated because of the new front end. Despite that I have learned how to make and activate my mods. My question now is how to add objects. Following the WB tutorial I am supposed to make an object that automatically gives me characters 3000 exp. However, when I log in game, I do not get the exp. I believe I followed the instructions word for word: Made new trigger prototype (with new # and description) Edited San_heartbeat from 240 to 400 (script #?) Moved new Protos and Description files to my mod Wrote the script for the 3000 exp and saved it in correct location as py00400give_level3.py Put the new object in the map folder (only MOD file) Make new TFM file with new name and place in root folder, Activate, Load Game, No EXP Is the object linked to trigger the script file? I am assuming that when I edited the objects script # from 240 to 400, it automatically knows to run the py00400give_level3.py file, is that correct?
Because you will ask, the script I copied and pasted from the tutorial. Posted below: Code: [COLOR="Lime"]from toee import * def san_heartbeat( attachee, triggerer ): for obj in game.obj_list_vicinity(attachee.location,OLC_PC): obj.award_experience(3000) attachee.destroy() return RUN_DEFAULT[/COLOR] And I ran into this line the tutorial: 41. Now, let’s write the script file itself. All scripts should go either to “C:/Mod/data.Tutorial/scr”, or to “C:/Mod/modules/Tutorial/scr” (the latter is better). Create one of these subfolders (the one in “modules” is preferable) and create a file inside, named like this: py00400give_level3.py I tried putting the file in both locations (but now the folders are named slightly different for the new front end).
You'll forgive me if I set it up with the 'code' command so we can see what is what. If you are saying you put it in Data/Scr then yeah, thats where it goes along with all the other .py files. But the parsing (or indentations) should look like this: Code: [COLOR="Lime"]from toee import * def san_heartbeat( attachee, triggerer ): for obj in game.obj_list_vicinity(attachee.location,OLC_PC): obj.award_experience(3000) attachee.destroy() return RUN_DEFAULT[/COLOR] As a rule of thumb, you want to do an additional indent after EVERY colon: always after a colon, never in any other circumstances. And only one indent (with the tab key), Python is really particular about that. Also, that script is far from bullet-proof. Of course Ag is only starting with something simple, but you would have to start directly next to the object to get this to work, since it will destroy itself at the end of the first heartbeat it fires. But it should certainly find something in the vicinity, so if you are starting your party next to your object at least someone should get 3000xp. Also, is the object marked in the first column as an obj_t_npc (an NPC) in the 14000s? Only NPCs get heartbeats.
Yes it is in the 14000's. I bet the indentions are the problem. I was putting the script into Wordpad and then changing the extension to .py Is there a better program so that the indention/formatting isn't lost when I change the file extension? Also, are you sure it goes in Data/Scr? Because the WB tutorial says the module/ToEE/Scr/ is preferable. I am having similiar problems with loading a npc/merchant. I can get the npc in my mod dressed the way I want, but they refuse to talk to me. Therefore the problem has to be my scripts/dialogue files. Which program do you use to write Python?
I use Notepad myself. Other people use Notepad++. The best way to do these things (imho) is to copy an existing file: this lets you see how things are set out and also helps prevent typos. Plus that way your file extensions stays the same. The first one that comes to my mind is the Tower Sentinel at the Temple back door, so copy py00121towersentinel.py and rename it to py00400givelevel3.py. Then open your newly renamed one in Notepad, and delete everything you don't want (in this case, everything that isn't in the san_heartbeat script). Then modify the existing san_heartbeat script, or copy-paste your new one. I would suggest just modifying it. It currently says: Code: def san_heartbeat( attachee, triggerer ): [color=orange]if (not game.combat_is_active()): if (not attachee.has_met(game.party[0])): if (is_better_to_talk(attachee,game.party[0])): if (not critter_is_unconscious(game.party[0])): if (anyone( game.party[0].group_list(), "has_follower", 8002 )): attachee.turn_towards(game.party[0]) game.party[0].begin_dialog( attachee, 70 ) else: attachee.turn_towards(game.party[0]) game.party[0].begin_dialog( attachee, 1 ) else: [/color] for obj in game.obj_list_vicinity(attachee.location,OLC_PC): [color=orange]if (is_safe_to_talk(attachee, obj)): if (anyone( obj.group_list(), "has_follower", 8002 )): attachee.turn_towards(obj) obj.begin_dialog( attachee, 70 ) else: attachee.turn_towards(obj) obj.begin_dialog( attachee, 1 )[/color] return RUN_DEFAULT So first up, delete all the orange stuff. This will leave you with your 'for obj in...' script and your RETURN at the end. Delete the indents so there is only one, then add your other couple lines and you're done EDIT: O and I don't know what modules/ToEE/scr does: certainly you want to put it in Data/Scr.
I was able to get the level 3 script working. Now I am unable to make my NPC talk to me and trader with me. Below are the Script and Dialogue files (per the WB Tutorial) do you see any looming errors? Script: py00401merchant_dialog.py Code: from toee import * def san_dialog( attachee, triggerer ): triggerer.begin_dialog( attachee, 1 ) return SKIP_DEFAULT Dialogue: 00401wandering_merchant.dlg Code: {1}{Greetings. Do you want to look at my wares?}{Greetings. Do you want to look at my wares?}{}{}{}{} {10}{B:}{}{1}{}{0}{pc.barter(npc)} {20}{E:}{}{1}{}{0}{}
That one's easy. You need to have the name of the py file and the dlg file match exactly, not just matching number (ie py00401merchant_dialog.py and 00401merchant_dialog.dlg). This one nearly drove me nuts when I was doing DH - I had py00291tenant.py and 00291tennant.dlg and couldn't for the life of me figure out why it wasn't working. Many wasted hours... :anger:
Thanks Ted. The WB Tutorial had the file names different so I just copied and pasted. I am thinking about re-writing the WB Tutorial (if it is ok with AG) because I am noticing a lot of errors with it (mostly b/c of the new Front End). I downloaded and read your tutorial PDF. There is a lot of great info in there so I will try to refer to that before I post questions.
General Modding Question: If I input the Rufus (or anyone) prototype .MOD file into a random location (say Nulb) and he dies, does that automatically change his global variable so he wont be in the tower after his death? Or would the mod just make a copy of him in the new location and the game does realize he is dead?
You'd have to contact Ag about rewriting the tutorial, but I am sure he is open to suggestions. EDIT: Eeek! Simultaneous post! Mobs exist independantly. Having 5 Rufus mobs is no different to having 5 Gnoll mobs in the moathouse: you can have one prototype and any number of mobs off it, though they all may run off the same single heartbeat (though it will effect them independantly. So if one achieves the 'attachee.destroy()' condition, it will only destroy that one mob, the others will keep going happily. Sounds complicated but you will get the hang of it quickly). So in the case you described, you could create a new Rufus mob (or even spawn him from the prototype) and anything you do to him will have nothing to do with the one in the Tower. This is one of the reason we have global flags: if you want the one in the Tower to react too, you set a global flag, then they only need to check one script to all react the same. EDIT2: Regarding the idae of 'copying' Rufus' mobs (if that is what you are saying) to Nulb, you have to copy everything attached to the mob too, so all his niventory as well. These are internally related (the parent mob's GUID, or 'globally unique ID' which I think is what it stands for, is written into the mob of the inventory item). If any are missing, the game will look for them, not find them, and crash. If you 'drag and drop' Rufus' mobs to Nulb, he will STILL turn up in the Tower because the game will still get his mobs from the .DAT files. You can't 'remove' anything fromt he original game, neither from the .DAT files or from the protos.tab. You can only do workarounds: for instance, if you wanted Rufus in Nulb, you would write a first heartbeat script to check if it is in the Tower: if so, destroy him. If not, destroy the script. Then stick him in Nulb. If he's in Nulb, fine, the script eradicates itself. If it fires in the Tower, it destroys Rufus and you never see him.
Thanks Ted. At least I know that what I am planning is feasible, but difficult. I hope I can impress everyone with this expansion someday.
Would the following be possible? Make a global event/variable affect an exsisting map location so that it would show new artwork when visited after the event? An example would be an earthquake that made the back route to the moathouse collapse and no longer usable. After the earthquake occurs, whenever the party goes to the backdoor location (from the world map or any other way) they see the cave caved-in and no way to get inside anymore. I would assume that the world map functions are hard wired and do not preform script checks concerning global variables (except if a location has been discovered by the party), and therefore the above situation is not possible... but you do know best.
Theoretically. Its something I've had in mind but never tried: Python excels at file-handling (BitTorrent software is written in Python) and you should be able to do it. Plus you could add effects. Eg one minute you see a church, next time you see a burnt shell, complete with smoke coming out. You CAN'T redo sectoring on the fly (the invisible marking-up of the map that lets you run here but not there) but if you redid the little door icon to expect such an event, you could switch it off, and it would be the same effect: you see a cave-in, the door is gone, everyone is happy Lest anyone wonder, you can't redo soundtracks either.
In regarding to the sectoring issue, cant you make the game think it is a completely new map? Granted the artwork would look very similar, but if we can make it load new artwork (ala the burning church) cant I make it load a new sector map? Thanks