// Note: this is a recursive method. private void ReadBook(ConnectedPlayer player, int pageToRead = 0) { var playerTile = player.GameObject.RegisterTile(); if (pageToRead >= pagesToRead || pageToRead > 10) { FinishReading(player); return; } StandardProgressActionConfig cfg = new StandardProgressActionConfig( StandardProgressActionType.Construction, false, false ); StandardProgressAction.Create(cfg, ReadPage).ServerStartProgress( playerTile, timeToReadPage, player.GameObject ); void ReadPage() { readerProgress[player]++; SoundManager.PlayNetworkedAtPos(pageturnSfx.PickRandom(), playerTile.WorldPositionServer, sourceObj: player.GameObject); Chat.AddExamineMsgFromServer(player.GameObject, remarks.PickRandom()); ReadBook(player, readerProgress[player]); } }
public void ServerPerformInteraction(HandApply interaction) { void Perform() { var livingHealthMaster = interaction.TargetObject.GetComponent <LivingHealthMasterBase>(); var objectPos = gameObject.AssumedWorldPosServer(); if (CanDefibrillate(livingHealthMaster, interaction.Performer) == false) { _ = SoundManager.PlayNetworkedAtPosAsync(soundFailed, objectPos); StartCoroutine(Cooldown()); return; } livingHealthMaster.RestartHeart(); _ = SoundManager.PlayNetworkedAtPosAsync(soundZap, objectPos); if (livingHealthMaster.IsDead == false) { livingHealthMaster.playerScript.ReturnGhostToBody(); _ = SoundManager.PlayNetworkedAtPosAsync(soundSuccsuess, objectPos); StartCoroutine(Cooldown()); return; } _ = SoundManager.PlayNetworkedAtPosAsync(soundFailed, objectPos); StartCoroutine(Cooldown()); } if (isReady == false || onCooldown == true) { Chat.AddExamineMsg(interaction.Performer, $"You need to charge the {gameObject.ExpensiveName()} first!"); return; } var bar = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.CPR, false, false, true), Perform); bar.ServerStartProgress(interaction.Performer.RegisterTile(), Time, interaction.Performer); }
// Note: this is a recursive method. private void ReadBook(ConnectedPlayer player, int pageToRead = 0) { if (pageToRead >= pagesToRead || pageToRead > 10) { FinishReading(player); return; } StandardProgressActionConfig cfg = new StandardProgressActionConfig( StandardProgressActionType.Construction, false, false ); StandardProgressAction.Create(cfg, ReadPage).ServerStartProgress( player.GameObject.RegisterTile(), timeToReadPage, player.GameObject ); void ReadPage() { readerProgress[player]++; // TODO: play random page-turning sound => pageturn1.ogg || pageturn2.ogg || pageturn3.ogg string remark = remarks[Random.Range(0, remarks.Length)]; Chat.AddExamineMsgFromServer(player.GameObject, remark); ReadBook(player, readerProgress[player]); } }
/// <summary> /// Handles the interaction request for uncuffing serverside /// </summary> public void ServerPerformInteraction(ContextMenuApply interaction) { var handcuffSlots = interaction.TargetObject.GetComponent <DynamicItemStorage>().OrNull()?.GetNamedItemSlots(NamedSlot.handcuffs) .Where(x => x.IsEmpty == false).ToList(); if (handcuffSlots == null) { return; } //Somehow has no cuffs but has cuffed effect, force uncuff if (handcuffSlots.Count == 0) { Uncuff(); return; } foreach (var handcuffSlot in handcuffSlots) { var restraint = handcuffSlot.Item.GetComponent <Restraint>(); if (restraint == null) { continue; } var progressConfig = new StandardProgressActionConfig(StandardProgressActionType.Uncuff); StandardProgressAction.Create(progressConfig, Uncuff) .ServerStartProgress(interaction.TargetObject.RegisterTile(), restraint.RemoveTime * (handcuffSlots.Count / 2f), interaction.Performer); //Only need to do it once break; } }
public void ServerPerformInteraction(HandApply interaction) { void Perform() { var LHMB = interaction.TargetObject.GetComponent <LivingHealthMasterBase>(); if (LHMB.brain == null || LHMB.brain?.RelatedPart?.Health < -100) { Chat.AddExamineMsgFromServer(interaction.Performer, "It appears they're missing their brain or Their brain is too damaged"); } foreach (var BodyPart in LHMB.ImplantList) { foreach (var bodyPartModification in BodyPart.BodyPartModifications) { if (bodyPartModification is Heart heart) { heart.HeartAttack = false; heart.CanTriggerHeartAttack = false; heart.CurrentPulse = 0; } } } } var bar = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.CPR, false, false, true), Perform); bar.ServerStartProgress(interaction.Performer.RegisterTile(), Time, interaction.Performer); }
public void ServerBeginUnCuffAttempt() { float resistTime = GameObjectReference.GetComponent <Restraint>().ResistTime; healthCache = thisPlayerScript.playerHealth.OverallHealth; positionCache = thisPlayerScript.registerTile.LocalPositionServer; void ProgressFinishAction() { thisPlayerScript.playerMove.Uncuff(); Chat.AddActionMsgToChat(thisPlayerScript.gameObject, "You have successfully removed the cuffs", thisPlayerScript.playerName + " has removed their cuffs"); SoundManager.PlayNetworkedAtPos(restraintRemovalSound, thisPlayerScript.registerTile.WorldPosition, sourceObj: gameObject); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(thisPlayerScript.gameObject.RegisterTile(), resistTime, thisPlayerScript.gameObject); if (bar != null) { Chat.AddActionMsgToChat( thisPlayerScript.gameObject, $"You are attempting to remove the cuffs. This will take {resistTime:0} seconds", thisPlayerScript.playerName + " is attempting to remove their cuffs"); } }
public override void ServerPerformInteraction(TileApply interaction) { if (!interaction.UsedObject.RegisterTile().Matrix.IsPassableAt(interaction.TargetCellPos, true, true, null, excludeTiles)) { return; } StandardProgressActionConfig cfg = new StandardProgressActionConfig(StandardProgressActionType.Construction, false, false, false); var x = StandardProgressAction.Create(cfg, () => { PlayerScript playerScript; if (interaction.UsedObject.TryGetComponent(out playerScript)) { List <TileType> excludeTiles = new List <TileType>() { TileType.Table }; if (playerScript.registerTile.Matrix.IsPassableAt(interaction.TargetCellPos, true, true, null, excludeTiles)) { playerScript.PlayerSync.SetPosition(interaction.WorldPositionTarget); } } else { var transformComp = interaction.UsedObject.GetComponent <CustomNetTransform>(); if (transformComp != null) { transformComp.AppearAtPositionServer(interaction.WorldPositionTarget); } } }).ServerStartProgress(interaction.UsedObject.RegisterTile(), 3.0f, interaction.Performer); }
public override void TryConsume(GameObject feederGO, GameObject eaterGO) { var eater = eaterGO.GetComponent <PlayerScript>(); if (eater == null) { // todo: implement non-player eating SoundManager.PlayNetworkedAtPos(sound, eater.WorldPos); Despawn.ServerSingle(gameObject); return; } var feeder = feederGO.GetComponent <PlayerScript>(); // Show eater message var eaterHungerState = eater.playerHealth.Metabolism.HungerState; ConsumableTextUtils.SendGenericConsumeMessage(feeder, eater, eaterHungerState, Name, "eat"); // Check if eater can eat anything if (feeder != eater) //If you're feeding it to someone else. { //Wait 3 seconds before you can feed StandardProgressAction.Create(ProgressConfig, () => { ConsumableTextUtils.SendGenericForceFeedMessage(feeder, eater, eaterHungerState, Name, "eat"); Eat(eater, feeder); }).ServerStartProgress(eater.registerTile, 3f, feeder.gameObject); return; } else { Eat(eater, feeder); } }
public void ServerPerformInteraction(PositionalHandApply interaction) { if (reagentContainer.CurrentCapacity < 1) { //warning Chat.AddExamineMsg(interaction.Performer, "Your mop is dry!"); return; } //server is performing server-side logic for the interaction //do the mopping void CompleteProgress() { CleanTile(interaction.WorldPositionTarget); Chat.AddExamineMsg(interaction.Performer, "You finish mopping."); } //Start the progress bar: var bar = StandardProgressAction.Create(ProgressConfig, CompleteProgress) .ServerStartProgress(interaction.WorldPositionTarget.RoundToInt(), useTime, interaction.Performer); if (bar) { Chat.AddActionMsgToChat(interaction.Performer, $"You begin to clean the floor with {gameObject.ExpensiveName()}...", $"{interaction.Performer.name} begins to clean the floor with {gameObject.ExpensiveName()}."); } }
public void ServerPerformInteraction(PositionalHandApply interaction) { if (Validations.HasItemTrait(interaction.HandObject, CommonTraits.Instance.Wrench)) { SoundManager.PlayNetworkedAtPos("Wrench", interaction.WorldPositionTarget, 1f); Spawn.ServerPrefab("Metal", interaction.WorldPositionTarget.RoundToInt(), transform.parent, count: 1, scatterRadius: Spawn.DefaultScatterRadius, cancelIfImpassable: true); Despawn.ServerSingle(gameObject); return; } void ProgressComplete() { Chat.AddExamineMsgFromServer(interaction.Performer, "You assemble a rack."); Spawn.ServerPrefab(rackPrefab, interaction.WorldPositionTarget.RoundToInt(), interaction.Performer.transform.parent); var handObj = interaction.HandObject; Inventory.ServerDespawn(interaction.HandSlot); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressComplete) .ServerStartProgress(interaction.WorldPositionTarget.RoundToInt(), 5f, interaction.Performer); if (bar != null) { Chat.AddExamineMsgFromServer(interaction.Performer, "You start constructing a rack..."); } }
public void CmdRequestCPR(GameObject cardiacArrestPlayer) { //TODO: Probably refactor this to IF2 if (!Validations.CanApply(playerScript, cardiacArrestPlayer, NetworkSide.Server)) { return; } if (!Cooldowns.TryStartServer(playerScript, CommonCooldowns.Instance.Interaction)) { return; } var cardiacArrestPlayerRegister = cardiacArrestPlayer.GetComponent <RegisterPlayer>(); void ProgressComplete() { DoCPR(playerScript.gameObject, cardiacArrestPlayer); } var bar = StandardProgressAction.Create(CPRProgressConfig, ProgressComplete) .ServerStartProgress(cardiacArrestPlayerRegister, 5f, playerScript.gameObject); if (bar != null) { Chat.AddActionMsgToChat(playerScript.gameObject, $"You begin performing CPR on {cardiacArrestPlayer.Player()?.Name}.", $"{playerScript.gameObject.Player()?.Name} is trying to perform CPR on {cardiacArrestPlayer.Player()?.Name}."); } }
protected void PinRemoval(InventoryApply interaction) { void ProgressFinishAction() { Chat.AddActionMsgToChat(interaction.Performer, $"You remove the {FiringPin.gameObject.ExpensiveName()} from {gameObject.ExpensiveName()}", $"{interaction.Performer.ExpensiveName()} removes the {FiringPin.gameObject.ExpensiveName()} from {gameObject.ExpensiveName()}."); SyncPredictionCanFire(predictionCanFire, false); Inventory.ServerDrop(pinSlot); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(interaction.Performer.RegisterTile(), PinRemoveTime, interaction.Performer); if (bar != null) { Chat.AddActionMsgToChat(interaction.Performer, $"You begin removing the {FiringPin.gameObject.ExpensiveName()} from {gameObject.ExpensiveName()}", $"{interaction.Performer.ExpensiveName()} begins removing the {FiringPin.gameObject.ExpensiveName()} from {gameObject.ExpensiveName()}."); AudioSourceParameters audioSourceParameters = new AudioSourceParameters(UnityEngine.Random.Range(0.8f, 1.2f)); SoundManager.PlayNetworkedAtPos(SingletonSOSounds.Instance.WireCutter, interaction.Performer.AssumedWorldPosServer(), audioSourceParameters, sourceObj: serverHolder); } }
public void ServerPerformInteraction(HandApply interaction) { GameObject target = interaction.TargetObject; GameObject performer = interaction.Performer; void ProgressFinishAction() { if (performer.GetComponent <PlayerScript>()?.IsGameObjectReachable(target, true) ?? false) { target.GetComponent <PlayerMove>().Cuff(interaction); Chat.AddActionMsgToChat(performer, $"You successfully restrain {target.ExpensiveName()}.", $"{performer.ExpensiveName()} successfully restrains {target.ExpensiveName()}."); } } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(target.RegisterTile(), applyTime, performer); if (bar != null) { SoundManager.PlayNetworkedAtPos(sound, target.transform.position, sourceObj: target.gameObject); Chat.AddActionMsgToChat(performer, $"You begin restraining {target.ExpensiveName()}...", $"{performer.ExpensiveName()} begins restraining {target.ExpensiveName()}..."); } }
public void CmdDisrobe(GameObject toDisrobe) { if (!Validations.CanApply(playerScript, toDisrobe, NetworkSide.Server)) { return; } //only allowed if this player is an observer of the player to disrobe var itemStorage = toDisrobe.GetComponent <ItemStorage>(); if (itemStorage == null) { return; } //are we an observer of the player to disrobe? if (!itemStorage.ServerIsObserver(gameObject)) { return; } //disrobe each slot, taking .2s per each occupied slot //calculate time var occupiedSlots = itemStorage.GetItemSlots() .Count(slot => slot.NamedSlot != NamedSlot.handcuffs && !slot.IsEmpty); if (occupiedSlots == 0) { return; } if (!Cooldowns.TryStartServer(playerScript, CommonCooldowns.Instance.Interaction)) { return; } var timeTaken = occupiedSlots * .4f; void ProgressComplete() { var victimsHealth = toDisrobe.GetComponent <PlayerHealth>(); foreach (var itemSlot in itemStorage.GetItemSlots()) { //skip slots which have special uses if (itemSlot.NamedSlot == NamedSlot.handcuffs) { continue; } // cancels out of the loop if player gets up if (!victimsHealth.IsCrit) { break; } Inventory.ServerDrop(itemSlot); } } StandardProgressAction.Create(DisrobeProgressConfig, ProgressComplete) .ServerStartProgress(toDisrobe.RegisterTile(), timeTaken, gameObject); }
public override void Process() { LoadMultipleObjects(new uint[] { PlayerStorage, TargetStorage }); if (NetworkObjects[0] == null || NetworkObjects[1] == null) { return; } var playerSlot = ItemSlot.Get(NetworkObjects[0].GetComponent <ItemStorage>(), PlayerNamedSlot, PlayerSlotIndex); var targetSlot = ItemSlot.Get(NetworkObjects[1].GetComponent <ItemStorage>(), TargetNamedSlot, TargetSlotIndex); var playerScript = SentByPlayer.Script; var playerObject = playerScript.gameObject; var targetObject = targetSlot.Player.gameObject; if (!Validation(playerSlot, targetSlot, playerScript, targetObject, NetworkSide.Server)) { return; } int speed; if (!targetSlot.IsEmpty) { Chat.AddActionMsgToChat(playerObject, $"You try to remove {targetObject.ExpensiveName()}'s {targetSlot.ItemObject.ExpensiveName()}...", $"{playerObject.ExpensiveName()} tries to remove {targetObject.ExpensiveName()}'s {targetSlot.ItemObject.ExpensiveName()}."); speed = 3; } else { Chat.AddActionMsgToChat(playerObject, $"You try to put the {playerSlot.ItemObject.ExpensiveName()} on {targetObject.ExpensiveName()}...", $"{playerObject.ExpensiveName()} tries to put the {playerSlot.ItemObject.ExpensiveName()} on {targetObject.ExpensiveName()}."); speed = 1; } var progressAction = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.ItemTransfer), FinishTransfer); progressAction.ServerStartProgress(targetObject.RegisterTile(), speed, playerObject); void FinishTransfer() { if (!targetSlot.IsEmpty) { if (playerSlot.IsEmpty) { Inventory.ServerTransfer(targetSlot, playerSlot); } else { Inventory.ServerDrop(targetSlot); } } else { Inventory.ServerTransfer(playerSlot, targetSlot); } } }
public void ServerPerformInteraction(PositionalHandApply interaction) { //which matrix are we clicking on var interactableTiles = InteractableTiles.GetAt(interaction.WorldPositionTarget, true); Vector3Int cellPos = interactableTiles.WorldToCell(interaction.WorldPositionTarget); var tileAtPosition = interactableTiles.LayerTileAt(interaction.WorldPositionTarget, layerTypeSelection); PlaceableTileEntry placeableTileEntry = null; int itemAmount = 1; var stackable = interaction.HandObject.GetComponent <Stackable>(); if (stackable != null) { itemAmount = stackable.Amount; } // find the first valid way possible to place a tile foreach (var entry in waysToPlace) { //skip what can't be afforded if (entry.itemCost > itemAmount) { continue; } //open space if (tileAtPosition == null && entry.placeableOn == LayerType.None && entry.placeableOnlyOnTile == null) { placeableTileEntry = entry; break; } // placing on an existing tile else if (tileAtPosition.LayerType == entry.placeableOn && (entry.placeableOnlyOnTile == null || entry.placeableOnlyOnTile == tileAtPosition)) { placeableTileEntry = entry; break; } } if (placeableTileEntry != null) { GameObject performer = interaction.Performer; Vector2 targetPosition = interaction.WorldPositionTarget; void ProgressFinishAction() { interactableTiles.TileChangeManager.UpdateTile(cellPos, placeableTileEntry.layerTile); interactableTiles.TileChangeManager.SubsystemManager.UpdateAt(cellPos); Inventory.ServerConsume(interaction.HandSlot, placeableTileEntry.itemCost); SoundManager.PlayNetworkedAtPos(placeSound, targetPosition); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(targetPosition, placeableTileEntry.timeToPlace, performer); } }
public void EntityTryEscape(GameObject performer, Action ifCompleted) { // First, try to just open the closet. Anything can do this. if (IsLocked == false && IsWelded == false) { SetDoor(Door.Opened); ifCompleted?.Invoke(); return; } GameObject sourceobjbehavior = gameObject; RegisterObject sourceregisterobject = registerObject; if (pushPull.parentContainer != null) { sourceobjbehavior = pushPull.parentContainer.gameObject; sourceregisterobject = sourceobjbehavior.GetComponent <RegisterObject>(); } // banging sound SoundManager.PlayNetworkedAtPos(soundOnEscapeAttempt, sourceregisterobject.WorldPositionServer, sourceObj: sourceobjbehavior); // complex task involved if (performer.Player() == null) { return; } var bar = StandardProgressAction.Create(ProgressConfig, () => { ifCompleted?.Invoke(); if (IsWelded) { // Remove the weld SetWeld(Weld.NotWelded); } if (IsLocked) { BreakLock(); } SetDoor(Door.Opened); SoundManager.PlayNetworkedAtPos(soundOnEmag, sourceregisterobject.WorldPositionServer, sourceObj: sourceobjbehavior); Chat.AddActionMsgToChat(performer, $"You successfully break out of the {closetName}.", $"{performer.ExpensiveName()} emerges from the {closetName}!"); }); bar.ServerStartProgress(sourceregisterobject, breakoutTime, performer); SoundManager.PlayNetworkedAtPos(soundOnEscape, sourceregisterobject.WorldPositionServer, sourceObj: sourceobjbehavior); Chat.AddActionMsgToChat(performer, $"You begin breaking out of the {closetName}...", $"You hear noises coming from the {closetName}... Something must be trying to break out!"); }
public void ServerPerformInteraction(HandApply interaction) { //Server actions // Close the door if it's open if (!Controller.IsClosed) { Controller.ServerTryClose(); } else { if (Validations.HasItemTrait(interaction.HandObject, CommonTraits.Instance.Welder)) // welding the door (only if closed and not helping) { if (Controller.IsWeldable) { var welder = interaction.HandObject.GetComponent <Welder>(); if (welder.IsOn && interaction.Intent != Intent.Help) { void ProgressComplete() { if (Controller != null) { Chat.AddExamineMsgFromServer(interaction.Performer, "You " + (Controller.IsWelded ? "unweld" : "weld") + " the door."); Controller.ServerTryWeld(); } } var bar = StandardProgressAction.CreateForWelder(ProgressConfig, ProgressComplete, welder) .ServerStartProgress(interaction.Performer.transform.position, weldTime, interaction.Performer); if (bar != null) { SoundManager.PlayNetworkedAtPos("Weld", interaction.Performer.transform.position, Random.Range(0.8f, 1.2f), sourceObj: interaction.Performer); Chat.AddExamineMsgFromServer(interaction.Performer, "You start " + (Controller.IsWelded ? "unwelding" : "welding") + " the door..."); } return; } } else if (!Controller.IsAutomatic) { ToolUtils.ServerUseToolWithActionMessages(interaction, 4f, "You start to disassemble the false wall...", $"{interaction.Performer.ExpensiveName()} starts to disassemble the false wall...", "You disassemble the girder.", $"{interaction.Performer.ExpensiveName()} disassembles the false wall.", () => Controller.ServerDisassemble(interaction)); return; } } // Attempt to open if it's closed Controller.ServerTryOpen(interaction.Performer); } allowInput = false; StartCoroutine(DoorInputCoolDown()); }
private void ServerSelfHeal(GameObject originator, LivingHealthMasterBase livingHealthMasterBase, HandApply interaction) { void ProgressComplete() { ServerApplyHeal(livingHealthMasterBase, interaction); } StandardProgressAction.Create(ProgressConfig, ProgressComplete) .ServerStartProgress(originator.RegisterTile(), 5f, originator); }
private void ServerSelfHeal(GameObject originator, BodyPartBehaviour targetBodyPart) { void ProgressComplete() { ServerApplyHeal(targetBodyPart); } StandardProgressAction.Create(ProgressConfig, ProgressComplete) .ServerStartProgress(originator.RegisterTile(), 5f, originator); }
public void ServerPerformInteraction(MouseDrop interaction) { StandardProgressActionConfig cfg = new StandardProgressActionConfig(StandardProgressActionType.Construction, false, false, false); StandardProgressAction.Create(cfg, () => { if (interaction.UsedObject.TryGetComponent <PlayerScript>(out var playerScript)) { playerScript.PlayerSync.SetPosition(gameObject.WorldPosServer()); }
public override void TryConsume(GameObject feederGO, GameObject eaterGO) { if (!container) { return; } // todo: make seperate logic for NPC var eater = eaterGO.GetComponent <PlayerScript>(); var feeder = feederGO.GetComponent <PlayerScript>(); if (eater == null || feeder == null) { return; } // Check if player is wearing clothing that prevents eating or drinking if (eater.Equipment.CanConsume() == false) { Chat.AddExamineMsgFromServer(eater.gameObject, $"Remove items that cover your mouth first!"); return; } // Check if container is empty var reagentUnits = container.ReagentMixTotal; if (reagentUnits <= 0f) { Chat.AddExamineMsgFromServer(eater.gameObject, $"The {gameObject.ExpensiveName()} is empty."); return; } // Get current container name var name = itemAttributes ? itemAttributes.ArticleName : gameObject.ExpensiveName(); // Generate message to player ConsumableTextUtils.SendGenericConsumeMessage(feeder, eater, HungerState.Hungry, name, "drink"); if (feeder != eater) //If you're feeding it to someone else. { //Wait 3 seconds before you can feed StandardProgressAction.Create(ProgressConfig, () => { ConsumableTextUtils.SendGenericForceFeedMessage(feeder, eater, HungerState.Hungry, name, "drink"); Drink(eater, feeder); }).ServerStartProgress(eater.registerTile, 3f, feeder.gameObject); return; } else { Drink(eater, feeder); } }
public void ServerPerformInteraction(PositionalHandApply interaction) { bool emptyHand = interaction.HandSlot.IsEmpty; var wna = interaction.Performer.GetComponent <WeaponNetworkActions>(); if (interactableTiles != null && !emptyHand) { //attacking tiles var tileAt = interactableTiles.LayerTileAt(interaction.WorldPositionTarget, true); if (tileAt == null) { return; } if (tileAt.TileType == TileType.Wall) { return; } wna.ServerPerformMeleeAttack(gameObject, interaction.TargetVector, BodyPartType.None, tileAt.LayerType); } else { //attacking objects //butcher check GameObject victim = interaction.TargetObject; var healthComponent = victim.GetComponent <LivingHealthBehaviour>(); if (healthComponent && healthComponent.allowKnifeHarvest && healthComponent.IsDead && Validations.HasItemTrait(interaction.HandObject, CommonTraits.Instance.Knife) && interaction.Intent == Intent.Harm) { GameObject performer = interaction.Performer; void ProgressFinishAction() { LivingHealthBehaviour victimHealth = victim.GetComponent <LivingHealthBehaviour>(); victimHealth.Harvest(); SoundManager.PlayNetworkedAtPos(butcherSound, victim.RegisterTile().WorldPositionServer); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(victim.RegisterTile(), butcherTime, performer); } else { if (gameObject.GetComponent <Integrity>() && emptyHand) { return; } wna.ServerPerformMeleeAttack(gameObject, interaction.TargetVector, interaction.TargetBodyPart, LayerType.None); } } }
protected void StartUnwrapAction(GameObject performer) { var cfg = new StandardProgressActionConfig( StandardProgressActionType.Restrain); Chat.AddActionMsgToChat( performer, string.Format(originatorUnwrapText, gameObject.ExpensiveName()), string.Format(othersUnwrapText, performer.ExpensiveName(), gameObject.ExpensiveName())); StandardProgressAction.Create(cfg, UnWrap) .ServerStartProgress(ActionTarget.Object(performer.RegisterTile()), timeToUnwrap, performer); }
public override void TryConsume(GameObject feederGO, GameObject eaterGO) { var eater = eaterGO.GetComponent <PlayerScript>(); if (eater == null) { // todo: implement non-player eating AudioSourceParameters eatSoundParameters = new AudioSourceParameters(pitch: RandomPitch); SoundManager.PlayNetworkedAtPos(sound, item.WorldPosition, eatSoundParameters); if (leavings != null) { Spawn.ServerPrefab(leavings, item.WorldPosition, transform.parent); } _ = Despawn.ServerSingle(gameObject); return; } var feeder = feederGO.GetComponent <PlayerScript>(); // Check if player is wearing clothing that prevents eating or drinking if (eater.Equipment.CanConsume() == false) { Chat.AddExamineMsgFromServer(eater.gameObject, $"Remove items that cover your mouth first!"); return; } // Show eater message var eaterHungerState = eater.playerHealth.HungerState; ConsumableTextUtils.SendGenericConsumeMessage(feeder, eater, eaterHungerState, Name, "eat"); // Check if eater can eat anything if (eaterHungerState != HungerState.Full) { if (feeder != eater) //If you're feeding it to someone else. { //Wait 3 seconds before you can feed StandardProgressAction.Create(ProgressConfig, () => { ConsumableTextUtils.SendGenericForceFeedMessage(feeder, eater, eaterHungerState, Name, "eat"); Eat(eater, feeder); }).ServerStartProgress(eater.registerTile, 3f, feeder.gameObject); return; } else { Eat(eater, feeder); } } }
private void StartCrafting(CraftingRecipe recipe, CraftingActionParameters craftingActionParameters) { if (recipe.CraftingTime.Approx(0)) { // ok then there is no need to create a special progress action TryToFinishCrafting(recipe, craftingActionParameters); return; } StandardProgressAction.Create( craftProgressActionConfig, () => TryToFinishCrafting(recipe, craftingActionParameters) ).ServerStartProgress(playerScript.registerTile, recipe.CraftingTime, playerScript.gameObject); }
public void ServerPerformInteraction(PositionalHandApply interaction) { //which matrix are we clicking on var matrix = InteractableTiles.TryGetNonSpaceMatrix(interaction.WorldPositionTarget.RoundToInt(), true); if (matrix.IsSpaceMatrix) { matrix = interaction.Performer.RegisterTile().Matrix; } var interactableTiles = matrix.TileChangeManager.InteractableTiles; Vector3Int cellPos = interactableTiles.WorldToCell(interaction.WorldPositionTarget); var tileAtPosition = interactableTiles.LayerTileAt(interaction.WorldPositionTarget, layerTypeSelection); PlaceableTileEntry placeableTileEntry = null; int itemAmount = 1; var stackable = interaction.HandObject.GetComponent <Stackable>(); if (stackable != null) { itemAmount = stackable.Amount; } placeableTileEntry = FindValidTile(itemAmount, tileAtPosition); if (placeableTileEntry != null) { GameObject performer = interaction.Performer; Vector2 targetPosition = interaction.WorldPositionTarget; void ProgressFinishAction() { ProgressFinishActionPriv(interaction, placeableTileEntry, interactableTiles, cellPos, targetPosition); } void ProgressInterruptedAction(ActionInterruptionType reason) { ProgressInterruptedActionPriv(interaction, reason, placeableTileEntry); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction, ProgressInterruptedAction) .ServerStartProgress(targetPosition, placeableTileEntry.timeToPlace, performer); } }
protected override void Wrap(GameObject performer, WrappingPaper paper) { var cfg = new StandardProgressActionConfig( StandardProgressActionType.Restrain); Chat.AddActionMsgToChat( performer, string.Format(actionTextOriginator, gameObject.ExpensiveName(), paper.gameObject.ExpensiveName()), string.Format(actionTextOthers, performer.ExpensiveName(), gameObject.ExpensiveName(), paper.gameObject.ExpensiveName())); StandardProgressAction.Create( cfg, () => FinishWrapping(paper) ).ServerStartProgress(ActionTarget.Object(performer.RegisterTile()), wrapTime, performer); }
/// <summary> /// Performs common tool usage logic, such as playing the correct sound. /// If item is not a tool, simply performs the progress action normally. /// </summary> /// <param name="performer">player using the tool</param> /// <param name="tool">tool being used</param> /// <param name="actionTarget">target of the action</param> /// <param name="seconds">seconds taken to perform the action, 0 if it should be instant</param> /// <param name="progressCompleteAction">completion callback (will also be called instantly if completion is instant)</param> /// <param name="playSound">Whether to play default tool sound</param> /// <returns>progress bar spawned, null if progress did not start or this was instant</returns> public static ProgressBar ServerUseTool(GameObject performer, GameObject tool, ActionTarget actionTarget, float seconds, Action progressCompleteAction, bool playSound = true) { //check tool stats var toolStats = tool.GetComponent <Tool>(); if (toolStats != null) { seconds /= toolStats.SpeedMultiplier; } if (seconds <= 0f) { if (playSound) { ServerPlayToolSound(tool, actionTarget.TargetWorldPosition, performer); } // Check for null as ServerUseTool(interaction) accepts null Action if (progressCompleteAction != null) { progressCompleteAction.Invoke(); } return(null); } else { var welder = tool.GetComponent <Welder>(); ProgressBar bar; if (welder != null) { bar = StandardProgressAction.CreateForWelder(ProgressConfig, progressCompleteAction, welder) .ServerStartProgress(actionTarget, seconds, performer); } else { bar = StandardProgressAction.Create(ProgressConfig, progressCompleteAction) .ServerStartProgress(actionTarget, seconds, performer); } if (bar != null && playSound) { ServerPlayToolSound(tool, actionTarget.TargetWorldPosition, performer); } return(bar); } }
public void ServerPerformInteraction(PositionalHandApply interaction) { if (reagentContainer.ReagentMixTotal < 1) { //warning Chat.AddExamineMsg(interaction.Performer, "Your mop is dry!"); return; } //server is performing server-side logic for the interaction //do the mopping void CompleteProgress() { Vector3Int worldPos = interaction.WorldPositionTarget.RoundToInt(); MatrixInfo matrixInfo = MatrixManager.AtPoint(worldPos, true); Vector3Int localPos = MatrixManager.WorldToLocalInt(worldPos, matrixInfo); if (reagentContainer) { if (reagentContainer.MajorMixReagent == Water) { matrixInfo.MetaDataLayer.Clean(worldPos, localPos, true); reagentContainer.TakeReagents(reagentsPerUse); } else if (reagentContainer.MajorMixReagent == SpaceCleaner) { matrixInfo.MetaDataLayer.Clean(worldPos, localPos, false); reagentContainer.TakeReagents(reagentsPerUse); } else { MatrixManager.ReagentReact(reagentContainer.TakeReagents(reagentsPerUse), worldPos); } } Chat.AddExamineMsg(interaction.Performer, "You finish mopping."); } //Start the progress bar: var bar = StandardProgressAction.Create(ProgressConfig, CompleteProgress) .ServerStartProgress(interaction.WorldPositionTarget.RoundToInt(), useTime, interaction.Performer); if (bar) { Chat.AddActionMsgToChat(interaction.Performer, $"You begin to clean the floor with the {gameObject.ExpensiveName()}...", $"{interaction.Performer.name} begins to clean the floor with the {gameObject.ExpensiveName()}."); } }