//For now allow only emag hacking for setting 3 private void TryEmagController(HandApply interaction) { if (isHacked) { Chat.AddExamineMsgFromServer(interaction.Performer, $"The {gameObject.ExpensiveName()} has already been hacked!"); return; } Chat.AddActionMsgToChat(interaction.Performer, $"You attempt to hack the {gameObject.ExpensiveName()}, this will take around {timeToHack} seconds", $"{interaction.Performer.ExpensiveName()} starts hacking the {gameObject.ExpensiveName()}"); var cfg = new StandardProgressActionConfig(StandardProgressActionType.Restrain); StandardProgressAction.Create( cfg, () => FinishHack(interaction) ).ServerStartProgress(ActionTarget.Object(registerTile), timeToHack, interaction.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>(); // 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); } } }
/// <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> /// <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) { //check tool stats var toolStats = tool.GetComponent <Tool>(); if (toolStats != null) { seconds /= toolStats.SpeedMultiplier; } if (seconds <= 0f) { 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) { ServerPlayToolSound(tool, actionTarget.TargetWorldPosition, performer); } return(bar); } }
public void EntityTryEscape(GameObject entity, Action ifCompleted) { if (entity.Player() == null) { return; } if (escapeTime <= 0.1f) { OpenDrawer(); return; } var bar = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.Escape, true, false, true, true), OpenDrawer); bar.ServerStartProgress(gameObject.RegisterTile(), escapeTime, entity); Chat.AddActionMsgToChat(entity, $"You begin breaking out of the {gameObject.ExpensiveName()}...", $"You hear noises coming from the {gameObject.ExpensiveName()}... Something must be trying to break out!"); }
public void ServerPerformInteraction(PositionalHandApply interaction) { //server is performing server-side logic for the interaction //do the mining void ProgressComplete() => FinishMine(interaction); //Start the progress bar: //technically pickaxe is deconstruction, so it would interrupt any construction / deconstruction being done //on that tile //TODO: Refactor this to use ToolUtils once that's merged in var bar = StandardProgressAction.Create(ProgressConfig, ProgressComplete) .ServerStartProgress(interaction.WorldPositionTarget.RoundToInt(), 5f, interaction.Performer); if (bar != null) { SoundManager.PlayNetworkedAtPos("pickaxe#", interaction.WorldPositionTarget); } }
public void ServerPerformInteraction(PositionalHandApply interaction) { var wna = interaction.Performer.GetComponent <WeaponNetworkActions>(); if (interactableTiles != null) { //attacking tiles var tileAt = interactableTiles.LayerTileAt(interaction.WorldPositionTarget, true); if (tileAt == null) { 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, butcherKnifeTrait) && 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 { wna.ServerPerformMeleeAttack(gameObject, interaction.TargetVector, interaction.TargetBodyPart, LayerType.None); } } }
// TODO This was copied from somewhere. Where? void StartStoringPlayer(MouseDrop interaction) { List <LayerType> excludeObjects = new List <LayerType>() { LayerType.Objects }; Vector3Int targetObjectLocalPosition = interaction.TargetObject.RegisterTile().LocalPosition; Vector3Int targetObjectWorldPos = interaction.TargetObject.WorldPosServer().CutToInt(); if (!interaction.UsedObject.RegisterTile().Matrix.IsPassableAt(targetObjectLocalPosition, true, excludeLayers: excludeObjects)) { return; } void StoringPlayer() { PlayerScript playerScript; if (interaction.UsedObject.TryGetComponent(out playerScript)) { if (playerScript.registerTile.Matrix.IsPassableAt(targetObjectLocalPosition, true, excludeLayers: excludeObjects)) { playerScript.PlayerSync.SetPosition(targetObjectWorldPos); } } else { var transformComp = interaction.UsedObject.GetComponent <CustomNetTransform>(); if (transformComp != null) { transformComp.AppearAtPositionServer(targetObjectWorldPos); } } StorePlayer(interaction); } StandardProgressActionConfig cfg = new StandardProgressActionConfig(StandardProgressActionType.Construction, false, false, false); StandardProgressAction.Create(cfg, StoringPlayer).ServerStartProgress(interaction.UsedObject.RegisterTile(), 2, interaction.Performer); }
public void ServerPerformInteraction(HandApply interaction) { GameObject target = interaction.TargetObject; GameObject performer = interaction.Performer; void ProgressFinishAction() { if (performer.GetComponent <PlayerScript>()?.IsInReach(target, true) ?? false) { target.GetComponent <PlayerMove>().Cuff(interaction); } } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(target.RegisterTile(), applyTime, performer); if (bar != null) { SoundManager.PlayNetworkedAtPos(sound, target.transform.position); } }
public void CmdUnbuckle() { if (IsCuffed) { Chat.AddActionMsgToChat( playerScript.gameObject, "You're trying to ubuckle yourself from the chair! (this will take some time...)", playerScript.name + " is trying to ubuckle themself from the chair!" ); StandardProgressAction.Create( new StandardProgressActionConfig(StandardProgressActionType.Unbuckle), Unbuckle ).ServerStartProgress( buckledObject.RegisterTile(), buckledObject.GetComponent <BuckleInteract>().ResistTime, playerScript.gameObject ); return; } Unbuckle(); }
public void ServerPerformInteraction(HandApply interaction) { void Perform() { var livingHealthMaster = interaction.TargetObject.GetComponent <LivingHealthMasterBase>(); if (CanDefibrillate(livingHealthMaster, interaction.Performer) == false) { return; } livingHealthMaster.RestartHeart(); if (livingHealthMaster.IsDead == false) { livingHealthMaster.playerScript.ReturnGhostToBody(); } } var bar = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.CPR, false, false, true), Perform); bar.ServerStartProgress(interaction.Performer.RegisterTile(), Time, interaction.Performer); }
/// <summary> /// Handles the interaction request for uncuffing serverside /// </summary> public void ServerPerformInteraction(ContextMenuApply interaction) { var handcuffs = interaction.TargetObject.GetComponent <ItemStorage>().GetNamedItemSlot(NamedSlot.handcuffs).ItemObject; if (handcuffs == null) { return; } var restraint = handcuffs.GetComponent <Restraint>(); if (restraint == null) { return; } var ProgressConfig = new StandardProgressActionConfig(StandardProgressActionType.Uncuff); StandardProgressAction.Create(ProgressConfig, Uncuff) .ServerStartProgress(interaction.TargetObject.RegisterTile(), restraint.RemoveTime, interaction.Performer); }
// TODO This was copied from somewhere. Where? void StartStoringPlayer(MouseDrop interaction) { Vector3Int targetObjectLocalPosition = interaction.TargetObject.RegisterTile().LocalPosition; Vector3Int targetObjectWorldPos = interaction.TargetObject.WorldPosServer().CutToInt(); // We check if there's nothing in the way, like another player or a directional window. if (interaction.UsedObject.RegisterTile().Matrix.IsPassableAtOneMatrixOneTile(targetObjectLocalPosition, true, context: gameObject) == false) { return; } // Runs when the progress action is complete. void StoringPlayer() { PlayerScript playerScript; if (interaction.UsedObject.TryGetComponent(out playerScript)) { if (playerScript.registerTile.Matrix.IsPassableAtOneMatrixOneTile(targetObjectLocalPosition, true, context: gameObject)) { playerScript.PlayerSync.SetPosition(targetObjectWorldPos); } } else { var transformComp = interaction.UsedObject.GetComponent <CustomNetTransform>(); if (transformComp != null) { transformComp.AppearAtPositionServer(targetObjectWorldPos); } } StorePlayer(interaction); } StandardProgressActionConfig cfg = new StandardProgressActionConfig(StandardProgressActionType.Construction, false, false, false); StandardProgressAction.Create(cfg, StoringPlayer).ServerStartProgress(interaction.UsedObject.RegisterTile(), 2, interaction.Performer); }
public void ServerPerformInteraction(HandApply interaction) { void Perform() { var LHMB = interaction.TargetObject.GetComponent <LivingHealthMasterBase>(); foreach (var BodyPart in LHMB.ImplantList) { var heart = BodyPart as Heart; if (heart != null) { 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); }
private void PowerCellRemoval(InventoryApply interaction) { void ProgressFinishAction() { Chat.AddActionMsgToChat(interaction.Performer, $"The {gameObject.ExpensiveName()}'s power cell pops out", $"{interaction.Performer.ExpensiveName()} finishes removing {gameObject.ExpensiveName()}'s energy cell."); base.RequestUnload(CurrentMagazine); } var bar = StandardProgressAction.Create(base.ProgressConfig, ProgressFinishAction) .ServerStartProgress(interaction.Performer.RegisterTile(), magRemoveTime, interaction.Performer); if (bar != null) { Chat.AddActionMsgToChat(interaction.Performer, $"You begin unsecuring the {gameObject.ExpensiveName()}'s power cell.", $"{interaction.Performer.ExpensiveName()} begins unsecuring {gameObject.ExpensiveName()}'s power cell."); AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: UnityEngine.Random.Range(0.8f, 1.2f)); SoundManager.PlayNetworkedAtPos(SingletonSOSounds.Instance.screwdriver, interaction.Performer.AssumedWorldPosServer(), audioSourceParameters, sourceObj: serverHolder); } }
public void ServerPerformInteraction(PositionalHandApply interaction) { //server is performing server-side logic for the interaction //do the scrubbing void CompleteProgress() { CleanTile(interaction); Chat.AddExamineMsg(interaction.Performer, "You finish scrubbing."); } //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 scrub the floor with the {gameObject.ExpensiveName()}...", $"{interaction.Performer.name} begins to scrub the floor with the {gameObject.ExpensiveName()}."); } }
public void PlayerTryEscaping(GameObject player) { // First, try to just open the closet. if (!isLocked && !isWelded) { ServerToggleClosed(); } else { GameObject target = this.gameObject; GameObject performer = player; void ProgressFinishAction() { //TODO: Add some sound here. ServerToggleClosed(); BreakLock(); //Remove the weld if (isWelded) { ServerTryWeld(); } SoundManager.PlayNetworkedAtPos(soundOnEmag, registerTile.WorldPositionServer, 1f, sourceObj: gameObject); Chat.AddActionMsgToChat(performer, $"You successfully broke out of {target.ExpensiveName()}.", $"{performer.ExpensiveName()} successfully breaks out of {target.ExpensiveName()}."); } var bar = StandardProgressAction.Create(ProgressConfig, ProgressFinishAction) .ServerStartProgress(target.RegisterTile(), breakoutTime, performer); if (bar != null) { SoundManager.PlayNetworkedAtPos(soundOnEscape, registerTile.WorldPositionServer, 1f, sourceObj: gameObject); Chat.AddActionMsgToChat(performer, $"You begin breaking out of {target.ExpensiveName()}...", $"{performer.ExpensiveName()} begins breaking out of {target.ExpensiveName()}..."); } } }
public void ServerPerformInteraction(PositionalHandApply interaction) { if (Validations.HasItemTrait(interaction.HandObject, CommonTraits.Instance.Wrench)) { ToolUtils.ServerPlayToolSound(interaction); Spawn.ServerPrefab(CommonPrefabs.Instance.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; if (handObj != null && handObj.GetInstanceID() == gameObject.GetInstanceID()) // the rack parts were assembled from the hands, despawn in inventory-fashion { // (note: instanceIDs used in case somebody starts assembling rack parts on the ground with rack parts in hand (which was not possible at the time this was written)) Inventory.ServerDespawn(interaction.HandSlot); } else // the rack parts were assembled from the ground, despawn in general fashion { Despawn.ServerSingle(gameObject); } } 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 override void Process() { LoadNetworkObject(PlayerToUncuff); GameObject actor = SentByPlayer.GameObject; GameObject playerToUncuff = NetworkObject; var handcuffs = playerToUncuff.GetComponent <ItemStorage>().GetNamedItemSlot(NamedSlot.handcuffs).ItemObject; if (handcuffs != null) { var restraint = handcuffs.GetComponent <Restraint>(); if (restraint) { void ProgressComplete() { playerToUncuff.GetComponent <PlayerMove>().RequestUncuff(actor); } StandardProgressAction.Create(ProgressConfig, ProgressComplete) .ServerStartProgress(playerToUncuff.RegisterTile(), restraint.RemoveTime, actor); } } }
public void ServerBeginUnCuffAttempt() { if (uncuffCoroutine != null) { StopCoroutine(uncuffCoroutine); } float resistTime = GameObjectReference.GetComponent <Restraint>().ResistTime; positionCache = thisPlayerScript.registerTile.LocalPositionServer; if (!CanUncuff()) { return; } var bar = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.Unbuckle, false, false, true), TryUncuff); bar.ServerStartProgress(thisPlayerScript.registerTile, resistTime, thisPlayerScript.gameObject); Chat.AddActionMsgToChat( thisPlayerScript.gameObject, $"You are attempting to remove the cuffs. This takes up to {resistTime:0} seconds", thisPlayerScript.playerName + " is attempting to remove their cuffs"); }
public void ServerCheckStandingChange(bool LayingDown, bool DoBar = false, float Time = 0.5f) { if (this.isLayingDown != LayingDown) { foreach (var Status in CheckableStatuses) { if (Status.AllowChange(LayingDown) == false) { return; } } if (DoBar) { var bar = StandardProgressAction.Create(new StandardProgressActionConfig(StandardProgressActionType.SelfHeal, false, false, true), ServerStandUp); bar.ServerStartProgress(this, 1.5f, gameObject); } else { SyncIsLayingDown(isLayingDown, LayingDown); } } }
public void ServerPerformInteraction(HandApply interaction) { performerName = interaction.Performer.ExpensiveName(); targetName = interaction.TargetObject.ExpensiveName(); var cardiacArrestPlayerRegister = interaction.TargetObject.GetComponent <RegisterPlayer>(); void ProgressComplete() { ServerDoCPR(interaction.Performer, interaction.TargetObject, interaction.TargetBodyPart); } var cpr = StandardProgressAction.Create(CPRProgressConfig, ProgressComplete) .ServerStartProgress(cardiacArrestPlayerRegister, CPR_TIME, interaction.Performer); if (cpr != null) { Chat.AddActionMsgToChat( interaction.Performer, $"You begin performing CPR on {targetName}'s " + interaction.TargetBodyPart, $"{performerName} is trying to perform CPR on {targetName}'s " + interaction.TargetBodyPart); } }
public override void ServerPerformInteraction(TileApply interaction) { if (!interaction.UsedObject.RegisterTile().Matrix.IsPassableAtOneMatrixOneTile(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.IsPassableAtOneMatrixOneTile(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); Chat.AddActionMsgToChat(interaction.Performer, "You begin climbing onto the table...", $"{interaction.Performer.ExpensiveName()} begins climbing onto the table..."); }
public void ServerPerformInteraction(HandApply interaction) { void Perform() { var livingHealthMaster = interaction.TargetObject.GetComponent <LivingHealthMasterBase>(); if (CanDefibrillate(livingHealthMaster, interaction.Performer) == false) { return; } foreach (var BodyPart in livingHealthMaster.BodyPartList) { foreach (var organ in BodyPart.OrganList) { if (organ is Heart heart) { heart.HeartAttack = false; heart.CanTriggerHeartAttack = false; heart.CurrentPulse = 0; } } } livingHealthMaster.CalculateOverallHealth(); if (livingHealthMaster.IsDead == false) { var ghost = livingHealthMaster.playerScript.mind?.ghost; if (ghost) { ghost.playerNetworkActions.GhostEnterBody(); } } } 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]); } }
public void CmdRequestCPR(GameObject cardiacArrestPlayer) { //TODO: Probably refactor this to IF2 if (!Validations.CanApply(playerScript, cardiacArrestPlayer, NetworkSide.Server)) { 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}."); } }
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; } // 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.MetaTileMap.SetTile(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 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 (IsGhost) { if (playerScript.IsGhost && PlayerList.Instance.IsAdmin(playerScript.connectedPlayer.UserId)) { FinishTransfer(); } return; } if (!Validation(playerSlot, targetSlot, playerScript, targetObject, NetworkSide.Server, IsGhost)) { 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); } } }
private void TryToEat(PlayerScript feeder, PlayerScript eater) { var feederSlot = feeder.ItemStorage.GetActiveHandSlot(); if (feederSlot.Item == null) { //Already been eaten or the food is no longer in hand return; } var eaterHungerState = eater.playerHealth.Metabolism.HungerState; if (feeder == eater) //If you're eating it yourself. { switch (eaterHungerState) { case HungerState.Full: Chat.AddActionMsgToChat(eater.gameObject, $"You cannot force any more of the {Name} to go down your throat!", $"{eater.playerName} cannot force any more of the {Name} to go down {eater.characterSettings.PossessivePronoun()} throat!"); return; //Not eating! case HungerState.Normal: Chat.AddActionMsgToChat(eater.gameObject, $"You unwillingly {EatVerb} the {Name}.", //"a bit of" $"{eater.playerName} unwillingly {EatVerb}s the {Name}."); //"a bit of" break; case HungerState.Hungry: Chat.AddActionMsgToChat(eater.gameObject, $"You {EatVerb} the {Name}.", $"{eater.playerName} {EatVerb}s the {Name}."); break; case HungerState.Malnourished: Chat.AddActionMsgToChat(eater.gameObject, $"You hungrily {EatVerb} the {Name}.", $"{eater.playerName} hungrily {EatVerb}s the {Name}."); break; case HungerState.Starving: Chat.AddActionMsgToChat(eater.gameObject, $"You hungrily {EatVerb} the {Name}, gobbling it down!", $"{eater.playerName} hungrily {EatVerb}s the {Name}, gobbling it down!"); break; } } else //If you're feeding it to someone else. { if (eaterHungerState == HungerState.Full) { Chat.AddActionMsgToChat(eater.gameObject, $"{feeder.playerName} cannot force any more of {Name} down your throat!", $"{feeder.playerName} cannot force any more of {Name} down {eater.playerName}'s throat!"); return; //Not eating! } else { Chat.AddActionMsgToChat(eater.gameObject, $"{feeder.playerName} attempts to feed you {Name}.", $"{feeder.playerName} attempts to feed {eater.playerName} {Name}."); } //Wait 3 seconds before you can feed StandardProgressAction.Create(ProgressConfig, () => { Chat.AddActionMsgToChat(eater.gameObject, $"{feeder.playerName} forces you to eat {Name}!", $"{feeder.playerName} forces {eater.playerName} to eat {Name}!"); Eat(); }).ServerStartProgress(eater.registerTile, 3f, feeder.gameObject); return; } Eat(); void Eat() { SoundManager.PlayNetworkedAtPos(isDrink ? "Slurp" : "EatFood", eater.WorldPos); eater.playerHealth.Metabolism .AddEffect(new MetabolismEffect(NutritionLevel, 0, MetabolismDuration.Food)); //If food has a stack component, decrease amount by one instead of deleting the entire stack. if (stackable != null) { stackable.ServerConsume(1); } else { Inventory.ServerDespawn(feederSlot); } if (leavings != null) { var leavingsInstance = Spawn.ServerPrefab(leavings).GameObject; var pickupable = leavingsInstance.GetComponent <Pickupable>(); bool added = Inventory.ServerAdd(pickupable, feederSlot); if (!added) { //If stackable has leavings and they couldn't go in the same slot, they should be dropped pickupable.CustomNetTransform.SetPosition(feeder.WorldPos); } } } }
public void ServerPerformInteraction(PositionalHandApply interaction) { var handObject = interaction.HandObject; 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); if (Validations.HasItemTrait(handObject, CommonTraits.Instance.Breakable)) { handObject.GetComponent <ItemBreakable>().AddDamage(); } } else { //attacking objects //butcher check GameObject victim = interaction.TargetObject; var healthComponent = victim.GetComponent <LivingHealthBehaviour>(); if (healthComponent && healthComponent.allowKnifeHarvest && healthComponent.IsDead && Validations.HasItemTrait(handObject, CommonTraits.Instance.Knife) && interaction.Intent == Intent.Harm) { GameObject performer = interaction.Performer; var playerMove = victim.GetComponent <PlayerMove>(); if (playerMove != null && playerMove.IsBuckled) { return; } 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); if (Validations.HasItemTrait(handObject, CommonTraits.Instance.Breakable)) { handObject.GetComponent <ItemBreakable>().AddDamage(); } } } }
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 dynamicItemStorage = toDisrobe.GetComponent <DynamicItemStorage>(); if (dynamicItemStorage == null) { return; } //disrobe each slot, taking .2s per each occupied slot //calculate time var occupiedSlots = dynamicItemStorage.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 <PlayerHealthV2>(); foreach (var itemSlot in dynamicItemStorage.GetItemSlots()) { //are we an observer of the player to disrobe? if (itemSlot.ServerIsObservedBy(gameObject) == false) { continue; } //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); }