public static bool Prefix([NotNull] EntityAlive __instance, DamageResponse _dmResponse) { Log.Debug($"Executing patch prefix for {nameof(EntityDamaged)} ..."); ScriptEvent eventType; if (__instance is EntityPlayer) { eventType = ScriptEvent.playerDamaged; } else if (__instance is EntityAnimal || __instance is EntityZombieDog || __instance is EntityEnemyAnimal || __instance is EntityHornet) { eventType = ScriptEvent.animalDamaged; } else if (__instance is EntityZombie) { eventType = ScriptEvent.zombieDamaged; } else { return(true); } CommandTools.InvokeScriptEvents(eventType, () => { var sourceEntity = GameManager.Instance.World?.GetEntity(_dmResponse.Source?.getEntityId() ?? -1) as EntityAlive; var targetClientInfo = ConnectionManager.Instance?.GetClientInfoForEntityId(__instance.entityId); var sourceClientInfo = ConnectionManager.Instance?.GetClientInfoForEntityId(sourceEntity?.entityId ?? -1); return(new EntityDamagedEventArgs { position = __instance.GetBlockPosition(), entityId = __instance.entityId, entityName = __instance.EntityName, entitySteamId = targetClientInfo?.playerId, sourceEntityId = sourceEntity?.entityId, sourceEntityName = sourceEntity?.EntityName, sourceEntitySteamId = sourceClientInfo?.playerId, damageType = _dmResponse.Source?.GetName().ToString(), hitBodyPart = _dmResponse.HitBodyPart.ToString(), hitDirection = _dmResponse.HitDirection.ToString(), damage = _dmResponse.Strength, armorDamage = _dmResponse.ArmorDamage, armorSlot = _dmResponse.ArmorSlot.ToString(), stunType = _dmResponse.Stun.ToString(), stunDuration = _dmResponse.StunDuration, critical = _dmResponse.Critical, fatal = _dmResponse.Fatal, crippleLegs = _dmResponse.CrippleLegs, dismember = _dmResponse.Dismember, turnIntoCrawler = _dmResponse.TurnIntoCrawler, painHit = _dmResponse.PainHit, }); }); return(true); }
/// <summary> /// Called when the game is in the process of shutting down, after connections were closed and resources were unloaded. /// </summary> public override void GameShutdown() { try { Log.Debug("Api.GameShutdown called."); TelemetryTools.Shutdown(); CommandTools.InvokeScriptEvents(ScriptEvent.gameShutdown, () => new ScriptEventArgs()); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called when a player has disconnected from the game and all associated game data is about to be unloaded. /// A chat message has not yet been distributed and "steamPlayerDisconnected" was not yet invoked. /// </summary> /// <param name="clientInfo"></param> /// <param name="shutdown"></param> public override void PlayerDisconnected(ClientInfo clientInfo, bool shutdown) { try { Log.Debug("Api.PlayerDisconnected called."); CommandTools.InvokeScriptEvents(ScriptEvent.playerDisconnected, () => new PlayerDisconnectedEventArgs() { clientInfo = clientInfo, }); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called when the player was authenticated and its entity was created ("entityLoaded" event) but before the player /// becomes visible and the loading screen disappears. During spawning all required chunks and entites are loaded. /// </summary> /// <param name="clientInfo"></param> /// <param name="chunkViewDim"></param> /// <param name="playerProfile"></param> public override void PlayerSpawning(ClientInfo clientInfo, int chunkViewDim, PlayerProfile playerProfile) { try { Log.Debug("Api.PlayerSpawning called."); CommandTools.InvokeScriptEvents(ScriptEvent.playerSpawning, () => new PlayerSpawningEventArgs() { clientInfo = clientInfo, playerProfile = playerProfile, }); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called when a player has connected but before he was authenticated with Steam. Do not trust the clientInfo data! /// </summary> /// <param name="clientInfo"></param> /// <param name="compatibilityVersion"></param> public override void PlayerLogin(ClientInfo clientInfo, string compatibilityVersion) { try { Log.Debug("Api.PlayerLogin called."); CommandTools.InvokeScriptEvents(ScriptEvent.playerLogin, () => new PlayerLoginEventArgs() { clientInfo = clientInfo, compatibilityVersion = compatibilityVersion, }); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
public static bool Prefix(Chunk __instance, Entity _entity) { Log.Debug($"Executing patch prefix {nameof(PlayerEnteredChunk)} ..."); if (_entity is EntityPlayer player) { CommandTools.InvokeScriptEvents(ScriptEvent.playerEnteredChunk, () => new PlayerEnteredChunkEventArgs() { newChunk = new Vector2xz(__instance.X, __instance.Z), oldChunk = new Vector2xz(_entity.chunkPosAddedEntityTo.x, _entity.chunkPosAddedEntityTo.z), position = player.GetBlockPosition(), clientInfo = ConnectionManager.Instance?.GetClientInfoForEntityId(player.entityId), }); } return(true); }
/// <summary> /// Called during game start on every mod, before the World is ready (GameManager.Instance.World == null) /// </summary> public override void GameAwake() { try { Log.Debug("Api.GameAwake called."); Log.Out("Initializing phase 2/3 ..."); CommandTools.InitScripts(); PatchTools.ApplyPatches(); CommandTools.InitScriptsMonitoring(); CommandTools.InvokeScriptEvents(ScriptEvent.gameAwake, () => new ScriptEventArgs()); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called when the map for the chunk was calculated by generating a pixel color for each of the 16x16 blocks. /// The map can be retrieved with chunk.GetMapColors(). /// </summary> /// <param name="chunk"></param> public override void CalcChunkColorsDone(Chunk chunk) { try { // No logging to avoid spam // Log.Debug("Api.CalcChunkColorsDone called."); CommandTools.InvokeScriptEvents(ScriptEvent.chunkMapCalculated, () => new ChunkMapCalculatedEventArgs() { chunkKey = chunk.Key, chunkPos = ChunkTools.ChunkKeyToChunkXZ(chunk.Key), }); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called when the player was made visible and the loading screen disappeared. /// </summary> /// <param name="clientInfo"></param> /// <param name="respawnReason"></param> /// <param name="pos"></param> public override void PlayerSpawnedInWorld(ClientInfo clientInfo, RespawnType respawnReason, Vector3i pos) { try { Log.Debug("Api.PlayerSpawnedInWorld called."); CommandTools.InvokeScriptEvents(ScriptEvent.playerSpawnedInWorld, () => new PlayerSpawnedInWorldEventArgs() { reason = respawnReason.ToString(), position = pos, clientInfo = clientInfo, }); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called when the game started and all objects are ready (e.g. GameManager.Instance.World) /// </summary> public override void GameStartDone() { try { Log.Debug("Api.GameStartDone called."); Log.Out("Initializing phase 3/3 ..."); EacTools.Init(); CommandTools.InitEvents(); RepairEngine.InitAuto(); TelemetryTools.Init(); Log.Out($"Done initializing {Constants.ModName}."); CommandTools.InvokeScriptEvents(ScriptEvent.gameStartDone, () => new ScriptEventArgs()); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called in regular intervalls for players to save their player file to disk /// </summary> /// <param name="clientInfo"></param> /// <param name="playerDataFile"></param> public override void SavePlayerData(ClientInfo clientInfo, PlayerDataFile playerDataFile) { try { Log.Debug("Api.SavePlayerData called."); CommandTools.InvokeScriptEvents(ScriptEvent.playerSaveData, () => { var playerDataDir = GameUtils.GetPlayerDataDir().Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; return(new PlayerSaveDataEventArgs() { playerDataFile = playerDataDir + clientInfo.playerId + "." + PlayerDataFile.EXT, clientInfo = clientInfo, }); }); } catch (Exception ex) { CommandTools.HandleEventException(ex); } }
/// <summary> /// Called for every chat message, including messages about Joins, Leaves, Died, Killed, etc. /// </summary> /// <returns>true if chat message can be processed further, false if it should be suppressed</returns> public override bool ChatMessage(ClientInfo clientInfo, EnumGameMessages messageType, string message, string mainName, bool localizeMain, string secondaryName, bool localizeSecondary) { try { Log.Debug("Api.ChatMessage called."); var args = new ChatMessageEventArgs() { messageType = messageType.ToString(), from = mainName, message = message, clientInfo = clientInfo, }; CommandTools.InvokeScriptEvents(ScriptEvent.chatMessage, () => args); return(!args.isPropagationStopped); } catch (Exception ex) { CommandTools.HandleEventException(ex); return(false); } }
public static void Postfix(NetPackagePlayerStats __instance, State __state, [CanBeNull] World _world) { Log.Debug($"Executing patch postfix {nameof(PlayerStatsChanged)} ..."); if (_world == null || __state == null) { return; } if (_world.GetEntity(__state.EntityId) is EntityPlayer player) { // Track level increase if (player.Level > __state.Level) { CommandTools.InvokeScriptEvents(ScriptEvent.playerLevelUp, () => new PlayerLevelUpEventArgs() { oldLevel = __state.Level, newLevel = player.Level, clientInfo = ConnectionManager.Instance?.GetClientInfoForEntityId(player.entityId), }); } // Track gained xp, including level-up by 1 (can't easily calculate multiple levels into xp) if (player.ExpToNextLevel != __state.ExpToNextLevel && (player.Level == __state.Level || player.Level == __state.Level + 1)) { CommandTools.InvokeScriptEvents(ScriptEvent.playerExpGained, () => new PlayerExpGainedEventArgs() { expGained = player.Level == __state.Level ? __state.ExpToNextLevel - player.ExpToNextLevel : __state.ExpToNextLevel + (player.GetExpForNextLevel() - player.ExpToNextLevel), expToNextLevel = player.ExpToNextLevel, levelUp = player.Level > __state.Level, clientInfo = ConnectionManager.Instance?.GetClientInfoForEntityId(player.entityId), }); } } }