bool psionic_mob_fight(struct creature *ch, struct creature *precious_vict) { struct creature *vict = NULL; if (!is_fighting(ch)) return false; // pick an enemy if (!(vict = choose_opponent(ch, precious_vict))) return false; int aggression = calculate_mob_aggression(ch, vict); // Psions can't really do anything when there's a psishield in place if (AFF3_FLAGGED(vict, AFF3_PSISHIELD) && can_cast_spell(ch, SPELL_PSIONIC_SHATTER)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSIONIC_SHATTER); return true; } // Prioritize healing with aggression if (GET_HIT(ch) < (GET_MAX_HIT(ch) * MIN(20, MAX(80, aggression)) / 100) && can_cast_spell(ch, SPELL_WOUND_CLOSURE)) { cast_spell(ch, ch, NULL, NULL, SPELL_WOUND_CLOSURE); return true; } if (aggression > 75) { // extremely aggressive - just attack hard if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return true; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return true; } } if (aggression > 50) { // somewhat aggressive - balance attacking with crippling if (GET_MANA(ch) < GET_MAX_MANA(ch) / 2 && can_cast_spell(ch, SKILL_PSIDRAIN) && can_psidrain(ch, vict, NULL, false)) { perform_psidrain(ch, vict); return true; } else if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH) && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH); return true; } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM) && can_cast_spell(ch, SPELL_MOTOR_SPASM)) { cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM); return true; } else if (!affected_by_spell(ch, SPELL_ADRENALINE) && can_cast_spell(ch, SPELL_ADRENALINE)) { cast_spell(ch, ch, NULL, NULL, SPELL_ADRENALINE); return true; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return true; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return true; } } if (aggression > 25) { // not very aggressive - play more defensively if (IS_PSIONIC(vict) && !affected_by_spell(ch, SPELL_PSYCHIC_RESISTANCE) && can_cast_spell(ch, SPELL_PSYCHIC_RESISTANCE)) { cast_spell(ch, ch, NULL, NULL, SPELL_PSYCHIC_RESISTANCE); return true; } else if (!IS_CONFUSED(vict) && can_cast_spell(ch, SPELL_CONFUSION) && (IS_MAGE(vict) || IS_PSIONIC(vict) || IS_CLERIC(vict) || IS_KNIGHT(vict) || IS_PHYSIC(vict))) { cast_spell(ch, vict, NULL, NULL, SPELL_CONFUSION); return true; } else if (GET_MOVE(ch) < GET_MAX_MOVE(ch) / 4 && can_cast_spell(ch, SPELL_ENDURANCE)) { cast_spell(ch, ch, NULL, NULL, SPELL_ENDURANCE); return true; } else if (GET_MOVE(ch) < GET_MAX_MOVE(ch) / 4 && can_cast_spell(ch, SPELL_DERMAL_HARDENING)) { cast_spell(ch, ch, NULL, NULL, SPELL_DERMAL_HARDENING); return true; } else if (!AFF2_FLAGGED(ch, AFF2_VERTIGO) && can_cast_spell(ch, SPELL_VERTIGO)) { cast_spell(ch, vict, NULL, NULL, SPELL_VERTIGO); return true; } else if (!affected_by_spell(vict, SPELL_PSYCHIC_FEEDBACK) && can_cast_spell(ch, SPELL_PSYCHIC_FEEDBACK)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_FEEDBACK); return true; } else if (!affected_by_spell(vict, SPELL_WEAKNESS) && can_cast_spell(ch, SPELL_WEAKNESS)) { cast_spell(ch, vict, NULL, NULL, SPELL_WEAKNESS); return true; } else if (!affected_by_spell(vict, SPELL_CLUMSINESS) && can_cast_spell(ch, SPELL_CLUMSINESS)) { cast_spell(ch, vict, NULL, NULL, SPELL_CLUMSINESS); return true; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return true; } } if (aggression > 5) { // attempt to neutralize or get away if (GET_POSITION(vict) > POS_SLEEPING && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) { cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD); return true; } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) { cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL); return true; } else if (can_cast_spell(ch, SPELL_AMNESIA)) { cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA); return true; } else if (can_cast_spell(ch, SPELL_FEAR)) { cast_spell(ch, vict, NULL, NULL, SPELL_FEAR); return true; } } return false; }
bool can_psidrain(struct creature *ch, struct creature *vict, int *out_dist, bool msg) { const char *to_char = NULL; const char *to_vict = NULL; int dist; if (CHECK_SKILL(ch, SKILL_PSIDRAIN) < 30 || !IS_PSIONIC(ch)) { to_char = "You have no idea how."; goto failure; } if (ROOM_FLAGGED(ch->in_room, ROOM_NOPSIONICS) && GET_LEVEL(ch) < LVL_GOD) { to_char = "Psychic powers are useless here!"; goto failure; } if (GET_LEVEL(vict) >= LVL_AMBASSADOR && GET_LEVEL(ch) < GET_LEVEL(vict)) { to_char = "You cannot locate them."; to_vict = "$n has just tried to psidrain you."; goto failure; } if (vict == ch) { to_char = "Ha ha... Funny!"; goto failure; } if (is_fighting(ch) && vict->in_room != ch->in_room) { to_char = "You cannot focus outside the room during battle!"; goto failure; } if (ch->in_room != vict->in_room && ch->in_room->zone != vict->in_room->zone) { to_char = "$N is not in your zone."; goto failure; } if (ROOM_FLAGGED(vict->in_room, ROOM_NOPSIONICS) && GET_LEVEL(ch) < LVL_GOD) { to_char = "Psychic powers are useless where $E is!"; goto failure; } if (!ok_to_attack(ch, vict, msg)) return false; if (GET_MOVE(ch) < 20) { to_char = "You are too physically exhausted."; goto failure; } dist = find_distance(ch->in_room, vict->in_room); if (out_dist) *out_dist = dist; if (dist > ((GET_LEVEL(ch) / 6))) { to_char = "$N is out of your psychic range."; goto failure; } if (NULL_PSI(vict)) { to_char = "It is pointless to attempt this on $M."; goto failure; } return true; failure: if (msg) { if (to_char) act(to_char, false, ch, NULL, vict, TO_CHAR); if (to_vict) act(to_vict, false, ch, NULL, vict, TO_VICT); } return false; }
/* say_spell erodes buf, buf1, buf2 */ void say_spell (struct char_data *ch, int spellnum, struct char_data *tch, struct obj_data *tobj) { char lbuf[256]; const char *format; struct char_data *i; int j, ofs = 0; *buf = '\0'; strcpy (lbuf, skill_name (spellnum)); while (lbuf[ofs]) { for (j = 0; *(syls[j].org); j++) { if (!strncmp (syls[j].org, lbuf + ofs, strlen (syls[j].org))) { strcat (buf, syls[j].news); ofs += strlen (syls[j].org); break; } } /* i.e., we didn't find a match in syls[] */ if (!*syls[j].org) { log ("No entry in syllable table for substring of '%s'", lbuf); ofs++; } } if (tch != NULL && IN_ROOM (tch) == IN_ROOM (ch)) { if (tch == ch) { if (IS_PSIONIC (ch) && (GET_LEVEL (ch) != LVL_IMPL)) { format = "$n congiunge le mani sulla testa e chiude i suoi occhi."; } else { format = "$n chiude i suoi occhi e lancia sul suo tricorder il processo, '%s'."; } } else { if (IS_PSIONIC (ch) && (GET_LEVEL (ch) != LVL_IMPL)) { format = "$n posa una mano sulla testa e punta l'altra su $N e chiude gli occhi."; } else { format = "$n punta il suo tricorder a $N e lancia il processo, '%s'."; } } } else if (tobj != NULL && ((IN_ROOM (tobj) == IN_ROOM (ch)) || (tobj->carried_by == ch))) { if (IS_PSIONIC (ch) && (GET_LEVEL (ch) != LVL_IMPL)) { format = "$n congiunge le mani su $p e chiude i suoi occhi."; } else { format = "$n punta il suo tricorder a $p e lancia il processo, '%s'."; } } else { if (IS_PSIONIC (ch) && (GET_LEVEL (ch) != LVL_IMPL)) { format = "$n congiunge le mani sulla testa e chiude i suoi occhi."; } else { format = "$n lancia sul suo tricorder il processo, '%s'."; } } sprintf (buf1, format, skill_name (spellnum)); sprintf (buf2, format, buf); for (i = world[IN_ROOM (ch)].people; i; i = i->next_in_room) { if (i == ch || i == tch || !i->desc || !AWAKE (i)) continue; if (GET_CLASS (ch) == GET_CLASS (i)) perform_act (buf1, ch, tobj, tch, i); else perform_act (buf2, ch, tobj, tch, i); } if (tch != NULL && tch != ch && IN_ROOM (tch) == IN_ROOM (ch)) { if (IS_PSIONIC (ch) && (GET_LEVEL (ch) != LVL_IMPL)) { sprintf (buf1, "$n posa una mano sulla testa e punta l'altra su di te."); } else { sprintf (buf1, "$n ti punta il suo tricorder e lancia il processo, '%s'.", GET_CLASS (ch) == GET_CLASS (tch) ? skill_name (spellnum) : buf); } act (buf1, FALSE, ch, NULL, tch, TO_VICT); } }
void psionic_best_attack(struct creature *ch, struct creature *vict) { int aggression = calculate_mob_aggression(ch, vict); // Psions can't really do anything when there's a psishield in place if (AFF3_FLAGGED(vict, AFF3_PSISHIELD) && can_cast_spell(ch, SPELL_PSIONIC_SHATTER)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSIONIC_SHATTER); return; } if (aggression > 75) { // extremely aggressive - just attack hard if (!affected_by_spell(vict, SPELL_PSYCHIC_SURGE) && can_cast_spell(ch, SPELL_PSYCHIC_SURGE)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_SURGE); return; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return; } } if (aggression > 50) { // somewhat aggressive - balance attacking with crippling if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH) && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH); return; } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM) && can_cast_spell(ch, SPELL_MOTOR_SPASM)) { cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM); return; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return; } } if (aggression > 25) { // not very aggressive - play more defensively if (!IS_CONFUSED(vict) && can_cast_spell(ch, SPELL_CONFUSION) && (IS_MAGE(vict) || IS_PSIONIC(vict) || IS_CLERIC(vict) || IS_KNIGHT(vict) || IS_PHYSIC(vict))) { cast_spell(ch, vict, NULL, NULL, SPELL_CONFUSION); return; } else if (!AFF2_FLAGGED(ch, AFF2_VERTIGO) && can_cast_spell(ch, SPELL_VERTIGO)) { cast_spell(ch, vict, NULL, NULL, SPELL_VERTIGO); return; } else if (!affected_by_spell(vict, SPELL_PSYCHIC_FEEDBACK) && can_cast_spell(ch, SPELL_PSYCHIC_FEEDBACK)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_FEEDBACK); return; } else if (nullpsi_is_advisable(vict) && can_cast_spell(ch, SPELL_NULLPSI)) { cast_spell(ch, vict, NULL, NULL, SPELL_NULLPSI); return; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return; } } if (aggression > 5) { // attempt to neutralize or get away if (GET_POSITION(vict) > POS_SLEEPING && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) { cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD); return; } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) { cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL); return; } else if (can_cast_spell(ch, SPELL_AMNESIA)) { cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA); return; } else if (can_cast_spell(ch, SPELL_FEAR)) { cast_spell(ch, vict, NULL, NULL, SPELL_FEAR); return; } } // desperation - just attack full force, as hard as possible if (!affected_by_spell(vict, SPELL_PSYCHIC_SURGE) && can_cast_spell(ch, SPELL_PSYCHIC_SURGE)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_SURGE); return; } else if (!affected_by_spell(vict, SPELL_PSYCHIC_CRUSH) && can_cast_spell(ch, SPELL_PSYCHIC_CRUSH)) { cast_spell(ch, vict, NULL, NULL, SPELL_PSYCHIC_CRUSH); return; } else if (!affected_by_spell(vict, SPELL_MOTOR_SPASM) && can_cast_spell(ch, SPELL_MOTOR_SPASM)) { cast_spell(ch, vict, NULL, NULL, SPELL_MOTOR_SPASM); return; } else if (can_cast_spell(ch, SKILL_PSIBLAST)) { perform_offensive_skill(ch, vict, SKILL_PSIBLAST); return; } else if (GET_POSITION(vict) > POS_SITTING && can_cast_spell(ch, SPELL_EGO_WHIP)) { cast_spell(ch, vict, NULL, NULL, SPELL_EGO_WHIP); return; } else if (GET_POSITION(vict) > POS_SLEEPING && can_cast_spell(ch, SPELL_MELATONIC_FLOOD)) { cast_spell(ch, vict, NULL, NULL, SPELL_MELATONIC_FLOOD); return; } else if (can_cast_spell(ch, SPELL_ASTRAL_SPELL)) { cast_spell(ch, vict, NULL, NULL, SPELL_ASTRAL_SPELL); return; } else if (can_cast_spell(ch, SPELL_AMNESIA)) { cast_spell(ch, vict, NULL, NULL, SPELL_AMNESIA); return; } else if (can_cast_spell(ch, SPELL_FEAR)) { cast_spell(ch, vict, NULL, NULL, SPELL_FEAR); return; } else { hit(ch, vict, TYPE_UNDEFINED); } }
int invalid_char_class(struct creature *ch, struct obj_data *obj) { // Protected object if (IS_PC(ch) && obj->shared->owner_id != 0 && obj->shared->owner_id != GET_IDNUM(ch)) { return true; } // Unapproved object if (!OBJ_APPROVED(obj) && !is_tester(ch) && GET_LEVEL(ch) < LVL_IMMORT) return true; // Anti class restrictions if ((IS_OBJ_STAT(obj, ITEM_ANTI_MAGIC_USER) && IS_MAGIC_USER(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_CLERIC) && IS_CLERIC(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_WARRIOR) && IS_WARRIOR(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_THIEF) && IS_THIEF(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_BARB) && IS_BARB(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_PSYCHIC) && IS_PSYCHIC(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_PHYSIC) && IS_PHYSIC(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_CYBORG) && IS_CYBORG(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_KNIGHT) && IS_KNIGHT(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_RANGER) && IS_RANGER(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_BARD) && IS_BARD(ch)) || (IS_OBJ_STAT(obj, ITEM_ANTI_MONK) && IS_MONK(ch)) || (IS_OBJ_STAT2(obj, ITEM2_ANTI_MERC) && IS_MERC(ch))) return true; // Required class restrictions - any one of them must be met if ((IS_OBJ_STAT3(obj, ITEM3_REQ_MAGE) && IS_MAGE(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_CLERIC) && IS_CLERIC(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_THIEF) && IS_THIEF(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_WARRIOR) && IS_WARRIOR(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_BARB) && IS_BARB(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_PSIONIC) && IS_PSIONIC(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_PHYSIC) && IS_PHYSIC(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_CYBORG) && IS_CYBORG(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_KNIGHT) && IS_KNIGHT(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_RANGER) && IS_RANGER(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_BARD) && IS_BARD(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_MONK) && IS_MONK(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_VAMPIRE) && IS_VAMPIRE(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_MERCENARY) && IS_MERC(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_SPARE1) && IS_SPARE1(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_SPARE2) && IS_SPARE2(ch)) || (IS_OBJ_STAT3(obj, ITEM3_REQ_SPARE3) && IS_SPARE3(ch))) return false; // A required class existed and the creature didn't fulfill any if (IS_OBJ_STAT3(obj, ITEM3_REQ_MAGE | ITEM3_REQ_CLERIC | ITEM3_REQ_THIEF | ITEM3_REQ_WARRIOR | ITEM3_REQ_BARB | ITEM3_REQ_PSIONIC | ITEM3_REQ_PHYSIC | ITEM3_REQ_CYBORG | ITEM3_REQ_KNIGHT | ITEM3_REQ_RANGER | ITEM3_REQ_BARD | ITEM3_REQ_MONK | ITEM3_REQ_VAMPIRE | ITEM3_REQ_MERCENARY | ITEM3_REQ_SPARE1 | ITEM3_REQ_SPARE2 | ITEM3_REQ_SPARE3)) return true; // Passes all tests return false; }