version 1.27 | | version 1.28 |
---|
| | |
/* | | /* |
* static char *rcsid_apply_c = | | * static char *rcsid_apply_c = |
* "$Id: apply.c,v 1.27 2000/12/18 02:45:56 peterm Exp $"; | | * "$Id: apply.c,v 1.28 2000/12/27 07:53:35 cvs Exp $"; |
*/ | | */ |
/* | | /* |
CrossFire, A Multiplayer game for X-windows | | CrossFire, A Multiplayer game for X-windows |
| | |
#endif | | #endif |
| | |
| | |
| | /* Special prayers are granted by gods and lost when the follower decides |
| | * to pray to a different gods. 'Force' objects keep track of which |
| | * prayers are special. |
| | */ |
| | |
| | static object *find_special_prayer_mark (object *op, int spell) |
| | { |
| | object *tmp; |
| | |
| | for (tmp = op->inv; tmp; tmp = tmp->below) |
| | if (tmp->type == FORCE && tmp->slaying |
| | && strcmp (tmp->slaying, "special prayer") == 0 |
| | && tmp->stats.sp == spell) |
| | return tmp; |
| | return 0; |
| | } |
| | |
| | static void insert_special_prayer_mark (object *op, int spell) |
| | { |
| | object *force = get_archetype ("force"); |
| | force->speed = 0; |
| | update_ob_speed (force); |
| | force->slaying = add_string ("special prayer"); |
| | force->stats.sp = spell; |
| | insert_ob_in_ob (force, op); |
| | } |
| | |
| | extern void do_learn_spell (object *op, int spell, int special_prayer) |
| | { |
| | object *tmp = find_special_prayer_mark (op, spell); |
| | |
| | if (op->type != PLAYER) { |
| | LOG (llevError, "BUG: do_forget_spell(): not a player\n"); |
| | return; |
| | } |
| | |
| | /* Upgrade special prayers to normal prayers */ |
| | if (check_spell_known (op, spell)) { |
| | if (special_prayer || ! tmp) { |
| | LOG (llevError, "BUG: do_learn_spell(): spell already known, but " |
| | "can't upgrade it\n"); |
| | return; |
| | } |
| | remove_ob (tmp); |
| | free_object (tmp); |
| | return; |
| | } |
| | |
| | /* Learn new spell/prayer */ |
| | if (tmp) { |
| | LOG (llevError, "BUG: do_learn_spell(): spell unknown, but special " |
| | "prayer mark present\n"); |
| | remove_ob (tmp); |
| | free_object (tmp); |
| | } |
| | play_sound_player_only (op->contr, SOUND_LEARN_SPELL, 0, 0); |
| | op->contr->known_spells[op->contr->nrofknownspells++] = spell; |
| | if (op->contr->nrofknownspells == 1) |
| | op->contr->chosen_spell = spell; |
| | insert_special_prayer_mark (op, spell); |
| | |
| | new_draw_info_format (NDI_UNIQUE, 0, op, |
| | "Type 'bind cast %s", spells[spell].name); |
| | new_draw_info (NDI_UNIQUE, 0, op, "to store the spell in a key."); |
| | } |
| | |
| | extern void do_forget_spell (object *op, int spell) |
| | { |
| | object *tmp; |
| | int i; |
| | |
| | if (op->type != PLAYER) { |
| | LOG (llevError, "BUG: do_forget_spell(): not a player\n"); |
| | return; |
| | } |
| | if ( ! check_spell_known (op, spell)) { |
| | LOG (llevError, "BUG: do_forget_spell(): spell not known\n"); |
| | return; |
| | } |
| | |
| | new_draw_info_format (NDI_UNIQUE, 0, op, "You lose knowledge of %s.", |
| | spells[spell].name); |
| | |
| | tmp = find_special_prayer_mark (op, spell); |
| | if (tmp) { |
| | remove_ob (tmp); |
| | free_object (tmp); |
| | } |
| | |
| | for (i = 0; i < op->contr->nrofknownspells; i++) |
| | { |
| | if (op->contr->known_spells[i] == spell) { |
| | op->contr->known_spells[i] = |
| | op->contr->known_spells[--op->contr->nrofknownspells]; |
| | return; |
| | } |
| | } |
| | LOG (llevError, "BUG: do_forget_spell(): couldn't find spell\n"); |
| | } |
| | |
static void apply_spellbook (object *op, object *tmp) | | static void apply_spellbook (object *op, object *tmp) |
{ | | { |
if(QUERY_FLAG(op, FLAG_BLIND)&&!QUERY_FLAG(op,FLAG_WIZ)) { | | if(QUERY_FLAG(op, FLAG_BLIND)&&!QUERY_FLAG(op,FLAG_WIZ)) { |
| | |
op->contr->socket.update_look=1; | | op->contr->socket.update_look=1; |
} | | } |
| | |
if(check_spell_known(op,tmp->stats.sp)) { | | if (check_spell_known (op, tmp->stats.sp) && (tmp->stats.Wis || |
| | find_special_prayer_mark (op, tmp->stats.sp) == NULL)) |
| | { |
new_draw_info(NDI_UNIQUE, 0,op,"You already know that spell.\n"); | | new_draw_info(NDI_UNIQUE, 0,op,"You already know that spell.\n"); |
return; | | return; |
} | | } |
| | |
scroll_failure(op,RANDOM()%(spells[tmp->stats.sp].level+1),spells[tmp->stats.sp].sp); | | scroll_failure(op,RANDOM()%(spells[tmp->stats.sp].level+1),spells[tmp->stats.sp].sp); |
} else if(QUERY_FLAG(tmp,FLAG_STARTEQUIP) || RANDOM()%150-(2*SK_level(op)) < | | } else if(QUERY_FLAG(tmp,FLAG_STARTEQUIP) || RANDOM()%150-(2*SK_level(op)) < |
learn_spell[spells[tmp->stats.sp].cleric ? op->stats.Wis : op->stats.Int]) { | | learn_spell[spells[tmp->stats.sp].cleric ? op->stats.Wis : op->stats.Int]) { |
play_sound_player_only(op->contr, SOUND_LEARN_SPELL,0,0); | | |
new_draw_info(NDI_UNIQUE, 0,op,"You succeed in learning the spell!"); | | new_draw_info(NDI_UNIQUE, 0,op,"You succeed in learning the spell!"); |
op->contr->known_spells[op->contr->nrofknownspells++]=tmp->stats.sp; | | do_learn_spell (op, tmp->stats.sp, tmp->stats.Wis); |
if(op->contr->nrofknownspells == 1) | | |
op->contr->chosen_spell=tmp->stats.sp; | | |
new_draw_info_format(NDI_UNIQUE, 0, op, | | |
"Type 'bind cast %s",spells[tmp->stats.sp].name); | | |
new_draw_info(NDI_UNIQUE, 0,op,"to store the spell in a key."); | | |
#ifdef ALLOW_SKILLS /* xp gain to literacy for spell learning */ | | #ifdef ALLOW_SKILLS /* xp gain to literacy for spell learning */ |
if ( ! QUERY_FLAG (tmp, FLAG_STARTEQUIP)) | | if ( ! QUERY_FLAG (tmp, FLAG_STARTEQUIP)) |
add_exp(op,calc_skill_exp(op,tmp)); | | add_exp(op,calc_skill_exp(op,tmp)); |
| | |
| | |
case TREASURE: | | case TREASURE: |
while ((op->stats.hp--)>0) | | while ((op->stats.hp--)>0) |
create_treasure(op->randomitems, op, op->map?GT_ENVIRONMENT:GT_INVENTORY, | | create_treasure(op->randomitems, op, op->map?GT_ENVIRONMENT:0, |
op->stats.exp ? op->stats.exp : | | op->stats.exp ? op->stats.exp : |
op->map == NULL ? 14: op->map->difficulty,0); | | op->map == NULL ? 14: op->map->difficulty,0); |
| | |
| | |
auto_apply(invtmp); | | auto_apply(invtmp); |
else if(invtmp->type==TREASURE) { | | else if(invtmp->type==TREASURE) { |
while ((invtmp->stats.hp--)>0) | | while ((invtmp->stats.hp--)>0) |
create_treasure(invtmp->randomitems, invtmp, GT_INVENTORY, | | create_treasure(invtmp->randomitems, invtmp, 0, |
m->difficulty,0); | | m->difficulty,0); |
} | | } |
} | | } |
| | |
auto_apply(tmp); | | auto_apply(tmp); |
else if((tmp->type==TREASURE || (tmp->type==CONTAINER))&&tmp->randomitems) { | | else if((tmp->type==TREASURE || (tmp->type==CONTAINER))&&tmp->randomitems) { |
while ((tmp->stats.hp--)>0) | | while ((tmp->stats.hp--)>0) |
create_treasure(tmp->randomitems, tmp, GT_INVENTORY, | | create_treasure(tmp->randomitems, tmp, 0, |
m->difficulty,0); | | m->difficulty,0); |
} | | } |
else if(tmp->type==TIMED_GATE) { | | else if(tmp->type==TIMED_GATE) { |
| | |
} | | } |
if(tmp && tmp->arch && tmp->type!=PLAYER && tmp->type!=TREASURE && | | if(tmp && tmp->arch && tmp->type!=PLAYER && tmp->type!=TREASURE && |
tmp->randomitems) | | tmp->randomitems) |
create_treasure(tmp->randomitems, tmp, GT_INVENTORY, | | create_treasure(tmp->randomitems, tmp, GT_APPLY, |
m->difficulty,0); | | m->difficulty,0); |
} | | } |
for(x=0;x<m->mapx;x++) | | for(x=0;x<m->mapx;x++) |