public void Finalize(CharEditorSelectionPacket charSpec, ref GameObject playerObj) { Trace.Assert(_pkt.raceId.HasValue); Trace.Assert(_pkt.genderId.HasValue); Trace.Assert(playerObj == null); var protoId = D20RaceSystem.GetProtoId(_pkt.raceId.Value, _pkt.genderId.Value); var protoObj = GameSystems.Proto.GetProtoById(protoId); playerObj = GameSystems.Object.CreateFromProto(protoObj, LocAndOffsets.Zero); for (var i = 0; i < 6; i++) { playerObj.SetBaseStat(Stat.strength + i, _pkt.abilityStats[i]); } var animHandle = playerObj.GetOrCreateAnimHandle(); var animParams = AnimatedModelParams.Default; animHandle.Advance(1.0f, 0, 0, animParams); if (_pkt.isPointbuy) { playerObj.SetInt32(obj_f.pc_roll_count, -Globals.Config.PointBuyBudget); } else { playerObj.SetInt32(obj_f.pc_roll_count, _pkt.numRerolls); } }
private void UpdateModelScale() { var race = _pkt.raceId.GetValueOrDefault(RaceId.human); var gender = _pkt.genderId.GetValueOrDefault(Gender.Male); var raceModelScale = D20RaceSystem.GetModelScale(race, gender); var height = (int)Math.Round(_minHeightInches + _slider.Value * (_maxHeightInches - _minHeightInches)); _pkt.height = Math.Clamp(height, _minHeightInches, _maxHeightInches); _pkt.modelScale = _pkt.height * raceModelScale / _maxHeightInches; _currentHeightLabel.Text = FormatHeight(_pkt.height); // Center the text vertically at the current slider's Y position var textHeight = _currentHeightLabel.GetPreferredSize().Height; _currentHeightLabel.Y = _slider.ThumbCenterY - textHeight / 2 + 5; var heightFactor = (_pkt.height - _minHeightInches) / (float)(_maxHeightInches - _minHeightInches); _pkt.weight = (int)(_minWeight + heightFactor * (_maxWeight - _minWeight)); // Update the model scale for preview purposes var editedChar = UiSystems.PCCreation.EditedChar; editedChar?.SetInt32(obj_f.model_scale, (int)(_pkt.modelScale * 100.0)); }
public void Show() { var race = _pkt.raceId.GetValueOrDefault(RaceId.human); var gender = _pkt.genderId.GetValueOrDefault(Gender.Male); var minHeight = D20RaceSystem.GetMinHeight(race, gender); var maxHeight = D20RaceSystem.GetMaxHeight(race, gender); SetHeightRange(minHeight, maxHeight); _minWeight = D20RaceSystem.GetMinWeight(race, gender); _maxWeight = D20RaceSystem.GetMaxWeight(race, gender); UpdateModelScale(); Container.Visible = true; }
public bool CanSelect(GameObject playerObj, DeityId deityId) { var deity = DeitiesById[deityId]; if (!deity.IsSelectable) { return(false); } var race = playerObj.GetRace(); if (D20RaceSystem.UseBaseRaceForDeity(race)) { race = D20RaceSystem.GetBaseRace(race); } var alignment = playerObj.GetAlignment(); var classEnum = (Stat)playerObj.GetInt32(obj_f.critter_level_idx, 0); var deityClass = D20ClassSystem.GetDeityClass(classEnum); var isCleric = deityClass == Stat.level_cleric; if (isCleric) { if (deityId == DeityId.NONE) { // Clerics MUST have a deity. return(false); } } var hasRace = deity.FavoredRaces.Contains(race); if (hasRace && !isCleric) // can't have Clerics casting spells of opposed alignments { return(true); } // doesn't have race automatic, so check the supported calsses var hasClass = deity.FavoredClasses.Count == 0 || deity.FavoredClasses.Contains(deityClass); if (!hasClass && !isCleric) { return(false); } // special casing - probably buggy but that's how it was in the original if (deity.FavoredRaces.Count > 0) { var isException = false; if (deityId == DeityId.CORELLON_LARETHIAN) { // Corellon Larethian for Bards isException = deityClass == Stat.level_bard; } else if (deityId == DeityId.EHLONNA) { // Ehlonna isException = deityClass == Stat.level_cleric; } if (!isException && !hasRace) { return(false); } } // check alignment if (deityId == DeityId.ST_CUTHBERT) // St. Cuthbert special case { return(alignment == Alignment.LAWFUL_GOOD || alignment == Alignment.LAWFUL); } var deityAlignment = deity.Alignment; if (deityAlignment == Alignment.NEUTRAL && !isCleric) { return(true); } if (alignment == deityAlignment) { return(true); } return(GameSystems.Stat.AlignmentsUnopposed(alignment, deityAlignment, true)); }