Jump to content

Walker White

Member
  • Posts

    89
  • Joined

  • Last visited

    Never

Everything posted by Walker White

  1. Quote: Originally written by Newtfeet: "Public" means about the same thing as "known by the interpreter". If you are a Microsoft programmer "not public" means "it is there and usable by anyone, but Microsoft won't tell me what it is so their Office programs can be better than mine." That's why I assumed that interpretation. I didn't mean any insult by it.
  2. Quote: Originally written by spyderbytes: I mean, if all food has the same value for 'variety', he's bound to have some way to query inventory by variety, I would think. It's likely just not public. It's more than not just public; it is not in the scripting language. He has functions in his engine for doing it. Those are C++ calls. The way scripts work, however, is part of the engine reads in the script text file (the thing doing the reader is called the interpreter) and converts it to C++ calls. If the interpreter does not know to translate calls about item variety into the existing C++ calls, then you can never use them in a script, whether you know their name or not. This is the big deal in the "Calls We Wish Existed Thread". If those calls already exist in C++ form in the engine, it is very easy for him to add them to AvernumScript; he could do it in a few minutes. If they don't, it is much harder to add them, and not necessarily advisable to do so, as it could break the engine. It's like the difference between needing a word in French for which the language translator does not know the correct word, and when there is no such word in French at all.
  3. Quote: Originally written by Newtfeet: Ok, so let me set this all out. clear: Obvious. Sets all the values for the object currently being edited to their defaults. property = new_value: Also obvious. Sets the value "property" to "new_value" for the object currently being edited. import = which_object: Replaces all the values for the object currently being edited to the values for "which_object". If "which_object" was already edited in this same script, it imports that. If it hasn't been, it imports from the core data. begindefine{object} which_object: Sets the object currently being edited to "which_object". Copies the data from the object that was edited before this statement over the data of "which_object". Is that right? Yes.
  4. Quote: Originally written by Newtfeet: Remind me why we have those "begindefineitem 450" and "import = 450" lines in there. Edit: And crap, I double posted and the first post is complete nonsense. Simple. I copied Bread into slot 450 which is the first empty item slot. I then cleared slot 4 (you can redefine ANY item slot you want) so that I could alter it. I loaded in all the data for Bread (which is now in slot 450) and added the extra definition to give it a special class. Rinse, lather, repeat. You cannot just say begindefineitem 4 as that will erase all the old Bread information. And I did not want to leave Bread as item 450, as then I would have two different types of Bread.
  5. Quote: Originally written by Newtfeet: What is that begindefinecreature bit in there? What does that have to do with items? Heh. The danger of not reading before I post. This was a mistake and I editted while you posted. I copied the example from the Chitrach level bump in VoDT (which is creature, not item). I forgot to make definecreature as defineitem everywhere.
  6. It won't be a problem if Jeff is a good programming language designer and does not eliminate the old API, just adding new ones. We will be fine. It may affect the scenario design contest. But then, by waiting until the Windows one is done, he will probably level the playing field a bit there.
  7. Quote: Originally written by spyderbytes: Obviously, the option should only come up in dialog if someone in the party actually has a food item. But I don't care WHAT particular food item (fish, bread, steak, whatever) it might be. So... do I have to check for each food item the party MIGHT have individually (until I find one or work through every possible food item), or is there an easy way? -spdyerbytes You will have to change food and give it a special class (say 0). To do this, in your scenario data file, do things like this Code: // Give Bread special class 0begindefineitem 450; import = 4;begindefineitem 4; import = 450; it_special_class = 0;// Give Mushrooms special class 0begindefineitem 450; import = 5;begindefineitem 5; import = 450; it_special_class = 0; and so on. If you do this for all the foods, you can use the item_of_class functions everywhere to query for food. Edit: Newtfeet beat me to the post.
  8. Quote: Originally written by wizardr6: Quote: Walker White: It would be nice, however, to have !x available for making x = 1 if 0 and 0 if anything else. Right now that requires an if-branch. Or you could do: x = 1 - x Shorts can be negative. So if x = 2, x = 1 - x makes -1, not 0.
  9. Quote: Originally written by wizardr6: Maybe the error is from a missing parenthesis? There should be a ")" before the "<=2". Oh. That's a typo in the post. It's okay in the actual script (which is actually more complicated. Compare if (who_hit_me() >= 0 && dist_to_char(who_hit_me() <= 2)) { which has problems with if (who_hit_me() >= 0) { if (dist_to_char(who_hit_me() <= 2)) { which works. I have tested the function. It's a short-circuit issue.
  10. Quote: Originally written by Newtfeet: Even with those, I'm not sure if scripting a outdoor combat town would work. You are right. I just tried it on the original, and nothing. Oh well, so much for that idea.
  11. Thought of two more: item_uses_in_slot(short which_char, short which_slot); and item_uses_on_loc(short loc_x, short loc_y). Returns the number of charges of the requisite specific item (not an item type). alter_item_uses_in_slot(short which_char, short which_slot, short amount); and alter_item_uses_on_loc(short loc_x, short loc_y, short amount). Recharges or drains item. EDIT: I just realized that there can be multiple items on a space. So only the item_uses_in_slot() [there can only be one wand in a slot] will work for these calls. The location ones are right out.
  12. Quote: Originally written by spyderbytes: You wouldn't need AoE spells to have what (to me) would be correct behavior for this call. Seems to me it would just be a check with the pathfinding algorithm to see if the path from the damager's current loc to the loc in question is range squares or less. The simplest solution is probably just to use the can_see calls for area effect attacks. If you cannot see the square, then some terrain is blocking it. This differs from the pathfinding as it would allow stuff to go through windows (which is probably a desirable effect).
  13. To anyone who knows: If I copy Blades of Avernum Out Fight and stick it into my scenario folder, will it use the copy or the original in the Files folder for the random encounter towns? Initial experimentation suggest that the original is loaded and the copy is ignored. However, I just want to be sure. In a nutshell, it would be nice to script the outdoor encounter towns without replacing the original Out Fight (which would script all scenarios: Bad!).
  14. One more thing. To make it a little more efficient, you want to write (now that I know the UBB for code) Code: beginstate 31;if (char_on_loc(19,36) >= 0 && char_on_loc(19,36) <= 3) { print_str("You are standing on the mat.");} else { print_str("You are not standing on the mat.");}break;
  15. Quote: Originally written by Drakefyre: For creature AI scripts - several calls that would be able to control where the creature moves, get the next move of the creature, tell it to acquire a next move randomly, etc. It's possible now, but only with horrible, horrible workarounds. What are you asking for here? Are you wanting the creature script to be called in the middle of movement and tell you the next square in the path computed by the path-finding algorithm? Or is it something else? Because the former would be really expensive. Quote: Also, the ability to block a space only to one character or group. That will almost certainly break the path-finding algorithms; badly. Yeah, it would be great, but I doubt we will ever see that.
  16. Quote: Originally written by Drakefyre: Well, it's not hard to fake the not operator with excessive use of DeMorgan's laws. True. I was thinking that you cannot do it in unary instances such as !char_ok(x), but I guess in all those cases you just do (char_ok(x) == FALSE). So maybe that's not too bad. It would be nice, however, to have !x available for making x = 1 if 0 and 0 if anything else. Right now that requires an if-branch.
  17. Quote: Originally written by Tentacle Monster: This script does nothing: beginstate 31; if(char_on_spot(19,36) == 0 || char_on_spot(19,36) == 1 || char_on_spot(19,36) == 2 || char_on_spot(19,36) == 3){ print_str("You are standing on the mat."); } else{ print_str("You are not standing on the mat."); } break; ---- If I'm merely making some stupid syntax error, then please alert me. It is a good idea to check out the tech support page page, as I and others have been sending all these issues to Jeff. This is a bad documentation bug. There are two functions, each of which is poorly documented: char_on_spot() and char_on_loc(). The function char_on_spot() is NPC only. You are clearly checking for player characters here. Change it to char_on_loc().
  18. Quote: Originally written by Snuff ling kin: As for maths, I find it totally unrelated to my scripting ability. Depends on what you want to do. A lot of simple scripts can be written without much math. However, much more complicated scripts like ones I have been doing in the Monsters thread do have quite a bit of math, such as probability and modular arithmetic.
  19. Quote: Originally written by Newtfeet: There is a set_creature_memory_cell() call; page 25 of the appendices. Well I'll be. Okay, that's one off the list. I swear, sometimes I cannot find these calls in the documentation (this is the second time this forum has shown me wrong). Does anyone else find the organization weird?
  20. Quote: Originally written by Drakefyre: I was planning on doing some of this (like the bodyguards and an adapted magekiller script), but you've beaten me to it. Now I'll have to work on something that you won't get to for a while. I'm thinking of working on a creature script that binds a monster to a certain type of terrain (ie fish in the water, birds in the sky, etc.). Then I will lay off that idea (but to be honest, I had not thought of it). My plans for the next few scripts after familiars are: A spawning pool that uses very complex messaging to control all its creatures as slaves (it does coordinated target acquisition and sends the creatures there). This will use a combination of tricks from my target acquisition and familiar examples. A bunch of interesting mirror terrains like a mirror of life trapping, and a mirror of opposition (if Jeff fixes give_char_item() so I can duplicate party items). You should be safe for a while.
  21. As I continue to play with AvernumScript, I find issues that I lump into three categories: (1) Bugs that need to be fixed, (2) Calls that I wish existed because I cannot fake, and (3) Things that don't work like I thought and need to be better documented. There are formal channels for (1), and Kelandon has created a thread for (2). This thread is for (3), the type of things that appear on the tech support page . That page is a stopgap for the really extreme problems. This thread is for people to post things they do not legitimately understand about the system and may need to appear in later documentation. Here is something to get us started. Boolean expressions in AvernumScript do not seem to short circuit. To see what I mean by this, consider the line of code if (who_hit_me() >= 0 && dist_to_char(who_hit_me() <= 2) { This checks if we were hits and that the offender is close (not an archer). In most programming languages, if who_hit_me() is negative, the script will not bother with the dist_to_char() call. One part is false, so the whole thing must be false. Not true in AvernumScript. If will make both calls. So if no one hit you, you will get an error here (because dist_to_char(-1) is bad). It also means that long complicated boolean expressions are inefficient. Is this a bug for Jeff to fix? Absolutely not. It was a reasonable design decision on his behalf. But this is something we need to be aware when writing scripts.
  22. Oh dear Lord. Where do I begin? Okay, here is a list, some of which I have already sent to Jeff. The Easy Ones (If Jeff did what I think he did) deduct_char_ap(short which_char, short amount) so items can manually deduct AP (and fix the 219 feature). equip_item_in_slot(short which_char, short which_item, short which_slot), so I can manually equip items in my creatures. set_char_memory_cell(short which_char, short which_cell). This would greatly improve message communication. We can already do this for terrain, why not characters? Missile animations for SFX. We can do booms and sparkles and effects. Why not missiles? A call to manually identify an item so that I am not forced to use shops. ]The Hard Ones (I am dreaming) Get calls for every item ability (what's its damage, type, etc...) Get calls for determining a creature's special attacks. Path finding calls: Is there a path on the ground from A to B? Compute this without actually moving a character. A dialog box for numeric input. Dear lord what I could do with this (I cast clairvoyance on square x=13, y =2). There is also the issue of string handling (being able to glue strings together and then like for better print_str() output). I have made some suggestions to Jeff about this, and he is thinking about it. However, my suggestion on strings is a major overhaul and if we pressure him to do a lot of calls, it will not happen.
  23. Quote: Originally written by Boots: Am I right that, were it possible to call deduct_ap from scripts other than creature scripts, the absence of AP cost for ability 219 wouldn't be as serious? Not that I'd know whether such a change would be less invasive for JV to make than adding a fixed AP cost to the ability, but presumably certain designers might prefer to have the freedom to vary the cost. That is correct. I cannot imagine that is too difficult to add to the language, but he would have to call deduct_ap() something else. He does not want to erase the old call (for compatibility), and he needs a way for his interpreter to recognize the right calls as they will have a different number of arguments. However, this all depends on how difficult it is to add functions to AvernumScript in general. If he has a proper symbol look-up table, it shouldn't be too hard, but then I don't know how he chose to design this. There are other modifications I would like made to AvernumScript like unary minus and the not operator (!) that are much harder and I doubt those will be added.
  24. A Bonus Script: Mind Duel The last script this week doesn't really have all that much to do with targetting, but it is another really neat example, so I wanted to post it. This example is motivated by Avernum 2, specifically what it was lacking. Those of us who played Exile 2 where really let down by the final battle. Garzahd is a demon, oh my. Not a big deal when it is easy to give all 4 characters level 3 repel spirit. If you want a real battle with Garzahd, try Exile 2. You all know what I mean. I present the return of Mind Duel to Avernum. Making Mind Duel characters is really easy; we just use ideas from the magekiller scripts. That is what I have done in minddueler.txt . What is much more interesting, however, is giving that ability to the party. To do this, we have to use a custom item. Aesthetically, I would prefer a custom ability, but custom abilities cannot target foes. Fortunately, items can using special abilities 219 and 220. In my script for battle arena I present the code for a mind duel item. It works pretty well and utilizes a d20 style willpower versus willpower check. And I stole the idea for demonic corruption from the Conan d20 RPG. There are a couple of issues with this script however arising from limitations in AvernumScript. Some of these I feel are bugs (but then Jeff is probably starting to get tired of by bug reports). There is no get_energy() function. This is one of the greatest oversights in all of AvernumScript. This means I cannot prevent the character from draining creatures with no energy points! I hope Jeff adds this function. In the meantime, the script does at least keep the character from draining non-spell casters. Weapons of ability 219 cost no AP to use. So you can use them as many times as you want. I stop this (inelegantly) by putting in a flag that is reset each turn. This may be a feature and not a bug (to make items with multiple targets), but it seems strange to me. There is no unary negation in AvernumScript. Try y = -x in AvernumScript. It won't work. Instead, you have to fake negation by subtracting from 0 as in y = 0 - x. If Jeff ever adds get_energy(), we will be able to do a lot more with this. For example, we can make real Exile 2 style Garzahds (immune to everything, but die when all energy points are drained). If you want to play with the mindduel, I have yet another one room scenario set up for it. Pick up the orb and try it out. Well that's this week. Depending on work or so, I may be back in a week with my next topic. Next Week(ish): Familiars and Pets. I will also show you how to make leashes and dog whistles to have the pets do cool tricks. The stuff I plan to do will also indirectly answer Boot's question at the beginning of this thread.
  25. Back to Basics: Bodyguards These scripts got really complicated, and it was clear that if I continued along this track, I wasn't going to really add anything useful to the script community. So what I really needed was other ways for us to choose targets, beyond just assessment of strength. One obvious way that jumps out is to have characters choose targets for each other. Your characters act as a party, why can't the hostiles? All we need is a way for the monsters to talk to each. And we have that. It is called messaging. To illustrate a simple messaging example, I have two scripts. guardednpc.txt . This is an important NPC like an official that is surrounded by guards. When he is hit, he calls out to the guards to strike down the offender. bodyguard.txt . This is a guard for the guardednpc that chooses targets based on messages sent to it. Clearly, we can do much more complicated set ups than this. However, as the last example demonstrates, it is best to keep these scripts simple when we can. At first glance, the scripts seem to be very simple. When the guardednpc is hit, it sends the character number of the creature that hit it as a message. When the guards receive the message, they make that their target. But there are some things to worry about. The first issue is that messaging is quite primitive. All you can do it send and receive a number. The receiver cannot even ask who sent the message. In fact, as terrains or even items can send messages, it does not make sense to ask who sent a message. So, we have to make sure everyone is in the same group and we only send messages in the group. There is currently no way in the editor to set groups (this is a script function). So to make it easier on the non-programmer, we use memory cell 4 to store the group and initialize this value in the INITIAL_STATE. That way we don't send messages to people who are not guarding the guardednpc, and any message the bodyguards receive they will assume is a cry for help. This means, however, that you have to be careful when you start mixing creatures that use messages. They may start to read each others messages and get confused. To avoid this, always send messages to groups, and avoid using the broadcast functions (which send to everyone). Sometimes this cannot be helped, but it is generally good practice. Next, notice that we have to be prepared to receive messages in any state other than the initial and dead one. If we are in a state that does not receive messages, then the message that round is lost forever. This also means that we need to avoid the set_state_continue() that I am always using. set_state_continue() changes state without deleting the message, while set_state() deletes it (because it exits the script). So set_state_continue would cause us to restart the message response process and put us in an infinite loop. Using set_state() is okay; if the monster has AP, it will call the script back up again. It is just less efficient as it stops the script and then starts it back up. Finally, there is one more issue addressed in this script. If the guardednpc keeps getting hit (the bodyguards aren't doing a very good job) he may keep shouting out different targets to the bodyguards. This would cause the bodyguards to hop about doing damage to a lot of targets and not killing anyone. Maybe you want this behaviour. In case you do not, in cell 5 of the bodyguard, we set a tolerance value. This determines whether a bodyguard will respond to additional target requests beyond the first. Again, the documentation is in the comments. Finally, as a homework exercise, I assign the following. Add a message to the DEAD_STATE of guardednpc so that it can let the guards know it died. Then have the guards do something in response.
×
×
  • Create New...