void handle_recall_spells(CHAR_DATA* ch) { AFFECT_DATA* aff = NULL; for(AFFECT_DATA* af = ch->affected; af; af = af->next) if (af->type == SPELL_RECALL_SPELLS) { aff = af; break; } if (!aff) return; //максимальный доступный чару круг unsigned max_slot = get_max_slot(ch); //обрабатываем только каждые RECALL_SPELLS_INTERVAL секунд int secs_left = (SECS_PER_PLAYER_AFFECT*aff->duration)/SECS_PER_MUD_HOUR -SECS_PER_PLAYER_AFFECT; if (secs_left / RECALL_SPELLS_INTERVAL < max_slot -aff->modifier || secs_left <= 2) { int slot_to_restore = aff->modifier++; bool found_spells = false; struct spell_mem_queue_item *next = NULL, *prev=NULL, *i = ch->MemQueue.queue; while (i) { next = i->link; if (spell_info[i->spellnum].slot_forc[(int) GET_CLASS(ch)][(int) GET_KIN(ch)] == slot_to_restore) { if (!found_spells) { send_to_char("Ваша голова прояснилась, в памяти всплыло несколько новых заклинаний.\r\n", ch); found_spells = true; } if (prev) prev->link = next; if (i == ch->MemQueue.queue) { ch->MemQueue.queue = next; GET_MEM_COMPLETED(ch) = 0; } GET_MEM_TOTAL(ch) = MAX(0, GET_MEM_TOTAL(ch) - mag_manacost(ch, i->spellnum)); sprintf(buf, "Вы вспомнили заклинание \"%s%s%s\".\r\n", CCICYN(ch, C_NRM), spell_info[i->spellnum].name, CCNRM(ch, C_NRM)); send_to_char(buf, ch); GET_SPELL_MEM(ch, i->spellnum)++; free(i); } else prev = i; i = next; } } }
/* * Rough duplicate of PC's cast. * @param mob the mobile * @vict the target of the spell * @spell_num the spell * @return TRUE if the mob was able to cast a spell even though it failed */ bool mob_cast(struct char_data *mob, struct char_data *vict, int spell_num) { int manaCost = mag_manacost(mob, spell_num); if(spell_num > 0 && manaCost <= GET_MANA(mob) && spell_info[spell_num].min_level[(int)GET_CLASS(mob)] <= GET_LEVEL(mob) && !AFF_FLAGGED(mob, AFF_SILENCE) && GET_WAIT_STATE(mob) < 1) { /* This is a very simple check for 'spell success'. In the future a more * sophisticated approach should be implemented. */ if(rand_number(0, 30) <= GET_INT(mob)) { cast_spell(mob, vict, NULL, spell_num); } /* even if the mob fails, they will still be "stunned" for a round */ WAIT_STATE(mob, PULSE_VIOLENCE); GET_MANA(mob) = MAX(0, MIN(GET_MAX_MANA(mob), GET_MANA(mob) - manaCost)); return TRUE; } return FALSE; }