|
The spell system that comes with iDirt 1.82 is an OK spell system with room to expand but some definite
room for improvement. Perhaps the biggest improvement that can be made is to fix it -- as it
stands, "duration" spells are broken in 1.82.
Duration spells are certain spells which can only be cast on players and last a certain amount of time. The stock spells are Armor, Damage, Blur, and Light. These spells can only be cast on a player because only a player has the necessary pointers for the spells. Each player has a pointer which can support a linked list of spells. The problem in 1.82, however, is that three of the functions are broken in how they handle the list. The typical chain of events runs something like this:
Player casts a duration spell, spell gets created but is not added to the player's list Depending on the spell being cast, it can result in nothing more happening than wondering why your MUD's process is growing in size -- or a player who suddenly has a damage and armor rating in the hundred's. Neither prospect is good. The following functions are recommended as replacements for the functions in stock iDirt 1.82. Just take the old ones out and drop these ones in. The code has been tested on several MUDs so it should be rock solid.
void
wipe_duration (int plr)
{
SPELL_DURATION *check;
SPELL_DURATION *nextptr;
if ( plr >= max_players) {
return;
}
check = players[plr].duration;
nextptr = NULL;
while (check != NULL) {
nextptr = check->next;
check->next = NULL;
duration_end(plr, check->spell, check->tmp);
FREE(check);
check = nextptr;
}
players[plr].duration = NULL;
}
/* This function handles going through the linklist to decrement the
* duration and check the spells.
*/
void
handle_duration (int plr)
{
SPELL_DURATION *top;
SPELL_DURATION *curr;
SPELL_DURATION *prev;
SPELL_DURATION *next;
top = plr < max_players ? players[plr].duration : NULL;
curr = top;
prev = top;
next = NULL;
if (curr == NULL) {
return;
}
while (curr != NULL) {
curr->duration--;
next = curr->next;
if (curr->duration <= 0) {
if (curr == top) {
top = next;
} else {
prev->next = next;
}
duration_end(plr, curr->spell, curr->tmp);
FREE(curr);
curr = next;
} else {
prev = curr;
curr = next;
}
}
players[plr].duration = top;
}
/* This function pushes the linklist to add another duration pointer
* into it.
*/
void
push_duration (int plr, int spell, int duration, int tmp)
{
SPELL_DURATION *newspell;
SPELL_DURATION *curr;
SPELL_DURATION *top;
// get current spell queue
top = players[plr].duration;
curr = top;
// create the new node for the spell queue
newspell = NEW(SPELL_DURATION, 1);
newspell->spell = spell;
newspell->duration = duration;
newspell->tmp = tmp;
// find the end of the queue and place the new spell on it
if (curr == NULL) {
curr = newspell;
top = newspell;
} else {
while (curr->next != NULL) {
curr = curr->next;
}
curr->next = newspell;
}
players[plr].duration = top;
}
|