private static void HandleFirstSent(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); int unkValue = packet.ReadInt(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); packet.ReadByte(); CoordF coords = packet.Read <CoordF>(); packet.ReadShort(); SkillCast skillCast = new SkillCast(skillId, skillLevel, skillSN, unkValue); int spiritCost = skillCast.GetSpCost(); int staminaCost = skillCast.GetStaCost(); if (session.Player.Stats[PlayerStatId.Spirit].Current >= spiritCost && session.Player.Stats[PlayerStatId.Stamina].Current >= staminaCost) { session.Player.ConsumeSp(spiritCost); session.Player.ConsumeStamina(staminaCost); // TODO: Add SP recovery session.FieldPlayer.Value.SkillCast = skillCast; session.Send(SkillUsePacket.SkillUse(skillCast, coords)); session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
public static void HandleEffect(GameSession session, SkillCast skillCast, int attackIndex) { Player player = session.Player; IFieldActor <Player> fieldPlayer = player.FieldPlayer; skillCast.EffectCoords = GetEffectCoords(skillCast, fieldPlayer.Coord, player.MapId, fieldPlayer.LookDirection, attackIndex); session.FieldManager.AddRegionSkillEffect(skillCast); Task removeEffectTask = RemoveEffects(session, skillCast); // TODO: Vibrate objects around skill if (skillCast.Interval <= 0) { HandleRegionSkill(session, skillCast); return; } // Task to loop trough all entities in range to do damage/heal Task.Run(async() => { while (!removeEffectTask.IsCompleted) { HandleRegionSkill(session, skillCast); // TODO: Find the correct delay for the skill await Task.Delay(skillCast.Interval); } }); }
public static PacketWriter TileSkill(SkillCast skillCast, byte targetCount, IFieldObject <Player> player, byte count2, CoordF position, CoordF direction, long damage) { PacketWriter pWriter = PacketWriter.Of(SendOp.SkillDamage); pWriter.Write(SkillDamageMode.RegionDamage); pWriter.WriteLong(skillCast.SkillSn); pWriter.WriteInt(skillCast.SkillId); pWriter.WriteShort(skillCast.SkillLevel); pWriter.WriteByte(targetCount); for (int i = 0; i < targetCount; i++) { pWriter.WriteInt(player.ObjectId); pWriter.WriteByte(count2); pWriter.Write(position); pWriter.Write(direction); for (int j = 0; j < count2; j++) // this maybe isn't a loop { pWriter.WriteByte(1); // 0 = normal, 1 = critical, 2 = miss pWriter.WriteLong(damage); } } return(pWriter); }
private static void HandleCast(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); int serverTick = packet.ReadInt(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); byte attackPoint = packet.ReadByte(); CoordF position = packet.Read <CoordF>(); CoordF direction = packet.Read <CoordF>(); CoordF rotation = packet.Read <CoordF>(); packet.ReadFloat(); int clientTick = packet.ReadInt(); packet.ReadBool(); packet.ReadLong(); bool flag = packet.ReadBool(); if (flag) { packet.ReadInt(); string unkString = packet.ReadUnicodeString(); } SkillCast skillCast = new SkillCast(skillId, skillLevel, skillSN, serverTick, session.FieldPlayer.ObjectId, clientTick, attackPoint); session.FieldPlayer.Value.Cast(skillCast); if (skillCast != null) { session.FieldManager.BroadcastPacket(SkillUsePacket.SkillUse(skillCast, position, direction, rotation)); session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
private static void HandleSyncDamage(GameSession session, PacketReader packet) { long skillSn = packet.ReadLong(); byte attackPoint = packet.ReadByte(); CoordF position = packet.Read <CoordF>(); CoordF rotation = packet.Read <CoordF>(); byte count = packet.ReadByte(); packet.ReadInt(); List <int> atkCount = new(); List <int> sourceId = new(); List <int> targetId = new(); List <short> animation = new(); // TODO: Handle multiple projectiles for (int i = 0; i < count; i++) { atkCount.Add(packet.ReadInt()); sourceId.Add(packet.ReadInt()); targetId.Add(packet.ReadInt()); animation.Add(packet.ReadShort()); } SkillCast skillCast = session.Player.FieldPlayer.SkillCast; if (skillCast is null) { return; } session.FieldManager.BroadcastPacket(SkillDamagePacket.SyncDamage(skillCast, position, rotation, session.Player.FieldPlayer, sourceId, count, atkCount, targetId, animation)); }
private static void HandleRegionSkills(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); byte mode = packet.ReadByte(); int unknown = packet.ReadInt(); int unknown2 = packet.ReadInt(); CoordF position = packet.Read <CoordF>(); CoordF rotation = packet.Read <CoordF>(); // TODO: Verify rest of skills to proc correctly. // Send status correctly when Region attacks are proc. SkillCast parentSkill = SkillUsePacket.SkillCastMap[skillSN]; if (parentSkill.GetConditionSkill() == null) { return; } foreach (SkillCondition conditionSkill in parentSkill.GetConditionSkill()) { if (!conditionSkill.Splash) { continue; } SkillCast skillCast = new SkillCast(conditionSkill.Id, conditionSkill.Level, GuidGenerator.Long(), session.ServerTick, parentSkill); RegionSkillHandler.Handle(session, GuidGenerator.Int(), session.FieldPlayer.Coord, skillCast); } }
private static void HandleRegionDamage(FieldManager field, SkillCast skillCast) { if (!field.State.Players.TryGetValue(skillCast.CasterObjectId, out Character caster)) { // Handle NPCs/Triggers sending skills return; } List <DamageHandler> damages = new(); foreach (IFieldActor <NpcMetadata> mob in field.State.Mobs.Values) { foreach (CoordF effectCoord in skillCast.EffectCoords) { if ((mob.Coord - effectCoord).Length() > skillCast.SkillAttack.RangeProperty.Distance) { continue; } DamageHandler damage = DamageHandler.CalculateDamage(skillCast, caster, mob); mob.Damage(damage, caster.Value.Session); damages.Add(damage); } } if (damages.Count <= 0) { return; } field.BroadcastPacket(SkillDamagePacket.RegionDamage(skillCast, damages)); }
public static Packet Send(int sourceObjectId, CoordS effectCoord, SkillCast skill) { PacketWriter pWriter = PacketWriter.Of(SendOp.REGION_SKILL); SkillCast parentSkill = skill.ParentSkill; List <MagicPathMove> skillMoves = parentSkill?.GetMagicPaths().MagicPathMoves ?? null; byte tileCount = (byte)(skillMoves != null ? skillMoves.Count : 1); pWriter.WriteEnum(RegionSkillMode.Add); pWriter.WriteInt(sourceObjectId); pWriter.WriteInt(sourceObjectId); pWriter.WriteInt(); pWriter.WriteByte(tileCount); if (tileCount == 0) { return(pWriter); } for (int i = 0; i < tileCount; i++) { CoordF currentSkillCoord = skillMoves != null ? skillMoves[i].FireOffsetPosition : CoordF.From(0, 0, 0); CoordF castPosition = Block.ClosestBlock(currentSkillCoord + effectCoord.ToFloat()); pWriter.Write(castPosition); } pWriter.WriteInt(skill.SkillId); pWriter.WriteShort(skill.SkillLevel); pWriter.WriteLong(); return(pWriter); }
public static PacketWriter RegionDamage(long skillSN, int userObjectId, int skillObjectId, byte count, byte count2, IFieldObject <Player> player, CoordF direction, CoordS blockPosition, long damage) { PacketWriter pWriter = PacketWriter.Of(SendOp.SKILL_DAMAGE); SkillCast skillCast = SkillUsePacket.SkillCastMap[skillSN]; pWriter.Write(SkillDamageMode.RegionDamage); pWriter.WriteLong(skillCast.SkillSN); pWriter.WriteInt(userObjectId); pWriter.WriteInt(skillObjectId); pWriter.WriteByte(); pWriter.WriteByte(count); for (int i = 0; i < count; i++) { pWriter.WriteInt(player.ObjectId); pWriter.WriteByte(count2); pWriter.Write(blockPosition); pWriter.Write(direction); for (int j = 0; j < count2; j++) { pWriter.Write(skillCast.GetSkillDamageType()); pWriter.WriteLong(damage); } } return(pWriter); }
public static PacketWriter RegionDamage(SkillCast skillCast, List <DamageHandler> damageHandlers) { PacketWriter pWriter = PacketWriter.Of(SendOp.SkillDamage); pWriter.Write(SkillDamageMode.RegionDamage); pWriter.WriteLong(); // always 0?? pWriter.WriteInt(skillCast.CasterObjectId); pWriter.WriteInt(skillCast.SkillObjectId); pWriter.WriteByte(); byte damageHandlersCount = (byte)damageHandlers.Count; pWriter.WriteByte(damageHandlersCount); foreach (DamageHandler damageHandler in damageHandlers) { pWriter.WriteInt(damageHandler.Target.ObjectId); bool flag = damageHandler.Damage > 0; pWriter.WriteBool(flag); if (!flag) { continue; } pWriter.Write(damageHandler.Target.Coord.ToShort()); pWriter.Write(damageHandler.Target.Velocity); pWriter.Write(damageHandler.HitType); pWriter.WriteLong((long)(-1 * damageHandler.Damage)); } return(pWriter); }
public static PacketWriter SyncDamage(long skillSN, CoordF position, CoordF rotation, IFieldObject <Player> player, List <int> sourceId, byte count, List <int> atkCount, List <int> entityId, List <short> animation) { PacketWriter pWriter = PacketWriter.Of(SendOp.SKILL_DAMAGE); SkillCast skillCast = SkillUsePacket.SkillCastMap[skillSN]; pWriter.Write(SkillDamageMode.SyncDamage); pWriter.WriteLong(skillSN); pWriter.WriteInt(player.ObjectId); pWriter.WriteInt(skillCast.SkillId); pWriter.WriteShort(skillCast.SkillLevel); pWriter.WriteByte(skillCast.MotionPoint); pWriter.WriteByte(skillCast.AttackPoint); pWriter.Write(position.ToShort()); pWriter.Write(rotation); pWriter.WriteByte(); pWriter.WriteInt(skillCast.ServerTick); pWriter.WriteByte(count); for (int i = 0; i < count; i++) { pWriter.WriteLong(); pWriter.WriteInt(atkCount[i]); pWriter.WriteInt(sourceId[i]); pWriter.WriteInt(entityId[i]); // objectId of the Impact pWriter.WriteShort(animation[i]); pWriter.WriteByte(); pWriter.WriteByte(); } return(pWriter); }
public static PacketWriter Send(SkillCast skill) { PacketWriter pWriter = PacketWriter.Of(SendOp.RegionSkill); pWriter.Write(RegionSkillMode.Add); pWriter.WriteInt(skill.SkillObjectId); pWriter.WriteInt(skill.CasterObjectId); pWriter.WriteInt(skill.ServerTick); pWriter.WriteByte((byte)skill.EffectCoords.Count); if (skill.EffectCoords.Count == 0) { return(pWriter); } foreach (CoordF effectCoord in skill.EffectCoords) { pWriter.Write(effectCoord); } pWriter.WriteInt(skill.SkillId); pWriter.WriteShort(skill.SkillLevel); pWriter.WriteFloat(); pWriter.WriteFloat(); return(pWriter); }
public static void HandleEffect(FieldManager field, SkillCast skillCast, int attackIndex) { skillCast.EffectCoords = GetEffectCoords(skillCast, field.MapId, attackIndex); field.AddRegionSkillEffect(skillCast); Task removeEffectTask = RemoveEffects(field, skillCast); if (skillCast.Interval <= 0) { HandleRegionSkill(field, skillCast); VibrateObjects(field, skillCast); return; } // Task to loop trough all entities in range to do damage/heal Task.Run(async() => { while (!removeEffectTask.IsCompleted) { HandleRegionSkill(field, skillCast); VibrateObjects(field, skillCast); // TODO: Find the correct delay for the skill await Task.Delay(skillCast.Interval); } }); }
public override void Cast(SkillCast skillCast) { int spiritCost = skillCast.GetSpCost(); int staminaCost = skillCast.GetStaCost(); if (Value.Stats[StatId.Spirit].Total < spiritCost || Value.Stats[StatId.Stamina].Total < staminaCost) { return; } SkillCast = skillCast; ConsumeSp(spiritCost); ConsumeStamina(staminaCost); Value.Session.SendNotice(skillCast.SkillId.ToString()); // TODO: Move this and all others combat cases like recover sp to its own class. // Since the cast is always sent by the skill, we have to check buffs even when not doing damage. if (skillCast.IsBuffToOwner() || skillCast.IsBuffToEntity() || skillCast.IsBuffShield() || skillCast.IsDebuffToOwner()) { Status status = new(skillCast, ObjectId, ObjectId, 1); StatusHandler.Handle(Value.Session, status); } Value.Session.FieldManager.BroadcastPacket(SkillUsePacket.SkillUse(skillCast)); Value.Session.Send(StatPacket.SetStats(this)); StartCombatStance(); }
public static Packet ApplyDamage(IFieldObject <Player> player, long skillSN, int unkValue, CoordF coords, List <IFieldObject <Mob> > mobs) { PacketWriter pWriter = PacketWriter.Of(SendOp.SKILL_DAMAGE); SkillCast skillCast = SkillUsePacket.SkillCastMap[skillSN]; DamageHandler damage = DamageHandler.CalculateSkillDamage(skillCast); pWriter.WriteByte(1); pWriter.WriteLong(skillSN); pWriter.WriteInt(unkValue); pWriter.WriteInt(player.ObjectId); pWriter.WriteInt(player.ObjectId); pWriter.WriteInt(skillCast.SkillId); pWriter.WriteShort(skillCast.SkillLevel); // This values appears on some SkillsId, and others like BossSkill, sometimes is 0 pWriter.WriteByte(); // The value is not always 0 pWriter.WriteByte(); // The value is not always 0, also seems to crash if its not a correct value pWriter.Write(coords.ToShort()); pWriter.Write(CoordS.From(0, 0, 0)); // Position of the image effect of the skillUse, seems to be rotation (0, 0, rotation). // TODO: Check if is a player or mob pWriter.WriteByte((byte)mobs.Count); for (int i = 0; i < mobs.Count; i++) { pWriter.WriteInt(mobs[i].ObjectId); pWriter.WriteByte((byte)damage.GetDamage() > 0 ? 1 : 0); pWriter.WriteBool(damage.IsCritical()); if (damage.GetDamage() != 0) { pWriter.WriteLong(-1 * (long)damage.GetDamage()); } } return(pWriter); }
public static PacketWriter Damage(long skillSN, int unkValue, CoordF position, CoordF rotation, IFieldObject <Player> player, IEnumerable <DamageHandler> effects) { PacketWriter pWriter = PacketWriter.Of(SendOp.SKILL_DAMAGE); SkillCast skillCast = SkillUsePacket.SkillCastMap[skillSN]; pWriter.Write(SkillDamageMode.Damage); pWriter.WriteLong(skillSN); pWriter.WriteInt(unkValue); pWriter.WriteInt(player.ObjectId); pWriter.WriteInt(player.ObjectId); pWriter.WriteInt(skillCast.SkillId); pWriter.WriteShort(skillCast.SkillLevel); // This values appears on some SkillsId, and others like BossSkill, sometimes is 0 pWriter.WriteByte(skillCast.MotionPoint); // The value is not always 0 pWriter.WriteByte(skillCast.AttackPoint); // The value is not always 0, also seems to crash if its not a correct value pWriter.Write(position.ToShort()); pWriter.Write(rotation.ToShort()); // Position of the image effect of the skillUse, seems to be rotation (0, 0, rotation). // TODO: Check if is a player or mob pWriter.WriteByte((byte)effects.Count()); foreach (DamageHandler effect in effects) { pWriter.WriteInt(effect.Target.ObjectId); pWriter.WriteBool(effect.Damage > 0); pWriter.WriteBool(effect.IsCrit); if (effect.Damage != 0) { pWriter.WriteLong(-1 * (long)effect.Damage); } } return(pWriter); }
public override void Execute(GameCommandTrigger trigger) { int id = trigger.Get <int>("id"); if (SkillMetadataStorage.GetSkill(id) == null) { trigger.Session.SendNotice($"No skill found with id: {id}"); return; } short level = trigger.Get <short>("level") <= 10 && trigger.Get <short>("level") != 0 ? trigger.Get <short>("level") : (short)1; // The Status packet needs this in miliseconds, we are converting them here for the user to just input the actual seconds. int duration = trigger.Get <int>("duration") <= 3600 && trigger.Get <int>("duration") != 0 ? trigger.Get <int>("duration") * 1000 : 10000; int stacks = trigger.Get <int>("stacks") == 0 ? 1 : trigger.Get <int>("stacks"); SkillCast skillCast = new SkillCast(id, level); if (skillCast.IsBuffToOwner() || skillCast.IsBuffToEntity() || skillCast.IsBuffShield() || skillCast.IsGM() || skillCast.IsGlobal() || skillCast.IsHealFromBuff()) { Status status = new Status(skillCast, trigger.Session.FieldPlayer.ObjectId, trigger.Session.FieldPlayer.ObjectId, stacks); StatusHandler.Handle(trigger.Session, status); return; } trigger.Session.SendNotice($"Skill with id: {id} is not a buff to the owner."); }
private static void HandleRegionDamage(GameSession session, SkillCast skillCast) { List <DamageHandler> damages = new(); bool isCrit = DamageHandler.RollCrit(session.Player.Stats[StatId.CritRate].Total); foreach (IFieldActor <NpcMetadata> mob in session.FieldManager.State.Mobs.Values) { foreach (CoordF effectCoord in skillCast.EffectCoords) { if ((mob.Coord - effectCoord).Length() > skillCast.SkillAttack.RangeProperty.Distance) { continue; } DamageHandler damage = DamageHandler.CalculateDamage(skillCast, session.Player.FieldPlayer, mob, isCrit); mob.Damage(damage, session); damages.Add(damage); } } if (damages.Count <= 0) { return; } session.FieldManager.BroadcastPacket(SkillDamagePacket.RegionDamage(skillCast, damages)); }
private static void HandleRegionSkill(GameSession session, SkillCast skillCast) { foreach (SkillMotion skillMotion in skillCast.GetSkillMotions()) { foreach (SkillAttack skillAttack in skillMotion.SkillAttacks) { if (skillAttack.SkillConditions?.Count > 0) { foreach (SkillCondition skillCondition in skillAttack.SkillConditions) { SkillCast splashSkill = new(skillCondition.SkillId, skillCondition.SkillLevel, GuidGenerator.Long(), session.ServerTick, skillCast) { CasterObjectId = session.Player.FieldPlayer.ObjectId, SkillAttack = skillAttack, EffectCoords = skillCast.EffectCoords, SkillObjectId = skillCast.SkillObjectId }; if (!splashSkill.MetadataExists) { return; } if (!skillCondition.ImmediateActive) { if (splashSkill.IsRecoveryFromBuff()) { HandleRegionHeal(session, splashSkill); continue; } HandleRegionDamage(session, splashSkill); continue; } // go to another skill condition?? might cause infinite loop // HandleRegionSkill(session, splashSkill); } continue; } skillCast.SkillAttack = skillAttack; if (!skillCast.MetadataExists) { return; } if (skillCast.IsRecoveryFromBuff()) { HandleRegionHeal(session, skillCast); continue; } HandleRegionDamage(session, skillCast); } } }
private static void Remove(GameSession session, SkillCast skillCast, int sourceId) { Task.Run(async() => { // TODO: Get the correct Region Skill Duration when calling chain Skills await Task.Delay(skillCast.DurationTick() + 5000); session.FieldManager.BroadcastPacket(RegionSkillPacket.Remove(sourceId)); }); }
public static DamageHandler CalculateDamage(SkillCast skill, IFieldActor <Player> source, IFieldActor target) { if (source.Value.GmFlags.Contains("oneshot")) { return(new(source, target, target.Stats[StatAttribute.Hp].Total, HitType.Critical)); } // get luck coefficient from class. new stat recommended, can be refactored away like isCrit was return(CalculateDamage(skill, source, target, 1)); }
public virtual void Cast(SkillCast skillCast) { SkillCast = skillCast; // TODO: Move this and all others combat cases like recover sp to its own class. // Since the cast is always sent by the skill, we have to check buffs even when not doing damage. if (skillCast.IsBuffToOwner() || skillCast.IsBuffToEntity() || skillCast.IsBuffShield() || skillCast.IsDebuffToOwner()) { Status status = new(skillCast, ObjectId, ObjectId, 1); //StatusHandler.Handle(Value.Session, status); } }
private static Task RemoveEffects(FieldManager field, SkillCast skillCast) { return(Task.Run(async() => { // TODO: Get the correct Region Skill Duration when calling chain Skills await Task.Delay(skillCast.Duration); if (!field.RemoveRegionSkillEffect(skillCast)) { Logger.Error("Failed to remove Region Skill"); } })); }
private static void HandleRegionSkills(GameSession session, PacketReader packet) { long skillSn = packet.ReadLong(); byte mode = packet.ReadByte(); int unknown = packet.ReadInt(); int attackIndex = packet.ReadInt(); CoordF position = packet.Read <CoordF>(); CoordF rotation = packet.Read <CoordF>(); // What are these values used? Check client vs server? // TODO: Verify rest of skills to proc correctly. // TODO: Send status correctly when Region attacks are proc. SkillCast parentSkill = session.Player.FieldPlayer.SkillCast; if (parentSkill is null || parentSkill.SkillSn != skillSn) { return; } SkillAttack skillAttack = parentSkill.GetSkillMotions().FirstOrDefault()?.SkillAttacks.FirstOrDefault(); if (skillAttack is null) { return; } if (skillAttack.CubeMagicPathId == 0 && skillAttack.MagicPathId == 0) { return; } SkillCondition skillCondition = skillAttack.SkillConditions.FirstOrDefault(x => x.IsSplash); if (skillCondition is null) { return; } SkillCast skillCast = new(skillCondition.SkillId, skillCondition.SkillLevel, GuidGenerator.Long(), session.ServerTick, parentSkill) { CasterObjectId = session.Player.FieldPlayer.ObjectId, SkillAttack = skillAttack, Duration = skillCondition.FireCount * 1000, Interval = skillCondition.Interval }; RegionSkillHandler.HandleEffect(session, skillCast, attackIndex); } #endregion }
public Status(SkillCast skillCast, int target, int source, int stacks) { SkillId = skillCast.SkillId; UniqueId = GuidGenerator.Int(); Target = target; Source = source; Level = skillCast.SkillLevel; Stacks = stacks > 0 && stacks <= skillCast.MaxStack() ? stacks : skillCast.MaxStack(); SkillCast = skillCast; Start = Environment.TickCount; Duration = skillCast.DurationTick(); End = Start + Duration; }
private static DamageHandler HandleCrit(SkillCast skillCast) { double damage = skillCast.GetDamageRate(); bool crit = skillCast.RollCrit(); if (crit) { damage += damage; } DamageHandler toReturn = new DamageHandler(damage, crit); return(toReturn); }
private static void HandleCancelSkill(GameSession session, PacketReader packet) { long skillSn = packet.ReadLong(); SkillCast skillCast = session.Player.FieldPlayer.SkillCast; if (skillCast is null || skillCast.SkillSn != skillSn) { return; } session.FieldManager.BroadcastPacket(SkillCancelPacket.SkillCancel(skillSn, session.Player.FieldPlayer.ObjectId), session); }
private static void VibrateObjects(FieldManager field, SkillCast skillCast) { foreach ((string objectId, MapVibrateObject metadata) in field.State.VibrateObjects) { foreach (CoordF effectCoord in skillCast.EffectCoords) { if ((metadata.Position - effectCoord).Length() > skillCast.SkillAttack.RangeProperty.Distance) { continue; } field.BroadcastPacket(VibratePacket.Vibrate(objectId, skillCast)); } } }
private static void HandleFirstSent(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); int unkValue = packet.ReadInt(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); packet.ReadByte(); CoordF coords = packet.Read <CoordF>(); packet.ReadShort(); SkillCast skillCast = new SkillCast(skillId, skillLevel, skillSN, unkValue); session.FieldPlayer.Value.SkillCast = skillCast; session.Send(SkillUsePacket.SkillUse(skillCast, coords)); }
void Start() { Hp = 3000; MaxHp = Hp; p = GameObject.Find("Player").GetComponent <Player>(); //money = GameObject.Find("Player").GetComponent<Player>().money; //moneyText = GameObject.Find("Player").GetComponent<Player>().moneyText; enemySpawnPool = PoolManager.Pools["Enemy"]; effectSpawnPool = PoolManager.Pools["Effect"]; bulletSpawnPool = PoolManager.Pools["Bullet"]; resultPanel = GameObject.Find("Canvas").transform.Find("ResultPanel").gameObject; successText = resultPanel.transform.Find("SuccessText").gameObject; rooms = GameObject.FindGameObjectsWithTag("Room"); foreach (GameObject go in rooms) { if (go.transform.position == Vector3.zero) { //获得当前房间下的子物体 for (int i = 0; i < go.transform.childCount; i++) { startPos.Add(go.transform.GetChild(i)); } foreach (Transform t in startPos) { //本房间的所有门 if (t.gameObject.tag == "Door") { //锁上门 t.GetComponent <Collider2D>().isTrigger = false; } } } } sr = GetComponent <SpriteRenderer>(); sunglasses = transform.FindChild("sunglasses"); mouse = transform.FindChild("mouse"); leftHand = transform.FindChild("lefthand"); rightHand = transform.FindChild("righthand"); skillCast = SkillCast.Default; //Invoke("PlayAudio", 1.0f); }