The Ties that Bond...

Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /var/www/pied-piper.ermarian.net/includes/common.inc).
AuthorTopic: The Ties that Bond...
Shaper
Member # 7472
Profile Homepage #0
I'm getting a 'Improper Command on Line 407' message. I looked that part of the script (lifebondnpc) over, but can't find anything that could be causing it. Any ideas?

// lifebondnpc.txt
// by Nioca

// This script behaves just like elitenpc, except that when it
// first is attacked, it forms a Lifebond with a nearby creature.
// Then, whenever the creature is injured, it heals itself using
// the bonded creatures spell energy and health.

// If a bonded creature's health is drained to 0, the creature is
// killed, and the creature who drained it gets an extra 50 HP.

// The extra item for creature cell has been replaced with the
// max drain cell. This prevents creatures with large amounts
// of health from becoming virtually invulnerable, and doesn't
// put the victim at too steep a disadvantage.

// If the bonded creature moves to a distance of more then 10 spaces
// away OR moves to a space where the draining creature can't see it,
// the bond is broken.

// Memory Cells:
// Cell 0 - How creature moves.
// 0 - Wander randomly.
// 1 - Stands still until a target appears.
// 2 - Completely immobile, even if target appears.
// Cell 1,2 - Stuff to do when killed. If both are zero, ignored.
// 0-299,0-29 - Set a flag to one when killed.
// 310-400,0-1 - Calls a state when killed. The state called is equal to
// the number in cell 1, minus 300. If cell 2 is set to 0, calls a
// state in the current town script. If set to 1, calls a state in
// the scenario script.
// Cell 3 - Dialogue node to start with if talked to. if left at 0, this
// character doesn't talk.
// Cell 4 - Level boost. When the creature is initialized, it's level will
// be the base level for that creature type plus this number.
// Cell 5 - Special Ability. When the creature is initialized, it will
// receive the special ability specified in this cell. Valid
// abilities to choose from are listed below.
// 0 - No ability/Default ability.
// 1 - Melee attack poisons target.
// 2 - Fires a ray that curses and weakens the target.
// 3 - Petrification. Has a chance of turning the target to stone.
// 4 - Melee attack slows target.
// 5 - Throws webs at the target. Has a maximum range of 4.
// 6 - Melee attack diseases target.
// 7 - Fires charm ray at target.
// 8 - Melee attack puts target to sleep.
// 9 - Fires sleep ray at target.
// 10 - Melee attack paralyzes target.
// 11 - Fires paralysis ray at target.
// 12 - Melee attack covers target with acid.
// 13 - Fires dumbfounding/spell point draining ray at target.
// 14 - Fires confusion ray at target.
// 15 - Fires terrify/enfeeble ray at target.
// 16 - Throws rocks, which do a fair amount of damage.
// 17 - Breathes fire at target.
// 18 - Breathes cold at target.
// 19 - Breathes acid at target.
// 20 - Melee attack does extra fire damage.
// 21 - Melee attack does extra cold damage.
// 22 - Melee attack drains experience.
// 23 - Melee attack does extra cold damage and drains experience.
// 24 - Creature is invisible. Can only be hit by melee attacks.
// 26 - Radiates a fire field.
// 27 - Radiates a cold field.
// 28 - Radiates an antimagic field.
// 29 - Divides in two when struck.
// 30 - Fires a fire ray at target.
// 32 - Fires an energy ray (magic damage) at target.
// 33 - Breathes darkness (damage + enfeeblement)
// 34 - Throws spines at target. Does good damage and paralyzes.
// 35 - Creates forcecage around target.
// 36 - Melee attack webs target.
// 37 - Radiates a sleep cloud.
// 38 - Radiates a stinking cloud.
// 39 - Radiates a blade field.
// Cell 6 - Sets the creature strategy.
// 0 - Act normally.
// 1 - Fire missiles or use innate special ability.
// 2 - Cast spells.
// 3 - Use items in inventory.
// Cell 7 - Maximum amount of SP/Health to drain in one turn.
// Cell 8 - Permanent status for creature.
// 0 - None.
// 1 - Poisoned.
// 2 - Blessed.
// 3 - Shielded.
// 4 - Hasted.
// 5 - Invulnerable.
// 6 - Magic Resistant.
// 7 - Webbed.
// 8 - Diseased.
// 9 - Charmed.
// 10 - Berserk.
// 11 - Asleep.
// 12 - Paralysed.
// 13 - Acidified.
// 14 - Dumbfounded.
// 15 - Sanctuary.
// 16 - Martyr's Shield.
// 17 - Divinely Touched.
// 18 - Resistant.
// 19 - Confused.
// 20 – Enlightened. This status is only used for special encounters.
// 21 - Terrified.
// 22 - Enfeebled.
// 23 - Regenerating.
// 24 - Nimble Fingers.
// 25 - Featherfall.
// 26 - Flying.
// 27 - Safe Travel.
// 28 - Hovering Feet.
// 29 - Drunk.
// 30 - Force Caged.
// 31 - Fleeing.
// 32 - Cursed.
// 33 - Weakened.
// 34 - Slowed.
// Cell 9 - Sniper mode. If this is set to 1, the creature will scan every
// turn for a new target. This is most useful for archers or spellcasters.

begincreaturescript;

variables;

short i,target,r,m,t,rand;
short scan;
short melee_or_missile;
short lifebond = -1;
short lastdrain;
short updatespeed;
string bondalert;

body;

beginstate INIT_STATE;

// 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 is so the crature doesn't drain twice in one turn.
lastdrain = get_current_tick();

// Update speed.
if ((get_level(my_number()) > 0) && (get_level(my_number()) < 6))
updatespeed = 1;
if ((get_level(my_number()) > 5) && (get_level(my_number()) < 16))
updatespeed = 5;
if ((get_level(my_number()) > 15) && (get_level(my_number()) < 26))
updatespeed = 10;
if ((get_level(my_number()) > 25) && (get_level(my_number()) < 36))
updatespeed = 30;
if ((get_level(my_number()) > 35) && (get_level(my_number()) < 51))
updatespeed = 50;
if ((get_level(my_number()) > 50) && (get_level(my_number()) < 71))
updatespeed = 100;
if ((get_level(my_number()) > 70) && (get_level(my_number()) < 91))
updatespeed = 300;
if (get_level(my_number()) > 90)
updatespeed = 500;

// 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(ME,get_memory_cell(5));

// Do I get a bonus item?
if (get_memory_cell(7) > 0)
char_give_item(ME,get_memory_cell(7));

// 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;

// 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;

// 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) && (dist_to_party() < 18)) {
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() == FALSE)
select_target(ME,r,1);
if (target_ok() == FALSE)
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() == FALSE)
select_target(ME,8,1);
if (target_ok() == FALSE)
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); }
}


// 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,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

// 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);
}

// Is my bond valid?
if (lifebond != -1) {
if ((dist_to_char(lifebond) > 10) || (can_see_char(lifebond) == 0)
|| (char_ok(lifebond) == 0)) {
clear_buffer();
append_char_name(ME);
append_string("'s Lifebond with ");
append_char_name(lifebond);
append_string(" was broken!");
get_buffer_text(bondalert);
print_str_color(bondalert,4);
lifebond = -1; }
}

// If I'm not bonded to any creature, find one
// and create a Lifebond with it.
while ((lifebond == -1) && (enemies_nearby(10) > 0)) {
rand = get_ran(1,0,120);
if (char_ok(rand)) {
if ((dist_to_char(rand) < 11)
&& (can_see_char(rand) == 1) && (char_attitude_to_char(ME,rand) == 2)) {
lifebond = rand;
// Some zaps were here, but I removed them for your sanity.
put_sparkles_on_char(ME,4,4);
put_sparkles_on_char(lifebond,7,4);
clear_buffer();
append_char_name(ME);
append_string(" formed a Lifebond with ");
append_char_name(lifebond);
append_string("!");
get_buffer_text(bondalert);
print_str_color(bondalert,3);
run_animation_sound(171); }
}
}

// If I'm injured, start draining!
if ((lifebond > -1) && (tick_difference(get_current_tick(),lastdrain) != 0)
&& (get_health(ME) < get_max_health(ME))) {
i = 0;
m = 1;
set_character_pose(ME,1);
force_instant_terrain_redraw();
lastdrain = get_current_tick();
while ((get_health(ME) < get_max_health(ME)) && (char_ok(lifebond) == 1)
&& ((i < get_memory_cell(7)) || (get_memory_cell(7) == 0))) {
if (get_health(lifebond) == 0) {
change_char_health(ME,50);
force_instant_terrain_redraw();
put_sparkles_on_char(ME,4,4);
put_sparkles_on_char(lifebond,7,4);
clear_buffer();
append_char_name(ME);
append_string(" drains ");
append_char_name(lifebond);
append_string("'s health!");
get_buffer_text(bondalert);
print_str_color(bondalert,1);
clear_buffer();
append_char_name(ME);
append_string(" is healed for ");
append_number(i + 50);
append_string(".");
get_buffer_text(bondalert);
print_str(bondalert);
run_animation_sound(171);
kill_char(lifebond,2,0); }
else {
// If the line information was correct, the problem is somewhere in here.
if ((updatespeed == 1) || (get_health(lifebond) - 5 < 0)
|| (get_health(ME) + 5 > get_max_health(ME))
|| ((i + 5 > get_memory_cell(7)) && (get_memory_cell(7) != 0)))) {
change_char_health(ME,1);
change_char_health(lifebond,-1);
i = i + 1; }
else if ((updatespeed == 5) || (get_health(lifebond) - 10 < 0)
|| (get_health(ME) + 10 > get_max_health(ME))
|| ((i + 10 > get_memory_cell(7)) && (get_memory_cell(7) != 0)))) {
change_char_health(ME,5);
change_char_health(lifebond,-5);
i = i + 5; }
else {
change_char_health(ME,10);
change_char_health(lifebond,-10);
i = i + 10; }
if (i / updatespeed == m) {
force_instant_terrain_redraw();
m = m + 1; }
}
}
if (char_ok(lifebond) == 1) {
put_sparkles_on_char(ME,4,4);
put_sparkles_on_char(lifebond,7,4);
clear_buffer();
append_char_name(ME);
append_string(" drains ");
append_char_name(lifebond);
append_string("'s health!");
get_buffer_text(bondalert);
print_str_color(bondalert,1);
clear_buffer();
append_char_name(ME);
append_string(" is healed for ");
append_number(i);
append_string(".");
get_buffer_text(bondalert);
print_str(bondalert);
run_animation_sound(171);
set_character_pose(ME,0);
force_instant_terrain_redraw(); }
}



// Should I scan for a new target?
if ((tick_difference(scan,get_current_tick()) > 3) || (get_memory_cell(9) > 0)) {
if (melee_or_missile == 0) {
select_target(ME,1,2);
if (target_ok() == FALSE)
select_target(ME,1,1);
if (target_ok() == FALSE)
select_target(ME,1,0);
}
}
if (melee_or_missile == 1) {
select_target(ME,8,2);
if (target_ok() == FALSE)
select_target(ME,8,1);
if (target_ok() == FALSE)
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() == FALSE)
select_target(ME,2,1);
if (target_ok() == FALSE)
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;
EDIT: I make my posts nice and stretchy. :)

[ Sunday, October 15, 2006 08:23: Message edited by: HalloweeNioca ]

--------------------
Scenarios need reviews! Please rate these scenarios at the CSR after playing them!
AmnesiaDileciaThe Empire's New GroveExpress Delivery
Twilight ValleyWitch HuntWhere the Rivers MeetFoul Hordes
Posts: 2686 | Registered: Friday, September 8 2006 07:00
Guardian
Member # 6670
Profile Homepage #1
Argh. Doesn't seem like Notepad wants to put in line breaks. Care to tell me where line 407 is? Without knowing that, all I can recommend is checking the spelling of your calls (I had the toughest time figuring out why get_buffer_str() didn't work a while ago).

--------------------
You idiots! You captured their stunt doubles!
- Spaceballs
Posts: 1509 | Registered: Tuesday, January 10 2006 08:00
Shaper
Member # 7472
Profile Homepage #2
Here's line 407 and some related code:
if ((updatespeed == 1) || (get_health(lifebond) - 5 < 0) || (get_health(ME) + 5 > get_max_health(ME))
|| ((i + 5 > get_memory_cell(7)) && (get_memory_cell(7) != 0)))) {
change_char_health(ME,1);
change_char_health(lifebond,-1);
i = i + 1; }
else if ((updatespeed == 5) || (get_health(lifebond) - 10 < 0)
|| (get_health(ME) + 10 > get_max_health(ME))
|| ((i + 10 > get_memory_cell(7)) && (get_memory_cell(7) != 0)))) {
change_char_health(ME,5);
change_char_health(lifebond,-5);
i = i + 5; }
else {
change_char_health(ME,10);
change_char_health(lifebond,-10);
i = i + 10; }
if (i / updatespeed == m) {
force_instant_terrain_redraw();
m = m + 1; }
EDIT: I don't know what's going on, but when I tried to copy a small piece from the above script, the whole thing came out as one BIG line. :confused:

[ Sunday, October 15, 2006 16:39: Message edited by: Ghouloca ]

--------------------
Scenarios need reviews! Please rate these scenarios at the CSR after playing them!
AmnesiaDileciaThe Empire's New GroveExpress Delivery
Twilight ValleyWitch HuntWhere the Rivers MeetFoul Hordes
Posts: 2686 | Registered: Friday, September 8 2006 07:00
Lifecrafter
Member # 6193
Profile Homepage #3
To copy code with line breaks click the "reply with quote" button, then copy the code out of there. It'll keep the breaks.

That is all, I gave your script a quick look but don't have time for a thorough debugging.

--------------------
Guaranteed to blow your mind.

Frostbite: Get It While It's...... Hot?
Posts: 900 | Registered: Monday, August 8 2005 07:00
Off With Their Heads
Member # 4045
Profile Homepage #4
|| ((i + 10 > get_memory_cell(7)) && (get_memory_cell(7) != 0)))) {There is apparently an extra parenthesis here. Delete the last "close parentheses."

[ Sunday, October 15, 2006 18:49: Message edited by: Kelandon ]

--------------------
Arancaytar: Every time you ask people to compare TM and Kel, you endanger the poor, fluffy kittens.
Smoo: Get ready to face the walls!
Ephesos: In conclusion, yarr.

Kelandon's Pink and Pretty Page!!: the authorized location for all things by me
The Archive of all released BoE scenarios ever
Posts: 7968 | Registered: Saturday, February 28 2004 08:00
Shaper
Member # 7472
Profile Homepage #5
I can't believe I missed that... Thanks for the help. And the dose of humility.

--------------------
Scenarios need reviews! Please rate these scenarios at the CSR after playing them!
AmnesiaDileciaThe Empire's New GroveExpress Delivery
Twilight ValleyWitch HuntWhere the Rivers MeetFoul Hordes
Posts: 2686 | Registered: Friday, September 8 2006 07:00
Guardian
Member # 6670
Profile Homepage #6
If you don't have a text editor that keeps track of parentheses, get one. I recommend Programmer's Notepad, but it's far from the only one out there.

--------------------
IT'S SNOWING!
Posts: 1509 | Registered: Tuesday, January 10 2006 08:00