package game import "strings" // init.c — per-game randomization of item appearances and probability // tables, and the player roll-up. // initPlayer rolls her up (init.c init_player). func (g *RogueGame) initPlayer() { p := &g.Player p.MaxStats = initStats p.Stats = p.MaxStats p.FoodLeft = HungerTime // Give him some food obj := newObject() obj.Kind = KindFood obj.Count = 1 g.addPack(obj, true) // And his suit of armor obj = newObject() obj.Kind = KindArmor obj.Which = int(ArmorRingMail) obj.Arm = aClass[ArmorRingMail] - 1 obj.Flags.Set(Known) obj.Count = 1 p.CurArmor = obj g.addPack(obj, true) // Give him his weaponry. First a mace. obj = newObject() g.initWeapon(obj, WeaponMace) obj.HPlus = 1 obj.DPlus = 1 obj.Flags.Set(Known) g.addPack(obj, true) p.CurWeapon = obj // Now a +1 bow obj = newObject() g.initWeapon(obj, WeaponBow) obj.HPlus = 1 obj.Flags.Set(Known) g.addPack(obj, true) // Now some arrows obj = newObject() g.initWeapon(obj, WeaponArrow) obj.Count = g.rnd(15) + 25 obj.Flags.Set(Known) g.addPack(obj, true) } // initColors initializes the potion color scheme for this game // (init.c init_colors). func (g *RogueGame) initColors() { used := make([]bool, len(rainbow)) for i := PotionKind(0); i < NumPotionTypes; i++ { var j int for { j = g.rnd(len(rainbow)) if !used[j] { break } } used[j] = true g.Items.PotColors[i] = rainbow[j] } } // initNames generates the names of the various scrolls (init.c init_names). func (g *RogueGame) initNames() { for i := ScrollKind(0); i < NumScrollTypes; i++ { var cp strings.Builder nwords := g.rnd(3) + 2 for ; nwords > 0; nwords-- { nsyl := g.rnd(3) + 1 for ; nsyl > 0; nsyl-- { sp := sylls[g.rnd(len(sylls))] if cp.Len()+len(sp) > MaxNameLen { break } cp.WriteString(sp) } cp.WriteByte(' ') } g.Items.ScrNames[i] = strings.TrimSuffix(cp.String(), " ") } } // initStones initializes the ring stone setting scheme for this game // (init.c init_stones). func (g *RogueGame) initStones() { used := make([]bool, len(stoneTable)) for i := RingKind(0); i < NumRingTypes; i++ { var j int for { j = g.rnd(len(stoneTable)) if !used[j] { break } } used[j] = true g.Items.RingStones[i] = stoneTable[j].Name g.Items.Rings[i].Worth += stoneTable[j].Value } } // initMaterials initializes the construction materials for wands and staffs // (init.c init_materials). func (g *RogueGame) initMaterials() { used := make([]bool, len(woods)) metused := make([]bool, len(metals)) for i := WandKind(0); i < NumWandTypes; i++ { var str string for { if g.rnd(2) == 0 { j := g.rnd(len(metals)) if !metused[j] { g.Items.WandType[i] = "wand" str = metals[j] metused[j] = true break } } else { j := g.rnd(len(woods)) if !used[j] { g.Items.WandType[i] = "staff" str = woods[j] used[j] = true break } } } g.Items.WandMade[i] = str } } // sumProbs sums up the probabilities for items appearing, converting the // per-item weights into a cumulative distribution (init.c sumprobs). func sumProbs(info []ObjInfo) { for i := 1; i < len(info); i++ { info[i].Prob += info[i-1].Prob } } // initProbs copies the base tables into the game and initializes the // probabilities for the various items (init.c init_probs). func (g *RogueGame) initProbs() { g.Items.Things = baseThings g.Items.Potions = basePotInfo g.Items.Scrolls = baseScrInfo g.Items.Rings = baseRingInfo g.Items.Sticks = baseWsInfo g.Items.Weapons = baseWeapInfo g.Items.Armors = baseArmInfo sumProbs(g.Items.Things[:]) sumProbs(g.Items.Potions[:]) sumProbs(g.Items.Scrolls[:]) sumProbs(g.Items.Rings[:]) sumProbs(g.Items.Sticks[:]) sumProbs(g.Items.Weapons[:NumWeaponTypes]) // C sums MAXWEAPONS, excluding the flame entry sumProbs(g.Items.Armors[:]) } // pickColor returns the given color, or a random one if the hero is // hallucinating (init.c pick_color). func (g *RogueGame) pickColor(col string) string { if g.Player.On(Hallucinating) { return rainbow[g.rnd(len(rainbow))] } return col }