static public object Rit_CurseRemoval(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { SkillPack spp = (SkillPack)"SKILL_PACK-CURSE_P"; SkillPack spm = (SkillPack)"SKILL_PACK-CURSE_M"; SkillPack sps = (SkillPack)"SKILL_PACK-CURSE_S"; foreach (var v in target.characters) { var si = v.Get().GetSkillEffectOnCharacterMatchingSkillpack(spp); if (si == null) { si = v.Get().GetSkillEffectOnCharacterMatchingSkillpack(spm); if (si == null) { si = v.Get().GetSkillEffectOnCharacterMatchingSkillpack(sps); } } if (si == null) { continue; } v.Get().LearnSkill(Character.SkillCategory.Effect, si.source, FInt.ONE, true, -1); } } return(null); }
/// <summary> /// This script calculates chances of getting an item as a drop /// </summary> /// <param name="targetGroup"></param> /// <param name="targetItems"></param> /// <returns></returns> static public float DropItemChance(Thea2.Server.Group targetGroup, float defaultChance) { Tag dropTag = Globals.GetInstanceFromDB <Tag>("TAG-DROP"); List <float> dropAttributes = new List <float>(); foreach (Character c in targetGroup.characters) { dropAttributes.Add(c.attributes.GetFinal(dropTag).ToFloat()); } dropAttributes.Sort(delegate(float a, float b) { return(-a.CompareTo(b)); }); float cumulativeChances = defaultChance; for (int i = 0; i < dropAttributes.Count; i++) { if (i == 0) { cumulativeChances += dropAttributes[i] * 0.01f; } else { cumulativeChances += dropAttributes[i] * 0.005f; } } return(cumulativeChances); }
static public object Rit_CreateTrollRock(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { string sb = "SUBRACE-CRATE_TROLL_ROCK"; Util_AddCharacter(target, sb); } return(null); }
static public object Rit_CreateAlkonost(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { string sb = "SUBRACE-CRATE_ALKONOST"; Util_AddCharacter(target, sb); } return(null); }
static public object Rit_KnowledgeArmor(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { Skill skill = (Skill)SKILL.KNOWLEDGE_ARMOR; Util_LearnSkillEffect(target, skill); } return(null); }
static public object Rit_EarthVision(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { Skill skill = (Skill)SKILL.EARTH_VISION; Util_LearnSkillEffect(target, skill); } return(null); }
static public object Rit_FireGift(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { Skill skill = (Skill)SKILL.FIRE_GIFT; Util_LearnSkillEffect(target, skill); } return(null); }
static public object Rit_ShouldersPower(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { Skill skill = (Skill)SKILL.SHOULDERS_POWER; Util_LearnSkillEffect(target, skill); } return(null); }
static public object Rit_BlessSpiritual(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { Skill skill = (Skill)SKILL.BLESS_S_RIT; Util_LearnSkillEffect(target, skill); } return(null); }
static public object Rit_CreateBogBies(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { string sb = "SUBRACE-CRATE_BOG_BIES"; Util_AddCharacter(target, sb); } return(null); }
static void Util_AddCharacter(Thea2.Server.Group target, string subrace) { DBClass t = Globals.GetInstanceFromDB(subrace); if (t != null) { Type tp = t.GetType(); if (tp == typeof(Subrace)) { Character c = Character.Instantiate(target, t as Subrace, 1); } } }
static public object Rit_HigherEducation(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { FInt extraXp = (FInt)3; FInt charactersInGroups = (FInt)target.characters.Count; FInt bonus = extraXp / charactersInGroups; foreach (var c in target.characters) { c.Get().Xp = c.Get().Xp + bonus; } } return(null); }
static public object Rit_Celebration(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { FInt newMorale = (FInt)40; foreach (Character c in target.characters) { if (c.attributes.GetFinal(TAG.MORALE) < newMorale) { c.attributes.SetBaseTo(TAG.MORALE, newMorale); } } } return(null); }
static void Util_LearnSkillEffect(Thea2.Server.Group target, Skill skill) { foreach (var v in target.characters) { Character c = v.Get(); SkillInstance si = c.effects.Find(o => o.source.reference == skill); if (si != null) { si.charges += 1; } else { c.LearnSkill(Character.SkillCategory.Effect, skill, FInt.ONE); } } }
static public object Rit_SummonPet(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { DBClass t = Globals.GetInstanceFromDB("ITEM_CARGO-WEAK_ONE_RANDOM_DOMESTIC_PET"); if (t != null) { Type tp = t.GetType(); if (tp == typeof(ItemCargo)) { CountEntityBase ceb = ItemBase.InstantaiteFrom(t as ItemCargo); target.AddItem(ceb); } } } return(null); }
static public object Rit_HealSHP(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.characters != null) { Tag shp = (Tag)TAG.HEALTH_SPIRIT; foreach (var v in target.characters) { FInt f = v.Get().attributes.GetBase(shp); FInt max = v.Get().maxSHP; if (max.ToInt() == f.ToInt()) { continue; } int heal = Mathf.Max(1, max.ToInt() / 2); int newHP = Mathf.Min(max.ToInt(), (f + heal).ToInt()); v.Get().attributes.SetBaseTo(shp, FInt.ONE * newHP); } } return(null); }
static public object DEV_DebugSelectedGroup(string data) { var v = GroupSelectionManager.Get().GetSelectedGroup(); if (v == null) { Debug.LogError("[ERROR]this script requires selected group"); return(null); } Thea2.Server.Group g = EntityManager.Get <Thea2.Server.Group>(v.GetID()); HoneyDebug.DebugGroups(g); if (g != null && g.characters != null) { StringBuilder sb = new StringBuilder(); foreach (var c in g.characters) { Character ch = c.Get(); sb.AppendLine("Name: " + ch.name); var d = ch.attributes.GetFinalDictionary(); foreach (var a in d) { sb.AppendLine(a.Key.Get().dbName + " : " + a.Value.ToString(true)); } sb.AppendLine("-------------"); } Debug.Log(sb.ToString()); } return(null); }
static bool Prefix(Equip __instance) { if (__instance.name == "Remove Character") { Dictionary <UIManager.Screen, List <ScreenBase> > openScreensByEnum = Traverse.Create(UIManager.Get()).Field("openScreensByEnum").GetValue <Dictionary <UIManager.Screen, List <ScreenBase> > >(); //Closes Equip and Navbar to return to HUD if (UIManager.Get() != null && openScreensByEnum != null) { foreach (KeyValuePair <UIManager.Screen, List <ScreenBase> > keyValuePair in openScreensByEnum) { if (keyValuePair.Value != null && keyValuePair.Value.Count >= 1) { List <ScreenBase> list = new List <ScreenBase>(keyValuePair.Value); foreach (ScreenBase screenBase in list) { if (!(screenBase is TopLayer) && screenBase.name != "HUD(Clone)") { UIManager.Close(screenBase); } } } } } //Clones "Giving up people" to simplify it and allow character to be removed without gaining items/rep with the slavyans AdvModule advModule = Array.Find <AdvModule>(AdventureLibrary.modules, (AdvModule o) => o.name == "Slavyan"); AdvEvent[] advEventList = Array.FindAll <AdvEvent>(advModule.events, (AdvEvent o) => o.name == "Generic Remove Character"); AdvEvent advEvent; if (advEventList.GetLength(0) == 0) { advEvent = Array.FindAll <AdvEvent>(advModule.events, (AdvEvent o) => o.name == "Giving up people")[0].Clone(); advEvent.module = advModule; advEvent.name = "Generic Remove Character"; Array.Resize <AdvEvent>(ref advModule.events, advModule.events.Length + 1); advModule.events[advModule.events.Length - 1] = advEvent; //advEvent.uniqueID = advModule.GetNextEventIndex(); //Might not be necessary to add ID since it will be removed later UnityEngine.Debug.Log("Equip_ButtonClick_Patch --------------------- making new event " + advEvent.name); } else { //In case the temporary event already exists, but I'm removing them after the event ends advEvent = advEventList[0]; } //Modifies the event to make it more generic and simple AdvNode[] nodes = advEvent.nodes; foreach (AdvNode node in nodes) { if (node is NodeAdventure) { (node as NodeAdventure).story = "You approach your group to decide if anyone should leave."; } List <AdvOutput> outputs = node.outputs; if (outputs != null) { foreach (AdvOutput output in outputs) { if (output.name == "Wish them well and leave.") { output.name = "Send someone away."; } if (output.name == "Actually, ask them to stay with you!") { output.name = "Nevermind."; } if (output.name == "Confirm") { output.targetID = 5; } if (output.name == "Cancel") { output.targetID = 5; } } } } //Run the new temporary event ClientGroupData selectedGroup = GroupSelectionManager.Get().GetSelectedGroup(); Thea2.Server.Group group = null; if (selectedGroup != null) { group = EntityManager.Get <Thea2.Server.Group>(selectedGroup.GetID(), true); } AdventureManager adventureManager = AdventureManager.TriggerEvent(group.ownerID, advEvent, group, null, -1, true); return(false); } return(true); }
static public List <string> GroupGetModels(Thea2.Server.Group targetGroup) { if (targetGroup.settlement) { return(new List <string>() { targetGroup.settlementModel }); } List <string> actors = new List <string>(); if (!World.IsLand(targetGroup.Position)) { if (targetGroup.items != null) { var tag = TAG.SHIP; CountEntityBase ship = null; int value = 0; foreach (var v in targetGroup.items) { if (v.GetItem().attributes.Contains(tag)) { if (ship == null) { ship = v; } else { ClientEntityItem it = new ClientEntityItem(v, false, true); int newValue = it.GetValue(); if (value == FInt.ZERO) { it = new ClientEntityItem(ship, false, true); value = it.GetValue(); } if (value < newValue) { value = newValue; ship = v; } } } } string graphic = null; if (ship != null) { graphic = ship.GetItem().GetDescriptionInfo().iconName; } else { Tag seaMp = (Tag)TAG.SEA_MOVEMENT_RANGE; bool canSwim = targetGroup.characters != null && targetGroup.characters.Count > 0; foreach (var v in targetGroup.characters) { if (v.Get().attributes.GetFinal(seaMp) < FInt.ONE) { canSwim = false; break; } } if (!canSwim) { if (targetGroup.ownerID > 0) { graphic = "Raft"; } else { graphic = "ShipPirate2"; } } } //if some ship graphic have been assigned use it, otherwise fall back to normal unit graphics if (graphic != null) { actors.Add(graphic); return(actors); } } } if (targetGroup.characters == null || targetGroup.characters.Count < 1) { actors.Add("GroundCargo"); } else { List <EntityReference <Character> > sortedChars = new List <EntityReference <Character> >(); sortedChars = new List <EntityReference <Character> >(targetGroup.characters); sortedChars.Sort(delegate(EntityReference <Character> a, EntityReference <Character> b) { var A = a.Get().GetPowerLevel(false); var B = b.Get().GetPowerLevel(false); return(-A.CompareTo(B)); }); for (int i = 0; i < 3; i++) { if (sortedChars.Count > i) { string s = sortedChars[i].Get().model; if (s != null) { actors.Add(s); } else { actors.Add(""); Debug.LogError("[ERROR]Missing name for character model " + sortedChars[i].Get().subrace.dbName); } } } } return(actors); }
static public object UpdateGroupAttributes(Thea2.Server.Group targetGroup, GameInstance gameInstance) { //targetGroup.mp = FInt.ZERO; targetGroup.maxMp = FInt.ZERO; targetGroup.viewRadius = new FInt(-20); targetGroup.detectDangerRadius = FInt.ZERO; targetGroup.detectability = FInt.ZERO; targetGroup.seaMaxMP = FInt.ZERO; targetGroup.seaCarryLimit = FInt.ZERO; targetGroup.gatheringRange = FInt.ONE; targetGroup.maxCraftingWorkersPerTask = new FInt(targetGroup.settlement ? 3 : 2); targetGroup.maxGatheringWorkersPerTask = new FInt(targetGroup.settlement ? 3 : 2); targetGroup.maxResearchWorkersPerTask = new FInt(targetGroup.settlement ? 3 : 2); targetGroup.maxRitualsWorkersPerTask = new FInt(targetGroup.settlement ? 3 : 2); targetGroup.viewRangeBonus = FInt.ZERO; Tag tDay = DBHelpers.GetDBInstance <Tag>(TAG.DAY); bool day = gameInstance.sharedAttributes.Contains(tDay, FInt.ONE); foreach (var v in targetGroup.items) { if (v.GetItem() != null && v.GetItem().skill != null) { SkillInstance si = v.GetItem().skill; foreach (var k in si.source.Get().skillSubskills) { if (k.trigger.triggerGroup == ETriggerGroupType.GroupPassive) { for (int i = 0; i < v.count; i++) { Globals.CallFunction(k.activation.scriptName, v, si.GetCurrentSkillAttributes()[k], targetGroup); } } } } } foreach (var v in targetGroup.characters) { var c = v.Get(); if (c != null) { if (c.learnedSkills != null) { foreach (var si in c.learnedSkills) { foreach (var k in si.source.Get().skillSubskills) { if (k.trigger.triggerGroup == ETriggerGroupType.GroupPassive) { Globals.CallFunction(k.activation.scriptName, null, si.GetCurrentSkillAttributes()[k], targetGroup); } } } } if (c.effects != null) { foreach (var si in c.effects) { foreach (var k in si.source.Get().skillSubskills) { if (k.trigger.triggerGroup == ETriggerGroupType.GroupPassive) { Globals.CallFunction(k.activation.scriptName, null, si.GetCurrentSkillAttributes()[k], targetGroup); } } } } if (c.equipmentEffects != null) { foreach (var si in c.equipmentEffects) { foreach (var k in si.source.Get().skillSubskills) { if (k.trigger.triggerGroup == ETriggerGroupType.GroupPassive) { Globals.CallFunction(k.activation.scriptName, null, si.GetCurrentSkillAttributes()[k], targetGroup); } } } } } } if (targetGroup.seaMaxMP < FInt.ONE) { targetGroup.seaMaxMP = FInt.ONE; } else if (targetGroup.ownerID > 0) { SPlayer player = GameInstance.Get().GetPlayer(targetGroup.ownerID); FInt v = player.attributes.GetBase(TAG.SEA_MOVEMENT_RANGE); targetGroup.seaMaxMP += v; } if (targetGroup.characters != null && targetGroup.seaCarryLimit < targetGroup.characters.Count * 40) { targetGroup.seaCarryLimit = new FInt(targetGroup.characters.Count * 40); } bool isLand = World.IsLand(targetGroup.Position); if (targetGroup.characters != null) { for (int i = 0; i < targetGroup.characters.Count; i++) { Character c = targetGroup.characters[i]; if (i == 0) { if (!targetGroup.settlement && isLand) { targetGroup.mp = c.GetCurentMP(); targetGroup.maxMp = c.GetMaxMP(); } if (day) { targetGroup.viewRadius = c.attributes.GetFinal(TAG.RANGE_OF_SIGHT_DAY) + targetGroup.viewRangeBonus; } else { targetGroup.viewRadius = c.attributes.GetFinal(TAG.RANGE_OF_SIGHT_NIGHT) + targetGroup.viewRangeBonus; } } else { if (!targetGroup.settlement && isLand) { targetGroup.mp = FInt.Min(targetGroup.mp, c.GetCurentMP()); targetGroup.maxMp = FInt.Min(targetGroup.maxMp, c.GetMaxMP()); } if (day) { FInt f = c.attributes.GetFinal(TAG.RANGE_OF_SIGHT_DAY) + targetGroup.viewRangeBonus; targetGroup.viewRadius = FInt.Max(targetGroup.viewRadius, f); } else { FInt f = c.attributes.GetFinal(TAG.RANGE_OF_SIGHT_NIGHT) + targetGroup.viewRangeBonus; targetGroup.viewRadius = FInt.Max(targetGroup.viewRadius, f); } } } } else { //zero MP only if this is group with no characters. //only land mp are updated from characters, //sea mp will not be updated leaving narrow margin for exploits, //but making it way cleaner for regular players targetGroup.mp = FInt.ZERO; } targetGroup.attributesDirty = false; return(null); }
static bool Prefix(Thea2.Server.Group __instance) { if (!__instance.settlement && !__instance.camping) { if (__instance.gatheringRangeArea != null) { __instance.gatheringRangeArea.Clear(); } else { __instance.gatheringRangeArea = new List <Vector3i>(); } return(false); } if (!__instance.settlement && (__instance.characters == null || __instance.characters.Count < 1)) { if (__instance.gatheringRangeArea != null) { __instance.gatheringRangeArea.Clear(); } else { __instance.gatheringRangeArea = new List <Vector3i>(); } return(false); } SPlayer player = GameInstance.Get().GetPlayer(__instance.ownerID); if (__instance.camping && player != null && player.attributes.Contains(DBDef.TAG.CAMP_GATHERING_RANGE)) { __instance.gatheringRange = (FInt)2; } __instance.gatheringRangeArea = HexNeighbors.GetRange(__instance.Position, __instance.gatheringRange.ToInt()); List <Thea2.Server.Group> playerGroups = GameInstance.Get().GetPlayerGroups().FindAll((Group o) => o.ownerID == __instance.ownerID); if (playerGroups != null) { using (List <Group> .Enumerator enumerator = playerGroups.GetEnumerator()) { while (enumerator.MoveNext()) { Group v = enumerator.Current; if (v != __instance) { if (v.settlement || v.camping) { if (v.settlement || (v.characters != null && v.characters.Count >= 1)) { if (v.gatheringRangeArea != null) { int b = HexCoordinates.HexDistance(v.Position, __instance.Position); if (!(v.gatheringRange + __instance.gatheringRange < b)) { __instance.gatheringRangeArea = __instance.gatheringRangeArea.FindAll((Vector3i o) => !v.gatheringRangeArea.Contains(o)); } } } } } } } } return(false); }
static public object Rit_RefreshUpgradeIdol(Thea2.Server.Group target, RitualsTask sourceTask) { if (target != null && target.items != null) { BuildingRecipe br = (BuildingRecipe)BUILD_REC.IDOL; var oldIdol = target.items.Find(o => o.GetItem().GetSource() == br); if (oldIdol == null) { return(null); } var oldDemon = oldIdol.GetItem().superConnection; #region Create new idol List <ItemBase> ibs = ItemBase.items.Where(o => o.GetSource() == br && (o as ItemCrafted).recipeIngredientCount[0] == sourceTask.GetMaterial1Count() && (o as ItemCrafted).recipeIngreadients[0].Get() == sourceTask.GetMaterial1()).ToList(); if (ibs.Count != 1) { Debug.LogError("[ERROR]Number of options in upgrade idol is different than 1: " + ibs.Count); return(null); } ItemCrafted ib = ibs[0] as ItemCrafted; ItemBase inst = ib.Clone <ItemBase>(true); Skill skill = null; if (br.skills != null) { if (!SkillInstance.skillPacks.ContainsKey(br.skills)) { Debug.LogError("[ERROR]Missing skillpack " + br.skills); return(null); } List <Skill> si = SkillInstance.skillPacks[br.skills]; HashSet <Tag> essences = new HashSet <Tag>(); Dictionary <Tag, FInt> essenceCounts = new Dictionary <Tag, FInt>(); List <Skill> valid = new List <Skill>(); CountedResource material1 = null; CountedResource material2 = null; if (ib.recipeIngreadients.Length > 0) { material1 = new CountedResource(); material1.resourceName = ib.recipeIngreadients[0].Get(); material1.resourceCount = ib.recipeIngredientCount[0]; } if (ib.recipeIngreadients.Length > 1) { material2 = new CountedResource(); material2.resourceName = ib.recipeIngreadients[1].Get(); material2.resourceCount = ib.recipeIngredientCount[1]; } if (material1 != null) { foreach (var v in material1.resourceName.essences) { FInt count = new FInt(v.amount) * material1.resourceCount; if (count <= 0) { continue; } essences.Add(v.tag); essenceCounts[v.tag] = count; } } if (material2 != null) { foreach (var v in material2.resourceName.essences) { FInt count = new FInt(v.amount) * material2.resourceCount; if (count <= 0) { continue; } if (!essences.Contains(v.tag)) { essences.Add(v.tag); } if (!essenceCounts.ContainsKey(v.tag)) { essenceCounts[v.tag] = count; } else { essenceCounts[v.tag] += count; } } if (essences.Count > 0) { Tag g = (Tag)TAG.ESSENCE_GRAY; essences.Add(g); } } foreach (var v in si) { bool b = true; foreach (var e in v.baseEssence) { if (!essences.Contains(e.tag)) { b = false; break; } } if (!b) { continue; } valid.Add(v); } if (valid.Count < 1) { Debug.LogError("[ERROR]No valid skill during upgrade of the idol in skillpack " + br.skills); return(null); } skill = valid[0]; } if (skill != null) { inst.skill = SkillInstance.Instantiate(skill, inst); } #endregion #region Destroy old idol //destroy old idol var ceb = target.TakeItem(oldIdol.GetItem(), 1); ceb.GetItem().Destroy(); #endregion //Add new idol var cebNewIdol = target.AddItem(inst, 1); //super connect with old demon to keep it alive if one was still there, otherwise it will create new one. if (oldDemon != null && oldDemon.Valid()) { cebNewIdol.GetItem().SuperConnectWith(oldDemon); } } return(null); }
static public object Rit_MoonBridge(Thea2.Server.Group target, RitualsTask sourceTask) { if (target.settlement) { return(null); } List <Thea2.Server.Group> groups = GameInstance.Get().GetValidPlayerGroups(); List <Thea2.Server.Group> visibleGroups = new List <Thea2.Server.Group>(groups); //visibleGroups.AddRange(groups); visibleGroups.AddRange(GameInstance.Get().GetEnemyGroups()); List <Vector3i> groupsPos = new List <Vector3i>(); List <Vector3i> range = new List <Vector3i>(); foreach (var g in groups) { //check if testing group is different than target group and if group owner is equal to target owner if (g != target && g.ownerID == target.ownerID) { groupsPos.Add(g.Position); } } //sort groups positions from nearest to farthest position groupsPos.Sort(delegate(Vector3i a, Vector3i b) { int distA = HexCoordinates.HexDistance(target.Position, a); int distB = HexCoordinates.HexDistance(target.Position, b); return(distA.CompareTo(distB)); }); //find proper group to teleport to foreach (Vector3i v in groupsPos) { //teleport is possible in range up to 5 hexes from available group, check from nearest to farthest hexes //find hexes in range //can't teleport on water //check if hex is occupied by enemy group, settlement or camping for (int i = 0; i <= 5; i++) { range = HexNeighbors.GetRange(v, i); foreach (var hex in range) { if (World.IsLand(hex) && !GameInstance.Get().GetGroupsToTeleport().ContainsValue(hex)) { List <Thea2.Server.Group> obstacles = visibleGroups.FindAll(o => o.Position == hex && (o.ownerID < 0 || o.settlement || o.camping)); if (obstacles.Count > 0) { continue; } GameInstance.Get().AddToTeleport(target.ID, hex); return(null); } } } } return(null); }