public override bool Execute(VM vm, VMAvatar caller) { //need caller to be present if (caller == null) { return(false); } var limit = caller.SkillLocks; SkillID = Math.Min(SkillID, (byte)5); //must be 0-5 int otherLocked = 0; for (int i = 0; i < 6; i++) //sum other skill locks to see what we can feasibly put in this skill { if (i == SkillID) { continue; } otherLocked += caller.GetPersonData((VMPersonDataVariable)((int)VMPersonDataVariable.SkillLockBase + i)) / 100; } if (otherLocked >= limit) { return(false); //cannot lock this skill at all } LockLevel = (short)Math.Min(caller.GetPersonData(LockToSkill[SkillID]) / 100, Math.Min(LockLevel, (short)(limit - otherLocked))); //can only lock up to the limit caller.SetPersonData((VMPersonDataVariable)((int)VMPersonDataVariable.SkillLockBase + SkillID), (short)(LockLevel * 100)); return(true); }
public void Save(VMAvatar avatar) { SkinTone = (byte)avatar.SkinTone; DefaultSuits = avatar.DefaultSuits; //todo: clone? //if naked or using clothes rack, save in daywear. //TODO: store and check simantics outfit category, and restore using that instead. var dyn = avatar.DynamicSuits; var bID = avatar.BodyOutfit.ID; var saveDaywear = dyn.Daywear == bID || dyn.Sleepwear == bID || dyn.Swimwear == bID; saveDaywear = saveDaywear || (bID == 0x24E0000000D || bID == 0x10000000D); BodyOutfit = (saveDaywear)?avatar.DefaultSuits.Daywear.ID : bID; HeadOutfit = avatar.HeadOutfit.ID; Name = avatar.Name; Permissions = avatar.AvatarState.Permissions; AvatarFlags = ((VMTSOAvatarState)avatar.TSOState).Flags; Budget = avatar.TSOState.Budget.Value; for (int i = 0; i < MotiveData.Length; i++) { MotiveData[i] = avatar.GetMotiveData((VMMotive)i); } MotiveData[(int)(VMMotive.SleepState)] = 0; for (int i = 0; i < PersonDataMap.Length; i++) { PersonData[i] = avatar.GetPersonData((VMPersonDataVariable)PersonDataMap[i]); } SkillLock = avatar.SkillLocks; OnlineJobInfo = ((VMTSOAvatarState)avatar.TSOState).JobInfo; IgnoredAvatars = ((VMTSOAvatarState)avatar.TSOState).IgnoredAvatars; }
public void Save(VMAvatar avatar) { SkinTone = (byte)avatar.SkinTone; DefaultSuits = avatar.DefaultSuits; //todo: clone? //if naked, save in daywear. BodyOutfit = (avatar.BodyOutfit.ID == 0x24E0000000D || avatar.BodyOutfit.ID == 0x10000000D)?avatar.DefaultSuits.Daywear.ID : avatar.BodyOutfit.ID; HeadOutfit = avatar.HeadOutfit.ID; Name = avatar.Name; Permissions = ((VMTSOAvatarState)avatar.TSOState).Permissions; AvatarFlags = ((VMTSOAvatarState)avatar.TSOState).Flags; Budget = avatar.TSOState.Budget.Value; for (int i = 0; i < MotiveData.Length; i++) { MotiveData[i] = avatar.GetMotiveData((VMMotive)i); } MotiveData[(int)(VMMotive.SleepState)] = 0; for (int i = 0; i < PersonDataMap.Length; i++) { PersonData[i] = avatar.GetPersonData((VMPersonDataVariable)PersonDataMap[i]); } SkillLock = avatar.SkillLocks; OnlineJobInfo = ((VMTSOAvatarState)avatar.TSOState).JobInfo; IgnoredAvatars = ((VMTSOAvatarState)avatar.TSOState).IgnoredAvatars; }
public void SetNameMessage(VMAvatar avatar) { Name = avatar.Name; Message = avatar.Message; Gender = avatar.GetPersonData(SimAntics.Model.VMPersonDataVariable.Gender) > 0; TTSContext?.Speak(Message.Replace('_', ' '), Gender, ((VMTSOAvatarState)avatar.TSOState).ChatTTSPitch); if (avatar.PersistID == 0) { BgColor = new Color(100, 100, 100); // NPC chat color } else if (((VMTSOAvatarState)avatar.TSOState).Permissions == VMTSOAvatarPermissions.Admin) { BgColor = new Color(180, 0, 0); // admin red color } else if (((VMTSOAvatarState)avatar.TSOState).Permissions == VMTSOAvatarPermissions.Visitor) { BgColor = new Color(30, 128, 30); // visitor green color } else { BgColor = new Color(8, 8, 128); // default blue color } Offscreen = false; if (Message == "") { Name = ""; } TextChanged(); }
public void SetNameMessage(VMAvatar avatar) { Name = avatar.Name; Message = avatar.Message; Gender = avatar.GetPersonData(SimAntics.Model.VMPersonDataVariable.Gender) > 0; TTSContext?.Speak(Message.Replace('_', ' '), Gender, ((VMTSOAvatarState)avatar.TSOState).ChatTTSPitch); Offscreen = false; if (Message == "") { Name = ""; } TextChanged(); }
public static VMOutfitReference GetPersonSuitTS1(VMAvatar avatar, ushort id) { var type = (VMPersonSuits)id; var bodyStrings = avatar.Object.Resource.Get <STR>(avatar.Object.OBJ.BodyStringID); bool male = (avatar.GetPersonData(VMPersonDataVariable.Gender) == 0); var age = avatar.GetPersonData(VMPersonDataVariable.PersonsAge); var skn = bodyStrings.GetString(14).ToLowerInvariant(); var child = (age < 18 && age != 0); var code = "fit"; if (bodyStrings.GetString(1).ToLowerInvariant().Contains("fat")) { code = "fat"; } else if (bodyStrings.GetString(1).ToLowerInvariant().Contains("skn")) { code = "skn"; } if (child) { code = "uchd"; } else { code = (male ? "m" : "f") + code; } VMOutfitReference toHandCopy = null; switch (type) { //todo: (tail etc), cockroach head case VMPersonSuits.DefaultDaywear: return(new VMOutfitReference(bodyStrings, false)); case VMPersonSuits.Naked: toHandCopy = new VMOutfitReference("n" + code + "_01,BODY=" + "n" + code + skn + "_01", false); break; case VMPersonSuits.DefaultSwimwear: if (IsValid(bodyStrings.GetString(31))) { goto case VMPersonSuits.TS1ExpandedSwimsuit; } toHandCopy = new VMOutfitReference("n" + code + "_01,BODY=" + "u" + code + skn + "_" + ((male && !child)?"briefs":"undies") + "01", false); break; case VMPersonSuits.TS1Formal: if (IsValid(bodyStrings.GetString(30))) { goto case VMPersonSuits.TS1ExpandedFormal; } toHandCopy = new VMOutfitReference("f" + code + "_01,BODY=" + "f" + code + skn + "_01", false); break; case VMPersonSuits.JobOutfit: var jtype = avatar.GetPersonData(VMPersonDataVariable.JobType); var level = avatar.GetPersonData(VMPersonDataVariable.JobPromotionLevel); var job = Content.GameContent.Get.Jobs.GetJobLevel(jtype, level); var bskn = job.MaleUniformMesh; if (bskn == "") { return(new VMOutfitReference(bodyStrings, false)); } if (!male && job.FemaleUniformMesh != null) { bskn = job.FemaleUniformMesh; } bskn = bskn.ToLowerInvariant().Replace("$g", code[0].ToString()).Replace("$b", code.Substring(1)).Replace("$c", skn); var btex = job.UniformSkin; btex = btex.ToLowerInvariant().Replace("$g", code[0].ToString()).Replace("$b", code.Substring(1)).Replace("$c", skn); toHandCopy = new VMOutfitReference(bskn + ",BODY=" + btex, false); break; case VMPersonSuits.DefaultSleepwear: if (IsValid(bodyStrings.GetString(32))) { goto case VMPersonSuits.TS1ExpandedPajamas; } var pj = (child ? "pjs" : "pajama"); var gen = (child ? (male ? "m" : "f") : (code)); var gen2 = (male ? "m" : "f"); toHandCopy = new VMOutfitReference(pj + gen + "_01,BODY=" + pj + gen2 + skn + "_01", false); break; case VMPersonSuits.SkeletonPlus: toHandCopy = new VMOutfitReference((child?"skeletonchd_01": "skeleton_01") + ",BODY=skeleton_01", true); break; case VMPersonSuits.SkeletonMinus: toHandCopy = new VMOutfitReference((child ? "skeletonchd_01" : "skeleton_01") + ",BODY=skeleneg_01", true); break; case VMPersonSuits.TS1Toga: case VMPersonSuits.TS1Country: case VMPersonSuits.TS1Luau: case VMPersonSuits.TS1Rave: case VMPersonSuits.TS1Costume: //person strings 27. hands: 28, 29 case VMPersonSuits.TS1ExpandedFormal: //person strings 30 (f###) toHandCopy = new VMOutfitReference(bodyStrings.GetString(30), false); break; case VMPersonSuits.TS1ExpandedSwimsuit: //person strings 31 (s###) toHandCopy = new VMOutfitReference(bodyStrings.GetString(31), false); break; case VMPersonSuits.TS1ExpandedPajamas: //person strings 32 (l###) toHandCopy = new VMOutfitReference(bodyStrings.GetString(32), false); break; case VMPersonSuits.TS1Disco: //??? case VMPersonSuits.TS1Winter: //person strings 33 (w###) toHandCopy = new VMOutfitReference(bodyStrings.GetString(33), false); break; case VMPersonSuits.TS1HighFashion: //person strings 34 (h###) toHandCopy = new VMOutfitReference(bodyStrings.GetString(34), false); break; } if (toHandCopy == null) { return(null); } else { if (avatar.DefaultSuits.Daywear.OftData?.LiteralHandgroup == null) { var oft = new Vitaboy.Outfit(); oft.Read(bodyStrings); toHandCopy.OftData.LiteralHandgroup = oft.LiteralHandgroup; } else { toHandCopy.OftData.LiteralHandgroup = avatar.DefaultSuits.Daywear.OftData?.LiteralHandgroup; } } return(toHandCopy); }
public void Tick(VMAvatar avatar, VMContext context) { var roomScore = context.GetRoomScore(context.GetRoomAt(avatar.Position)); avatar.SetMotiveData(VMMotive.Room, roomScore); if (context.Clock.Minutes == LastMinute) { return; } if (avatar.GetPersonData(VMPersonDataVariable.Cheats) > 0) { return; } LastMinute = context.Clock.Minutes; UpdateCategory(context); int sleepState = (avatar.GetMotiveData(VMMotive.SleepState) == 0)?1:0; int moodSum = 0; for (int i = 0; i < 7; i++) { int lotMul = LotMuls[i]; int frac = 0; var motive = avatar.GetMotiveData(DecrementMotives[i]); var r_Hunger = FracMul(FlatSimMotives[0] * (100 + avatar.GetMotiveData(VMMotive.Hunger)), LotMuls[0]); switch (i) { case 0: frac = r_Hunger; break; case 1: frac = FracMul(FlatSimMotives[1], lotMul); break; case 2: frac = FracMul(FlatSimMotives[2 + sleepState], lotMul); break; case 3: frac = FracMul(FlatSimMotives[4 + sleepState], lotMul) + FracMul(r_Hunger, FlatSimMotives[6]); break; case 4: frac = (FlatSimMotives[7] / (60 * FlatSimMotives[8])); // TODO: wrong but appears to be close? need one which uses energy weight, which is about 2.4 on skills break; case 5: frac = (sleepState == 0) ? 0 : FracMul(FlatSimMotives[9], lotMul); break; case 6: frac = FlatSimMotives[10] + FracMul((FlatSimMotives[11] * (100 + motive)), lotMul); frac /= 2; //make this less harsh right now, til I can work out how multiplayer bonus is meant to work break; } MotiveFractions[i] += (short)frac; if (MotiveFractions[i] >= 1000) { motive -= (short)(MotiveFractions[i] / 1000); MotiveFractions[i] %= 1000; if (motive < -100) { motive = -100; } avatar.SetMotiveData(DecrementMotives[i], motive); } moodSum += motive; } moodSum += roomScore; avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 8)); }
public void Tick(VMAvatar avatar, VMContext context) { var roomScore = context.GetRoomScore(context.GetRoomAt(avatar.Position)); avatar.SetMotiveData(VMMotive.Room, roomScore); if (context.Clock.Minutes / 2 == LastMinute) { return; } LastMinute = context.Clock.Minutes / 2; var sleeping = (avatar.GetMotiveData(VMMotive.SleepState) != 0); int moodSum = 0; for (int i = 0; i < 7; i++) { int frac = 0; var dm = DecrementMotives[i]; if (avatar.HasMotiveChange(dm) && dm != VMMotive.Energy) { continue; } var motive = avatar.GetMotiveData(dm); var r_Hunger = ToFixed1000(Constants[5]) * (100 + avatar.GetMotiveData(VMMotive.Hunger)); switch (i) { case 0: frac = r_Hunger; break; case 1: var active = avatar.GetPersonData(VMPersonDataVariable.ActivePersonality); if (active > 666) { frac = ToFixed1000(Constants[14]); } else if (active < 666) { frac = ToFixed1000(Constants[15]); } else { frac = ToFixed1000(Constants[16]); } break; case 2: frac = ToFixed1000(Constants[sleeping ? 11 : 10]); break; case 3: frac = ToFixed1000(Constants[sleeping ? 13 : 12]) + FracMul(r_Hunger, ToFixed1000(Constants[4])); break; case 4: if (sleeping) { frac = (context.Clock.Hours >= Constants[2]) ? ToFixed1000(Constants[3]) : 0; } else { frac = (ToFixed1000(Constants[0]) / (30 * (int)Constants[1])); } //energy span over wake hours. small energy drift applied if asleep during the day. break; case 5: frac = (sleeping)?0:ToFixed1000(Constants[8]); break; case 6: frac = ToFixed1000(Constants[6]) + ToFixed1000(Constants[7]) * avatar.GetPersonData(VMPersonDataVariable.OutgoingPersonality); break; } MotiveFractions[i] += (short)frac; if (MotiveFractions[i] >= 1000) { motive -= (short)(MotiveFractions[i] / 1000); MotiveFractions[i] %= 1000; if (motive < -100) { motive = -100; } avatar.SetMotiveData(DecrementMotives[i], motive); } moodSum += motive; } moodSum += roomScore; avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 8)); }
public void UpdateSkills(VMAvatar avatar) { SkillValues[0] = avatar.GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.CookingSkill); SkillValues[1] = avatar.GetPersonData(FSO.SimAntics.Model.VMPersonDataVariable.CharismaSkill); }
public void Tick(VMAvatar avatar, VMContext context) { var roomScore = context.GetRoomScore(context.GetRoomAt(avatar.Position)); avatar.SetMotiveData(VMMotive.Room, roomScore); if (context.Clock.Minutes == LastMinute) { return; } if (avatar.GetPersonData(VMPersonDataVariable.Cheats) > 0) { return; } LastMinute = context.Clock.Minutes; var cat = context.VM.TSOState.PropertyCategory; string category = CategoryNames[(cat == 255)?0:cat]; string sleepState = (avatar.GetMotiveData(VMMotive.SleepState) == 0)?"Awake":"Asleep"; int moodSum = 0; for (int i = 0; i < 7; i++) { int lotMul = ToFixed1000(LotMotives.GetNum(category + "_" + LotMotiveNames[i] + "Weight")); int frac = 0; var motive = avatar.GetMotiveData(DecrementMotives[i]); var r_Hunger = FracMul(ToFixed1000(SimMotives.GetNum("HungerDecrementRatio")) * (100 + avatar.GetMotiveData(VMMotive.Hunger)), ToFixed1000(LotMotives.GetNum(category + "_HungerWeight"))); switch (i) { case 0: frac = r_Hunger; break; case 1: frac = FracMul(ToFixed1000(SimMotives.GetNum("ComfortDecrementActive")), lotMul); break; case 2: frac = FracMul(ToFixed1000(SimMotives.GetNum("HygieneDecrement" + sleepState)), lotMul); break; case 3: frac = FracMul(ToFixed1000(SimMotives.GetNum("BladderDecrement" + sleepState)), lotMul) + FracMul(r_Hunger, ToFixed1000(SimMotives.GetNum("HungerToBladderMultiplier"))); break; case 4: frac = (ToFixed1000(SimMotives.GetNum("EnergySpan")) / (60 * (int)SimMotives.GetNum("WakeHours"))); // TODO: wrong but appears to be close? need one which uses energy weight, which is about 2.4 on skills break; case 5: frac = (sleepState == "Asleep") ? 0 : FracMul(ToFixed1000(SimMotives.GetNum("EntDecrementAwake")), lotMul); break; case 6: frac = ToFixed1000(SimMotives.GetNum("SocialDecrementBase")) + FracMul((ToFixed1000(SimMotives.GetNum("SocialDecrementMultiplier")) * (100 + motive)), lotMul); frac /= 2; //make this less harsh right now, til I can work out how multiplayer bonus is meant to work break; } MotiveFractions[i] += (short)frac; if (MotiveFractions[i] >= 1000) { motive -= (short)(MotiveFractions[i] / 1000); MotiveFractions[i] %= 1000; if (motive < -100) { motive = -100; } avatar.SetMotiveData(DecrementMotives[i], motive); } moodSum += motive; } moodSum += roomScore; avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 8)); }
void UpdateAvatar(Avatar model, VMAvatar avatar) { model.ClientSourced = true; model.Avatar_CurrentJob = (ushort)avatar.GetPersonData(VMPersonDataVariable.OnlineJobID); model.Avatar_SkillsLockPoints = (ushort)avatar.SkillLocks; model.Avatar_Skills = new AvatarSkills() { AvatarSkills_Body = (ushort)avatar.GetPersonData(VMPersonDataVariable.BodySkill), AvatarSkills_Charisma = (ushort)avatar.GetPersonData(VMPersonDataVariable.CharismaSkill), AvatarSkills_Cooking = (ushort)avatar.GetPersonData(VMPersonDataVariable.CookingSkill), AvatarSkills_Creativity = (ushort)avatar.GetPersonData(VMPersonDataVariable.CreativitySkill), AvatarSkills_Logic = (ushort)avatar.GetPersonData(VMPersonDataVariable.LogicSkill), AvatarSkills_Mechanical = (ushort)avatar.GetPersonData(VMPersonDataVariable.MechanicalSkill), AvatarSkills_LockLv_Body = (ushort)(avatar.GetPersonData(VMPersonDataVariable.SkillLockBody) / 100), AvatarSkills_LockLv_Charisma = (ushort)(avatar.GetPersonData(VMPersonDataVariable.SkillLockCharisma) / 100), AvatarSkills_LockLv_Cooking = (ushort)(avatar.GetPersonData(VMPersonDataVariable.SkillLockCooking) / 100), AvatarSkills_LockLv_Creativity = (ushort)(avatar.GetPersonData(VMPersonDataVariable.SkillLockCreativity) / 100), AvatarSkills_LockLv_Logic = (ushort)(avatar.GetPersonData(VMPersonDataVariable.SkillLockLogic) / 100), AvatarSkills_LockLv_Mechanical = (ushort)(avatar.GetPersonData(VMPersonDataVariable.SkillLockMechanical) / 100), }; var jobs = new List <JobLevel>(); foreach (var level in ((VMTSOAvatarState)avatar.TSOState).JobInfo) { jobs.Add(new JobLevel() { JobLevel_JobType = (ushort)level.Key, JobLevel_JobExperience = (ushort)level.Value.Experience, JobLevel_JobGrade = (ushort)level.Value.Level }); } model.Avatar_JobLevelVec = ImmutableList.ToImmutableList(jobs); /* * var friendships = new List<Relationship>(); * foreach (var rel in avatar.MeToPersist) * { * if (rel.Key < 16777216) * } */ }