@@ -1580,153 +1580,138 @@ func (r *Room) FindContainerByName(containerNameSearch string) string {
15801580}
15811581
15821582func (r * Room ) FindNoun (noun string ) (foundNoun string , nounDescription string ) {
1583-
15841583 if len (r .Nouns ) == 0 {
1585- return `` , ``
1584+ return "" , ""
15861585 }
15871586
1587+ // Flatten the room nouns and create single-word aliases for multi-word nouns
15881588 roomNouns := map [string ]string {}
1589-
15901589 for originalNoun , originalDesc := range r .Nouns {
15911590 roomNouns [originalNoun ] = originalDesc
1592-
1593- if strings .Contains (originalNoun , ` ` ) {
1594- for _ , n := range strings .Split (originalNoun , ` ` ) {
1595-
1596- if _ , ok := r .Nouns [n ]; ok {
1591+ if strings .Contains (originalNoun , " " ) {
1592+ for _ , part := range strings .Split (originalNoun , " " ) {
1593+ if _ , exists := r .Nouns [part ]; exists {
15971594 continue
15981595 }
1599-
1600- if _ , ok := roomNouns [n ]; ok {
1596+ if _ , exists := roomNouns [part ]; exists {
16011597 continue
16021598 }
1603-
1604- roomNouns [n ] = `:` + originalNoun
1605-
1599+ roomNouns [part ] = ":" + originalNoun
16061600 }
16071601 }
1608-
16091602 }
16101603
1604+ // Build candidate noun list
16111605 testNouns := util .SplitButRespectQuotes (noun )
1612- ct := len (testNouns )
1613- for i := 0 ; i < ct ; i ++ {
1614-
1615- if splitCount := strings .Split (testNouns [i ], ` ` ); len (splitCount ) > 1 {
1616-
1617- for _ , n2 := range splitCount {
1618-
1619- if len (n2 ) < 2 {
1620- continue
1621- }
1622-
1623- testNouns = append (testNouns , n2 )
1606+ for i := 0 ; i < len (testNouns ); i ++ {
1607+ if strings .Contains (testNouns [i ], " " ) {
1608+ for _ , part := range strings .Split (testNouns [i ], " " ) {
1609+ testNouns = append (testNouns , strings .ToLower (strings .TrimSpace (part )))
16241610 }
1625-
16261611 }
16271612 }
1628-
1629- // If it created more than one word, put the original back on as a full string to test
16301613 if len (testNouns ) > 1 {
1631- testNouns = append (testNouns , noun )
1614+ testNouns = append (testNouns , strings . ToLower ( strings . TrimSpace ( noun )) )
16321615 }
16331616
1634- for _ , newNoun := range testNouns {
1617+ // Try each candidate: exact, singular/plural, alias-aware
1618+ for _ , cand := range testNouns {
1619+ newNoun := strings .ToLower (strings .TrimSpace (cand ))
16351620
1621+ // Direct match or single-level alias
16361622 if desc , ok := roomNouns [newNoun ]; ok {
1637- if desc [0 :1 ] == `:` {
1638- return desc [1 :], roomNouns [desc [1 :]]
1623+ if strings .HasPrefix (desc , ":" ) {
1624+ target := desc [1 :]
1625+ if targetDesc , ok2 := roomNouns [target ]; ok2 && ! strings .HasPrefix (targetDesc , ":" ) {
1626+ return target , targetDesc
1627+ }
1628+ // alias->alias or missing target => ignore
1629+ } else {
1630+ return newNoun , desc
16391631 }
1640- return newNoun , desc
1641- }
1642-
1643- if len (newNoun ) < 2 {
1644- continue
16451632 }
16461633
1647- // If ended in `s`, strip it and add a new word to the search list
1648- if newNoun [len (newNoun )- 1 :] == `s` {
1649-
1650- testNoun := newNoun [:len (newNoun )- 1 ]
1651- if desc , ok := roomNouns [testNoun ]; ok {
1652- if desc [0 :1 ] == `:` {
1653- return desc [1 :], roomNouns [desc [1 :]]
1634+ // Strip "es"
1635+ if strings .HasSuffix (newNoun , "es" ) {
1636+ tn := strings .TrimSuffix (newNoun , "es" )
1637+ if desc , ok := roomNouns [tn ]; ok {
1638+ if strings .HasPrefix (desc , ":" ) {
1639+ target := desc [1 :]
1640+ if targetDesc , ok2 := roomNouns [target ]; ok2 && ! strings .HasPrefix (targetDesc , ":" ) {
1641+ return target , targetDesc
1642+ }
1643+ } else {
1644+ return tn , desc
16541645 }
1655- return testNoun , desc
16561646 }
1657-
16581647 } else {
1659-
1660- testNoun := newNoun + `s`
1661- if desc , ok := roomNouns [testNoun ]; ok { // `s`` at end
1662- if desc [0 :1 ] == `:` {
1663- return desc [1 :], roomNouns [desc [1 :]]
1648+ // Add "es"
1649+ tn := newNoun + "es"
1650+ if desc , ok := roomNouns [tn ]; ok {
1651+ if strings .HasPrefix (desc , ":" ) {
1652+ target := desc [1 :]
1653+ if targetDesc , ok2 := roomNouns [target ]; ok2 && ! strings .HasPrefix (targetDesc , ":" ) {
1654+ return target , targetDesc
1655+ }
1656+ } else {
1657+ return tn , desc
16641658 }
1665- return testNoun , desc
16661659 }
1667-
16681660 }
16691661
1670- // Switch ending of `y` to `ies`
1671- if newNoun [len (newNoun )- 1 :] == `y` {
1672-
1673- testNoun := newNoun [:len (newNoun )- 1 ] + `ies`
1674- if desc , ok := roomNouns [testNoun ]; ok { // `ies` instead of `y` at end
1675- if desc [0 :1 ] == `:` {
1676- return desc [1 :], roomNouns [desc [1 :]]
1662+ // "ies" -> "y"
1663+ if strings .HasSuffix (newNoun , "ies" ) {
1664+ tn := strings .TrimSuffix (newNoun , "ies" ) + "y"
1665+ if desc , ok := roomNouns [tn ]; ok {
1666+ if strings .HasPrefix (desc , ":" ) {
1667+ target := desc [1 :]
1668+ if targetDesc , ok2 := roomNouns [target ]; ok2 && ! strings .HasPrefix (targetDesc , ":" ) {
1669+ return target , targetDesc
1670+ }
1671+ } else {
1672+ return tn , desc
16771673 }
1678- return testNoun , desc
16791674 }
1680-
1681- }
1682-
1683- if len (newNoun ) < 3 {
1684- continue
16851675 }
1676+ }
16861677
1687- // Strip 'es' such as 'torches'
1688- if newNoun [len (newNoun )- 2 :] == `es` {
1689-
1690- testNoun := newNoun [:len (newNoun )- 2 ]
1691- if desc , ok := roomNouns [testNoun ]; ok {
1692- if desc [0 :1 ] == `:` {
1693- return desc [1 :], roomNouns [desc [1 :]]
1694- }
1695- return testNoun , desc
1696- }
1697-
1698- } else {
1699-
1700- testNoun := newNoun + `es`
1701- if desc , ok := roomNouns [testNoun ]; ok { // `es` at end
1702- if desc [0 :1 ] == `:` {
1703- return desc [1 :], roomNouns [desc [1 :]]
1678+ // Multi-word noun match
1679+ for full , desc := range roomNouns {
1680+ if strings .Contains (full , " " ) {
1681+ for _ , part := range testNouns {
1682+ if strings .Contains (full , part ) {
1683+ if strings .HasPrefix (desc , ":" ) {
1684+ target := desc [1 :]
1685+ if td , ok := roomNouns [target ]; ok && ! strings .HasPrefix (td , ":" ) {
1686+ return target , td
1687+ }
1688+ } else {
1689+ return full , desc
1690+ }
17041691 }
1705- return testNoun , desc
17061692 }
1707-
1708- }
1709-
1710- if len (newNoun ) < 4 {
1711- continue
17121693 }
1694+ }
17131695
1714- // Strip 'es' such as 'torches'
1715- if noun [len (newNoun )- 3 :] == `ies` {
1716-
1717- testNoun := newNoun [:len (newNoun )- 3 ] + `y`
1718- if desc , ok := roomNouns [testNoun ]; ok { // `y` instead of `ies` at end
1719- if desc [0 :1 ] == `:` {
1720- return desc [1 :], roomNouns [desc [1 :]]
1696+ // Single-word match for multi-word nouns
1697+ for full , desc := range roomNouns {
1698+ if ! strings .Contains (full , " " ) {
1699+ for _ , part := range testNouns {
1700+ if part == full {
1701+ if strings .HasPrefix (desc , ":" ) {
1702+ target := desc [1 :]
1703+ if td , ok := roomNouns [target ]; ok && ! strings .HasPrefix (td , ":" ) {
1704+ return target , td
1705+ }
1706+ } else {
1707+ return full , desc
1708+ }
17211709 }
1722- return testNoun , desc
17231710 }
1724-
17251711 }
1726-
17271712 }
17281713
1729- return `` , ``
1714+ return "" , ""
17301715}
17311716
17321717func (r * Room ) FindExitByName (exitNameSearch string ) (exitName string , exitRoomId int ) {
0 commit comments