public static void HitPlayer(PlayerBot bot, Player p, Orientation rot) { // Send player backwards if hit // Code "borrowed" from PvP plugin int srcHeight = ModelInfo.CalcEyeHeight(bot); int dstHeight = ModelInfo.CalcEyeHeight(p); int dx2 = bot.Pos.X - p.Pos.X, dy2 = (bot.Pos.Y + srcHeight) - (p.Pos.Y + dstHeight), dz2 = bot.Pos.Z - p.Pos.Z; Vec3F32 dir2 = new Vec3F32(dx2, dy2, dz2); if (dir2.Length > 0) { dir2 = Vec3F32.Normalise(dir2); } float mult = 1 / ModelInfo.GetRawScale(p.Model); float plScale = ModelInfo.GetRawScale(p.Model); float VelocityY = 1.0117f * mult; if (dir2.Length <= 0) { VelocityY = 0; } if (p.Supports(CpeExt.VelocityControl)) { // Intensity of force is in part determined by model scale p.Send(Packet.VelocityControl((-dir2.X * mult) * 0.57f, VelocityY, (-dir2.Z * mult) * 0.57f, 0, 1, 0)); } // If we are very close to a player, switch from trying to look // at them to just facing the opposite direction to them rot.RotY = (byte)(p.Rot.RotY + 128); bot.Rot = rot; }
// sends all missing models in level to player, // and removes all unused models from player static void CheckAddRemove(Player p, Level level) { Debug("CheckAddRemove {0}", p.name); var visibleModels = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { ModelInfo.GetRawModel(p.Model) }; if (!level.IsMuseum) { foreach (Player e in level.getPlayers()) { visibleModels.Add(ModelInfo.GetRawModel(e.Model)); } } else { visibleModels.Add(ModelInfo.GetRawModel(p.Model)); } foreach (PlayerBot e in level.Bots.Items) { visibleModels.Add(ModelInfo.GetRawModel(e.Model)); } if (p.Extras.TryGet("TempBot_BotList", out object obj)) { if (obj != null) { List <PlayerBot> botList = (List <PlayerBot>)obj; foreach (var bot in botList) { visibleModels.Add(ModelInfo.GetRawModel(bot.Model)); } } } // we must remove old models first before new models so that we have enough CM id's, // but removing first will cause a couple ms of humanoid to be shown before the new model arrives // TODO maybe check if we're about to overflow, and flip order? lock (SentCustomModels) { var sentModels = SentCustomModels[p.name]; // clone so we can modify while we iterate foreach (var modelName in sentModels.ToArray()) { // remove models not found in this level if (!visibleModels.Contains(modelName)) { CheckRemoveModel(p, modelName); } } } // send new models not yet in player's list foreach (var modelName in visibleModels) { CheckSendModel(p, modelName); } }
void OnPlayerMove(Player p, Position next, byte yaw, byte pitch) { string data = playerEffects.FindData(p.name); if (data == null) { return; } if (rnd.NextDouble() > 0.125f && !data.StartsWith("puff")) { return; } float x = p.Pos.X * 0.03125f; float y = (p.Pos.Y + ModelInfo.CalcEyeHeight(p) - Entities.CharacterHeight) * 0.03125f; float z = p.Pos.Z * 0.03125f; float originX = x; float originY = y; float originZ = z; Player notShownTo = null; //ugly hack if (data.StartsWith("leaf")) { if (rnd.NextDouble() > 0.5f) { return; } originX += 32; originZ += 8; } else if (data.StartsWith("puff")) { Random playerRandom = new Random(p.name.GetHashCode()); const int cycle = 4000; const int breatheOut = 1000; int offset = playerRandom.Next(0, cycle + 1); TimeSpan delta = DateTime.UtcNow - (startTime.AddMilliseconds(offset)); int ms = (int)delta.TotalMilliseconds; bool phase1 = (ms % cycle) < breatheOut; if (!phase1) { return; } Vec3F32 dir = DirUtils.GetDirVector(yaw, pitch); dir.X *= 0.3f; dir.Y *= 0.3f; dir.Z *= 0.3f; originY = y; x += dir.X; y += dir.Y; z += dir.Z; y -= 0.15f; originY -= 0.15f; notShownTo = p; } SpawnEffectAt(p.level, data, x, y, z, originX, originY, originZ); }
public void SetModel(string model) { Model = model; ModelBB = ModelInfo.CalcAABB(this); }