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); }