Example #1
0
        /// <summary>
        /// Callback sub-method for all units (player, npc, mob, pet, homu, merc)
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="args"></param>
        private static void Callback_GetAreaCharUnit(WorldObject obj, object[] args)
        {
            Character src = (Character)args[0];

            if (src == null || obj == null)
            {
                return;
            }

            WorldObjectViewData vd = WorldObject.GetViewData(obj);

            if (vd == null /* || vd.Class == INVISIBLE_CLASS)*/)
            {
                return;
            }

            // Unit is walking?
            if ((obj is WorldObjectUnit) && (obj as WorldObjectUnit).WalkTimer != null)
            {
                World.Send(new WorldSendUnitWalking(obj), src, ESendTarget.Self);
            }
            else
            {
                World.Send(new WorldSendUnitIdle(obj, false), src, ESendTarget.Self);
            }

            if (vd.ClothesColor > 0)
            {
                //clif_refreshlook(&sd->bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,SELF);
            }

            switch (obj.Type)
            {
            case EDatabaseType.Char:
                //clif_getareachar_pc

                // Special states
                // Battleground emblem
                break;

            case EDatabaseType.Mob:
                // Special states/sizes
                break;

            case EDatabaseType.Mercenary:
                // Devotion effect
                break;

            case EDatabaseType.Npc:
                // Chat over head
                // Special states/sizes
                break;

            case EDatabaseType.Pet:
                // Head bottom (Pet equip)
                break;
            }
        }
Example #2
0
        public WorldSendUnitWalking(WorldObject obj)
            : base(0)
        {
            WorldObjectStatusChangeList sc = WorldObject.GetStatusChange(obj);
            WorldObjectViewData         vd = WorldObject.GetViewData(obj);
            string name  = WorldObject.GetName(obj);
            ushort speed = WorldObject.GetSpeed(obj);

            Writer.Position = 0;
            Write((short)0x7f7);
            Write((short)(69 + name.Length));

            Write((byte)obj.GetPacketType());
            Write((uint)(obj is Character ? (obj as Character).Account.ID : obj.ID)); // For Character, send accountID as unique ID
            Write((ushort)speed);                                                     // status_get_speed(bl);
            Write((short)(sc != null ? sc.Option1 : 0));                              // (sc) ? sc->opt1 : 0;
            Write((short)(sc != null ? sc.Option2 : 0));                              // (sc) ? sc->opt2 : 0;
            Write((int)(sc != null ? sc.Option : 0));                                 // (sc) ? sc->option : 0;
            Write((short)vd.Class);                                                   // vd->class_;
            Write((short)vd.HairStlye);                                               // vd->hair_style;
            Write((short)vd.Weapon);                                                  // vd->weapon;
            Write((short)vd.Shield);                                                  // vd->shield;
            Write((short)vd.HeadBottom);                                              // vd->head_bottom
            Write((int)Timer.Ticks);
            Write((short)vd.HeadTop);                                                 // vd->head_top;
            Write((short)vd.HeadMid);                                                 // vd->head_mid;

            Write((short)vd.HairColor);                                               // vd->hair_color;
            Write((short)vd.ClothesColor);                                            // vd->cloth_color;
            Write((short)0);                                                          // (sd) ? sd->head_dir : 0;


            Write((int)0);                             // status_get_guild_id(bl);
            Write((short)0);                           // status_get_emblem_id(bl);
            Write((short)0);                           // (sd) ? sd->status.manner : 0;

            Write((int)(sc != null ? sc.Option3 : 0)); // (sc) ? sc->opt3 : 0;

            Write((byte)0);                            // (sd) ? sd->status.karma : 0;
            Write((byte)vd.Sex);                       // vd->sex;
            Write((obj as WorldObjectUnit).Location);
            Write((byte)(obj is Character ? 5 : 0));   // (sd) ? 5 : 0;
            Write((byte)(obj is Character ? 5 : 0));   // (sd) ? 5 : 0;
            Write((short)WorldObject.GetLevel(obj));   // clif_setlevel(status_get_lv(bl));

            Write((short)0);                           // sd ? sd->state.user_font : 0;
            int pos = Writer.Position;

            Write(name);
            pos = Writer.Position;
        }
Example #3
0
		public MonsterDatabaseData()
			: base() {
			// TODO: this is just a hack to let status know that this is mob status
			//		 find some other way than a none-existing mob..
			Status = new WorldObjectStatus(mEmptyMonster);
			Drops = new MonsterDropList();
			Skills = new MonsterSkillList();
			ViewData = new WorldObjectViewData();
			SpawnInfo = new List<MonsterSpawnInfo>();
		}
        public static WorldObjectViewData GetViewData(DatabaseObject obj, int classID)
        {
            // Load base values by ID (mob, npc, hom, merc, ..)
            WorldObjectViewData vd = null;

            // Fetch base view data
            if (obj.Serial.Type == EDatabaseType.Mob)
            {
                vd = (obj as MonsterDatabaseData).ViewData;
            }
            else
            {
                vd = new WorldObjectViewData();
            }

            // Set specific values
            // TODO: why an additional switch for this? Oo ..
            switch (obj.Serial.Type)
            {
            case EDatabaseType.Npc:
                break;

            case EDatabaseType.Mob:
                break;

            case EDatabaseType.Char:
                Character c = (Character)World.Objects[EDatabaseType.Char, obj.Serial.ID];
                if (Character.CheckID(classID) == true)
                {
                    if ((c.StatusChange.Option & EStatusOption.Wedding) > 0)
                    {
                        classID = (int)EClientClass.Wedding;
                    }
                    else if ((c.StatusChange.Option & EStatusOption.Summer) > 0)
                    {
                        classID = (int)EClientClass.Summer;
                    }
                    else if ((c.StatusChange.Option & EStatusOption.Xmas) > 0)
                    {
                        classID = (int)EClientClass.Xmas;
                    }
                    else if ((c.StatusChange.Option & EStatusOption.Riding) > 0)
                    {
                        //Adapt class to a Mounted one.
                        switch ((EClientClass)classID)
                        {
                        case EClientClass.Knight:
                            classID = (int)EClientClass.Knight2;
                            break;

                        case EClientClass.Crusader:
                            classID = (int)EClientClass.Crusader2;
                            break;

                        case EClientClass.LordKnight:
                            classID = (int)EClientClass.LordKnight2;
                            break;

                        case EClientClass.Paladin:
                            classID = (int)EClientClass.Paladin2;
                            break;

                        case EClientClass.BabyKnight:
                            classID = (int)EClientClass.BabyKnight2;
                            break;

                        case EClientClass.BabyCrusader:
                            classID = (int)EClientClass.BabyCrusader2;
                            break;
                        }
                    }

                    // TODO: why the hell have they another datatype?
                    vd.Class = (ushort)classID;
                    //clif_get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
                    vd.HeadTop      = (ushort)c.Status.HeadTop;
                    vd.HeadMid      = (ushort)c.Status.HeadMid;
                    vd.HeadBottom   = (ushort)c.Status.HeadBottom;
                    vd.HairStlye    = (ushort)c.Status.HairStyle;
                    vd.HairColor    = (ushort)c.Status.HairColor;
                    vd.ClothesColor = (ushort)c.Status.ClothColor;
                    vd.Sex          = c.Status.Sex;
                }
                else
                {
                }
                break;
            }

            return(vd);
        }
Example #5
0
        /// First packet after selecting a character
        /// 0x0436 19: <accountID>.L <charID>.L <loginID1>.L <clientTick>.L <sex>.B
        public static void WantToConnect(NetState state, PacketReader reader)
        {
            int         accountID  = reader.ReadInt32();
            int         charID     = reader.ReadInt32();
            int         loginID1   = reader.ReadInt32();
            int         clientTick = reader.ReadInt32();
            byte        iSex       = reader.ReadByte();
            EAccountSex sex        = (EAccountSex)iSex;

            state.Account = (Account)World.Objects[EDatabaseType.Account, accountID];
            if (state.Account == null || state.Account.AccountState != EAccountState.Char)
            {
                ServerConsole.DebugLine("Invalid account or account state: {0}", (state.Account != null ? state.Account.AccountState.ToString() : "null"));
                state.Disconnect();
                return;
            }
            if (state.Account.LoginID1 != loginID1 || state.Account.Sex != sex)
            {
                ServerConsole.DebugLine("Invalid loginID or sex: {0} != {1}; {2} != {3}", state.Account.LoginID1, loginID1, state.Account.Sex, sex);
                state.Disconnect();
                return;
            }
            if (state.Account.ActiveChar == null || state.Account.ActiveChar.ID != charID)
            {
                ServerConsole.DebugLine("Invalid active character or charID: {0}", (state.ActiveChar != null ? state.ActiveChar.ID.ToString() : "null"));
                state.Disconnect();
                return;
            }

            // Seems to be valid, save the netstate
            state.Account.Netstate = state;

            long tick = Timer.Ticks;

            // Mark as authed
            state.Account.AccountState = EAccountState.World;

            // pc_setnew
            state.ActiveChar.Status.Sex   = state.Account.Sex;
            state.ActiveChar.LoginID1     = loginID1;
            state.ActiveChar.LoginID2     = 0;
            state.ActiveChar.ClientTick   = clientTick;
            state.ActiveChar.State.Active = false;             //Is set to true after player is fully authed and loaded

            state.ActiveChar.CanLogTick = tick;
            // Required to prevent homunculus copuing a base speed of 0
            state.ActiveChar.BattleStatus.Speed = (ushort)Global.DEFAULT_WALK_SPEED;

            // pc_authok
            if (state.ActiveChar.Status.HP == 0)
            {
                state.ActiveChar.SetDead();
            }
            state.ActiveChar.State.ConnectNew = true;

            state.ActiveChar.FollowTimer    = null;
            state.ActiveChar.InvisibleTimer = null;
            state.ActiveChar.NpcTimer       = null;
            state.ActiveChar.PvpTimer       = null;

            state.ActiveChar.CanUseItemTick     = tick;
            state.ActiveChar.CanUseCashFoodTick = tick;
            state.ActiveChar.CanEquipTick       = tick;
            state.ActiveChar.CanTalkTick        = tick;
            state.ActiveChar.CanSendMailTick    = tick;

            state.ActiveChar.SpiritTimer = new List <Timer>();
            state.ActiveChar.AutoBonus.Clear();
            state.ActiveChar.AutoBonus2.Clear();
            state.ActiveChar.AutoBonus3.Clear();

            if (Config.ItemAutoGet)
            {
                state.ActiveChar.State.Autoloot = 10000;
            }
            if (Config.DispExperience)
            {
                state.ActiveChar.State.Showexp = true;
            }
            if (Config.DispZeny)
            {
                state.ActiveChar.State.Showzeny = true;
            }
            if ((Config.DisplaySkillFail & 2) > 0)
            {
                state.ActiveChar.State.Showdelay = true;
            }

            // Check and move equip
            //pc_setinventorydata(sd);
            for (int i = 0; i < state.ActiveChar.Status.Inventory.Count; i++)
            {
            }
            //pc_setequipindex(sd);

            // status_change_init here!
            // Note: eAthena dosnt realy init the status here, just memset() all to 0

            // TODO: why did i set StatusChange.Clear() HERE? confirm this..
            state.ActiveChar.StatusChange.Clear();

            // TODO: implement player commands (eAthenas @commands)
            //if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) && (pc_isGM(sd) >= get_atcommand_level(atcommand_hide)))
            //	sd->status.option &= (OPTION_MASK | OPTION_INVISIBLE);
            //else
            state.ActiveChar.Status.Option &= EStatusOption.Mask;

            state.ActiveChar.StatusChange.Option = state.ActiveChar.Status.Option;             // This is the actual option used in battle
            // Set here because we need the inventory data for weapon sprite parsing
            state.ActiveChar.ViewData = WorldObjectViewData.GetViewData(state.ActiveChar.Status, (int)state.ActiveChar.Status.Class);

            // Set base timer for walkable units (from unit_setdata)
            // TODO: maybe this should be placed in a WorldObjectUnit-method to be used for every walkable unit..
            state.ActiveChar.WalkTimer           = null;
            state.ActiveChar.ActiveSkillTimer    = null;
            state.ActiveChar.AttackTimer         = null;
            state.ActiveChar.AttackableTick      =
                state.ActiveChar.CanActTick      =
                    state.ActiveChar.CanMoveTick = tick;

            // clif_authok crap
            state.ActiveChar.GuildPosition = new Point2D(-1, -1);

            // Event timer
            state.ActiveChar.EventTimer = new List <Timer>();
            // Rental Timer
            state.ActiveChar.RentalTimer = null;

            state.ActiveChar.HateMob = new short[3] {
                -1, -1, -1
            };

            // Character enters the map block
            // TODO: Position checking
            state.ActiveChar.Location.Map.OnEnter(state.ActiveChar);

            /*
             * if ((i = pc_setpos(sd, sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != 0) {
             *      ShowError("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i);
             *
             *      // try warping to a default map instead (church graveyard)
             *      if (pc_setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != 0) {
             *              // if we fail again
             *              clif_authfail_fd(sd->fd, 0);
             *              return false;
             *      }
             * }
             */

            // Let the client know that the authendication was successfull
            state.Send(new WorldResponseAuthOK(state.Account));

            // eA puts the "char logged in" message here..

            // TODO: send friend list

            // TODO: message about expired accounts, night flag

            // TODO: request registry
            //		 or dont need an async load of registry?

            state.ActiveChar.DieCounter = -1;
        }
Example #6
0
		public Character(DatabaseID dbID, bool addToWorld)
			: base(dbID, addToWorld) {
			BaseStatus = new WorldObjectStatus(this);
			BattleStatus = new WorldObjectStatus(this);
			ViewData = new WorldObjectViewData();
			StatusChange = new WorldObjectStatusChangeList();

			// TODO: i dont where eAthena initialize them realy..
			//		 they using struct, which cant be null x.x
			Regen = new WorldObjectRegenerationData(this);
			HPRegen = new StatusVariationData();
			SPRegen = new StatusVariationData();
			SRegen = new CharacterRegenerationData();
			SSRegen = new CharacterRegenerationData();
		}
Example #7
0
        public WorldSendUnitIdle(WorldObject obj, bool spawn)
            : base(0)
        {
            string                      name   = WorldObject.GetName(obj);
            WorldObjectStatus           status = WorldObject.GetStatusData(obj);
            WorldObjectViewData         vd     = WorldObject.GetViewData(obj);
            WorldObjectStatusChangeList sc     = WorldObject.GetStatusChange(obj);
            ushort                      speed  = WorldObject.GetSpeed(obj);

            Writer.Position = 0;
            Write((short)(spawn ? 0x7f8 : 0x7f9));
            Write((short)((spawn ? 62 : 63) + name.Length));
            Write((byte)obj.GetPacketType());
            Write((uint)(obj is Character ? (obj as Character).Account.ID : obj.ID));      // For Character, send accountID as unique ID
            Write((ushort)speed);                                                          // status_get_speed(bl);
            Write((short)(sc != null ? sc.Option1 : 0));                                   // (sc) ? sc->opt1 : 0;
            Write((short)(sc != null ? sc.Option2 : 0));                                   // (sc) ? sc->opt2 : 0;
            Write((int)(sc != null ? sc.Option : 0));                                      // (sc) ? sc->option : 0;
            Write((short)(obj is NpcScript ? (obj as NpcScript).Class : (short)vd.Class)); // vd->class_;
            Write((short)(vd != null ? vd.HairStlye : 0));                                 // vd->hair_style;
            Write((short)(vd != null ? vd.Weapon : 0));                                    // vd->weapon;
            Write((short)(vd != null ? vd.Shield : 0));                                    // vd->shield;
            Write((short)(vd != null ? vd.HeadBottom : 0));                                // vd->head_bottom
            Write((short)(vd != null ? vd.HeadTop : 0));                                   // vd->head_top;
            Write((short)(vd != null ? vd.HeadMid : 0));                                   // vd->head_mid;

            // TODO: implementieren!

            /*
             * if (bl->type == BL_NPC && vd->class_ == FLAG_CLASS) {	//The hell, why flags work like this?
             *      WBUFL(buf, 22) = status_get_emblem_id(bl);
             *      WBUFL(buf, 26) = status_get_guild_id(bl);
             * }
             */

            Write((short)(vd != null ? vd.HairColor : 0));    // vd->hair_color;
            Write((short)(vd != null ? vd.ClothesColor : 0)); // vd->cloth_color;
            Write((short)0);                                  // (sd) ? sd->head_dir : 0;


            Write((int)0);                             // status_get_guild_id(bl);
            Write((short)0);                           // status_get_emblem_id(bl);
            Write((short)0);                           // (sd) ? sd->status.manner : 0;

            Write((int)(sc != null ? sc.Option3 : 0)); // (sc) ? sc->opt3 : 0;

            Write((byte)0);                            // (sd) ? sd->status.karma : 0;
            Write((byte)(vd != null ? vd.Sex : 0));    // vd->sex;
            Write((obj as WorldObjectUnit).Location);
            Write((byte)(obj is Character ? 5 : 0));   // (sd) ? 5 : 0;
            Write((byte)(obj is Character ? 5 : 0));   // (sd) ? 5 : 0;
            if (!spawn)
            {
                Write((byte)(vd != null ? vd.DeadSit : 0)); // vd->dead_sit;
            }
            Write((short)WorldObject.GetLevel(obj));        // clif_setlevel(status_get_lv(bl));

            Write((short)0);                                // sd ? sd->state.user_font : 0;
            int pos = Writer.Position;

            Write(name);
            pos = Writer.Position;
        }