protected override void ApplySnapshot(Frame snapframe, Frame targframe, bool snapIsValid, bool targIsValid) { base.ApplySnapshot(snapframe, targframe, snapIsValid, targIsValid); if (snapframe.content == FrameContents.Complete) { List <ContactRecord> contacts = snapframe.contactRecords; for (int i = 0, cnt = contacts.Count; i < cnt; ++i) { ContactRecord contact = contacts[i]; var pv = PhotonNetwork.GetPhotonView(contact.contactSystemViewID); if (pv && pv.IsMine) { var cm = pv.GetComponent <ContactManager>(); if (cm) { var currentAttachedICS = cm.GetContacting(contact.contactSystemIndex); // Retry the trigger and see if this will consume it, if so run pickup to apply it. var contactevent = new ContactEvent(currentAttachedICS, contactTrigger, contact.contactType); var consumed = Contact(contactevent); if (consumed != Consumption.None) { Consume(snapframe, contactevent, consumed); } } } } } }
protected override Consumption ProcessContactEvent(ContactEvent contactEvent) { //Debug.Log("Process " + contactEvent + " -- " + contactEvent.contactSystem.GetType().Name + " : " + (contactEvent.contactSystem as IInventorySystem<T>)); var system = (contactEvent.contactSystem as IInventorySystem <T>); if (system == null) { return(Consumption.None); } ///// TEST - Notify other component of pickup condition //var onContact = transform.GetComponent<IOnPickup>(); //Debug.Log("POST 2 " + (onContact != null)); //if (onContact != null) // syncState.HardMount(onContact.OnPickup(contactEvent)); if (IsPickup) { Mount mount = system.TryPickup(this, contactEvent); if (mount) { syncState.HardMount(mount); } } return(Consumption.All); }
protected virtual bool EnqueueEvent(ContactEvent contactEvent) { ///// TODO: need to put a consumption validity test here //IContactSystem ics = contactEvent.contactSystem; //if (ReferenceEquals(ics, null)) // return false; queuedContactEvents.Enqueue(contactEvent); return(true); }
// Step #1 public virtual void SyncContactEvent(ContactEvent contactEvent) { if (!IsMine) { return; } //// TODO: this allows undefined contacts to trigger if triggerOn is also undefined. May not be desired. //if (triggerOn != 0 && (triggerOn & contactType) == 0) // return; //Debug.Log(name + " OnContactEvent <b>ENQUEUE</b> " + " " + contactEvent.contactSystem.GetType().Name + " trigon:" + triggerOn + "/" + contactType); EnqueueEvent(contactEvent); }
//protected virtual void OnTriggerSuccess(Frame frame, ContactEvent contactEvent, Consumption consumed) //{ //} /// <summary> /// Attempt a trigger. Returns true if a triggerEvent results in a valid collision. /// </summary> protected virtual Consumption Contact(ContactEvent contactEvent) { //Debug.Log(name + " CONTACTS " + this.OnTriggerCallbacks.Count); return(contactTrigger.ContactCallbacks(contactEvent)); //for (int i = 0, cnt = this.OnTriggerCallbacks.Count; i < cnt; ++i) //{ // Consumption consumed = this.OnTriggerCallbacks[i].OnContact(contactEvent); // if (consumed != Consumption.None) // return consumed; //} //return Consumption.None; }
public virtual Consumption ContactCallbacks(ContactEvent contactEvent) { //if (contactEvent.contactType == ContactType.Enter) // Debug.Log("ContactCallbacks " + contactEvent); Consumption consumption = Consumption.None; for (int i = 0, cnt = this.OnContactEventCallbacks.Count; i < cnt; ++i) { consumption |= this.OnContactEventCallbacks[i].OnContactEvent(contactEvent); if (consumption == Consumption.All) { return(Consumption.All); } } return(consumption); }
public virtual Consumption TryTrigger(IContactReactor reactor, ContactEvent contactEvent, int compatibleMounts) { //Debug.Log("TryTrigger Basic Inv. compat with: " + compatibleMounts + " defMountId: " + defaultMounting.id + " defMask: " + defaultMountingMask); IInventoryable <T> iven = reactor as IInventoryable <T>; if (ReferenceEquals(iven, null)) { return(Consumption.None); } if (contactGroups != 0) { IContactGroupsAssign groups = contactEvent.contactTrigger.ContactGroupsAssign; int triggermask = ReferenceEquals(groups, null) ? 0 : groups.Mask; if ((contactGroups.Mask & triggermask) == 0) { //Debug.Log("Try trigger... ContactGroup mismatch " + contactGroups.Mask + "<>" + triggermask); return(Consumption.None); } } /// Return if the object being picked up exceeds remaining inventory. if (TestCapacity(reactor as IInventoryable <T>) == false) { //Debug.Log(name + " failed"); return(Consumption.None); } /// If both are set to 0 (Root) then consider that a match, otherwise zero for one but not the other is a mismatch (for now) if ((compatibleMounts == defaultMountingMask) || (compatibleMounts & defaultMountingMask) != 0) { // TODO: partial consumption handling needed //Debug.Log(name + " <> " + (trigger as Component).name + " <b>success</b>: " + compatibleMounts + " <> " + defaultMountingMask); return(Consumption.All); } else { //Debug.Log(name + " <> " + (trigger as Component).name + " failed: " + compatibleMounts + " <> " + defaultMountingMask); return(Consumption.None); } }
public virtual Consumption OnContactEvent(ContactEvent contactEvent) { // Don't react to contact events if we are using a sync. It will capture and manage contact events. //if (deferToISyncContact) // return Consumption.None; if (contactEvent.contactType == ContactType.Hitscan) { Debug.Log(Time.time + " SCAN " + name + " OnContactEvent " + contactEvent); } var contactType = contactEvent.contactType; if (triggerOn != 0 && (contactType & triggerOn) == 0) { return(Consumption.None); } /// Pickup requires mount compatibility to be valid if (IsPickup) { var system = contactEvent.contactSystem; int systemMount = system.ValidMountsMask; int mountableTo = syncState.mountableTo; if (systemMount != 0 && (systemMount & mountableTo) == 0) { #if UNITY_EDITOR if (DebugMismatches) { Debug.LogWarning(name + " mount mask mismatch with: '" + system.NetObj.name + "':" + system.GetType().Name + "[" + system.SystemIndex + "] masks: " + systemMount + " <-> " + mountableTo); } #endif return(Consumption.None); } } return(ProcessContactEvent(contactEvent)); }
protected Consumption TestConsumption(double amountConsumed, IVitalsConsumable iva, ContactEvent contactEvent) { var consumption = iva.Consumption; var discharge = iva.DischargeValue(contactEvent.contactType); if (consumption == Consumption.None) { return(Consumption.None); } if (consumption == Consumption.All) { if (amountConsumed != 0) { iva.Charges = 0; return(Consumption.All); } return(Consumption.None); } var consumed = amountConsumed == 0 ? Consumption.None : discharge == amountConsumed ? Consumption.All : Consumption.Partial; iva.Charges -= amountConsumed; return(consumed); }
public Consumption TryTrigger(IContactReactor icontactReactor, ContactEvent contactEvent, int compatibleMounts) { var reactor = (icontactReactor as IVitalsContactReactor); if (ReferenceEquals(reactor, null)) { return(Consumption.None); } /// First test to see if the contacting and contacted are a groups match - if not return false. if (contactGroups != 0) { //var groups = (reactor as Component).GetComponent<ContactGroupAssign>(); IContactGroupsAssign groups = contactEvent.contactTrigger.ContactGroupsAssign; int triggermask = ReferenceEquals(groups, null) ? 0 : groups.Mask; if ((contactGroups.Mask & triggermask) == 0) { #if UNITY_EDITOR Debug.Log(name + " SyncVitals.TryTrigger() ContactGroup Mismatch. Cannot pick up '" + (contactEvent.contactTrigger as Component).transform.root.name + "' because its has a non-matching ContactGroupAssign."); #endif return(Consumption.None); } } /// If both are set to 0 (Root) then consider that a match, otherwise zero for one but not the other is a mismatch (for now) if ((compatibleMounts != defaultMountingMask) && (compatibleMounts & defaultMountingMask) == 0) { return(Consumption.None); } Vital vital = vitals.GetVital(reactor.VitalNameType); if (vital == null) { return(Consumption.None); } /// Apply changes resulting from the trigger. Return true if affected/consumed. This bool is used to inform whether the trigger should despawn/pickup. //double charge = vpr.Charge; Consumption consumed; double amountConsumed; { /// Apply to vital if vital has authority. if (IsMine) { double discharge = reactor.DischargeValue(contactEvent.contactType); amountConsumed = vitals.ApplyCharges(discharge, reactor.AllowOverload, reactor.Propagate); } /// Vital does not belong to us, but we want to know IF it would have been consumed for prediction purposes. else { amountConsumed = vital.TestApplyChange(reactor, contactEvent); } } var consumable = icontactReactor as IVitalsConsumable; if (!ReferenceEquals(consumable, null)) { consumed = TestConsumption(amountConsumed, consumable, contactEvent); } else { consumed = Consumption.None; } return(consumed); }
protected abstract Consumption ProcessContactEvent(ContactEvent contactEvent);
protected virtual void Consume(Frame frame, ContactEvent contactEvent, Consumption consumed) { }
public double TestApplyChange(IVitalsContactReactor iVitalsAffector, ContactEvent contactEvent) { double charge = iVitalsAffector.DischargeValue(contactEvent.contactType); return(TestApplyChange(charge, iVitalsAffector)); }
public ContactEvent(ContactEvent contactEvent) { this.contactSystem = contactEvent.contactSystem; this.contactTrigger = contactEvent.contactTrigger; this.contactType = contactEvent.contactType; }
public Mount TryPickup(IContactReactor reactor, ContactEvent contactEvent) { return(DefaultMount); }
protected override Consumption ProcessContactEvent(ContactEvent contactEvent) { //Debug.Log("Process " + contactEvent + " -- " + (contactEvent.contactSystem as IVitalsSystem)); //double consumed; var system = (contactEvent.contactSystem as IVitalsSystem); if (system == null) { return(Consumption.None); } double value = GetValueForTriggerType(contactEvent.contactType); //if (vitalNameType.type == VitalType.None) //{ // consumed = system.Vitals.ApplyCharges(vitalNameType, value, allowOverload, propagate); //} //else //{ // Vital vital = system.Vitals.GetVital(vitalNameType); // if (ReferenceEquals(vital, null)) // { // Debug.LogWarning("No matching Vital found."); // return Consumption.None; // } // //consumed = vital.ApplyChange(value, this); //} double consumed = system.Vitals.ApplyCharges(vitalNameType, value, allowOverload, propagate); Consumption consumption; if (useCharges) { consumption = ConsumeCharges(consumed); } else if (consumed != 0) { if (consumed == value) { consumption = Consumption.All; } else { consumption = Consumption.Partial; } Consume(consumption); } else { //Debug.LogWarning("Reactor not consumed."); return(Consumption.None); } ///// TEST - Notify other component of pickup condition //var onContact = transform.GetComponent<IOnPickup>(); //Debug.Log("POST 2 " + (onContact != null)); //if (onContact != null) // syncState.HardMount(onContact.OnPickup(contactEvent)); if (isPickup && consumption != Consumption.None) { Mount mount = system.TryPickup(this, contactEvent); if (mount) { syncState.HardMount(mount); } } return(consumption); }
public virtual void OnContact(IContactTrigger otherCT, ContactType contactType) { if (GetComponent <ContactProjectile>() && contactType == ContactType.Enter) { Debug.Log("Prj Contact"); } /// Check each system that is part of this contact event, to see if what it contacted with is applicable List <IContactSystem> systems = otherCT.Proxy.ContactSystems; int systemsCount = systems.Count; if (systemsCount == 0) { return; } /// May be important in preventing race conditions when objects first spawn in, where they might trigger contacts by starting in the wrong state. if (netObj != null && !this._proxy.NetObj.AllObjsAreReady) { //Debug.LogError(Time.time + name + " " + _proxy.NetObj.photonView.OwnerActorNr + " Not ready so ignoring contact"); return; } var otherNetObj = otherCT.Proxy.NetObj; if (otherNetObj != null && !otherNetObj.AllObjsAreReady) { Debug.Log(Time.time + name + " " + otherNetObj.photonView.OwnerActorNr + " Other object not ready so ignoring contact"); return; } for (int i = 0; i < systemsCount; i++) { var system = systems[i]; if (!IsCompatibleSystem(system, otherCT)) { continue; } //Debug.Log(name + " " + GetType().Name + " <> " + ics.GetType().Name + " <b>PASSED</b>"); /// Check to see if we have already reacted to this collision (multiple colliders/etc) if (preventRepeats) { switch (contactType) { case ContactType.Enter: { if (triggeringEnters.Contains(system)) { continue; } triggeringEnters.Add(system); break; } case ContactType.Stay: { if (triggeringStays.Contains(system)) { continue; } triggeringStays.Add(system); break; } case ContactType.Exit: { if (!triggeringEnters.Contains(system)) { continue; } triggeringEnters.Remove(system); break; } case ContactType.Hitscan: { if (triggeringHitscans.Contains(system)) { continue; } triggeringHitscans.Add(system); break; } } } //Debug.Log("Other " + (otherCT as Component).name + " : " + (otherCT as Component).GetType().Name); /// Ignore contact types we have no reactors for. This runs after the above loop, because Enter/Stay/Exit all need to be processed for PreventRepeats to work. if ((usedContactTypes & contactType) == 0) { return; } /// If there is an ISyncContact, pass contactEvents to it rather than executing them. var contactEvent = new ContactEvent(system, otherCT, contactType); if (ReferenceEquals(Proxy.SyncContact, null)) { ContactCallbacks(contactEvent); } else { syncContact.SyncContactEvent(contactEvent); } } }