Easygoing Eyebeast Enraged Slith Posted December 21, 2010 Posted December 21, 2010 Two things I've noticed about creatures lately when trying to script interesting encounters: 1. Their pathfinding is ass. One of my fights involves the party starting up on a cliff, with a ramp leading down to the battle. The enemy creatures literally beeline straight for the cliff edge from below and just sit there like statues. I can work around this with waypoints, but eww... 2. Creatures (maybe just certain creature types) don't like to follow drop percentages. They just drop whatever you feel like. If you decide that you're going to have a creature use a long sword, and you set it to 100%, you aren't going to see 100% long swords every time you kill that creature. Chances are, you aren't even going to see 50% long swords. As another example, in Gluckcluck, I tried giving a random monster a 1% chance of dropping a Ring of Speed, and yet, in my tests and from every beta report I received, that ring dropped nearly every single time. I really don't know the specifics behind this bug, but it's pretty darn aggravating. If anyone has any other creature related curiosities, or can expand on these two, I'd be happy to hear it. Quote
Easygoing Eyebeast Dintiradan Posted December 22, 2010 Posted December 22, 2010 Blades Invaders was actually just an exercise in pathfinding, and what could and couldn't be done in Blades. If you want to have finer control over a monster's movement, but need to use dynamic waypoints, you can spawn a creature, move the target creatu...pawned creature. Quote
Easygoing Eyebeast Enraged Slith Posted December 26, 2010 Author Posted December 26, 2010 Is there any way to force creatures to use their expendables? I've got a script for a creature that gives potions to all friendly creatures that need them, but it wont do much good if they don't use them. Quote
Well-Actually War Trall Niemand Posted December 26, 2010 Posted December 26, 2010 Quote: Is there any way to force creatures to use their expendables? No, there is not. It's rather maddening. (Note that do_attack_tactic(3) claims to do this, but it does not appear to actually work.) Quote
Easygoing Eyebeast The Mystic Posted December 27, 2010 Posted December 27, 2010 I just did a quick check in the original Avernumscript documentation; do_attack_tactic(3) will force a character to "strongly prefer to use an item in its inventory." I'm assuming that means there's still a chance (albeit lessened) that the character can use other tactics, so using an item won't happen automatically every time. Quote
Well-Actually War Trall Niemand Posted December 27, 2010 Posted December 27, 2010 That would make sense from the documentation, however, I'm not aware of anyone having ever observed that call causing a creature to use an item. Quote
Easygoing Eyebeast Enraged Slith Posted July 21, 2011 Author Posted July 21, 2011 This repeats until the creature runs out of action points, without running through the rest of the script. Code: if(enemies_nearby(1) > 1){ print_str("test"); deduct_ap(1); } Removing the call deduct_ap() doesn't produce this problem. Neither does changing the condition. I have no idea why the combination of enemies_nearby() and deduct_ap() cause the script to behave silly. Quote
Well-Actually War Trall Niemand Posted July 22, 2011 Posted July 22, 2011 I tried this and saw no problem: When the creature had two enemies standing adjacent to it, it would print "test" and the then print the text from the print statement I put immediately after the block you posted. Can you post a complete script that exhibits the funny behavior? Quote
Easygoing Eyebeast Enraged Slith Posted July 22, 2011 Author Posted July 22, 2011 It isn't finished yet and it's still messy because I'm trying to figure out the best way to get it to leave a trail of flames behind after every step. It works, crudely, but the deduct_ap() in the problem section caused everything past it to completely stop. There were no errors, the script simply loops until he's out of action points. When I changed the condition, there was no problem, and when I removed the call, there was no problem. Code: beginstate 3; // attacking target = get_target(); if (target_ok() == FALSE) set_state(START_STATE); if((myx != my_loc_x()) || (myy != my_loc_y())){ put_field_on_space(myx,myy,1); put_effect_on_space(myx,myy,1,3,1); run_animation_sound(-167); } if(enemies_nearby(1) > 1){ put_effect_on_char(ME,0,7,1); run_animation_sound(44); force_status_nearby(-1,1,2,0); deduct_ap(1); } if(maintain_dist_to_char(ME,target,4) == 1){ x = get_ran(1,1,5); myx = my_loc_x(); myy = my_loc_y(); tx = char_loc_x(get_target()); ty = char_loc_y(get_target()); if(x == 1){ set_character_pose(ME,1); force_instant_terrain_redraw(); put_effect_on_char(target,12,1,2); put_straight_zap(myx,myy,tx,ty,4); run_animation_sound(70); damage_char(target,get_ran(1,1,7),4); } if(x == 2){ set_character_pose(ME,1); force_instant_terrain_redraw(); put_effect_on_char(target,9,1,2); put_straight_zap(myx,myy,tx,ty,0); run_animation_sound(11); damage_near_loc(tx,ty,get_ran(1,3,5),2,1); } if(x == 3){ set_character_pose(ME,1); force_instant_terrain_redraw(); put_effect_on_char(target,3,1,2); put_straight_zap(myx,myy,tx,ty,0); run_animation_sound(14); damage_char(target,get_ran(1,1,3),1); set_char_status(target,3,-2,0,1); } if(x == 4){ set_character_pose(ME,1); force_instant_terrain_redraw(); put_effect_on_char(target,13,1,2); put_straight_zap(myx,myy,tx,ty,3); run_animation_sound(14); put_field_on_space(tx,ty,3); put_field_on_space(tx + 1,ty,3); put_field_on_space(tx - 1,ty,3); put_field_on_space(tx,ty + 1,3); put_field_on_space(tx,ty - 1,3); set_char_status(target,0,20,0,1); set_char_status(target,21,2,0,1); play_sound(66); } if(x == 5){ set_character_pose(ME,1); force_instant_terrain_redraw(); put_sparkles_on_char(target,7,5); put_straight_zap(myx,myy,tx,ty,0); run_animation_sound(17); set_char_status(target,9,2,0,1); set_char_status(target,18,2,0,1); } set_character_pose(ME,0); force_instant_terrain_redraw(); pause(2); deduct_ap(1); } myx = my_loc_x(); myy = my_loc_y();break; Everything else functions like the basicnpc script, save the removal of every do_attack(). Quote
Well-Actually War Trall Niemand Posted July 22, 2011 Posted July 22, 2011 Hm. I agree that something funny is going on, but I don't think it has to with the enemies_nearby block. I marked it up like this: Code: if(enemies_nearby(1) > 1){ //put_effect_on_char(ME,0,7,1); //run_animation_sound(44); //force_status_nearby(-1,1,2,0); print_str("Test"); deduct_ap(1); } print_str("After"); And it prints: Quote: TestAfter Test After Test After But then the character does nothing else. Something that looks like an important detail is that I checked and the return value of the maintain_dist_to_char call is 0 in these cases. This doesn't make sense since the character didn't move, but it does explain why none of the other scripted actions are carried out. So, it looks like you may need to check for this case and decide what you want to do when it happens. Since you're already tracking the character's location, it may be safer to use that then to trust maintain_dist_to_char to tell you the truth. Quote
Easygoing Eyebeast Enraged Slith Posted July 27, 2011 Author Posted July 27, 2011 Code: beginstate 3; if (who_hit_me() >= 0) { set_target(ME,who_hit_me()); broadcast_char_message(8,who_hit_me(),1); } target = get_target(); if (target_ok() == FALSE) set_state(START_STATE); x = 0; myx = my_loc_x(); myy = my_loc_y(); while(x < 120){ if(char_ok(x) == TRUE) if(can_see_char(x) == TRUE) if(creature_type(x) == 242) x = 120; x = x + 1; } if(x == 120){ x = 0; while(x < 100){ y = get_ran(1,(myx - 2),(myx + 2)); z = get_ran(1,(myy - 2),(myy + 2)); if((y >= 0) && (z >= 0)) if(can_see_loc(y,z) == TRUE) if(get_terrain(y,z) == 0) if(char_on_loc(y,z) == FALSE) x = 100; x = x + 1; } if(x == 101){ set_character_pose(ME,1); force_instant_terrain_redraw(); place_monster(y,z,242,1); put_sparkles_on_space(y,z,3,3); run_animation_sound(120); pause(2); set_character_pose(ME,0); force_instant_terrain_redraw(); pause(2); deduct_ap(2); i = get_current_tick(); } } if(x == 121){ if(tick_difference(i,get_current_tick()) > 2){ x = 0; while(x < 100){ y = get_ran(1,(myx - 2),(myx + 2)); z = get_ran(1,(myy - 2),(myy + 2)); if((y >= 0) && (z >= 0)) if(can_see_loc(y,z) == TRUE) if(get_terrain(y,z) == 0) if(char_on_loc(y,z) == FALSE) x = 100; x = x + 1; } if(x == 101){ set_character_pose(ME,1); force_instant_terrain_redraw(); place_monster(y,z,242,1); put_sparkles_on_space(y,z,3,3); run_animation_sound(120); pause(2); set_character_pose(ME,0); force_instant_terrain_redraw(); pause(2); deduct_ap(2); } } } if((approach_char(ME,target,1) == 1) && (dist_to_char(target) == 1)){ y = char_loc_x(target); z = char_loc_y(target); set_character_pose(ME,1); force_instant_terrain_redraw(); put_effect_on_char(target,11,1,2); run_animation_sound(118); if((char_has_trait(target,10) == TRUE) || (get_ran(1,0,99) <= 19)) damage_char(target,get_ran(8,2,4),3); else damage_char(target,get_ran(4,2,4),3); put_field_on_space(y,z,2); if(get_health(target) == 0){ put_boom_on_char(target,6,0); set_char_status(target,21,3,1,0); alter_stat(target,31,1); run_animation_sound(25);//25,54,65,112,118 } pause(2); set_character_pose(ME,0); force_instant_terrain_redraw(); end_combat_turn(); } if(tick_difference(i,get_current_tick()) > 2) i = get_current_tick();break; There is no order of operations here. For whatever reason, the script insists on doing the approach_char crap first. What's also confusing, is that it is ignoring my variables. It places the sparkles directly on the script's current target while placing the monster elsewhere, even though they both follow the same coordinates. It seems to base y and z off of the coordinates of where the current target is standing, even though I base them off of myx and myy, which are specified as my_loc_x/y() respectively. None of this makes any sense to me.Any glaring issues here, or is this just the game behaving strangely? The reason I ask is because I've had some really weird bugs lately, like the game refusing to recognize message_dialog("","") as a call, until I copy-pasted a working "message_dialog(" over that "message_dialog(". There were no errors or minor typos - I checked it over a hundred times. Quote
Easygoing Eyebeast Enraged Slith Posted July 27, 2011 Author Posted July 27, 2011 I fixed everything by changing (char_on_loc(y,z) == FALSE) to (char_on_loc(y,z) < 0). Either char_on_loc() goes wonky when you ask for it to return a -1, or FALSE does more than I thought. I have no idea why it was screwing everything up. EDIT: Oh, FALSE returns a 0. That explains everything. Quote
Easygoing Eyebeast Enraged Slith Posted August 3, 2011 Author Posted August 3, 2011 Anyone mind running a script for me? I'm having trouble narrowing down what's wrong with it, because, for the most part, it works. When my monsters kill their target, they will occasionally wander off somewhere and cease to function. Sometimes they'll blip back to life and run just part of the script before slipping back into a coma. Sometimes they will completely ignore multiple calls that tell them to stop doing what they're doing and continuously cycle through their entire script while attacking nothing but air. I really have no idea where to begin troubleshooting something like this. Code: begincreaturescript;variables;short i,num,prey,health;short stealth_mode;short i_am_hurt;body;beginstate INIT_STATE; if (get_memory_cell(0) == 2) set_mobility(ME,0); num = my_number(); stealth_mode = 0; health = get_health(num); prey = -1; 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)) { set_state(3); } // Have I been hit? Strike back! if (who_hit_me() >= 0) { set_target(ME,who_hit_me()); 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; if(target_ok() == FALSE){ if(stealth_mode > 0){ set_special_ability(num,0); put_effect_on_char(num,4,3,1); run_animation_sound(62); stealth_mode = 0; } set_state(START_STATE); } if(get_health(num) < health) i_am_hurt = 1; if((i_am_hurt == 1) && (stealth_mode > 0)){ set_target(num,who_hit_me()); set_special_ability(num,0); put_effect_on_char(num,9,1,2); run_animation_sound(61); print_str_color("Discovered.",2); stealth_mode = 0; i_am_hurt = 0; end_combat_turn(); } if(stealth_mode == 0){ if(flee_char(num,get_target(),3) == 0){ set_char_status(num,4,1,1,0); } else{ put_sparkles_on_char(num,11,5); run_animation_sound(52); set_special_ability(num,24); print_str_color("Stealth.",2); stealth_mode = 1; set_char_status(num,4,(get_char_status(num,4) * -1),1,0); } } if(stealth_mode == 1){ if(prey == -1){ i = 0; prey = 0; while(i < 119){ if(char_ok(i) == TRUE) if(can_see_char(i) == TRUE) if(char_attitude_to_char(num,i) == 2) if(get_health(i) <= get_health(prey)) prey = i; i = i + 1; } set_target(num,prey); } if(approach_char(num,prey,2) == 0) set_char_status(num,4,1,1,0); else{ if(dist_to_char(prey) <= 2){ stealth_mode = 2; set_char_status(num,4,(get_char_status(num,4) * -1),1,0); end_combat_turn(); } } } if(stealth_mode == 2){ if(approach_char(num,prey,1) == 1){ if(dist_to_char(prey) == 1){ set_special_ability(num,0); put_effect_on_char(num,4,3,1); run_animation_sound(62); pause(2); set_character_pose(num,1); force_instant_terrain_redraw(); put_effect_on_char(prey,5,1,2); run_animation_sound(73); damage_char(prey,get_ran(4,1,5),0); damage_char(prey,get_ran(4,1,5),0); set_char_status(prey,3,-3,0,1); set_char_status(prey,21,3,0,1); set_character_pose(num,0); force_instant_terrain_redraw(); print_str_color("Sneak attack!",2); prey = -1; stealth_mode = 0; } end_combat_turn(); } } health = get_health(num);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; Quote
Easygoing Eyebeast Enraged Slith Posted August 16, 2011 Author Posted August 16, 2011 EDIT: Ha ha, I suck. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.