public override void TileProc(int aX, int aY, ref bool refContinue) { NWField f = Field; Step(aX, aY); if (f.IsBarrier(aX, aY)) { refContinue = false; } else { BaseTile tile = f.GetTile(aX, aY); NWCreature c = (NWCreature)f.FindCreature(aX, aY); if (c != null) { string cSign = c.Entry.Sign; if (cSign.Equals("Mudman") || cSign.Equals("MudFlow")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Mud); } else { if (cSign.Equals("LavaFlow")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Lava); } else { if (cSign.Equals("Jagredin") || cSign.Equals("LiveRock")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Rubble); } else { if (cSign.Equals("SandForm")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Quicksand); } else { if (cSign.Equals("WateryForm")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Water); } else { if (c.State == CreatureState.Undead) { c.Death("", null); } } } } } } } } }
public override void TileProc(int aX, int aY, ref bool aContinue) { NWField fld = Field; NWTile tile = (NWTile)fld.GetTile(aX, aY); Step(aX, aY); if (fld.IsBarrier(aX, aY)) { if (tile.ForeBase == PlaceID.pid_Tree) { tile.Foreground = PlaceID.pid_Undefined; fld.AddCreature(aX, aY, GlobalVars.nwrDB.FindEntryBySign("Faleryn").GUID); } aContinue = false; } else { NWCreature c = (NWCreature)fld.FindCreature(aX, aY); if (c != null) { EffectsFactory.e_Transformation(EffectID.eid_Transformation, c, null, ItemState.is_Normal, InvokeMode.im_ItSelf, null); } } }
public void Paintsplat(Vector3Int worldPosInt, Vector3Int localPosInt, ReagentMix reagents) { switch (ChemistryUtils.GetMixStateDescription(reagents)) { case "powder": { EffectsFactory.PowderSplat(worldPosInt, reagents.MixColor, reagents); break; } case "liquid": { //TODO: Work out if reagent is "slippery" according to its viscocity (not modeled yet) EffectsFactory.ChemSplat(worldPosInt, reagents.MixColor, reagents); break; } case "gas": //TODO: Make gas reagents release into the atmos. break; default: { EffectsFactory.ChemSplat(worldPosInt, reagents.MixColor, reagents); break; } } }
private void LoseBlood(float amount) { if (amount <= 0) { return; } Logger.LogTraceFormat("{0} lost blood: {1}->{2}", Category.Health, this.gameObject.name, BloodLevel, BloodLevel - amount); BloodLevel -= amount; BloodSplatSize scaleOfTragedy; if (amount > 0 && amount < 15) { scaleOfTragedy = BloodSplatSize.small; } else if (amount >= 15 && amount < 40) { scaleOfTragedy = BloodSplatSize.medium; } else { scaleOfTragedy = BloodSplatSize.large; } EffectsFactory.BloodSplat(transform.position, scaleOfTragedy, bloodSplatColor); }
protected override void OnDeathActions() { if (CustomNetworkManager.Instance._isServer) { ConnectedPlayer player = PlayerList.Instance.Get(gameObject); string killerName = null; if (LastDamagedBy != null) { killerName = PlayerList.Instance.Get(LastDamagedBy)?.Name; } if (killerName == null) { killerName = "Stressful work"; } string playerName = player?.Name ?? "dummy"; if (killerName == playerName) { Chat.AddActionMsgToChat(gameObject, "You committed suicide, what a waste.", $"{playerName} committed suicide."); } else if (killerName.EndsWith(playerName)) { // chain reactions Chat.AddActionMsgToChat(gameObject, $" You screwed yourself up with some help from {killerName}", $"{playerName} screwed himself up with some help from {killerName}"); } else { PlayerList.Instance.TrackKill(LastDamagedBy, gameObject); } //drop items in hand if (itemStorage != null) { Inventory.ServerDrop(itemStorage.GetNamedItemSlot(NamedSlot.leftHand)); Inventory.ServerDrop(itemStorage.GetNamedItemSlot(NamedSlot.rightHand)); } if (isServer) { EffectsFactory.BloodSplat(transform.position, BloodSplatSize.large, bloodColor); string descriptor = null; if (player != null) { descriptor = player?.Script?.characterSettings?.PossessivePronoun(); } if (descriptor == null) { descriptor = "their"; } Chat.AddLocalMsgToChat($"<b>{playerName}</b> seizes up and falls limp, {descriptor} eyes dead and lifeless...", (Vector3)registerPlayer.WorldPositionServer); } PlayerDeathMessage.Send(gameObject); } }
protected override void Gib() { EffectsFactory.BloodSplat(transform.position, BloodSplatSize.large, bloodColor); //drop clothes, gib... but don't destroy actual player, a piece should remain //drop everything foreach (var slot in itemStorage.GetItemSlots()) { Inventory.ServerDrop(slot); } if (!playerMove.PlayerScript.IsGhost) { //dirty way to follow gibs. change this when implementing proper gibbing, perhaps make it follow brain var gibsToFollow = MatrixManager.GetAt <RawMeat>(transform.position.CutToInt(), true); if (gibsToFollow.Count > 0) { var gibs = gibsToFollow[0]; FollowCameraMessage.Send(gameObject, gibs.gameObject); var gibsIntegrity = gibs.GetComponent <Integrity>(); if (gibsIntegrity != null) { //Stop cam following gibs if they are destroyed gibsIntegrity.OnWillDestroyServer.AddListener(x => FollowCameraMessage.Send(gameObject, null)); } } } playerMove.PlayerScript.pushPull.VisibleState = false; }
private void DefaultBurnUp(DestructionInfo info) { //just a guess - objects which can be picked up should have a smaller amount of ash EffectsFactory.Ash(registerTile.WorldPosition.To2Int(), isLarge); Chat.AddLocalDestroyMsgToChat(gameObject.ExpensiveName(), " burnt to ash.", gameObject.TileWorldPosition()); Logger.LogTraceFormat("{0} burning up, onfire is {1} (burningObject enabled {2})", Category.Health, name, this.onFire, burningObjectOverlay?.enabled); Despawn.ServerSingle(gameObject); }
public Sword() : base(null, new Point(), new Vector2()) { this.gravity = new Gravity(this); this.gravity.ChangeGravityIntensity(1.0f); this.SpriteFactory = EffectsFactory.GetInstance(); this.SwordState = new ReadyToSwingState(this); this.hitboxOffset = 0; }
private void Awake() { if (Instance == null) { Instance = this; } else { Destroy(this); } }
public void Setup() { FireMarioFactory.GetInstance().ChangeTexture(_costumes[Index].MarioTexture); Mario.GetInstance().UpdateActionSprite(); ItemFactory.GetInstance().ChangeTexture(_costumes[Index].ItemTexture); Mario.GetInstance().GravityIntensity = _costumes[Index].MarioGravityIntensity; Mario.GetInstance().UpdateFireballsAndSword(_costumes[Index].ProjectileNum, _costumes[Index].ProjectileGravity, _costumes[Index].ProjectileYBounceSpeed, _costumes[Index].ProjectileInitXSpeed, _costumes[Index].ProjectileInitYSpeed, _costumes[Index].HasSword, _costumes[Index].SwordGravity); EffectsFactory.GetInstance().ChangeTexture(_costumes[Index].EffectsTexture); }
/// <summary> /// Release reagents at provided coordinates, making them react with world /// </summary> public void ReagentReact(Dictionary <string, float> reagents, Vector3Int worldPosInt, Vector3Int localPosInt) { if (MatrixManager.IsTotallyImpassable(worldPosInt, true)) { return; } bool didSplat = false; foreach (KeyValuePair <string, float> reagent in reagents) { if (reagent.Value < 1) { continue; } if (reagent.Key == "water") { matrix.ReactionManager.ExtinguishHotspot(localPosInt); foreach (var livingHealthBehaviour in matrix.Get <LivingHealthBehaviour>(localPosInt, true)) { livingHealthBehaviour.Extinguish(); } Clean(worldPosInt, localPosInt, true); } else if (reagent.Key == "cleaner") { Clean(worldPosInt, localPosInt, false); } else if (reagent.Key == "welding_fuel") { //temporary: converting spilled fuel to plasma Get(localPosInt).GasMix.AddGas(Gas.Plasma, reagent.Value); } else if (reagent.Key == "lube") { //( ͡° ͜ʖ ͡°) if (!Get(localPosInt).IsSlippery) { EffectsFactory.WaterSplat(worldPosInt); MakeSlipperyAt(localPosInt, false); } } else { //for all other things leave a chem splat if (!didSplat) { EffectsFactory.ChemSplat(worldPosInt); didSplat = true; } } } }
protected override void Gib() { Death(); EffectsFactory.BloodSplat(RegisterTile.WorldPositionServer, BloodSplatSize.large, BloodSplatType.red); //drop clothes, gib... but don't destroy actual player, a piece should remain //drop everything foreach (var slot in itemStorage.GetItemSlots()) { Inventory.ServerDrop(slot); } PlayerMove.PlayerScript.pushPull.VisibleState = false; playerNetworkActions.ServerSpawnPlayerGhost(); }
public void ActionForPlayer(Player player) { if (ItemIsTooHeavyToPickupRule(this, player)) { return; } if (UniqueItemPickupRule(this, player)) { return; } foreach (var effect in EffectsFactory.EffectsFor(this)) { effect.Effect(this, player, player.GameEngine, AddItemToInventory); } }
public void Clean(Vector3Int worldPosInt, Vector3Int localPosInt, bool makeSlippery) { var floorDecals = MatrixManager.GetAt <FloorDecal>(worldPosInt, isServer: true); for (var i = 0; i < floorDecals.Count; i++) { floorDecals[i].TryClean(); } if (!MatrixManager.IsSpaceAt(worldPosInt, true) && makeSlippery) { // Create a WaterSplat Decal (visible slippery tile) EffectsFactory.WaterSplat(worldPosInt); // Sets a tile to slippery MakeSlipperyAt(localPosInt); } }
public override void TileProc(int aX, int aY, ref bool aContinue) { NWField f = Field; if (f.IsBarrier(aX, aY)) { aContinue = false; } else { NWCreature c = (NWCreature)f.FindCreature(aX, aY); if (c != null) { EffectsFactory.FireHit(EffectID.eid_FireVision, Creature, c, RandomHelper.GetBoundedRnd(2, 40)); } aContinue = (c == null); } }
protected override void OnDeathActions() { if (CustomNetworkManager.Instance._isServer) { PlayerNetworkActions pna = gameObject.GetComponent <PlayerNetworkActions>(); PlayerMove pm = gameObject.GetComponent <PlayerMove>(); ConnectedPlayer player = PlayerList.Instance.Get(gameObject); string killerName = "Stressful work"; if (LastDamagedBy != null) { killerName = PlayerList.Instance.Get(LastDamagedBy).Name; } string playerName = player.Name ?? "dummy"; if (killerName == playerName) { Chat.AddActionMsgToChat(gameObject, "You committed suicide, what a waste.", $"{playerName} committed suicide."); } else if (killerName.EndsWith(playerName)) { // chain reactions Chat.AddActionMsgToChat(gameObject, $" You screwed yourself up with some help from {killerName}", $"{playerName} screwed himself up with some help from {killerName}"); } else { PlayerList.Instance.TrackKill(LastDamagedBy, gameObject); } //drop items in hand Inventory.ServerDrop(itemStorage.GetNamedItemSlot(NamedSlot.leftHand)); Inventory.ServerDrop(itemStorage.GetNamedItemSlot(NamedSlot.rightHand)); if (isServer) { EffectsFactory.BloodSplat(transform.position, BloodSplatSize.large, bloodColor); } PlayerDeathMessage.Send(gameObject); } }
public PortalProjectile(bool left) : base(EffectsFactory.GetInstance(), Mario.GetInstance().GetCenter(), new Vector2()) { Systems.Events.TheInstance.PortalProjectileFiring(); double angle = MouseController.DetermineAngleFromMouse(Mario.GetInstance().GetCenter()); this.XSpeed = (int)(SPEED * Math.Cos(angle)); this.YSpeed = (int)(SPEED * Math.Sin(angle)); this.left = left; if (this.left) { this.sprite = this.spriteFactory.CreateProduct(EffectTypes.BluePortalProjectile); } else { this.sprite = this.spriteFactory.CreateProduct(EffectTypes.OrangePortalProjectile); } MarioGame.GetInstance.AddNewGameObject(false, this); }
public void CleanTile(Vector3 worldPos, bool makeSlippery) { var worldPosInt = worldPos.CutToInt(); var matrix = AtPoint(worldPosInt, true); var localPosInt = WorldToLocalInt(worldPosInt, matrix); var floorDecals = GetAt <FloorDecal>(worldPosInt, isServer: true); for (var i = 0; i < floorDecals.Count; i++) { floorDecals[i].TryClean(); } if (!IsSpaceAt(worldPosInt, true) && makeSlippery) { // Create a WaterSplat Decal (visible slippery tile) EffectsFactory.WaterSplat(worldPosInt); // Sets a tile to slippery matrix.MetaDataLayer.MakeSlipperyAt(localPosInt); } }
public void Clean(Vector3Int worldPosInt, Vector3Int localPosInt, bool makeSlippery) { Get(localPosInt).IsSlippery = false; var floorDecals = MatrixManager.GetAt <FloorDecal>(worldPosInt, isServer: true); for (var i = 0; i < floorDecals.Count; i++) { floorDecals[i].TryClean(); } //check for any moppable overlays matrix.TileChangeManager.RemoveFloorWallOverlaysOfType(localPosInt, OverlayType.Cleanable); if (MatrixManager.IsSpaceAt(worldPosInt, true, matrix.MatrixInfo) == false && makeSlippery) { // Create a WaterSplat Decal (visible slippery tile) EffectsFactory.WaterSplat(worldPosInt); // Sets a tile to slippery MakeSlipperyAt(localPosInt); } }
public override void TileProc(int aX, int aY, ref bool aContinue) { NWField fld = Field; NWTile tile = (NWTile)fld.GetTile(aX, aY); Step(aX, aY); if (fld.IsBarrier(aX, aY)) { if (tile.ForeBase == PlaceID.pid_Tree) { tile.Foreground = PlaceID.pid_Undefined; } aContinue = false; } else { NWCreature c = (NWCreature)fld.FindCreature(aX, aY); if (c != null) { EffectsFactory.FireHit(EffectID.eid_Fire, Creature, c, RandomHelper.GetBoundedRnd(6, 21)); } } }
public override void TileProc(int aX, int aY, ref bool refContinue) { NWField f = Field; if (f.IsBarrier(aX, aY)) { refContinue = false; } else { NWTile tile = (NWTile)f.GetTile(aX, aY); int bg = tile.BackBase; if (bg == PlaceID.pid_Mud || bg == PlaceID.pid_Rubble) { tile.Background = PlaceID.pid_Ground; } else { tile.Background = dbTransmutatedList[RandomHelper.GetRandom(2)]; } NWCreature c = (NWCreature)f.FindCreature(aX, aY); if (c != null) { string cSign = c.Entry.Sign; if (cSign.Equals("Mudman") || cSign.Equals("MudFlow")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Mud); } else { if (cSign.Equals("LavaFlow")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Lava); } else { if (cSign.Equals("Jagredin") || cSign.Equals("LiveRock")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Rubble); } else { if (cSign.Equals("SandForm")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Quicksand); } else { if (cSign.Equals("WateryForm")) { EffectsFactory.Deanimate(f, c, tile, PlaceID.pid_Water); } } } } } } } }
public GameController(Canvas mainCanvas, Camera mainCam, GameStats gameStat, int lapsCount, int shipCount) // конструктор игры, можно сделать несколько конструкторов(например сколько противников, какая сложность, какая трасса) { mainCamera = mainCam; objectsInGame = new List <GameObject>(); canvas = mainCanvas; gameStats = gameStat; //создаем трассу trackMV = TrackFactory.CreateBigTrackModelView(gameStats.testTrackPrefab); // создаем трассу и добавляем в лист объектов в игре trackMV.OnPause += HandleGamePause; // подписываем обработчик паузы на событие паузы objectsInGame.Add(trackMV.gameObject); //создаем сеть чекпоинтов checkpointsPath = TrackFactory.CreateBigTrackPath(gameStats.testTrackPathPrefab, lapsCount); checkpointsPath.OnFinish += HandleTrackFinish; objectsInGame.Add(checkpointsPath.gameObject); // создаем объект размещения кораблей на трассе StartPlacerModelView placerMV = TrackFactory.CreateStartPlacer(checkpointsPath.GetStartPosition(), gameStats.placerPrefab); // создаем корабль игрока ShipModelView playerShipMV = ShipFactory.CreateShipModelView(placerMV.GetSpawnPoint(0)); ShipController shipController = ShipFactory.CreateShipController(playerShipMV, null); playerShipMV.gameObject.AddComponent <AudioListener>(); objectsInGame.Add(playerShipMV.gameObject); playerShipMV.name = "Player"; ///Создаем эффект песчаной бури и привязываем к игроку EffectModelView effectModelView = EffectsFactory.CreateSandstormEffect(gameStats.sandStormPrefab); effectModelView.transform.parent = playerShipMV.transform; effectModelView.transform.position = playerShipMV.transform.position; // создаем HUD стрелку направления DirectionArrowModelView HUDarrowMV = UIFactory.CreateDirectionArrow(canvas); // создаем пилота игрока PlayerPilotModelView playerPilotMV = PilotFactory.CreatePlayerPilotModelView(playerShipMV.transform); PlayerPilotController playerController = PilotFactory.CreatePlayerPilotController(playerPilotMV, playerShipMV, checkpointsPath, HUDarrowMV); objectsInGame.Add(playerPilotMV.gameObject); UIFactory.AddMinimapPointToPlayer(playerPilotMV.transform); for (int i = 1; i < shipCount; i++) { // создаем корабль противника ShipModelView enemyShipMV = ShipFactory.CreateShipModelView(placerMV.GetSpawnPoint(i)); objectsInGame.Add(enemyShipMV.gameObject); enemyShipMV.name = $"Enemy {i}"; // создаем показатель хитпоинтов корабля противника HitpointsCanvasModelView enemyHp = UIFactory.CreateShipHealthBar(enemyShipMV.transform); if (enemyHp == null) { Debug.Log("HP NOT CREATED!!"); } objectsInGame.Add(enemyHp.gameObject); // создаем контроллер корабля противника ShipController enemyShipController = ShipFactory.CreateShipController(enemyShipMV, enemyHp); // создаем пилота противника EnemyPilotModelView enemyPilotMV = PilotFactory.CreateEnemyPilotModelView(enemyShipMV.transform); EnemyPilotController enemyPilotController = PilotFactory.CreateEnemyPilotController(enemyPilotMV, enemyShipMV, checkpointsPath); enemyShipMV.enemyPilotController = enemyPilotController; objectsInGame.Add(enemyPilotMV.gameObject); UIFactory.AddMinimapPointToEnemy(enemyPilotMV.transform); } // TODO создаем HUD отображение способностей (ТЕСТОВОЕ!!!) AbilityHUDModelView abilityHUDMV = UIFactory.CreatePlayerAbilityUI(canvas); objectsInGame.Add(abilityHUDMV.gameObject); AbilityHUDController abilityHUDController = new AbilityHUDController(abilityHUDMV, playerShipMV); // создаем риг камер CinemachineModelView cameraMV = CameraFactory.CreateCameraRig(playerShipMV.transform); mainCamera.gameObject.SetActive(false); // отключаем основную камеру после появления рига objectsInGame.Add(cameraMV.gameObject); //Создание синглтона Ввода данных от пользователя GameObject inputController = new GameObject(); inputController.AddComponent <InputControl>(); objectsInGame.Add(inputController); //Создание синглтона контроля за TimeScale GameObject timeFollowController = new GameObject(); timeFollowController.AddComponent <TimeFollowController>(); objectsInGame.Add(timeFollowController); // создаем окно оповещений alertsModelView = UIFactory.CreateAlertsModelView(canvas); objectsInGame.Add(alertsModelView.gameObject); //Создаём окно позиции в гонке: TrackPositionModelView trackposMenuModel = UIFactory.CreateTrackPositionModelView(canvas); trackposMenuModel.trackPath = checkpointsPath; objectsInGame.Add(trackposMenuModel.gameObject); // создаем миникарту GameObject minimapCamera = UnityEngine.Object.Instantiate(Resources.Load <GameObject>("Prefabs/MinimapCamera")); objectsInGame.Add(minimapCamera); GameObject miniMap = UIFactory.CreateMinimapObj(canvas); objectsInGame.Add(miniMap); }
/// <summary> /// Release reagents at provided coordinates, making them react with world /// </summary> public void ReagentReact(ReagentMix reagents, Vector3Int worldPosInt, Vector3Int localPosInt) { if (MatrixManager.IsTotallyImpassable(worldPosInt, true)) { return; } bool didSplat = false; foreach (var reagent in reagents) { if (reagent.Value < 1) { continue; } switch (reagent.Key.name) { case "Water": { matrix.ReactionManager.ExtinguishHotspot(localPosInt); foreach (var livingHealthBehaviour in matrix.Get <LivingHealthBehaviour>(localPosInt, true)) { livingHealthBehaviour.Extinguish(); } Clean(worldPosInt, localPosInt, true); break; } case "SpaceCleaner": Clean(worldPosInt, localPosInt, false); break; case "WeldingFuel": //temporary: converting spilled fuel to plasma Get(localPosInt).GasMix.AddGas(Gas.Plasma, reagent.Value); break; case "SpaceLube": { //( ͡° ͜ʖ ͡°) if (!Get(localPosInt).IsSlippery) { EffectsFactory.WaterSplat(worldPosInt); MakeSlipperyAt(localPosInt, false); } break; } default: { //for all other things leave a chem splat if (!didSplat) { EffectsFactory.ChemSplat(worldPosInt, reagents.MixColor); didSplat = true; } break; } } } }
public void PaintBlood(Vector3Int worldPosInt, ReagentMix reagents) { EffectsFactory.BloodSplat(worldPosInt, reagents); BloodDry(worldPosInt); }
/// <summary> /// Release reagents at provided coordinates, making them react with world /// </summary> public void ReagentReact(ReagentMix reagents, Vector3Int worldPosInt, Vector3Int localPosInt) { if (MatrixManager.IsTotallyImpassable(worldPosInt, true)) { return; } bool didSplat = false; bool paintBlood = false; //Find all reagents on this tile (including current reagent) var reagentContainer = MatrixManager.GetAt <ReagentContainer>(worldPosInt, true); var existingSplats = MatrixManager.GetAt <FloorDecal>(worldPosInt, true); for (var i = 0; i < existingSplats.Count; i++) { if (existingSplats[i].GetComponent <ReagentContainer>()) { existingSplat = existingSplats[i]; } } //Loop though all reagent containers and add the passed in reagents foreach (ReagentContainer chem in reagentContainer) { //If the reagent tile is a pool/puddle/splat if (chem.ExamineAmount == ReagentContainer.ExamineAmountMode.UNKNOWN_AMOUNT) { reagents.Add(chem.CurrentReagentMix); } //TODO: could allow you to add this to other container types like beakers but would need some balance and perhaps knocking over the beaker } if (reagents.Total > 0) { //Force clean the tile Clean(worldPosInt, localPosInt, false); lock (reagents.reagents) { foreach (var reagent in reagents.reagents.m_dict) { switch (reagent.Key.name) { case "HumanBlood": { paintBlood = true; break; } case "Water": { MakeSlipperyAt(localPosInt); matrix.ReactionManager.ExtinguishHotspot(localPosInt); foreach (var livingHealthBehaviour in matrix.Get <LivingHealthMasterBase>(localPosInt, true)) { livingHealthBehaviour.Extinguish(); } break; } case "SpaceCleaner": Clean(worldPosInt, localPosInt, false); didSplat = true; break; case "SpaceLube": { // ( ͡° ͜ʖ ͡°) if (Get(localPosInt).IsSlippery == false) { EffectsFactory.WaterSplat(worldPosInt); MakeSlipperyAt(localPosInt, false); } break; } default: break; } } } if (didSplat == false) { if (paintBlood) { PaintBlood(worldPosInt, reagents); } else { Paintsplat(worldPosInt, localPosInt, reagents); } } } }
/// <summary> /// Actions the server performs when the player dies /// </summary> protected override void OnDeathActions() { if (CustomNetworkManager.Instance._isServer) { ConnectedPlayer player = PlayerList.Instance.Get(gameObject); string killerName = null; if (LastDamagedBy != null) { var lastDamager = PlayerList.Instance.Get(LastDamagedBy); if (lastDamager != null) { killerName = lastDamager.Name; AutoMod.ProcessPlayerKill(lastDamager, player); } } if (killerName == null) { killerName = "stressful work"; } string playerName = player?.Name ?? "dummy"; if (killerName == playerName) { Chat.AddActionMsgToChat(gameObject, "You committed suicide, what a waste.", $"{playerName} committed suicide."); } else if (killerName.EndsWith(playerName)) { string themself = null; if (player != null) { themself = player.CharacterSettings?.ThemselfPronoun(player.Script); } if (themself == null) { themself = "themself"; } //chain reactions Chat.AddActionMsgToChat(gameObject, $"You screwed yourself up with some help from {killerName}", $"{playerName} screwed {themself} up with some help from {killerName}"); } else { PlayerList.Instance.TrackKill(LastDamagedBy, gameObject); } //drop items in hand if (itemStorage != null) { Inventory.ServerDrop(itemStorage.GetNamedItemSlot(NamedSlot.leftHand)); Inventory.ServerDrop(itemStorage.GetNamedItemSlot(NamedSlot.rightHand)); } if (isServer) { EffectsFactory.BloodSplat(RegisterTile.WorldPositionServer, BloodSplatSize.large, BloodSplatType.red); string their = null; if (player != null) { their = player.CharacterSettings?.TheirPronoun(player.Script); } if (their == null) { their = "their"; } Chat.AddLocalMsgToChat($"<b>{player.Name}</b> seizes up and falls limp, {their} eyes dead and lifeless...", gameObject); } TriggerEventMessage.SendTo(gameObject, EVENT.PlayerDied); } }