public void CmdThrow(EquipSlot equipSlot, Vector3 worldTargetPos, int aim) { var inventorySlot = Inventory[equipSlot]; if (playerScript.canNotInteract() || equipSlot != EquipSlot.leftHand && equipSlot != EquipSlot.rightHand || !SlotNotEmpty(equipSlot)) { return; } GameObject throwable = inventorySlot.Item; Vector3 playerPos = playerScript.PlayerSync.ServerState.WorldPosition; InventoryManager.ClearInvSlot(inventorySlot); var throwInfo = new ThrowInfo { ThrownBy = gameObject, Aim = (BodyPartType)aim, OriginPos = playerPos, TargetPos = worldTargetPos, //Clockwise spin from left hand and Counterclockwise from the right hand SpinMode = equipSlot == EquipSlot.leftHand ? SpinMode.Clockwise : SpinMode.CounterClockwise, }; throwable.GetComponent <CustomNetTransform>().Throw(throwInfo); //Simplified counter-impulse for players in space if (playerScript.PlayerSync.IsWeightlessServer) { playerScript.PlayerSync.Push(Vector2Int.RoundToInt(-throwInfo.Trajectory.normalized)); } }
/// <summary> /// Hit for thrown (non-tile-snapped) items /// </summary> private void OnHit(Vector3Int pos, ThrowInfo info, IReadOnlyCollection <LivingHealthMasterBase> hitCreatures) { if (ItemAttributes == null) { return; } if (hitCreatures == null || hitCreatures.Count <= 0) { return; } foreach (var creature in hitCreatures) { if (creature.gameObject == info.ThrownBy) { continue; } //Remove cast to int when moving health values to float var damage = (int)(ItemAttributes.ServerThrowDamage); var hitZone = info.Aim.Randomize(); creature.ApplyDamageToBodyPart(info.ThrownBy, damage, AttackType.Melee, DamageType.Brute, hitZone); Chat.AddThrowHitMsgToChat(gameObject, creature.gameObject, hitZone); AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: 1f); SoundManager.PlayNetworkedAtPos(CommonSounds.Instance.GenericHit, transform.position, audioSourceParameters, sourceObj: gameObject); } }
protected virtual void OnHit(Vector3Int pos, ThrowInfo info, List <LivingHealthBehaviour> objects, List <TilemapDamage> tiles) { if (!ItemAttributes) { Logger.LogWarningFormat("{0}: Tried to hit stuff at pos {1} but have no ItemAttributes.", Category.Throwing, gameObject.name, pos); return; } //Hurting tiles for (var i = 0; i < tiles.Count; i++) { var tileDmg = tiles[i]; var damage = ( int )(ItemAttributes.throwDamage * 2); tileDmg.DoThrowDamage(pos, info, damage); } //Hurting objects if (objects != null && objects.Count > 0 && !Equals(info, ThrowInfo.NoThrow)) { for (var i = 0; i < objects.Count; i++) { //Remove cast to int when moving health values to float var damage = (int)(ItemAttributes.throwDamage * 2); var hitZone = info.Aim.Randomize(); objects[i].ApplyDamage(info.ThrownBy, damage, DamageType.Brute, hitZone); PostToChatMessage.SendThrowHitMessage(gameObject, objects[i].gameObject, damage, hitZone); } //hit sound PlaySoundMessage.SendToAll("GenericHit", transform.position, 1f); } else { //todo different sound for no-damage hit? PlaySoundMessage.SendToAll("GenericHit", transform.position, 0.8f); } }
/// <summary> /// Hit for thrown (non-tile-snapped) items /// </summary> protected virtual void OnHit(Vector3Int pos, ThrowInfo info, List <LivingHealthBehaviour> objects, List <TilemapDamage> tiles) { if (ItemAttributes == null) { Logger.LogWarningFormat("{0}: Tried to hit stuff at pos {1} but have no ItemAttributes.", Category.Throwing, gameObject.name, pos); return; } //Hurting tiles for (var i = 0; i < tiles.Count; i++) { var tileDmg = tiles[i]; var damage = (int)(ItemAttributes.ServerThrowDamage * 2); tileDmg.DoThrowDamage(pos, info, damage); } //Hurting objects if (objects != null && objects.Count > 0) { for (var i = 0; i < objects.Count; i++) { //Remove cast to int when moving health values to float var damage = (int)(ItemAttributes.ServerThrowDamage * 2); var hitZone = info.Aim.Randomize(); objects[i].ApplyDamageToBodypart(info.ThrownBy, damage, AttackType.Melee, DamageType.Brute, hitZone); Chat.AddThrowHitMsgToChat(gameObject, objects[i].gameObject, hitZone); } //hit sound SoundManager.PlayNetworkedAtPos("GenericHit", transform.position, 1f); } else { //todo different sound for no-damage hit? SoundManager.PlayNetworkedAtPos("GenericHit", transform.position, 0.8f); } }
public void CmdRequestThrow(string slot, Vector3 worldTargetPos, int aim) { if (playerScript.canNotInteract() || slot != "leftHand" && slot != "rightHand" || !SlotNotEmpty(slot)) { RollbackPrediction(slot); return; } GameObject throwable = Inventory[slot]; Vector3 playerPos = playerScript.playerSync.ServerState.WorldPosition; EquipmentPool.DisposeOfObject(gameObject, throwable); ClearInventorySlot(slot); var throwInfo = new ThrowInfo { ThrownBy = gameObject, Aim = (BodyPartType)aim, OriginPos = playerPos, TargetPos = worldTargetPos, //Clockwise spin from left hand and Counterclockwise from the right hand SpinMode = slot == "leftHand" ? SpinMode.Clockwise : SpinMode.CounterClockwise, }; throwable.GetComponent <CustomNetTransform>().Throw(throwInfo); //Simplified counter-impulse for players in space if (playerScript.playerSync.IsInSpace) { playerScript.playerSync.Push(Vector2Int.RoundToInt(-throwInfo.Trajectory.normalized)); } }
public override IEnumerable <ThrowInfo> Throw(FlowController flow, FlowOutputSet outSet, ThrowStmt throwStmt, MemoryEntry throwedValue) { //TODO this is only simple implementation var exceptionObj = (ObjectValue)throwedValue.PossibleValues.First(); var catchBlocks = outSet.ReadControlVariable(CatchBlocks_Storage).ReadMemory(outSet.Snapshot); var throwBranches = new List <ThrowInfo>(); //find catch blocks with valid scope and matching catch condition foreach (InfoValue <CatchBlockDescription> blockInfo in catchBlocks.PossibleValues) { var throwedType = outSet.ObjectType(exceptionObj).QualifiedName; //check catch condition if (blockInfo.Data.CatchedType.QualifiedName != throwedType) { continue; } var branch = new ThrowInfo(blockInfo.Data, throwedValue); throwBranches.Add(branch); } return(throwBranches); }
public override MemoryEntry Exit(ExitEx exit, MemoryEntry status) { var end = new ThrowInfo(new CatchBlockDescription(Flow.ProgramEnd, new GenericQualifiedName(), null), status); Flow.SetThrowBranching(new[] { end }, true); // Exit expression never returns, but it is still expression so it must return something return(new MemoryEntry(OutSet.AnyValue)); }
/// <summary> /// Updates throw information stored in current point /// </summary> /// <param name="info">Throw information that has to be compatilbe with current point</param> internal void ReThrow(ThrowInfo info) { if (!CatchDescription.Equals(info.Catch)) { throw new NotSupportedException("Cannot rethrow with given info"); } _info = info; }
void Game_onThrowSuccess(ThrowInfo info) { StopUpdateLoop(); if (_timeNextThrow < TimeEndFight) { _scoreInFight += info.score; } }
private void ThrowStart(ThrowInfo throwInfo) { if (throwInfo.ThrownBy.GetComponent <NetworkIdentity>() == null) { return; } Chat.AddActionMsgToChat(throwInfo.ThrownBy, $"You throw the {dieName}...", $"{throwInfo.ThrownBy.ExpensiveName()} throws the {dieName}..."); }
private void OnThrown(ThrowInfo info) { if (DMMath.Prob(chanceToBreak)) { Spawn.ServerPrefab(brokenItem, gameObject.AssumedWorldPosServer()); SoundManager.PlayNetworkedAtPos(useCustomSound ? customSound : SingletonSOSounds.Instance.GlassBreak01, gameObject.AssumedWorldPosServer()); Despawn.ServerSingle(gameObject); } }
private void fatalError(FlowController flow, bool removeFlowChildren) { var catchedType = new GenericQualifiedName(new QualifiedName(new Name(string.Empty))); var catchVariable = new VariableIdentifier(string.Empty); var description = new CatchBlockDescription(flow.ProgramEnd, catchedType, catchVariable); var info = new ThrowInfo(description, new MemoryEntry()); var throws = new ThrowInfo[] { info }; flow.SetThrowBranching(throws, removeFlowChildren); }
private void OnKnifeThrowSuccess(ThrowInfo info) { for (int i = 0; i < m_behaviours.Length; i++) { m_behaviours[i].PostKnifeThrowSuccess(this, info); } if (knifeThrowSuccess != null) { knifeThrowSuccess(info); } }
private void ThrowItem(CustomNetTransform cnt, Vector3 throwVector) { Vector3 vector = cnt.transform.rotation * throwVector; ThrowInfo throwInfo = new ThrowInfo { ThrownBy = gameObject, Aim = (BodyPartType)Random.Range(0, 13), OriginWorldPos = ContainerWorldPosition, WorldTrajectory = vector, SpinMode = DMMath.Prob(50) ? SpinMode.Clockwise : SpinMode.CounterClockwise }; cnt.Throw(throwInfo); }
void HandleCoinCleanup(CoinInfo InCoinInfo) { ThrowInfo TossResults = new ThrowInfo(); if (InCoinInfo.OurRoll && InCoinInfo.OurResizer) { TossResults.result = InCoinInfo.OurRoll.GetRollstate(); TossResults.radius = InCoinInfo.OurResizer.GetRadius(); TossResults.depth = InCoinInfo.OurResizer.GetDepth(); TossResults.hasValidData = true; switch (TossResults.result) { case RollState.Edge: NumEdge++; break; case RollState.Heads: NumHeads++; break; case RollState.Tails: NumTails++; break; } } else { if (!InCoinInfo.OurRoll) { Debug.LogError("Invalid Current Roll Component."); } if (!InCoinInfo.OurResizer) { Debug.LogError("Invalid Current Resizer Component."); } } if (TossResults.hasValidData) { Tosses.Add(TossResults); } else { Debug.LogError("Invalid Toss Data."); } if (InCoinInfo.OurCoin) { Destroy(InCoinInfo.OurCoin); CoinsInfo.Remove(InCoinInfo); } }
private void ThrowItem(ObjectBehaviour item, Vector3 throwVector) { Vector3 vector = item.transform.rotation * throwVector; var spin = RandomSpin(); ThrowInfo throwInfo = new ThrowInfo { ThrownBy = gameObject, Aim = BodyPartType.Chest, OriginWorldPos = transform.position, WorldTrajectory = vector, SpinMode = spin }; CustomNetTransform itemTransform = item.GetComponent<CustomNetTransform>(); if (itemTransform == null) return; itemTransform.Throw(throwInfo); }
public void Shot(ThrowInfo [] throwInfos) { m_throwedDice = throwInfos; if(m_throwedDice == null) { Debug.LogError("if(m_throwedDice == null)"); return; } m_buttonShot.gameObject.SetActive (false); m_number.text = ""; foreach(var x in m_throwedDice) { x.Reset(); x.Shot(StopedDice); } }
private void DamageTiles(Vector3Int pos, ThrowInfo info, List <TilemapDamage> tiles) { if (ItemAttributes == null) { return; } if (tiles == null || tiles.Count <= 0) { return; } //Hurting tiles foreach (var tileDmg in tiles) { var damage = (int)(ItemAttributes.ServerThrowDamage); tileDmg.DoThrowDamage(pos, info, damage); } }
private static void FinishThrow(ThrowInfo info) { Mobile from = info.From; Mobile to = info.To; int min = info.DamageMin; int max = info.DamageMax; bool b = info.Break; Item item = info.Item; to.Damage(Utility.RandomMinMax(min, max), from); if (b) { int count = Utility.RandomMinMax(1, 4); for (int i = 0; i < count; ++i) { Point3D p = new Point3D(to.Location); p.X += Utility.RandomMinMax(-1, 1); p.Y += Utility.RandomMinMax(-1, 1); if (!from.Map.CanFit(p.X, p.Y, p.Z, 16, false, true)) { p.Z = from.Map.GetAverageZ(p.X, p.X); if (p.Z == to.Z || !from.Map.CanFit(p.X, p.Y, p.Z, 16, false, true)) { continue; } } StoolLeg leg = new StoolLeg(); leg.MoveToWorld(p, from.Map); } } if (item != null) { item.MoveToWorld(to.Location, to.Map); } }
void ThrowItem(ObjectBehaviour item, Vector3 throwVector) { Vector3 vector = item.transform.rotation * throwVector; ThrowInfo throwInfo = new ThrowInfo { ThrownBy = Matrix.transform.parent.gameObject, Aim = BodyPartType.Chest, OriginWorldPos = ContainerWorldPosition, WorldTrajectory = vector, SpinMode = SpinMode.Clockwise // TODO: randomise this }; CustomNetTransform itemTransform = item.GetComponent <CustomNetTransform>(); if (itemTransform == null) { return; } itemTransform.Throw(throwInfo); }
public void Throw(ThrowInfo info) { OnThrowStart.Invoke(info); SetPosition(info.OriginWorldPos, false); float throwSpeed = ItemAttributes.ThrowSpeed * 10; //tiles per second float throwRange = ItemAttributes.ThrowRange; Vector2 worldImpulse = info.WorldTrajectory.normalized; var correctedInfo = info; //limit throw range here if (info.WorldTrajectory.magnitude > throwRange) { correctedInfo.WorldTrajectory = Vector3.ClampMagnitude(info.WorldTrajectory, throwRange); // Logger.Log( $"Throw distance clamped to {correctedInfo.Trajectory.magnitude}, " + // $"target changed {info.TargetPos}->{correctedInfo.TargetPos}" ); } //add player momentum float playerMomentum = 0f; //If throwing nearby, do so at 1/2 speed (looks clunky otherwise) float speedMultiplier = Mathf.Clamp(correctedInfo.WorldTrajectory.magnitude / (throwRange <= 0 ? 1 : throwRange), 0.6f, 1f); serverState.Speed = (Random.Range(-0.2f, 0.2f) + throwSpeed + playerMomentum) * speedMultiplier; correctedInfo.InitialSpeed = serverState.Speed; serverState.WorldImpulse = worldImpulse; if (info.SpinMode != SpinMode.None) { serverState.SpinFactor = (sbyte)(Mathf.Clamp(throwSpeed * (2f / (int)ItemAttributes.Size + 1), sbyte.MinValue, sbyte.MaxValue) * (info.SpinMode == SpinMode.Clockwise ? 1 : -1)); } serverState.ActiveThrow = correctedInfo; // Logger.Log( $"Throw:{correctedInfo} {serverState}" ); NotifyPlayers(); }
/// <summary> /// Hit for thrown (non-tile-snapped) items /// </summary> private void OnHit(Vector3Int pos, ThrowInfo info, IReadOnlyCollection <LivingHealthBehaviour> hitCreatures) { if (ItemAttributes == null) { return; } if (hitCreatures == null || hitCreatures.Count <= 0) { return; } foreach (var creature in hitCreatures) { //Remove cast to int when moving health values to float var damage = (int)(ItemAttributes.ServerThrowDamage); var hitZone = info.Aim.Randomize(); creature.ApplyDamageToBodypart(info.ThrownBy, damage, AttackType.Melee, DamageType.Brute, hitZone); Chat.AddThrowHitMsgToChat(gameObject, creature.gameObject, hitZone); } SoundManager.PlayNetworkedAtPos("GenericHit", transform.position, 1f, sourceObj: gameObject); }
public void Process() { float Damagedealt = AngleAndIntensity.magnitude; float EnergyExpended = 0; var v3int = new Vector3Int(Location.x, Location.y, 0); var metaTileMap = matrix.MetaTileMap; if (Damagedealt <= 0) { return; } if (metaTileMap == null) { return; } EnergyExpended = metaTileMap.ApplyDamage(v3int, Damagedealt, MatrixManager.LocalToWorldInt(v3int, matrix.MatrixInfo), AttackType.Bomb); if (Damagedealt > 100) { var Node = matrix.GetMetaDataNode(v3int); if (Node != null) { foreach (var electricalData in Node.ElectricalData) { electricalData.InData.DestroyThisPlease(); } SavedPipes.Clear(); SavedPipes.AddRange(Node.PipeData); foreach (var Pipe in SavedPipes) { Pipe.pipeData.DestroyThis(); } } } foreach (var integrity in matrix.Get <Integrity>(v3int, true)) { //Throw items if (integrity.GetComponent <ItemAttributesV2>() != null) { ThrowInfo throwInfo = new ThrowInfo { //the thrown object is itself for now, in case ThrownBy breaks if null ThrownBy = integrity.gameObject, Aim = BodyPartType.Chest, OriginWorldPos = integrity.RegisterTile.WorldPosition, WorldTrajectory = AngleAndIntensity.Rotate90(), SpinMode = RandomUtils.RandomSpin() }; integrity.GetComponent <CustomNetTransform>().Throw(throwInfo); } //And do damage to objects integrity.ApplyDamage(Damagedealt, AttackType.Bomb, DamageType.Brute); } foreach (var player in matrix.Get <ObjectBehaviour>(v3int, ObjectType.Player, true)) { // do damage player.GetComponent <PlayerHealthV2>().ApplyDamageAll(null, Damagedealt, AttackType.Bomb, DamageType.Brute); } foreach (var line in PresentLines) { line.ExplosionStrength -= EnergyExpended * (line.ExplosionStrength / Damagedealt); } AngleAndIntensity = Vector2.zero; }
private static void FinishThrow( ThrowInfo info ) { Mobile from = info.From; Mobile to = info.To; int min = info.DamageMin; int max = info.DamageMax; bool b = info.Break; Item item = info.Item; to.Damage( Utility.RandomMinMax( min, max ), from ); if ( b ) { int count = Utility.RandomMinMax( 1, 4 ); for ( int i = 0; i < count; ++i ) { Point3D p = new Point3D( to.Location ); p.X += Utility.RandomMinMax(-1, 1); p.Y += Utility.RandomMinMax(-1, 1); if ( !from.Map.CanFit( p.X, p.Y, p.Z, 16, false, true ) ) { p.Z = from.Map.GetAverageZ( p.X, p.X ); if ( p.Z == to.Z || !from.Map.CanFit( p.X, p.Y, p.Z, 16, false, true ) ) continue; } StoolLeg leg = new StoolLeg(); leg.MoveToWorld( p, from.Map ); } } if ( item != null ) item.MoveToWorld( to.Location, to.Map ); }
public bool Equals(ThrowInfo other) { return(OriginWorldPos.Equals(other.OriginWorldPos) && WorldTrajectory.Equals(other.WorldTrajectory)); }
private void ThrowEnd(ThrowInfo throwInfo) { this.RestartCoroutine(WaitForSide(), ref waitForSide); }
private void ThrowStart(ThrowInfo throwInfo) { Chat.AddActionMsgToChat(throwInfo.ThrownBy, $"You throw the {dieName}...", $"{throwInfo.ThrownBy} throws the {dieName}..."); }
protected override void OnHit(Vector3Int pos, ThrowInfo info, List <LivingHealthBehaviour> objects, List <TilemapDamage> tiles) { //base.OnHit( pos, info, objects, tiles ); //umm todo }
public void DoThrowDamage(Vector3Int worldTargetPos, ThrowInfo throwInfo, int dmgAmt) { DoMeleeDamage(new Vector2(worldTargetPos.x, worldTargetPos.y), throwInfo.ThrownBy, dmgAmt); }
private static bool ServerPerformRemove(InventoryMove toPerform, Pickupable pickupable) { if (pickupable.ItemSlot == null) { Logger.LogTraceFormat("Attempted to remove {0} from inventory but item is not in a slot." + " remove will not be performed.", Category.Inventory, pickupable.name); return(false); } var fromSlot = toPerform.FromSlot; if (fromSlot == null) { Logger.LogTraceFormat("Attempted to remove {0} from inventory but from slot was null." + " Move will not be performed.", Category.Inventory, pickupable.name); return(false); } if (fromSlot.Item == null) { Logger.LogTraceFormat("Attempted to remove {0} from inventory but from slot {1} had no item in it." + " Move will not be performed.", Category.Inventory, pickupable.name, fromSlot); return(false); } //update pickupable's item and slot's item pickupable._SetItemSlot(null); fromSlot._ServerRemoveItem(); //decide how it should be removed var removeType = toPerform.RemoveType; var holder = fromSlot.GetRootStorageOrPlayer(); var holderPushPull = holder?.GetComponent <PushPull>(); var parentContainer = holderPushPull == null ? null : holderPushPull.parentContainer; if (parentContainer != null && removeType == InventoryRemoveType.Throw) { Logger.LogTraceFormat("throwing from slot {0} while in container {1}. Will drop instead.", Category.Inventory, fromSlot, parentContainer.name); removeType = InventoryRemoveType.Drop; } if (removeType == InventoryRemoveType.Despawn) { // destroy (safe to skip invnetory despawn check because we already performed necessary inventory logic) _ = Despawn.ServerSingle(pickupable.gameObject, true); } else if (removeType == InventoryRemoveType.Drop) { // drop where it is // determine where it will appear if (parentContainer != null) { // TODO: Not a big fan of this bespoke logic for dealing with dropping in closet control. Try to refactor this Logger.LogTraceFormat("Dropping from slot {0} while in container {1}", Category.Inventory, fromSlot, parentContainer.name); var closetControl = parentContainer.GetComponent <ClosetControl>(); if (closetControl == null) { Logger.LogWarningFormat("Dropping from slot {0} while in container {1}, but container type was not recognized. " + "Currently only ClosetControl is supported. Please add code to handle this case.", Category.Inventory, fromSlot, holderPushPull.parentContainer.name); return(false); } //vanish it and set its parent container ServerVanish(fromSlot); var objBehavior = pickupable.GetComponent <ObjectBehaviour>(); if (objBehavior == null) { Logger.LogTraceFormat("Dropping object {0} while in container {1}, but dropped object had" + " no object behavior. Cannot drop.", Category.Inventory, pickupable, holderPushPull.parentContainer.name); return(false); } closetControl.ServerAddInternalItem(objBehavior); return(true); } var holderPlayer = holder?.GetComponent <PlayerSync>(); var cnt = pickupable.GetComponent <CustomNetTransform>(); var holderPosition = holder?.gameObject.AssumedWorldPosServer(); Vector3 targetWorldPos = holderPosition.GetValueOrDefault(Vector3.zero) + (Vector3)toPerform.WorldTargetVector.GetValueOrDefault(Vector2.zero); if (holderPlayer != null) { // dropping from player // Inertia drop works only if player has external impulse (space floating etc.) cnt.InertiaDrop(targetWorldPos, holderPlayer.SpeedServer, holderPlayer.ServerImpulse); } else { // dropping from not-held storage cnt.AppearAtPositionServer(targetWorldPos); } } else if (removeType == InventoryRemoveType.Throw) { // throw / eject // determine where it will be thrown from var cnt = pickupable.GetComponent <CustomNetTransform>(); var assumedWorldPosServer = holder.gameObject.AssumedWorldPosServer(); var throwInfo = new ThrowInfo { ThrownBy = holder.gameObject, Aim = toPerform.ThrowAim.GetValueOrDefault(BodyPartType.Chest), OriginWorldPos = assumedWorldPosServer, WorldTrajectory = toPerform.WorldTargetVector.GetValueOrDefault(Vector2.zero), SpinMode = toPerform.ThrowSpinMode.GetValueOrDefault(SpinMode.Clockwise) }; // dropping from player // Inertia drop works only if player has external impulse (space floating etc.) cnt.Throw(throwInfo); // Counter-impulse for players in space holderPushPull.Pushable.NewtonianMove((-throwInfo.WorldTrajectory).NormalizeTo2Int(), speed: (int)cnt.Size + 1); } // NOTE: vanish doesn't require any extra logic. The item is already at hiddenpos and has // already been removed from the inventory system. foreach (var onMove in pickupable.GetComponents <IServerInventoryMove>()) { onMove.OnInventoryMoveServer(toPerform); } return(true); }
public bool Equals(ThrowInfo other) { return(OriginPos.Equals(other.OriginPos) && TargetPos.Equals(other.TargetPos)); }
public virtual void PostKnifeThrowSuccess(ILocalGame game, ThrowInfo info) { }