Пример #1
0
        /// <summary>
        /// Check for use of Direct targeted spells (TargetType.singleCharacterOffensive)
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="victim"></param>
        /// <param name="spell"></param>
        /// <param name="percent"></param>
        /// <returns></returns>
        public static bool CheckOffensive( CharData ch, CharData victim, Spell spell, int percent )
        {
            if (ch == null) return false;
            string buf = String.Format("CheckOffensive: spell ({0})'{1}'", spell, spell.Name);
            Log.Trace( buf );

            if( spell == null )
                return false;

            if( ch.HasSpell(spell) && ( MUDMath.NumberPercent() < percent ) )
            {
                if (spell.ValidTargets != TargetType.singleCharacterOffensive &&
                        spell.ValidTargets != TargetType.none &&
                        spell.ValidTargets != TargetType.singleCharacterRanged)
                    Log.Error( "Check_spellup:  Mob casting spell {0} which is neither _targetType offensive nor ignore.a", spell );

                SocketConnection.Act( "$n&n  starts casting...", ch, null, null, SocketConnection.MessageTarget.room );
                ch.SetAffectBit( Affect.AFFECT_CASTING );
                CastData caster = new CastData();
                caster.Who = ch;
                caster.Eventdata = Event.CreateEvent(Event.EventType.spell_cast, spell.CastingTime, ch, victim, spell);
                Database.CastList.Add( caster );
                return true;
            }

            return false;
        }
Пример #2
0
        // This _function should prevent a mob from spamming
        // spellups on itself if it is already affected by the spell.
        // in the Spellup() _function, checks for Affect.AFFECT_WHATEVER
        // still need to be done. - Xangis
        static bool CheckSpellup( CharData ch, string name, int percent )
        {
            if (ch == null) return false;
            if (String.IsNullOrEmpty(name))
                return false;

            Spell spell = Spell.SpellList[name];
            if (spell == null)
            {
                return false;
            }

            // Keep mobs from casting spells they are affected by
            if( ch.HasAffect( Affect.AffectType.spell, spell ) )
                return false;

            if( ( ch.HasSpell( name ) )
                    && ( MUDMath.NumberPercent() < percent ) )
            {
                if (spell.ValidTargets != TargetType.singleCharacterDefensive &&
                        spell.ValidTargets != TargetType.self)
                    Log.Error( "CheckSpellup:  Mob casting spell {0} which is neither TargetType.self nor TargetType.defensive.", spell );

                SocketConnection.Act( "$n&n starts casting...", ch, null, null, SocketConnection.MessageTarget.room );
                ch.SetAffectBit( Affect.AFFECT_CASTING );
                CastData caster = new CastData();
                caster.Who = ch;
                caster.Eventdata = Event.CreateEvent(Event.EventType.spell_cast, spell.CastingTime, ch, ch, spell);
                Database.CastList.Add( caster );
                return true;
            }

            return false;
        }
Пример #3
0
        /// <summary>
        /// Called by the cast function to process a spell's targets and react accordingly.
        /// </summary>
        /// <param name="ch"></param>
        /// <param name="spell"></param>
        /// <param name="argument"></param>
        private static void ProcessSpellTargets(CharData ch, Spell spell, string argument)
        {
            Object obj = null;
            Target target = null;
            CharData victim = null;

            if (!ch.IsClass(CharClass.Names.bard))
                switch (spell.ValidTargets)
                {
                    default:
                        Log.Error("Magic.Cast: bad target type for spell {0}.  Type is: {1}", spell.Name, spell.ValidTargets.ToString());
                        return;
                    case TargetType.none:
                        target = new Target(argument);
                        break;
                    case TargetType.singleCharacterWorld:
                        victim = ch.GetCharWorld(argument);
                        if (victim == null)
                        {
                            ch.SendText("Cast the spell on whom?\r\n");
                            return;
                        }
                        target = new Target(victim);
                        break;
                    case TargetType.trap:
                        ch.SendText("You cannot cast a trap!\r\n");
                        return;
                    case TargetType.singleCharacterOffensive:
                        if (String.IsNullOrEmpty(argument))
                        {
                            victim = ch.Fighting;
                            if (victim == null)
                            {
                                if (ch.IsClass(CharClass.Names.psionicist))
                                    ch.SendText("Will the spell upon whom?\r\n");
                                else
                                    ch.SendText("Cast the spell upon whom?\r\n");
                                return;
                            }
                        }
                        else
                        {
                            victim = ch.GetCharRoom(argument);
                            if (!victim)
                            {
                                ch.SendText("They aren't here.\r\n");
                                return;
                            }
                        }

                        if (ch.IsAffected( Affect.AFFECT_CHARM) && ch.Master == victim)
                        {
                            ch.SendText("You can't do that to your master!.\r\n");
                            return;
                        }

                        if (Combat.IsSafe(ch, victim))
                            return;
                        // Combat.IsSafe could wipe out victim, as it calls procs if a boss
                        // check and see that victim is still valid
                        if (!victim)
                            return;

                        Crime.CheckAttemptedMurder(ch, victim);
                        target = new Target(victim);
                        ch.BreakInvisibility();
                        break;

                    case TargetType.singleCharacterDefensive:
                        if (String.IsNullOrEmpty(argument))
                        {
                            victim = ch;
                        }
                        else
                        {
                            victim = ch.GetCharRoom(argument);
                            if (victim == null)
                            {
                                ch.SendText("They aren't here.\r\n");
                                return;
                            }
                        }

                        target = new Target(victim);
                        break;

                    case TargetType.self:
                        if (!String.IsNullOrEmpty(argument) && !MUDString.NameContainedIn(argument, ch.Name) &&
                                "me".Equals(argument, StringComparison.CurrentCultureIgnoreCase) &&
                                "self".Equals(argument, StringComparison.CurrentCultureIgnoreCase))
                        {
                            ch.SendText("You cannot cast this spell on another.\r\n");
                            return;
                        }

                        target = new Target(ch);
                        break;

                    case TargetType.objectInInventory:
                        if (String.IsNullOrEmpty(argument))
                        {
                            ch.SendText("What item should the spell be cast upon?\r\n");
                            return;
                        }

                        obj = ch.GetObjCarrying(argument);
                        if (obj == null)
                        {
                            ch.SendText("You are not carrying that.\r\n");
                            return;
                        }

                        target = new Target(obj);
                        break;

                    case TargetType.objectInRoom:
                        if (String.IsNullOrEmpty(argument))
                        {
                            ch.SendText("What should the spell be cast upon?\r\n");
                            return;
                        }

                        obj = ch.GetObjHere(argument);
                        if (obj == null)
                        {
                            ch.SendText("You do not see that here.\r\n");
                            return;
                        }

                        target = new Target(obj);
                        break;

                    case TargetType.objectCorpse:
                        target = new Target(argument);
                        break;
                    case TargetType.objectOrCharacter:
                        if (String.IsNullOrEmpty(argument))
                        {
                            if (ch.Fighting != null)
                                victim = ch.Fighting;
                            else
                            {
                                ch.SendText("Cast upon what?\r\n");
                                return;
                            }
                        }
                        else if (!(victim = ch.GetCharRoom(argument)))
                        {
                            obj = ch.GetObjHere(argument);
                        }

                        if (victim != null)
                        {
                            target = new Target(victim);
                        }
                        else if (obj != null)
                        {
                            target = new Target(obj);
                        }
                        else
                        {
                            ch.SendText("You do not see that here.\r\n");
                            return;
                        }

                        break;
                    case TargetType.singleCharacterRanged:
                        if (String.IsNullOrEmpty(argument))
                        {
                            victim = ch.Fighting;
                            if (victim == null)
                            {
                                ch.SendText("Cast the spell on whom?\r\n");
                                return;
                            }
                        }
                        else
                        {
                            victim = ch.GetCharRoom(argument);
                            if (!victim)
                            {
                                ch.SendText("They aren't here.\r\n");
                                return;
                            }
                            // Ranged combat.
                            //
                            // TODO: FIXME: The next line does not successfully get the required argument.
                            //int dir = Movement.FindExit(ch, arg3);
                            //if (ch._level >= Limits.LEVEL_IMMORTAL)
                            //{
                            //    buf = String.Format("Looking for {0} to the {1}.\r\n", arg2, arg3);
                            //    ch.SendText(buf);
                            //}
                            //if (ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.walled)
                            //        || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.blocked)
                            //        || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.secret)
                            //        || ch._inRoom._exitData[dir].HasFlag(Exit.ExitFlags.closed)
                            //        || !ch._inRoom._exitData[dir]._targetRoom
                            //        || ch._inRoom._area != ch._inRoom._exitData[dir]._targetRoom._area)
                            //{
                            //    ch.SendText("You see nothing in that direction.\r\n");
                            //    return;
                            //}
                            //room2 = Movement.FindRoom(ch, arg3);
                            //if (room2 == null)
                            //{
                            //    ch.SendText("You see nothing in that direction.\r\n");
                            //    return;
                            //}
                            //victim = CharData.GetCharAtRoom(room2, ch, arg2);
                            //if (victim == null)
                            //{
                            //    Room room3;
                            //    if (room2._exitData[dir] && ((room3 = Room.GetRoom(room2._exitData[dir]._vnum))) &&
                            //        spell == Spell.SpellList["fireball"])
                            //    {
                            //        victim = CharData.GetCharAtRoom(room3, ch, arg2);
                            //    }
                            //}
                            //if (victim == null)
                            //{
                            //    ch.SendText("They aren't here.\r\n");
                            //    return;
                            //}
                            //} //end else
                        } //end else
                        if (ch.IsAffected(Affect.AFFECT_CHARM) && ch.Master == victim)
                        {
                            ch.SendText("You can't do that to your master!.\r\n");
                            return;
                        }

                        if (Combat.IsSafe(ch, victim))
                            return;
                        // Combat.IsSafe could wipe out victim, as it calls procs if a boss
                        // check and see that victim is still valid
                        if (!victim)
                            return;

                        Crime.CheckAttemptedMurder(ch, victim);

                        target = new Target(victim);
                        ch.BreakInvisibility();
                        break;
                }

            int beats = 0;  // For quick chant
            if (!ch.IsClass(CharClass.Names.bard) && !ch.IsClass(CharClass.Names.psionicist))
            {
                ch.SendText( "You begin casting...\r\n" );
                if( "ventriloquate".Equals(spell.Name, StringComparison.CurrentCultureIgnoreCase ))
                {
                    if( spell.ValidTargets == TargetType.singleCharacterOffensive
                            || spell.ValidTargets == TargetType.singleCharacterRanged )
                        SocketConnection.Act( "$n&n begins casting an offensive spell...", ch, null, null, SocketConnection.MessageTarget.room );
                    else
                        SocketConnection.Act( "$n&n begins casting...", ch, null, null, SocketConnection.MessageTarget.room );
                }
                beats = spell.CastingTime;
            }
            else if (ch.IsClass(CharClass.Names.bard))
            {
                ch.SendText( "You begin singing...\r\n" );
                SocketConnection.Act( "$n&n starts singing...", ch, null, null, SocketConnection.MessageTarget.room );
                beats = 0;
            }

            if (!ch.IsClass(CharClass.Names.psionicist) && !ch.IsClass(CharClass.Names.bard))
            {
                // Characters with int of 110 have normal memtimes.
                // int of 100 worsens casting times by 10%
                // with an int of 55 casting times are doubled.
                // This may seem a bit harsh, but keep in mind any
                // casters are very likely to have an int above 100, as it
                // is their prime requisite.  120 is the max int for Grey Elves
                // to start.
                if (ch.IsClass(CharClass.Names.cleric) || ch.IsClass(CharClass.Names.druid)
                        || ch.IsClass(CharClass.Names.paladin) || ch.IsClass(CharClass.Names.antipaladin))
                {
                    beats = ( beats * 110 ) / ch.GetCurrWis();
                }
                else if (ch.IsClass( CharClass.Names.shaman))
                {
                    beats = ( beats * 330 ) / ( ch.GetCurrInt() + ( ch.GetCurrWis() * 2 ) );
                }
                else
                {
                    beats = ( beats * 110 ) / ch.GetCurrInt();
                }

                if( ch.CheckSkill("quick chant", PracticeType.only_on_success) )
                {
                    beats = beats / 2;
                }

                /*
                * A check for impossibly long cast times...came about from a player
                * trying to cast when feebleminded.  100 casting time is arbitrary.
                */
                if( beats > 100 )
                {
                    ch.SendText( "Forget it!  In your present state you haven't a dream of success.\r\n" );
                    return;
                }
                ch.WaitState( beats );

                if( CheckHypnoticPattern( ch ) )
                {
                    return;
                }

                CastData caster = new CastData();
                caster.Who = ch;
                caster.Eventdata = Event.CreateEvent( Event.EventType.spell_cast, beats, ch, target, spell );
                Database.CastList.Add( caster );
                ch.SetAffectBit( Affect.AFFECT_CASTING );
            }
            else if (ch.IsClass( CharClass.Names.psionicist))
            {
                ch.WaitState( beats );

                if( CheckHypnoticPattern( ch ) )
                {
                    return;
                }

                ch.PracticeSpell( spell );

                int mana = 0;
                if( !ch.IsImmortal() && !ch.IsNPC()
                        && ch.Level < ( spell.SpellCircle[ (int)ch.CharacterClass.ClassNumber ] * 4 + 1 )
                        && MUDMath.NumberPercent() > ((PC)ch).SpellAptitude[spell.Name])
                {
                    ch.SendText( "You lost your concentration.\r\n" );
                    SocketConnection.Act( "&+r$n&n&+r's face flushes white for a moment.&n", ch, null, null, SocketConnection.MessageTarget.room );
                    ch.CurrentMana -= mana / 2;
                }
                else
                {
                    ch.CurrentMana -= mana;
                    string buf = String.Format( "Spell {0} ({1}) being willed by {2}", spell,
                                                spell.Name, ch.Name );
                    Log.Trace( buf );
                    ch.SetAffectBit( Affect.AFFECT_CASTING );
                    FinishSpell( ch, spell, target );
                }
                if( ch.CurrentPosition > Position.sleeping && ch.CurrentMana < 0 )
                {
                    ch.WaitState( 2 * Event.TICK_PER_SECOND );
                    ch.SendText( "&+WThat last spe&+wll w&+Las a _bitvector&+l much...&n\r\n" );
                    ch.CurrentPosition = Position.standing;
                    ch.Fighting = null;
                    SocketConnection.Act( "$n&n collapses from exhaustion&n.",
                         ch, null, null, SocketConnection.MessageTarget.room );
                    ch.CurrentPosition = Position.sleeping;
                }

                if( spell.ValidTargets == TargetType.singleCharacterOffensive
                        && victim && victim.Master != ch && victim != ch && victim.IsAwake() )
                {
                    foreach( CharData roomChar in ch.InRoom.People )
                    {
                        if( victim == roomChar && !victim.Fighting )
                        {
                            victim.AttackCharacter( ch );
                            break;
                        }
                    }
                }
            }
            else if( ch.IsClass(CharClass.Names.bard ))
            {
                ch.WaitState( 0 );

                // Create an event to handle the spell
                CastData caster = new CastData();
                caster.Who = ch;
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG, ch, target, spell );
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 2, ch, target, spell);
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 3, ch, target, spell);
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 4, ch, target, spell);
                caster.Eventdata = Event.CreateEvent( Event.EventType.bard_song, Event.TICK_SONG * 5, ch, target, spell);
                Database.CastList.Add( caster );
                ch.SetAffectBit( Affect.AFFECT_SINGING );
            }
            return;
        }