Skip to content

Commit

Permalink
Allow randomizing the Friends & Foes module
Browse files Browse the repository at this point in the history
As a quality of life thing I unified the player count controls between basic nemesis cards, banners, and the turn order deck, since I figured if you rolled friend foe and banners for 4 players then went to turn order, you were probably about to play a game with 4 players and a friend and foe. I didn't do that for mages since drawing more mages than players is already a thing (e.g. for expeditions).
  • Loading branch information
Torgen authored and on3iro committed Dec 11, 2024
1 parent df5cac1 commit 7965af2
Show file tree
Hide file tree
Showing 35 changed files with 431 additions and 176 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

23 changes: 0 additions & 23 deletions src/Redux/Store/Randomizer/BasicNemesisCards/PlayerCount/types.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as types from 'aer-types/types'

import { ActionTypes } from './types'

import { PlayerCount } from '../PlayerCount/types'
import { PlayerCount } from 'aer-types/types/data'

export const actions = {
noOp: () => createAction('@@REDUX_LOOP/ENFORCE_DEFAULT_HANDLING'),
Expand Down
8 changes: 1 addition & 7 deletions src/Redux/Store/Randomizer/BasicNemesisCards/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import { combineReducers } from 'redux-loop'

import * as PlayerCount from './PlayerCount'
import * as RandomCards from './RandomCards'

export type State = {
PlayerCount: PlayerCount.State
RandomCards: RandomCards.State
}

export type Action = PlayerCount.Action | RandomCards.Action
export type Action = RandomCards.Action

export const selectors = {
PlayerCount: PlayerCount.selectors,
RandomCards: RandomCards.selectors,
}

export const actions = {
PlayerCount: PlayerCount.actions,
RandomCards: RandomCards.actions,
}

export const initialState = {
PlayerCount: PlayerCount.initialState,
RandomCards: RandomCards.initialState,
}

export const Reducer = combineReducers({
PlayerCount: PlayerCount.Reducer,
RandomCards: RandomCards.Reducer,
})
108 changes: 108 additions & 0 deletions src/Redux/Store/Randomizer/FriendFoe/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { createAction, ActionsUnion } from '@martin_hotell/rex-tils'
import { LoopReducer } from 'redux-loop'

import * as types from 'aer-types/types'

import { getRandomEntity, createIdList, createArrayWithDefaultValues } from 'Redux/helpers'
import { PlayerCount } from 'aer-types/types/data'

///////////
// STATE //
///////////

export type State = Readonly<{ friend?: string, foe?: string, banners?: string[] }>
export const initialState: State = {}

/////////////
// ACTIONS //
/////////////

export enum ActionTypes {
SET_RANDOM_FRIEND = 'FriendFoe/SET_RANDOM_FRIEND',
SET_RANDOM_FOE = 'FriendFoe/SET_RANDOM_FOE',
SET_RANDOM_BANNERS = 'FriendFoe/SET_RANDOM_BANNERS',
}

export const actions = {
noOp: () => createAction('@@REDUX_LOOP/ENFORCE_DEFAULT_HANDLING'),
setRandomFriend: (
availableFriends: ReadonlyArray<types.Friend>,
seed?: types.Seed
) =>
createAction(ActionTypes.SET_RANDOM_FRIEND, {
friend: getRandomEntity(availableFriends, seed),
}),
setRandomFoe: (
availableFoes: ReadonlyArray<types.Foe>,
seed?: types.Seed
) =>
createAction(ActionTypes.SET_RANDOM_FOE, {
foe: getRandomEntity(availableFoes, seed),
}),
setRandomBanners: (
availableBanners: ReadonlyArray<types.ICard>,
playerCount: PlayerCount,
seed?: types.Seed
) => {
const length = Math.min(availableBanners.length, playerCount + 2)
const slotList = createArrayWithDefaultValues(length, 'EMPTY')
const banners = createIdList(availableBanners.map((x: types.ICard) => x.id), slotList, getRandomEntity, seed).result
return createAction(ActionTypes.SET_RANDOM_BANNERS, { banners })
},
}

export type Action = ActionsUnion<typeof actions>

/////////////
// REDUCER //
/////////////

export const Reducer: LoopReducer<State, Action> = (
state: State = initialState,
action: Action
) => {
switch (action.type) {
case ActionTypes.SET_RANDOM_FRIEND: {
return {
...state,
friend: action.payload.friend.entity.id,
}
}
case ActionTypes.SET_RANDOM_FOE: {
return {
...state,
foe: action.payload.foe.entity.id,
}
}
case ActionTypes.SET_RANDOM_BANNERS: {
return {
...state,
banners: action.payload.banners
}
}

default: {
return state
}
}
}

///////////////
// SELECTORS //
///////////////

export type FriendFoeStateSlice = {
Randomizer: {
FriendFoe: State
}
}

const getFriend = (state: FriendFoeStateSlice) => state.Randomizer.FriendFoe.friend
const getFoe = (state: FriendFoeStateSlice) => state.Randomizer.FriendFoe.foe
const getBanners = (state: FriendFoeStateSlice) => state.Randomizer.FriendFoe.banners

export const selectors = {
getFriend,
getFoe,
getBanners,
}
7 changes: 7 additions & 0 deletions src/Redux/Store/Randomizer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,51 @@ import * as Nemesis from './Nemesis'
import * as BasicNemesisCards from './BasicNemesisCards'
import * as Mages from './Mages'
import * as Supply from './Supply'
import * as FriendFoe from './FriendFoe'

export type State = {
Nemesis: Nemesis.State
BasicNemesisCards: BasicNemesisCards.State
Mages: Mages.State
Supply: Supply.State
FriendFoe: FriendFoe.State
}

export const actions = {
Nemesis: Nemesis.actions,
BasicNemesisCards: BasicNemesisCards.actions,
Mages: Mages.actions,
Supply: Supply.actions,
FriendFoe: FriendFoe.actions
}

export const selectors = {
Nemesis: Nemesis.selectors,
BasicNemesisCards: BasicNemesisCards.selectors,
Mages: Mages.selectors,
Supply: Supply.selectors,
FriendFoe: FriendFoe.selectors,
}

export type Action =
| Nemesis.Action
| BasicNemesisCards.Action
| Mages.Action
| Supply.Action
| FriendFoe.Action

export const initialState = {
Nemesis: Nemesis.initialState,
BasicNemesisCards: BasicNemesisCards.initialState,
Mages: Mages.initialState,
Supply: Supply.initialState,
FriendFoe: FriendFoe.initialState
}

export const Reducer = combineReducers({
Nemesis: Nemesis.Reducer,
BasicNemesisCards: BasicNemesisCards.Reducer,
Mages: Mages.Reducer,
Supply: Supply.Reducer,
FriendFoe: FriendFoe.Reducer
})
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ export const toggle = (
state: State,
action: ReturnType<typeof actions.toggle>
) => {
console.log(state)
console.log(action)
const newState = state.includes(action.payload)
? state.filter((id) => id !== action.payload)
: [...state, action.payload]
Expand Down
2 changes: 0 additions & 2 deletions src/Redux/Store/Settings/Expansions/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ export const getContentByIdWithLanguageFallback = <T extends Entity>(
content: ContentStruct<T>,
id: string
) => {
console.log(id)
console.log(content)
// Just get the corresponding expansion id from the english version
const language = languages[content.ENG[id].expansion]

Expand Down
15 changes: 15 additions & 0 deletions src/Redux/Store/Settings/Expansions/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import * as Mages from './Mages'
import * as Treasures from './Treasures'
import * as BasicNemesisCards from './BasicNemesisCards'
import * as UpgradedBasicNemesisCards from './UpgradedBasicNemesisCards'
import * as Friends from './Friends'
import * as Foes from './Foes'
import * as Banners from './Banners'

// FIXME any typing sucks ;)
export const getSelectedEntitiesForSelectedExpansions = <T>(
Expand Down Expand Up @@ -122,3 +125,15 @@ export const getSelectedBasicNemesisCardIdsForSelectedExpansions = createSelecto
[getSelectedBasicNemesisCardsForSelectedExpansions],
(basicNemesisCards) => basicNemesisCards.map((card) => card.id)
)

export const getSelectedFriendsForSelectedExpansions = getSelectedEntitiesForSelectedExpansions(
Friends.selectors.getSelectedFriends
)

export const getSelectedFoesForSelectedExpansions = getSelectedEntitiesForSelectedExpansions(
Foes.selectors.getSelectedFoes
)

export const getSelectedBannersForSelectedExpansions = getSelectedEntitiesForSelectedExpansions(
Banners.selectors.getSelectedBanners
)
7 changes: 7 additions & 0 deletions src/Redux/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ export const createIdList = (
seed?: types.Seed
) => generateListFrom(availableIds, slots, getEntity, stringsEqual, seed)

export const createBannerList = (
availableBanners: ReadonlyArray<types.ICard>,
slots: Array<types.Slot>,
getEntity: types.SeededEntityGetter,
seed?: types.Seed
) => generateListFrom(availableBanners, slots, getEntity, entitiesEqual, seed)

/**
* Gets a random value from a list. (The wording of entities is just used for semantic context)
* @param availableEntities: List of entities to pick from
Expand Down
Loading

0 comments on commit 7965af2

Please sign in to comment.