Jump to content

Scripting help


Jerakeen

Recommended Posts

OK, what I'm trying to do is compare how much gold the party has before they sell their stuff and after. I can get the first number by putting this (courtesy of Niemand) in the dialogue node before the shop mode node:

Click to reveal..

i = coins_amount();

set_flag(74,0,i/256);

set_flag(74,1,i%256);

 

But I can't figure out how to get the second number. Putting a similar chunk of code in the code section after begin_shop_mode doesn't seem to work.

I think basically what I need is some way to call a state immediately after the party finishes shopping. Feasible?

 

Edit: Using the SET_SDF action to trigger a call in the town's start state sort of works, but if the player goes into shop mode again before moving or waiting or otherwise using up a tick, the original number gets over-written before the second number is generated.

 

Another Edit: OK, I've got it. SDFs make dialogue into a versatile tool. Added another node: "I'm busy, come back when flag (0,17) is set back to zero." sort of thing.

 

It would be more elegant if I could put the call right into the dialogue script, but the game doesn't seem to pay attention to anything you put after begin_shop_mode. Is this one more thing that isn't mentioned in the documentation?

 

Link to comment
Share on other sites

I think there's a way you could make this work even in case the party tries to shop twice. It's similar to what you mentioned already:

Quote:
SDFs make dialogue into a versatile tool. Added another node: "I'm busy, come back when flag (0,17) is set back to zero." sort of thing.

What you do is that when the party tries to shop, you first check whether the flag indicating the start of a transaction is already set. If so, you do whatever it is you want to do to complete the transaction (e.g. record the change in gold). Then, you set the flag and start a new transaction.

Then, you need to duplicate the code to complete the transaction in other places to make sure that it always gets run eventually (and probably before the player has a chance to do anything else to modify the party's amount of gold). So, you would probably want to put it in the town's START_STATE and also in the code of any other nodes in the dialogue which depend on the amount the party spent.

Link to comment
Share on other sites

  • 3 weeks later...

Well, it's been a while since I've last scripted, and I'm trying to make a special ability for an enemy that selects all nearby enemies and puts animations on them so that they activate all at once and selectively damage them all at once.

 

The animation is fine, because it doesn't pause the game until it runs. Damage, on the other hand, pauses the game, which makes using them both in conjunction a little difficult. Essentially, I can have the script cycle through a bunch of enemies and do what it's supposed to do one at a time, but I want it to happen all at once.

Link to comment
Share on other sites

There's not a very good way to do this, as I recall; a number of us have tried to do what you describe, and I'm not sure if anyone has found a way to do it well. You may just be stuck with a long, annoying set of delays.

 

One trick that might make it work is that a number of the things that the game does, like showing damage inflicted, involve running animations, which, as I recall, will also trigger queued up user animations. So, you could try setting all of the animations, not triggering them yourself, and then applying the damage.

Link to comment
Share on other sites

How do I get a creature to move closer to the party during combat?

 

In a custom creature script, I removed all of the do_attack() calls in order to keep the monster from occasionally charging my party instead of doing what it's supposed to do. Unfortunately, now it refuses to move during combat in order to keep my party in sight. What's worse is that it will use its abilities even when no one is in sight.

 

I tried having his script revert him back to the START_STATE if he couldn't see his target, but apparently creature scripts employ selective hearing, just like my dog.

Link to comment
Share on other sites

Quote:
How do I get a creature to move closer to the party during combat?

I'd say that approach_char(), with 1000 as the target argument would be the thing to try.

Quote:
In a custom creature script, I removed all of the do_attack() calls in order to keep the monster from occasionally charging my party instead of doing what it's supposed to do. Unfortunately, now it refuses to move during combat in order to keep my party in sight. What's worse is that it will use its abilities even when no one is in sight.

I tried having his script revert him back to the START_STATE if he couldn't see his target, but apparently creature scripts employ selective hearing, just like my dog.

If you're having trouble with behavior across states, maybe try simplifying the script by putting everything into just the START_STATE. It's often easier to reason about how the code will work when there are no state transitions involved.
Link to comment
Share on other sites

Code:
	if(dist_to_char(get_target()) > 2){		t = dist_to_char(get_target());		while(t >= 3){			if(approach_char(ME,get_target(),1) == 0)				t = dist_to_char(get_target());			if(my_ap() == 0)				end_combat_turn();			}		}

This seems to be doing what I want it to do, save that the game claims it's an infinite loop. What exactly is infinite about this?

Jeeze, my coding ability must seem akin to breaking rocks into smaller rocks.
Link to comment
Share on other sites

One issue is that if approach_char() returns 1, you remove all of the creature's AP, but keep running the loop. (Keep in mind that the game will call the creature's script repeatedly as long as the creature still has AP, but if the creature runs out of AP while the script is running, the script still runs to completion.)

Link to comment
Share on other sites

Originally Posted By: Niemand
The return value indicates what the creature is actually going to do, after having received the instruction. You may need to cancel whatever the creature was already doing (using stop_moving()) in order to make it do anything useful.

How are you supposed to make that any useful? It's supposed to return a 1 if the creature can no longer move, but, from what I can tell, it doesn't.

If I set up the approach_char() as a while loop to keep running as long as it keeps returning 0 (the creature is moving), then the script infinitely loops even after the creature has arrived at its destination or can no longer move. If the creature cannot move, then the call is supposed to return a 1, which should end the loop.

I am real close to forgetting these movement AI calls and manually moving the creature myself. I have truly created a monster, and I shall enjoy repeatedly murdering it in testing.
Link to comment
Share on other sites

I completely forgot that creature scripts will repeatedly loop. All my script needed was a simple restructure, and now it works perfectly. Thank you so much.

 

Now, if only I could figure out why Sanctuary randomly breaks. I may just have to give the monster an equal amount of invulnerability to fill in the cracks.

Link to comment
Share on other sites

Quote:
Now, if only I could figure out why Sanctuary randomly breaks. I may just have to give the monster an equal amount of invulnerability to fill in the cracks.

Yeah, that's a weird one. If, however, all you want is for the creature to not be harmed (you don't need the completeness of it being able to break its own sanctuary by itself attacking) invulnerability should be just about equivalent. Even if you do need it to be able to 'break' its protection, you could script it so that it removes its own invulnerability before attacking.
Link to comment
Share on other sites

The effect of sanctuary (as I recall, for PCs) is that the character cannot be targeted for attack by enemies, unless he attacks someone else, in which case the sanctuary is lost. Invulnerability isn't quite the same thing, since attacks will be able to target the creature, but they still won't inflict any harm.

Link to comment
Share on other sites

Whenever the PC attacks a monster with sanctuary, you get a message saying something to the effect of "this creature is protected by sanctuary."

 

Unfortunately, for whatever reason, attacks occasionally break through. This makes it difficult to use Sanctuary for any sort of reasonable purpose, particularly since Invulnerability does the same thing with no bugs attached.

Link to comment
Share on other sites

So I just had one of my scripts eaten by Vista, because ever since I tried shutting my UAC off my computer freezes whenever a program goes unresponsive. Oddly enough, I thought I had saved the file a bunch of times, but w/e.

 

At the time, I was trying to figure out how to check whether or not a space was clear of obstructive terrain or floors, but there doesn't seem to be a call that checks to see if the party can walk on a space.

 

I really don't want to have to manually punch in the number for each terrain I want the script to check for, so is there any easy work around that doesn't involve simply making sure the spot is devoid of terrain altogether?

Link to comment
Share on other sites

Quote:
I really don't want to have to manually punch in the number for each terrain I want the script to check for, so is there any easy work around that doesn't involve simply making sure the spot is devoid of terrain altogether?

There is no supported way. I think that there is probably a tricky solution, however, and it should even be pretty portable. I haven't researched it in detail, but I could if you want.
Link to comment
Share on other sites

Originally Posted By: Niemand
Quote:
I really don't want to have to manually punch in the number for each terrain I want the script to check for, so is there any easy work around that doesn't involve simply making sure the spot is devoid of terrain altogether?

There is no supported way. I think that there is probably a tricky solution, however, and it should even be pretty portable. I haven't researched it in detail, but I could if you want.


That's alright, the alternative doesn't take that long, it's just more dependent on location,which is fine for this, since it's just one fight.
Link to comment
Share on other sites

How do I keep enemies from getting free pot shots at the party if you turn them hostile after a cutscene?

 

I've done everything I can think of, save a really inconvenient workaround, but it seems that the game skips ahead quite a few ticks.

 

EDIT: I finally figured out why my tick method wasn't working. If I declared the variable during the cutscene, ending the cutscene would move the game forward a tick, so that wouldn't work. Without declaring the variable, my original (tick_difference(tick,get_current_tick()) != 0) would always run because of whatever number variables are naturally set to return.

 

Code:
	if(get_flag(0,0) == 2){		if((tick_difference(tick,get_current_tick()) == 1) || (tick_difference(tick,get_current_tick()) == -29999)){			set_attitude(1001,10);			set_flag(0,0,3);			}		}	if(get_flag(0,0) == 2)		tick = get_current_tick();
Link to comment
Share on other sites

Quote:
Unfortunately, get_char_status() will not return a negative number. Any way around this?

I just tried this out, and it seemed to work. In the START_STATE of a creature script I put:
Code:
set_char_status(ME,1,-10,1,0);

and in the START_STATE of the town script I put:
Code:
print_nums(get_char_status(6,1),get_char_status(7,1),get_char_status(8,1));

(Creatures 6, 7, and 8 are ones using the script I first modified.)
I saw matching negative numbers being printed out, as hoped for. One thing to watch out for: Did you try using print_num() to have a script report values to you? As I recall that particular print call doesn't handle negative numbers properly, which is why I've made a habit of using print_nums() instead (although doing so necessitates providing three numbers to print, whether that was what you needed or not).
Link to comment
Share on other sites

Originally Posted By: Niemand
Quote:
Unfortunately, get_char_status() will not return a negative number. Any way around this?

I just tried this out, and it seemed to work. In the START_STATE of a creature script I put:
Code:
set_char_status(ME,1,-10,1,0);

and in the START_STATE of the town script I put:
Code:
print_nums(get_char_status(6,1),get_char_status(7,1),get_char_status(8,1));

(Creatures 6, 7, and 8 are ones using the script I first modified.)
I saw matching negative numbers being printed out, as hoped for. One thing to watch out for: Did you try using print_num() to have a script report values to you? As I recall that particular print call doesn't handle negative numbers properly, which is why I've made a habit of using print_nums() instead (although doing so necessitates providing three numbers to print, whether that was what you needed or not).

Ha ha, yep.

Coincidentally, my script worked when I removed the portion checking to see if the specific status returned a negative number (though I left the ones checking for positive numbers). I have no idea why it wasn't working, all I know is that it wasn't. I like my alternative better, though, so it doesn't matter to me at the moment.

Thanks for the heads up.
Link to comment
Share on other sites

  • 6 months later...

I assume you mean, when you use a set_terrain call to create a door where there wasn't one, why doesn't it get a door script added on that space? I think that some of it has to do with the fact that this isn't what one would always want, that it might be a bit tricky for the game to handle loading another script when not in the process of loading a zone, and partially that this is yet another feature Jeff overlooked because he didn't happen to need to dynamically manage terrain scripts.

 

A work-around, if you're always modifying a terrain on the same space, would be to place a terrain script there ahead of time that lies dormant until you need it. This script could be activated (via give_ter_script_message might be a good way) when you place the new terrain on top of it.

Link to comment
Share on other sites

I considered that, but the intention was actually to have a creature script drop/throw explosives around that would explode in a turn or two. The alternative was to transfer the code to a creature script, I just preferred that the player and other creatures be able to walk over the explosives.

 

Actually, I can carpet the relevant area with dormant terrain scripts without hitting the town limit. I guess this will have to do. Thanks for the help.

Link to comment
Share on other sites

Originally Posted By: Enraged Slith
I considered that, but the intention was actually to have a creature script drop/throw explosives around that would explode in a turn or two. The alternative was to transfer the code to a creature script, I just preferred that the player and other creatures be able to walk over the explosives.

You could do this without terrain scripts. You'll need to set aside three SDFs for every explosive you want to be available at a time (say you want a max of three at a time, then you need nine SDFs). When the creature 'throws' an explosive, have the creature script set those three flags to the numbers you want, the first two being the x and y locations of the explosive and the third the time to the explosion. Be sure to make the creature script check if those flags are zero before changing them, or you're going to have explosives jumping all over the place. Then what you want is for the START_STATE in the town script to check if the flags are non-zero. If so, have it reduce the timer flag by one, then check if that flag is zero. If so, set off the explosion at the location defined by your first two flags. Then, set those flags back to zero.
Link to comment
Share on other sites

Originally Posted By: B.J.Earles
You could do this without terrain scripts. You'll need to set aside three SDFs for every explosive you want to be available at a time (say you want a max of three at a time, then you need nine SDFs). When the creature 'throws' an explosive, have the creature script set those three flags to the numbers you want, the first two being the x and y locations of the explosive and the third the time to the explosion. Be sure to make the creature script check if those flags are zero before changing them, or you're going to have explosives jumping all over the place. Then what you want is for the START_STATE in the town script to check if the flags are non-zero. If so, have it reduce the timer flag by one, then check if that flag is zero. If so, set off the explosion at the location defined by your first two flags. Then, set those flags back to zero.

This is the way to go.

Originally Posted By: Enraged Slith
That's a cool idea, but aren't flag values maxed out at (299,29,whatevermaxnumberthegamecanrecognize)?

Yes, they are limited to the range[0,255]. However, have a look at this tip for a means of storing the necessary time.
Link to comment
Share on other sites

Any idea why a dialogue script would simply stop in the middle? My states and nodes line up correctly, and there's nothing outstanding about the problem node to make the game act funny. It simply stops there and gives the generic "I have no more questions" line.

 

EDIT: It appears that the problem lies with how I'm activating it. I'm using a creature script that initiates dialogue from the start_state.

 

Specifically, I put this code in the start state of an otherwise unaltered basicnpc script:

 

Code:
	if((get_memory_cell(4) > 0) && (get_memory_cell(5) > 0))		if(get_flag(get_memory_cell(4),get_memory_cell(5)) == get_memory_cell(6)){			begin_talk_mode(get_memory_cell(3));			inc_flag(get_memory_cell(4),get_memory_cell(5),1);			}

 

Everything works, the dialogue just stops prematurely in an odd location. What's weirder is that if I initiate the dialogue naturally, the problem doesn't come up. Specifically, if I don't include the inc_flag and the dialogue is forced each turn, I can talk to the NPC normally in between turns and have it work just fine.

Link to comment
Share on other sites

Not sure if it will do anything different, but have you tried moving the inc_flag line before the begin_talk_mode line? All of the examples I have of beginning talk in the creature start state have the begin_talk_mode call as the last call made.

Similar to the following (if check wraps the move/fidget code also).

Code:
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);	}	if (get_flag(2, 1) > 0) {		// 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);		}	}	else {		begin_talk_mode(get_memory_cell(3));	}	// 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;
Link to comment
Share on other sites

  • 3 weeks later...

I still don't know why forcing dialogue in the start state is being so buggy. It works for one of my dialogue trees, but stops at the second node for the others. Dialogue works fine otherwise. I've tried removing everything else in the start state, and the bug is the same. This is just weird.

Link to comment
Share on other sites

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...