public void ApplyTo(EntityChangeSet outChangeSet, EntityLogic logic, byte[] serialLogic, EntityChange.ExecutionContext ctx) { Vec3 dest = ctx.ClampDestination("Motion", NewPosition, id, #if STATE_ADV SuppressAdvertisements ? ctx.Ranges.R : ctx.Ranges.Motion #else ctx.Ranges.Motion #endif ); var newID = id.Relocate(dest); outChangeSet.Add(new EntityChange.Motion(id, dest, #if STATE_ADV newAppearances, #endif logic, serialLogic)); //motion doubles as logic-state-update #if STATE_ADV if (!SuppressAdvertisements) { outChangeSet.Add(new EntityChange.StateAdvertisement(new EntityContact(newID, newAppearances, dest - id.Position))); } #endif foreach (var inst in instantiations) { outChangeSet.Add(new EntityChange.Instantiation(newID, ctx.ClampDestination("Instantiation", inst.targetLocation, newID, ctx.Ranges.Motion), #if STATE_ADV inst.appearances, #endif inst.logic, Helper.SerializeToArray(inst.logic))); } foreach (var rem in removals) { if (ctx.CheckT("Removal", rem.Position, newID)) { outChangeSet.Add(new EntityChange.Removal(newID, rem)); } } int messageID = 0; var messageOriginID = ctx.Ranges.DisplacedTransmission ? newID : id; foreach (var m in messages) { if (m.IsDirectedToClient) { ctx.RelayClientMessage(id.Guid, m.receiver.Guid, m.channel, m.data); } else { outChangeSet.Add(new EntityChange.Message(messageOriginID, messageID++, m.receiver.Guid, m.channel, m.data)); } } foreach (var b in broadcasts) { outChangeSet.Add(new EntityChange.Broadcast(messageOriginID, messageID++, b.maxRange, b.channel, b.data)); } if (nowInconsistent) { throw new ExecutionException(id, "Inconsistency by logic request"); } }
/// <summary> /// Checks if the specified receiver exists, and is within influence range of <paramref name="senderPosition"/>. /// If so, the message is relayed to the receiver, and the method returns true. /// </summary> /// <param name="senderPosition"></param> /// <param name="receiver"></param> /// <param name="message"></param> /// <returns>True if the entity was found, in range, and the message index was not yet used by the receiver-sender-tuple</returns> public bool RelayMessage(Vec3 senderPosition, Guid receiver, OrderedEntityMessage message) { Container rs; if (!guidMap.TryGetValue(receiver, out rs)) { return(false); } if (!ctx.CheckT("Message", senderPosition, rs.entity)) { return(false); } return(rs.messages.GetOrAdd(message.Message.Sender.Guid, guid => new Container.BySender()).Add(message)); }