Jump to content

Creature Script Targeting Trouble


Nioca

Recommended Posts

I'm having some trouble with getting a target in a new creature script I've designed. No matter how I try, the only way I can even get the script to register that an enemy is nearby is by attacking the creature who has the script. Then, even though it has a target, it won't go to state 3 (attacking state), or engage the target. I can't see what could be causing the problem, as an error never appears, and everything should be functioning normally.

Code:
begincreaturescript;variables;short i,target,r,m,t,rand;short protector = -1;short myattitude;short abort = 0;short scan;short melee_or_missile = 0;body;beginstate INIT_STATE;	// Check for improperly set memory cells.	if (get_memory_cell(0) > 2) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 0)",1);		print_str_color("   Valid movement types are 0-2.",1);		}	if (get_memory_cell(1) > 1855) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 1)",1);		}	if (get_memory_cell(2) > 255) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 2)",1);		}	if (get_memory_cell(3) > 199) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 3)",1);		print_str_color("   Valid dialogue nodes are 0-199.",1);		} 	if (get_memory_cell(4) + get_level(my_number()) > 100) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 4)",1);		print_str_color("   A creature's level cannot exceed 100.",1);		} 	if (get_memory_cell(5) > 39) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 5)",1);		print_str_color("   Valid abilities are 0-39.",1);		}	if ((get_memory_cell(5) == 25) || (get_memory_cell(5) == 31)) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 5)",1);		print_str_color("   Invalid ability.",1);		}	if (get_memory_cell(6) > 3) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 6)",1);		print_str_color("   Valid strategies are 0-3.",1);		}	if (get_memory_cell(7) > 498) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 7)",1);		print_str_color("   Valid items are 0-498.",1);		}	if (get_memory_cell(8) > 34) {		abort = TRUE;		print_str_color("elitenpc Error: Invalid memory cell value. (cell 8)",1);		print_str_color("   Valid statuses are 0-34.",1);		}	if (abort)		end(); 	// Next we set certain variables. 	// Melee_or_missile checks whether the creature is a melee or missile combatant. 	// This is important when scanning for targets. 	 	if ((item_type_in_slot(my_number(),2) > 0) || (get_stat(ME,11) > 0) || (get_stat(ME,12) > 3)) 	melee_or_missile = 1;  	// This one is the creature's attitude. This is to work around a bug.	myattitude = get_attitude(ME);			// Now we set some important characteristics about myself.	// Can I move?	if (get_memory_cell(0) == 2)		set_mobility(ME,0);	// Do I recieve a level bonus?	set_level(ME,get_level(my_number()) + get_memory_cell(4));	// Do I get a special ability?	if (get_memory_cell(5) > 0) 		set_special_ability(get_memory_cell(5));	// Activate my permanent status, if I have one.	if (get_memory_cell(8) > 0) {		if (get_memory_cell(8) < 32)			set_char_status(ME,get_memory_cell(8) - 1,250,1,0);		if (get_memory_cell(8) == 33) 			set_char_status(ME,1,-250,1,0);		if (get_memory_cell(8) == 34)			set_char_status(ME,2,-250,1,0);		if (get_memory_cell(8) == 35)			set_char_status(ME,3,-250,1,0);		}break;beginstate DEAD_STATE;	if (abort)		end();	// What should happen when I die?	// If cells 1 and 2 are 0, nothing.	if (get_memory_cell(1) + get_memory_cell(2) == 0)		end();	// If cell 1 is less than 300, set a flag to 1.	if (get_memory_cell(1) < 300) {		set_flag(get_memory_cell(get_memory_cell(1),get_memory_cell(2),1)		end(); }		// If cell 1 is a value between 310 and 400, call a state.	if ((get_memory_cell(1) > 309) && (get_memory_cell(1) < 401)) {		if (get_memory_cell(2) == 1)			run_scenario_script(get_memory_cell(1));		else run_town_script(get_memory_cell(1));		end(); }break;beginstate START_STATE;	if (abort)		end();	// Sustain my permanent status, if I have one.	if (get_memory_cell(8) > 0) {		if (get_memory_cell(8) < 32)			set_char_status(ME,get_memory_cell(8) - 1,250,1,0);		if (get_memory_cell(8) == 33) 			set_char_status(ME,1,-250,1,0);		if (get_memory_cell(8) == 34)			set_char_status(ME,2,-250,1,0);		if (get_memory_cell(8) == 35)			set_char_status(ME,3,-250,1,0);		}	// Has one of my comrades found a target?	if (my_current_message() == 1)		alert_char(ME);        // If I have a target for some reason, go attack it        if (target_ok()) {                if (dist_to_char(get_target()) <= 16) {			scan = get_current_tick();			broadcast_char_message(8,1,1)                        set_state(3); }                else set_target(ME,-1);		}        // Have I been hit by nearby living creature? Strike back!        if (who_hit_me() >= 0) {                if (dist_to_char(who_hit_me()) <= 2 && char_ok(who_hit_me()) == TRUE) {	                	set_target(ME,who_hit_me()); 			scan = get_current_tick();			broadcast_char_message(8,1,1);                	set_state(3);                	}        	}        // If no one close, we defend ourselves against ranged attackers.        if (who_hit_me() >= 0) {                // Target may have been killed since it struck.                if (char_ok(who_hit_me()) == TRUE) {                        set_target(ME,who_hit_me());			scan = get_current_tick();			broadcast_char_message(8,1,1);                        set_state(3);                }        }        // Start looking for a target.	if (melee_or_missile == 0) {		r = 1;		while (r < 8) {	        	select_target(ME,r,2);	        	if (target_ok())	        		select_target(ME,r,1);		        if (target_ok())		        	select_target(ME,r,0);			if (target_ok()) {				scan = get_current_tick();				broadcast_char_message(8,1,1);				set_state(3); }			r = r + 2; }			}	if (melee_or_missile == 1) {		select_target(ME,8,2);	        if (target_ok())	       		select_target(ME,8,1);		if (target_ok())		        select_target(ME,8,0);		if (target_ok()) {			scan = get_current_tick();			broadcast_char_message(8,1,1);			set_state(3); }			}	// Finally, if I've been hit, but can't find a target, we hunt	// down the attacker. (This undermines a popular strategy of	// hasting an archer, having him fire into the room, and then	// stepping back out so that the creature won't fight back.)        if (who_hit_me() >= 0) {                // Attacker may have been killed since it struck.                if (char_ok(who_hit_me()) == TRUE) {			approach_char(ME,who_hit_me(),0); }		}	// Do I have someone to protect me? Then stay close to it till my health is	// at least %50 of its maximum value. If I'm wounded badly, find someone to        // protect me untill my health is at least %50. Otherwise, just peacefully         // move around.	// A part of this code may seem odd, but it's to avoid a major bug with the call	// 'dist_to_char'. Apparently, it can't accept variables without breaking down.	if ((get_health(ME) >= get_max_health(ME) / 2) || ((can_see_char(protector) == 0) && (dist_to_char(get_ran(protector,protector,1)) > 5))) {		protector = -1; }        if ((get_health(ME) < get_max_health(ME) / 3) && (protector == -1) && (enemies_nearby(20) == 0)) {		// Am I friendly or neutral? Then find a good character to protect me.		// (Maybe even the party!)		if (myattitude <= 4) {			// Dodging yet another bug with the call 'get_nearest_good_char'.			// If you use this call with a friendly or neutral character, the			// call will return the number of the character running the script.			// Therefore, we switch the attitude of the creature momentarily so			// the call works correctly, then switch it back.			set_attitude(ME,10);                	protector = get_nearest_good_char(5);                	set_attitude(ME,myattitude); }		// Am I hostile? Then find an evil character to protect me.		else if (myattitude >= 10) {			// The call 'get_nearest_evil_char' has this problem as well.                	set_attitude(ME,3);                 	protector = get_nearest_evil_char(5);                 	set_attitude(ME,myattitude); }		if (approach_char(ME,protector,2) == 1) {			fidget(ME,60);                 }        }         // Otherwise, just peacefully move around. Go back to start, if I'm too far        // from where I started and on't have a protector.        if ((protector == -1) && ((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,45);        }        // 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 (abort)		end();	// Sustain my permanent status, if I have one.	if (get_memory_cell(8) > 0) {		if (get_memory_cell(8) < 32)			set_char_status(ME,get_memory_cell(8) - 1,250,1,0);		if (get_memory_cell(8) == 33) 			set_char_status(ME,1,-250,1,0);		if (get_memory_cell(8) == 34)			set_char_status(ME,2,-250,1,0);		if (get_memory_cell(8) == 35)			set_char_status(ME,3,-250,1,0);	// Should I scan for a new target?	if (tick_difference(scan,get_current_tick()) > 3) {		if (melee_or_missile == 0) {	        	select_target(ME,1,2);	        	if (target_ok())	        		select_target(ME,1,1);	        	if (target_ok())	        		select_target(ME,1,0);	        	}	        if (melee_or_missile == 1) {	        	select_target(ME,8,2);	        	if (target_ok())	        		select_target(ME,8,1);	        	if (target_ok())	        		select_target(ME,8,0);	        	}							// Is my current target ok?        if (target_ok() == FALSE) {		// Do I have another target nearby?        	select_target(ME,2,2);        	if (target_ok())        		select_target(ME,2,1);        	if (target_ok())        		select_target(ME,2,0);		// If I don't, go back to the start state.        	if (target_ok())                	set_state(START_STATE);		else scan = get_current_tick();        }        do_attack_tactic(get_memory_cell(6));break;beginstate TALKING_STATE;        if (get_memory_cell(3) > 0)		begin_talk_mode(get_memory_cell(3));	else print_str("Talking: It doesn't respond.");break; 
I think the problem is in either the start state or the attacking state. Any ideas? confused

 

EDIT: Modified one of the conditionals, because it caused the width of the post to get mildly out of control. Also added my signature. smile

Link to comment
Share on other sites

While I don't have time at this moment to debug your script, perhaps I can offer a little advice. Make use of the print_num() command to get a feel for the flow of logic with these scripts. I know sometimes I have counterintuitive (at least to me) results. Then modify your script around those if possible.

Link to comment
Share on other sites

Got it fixed, thanks *i. Turns out, I had most of my target_ok conditionals backwards, which stopped target-finding cold, and a couple misplaced brackets was the reason for the attack state not activating.

 

That being said, I feel like a complete idiot.

 

On a different note, do you have to be registered at the Codex to submit codes?

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