//Character name aliasing public static PlayableCharacters GetCharacterFromString(string characterName) { characterName = characterName.ToLower(); foreach (PlayableCharacters character in Enum.GetValues(typeof(PlayableCharacters))) { var name = character.ToString().ToLower().Replace("coop", ""); if (name.Equals(characterName)) { return(character); } } if (characterName.Equals("marine")) { return(PlayableCharacters.Soldier); } if (characterName.Equals("hunter")) { return(PlayableCharacters.Guide); } if (characterName.Equals("paradox")) { return(PlayableCharacters.Eevee); } ToolsCharApi.Print("Failed to find character base: " + characterName); return(PlayableCharacters.Pilot); }
public static Texture2D GetTextureFromResource(string resourceName) { byte[] array = ExtractEmbeddedResource(resourceName); bool flag = array == null; Texture2D result; if (flag) { ToolsCharApi.PrintError <string>("No bytes found in " + resourceName, "FF0000"); result = null; } else { Texture2D texture2D = new Texture2D(1, 1, TextureFormat.RGBAFloat, false); texture2D.LoadImage(array); texture2D.filterMode = FilterMode.Point; string text = resourceName.Substring(0, resourceName.LastIndexOf('.')); bool flag2 = text.LastIndexOf('.') >= 0; if (flag2) { text = text.Substring(text.LastIndexOf('.') + 1); } texture2D.name = text; result = texture2D; } return(result); }
public static CustomCharacterData BuildCharacter(string filePath, CustomPlayableCharacters identity, Vector3 foyerPos, bool hasAltSkin, Vector3 altSwapperPos, bool removeFoyerExtras = true, bool hasArmourlessAnimations = false, bool usesArmourNotHealth = false, bool paradoxUsesSprites = true, bool useGlow = false, GlowMatDoer glowVars = null, GlowMatDoer altGlowVars = null, int metaCost = 0, bool hasCustomPast = false, string customPast = "") { //ETGModConsole.Log(BotsModule.FilePath); //ETGModConsole.Log(BotsModule.ZipFilePath); var data = GetCharacterData(filePath); data.foyerPos = foyerPos; data.idleDoer = new CharacterSelectIdleDoer { onSelectedAnimation = "select_choose", coreIdleAnimation = "select_idle", idleMax = 10, idleMin = 4, EeveeTex = null, IsEevee = false, AnimationLibraries = new tk2dSpriteAnimation[0], phases = new CharacterSelectIdlePhase[0], }; //BotsModule.Log(data.nameInternal); //data.atlas = GameUIRoot.Instance.ConversationBar.portraitSprite.Atlas;//obj.GetOrAddComponent<dfAtlas>(); data.skinSwapperPos = altSwapperPos; data.identity = identity; bool success = true; if (!CharApiHiveMind.AddNewCharacter(CharApi.prefix, (PlayableCharacters)identity)) { ToolsCharApi.PrintError($"Duplicate Character ID found!! Character building for {identity} has been stopped to avoid horribly breaking things!"); success = false; } else { try { CharacterBuilder.BuildCharacter(data, hasAltSkin, paradoxUsesSprites, removeFoyerExtras, hasArmourlessAnimations, usesArmourNotHealth, hasCustomPast, customPast, metaCost, useGlow, glowVars, altGlowVars); myPlayableCharacters.Add((PlayableCharacters)data.identity); } catch (Exception e) { success = false; ToolsCharApi.PrintError("An error occured while creating the character: " + data.name); ToolsCharApi.PrintException(e); } } if (success) { ToolsCharApi.Print("Built prefab for: " + data.name); return(data); } return(null); }
private static void OnPlayerCharacterChanged(PlayerController player, FoyerCharacterSelectFlag selectCharacter, string characterPath) { if (player.name.ToLower().Contains(characterPath)) { ToolsCharApi.Print("Selected: " + characterPath); if (selectCharacter.gameObject.activeSelf) { selectCharacter.ClearOverheadElement(); selectCharacter.talkDoer.OnExitRange(null); selectCharacter.gameObject.SetActive(false); selectCharacter.GetComponent <SpeculativeRigidbody>().enabled = false; } } else if (!selectCharacter.gameObject.activeSelf) { selectCharacter.gameObject.SetActive(true); SpriteOutlineManager.RemoveOutlineFromSprite(selectCharacter.sprite, true); SpriteOutlineManager.AddOutlineToSprite(selectCharacter.sprite, Color.black); selectCharacter.specRigidbody.enabled = true; PhysicsEngine.Instance.RegisterOverlappingGhostCollisionExceptions(selectCharacter.specRigidbody, null, false); CharacterSelectIdleDoer idleDoer = selectCharacter.GetComponent <CharacterSelectIdleDoer>(); idleDoer.enabled = true; } }
public static Rect AddFaceCardToAtlas(Texture2D tex, Texture2D atlas, int index, Rect bounds) { int xCapacity = (int)(bounds.width / 34); //floor of width/spritesize int yCapacity = (int)(bounds.height / 34); int xIndex = index % xCapacity; int yIndex = index / xCapacity; if (xIndex >= xCapacity || yIndex >= yCapacity) { ToolsCharApi.PrintError("Not enough room left on the Facecard Atlas for this facecard!"); return(Rect.zero); } int xOffset = (int)bounds.x + (xIndex * 34); int yOffset = (int)bounds.y + (yIndex * 34); for (int x = 0; x < tex.width; x++) { for (int y = 0; y < tex.height; y++) { atlas.SetPixel(x + xOffset, y + yOffset, tex.GetPixel(x, y)); } } atlas.Apply(false, false); return(new Rect((float)xOffset / atlas.width, (float)yOffset / atlas.height, 34f / atlas.width, 34f / atlas.height)); }
public static void DumpdfAtlas(dfAtlas atlas) { string collectionName = atlas.name; string defName; Texture2D texture, output; int width, height, minX, minY, maxX, maxY, w, h; Color[] pixels; var itemSizes = atlas.GetPixelRegions(); for (int i = 0; i < itemSizes.Count; i++) { var def = atlas.Items[i]; if (def == null) { continue; } defName = string.IsNullOrEmpty(def.name) ? collectionName + "_" + i : def.name; texture = (Texture2D)atlas.Texture.GetReadable(); width = texture.width; height = texture.height; minX = itemSizes[i].xMin; minY = itemSizes[i].yMin; maxX = itemSizes[i].xMax; maxY = itemSizes[i].yMax; w = maxX - minX; h = maxY - minY; if (w <= 0 || h <= 0) { ToolsCharApi.PrintError <string>($"[{defName}]: is to small. minX: {minX}, minY: {minY}, maxX: {maxX}, maxY: {maxY}"); //ToolsCharApi.ExportTexture(new Texture2D(1, 1) { name = defName }); continue; } ; pixels = texture.GetPixels(minX, minY, w, h); output = new Texture2D(w, h); output.SetPixels(pixels); output.Apply(); output.name = def.name; //BotsModule.Log(output.name, BotsModule.TEXT_COLOR); ToolsCharApi.ExportTexture(output, "SpriteDump/df/" + collectionName); } }
public static void Init(string prefix) { CharApi.prefix = prefix; CharApiHiveMind.Init(prefix); Hooks.Init(); ToolsCharApi.Init(); ETGMod.StartGlobalCoroutine(DelayedStartCR()); //SaveFileBullShit.Load(); }
public static void HandleLoadout(PlayerController player, List <Tuple <PickupObject, bool> > loadout, List <Tuple <PickupObject, bool> > altGun) { if (loadout == null) { ToolsCharApi.PrintError("loadout is null :(((((((("); } if (altGun == null) { ToolsCharApi.PrintError("altGun is null :(((((((("); } StripPlayer(player); foreach (var tuple in loadout) { var item = tuple.First; int id = item.PickupObjectId; var passive = item.GetComponent <PassiveItem>(); var active = item.GetComponent <PlayerItem>(); var gun = item.GetComponent <Gun>(); if (passive) { player.startingPassiveItemIds.Add(id); } else if (active) { player.startingActiveItemIds.Add(id); } else if (gun) { player.startingGunIds.Add(id); } else { ToolsCharApi.PrintError("Is this even an item? It has no passive, active or gun component! " + item.EncounterNameOrDisplayName); } } foreach (var tuple in altGun) { var item = tuple.First; int id = item.PickupObjectId; var gun = item.GetComponent <Gun>(); if (gun) { player.startingAlternateGunIds.Add(id); } else { ToolsCharApi.PrintError("Is this even an gun? It has no gun component! " + item.EncounterNameOrDisplayName); } } }
public static void StopTimerAndReport(string name) { string key = name.ToLower(); if (!timers.ContainsKey(key)) { ToolsCharApi.PrintError($"Could not stop timer {name}, no such timer exists"); return; } float timerStart = timers[key]; int elapsed = (int)((Time.realtimeSinceStartup - timerStart) * 1000); timers.Remove(key); ToolsCharApi.Print($"{name} finished in " + elapsed + "ms"); }
private static IEnumerator HandleCharacterChange() { //Pixelator.Instance.FadeToBlack(0.5f, false); InputDevice lastActiveDevice = GameManager.Instance.LastUsedInputDeviceForConversation; Vector3 position = GameManager.Instance.SecondaryPlayer.transform.position; //Destroy Player 2 if (GameManager.Instance.CurrentGameType == GameManager.GameType.COOP_2_PLAYER) { GameManager.Instance.SecondaryPlayer.SetInputOverride("getting deleted"); GameManager.Instance.ClearSecondaryPlayer(); if (GameManager.Instance.PrimaryPlayer) { GameManager.Instance.PrimaryPlayer.ReinitializeMovementRestrictors(); } yield return(null); } //Build new Player 2 GameManager.Instance.CurrentGameType = GameManager.GameType.COOP_2_PLAYER; if (GameManager.Instance.PrimaryPlayer) { GameManager.Instance.PrimaryPlayer.ReinitializeMovementRestrictors(); } PlayerController newPlayer = GeneratePlayer(position); yield return(null); GameUIRoot.Instance.ConvertCoreUIToCoopMode(); PhysicsEngine.Instance.RegisterOverlappingGhostCollisionExceptions(newPlayer.specRigidbody, null, false); GameManager.Instance.MainCameraController.ClearPlayerCache(); BraveInput.ReassignAllControllers(lastActiveDevice); if (Foyer.Instance) { Foyer.Instance.ProcessPlayerEnteredFoyer(newPlayer); Foyer.Instance.OnCoopModeChanged?.Invoke(); } GameManager.Instance.SecondaryPlayer.PlayerIDX = 1; GameManager.Instance.SecondaryPlayer.characterIdentity = PlayableCharacters.CoopCultist; //Reset GameManager.Instance.RefreshAllPlayers(); ToolsCharApi.Print("Character swapped", "FFFFFF", true); yield break; }
public static List <FoyerCharacterSelectFlag> AddCustomCharactersToFoyer(List <FoyerCharacterSelectFlag> sortedByX) { if (!hasInitialized) { Init(); hasInitialized = true; } List <FoyerCharacterSelectFlag> list = new List <FoyerCharacterSelectFlag>(); foreach (var character in CharacterBuilder.storedCharacters) { try { ToolsCharApi.Print($"Adding {character.Key} to the breach."); var identity = character.Value.First.baseCharacter; var selectCharacter = AddCharacterToFoyer(character.Key, GetFlagFromIdentity(identity, sortedByX).gameObject); if (selectCharacter.PrerequisitesFulfilled()) { sortedByX.Insert(6, selectCharacter); list.Add(selectCharacter); Foyer.Instance.OnPlayerCharacterChanged += selectCharacter.OnSelectedCharacterCallback; } else { UnityEngine.Object.Destroy(selectCharacter.gameObject); } } catch (Exception e) { ToolsCharApi.PrintError($"An error occured while adding character {character.Key} to the breach."); ToolsCharApi.PrintException(e); } } foreach (var flag in sortedByX) { ResetToIdle(flag); } return(list); }
public static FoyerCharacterSelectFlag GetFlagFromIdentity(PlayableCharacters character, List <FoyerCharacterSelectFlag> sortedByX) { string path; foreach (var flag in sortedByX) { path = flag.CharacterPrefabPath.ToLower(); if (character == PlayableCharacters.Eevee && flag.IsEevee) { return(flag); } if (character == PlayableCharacters.Gunslinger && flag.IsGunslinger) { return(flag); } if (character == PlayableCharacters.Bullet && path.Contains("bullet")) { return(flag); } if (character == PlayableCharacters.Convict && path.Contains("convict")) { return(flag); } if (character == PlayableCharacters.Guide && path.Contains("guide")) { return(flag); } if (character == PlayableCharacters.Soldier && path.Contains("marine")) { return(flag); } if (character == PlayableCharacters.Robot && path.Contains("robot")) { return(flag); } if (character == PlayableCharacters.Pilot && path.Contains("rogue")) { return(flag); } } ToolsCharApi.PrintError("Couldn't find foyer select flag for: " + character); ToolsCharApi.PrintError(" Have you unlocked them yet?"); return(sortedByX[1]); }
public static List <Texture2D> GetTexturesFromResource(string resourceName) { string[] resources = ToolsCharApi.GetResourceNames(); List <Texture2D> result = new List <Texture2D>(); for (int i = 0; i < resources.Length; i++) { if (resources[i].StartsWith(resourceName.Replace('/', '.') + ".", StringComparison.OrdinalIgnoreCase)) { //DebugUtility.PrintError<string>(resourceName, "FF0000"); result.Add(GetTextureFromResource(resources[i])); } } if (result.Count == 0) { ToolsCharApi.PrintError <string>("No bytes found in " + resourceName, "FF0000"); result = null; } return(result); }
public static void SwitchSecondaryCharacter(string[] args) { if (args == null || args.Length < 1) { return; } if (!GameManager.Instance.SecondaryPlayer) { ToolsCharApi.PrintError("You need to enter co-op mode before using the character2 command"); return; } prefabPath = "Player" + args[0]; var prefab = (GameObject)BraveResources.Load(prefabPath, ".prefab"); if (prefab == null) { ToolsCharApi.Print("Failed getting prefab for " + args[0]); return; } GameManager.Instance.StartCoroutine(HandleCharacterChange()); Hooks.ResetInfiniteGuns(); }
public static void CustomizeCharacter(PlayerController player, CustomCharacterData data, bool paradoxUsesSprites) { HandleStrings(player, data); ToolsCharApi.StartTimer(" Sprite Handling"); SpriteHandler.HandleSprites(player, data); ToolsCharApi.StopTimerAndReport(" Sprite Handling"); if (data.loadout != null) { HandleLoadout(player, data.loadout, data.altGun); } if (data.stats != null) { HandleStats(player, data.stats); } player.healthHaver.ForceSetCurrentHealth(data.health); player.healthHaver.Armor = (int)data.armor; player.characterIdentity = (PlayableCharacters)data.identity; //player.OverridePlayerSwitchState = "Ninja"; //AkSoundEngine.switch //AkSoundEngine.SetSwitch("CHR_Player", (player.OverridePlayerSwitchState == null) ? data.nameShort : player.OverridePlayerSwitchState, player.gameObject); //AkSoundEngine.GetSwitch("CHR_Player", player.gameObject, out idk); //BotsModule.Log((player.OverridePlayerSwitchState == null) ? data.nameShort : player.OverridePlayerSwitchState); //BotsModule.Strings.Core.Set("#PLAYER_NICK_LOST", "Dead Thing"); //BotsModule.Strings.Core.Set("#PLAYER_NAME_LOST", "Lost"); StringHandler.AddStringDefinition("#PLAYER_NAME_" + player.characterIdentity.ToString().ToUpperInvariant(), data.name); StringHandler.AddStringDefinition("#PLAYER_NICK_" + player.characterIdentity.ToString().ToUpperInvariant(), data.nickname); StringHandler.AddDFStringDefinition("#CHAR_" + data.nameShort.ToString().ToUpper(), data.name); StringHandler.AddDFStringDefinition("#CHAR_" + data.nameShort.ToString().ToUpper() + "_SHORT", data.nameShort); //BotsModule.Log("Player is: " + data.nameShort.ToString(), BotsModule.LOST_COLOR); //BotsModule.Log("#CHAR_" + data.nameShort.ToUpper(), BotsModule.LOST_COLOR); /*if (!hasClearedEeveeAnims) * { * var eevee = (GameObject)ResourceCache.Acquire("PlayerEevee"); * if (eevee != null) * { * eevee.GetComponent<CharacterAnimationRandomizer>().AnimationLibraries.Clear(); * } * hasClearedEeveeAnims = true; * }*/ if (paradoxUsesSprites) { var eevee = (GameObject)ResourceCache.Acquire("PlayerEevee"); if (player.spriteAnimator.Library != null && eevee != null) { eevee.GetComponent <CharacterAnimationRandomizer>().AddOverrideAnimLibrary(player.spriteAnimator.Library); //BotsModule.Log("player.spriteAnimator.Library added"); } if (player.AlternateCostumeLibrary != null && eevee != null) { eevee.GetComponent <CharacterAnimationRandomizer>().AddOverrideAnimLibrary(player.AlternateCostumeLibrary); //BotsModule.Log("AlternateCostumeLibrary added"); } } //GameManager.Instance.PrimaryPlayer.GetComponent<CharacterAnimationRandomizer>().AddOverrideAnimLibrary(player.spriteAnimator.Library); }
//Main parse loop public static CustomCharacterData ParseCharacterData(string[] lines) { CustomCharacterData data = new CustomCharacterData(); for (int i = 0; i < lines.Length; i++) { string line = lines[i].ToLower().Trim(); string lineCaseSensitive = lines[i].Trim(); if (string.IsNullOrEmpty(line)) { continue; } if (line.StartsWith("#")) { continue; } if (line.StartsWith("<loadout>")) { data.loadout = GetLoadout(lines, i + 1, out i); continue; } if (line.StartsWith("<altguns>")) { //ToolsCharApi.PrintError("alt guns found"); data.altGun = GetAltguns(lines, i + 1, out i); continue; } if (line.StartsWith("<stats>")) { data.stats = GetStats(lines, i + 1, out i); continue; } int dividerIndex = line.IndexOf(':'); if (dividerIndex < 0) { continue; } string value = lineCaseSensitive.Substring(dividerIndex + 1).Trim(); if (line.StartsWith("base:")) { data.baseCharacter = GetCharacterFromString(value); if (data.baseCharacter == PlayableCharacters.Robot) { data.armor = 6; } continue; } if (line.StartsWith("name:")) { data.name = value; continue; } /*if (line.StartsWith("unlock:")) * { * data.unlockFlag = GetFlagFromString(value); * //BotsModule.Log(data.unlockFlag+"", BotsModule.LOST_COLOR); * continue; * }*/ if (line.StartsWith("name short:")) { data.nameShort = value.Replace(" ", "_"); data.nameInternal = "Player" + data.nameShort; continue; } if (line.StartsWith("nickname:")) { data.nickname = value; continue; } if (line.StartsWith("armor:")) { float floatValue; if (!float.TryParse(value, out floatValue)) { ToolsCharApi.PrintError("Invalid armor value: " + line); continue; } data.armor = floatValue; continue; } ToolsCharApi.PrintError($"Line {i} in {DataFile} did not meet any expected criteria:"); ToolsCharApi.PrintRaw("----" + line, true); } return(data); }
private static CustomCharacterData GetCharacterData(string filePath) { filePath = filePath.Replace("/", ".").Replace("\\", "."); ToolsCharApi.StartTimer("Loading data for " + Path.GetFileName(filePath)); ToolsCharApi.Print(""); ToolsCharApi.Print("--Loading " + Path.GetFileName(filePath) + "--", "0000FF"); //string customCharacterDir = Path.Combine(CharacterDirectory, filePath).Replace("/", ".").Replace("\\", "."); string dataFilePath = Path.Combine(filePath, "characterdata.txt").Replace("/", ".").Replace("\\", "."); var assembly = Assembly.GetCallingAssembly(); var lines = new string[0]; using (Stream stream = assembly.GetManifestResourceStream(dataFilePath)) using (StreamReader reader = new StreamReader(stream)) { var linesList = new List <string>(); string line = null; while ((line = reader.ReadLine()) != null) { linesList.Add(line); } //ToolsCharApi.PrintError(linesList.Count().ToString()); lines = linesList.ToArray(); } if (lines.Count() <= 0) { ToolsCharApi.PrintError($"No \"{DataFile}\" file found for " + Path.GetFileName(filePath)); return(null); } //var lines = ToolsCharApi.GetLinesFromFile(dataFilePath); var data = ParseCharacterData(lines); string spritesDir = Path.Combine(filePath, "sprites").Replace("/", ".").Replace("\\", "."); string newSpritesDir = Path.Combine(filePath, "newspritesetup").Replace("/", ".").Replace("\\", "."); string newAltSpritesDir = Path.Combine(filePath, "newaltspritesetup").Replace("/", ".").Replace("\\", "."); string altSpritesDir = Path.Combine(filePath, "alt_sprites").Replace("/", ".").Replace("\\", "."); string loadoutDir = Path.Combine(filePath, "loadoutsprites").Replace("/", ".").Replace("\\", "."); string foyerDir = Path.Combine(filePath, "foyercard").Replace("/", ".").Replace("\\", "."); string punchoutDir = Path.Combine(filePath, "punchout").Replace("/", ".").Replace("\\", "."); string punchoutSpritesDir = Path.Combine(filePath, "punchout.sprites").Replace("/", ".").Replace("\\", "."); string[] resources = ToolsCharApi.GetResourceNames(); for (int i = 0; i < resources.Length; i++) { if (resources[i].Contains(filePath)) { if (resources[i].StartsWith(spritesDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && data.sprites == null) { //ToolsCharApi.PrintError("Found: Sprites folder"); data.sprites = ToolsCharApi.GetTexturesFromResource(spritesDir); } if (resources[i].StartsWith(altSpritesDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && data.altSprites == null) { //ToolsCharApi.PrintError("Found: Alt Sprites folder"); data.altSprites = ToolsCharApi.GetTexturesFromResource(altSpritesDir); } if (resources[i].StartsWith(newSpritesDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && string.IsNullOrEmpty(data.pathForSprites)) { //ToolsCharApi.PrintError("Found: New Sprites folder"); data.pathForSprites = newSpritesDir; } if (resources[i].StartsWith(newAltSpritesDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && string.IsNullOrEmpty(data.pathForAltSprites)) { //ToolsCharApi.PrintError("Found: New Sprites folder"); data.pathForAltSprites = newAltSpritesDir; } if (resources[i].StartsWith(foyerDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && data.foyerCardSprites == null) { //ToolsCharApi.PrintError("Found: Foyer card folder"); data.foyerCardSprites = ToolsCharApi.GetTexturesFromResource(foyerDir); } if (resources[i].StartsWith(loadoutDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && data.loadoutSprites == null) { //ToolsCharApi.PrintError("Found: Loadout card folder"); data.loadoutSprites = ToolsCharApi.GetTexturesFromResource(loadoutDir); //ToolsCharApi.PrintError(data.loadoutSprites.Count.ToString()); } if (resources[i].StartsWith(punchoutSpritesDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && data.punchoutSprites == null) { ToolsCharApi.Print("Found: Punchout Sprites folder"); Debug.Log("Found: Punchout Sprites folder"); data.punchoutSprites = new Dictionary <string, Texture2D>(); foreach (var tex in ToolsCharApi.GetTexturesFromResource(punchoutSpritesDir)) { data.punchoutSprites.Add(tex.name, tex); } } if (resources[i].StartsWith(punchoutDir.Replace('/', '.'), StringComparison.OrdinalIgnoreCase) && data.punchoutFaceCards == null) { data.punchoutFaceCards = new List <Texture2D>(); //ETGModConsole.Log(punchoutDir); var punchoutSprites = ToolsCharApi.GetTexturesFromResource(punchoutDir); foreach (var tex in punchoutSprites) { string name = tex.name.ToLower(); if (name.Contains("facecard1") || name.Contains("facecard2") || name.Contains("facecard3")) { data.punchoutFaceCards.Add(tex); ToolsCharApi.Print("Found: Punchout facecard " + tex.name); } } } } } //ToolsCharApi.PrintError("new sprites"); //ToolsCharApi.PrintError("alt sprites"); //ToolsCharApi.PrintError("foyer card sprites"); //ToolsCharApi.PrintError("loadout sprites"); List <Texture2D> miscTextures = ToolsCharApi.GetTexturesFromResource(filePath); foreach (var tex in miscTextures) { string name = tex.name.ToLower(); if (name.Equals("icon")) { //ToolsCharApi.PrintError("Found: Icon "); data.minimapIcon = tex; } if (name.Equals("coop_page_death")) { //ToolsCharApi.PrintError("Found: Icon "); data.coopDeathScreenIcon = tex; } if (name.Contains("bosscard_")) { //ToolsCharApi.PrintError("Found: Bosscard"); //BotsModule.Log(name.ToLower().Replace("bosscard_", "").Replace("0", "")); data.bossCard.Add(tex); } if (name.Equals("playersheet")) { //ToolsCharApi.PrintError("Found: Playersheet"); data.playerSheet = tex; } if (name.Equals("facecard")) { //ToolsCharApi.PrintError("Found: Facecard"); data.faceCard = tex; } if (name.Equals("win_pic_junkan")) { //ToolsCharApi.PrintError("Found: Junkan Win Pic"); data.junkanWinPic = tex; } if (name.Equals("win_pic")) { //ToolsCharApi.PrintError("Found: Past Win Pic"); data.pastWinPic = tex; } if (name.Equals("alt_skin_obj_sprite_001")) { //ToolsCharApi.PrintError("Found: alt_skin_obj_sprite_001"); data.altObjSprite1 = tex; } if (name.Equals("alt_skin_obj_sprite_002")) { //ToolsCharApi.PrintError("Found: alt_skin_obj_sprite_002"); data.altObjSprite2 = tex; } } //ToolsCharApi.PrintError("other sprites"); //ToolsCharApi.StopTimerAndReport("Loading data for " + Path.GetFileName(directories[i])); return(data); }
public static void DumpAnimation(tk2dSpriteAnimation animation) { string collectionName = string.IsNullOrEmpty(animation.name) ? animation.gameObject.name + "_Animation" : animation.name; tk2dSpriteDefinition def; string defName; Material material; Texture2D texture, output; int width, height, minX, minY, maxX, maxY, w, h; Vector2[] uvs; Color[] pixels; foreach (var clip in animation.clips) { foreach (var frame in clip.frames) { def = frame.spriteCollection.spriteDefinitions[frame.spriteId]; if (def == null) { continue; } defName = string.IsNullOrEmpty(def.name) ? collectionName + "_" + frame.spriteId : def.name; material = def.material == null ? def.materialInst : def.material; if (material == null || material.mainTexture == null) { ToolsCharApi.PrintError($"Failed to dump {defName} in {collectionName}: No valid material"); continue; } texture = (Texture2D)material.mainTexture.GetReadable(); width = texture.width; height = texture.height; uvs = def.uvs; if (def.uvs == null || def.uvs.Length < 4) { ToolsCharApi.PrintError($"Failed to dump {defName} in {collectionName}: Invalid UV's"); continue; } minX = Mathf.RoundToInt(uvs[0].x * width); minY = Mathf.RoundToInt(uvs[0].y * height); maxX = Mathf.RoundToInt(uvs[3].x * width); maxY = Mathf.RoundToInt(uvs[3].y * height); w = maxX - minX; h = maxY - minY; if (w <= 0 || h <= 0) { ToolsCharApi.ExportTexture(new Texture2D(1, 1) { name = defName }); continue; } ; pixels = texture.GetPixels(minX, minY, w, h); output = new Texture2D(w, h); output.SetPixels(pixels); output.Apply(); if (def.flipped == tk2dSpriteDefinition.FlipMode.Tk2d) { output = output.Rotated().Flipped(); } output.name = def.name; ToolsCharApi.ExportTexture(output, $"AnimationDump/{collectionName.Replace("/", "-").Replace("\\", "-")}/{clip.name}", $"{output.name}_{clip.frames.IndexOf(frame)}"); } } }
//Stats public static Dictionary <StatType, float> GetStats(string[] lines, int startIndex, out int endIndex) { endIndex = startIndex; Dictionary <PlayerStats.StatType, float> stats = new Dictionary <PlayerStats.StatType, float>(); string line; string[] args; for (int i = startIndex; i < lines.Length; i++) { endIndex = i; line = lines[i].ToLower().Trim(); if (line.StartsWith("</stats>")) { return(stats); } args = line.Split(':'); if (args.Length == 0) { continue; } if (string.IsNullOrEmpty(args[0])) { continue; } if (args.Length < 2) { ToolsCharApi.PrintError("Invalid stat line: " + line); continue; } StatType stat = StatType.Accuracy; bool foundStat = false; foreach (StatType statType in Enum.GetValues(typeof(StatType))) { if (statType.ToString().ToLower().Equals(args[0].ToLower())) { stat = statType; foundStat = true; break; } } if (!foundStat) { ToolsCharApi.PrintError("Unable to find stat: " + line); continue; } float value; bool foundValue = float.TryParse(args[1].Trim(), out value); if (!foundValue) { ToolsCharApi.PrintError("Invalid stat value: " + line); continue; } stats.Add(stat, value); } ToolsCharApi.PrintError("Invalid stats setup, expecting '</stats>' but found none"); return(new Dictionary <StatType, float>()); }
public static void BuildCharacter(CustomCharacterData data, bool hasAltSkin, bool paradoxUsesSprites, bool removeFoyerExtras, bool hasArmourlessAnimations = false, bool usesArmourNotHealth = false, bool hasCustomPast = false, string customPast = "", int metaCost = 0, bool useGlow = false, GlowMatDoer glowVars = null, GlowMatDoer altGlowVars = null) { var basePrefab = GetPlayerPrefab(data.baseCharacter); if (basePrefab == null) { ToolsCharApi.PrintError("Could not find prefab for: " + data.baseCharacter.ToString()); return; } ToolsCharApi.Print(""); ToolsCharApi.Print("--Building Character: " + data.nameShort + "--", "0000FF"); PlayerController playerController; GameObject gameObject = GameObject.Instantiate(basePrefab); playerController = gameObject.GetComponent <PlayerController>(); var customCharacter = gameObject.AddComponent <CustomCharacter>(); customCharacter.data = data; data.characterID = storedCharacters.Count; playerController.AllowZeroHealthState = usesArmourNotHealth; playerController.ForceZeroHealthState = usesArmourNotHealth; playerController.hasArmorlessAnimations = hasArmourlessAnimations; playerController.altHandName = "hand_alt"; playerController.SwapHandsOnAltCostume = true; GameObject.DontDestroyOnLoad(gameObject); CustomizeCharacter(playerController, data, paradoxUsesSprites); data.useGlow = useGlow; if (useGlow) { data.emissiveColor = glowVars.emissiveColor; data.emissiveColorPower = glowVars.emissiveColorPower; data.emissivePower = glowVars.emissivePower; } data.removeFoyerExtras = removeFoyerExtras; data.metaCost = metaCost; if (useGlow) { var material = new Material(EnemyDatabase.GetOrLoadByName("GunNut").sprite.renderer.material); //var material = new Material(ShaderCache.Acquire("Brave/UnlitTintableCutoutEmissive")); material.DisableKeyword("BRIGHTNESS_CLAMP_ON"); material.EnableKeyword("BRIGHTNESS_CLAMP_OFF"); material.SetTexture("_MainTexture", material.GetTexture("_MainTex")); material.SetColor("_EmissiveColor", glowVars.emissiveColor); material.SetFloat("_EmissiveColorPower", glowVars.emissiveColorPower); material.SetFloat("_EmissivePower", glowVars.emissivePower); material.SetFloat("_EmissiveThresholdSensitivity", 0.5f); data.glowMaterial = material; } if (useGlow && hasAltSkin) { var material = new Material(EnemyDatabase.GetOrLoadByName("GunNut").sprite.renderer.material); //var material = new Material(ShaderCache.Acquire("Brave/UnlitTintableCutoutEmissive")); material.DisableKeyword("BRIGHTNESS_CLAMP_ON"); material.EnableKeyword("BRIGHTNESS_CLAMP_OFF"); material.SetTexture("_MainTexture", material.GetTexture("_MainTex")); material.SetColor("_EmissiveColor", altGlowVars.emissiveColor); material.SetFloat("_EmissiveColorPower", altGlowVars.emissiveColorPower); material.SetFloat("_EmissivePower", altGlowVars.emissivePower); material.SetFloat("_EmissiveThresholdSensitivity", 0.5f); data.altGlowMaterial = material; } data.normalMaterial = new Material(ShaderCache.Acquire("Brave/PlayerShader")); basePrefab = null; storedCharacters.Add(data.nameInternal.ToLower(), new Tuple <CustomCharacterData, GameObject>(data, gameObject)); //BotsModule.Log("nameInternal: " + data.nameInternal, BotsModule.TEXT_COLOR); customCharacter.past = customPast; customCharacter.hasPast = hasCustomPast; gameObject.SetActive(false); FakePrefab.MarkAsFakePrefab(gameObject); }
private static FoyerCharacterSelectFlag AddCharacterToFoyer(string characterPath, GameObject selectFlagPrefab) { //Gather character data var customCharacter = CharacterBuilder.storedCharacters[characterPath.ToLower()]; //if (!CheckUnlocked(customCharacter.First)) //{ // return null; //} ToolsCharApi.Print(" Got custom character"); //Create new object FoyerCharacterSelectFlag selectFlag = GameObject.Instantiate(selectFlagPrefab).GetComponent <FoyerCharacterSelectFlag>(); selectFlag.prerequisites = customCharacter.First.prerequisites; FakePrefab.MarkAsFakePrefab(selectFlag.gameObject); SceneManager.MoveGameObjectToScene(selectFlag.gameObject, SceneManager.GetActiveScene()); selectFlag.transform.position = customCharacter.First.foyerPos; selectFlag.CharacterPrefabPath = characterPath; selectFlag.name = "NPC_FoyerCharacter_" + customCharacter.First.nameShort; ToolsCharApi.Print(" Made select flag"); //Replace sprites HandleSprites(selectFlag, customCharacter.Second.GetComponent <PlayerController>()); ToolsCharApi.Print(" Replaced sprites"); var td = selectFlag.talkDoer; GameObject groundThingHandler = new GameObject($"{customCharacter.First.nameShort}GroundThingHandler"); groundThingHandler.transform.position = customCharacter.First.foyerPos; //Setup overhead card if (!string.IsNullOrEmpty(customCharacter.First.pathForSprites)) { var idleDoer = selectFlag.gameObject.GetComponent <CharacterSelectIdleDoer>(); idleDoer.AnimationLibraries = customCharacter.First.idleDoer.AnimationLibraries; idleDoer.coreIdleAnimation = customCharacter.First.idleDoer.coreIdleAnimation; idleDoer.onSelectedAnimation = customCharacter.First.idleDoer.onSelectedAnimation; idleDoer.EeveeTex = customCharacter.First.idleDoer.EeveeTex; idleDoer.idleMax = customCharacter.First.idleDoer.idleMax; idleDoer.idleMin = customCharacter.First.idleDoer.idleMin; idleDoer.IsEevee = customCharacter.First.idleDoer.IsEevee; idleDoer.phases = customCharacter.First.idleDoer.phases; } selectFlag.gameObject.GetComponent <tk2dSpriteAnimator>().DefaultClipId = customCharacter.Second.GetComponent <PlayerController>().spriteAnimator.GetClipIdByName("select_idle"); if (customCharacter.First.removeFoyerExtras) { foreach (var child in selectFlag.gameObject.transform) { //wow look i did a peta and killed a dog for no reason if (((Transform)child).gameObject.name == "Doggy") { UnityEngine.Object.DestroyImmediate(((Transform)child).gameObject); } } foreach (var phase in selectFlag.gameObject.GetComponent <CharacterSelectIdleDoer>().phases) { phase.vfxTrigger = CharacterSelectIdlePhase.VFXPhaseTrigger.NONE; phase.endVFXSpriteAnimator = null; } } foreach (var thing in customCharacter.First.randomFoyerBullshitNNAskedFor) { UnityEngine.Object.Instantiate <GameObject>(thing.First, Foyer.Instance.transform.Find("Livery xform")).transform.position = customCharacter.First.foyerPos + thing.Second; } CreateOverheadCard(selectFlag, customCharacter.First); //FakePrefab.MarkAsFakePrefab(selectFlag.OverheadElement); //ETGModConsole.Log(selectFlag.OverheadElement.ToString()); td.OverheadUIElementOnPreInteract = selectFlag.OverheadElement; //FakePrefab.MarkAsFakePrefab(td.OverheadUIElementOnPreInteract); ToolsCharApi.Print(" Made Overhead Card"); //Change the effect of talking to the character foreach (var state in selectFlag.playmakerFsm.Fsm.FsmComponent.FsmStates) { foreach (var action in state.Actions) { if (action is HutongCharacter) { ((HutongCharacter)action).PlayerPrefabPath = characterPath; } } } MakeSkinSwapper(customCharacter.First); ToolsCharApi.Print(" Added swapper"); //Make interactable if (!Dungeonator.RoomHandler.unassignedInteractableObjects.Contains(td)) { Dungeonator.RoomHandler.unassignedInteractableObjects.Add(td); } ToolsCharApi.Print(" Adjusted Talk-Doer"); //Player changed callback - Hides and shows player select object Foyer.Instance.OnPlayerCharacterChanged += (player) => { OnPlayerCharacterChanged(player, selectFlag, characterPath); }; ToolsCharApi.Print(" Added callback"); return(selectFlag); }
public static List <Tuple <PickupObject, bool> > GetAltguns(string[] lines, int startIndex, out int endIndex) { endIndex = startIndex; ToolsCharApi.Print("altguns loadout..."); List <Tuple <PickupObject, bool> > items = new List <Tuple <PickupObject, bool> >(); //ToolsCharApi.PrintError("go f**k yourself"); string line; string[] args; for (int i = startIndex; i < lines.Length; i++) { endIndex = i; line = lines[i].ToLower().Trim(); if (string.IsNullOrEmpty(line)) { continue; } if (line.StartsWith("</altguns>")) { return(items); } args = line.Split(' '); if (args.Length == 0) { continue; } if (!Gungeon.Game.Items.ContainsID(args[0])) { ToolsCharApi.PrintError("Could not find item with ID: \"" + args[0] + "\""); continue; } var item = Gungeon.Game.Items[args[0]]; if (item == null) { ToolsCharApi.PrintError("Could not find item with ID: \"" + args[0] + "\""); continue; } var gun = item.GetComponent <Gun>(); if (gun == null) { ToolsCharApi.PrintError("\"" + args[0] + "\" isn't a gun..."); continue; } if (args.Length > 1 && args[1].Contains("infinite")) { if (gun != null) { if (!CharacterBuilder.guns.Contains(gun) && !gun.InfiniteAmmo) { CharacterBuilder.guns.Add(gun); } items.Add(new Tuple <PickupObject, bool>(item, true)); ToolsCharApi.Print(" " + item.EncounterNameOrDisplayName + " (infinite)"); continue; } else { ToolsCharApi.PrintError(item.EncounterNameOrDisplayName + " is not a gun, and therefore cannot be infinite"); } } else { items.Add(new Tuple <PickupObject, bool>(item, false)); ToolsCharApi.Print(" " + item.EncounterNameOrDisplayName); } } ToolsCharApi.PrintError("Invalid loadout setup, expecting '</altguns>' but found none"); return(new List <Tuple <PickupObject, bool> >()); }
public IEnumerator CheckInfiniteGuns() { while (!checkedGuns) { ToolsCharApi.Print(" Data check"); if (data == null) { ToolsCharApi.PrintError("Couldn't find a character data object for this player!"); yield return(new WaitForSeconds(.1f)); } ToolsCharApi.Print(" Loadout check"); var loadout = data.loadout; if (loadout == null) { checkedGuns = true; yield break; } var player = GetComponent <PlayerController>(); if (player?.inventory?.AllGuns == null) { ToolsCharApi.PrintError("Player or inventory not found"); yield return(new WaitForSeconds(.1f)); } ToolsCharApi.Print($"Doing infinite gun check on {player.name}"); this.infiniteGunIDs = GetInfiniteGunIDs(); ToolsCharApi.Print(" Gun check"); foreach (var gun in player.inventory.AllGuns) { if (infiniteGunIDs.Contains(gun.PickupObjectId)) { if (!Hooks.gunBackups.ContainsKey(gun.PickupObjectId)) { var backup = new Hooks.GunBackupData() { InfiniteAmmo = gun.InfiniteAmmo, PreventStartingOwnerFromDropping = gun.PreventStartingOwnerFromDropping, CanBeDropped = gun.CanBeDropped, PersistsOnDeath = gun.PersistsOnDeath }; Hooks.gunBackups.Add(gun.PickupObjectId, backup); var prefab = PickupObjectDatabase.GetById(gun.PickupObjectId) as Gun; prefab.InfiniteAmmo = true; prefab.PersistsOnDeath = true; prefab.CanBeDropped = false; prefab.PreventStartingOwnerFromDropping = true; } gun.InfiniteAmmo = true; gun.PersistsOnDeath = true; gun.CanBeDropped = false; gun.PreventStartingOwnerFromDropping = true; ToolsCharApi.Print($" {gun.name} is infinite now."); } } checkedGuns = true; yield break; } }