Jump to content

Krizmn's Questions and Discussions on Avernum Script


krizmn

Recommended Posts

So I will introduce myself. This will be simple and short. I am in my early thirties now and I want to work on a project. I have past experiences with programming, game design, and psuedo-stuff to put it.

 

I am probably one of the many who have attempted to come on board these forums and try to start an epic scenario. If I fail great, if I succeed great. I just want to work on something. So anyways, I will post more in the future about the scenario I am working on.

 

I am new to the Avernum script and it's frustrating that most links and examples on this website are shutdown, abandoned, or forgotten. So if anyone is bored or wants to help, I will be posting simple questions and discussions about the script. :-)

 

 

Feel free to reply!

Link to comment
Share on other sites

My first official question is about combat and hitting a target

Is there any calls through npc scripts or item scripts to check if you hit a target? Pretty much I want an NPC to "do something" to a PC when it strikes them.

 

I am was checking wiki, an didn't see much. I found something where you can check if the NPC got hit.

 

Example: When it is the wyvern's turn to attack, it chooses to pick up a player and moves them to a location.

 

Example: When a whip hits an enemy, it takes away X amount of AP.

Link to comment
Share on other sites

Yeah... so as you discovered, you can see if an NPC has been hit, and by which character. Using that information, you can then use other calls to end combat turns, relocate characters, and so on. Using "char_has_item_of_class_equip" (and setting certain weapons to be certain classes) you can even have it so that hits from particular weapon types have their own responses.

 

I honestly kind of feel like you've largely answered your own question though. :p

Link to comment
Share on other sites

Yeah... so as you discovered, you can see if an NPC has been hit, and by which character.

 

They also want to do the opposite: check to see if a PC has been hit by a specific NPC, and call a scripted response to that -- for example, inflicting a deleterious effect that can't normally be set as a creature's ability. As far as I know, there isn't really an easy way to do that -- the best solution might be to bypass the ordinary combat engine entirely for that attack and put the logic of the entire attack, including to-hit, damage and additional effects, into the creature script.

Link to comment
Share on other sites

Yeah, I thought that's what was being asked at first, but OP starts by asking if there's 'any calls through npc scripts or item scripts to check if you hit a target?'

 

Anyway, in that case it;s possible using creature scripts, and you don't need to do anything too complicated; adding code to the attacking state of a creature script will let you do things like steal gold, inflict status effects, cause knockback and so on. Here's a snippet of code from TM's Echoes: Renegade that has an NPC stealing gold when it hits (all comments are my own):

 


trgt = (get_target()); //set the variable 'trgt' to whichever PC the monster is attacking
start_hp = get_health(trgt); //The next three lines determines if the NPC/enemy hits by checking that health has been lost.
do_attack();
end_hp = get_health(trgt);
if(start_hp > end_hp) { //if I've hit them (and I know because their HP has decreased since I called do_attack()) lets try and steal!
    steal_amt = (start_hp - end_hp); //sets the amount to steal to the amount of lost HP
    atktyp = get_ran(1,0,11); //sets the variable atktyp to a random number between 0 and 1
    if((atktyp >= 0) && (atktyp <= 4)) { //if that random number is between 0 and 4, do the next things...
         if(coins_amount() == 0) { //first, check to see if they have money. if the party has no money, then we can't take any...
              atktyp = (get_ran(1,5,11); //..and so we should set the random number to something else so that we can try to do other things with it later
         } else { //if they do have coin and get_ran turned up a number low enough, they next few lines remove gold from the party
              print_str_color("Your gold is stolen!",4);
              if(steal_amt > coins_amount())
              steal_amt = (coins_amount);
              change_coins(steal_amt * -1);
              }
       }
}

 

There's a lot more going on in that creature script too: if the coin snatch fails, TM coded the monster to either curse it's target or steal experience, and in other scripts set various status effects to occur on a successful hit.

 

(man, that code tag is annoyingly messed up)

Link to comment
Share on other sites

right. i went back and edited it. it was doing stupid things because i was colouring text and the code tag was also trying to colour text.

 

also, i'm not sure where i failed to call coins_amount again, but that was snipped straight from brg.txt, where coins_amount appears exactly three times - as it does in my code above. as far as i can see, you don't need to call coins_amount again because you've already ensured that they have more than 0 coins. i mean not that it matters massively - i was demonstrating that it's possible to do neat stuff with enemy attacks - if you wanted this code you may as well rip it from E:R like i did.

 

edit: if you mean i used "coins_amount" rather than "coins_amount()", then TM did too.

Link to comment
Share on other sites

Ha :-) Thanks for the responses. I wasn't sure if the forums were kinda dead or not. Glad to see they are alive. I will try to get something to work. The avernum script seems to be a lot of trial by error at first to see what works.

 

And ya, I want to have it so the npc will do something to the pc.

 

I am trying to make combat be a little more strategic and fun.

 

 

if (target_ok() == FALSE)
set_state(START_STATE);
 trgt = (get_target());
 start_hp = get_health(trgt);
 pc_x = char_loc_x(trgt);
 pc_y = char_loc_y(trgt);
 npc_x = my_loc_x;
 npc_y = my_loc_y;
 dest_x =npc_x + ((pc_x - npc_x) * 3);
 dest_y =npc_y + ((pc_y - npc_y) * 3);
 do_attack();
 end_hp = get_health(trgt);
 if(start_hp > end_hp)
	 {
                relocate_character(trgt, dest_x, dest_y);
	 }
break;

 

 

Bam :-) It works. So when the monster hits a player it pushes them back 3 tiles. I have a bad feeling that when it casts magic it will do the same, so for now this can only be used for melee monsters.

 

Next step is to make sure that if it is a blocked tile or someone is on the tile, you won't land on top. :-)

Link to comment
Share on other sites

beginstate 3; // attacking
 if (target_ok() == FALSE)
   set_state(START_STATE);
  trgt = (get_target());
  start_hp = get_health(trgt);
  pc_x = char_loc_x(trgt);
  pc_y = char_loc_y(trgt);
  npc_x = my_loc_x;
  npc_y = my_loc_y;
  push_strength = 1;
  dest_blocked = 0;
  dest_x = pc_x + ((pc_x - npc_x) * push_strength);
  dest_y = pc_y + ((pc_y - npc_y) * push_strength);
  if (char_on_loc(dest_x, dest_y) > -1)
  {dest_blocked = 1;}
  if (is_blocked(dest_x,dest_y) == 1)
  {dest_blocked = 1;}
  do_attack();

  end_hp = get_health(trgt);
  if(start_hp > end_hp)
	 {
		   if (dest_blocked == 0)
			   {
			    relocate_character(trgt, dest_x, dest_y);
			    change_coins(dest_x);
			    change_coins(dest_y);
			   }
	 }
break;

 

Alright, having a tough time trying to find a way to detect if a floor/terrain is blocked or not. The only thing I can find is to loop through all the coded tiles that are blocked. Anyone have any ideas?

Link to comment
Share on other sites

Hmm… good question!

 

Could you use the call move_to_loc_x_y(short which_char_or_group, short x, short y)? It returns 1 if the creature can't find a path to the spot. My understanding is that the creature will not attempt to move near the space if it's blocked, but you'd have to test that.

 

If that doesn't work you could use the calls change_blocked(short x, short y, short blocked) and is_blocked(short x, short y) to manually designate given spaces as blocked. That would only work in town, though.

Link to comment
Share on other sites

Alright, the script actually works pretty well :-)

 

Took me all frickin day, cause I kept running into stupid problems. I just have it so any terrain will block you.

 

I might even add a bit of extra script where if you get bashed into another pc, pc(1) takes damage and so does pc(2).

Also I might add some strength checks for how far you go, and the strength of the hitter, etc etc etc.

Link to comment
Share on other sites

Could you use the call move_to_loc_x_y(short which_char_or_group, short x, short y)? It returns 1 if the creature can't find a path to the spot. My understanding is that the creature will not attempt to move near the space if it's blocked, but you'd have to test that.

 

If that doesn't work you could use the calls change_blocked(short x, short y, short blocked) and is_blocked(short x, short y) to manually designate given spaces as blocked. That would only work in town, though.

If I'm remembering correctly, neither of these calls actually would work. The move_to_loc_x_y() call has a creature take steps, deducting ap as it goes. That's not what you want. The is_blocked() call is about whether NPCs can step on the spot and whether the party can be placed there in end combat, not whether the space is blocked from PC movement, so it's overinclusive; some things would return that they were blocked per the is_blocked() call but wouldn't actually be blocked from a PC being able to step there.

Link to comment
Share on other sites

some things would return that they were blocked per the is_blocked() call but wouldn't actually be blocked from a PC being able to step there.

Is there a separate way to test for those things, I wonder? For example, isn't blocked-to-NPC a type of field?
Link to comment
Share on other sites

//begindefinecreature 325;

//import 86;

//begindefinecreature 86;

//import 325;

//cr_name = "Louz Child";

 

 

Alright, so I keep getting errors with the 3d editor. It won't let me define creatures with ids higher than 255? Am I missing something? I placed a bunch of creatures down, and it is not allowing me to define any of them.

 

Can someone explain this?

 

Edit: Nevermind, I understand how it works. You can only have truly 255 unique creatures. So it would be in theory impossible to have 300 unique npcs with 300 unique names. The only way maybe bypass this is when you enter a town to change the names of the npcs. I just tested it and that works. The character id thing kinda confused me. Is there ever a time when we need to refer to the character id?

Link to comment
Share on other sites

The only way maybe bypass this is when you enter a town to change the names of the npcs.

This is what you're supposed to do, yes. Use set_name() to distinguish among your NPCs. Creature type is a totally different thing.

 

The character id thing kinda confused me. Is there ever a time when we need to refer to the character id?

Other than joined NPCs, not really.

 

If I remember correctly I occasionally used it for the following purpose. If someone is the same character in multiple towns, then you could set the character id to be the same across all the towns in case you wanted a death in one place to mean a death in all places. So, say you have a character named Bob. Bob is in towns 2, 4, and 7. If Bob dies in any of those towns, you want him to be dead in all of those towns. You can do that by setting Bob's character ID to be identical in all of those towns.

 

But it's probably better to accomplish the same thing with an SDF.

 

Also, if you're not already doing this, you should be looking at scripts of released scenarios to see how people do common things (such as name NPCs). It's much easier than reinventing the wheel.

Link to comment
Share on other sites

Thanks for all the replies and help. This is my first week and a half even knowing about this site and game. It really needs more advertising, cause this is so AWESOME. Anyways, is there any documentation on how to set spells, powers, skills, etc? Do you have to script them with calls and such or are they like setting up an npc/item/terrain?

 

I hate to ask so much, but 99% of all the links on the website referring me to other people's scripts are dead or missing. :-)

Link to comment
Share on other sites

If you mean creating new spells or skills for player use, it's impossible. There's documentation somewhere on creating custom special abilities (they go in the "Use Ability" area); they work by calling a scenario state. Try searching the official docs (the two files that come with the editor) for something like "ability"?

 

You can also create new "spells" attached to an item by making the item call a scenario state when used, possibly even allowing the player to select a target.

 

If you mean you want to give the player a spell or increase their level in a skill, you should search through the appendix for the relevant script call(s).

Link to comment
Share on other sites

Anyways, is there any documentation on how to set spells, powers, skills, etc? Do you have to script them with calls and such or are they like setting up an npc/item/terrain?

Just to fill in on what CM said a bit.

Spells: You have to fake this via special abilities and items. Various scenarios do this, including my scenario Exodus, so you can find examples.

Powers: This is not a thing. If you mean special abilities, yeah, check the appendices. My recent scenario The Magic makes pretty extensive use of this.

Skills: You have to fake this via SDFs. No scenario that has done this comes to mind, but it's pretty straightforward.

 

I hate to ask so much, but 99% of all the links on the website referring me to other people's scripts are dead or missing. :-)

Um, yeah, Spiderweb stopped supporting this game about seven or eight years ago. The community engaged far more extensively with BoA than Spiderweb ever did. If you want a link to a current site, go to TrueSite. There are still plenty of things up, just not at their decade-old addresses.

Link to comment
Share on other sites

Right on :-) thanks for the help, I will check out yours and play it first.

 

The only thing I am wary about is that I am going to spend endless months working on something that maybe a handful of players will play. They should make it so people can play custom maps for free. It could draw in a ton of new players.

Link to comment
Share on other sites

Right on :-) thanks for the help, I will check out yours and play it first.

 

The only thing I am wary about is that I am going to spend endless months working on something that maybe a handful of players will play. They should make it so people can play custom maps for free. It could draw in a ton of new players.

 

For what it's worth, Blades of Avernum's predecessor Blades of Exile has in fact been released to the public free of charge (complete with source code, so fans have been able to update it to work on modern computers). Its node-based system for special encounters isn't quite as potentially powerful and versatile as BoA's scripting, but on the other hand it's generally considered easier to use and has a larger number of scenarios available for it. Spiderweb Software's Jeff Vogel suggested that a similar release of BoA's source code might be possible down the line if the release of BoE's source gathered a lot of interest, but as things turned out it didn't exactly set the world on fire. There are a lot more modding tools and game creation kits available for free or at low cost to the general public than there used to be, so games like BoE and BoA have more competition than they did when they were originally released.

Link to comment
Share on other sites

This is a silly and easy question to answer. When I am in a town, is the ONLY way for me to go outside is to go to the edges?

 

Example, I am underground and I want to climb a rope a in the middle of the map. I know how to set my outdoor location, is there a way to transport me outdoors to THAT location, or do I need to set the rope to be on the edge of the map with that red line border?

Link to comment
Share on other sites

					 // basicnpc.txt
// A very simple, naive text. Creature attacks anything it hates nearby.
// Once it has won, it returns to its home.
// Memory Cells:
// Cell 0 - How creature moves.
//	 0 - If 0, wander randomly.
//	 1 - Stands still until a target appears.
//	 2 - Completely immobile, even if target appears.
// Cell 1,2 - Stuff done flag. If both 0, nothing. Otherwise when this
//	 is killed, set to 1. (Example: If cell 1 is 3 and cell 2 is 5, when
//	 creature is killed, sets SDF(3,5) to 1.)
// Cell 3 - Dialogue node to start with if talked to. if left at 0, this
//	 character doesn't talk.
begincreaturescript;
variables;
short i,j,k,target, trgt, end_hp, start_hp, npc_x, npc_y, pc_x, pc_y,
dest_x, dest_y, push_strength, distance, floor_nopass, second_target,
terrain_target;
string damage_text;
body;
beginstate INIT_STATE;
if (get_memory_cell(0) == 2)
set_mobility(ME,0);
break;
beginstate DEAD_STATE;
// Set the appropriate stuff done flag for this character being dead
if ((get_memory_cell(1) != 0) || (get_memory_cell(2) != 0))
set_flag(get_memory_cell(1),get_memory_cell(2),1);
break;
beginstate START_STATE;
// if I have a target for some reason, go attack it
if (target_ok()) {
if (dist_to_char(get_target()) <= 16)
 set_state(3);
 else set_target(ME,-1);
}
// Look for a target, attack it if visible
if (select_target(ME,8,0)) {
 do_attack();
				 }
	 set_state(3);
}
// Have I been hit? Strike back!
if (who_hit_me() >= 0) {
set_target(ME,who_hit_me());
 do_attack();
set_state(3);
}
// Otherwise, just peacefully move around. Go back to start, if I'm too far
// from where I started.
if ((my_dist_from_start() >= 6) || ((my_dist_from_start() > 0) && (get_memory_cell(0) > 0))) {
if (get_ran(1,1,100) < 40)
 return_to_start(ME,1);
}
else if (get_memory_cell(0) == 0) {
 fidget(ME,25);
 }
// if we're in combat and the above didn't give me anything to do, just
// stop now. Otherwise, game will keep running script, and that eats up CPU time.
if (am_i_doing_action() == FALSE)
end_combat_turn();
break;
beginstate 3; // attacking
if (target_ok() == FALSE)
set_state(START_STATE);
 trgt = (get_target());
 second_target = -1;
 start_hp = get_health(trgt);
 pc_x = char_loc_x(trgt);
 pc_y = char_loc_y(trgt);
 npc_x = my_loc_x;
 npc_y = my_loc_y;
 push_strength = get_memory_cell(8);
 distance = 0;
 floor_nopass = 0;
 i = 1;
 j = 1;
 while (i <= push_strength) { // Memory Cell 8 will determine how many tiles pushed.
	 k = 23; // floor number 23, Got to cycle through so many :-(
	 dest_x = pc_x + ((pc_x - npc_x) * (i));
	 dest_y = pc_y + ((pc_y - npc_y) * (i));
	 while (k < 37) {
	 if (get_floor(dest_x,dest_y) == k)
		 floor_nopass = 1;
		 k = k + 1 ;
	 }
	 k = 57;
	 while (k < 72) {
	 if (get_floor(dest_x,dest_y) == k)
		 floor_nopass = 1;
		 k = k + 1 ;
	 }
	 if (get_terrain(dest_x,dest_y) != 0)
		 {terrain_target = get_terrain(dest_x, dest_y); floor_nopass = 2;}

	 if (char_on_loc(dest_x, dest_y) != -1)
		 {second_target = char_on_loc(dest_x, dest_y); floor_nopass = 3;}

	 if (floor_nopass == 0)
	 {distance = j; j = j + 1;}else
	 {distance = j - 1; i = push_strength + 1;}

 i = i + 1;
 }

 if (distance > 0){
 dest_x = pc_x + ((pc_x - npc_x) * distance);
 dest_y = pc_y + ((pc_y - npc_y) * distance);
 }
	 // if (is_blocked(dest_x,dest_y) == 1)

 do_attack();

 end_hp = get_health(trgt);
 if(start_hp > end_hp)
	 {
	 play_sound(5);
			 if (distance > 0)
			 {relocate_character(trgt, dest_x, dest_y);}
			 if (floor_nopass == 2)
			 {damage_char(trgt, 3 * push_strength ,4);
			 clear_buffer();
			 append_char_name(trgt);
			 append_string(" gets slammed!");
			 get_buffer_text(damage_text);
			 print_str_color(damage_text,2);
			 clear_buffer();}
			 if (floor_nopass == 3)
			 {damage_char(second_target, 3 * push_strength, 4);
			 damage_char(trgt,push_strength,4);
			 clear_buffer();
			 append_char_name(trgt);
			 append_string(" gets slammed into ");
			 append_char_name(second_target);
			 append_string("!");
			 get_buffer_text(damage_text);
			 print_str_color(damage_text,2);
			 clear_buffer(); }

	 }
break;
beginstate TALKING_STATE;
if (get_memory_cell(3) == 0) {
print_str("Talking: It doesn't respond.");
end();
}
begin_talk_mode(get_memory_cell(3));
break;

 

Ok so this is my first script. I took a break from it to work on my scenario, then today I went back to polish it up a bit.

 

What it does: This is an npc script that will bash players backward. The amount of tiles and damage is determined by memory cell 8. If player one is hit and is knocked back into another player; player 2 takes damage and player 1's damage is reduced a bit. If player 1 is bashed into a terrain(wall, rock, tree, etc) they will take heavier damage. If the player hits no object/player they instead just fly backwards. I have tested it up to 5 tiles, I worry that too many will cause it to have the loop error.

 

Anyways, 2 things I need to add: check for height differences and town boundaries. Falling down heights will do extra damage :-) This will be easy to add, but I need to head to work. Peace.

 

P.s. I apologize for the formatting. It has been roughly 6+ years since I have coded/scripted anything.

Link to comment
Share on other sites

This is probably a no; but can you change a pc's sprite image at any point in the game? Also can you change a monster's image without loading a new monster in it's place?

No. For the latter, just put in a new monster. (I tend to have better luck with hidden groups than placed monsters, but it depends on your purposes.)

Link to comment
Share on other sites

I think the only way is to place it on the tile "below" where the (N)PC stands. Depending on the order things are drawn in, it might be possible to do this and use adjusts to make it look like the terrain is on a space other than the one it's "officially" placed on... of course, if it's something other than a decoration (ie, anything with a mechanical effect), this won't do what you want.

 

...oh wait, come to think of it, there should also be a way that's used with walls to paint them on top of the (N)PCs... I can't remember.

Link to comment
Share on other sites

This is why I love having a discussion thread. Yeah I found a way to make it look like you are waist deep in water. Looks awesome. I think I will eventually make a sick looking swamp tile. :-) I adjusted the terrain height and also made it so when players step on it they drop down a few pixels. So it appears like you sink down into the water.

 

I am having such a great time working on this scenario.

 

I tried to do some searching. Cliff images....can I set different ones for outside? Or can I only have one official one?

Link to comment
Share on other sites

What if I define them differently? Could that change them? I wanna get rid of that dirt cliff lol. :-) I will test it later.

 

Also does my pc "0" stay pc "0" even when I change the position of the characters? I really hope so. But anyways, if anyone knows instantly let me know. Otherwise I can test it tomorrow.

 

Btw. A little about me. I am on a 3 monthish vacation in Hawaii on the big island. I actually have more time when at home in Maine. Should be back home in the next month or so.

 

Oh and one last thing. The terrain, (n)pcs, items, and floors that the community have created are amazing. I have found so many useful ones. I didn't know if anyone came across a selection of dead trees? I found one or two, but barely the style I was looking for. If anyone knows any good ones :-) let me know.

 

Btw this community rocks. I feel like I missed out on the best days of these forums. I've been slowly taking time to check out custom maps. Some really awesome potential that seemed to just have faded away.

Link to comment
Share on other sites

Changing the outdoor cliff graphics is possible if you just include a custom graphic with the same number (657 I think?). The fiddly bit, iirc, is that the outdoor cliffs are not quite the same size as the town ones, which means you can't do a straight copy-paste. You have to either edit a copy of the original image, being careful not to mess with the white background, or use it as a template to create a new one. You can take one of the town ones and carefully paste extra rows of pixels onto it until it's the right size. It may take a bit of trial and error to make it look right, because it's supposed to make a relatively seamless surface.

Link to comment
Share on other sites

I certainly can't recall seeing custom outdoor cliffs, which is why I answered with such certainty before (and I play on PC). MacBoA is a lot more open with what you can do - Thralni even got some custom music into HIM2.

Niemand included music in the Mac version of Stairway as well.
Link to comment
Share on other sites

What, really?!

 

Does the PC version of Sorcerer's Apprentice just use the default cliff graphic? I had no idea.

I don't know for certain. However, that sort of thing works due to the Resource Manager's fallback mechanisms - basically, when searching for a resource with a given ID, it checks the most-recently-opened file first. Since the Windows version obviously doesn't use the Resource Manager, Jeff would have had to implement his own way of mimicking the fallback mechanism, which I doubt he would've thought of. So, it would surprise me if substituting default graphics works on Windows.

 

That said, I don't recall ever testing it. So I could be wrong, I guess.

Link to comment
Share on other sites

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...