public static void UpdateStance(Actor actor) { if (actor == null) return; Regiontree tree = actor.currentzone.Regiontree; foreach (Character target in tree.SearchActors(actor, SearchFlags.Characters)) { if (Point.IsInSightRangeByRadius(target.Position, actor.Position)) { SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE(); spkt.Stance = actor.stance; spkt.State = 0; spkt.SessionId = target.id; spkt.ActorID = actor.id; spkt.TargetActor = actor._targetid; target.client.Send((byte[])spkt); } } }
/// <summary> /// Notifies the client to load start sending all pre-cached and yet to be /// processed packets. /// /// See the above method /// </summary> /// <remarks> /// Due the nature of this method we'll be invoking a notification on /// our "assumed" to be pending LoadMap method. We'll process all Moveable /// objects in the sightrange here. /// /// We cannot do this when we're precaching because suppose the client takes /// 10 minutes to load, all the moveable monsters and characters can be gone /// already. And thus sending outdated information. /// </remarks> private void CM_CHARACTER_MAPLOADED() { try { #region Internal //Register on the new map this.character.currentzone.Regiontree.Subscribe(this.character); //GET NEW Z-POS float z = character.Position.z + 100; //Refresh Personal Requests CommonFunctions.RefreshPersonalRequests(this.character); Regiontree.UpdateRegion(this.character); isloaded = false; #endregion Internal #region Actor infromation { /* * Send actor information * * This packet makes a actor appear on the screen. Just like character information * It defines automaticly which actor is your actor. */ SMSG_ACTORINFO spkt = new SMSG_ACTORINFO(); spkt.ActorID = this.character.id; spkt.X = this.character.Position.x; spkt.Y = this.character.Position.y; spkt.Z = this.character.Position.z; spkt.race = this.character.race; spkt.face = this.character.FaceDetails; spkt.ActiveWeaponIndex = (byte)this.character.weapons.ActiveWeaponIndex; spkt.InventoryContainerSize = (byte)this.character.container.Capacity; spkt.StorageContainerSize = (byte)this.character.STORAGE.Capacity; spkt.UnlockedWeaponCount = this.character.weapons.UnlockedWeaponSlots; spkt.Unknown = 0; spkt.PrimaryWeaponByIndex = this.character.weapons.PrimaryWeaponIndex; spkt.SeccondairyWeaponByIndex = this.character.weapons.SeconairyWeaponIndex; spkt.Name = this.character.Name; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Actor infromation #region Battle Stats { CommonFunctions.SendBattleStatus(this.character); } #endregion Battle Stats #region Extend Stats { /* * Sends over the status points attributes * */ SMSG_EXTSTATS spkt2 = new SMSG_EXTSTATS(); spkt2.base_stats_1 = character.stats.BASE; spkt2.base_stats_2 = character.stats.CHARACTER; spkt2.base_stats_jobs = character.stats.EQUIPMENT; spkt2.base_stats_bonus = character.stats.ENCHANTMENT; spkt2.statpoints = character.stats.REMAINING; spkt2.SessionId = character.id; this.Send((byte[])spkt2); } #endregion Extend Stats if (IsFirstTimeLoad) { #if THREADING WaitCallback FireTimeLoginCallback = delegate(object a) { #else { #endif #region Equipment List { /* * Sends a list of all Equiped Equipment */ SMSG_EQUIPMENTLIST spkt = new SMSG_EQUIPMENTLIST(); for (int i = 0; i < 16; i++) { Rag2Item item = this.character.Equipment[i]; if (item != null) spkt.AddItem(item, item.active, i); } spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Equipment List #region Weaponary List { /* * Sends a list of all weapons */ SMSG_WEAPONLIST spkt = new SMSG_WEAPONLIST(); spkt.SessionId = this.character.id; for (int i = 0; i < 5; i++) { Weapon current = this.character.weapons[i]; spkt.AddWeapon(current); } this.Send((byte[])spkt); } #endregion Weaponary List #region Unlock Weaponary { /* * This packet unlocks the selected slots */ SMSG_ADDITIONLIST spkt = new SMSG_ADDITIONLIST(); spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Unlock Weaponary #region Character Status { /* * Send Character status * * This updates the characters status, this defines which job you're using * the experience you have. The experience is expressed in absolute values * so it doesn't represent a relative value for exp required. * * It also contains the definitions of how many LC, LP, HP, SP you have. * Note: LC represents the amount of breath capacity. */ SMSG_CHARSTATUS spkt = new SMSG_CHARSTATUS(); spkt.Job = this.character.job; spkt.Exp = this.character.Cexp; spkt.JobExp = this.character.Jexp; spkt.LC = this.character._status.CurrentOxygen; spkt.MaxLC = this.character._status.MaximumOxygen; spkt.HP = this.character.HP; spkt.MaxHP = this.character.HPMAX; spkt.SP = this.character.SP; spkt.MaxSP = this.character.SPMAX; spkt.LP = this.character._status.CurrentLp; spkt.MaxLP = 7; spkt.FieldOfSight = 0; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Character Status #region Battle Skills { /* * Region Send all battle skills * * Also known as all active skills, heals, buffs included */ List<Skill> list = this.character.learnedskills; SMSG_BATTLESKILL battleskills = new SMSG_BATTLESKILL(list.Count); foreach (Skill skill in list) battleskills.AddSkill(skill.Id, skill.Experience); battleskills.SessionId = this.character.id; this.Send((byte[])battleskills); } #endregion Battle Skills #region Special Skills { /* * Sends over an list of special skills * */ SMSG_LISTSPECIALSKILLS spkt = new SMSG_LISTSPECIALSKILLS(); for (int i = 0; i < 16; i++) { Skill skill = character.SpecialSkills[i]; if (skill != null) { spkt.AddSkill(skill.info.skillid, skill.Experience, (byte)i); } } spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Special Skills #region Update Zeny { /* * Send Money * * This sets the money of a player to a absolute value. For instance if you * say 500, it would mean the player gets 500 rufi. There are no relative * values for TakeMoney or GiveMoney. */ SMSG_SENDZENY spkt = new SMSG_SENDZENY(); spkt.Zeny = this.character.ZENY; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Update Zeny #region Send Quest List { SMSG_QUESTINFO spkt3 = new SMSG_QUESTINFO(); spkt3.SessionId = this.character.id; foreach (QuestBase Quest in this.character.QuestObjectives) { List<Saga.Quests.Objectives.ObjectiveList.StepInfo> Steps = QuestBase.GetSteps(this.character, Quest.QuestId); spkt3.AddQuest(Quest.QuestId, (byte)Steps.Count); for (int i = 0; i < Steps.Count; i++) { Saga.Quests.Objectives.ObjectiveList.StepInfo currentStep = Steps[i]; uint nextstep = (i + 1 < Steps.Count) ? Steps[i + 1].StepId : 0; spkt3.AddQuestStep(currentStep.StepId, currentStep.State, nextstep, Quest.isnew); } } this.Send((byte[])spkt3); foreach (QuestBase Quest in this.character.QuestObjectives) { List<Saga.Quests.Objectives.ObjectiveList.StepInfo> Steps = QuestBase.GetSteps(this.character, Quest.QuestId); for (int i = 0; i < Steps.Count; i++) { Saga.Quests.Objectives.ObjectiveList.StepInfo currentStep = Steps[i]; if (currentStep.State == 1) { Predicate<Saga.Quests.Objectives.ObjectiveList.SubStep> Findsubstep = delegate(Saga.Quests.Objectives.ObjectiveList.SubStep objective) { return objective.Quest == Quest.QuestId && objective.StepId == currentStep.StepId; }; List<Quests.Objectives.ObjectiveList.SubStep> Substeps = this.character.QuestObjectives.Substeps.FindAll(Findsubstep); foreach (Saga.Quests.Objectives.ObjectiveList.SubStep substep in Substeps) { if (substep.current > 0) { SMSG_QUESTSUBSTEPUPDATE spkt = new SMSG_QUESTSUBSTEPUPDATE(); spkt.Unknown = 1; spkt.SubStep = (byte)substep.SubStepId; spkt.StepID = substep.StepId; spkt.QuestID = substep.Quest; spkt.Amount = (byte)substep.current; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } } break; } } } } #endregion Send Quest List #region Send Way Points { foreach (QuestBase Quest in this.character.QuestObjectives) { SMSG_SENDNAVIGATIONPOINT spkt2 = new SMSG_SENDNAVIGATIONPOINT(); spkt2.SessionId = this.character.id; spkt2.QuestID = Quest.QuestId; foreach (Saga.Quests.Objectives.ObjectiveList.Waypoint waypoint in QuestBase.UserGetWaypoints(this.character, Quest.QuestId)) { Predicate<MapObject> IsNpc = delegate(MapObject match) { return match.ModelId == waypoint.NpcId; }; MapObject myObject = this.character.currentzone.Regiontree.SearchActor(IsNpc, SearchFlags.Npcs); if (myObject != null) { spkt2.AddPosition(waypoint.NpcId, myObject.Position.x, myObject.Position.y, myObject.Position.z); } } this.Send((byte[])spkt2); } } #endregion Send Way Points #region Addition List { SMSG_ADDITIONLIST spkt = new SMSG_ADDITIONLIST(); spkt.SessionId = this.character.id; foreach (AdditionState state in character._additions) { if (state.CanExpire) { spkt.Add(state.Addition, state.Lifetime); } else { spkt.Add(state.Addition, 0); } } this.Send((byte[])spkt); } #endregion Addition List #region Scenario { QuestBase scenarioQuest = this.character.QuestObjectives.Quests[3]; if (scenarioQuest != null) { SMSG_INITIALIZESCENARIO spkt = new SMSG_INITIALIZESCENARIO(); spkt.Scenario1 = scenarioQuest.QuestId; List<Saga.Quests.Objectives.ObjectiveList.StepInfo> list; if (this.character.QuestObjectives.ScenarioSteps.TryGetValue(scenarioQuest.QuestId, out list)) if (list.Count > 0) { spkt.Scenario2 = list[0].StepId; spkt.StepStatus = 1; spkt.Enabled = 0; } spkt.SessionId = this.character.id; this.Send((byte[])spkt); } else { QuestBase qbase; if (Singleton.Quests.TryFindScenarioQuest(1, out qbase)) { qbase.OnStart(character.id); } } } #endregion Scenario #region Mail { int count = Singleton.Database.GetInboxUncheckedCount(this.character.Name); SMSG_MAILARRIVED spkt = new SMSG_MAILARRIVED(); spkt.Amount = (uint)count; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } #endregion Mail #region Inventory List { SMSG_INVENTORYLIST spkt5 = new SMSG_INVENTORYLIST((byte)this.character.container.Count); spkt5.SessionId = this.character.id; foreach (Rag2Item c in this.character.container) spkt5.AddItem(c); this.Send((byte[])spkt5); } #endregion Inventory List #region Friendlist { WaitCallback FriendlistLogin = delegate(object state) { //Look through all friends lists of logged on players and if they are friends then // notify them that the user logged on. SMSG_FRIENDSLIST_NOTIFYLOGIN spkt = new SMSG_FRIENDSLIST_NOTIFYLOGIN(); spkt.name = this.character.Name; foreach (Character characterTarget in LifeCycle.Characters) { lock (characterTarget) { if (characterTarget.id != this.character.id) if (character._friendlist.Contains(this.character.Name)) { spkt.SessionId = characterTarget.id; characterTarget.client.Send((byte[])spkt); } } } }; ThreadPool.QueueUserWorkItem(FriendlistLogin); } #endregion Friendlist #if THREADING }; ThreadPool.QueueUserWorkItem(FireTimeLoginCallback); #else } #endif } else { //Always ubsubcribe from the respawn manager in case //we forget to do it. Tasks.Respawns.Unsubscribe(this.character); } #region Dynamic Objects { try { Regiontree tree = this.character.currentzone.Regiontree; #if THREADING WaitCallback FindCharactersActors = delegate(object a) { #else { #endif foreach (Character regionObject in tree.SearchActors(this.character, SearchFlags.Characters)) { try { if (Point.IsInSightRangeByRadius(this.character.Position, regionObject.Position)) { regionObject.ShowObject(this.character); if (this.character.id != regionObject.id) { this.character.ShowObject(regionObject); } regionObject.Appears(this.character); } } catch (SocketException) { Trace.WriteLine("Network eror"); } catch (Exception e) { Trace.WriteLine(e.Message); } } #if THREADING }; #else } #endif #if THREADING WaitCallback FindNpcActors = delegate(object a) { #else { #endif foreach (MapObject regionObject in tree.SearchActors(this.character, SearchFlags.MapItems | SearchFlags.Npcs)) { try { if (Point.IsInSightRangeByRadius(this.character.Position, regionObject.Position)) { regionObject.ShowObject(this.character); regionObject.Appears(this.character); } } catch (SocketException) { Trace.WriteLine("Network eror"); } catch (Exception e) { Trace.WriteLine(e.Message); } } #if THREADING }; #else } #endif #if THREADING ThreadPool.QueueUserWorkItem(FindCharactersActors); ThreadPool.QueueUserWorkItem(FindNpcActors); #endif } catch (Exception e) { Trace.WriteLine(e.Message); } } #endregion Dynamic Objects #region Time Weather CommonFunctions.UpdateTimeWeather(this.character); #endregion Time Weather #region Map Info { SMSG_SHOWMAPINFO spkt2 = new SMSG_SHOWMAPINFO(); spkt2.SessionId = this.character.id; spkt2.ZoneInfo = this.character.ZoneInformation; this.Send((byte[])spkt2); } #endregion Map Info #region Return Points { /* * Send Resturn points * Return points define which map you'll be send to when you * use your promise stone or die */ WorldCoordinate lpos = this.character.lastlocation.map > 0 ? this.character.lastlocation : this.character.savelocation; WorldCoordinate spos = this.character.savelocation; if (spos.map == this.character.currentzone.Map) { this.character.stance = (byte)StancePosition.Stand; SMSG_RETURNMAPLIST spkt = new SMSG_RETURNMAPLIST(); spkt.ToMap = lpos.map; spkt.FromMap = this.character.currentzone.CathelayaLocation.map; spkt.IsSaveLocationSet = (lpos.map > 0) ? (byte)1 : (byte)0; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } else { this.character.stance = (byte)StancePosition.Stand; SMSG_RETURNMAPLIST spkt = new SMSG_RETURNMAPLIST(); spkt.ToMap = spos.map; spkt.FromMap = this.character.currentzone.CathelayaLocation.map; spkt.IsSaveLocationSet = (spos.map > 0) ? (byte)1 : (byte)0; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } } #endregion Return Points #region Job Levels { SMSG_JOBLEVELS spkt2 = new SMSG_JOBLEVELS(); spkt2.SessionId = this.character.id; spkt2.jobslevels = this.character.CharacterJobLevel; this.Send((byte[])spkt2); } #endregion Job Levels #region Change Actors state { /* * Change the actors state * * This is used to change the actors state to a non-active-battle position. * Note we will not warp the player back on their x and y coords if they were dead. * This would result in double loading a map. This should be handeld before processing * the character. */ this.character.stance = (byte)StancePosition.Reborn; this.character.ISONBATTLE = false; SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE(); spkt.ActorID = this.character.id; spkt.SessionId = this.character.id; spkt.Stance = this.character.stance; spkt.State = (this.character.ISONBATTLE) ? (byte)1 : (byte)0; this.Send((byte[])spkt); } #endregion Change Actors state #region Party Update if (this.character.sessionParty != null) { foreach (Character partyTarget in this.character.sessionParty._Characters) { //Only process if we're on the same map if (partyTarget.id != this.character.id) if (partyTarget.map == this.character.map) { //Retrieve positions people that are loaded SMSG_PARTYMEMBERLOCATION spkt2 = new SMSG_PARTYMEMBERLOCATION(); spkt2.Index = 1; spkt2.ActorId = partyTarget.id; spkt2.SessionId = this.character.id; spkt2.X = (partyTarget.Position.x / 1000); spkt2.Y = (partyTarget.Position.y / 1000); this.Send((byte[])spkt2); //Update the position of myself to loaded characters SMSG_PARTYMEMBERLOCATION spkt3 = new SMSG_PARTYMEMBERLOCATION(); spkt3.Index = 1; spkt3.ActorId = this.character.id; spkt3.SessionId = partyTarget.id; spkt3.X = (this.character.Position.x / 1000); spkt3.Y = (this.character.Position.y / 1000); partyTarget.client.Send((byte[])spkt3); } } } #endregion Party Update #region Static Objects try { //SEND OVER ALL CHARACTERS THAT ARE ALWAYS VISIBLE foreach (MapObject regionObject in this.character.currentzone.Regiontree.SearchActors(SearchFlags.StaticObjects)) { Console.WriteLine("Show object: {0}", regionObject.ToString()); regionObject.ShowObject(this.character); regionObject.Appears(this.character); } } catch (Exception) { //Do nothing } #endregion Static Objects } catch (Exception e) { Console.WriteLine(e); this.Close(); } finally { this.character.ISONBATTLE = false; isloaded = true; IsFirstTimeLoad = false; this.character.LastPositionTick = Environment.TickCount; } }
public static void UpdateStance(Character target, Actor actor) { if (actor != null) { Console.WriteLine("Updating stance: {0} {1}", actor.stance, actor.ModelId); SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE(); spkt.Stance = actor.stance; spkt.State = 0; spkt.SessionId = target.id; spkt.ActorID = actor.id; spkt.TargetActor = actor._targetid; target.client.Send((byte[])spkt); } }
/// <summary> /// Occurs when confirming or decling to show love you've /// recieve from a person. /// </summary> /// <param name="cpkt"></param> private void CM_CHARACTER_CONFIRMSHOWLOVE(CMSG_SHOWLOVECONFIRM cpkt) { Character target; if (LifeCycle.TryGetById(this.character._ShowLoveDialog, out target)) { if (cpkt.Response == 0) { SMSG_ACTORCHANGESTATE spkt3 = new SMSG_ACTORCHANGESTATE(); spkt3.ActorID = this.character.id; spkt3.State = 0; spkt3.Stance = (byte)StancePosition.VALENTINE_LAY; spkt3.TargetActor = target.id; SMSG_ACTORCHANGESTATE spkt2 = new SMSG_ACTORCHANGESTATE(); spkt2.ActorID = target.id; spkt2.State = 0; spkt2.Stance = (byte)StancePosition.VALENTINE_SIT; spkt2.TargetActor = this.character.id; foreach (MapObject myObject in this.character.currentzone.GetObjectsInRegionalRange(this.character)) { if (this.character.currentzone.IsInSightRangeBySquare(this.character.Position, myObject.Position)) { if (MapObject.IsPlayer(myObject)) { Character current = myObject as Character; if (current.client != null && current.client.isloaded == true) { spkt3.SessionId = current.id; spkt2.SessionId = current.id; current.client.Send((byte[])spkt3); current.client.Send((byte[])spkt2); } } } } } else { character._ShowLoveDialog = 0; } if (target.client != null) { SMSG_RESPONSESHOWLOVE spkt = new SMSG_RESPONSESHOWLOVE(); spkt.Result = cpkt.Response; spkt.SessionId = target.id; target.client.Send((byte[])spkt); } } }
/// <summary> /// Changes the state of the player. /// </summary> /// <remarks> /// This functions is invoked when the user changes his/hers p /// players state. For example when the players is laying down ///or is sitting down. This packet is called. /// /// When a player is going to sit down, the regen bonusses are /// changed. The regeneration bonussed are since the 26dec patch /// 2007: /// /// Players battle stance: 0-HP 0.35MSP-SP /// Player standing: 15-HP 0.35MSP-SP /// Player sitting: 15-HP 0.35MSP-SP /// Player laying: 15-HP 0.35MSP-SP /// </remarks> /// <param name="cpkt"></param> private void CM_CHARACTER_CHANGESTATE(CMSG_ACTORCHANGESTATE cpkt) { if (cpkt.Stance > 12) return; //Checks if the old position was a valentine lay Regiontree tree = this.character.currentzone.Regiontree; bool LeaveLove = (this.character.stance == 9 || this.character.stance == 10); if (LeaveLove) { Character target; if (LifeCycle.TryGetById(this.character._ShowLoveDialog, out target)) { //Update the stance switch ((StancePosition)target.stance) { case StancePosition.VALENTINE_SIT: target.stance = (byte)StancePosition.Sit; break; case StancePosition.VALENTINE_LAY: target.stance = (byte)StancePosition.Lie; break; default: target.stance = (byte)StancePosition.Stand; break; } //Release the showlove this.character._ShowLoveDialog = 0; //Reset the stance foreach (Character current in tree.SearchActors(this.character, SearchFlags.Characters)) { if (current.client.isloaded == false || !Point.IsInSightRangeByRadius(current.Position, this.character.Position)) continue; SMSG_ACTORCHANGESTATE spkt2 = new SMSG_ACTORCHANGESTATE(); spkt2.ActorID = target.id; spkt2.State = (byte)((target.ISONBATTLE) ? 1 : 0); spkt2.Stance = target.stance; spkt2.TargetActor = target._targetid; spkt2.SessionId = current.id; current.client.Send((byte[])spkt2); } } } //Update my information this.character.stance = cpkt.Stance; this.character.ISONBATTLE = cpkt.State > 0; //Create packet SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE(); spkt.ActorID = this.character.id; spkt.State = cpkt.State; spkt.Stance = cpkt.Stance; spkt.TargetActor = cpkt.TargetActor; foreach (Character current in tree.SearchActors(this.character, SearchFlags.Characters)) { if (current.client.isloaded == false) continue; spkt.SessionId = current.id; current.client.Send((byte[])spkt); } }
/// <summary> /// Makes your character jump in the air. /// </summary> private void CM_CHARACTER_JUMP() { SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE(); spkt.ActorID = this.character.id; spkt.TargetActor = this.character._targetid; spkt.Stance = (byte)StancePosition.Jump; spkt.State = (byte)((this.character.ISONBATTLE == true) ? 1 : 0); foreach (MapObject myObject in this.character.currentzone.GetObjectsInRegionalRange(this.character)) if (this.character.currentzone.IsInSightRangeBySquare(this.character.Position, myObject.Position)) if (MapObject.IsPlayer(myObject)) { Character current = myObject as Character; if (current.client.isloaded == true) { spkt.SessionId = current.id; current.client.Send((byte[])spkt); } } }
public static bool Warp(Character target, Point destination, Zone NewZoneInstance) { if (target.client.isloaded == true) { if (target.map > 0 && NewZoneInstance.Map > 0) { if (target.map != NewZoneInstance.Map) { #region Not the same Zone if (target.currentzone.Type != ZoneType.Dungeon) { WorldCoordinate worldcoord; worldcoord.coords = target.Position; worldcoord.map = target.currentzone.Map; target.lastlocation = worldcoord; } //Start loading target.client.isloaded = false; Zone currentZone = target.currentzone; target.currentzone.OnLeave(target); lock (target) { //Unregister currentZone.Regiontree.Unsubscribe(target); //Set position to the new location target.map = NewZoneInstance.Map; //Set new position target.Position = new Point( destination.x, destination.y, destination.z ); } //Update party members if (target.sessionParty != null) foreach (Character partyTarget in target.sessionParty) { //switch the map SMSG_PARTYMEMBERMAPCHANGE spkt4 = new SMSG_PARTYMEMBERMAPCHANGE(); spkt4.Index = 1; spkt4.ActorId = target.id; spkt4.Unknown = (byte)(target.map + 0x065); spkt4.Zone = target.map; spkt4.SessionId = partyTarget.id; partyTarget.client.Send((byte[])spkt4); } //Set zone instance target.currentzone = NewZoneInstance; //Send over load packet SMSG_SENDSTART spkt = new SMSG_SENDSTART(); spkt.SessionId = target.id; spkt.X = destination.x; spkt.Y = destination.y; spkt.Z = destination.z; spkt.MapId = NewZoneInstance.Map; spkt.Unknown = (byte)(target.map + 0x65); spkt.Channel = 1; target.client.Send((byte[])spkt); return true; #endregion Not the same Zone } else { #region Notify People That Actor Disapears Point origin = target.Position; Regiontree tree; tree = target.currentzone.Regiontree; foreach (MapObject c in tree.SearchActors(target, SearchFlags.DynamicObjects)) { bool insightrangeold = Point.IsInSightRangeByRadius(origin, c.Position); bool insightrangenew = Point.IsInSightRangeByRadius(destination, c.Position); if (c.id == target.id) continue; //If vible from old postion but not from new position hide if (insightrangeold && !insightrangenew) { double distance = Point.GetDistance3D(destination, c.Position); //CROSS NOTIFY PLAYERS ACTORS DISAPPPEARS if (MapObject.IsPlayer(c)) { Character targetChar = c as Character; targetChar.HideObject(target); } c.HideObject(target); c.Disappear(target); } } #endregion Notify People That Actor Disapears #region Update Region target.Position = new Point(destination.x, destination.y, destination.z); Regiontree.UpdateRegion(target); #endregion Update Region #region Teleport SMSG_ACTORTELEPORT spkt = new SMSG_ACTORTELEPORT(); spkt.SessionId = target.id; spkt.x = destination.x; spkt.y = destination.y; spkt.Z = destination.z; target.client.Send((byte[])spkt); #endregion Teleport #region Reset State target.ISONBATTLE = false; target.stance = (byte)StancePosition.Reborn; target._targetid = 0; SMSG_ACTORCHANGESTATE spkt4 = new SMSG_ACTORCHANGESTATE(); spkt4.SessionId = target.id; spkt4.Stance = target.stance; spkt4.TargetActor = target._targetid; spkt4.State = (target.ISONBATTLE == true) ? (byte)1 : (byte)0; spkt4.ActorID = target.id; target.client.Send((byte[])spkt4); #endregion Reset State #region Notify People That the Actor Appears tree = target.currentzone.Regiontree; foreach (MapObject myObject in tree.SearchActors(target, SearchFlags.DynamicObjects)) { bool insightrangeold = Point.IsInSightRangeByRadius(origin, myObject.Position); bool insightrangenew = Point.IsInSightRangeByRadius(destination, myObject.Position); double distance = Point.GetDistance3D(destination, myObject.Position); //If visible from new postion but not from old postion if (insightrangenew && !insightrangeold) { myObject.ShowObject(target); myObject.Appears(target); if (MapObject.IsPlayer(myObject)) { Character current = (Character)myObject; if (current.client.isloaded == false) continue; target.ShowObject(current); } } } #endregion Notify People That the Actor Appears #region Notify Party Members if (target.sessionParty != null) { foreach (Character partyTarget in target.sessionParty) { if (partyTarget.id == target.id) continue; SMSG_PARTYMEMBERLOCATION spkt3 = new SMSG_PARTYMEMBERLOCATION(); spkt3.Index = 1; spkt3.ActorId = target.id; spkt3.SessionId = partyTarget.id; spkt3.X = (destination.x / 1000); spkt3.Y = (destination.y / 1000); partyTarget.client.Send((byte[])spkt3); } } #endregion Notify Party Members return true; } } else { Trace.TraceError("Warping player {0} to unsupported map {1}", target.Name, 0); return false; } } else { return false; } }
public void ChangeStance(byte stance) { this.stance = stance; SMSG_ACTORCHANGESTATE spkt = new SMSG_ACTORCHANGESTATE(); spkt.ActorID = this.id; spkt.TargetActor = (this._target != null) ? this._target.id : 0; spkt.State = 1; spkt.Stance = stance; ForwardToAll(spkt); }