diff --git a/server/src/log.rs b/server/src/log.rs index ccf163c..86567b0 100644 --- a/server/src/log.rs +++ b/server/src/log.rs @@ -142,9 +142,9 @@ fn format_cultural_influence_attempt_log_item( pub fn format_happiness_increase( player: &Player, player_name: &str, - happiness_increases: &IncreaseHappiness, + i: &IncreaseHappiness, ) -> String { - let happiness_increases = happiness_increases + let happiness_increases = i .happiness_increases .iter() .filter_map(|(position, steps)| { @@ -164,7 +164,8 @@ pub fn format_happiness_increase( }) .collect::>(); format!( - "{player_name} increased happiness in {}", + "{player_name} paid {} to increase happiness in {}", + i.payment, utils::format_list(&happiness_increases, "no city") ) } diff --git a/server/src/playing_actions.rs b/server/src/playing_actions.rs index a369b5c..69b8c94 100644 --- a/server/src/playing_actions.rs +++ b/server/src/playing_actions.rs @@ -497,7 +497,9 @@ pub(crate) fn increase_happiness(game: &mut Game, player_index: usize, i: Increa let cost = player .increase_happiness_cost(city, steps) .expect("Illegal action"); - assert!(steps > 0, "Illegal action"); + if steps == 0 { + continue; + } if city.mood_state == MoodState::Angry { angry_activations.push(city_position); } @@ -520,17 +522,14 @@ pub(crate) fn increase_happiness(game: &mut Game, player_index: usize, i: Increa } pub(crate) fn undo_increase_happiness(game: &mut Game, player_index: usize, i: IncreaseHappiness) { - let mut cost = 0; let player = &mut game.players[player_index]; for (city_position, steps) in i.happiness_increases { - let city = player.get_city(city_position).expect("Illegal action"); - cost += city.size() as u32 * steps; let city = player.get_city_mut(city_position).expect("Illegal action"); for _ in 0..steps { city.decrease_mood_state(); } } - player.gain_resources(ResourcePile::mood_tokens(cost)); + player.gain_resources(i.payment); if let Some(UndoContext::IncreaseHappiness { angry_activations }) = game.undo_context_stack.pop() diff --git a/server/tests/game_api_tests.rs b/server/tests/game_api_tests.rs index cd26f76..f23b9d3 100644 --- a/server/tests/game_api_tests.rs +++ b/server/tests/game_api_tests.rs @@ -715,6 +715,25 @@ fn test_increase_happiness_voting() { ); } +#[test] +fn test_increase_happiness_voting_rituals() { + test_action( + "increase_happiness_voting_rituals", + Action::Playing(Custom(CustomAction::VotingIncreaseHappiness( + playing_actions::IncreaseHappiness { + happiness_increases: vec![ + (Position::from_offset("C2"), 1), + (Position::from_offset("B3"), 2), + ], + payment: ResourcePile::new(1, 0, 1, 1, 1, 1, 0), + }, + ))), + 0, + true, + false, + ); +} + #[test] fn test_custom_action_forced_labor() { test_action( diff --git a/server/tests/test_games/increase_happiness.outcome.json b/server/tests/test_games/increase_happiness.outcome.json index 6fd5e7d..ff9e03e 100644 --- a/server/tests/test_games/increase_happiness.outcome.json +++ b/server/tests/test_games/increase_happiness.outcome.json @@ -369,7 +369,7 @@ "The game has started", "Age 1 has started", "Round 1/3", - "Player1 increased happiness in the city at C2 by 1 steps, making it Neutral and the city at B3 by 2 steps, making it Happy" + "Player1 paid 5 mood tokens to increase happiness in the city at C2 by 1 steps, making it Neutral and the city at B3 by 2 steps, making it Happy" ], "undo_limit": 0, "actions_left": 2, @@ -444,4 +444,4 @@ } } ] -} +} \ No newline at end of file diff --git a/server/tests/test_games/increase_happiness_voting.outcome.json b/server/tests/test_games/increase_happiness_voting.outcome.json index b8ccf31..55a8c68 100644 --- a/server/tests/test_games/increase_happiness_voting.outcome.json +++ b/server/tests/test_games/increase_happiness_voting.outcome.json @@ -348,30 +348,30 @@ "Playing": { "Custom": { "VotingIncreaseHappiness": { - "happiness_increases": [ - [ - "C2", - 1 + "happiness_increases": [ + [ + "C2", + 1 + ], + [ + "B3", + 2 + ] ], - [ - "B3", - 2 - ] - ], - "payment": { - "mood_tokens": 5 + "payment": { + "mood_tokens": 5 + } } } } } - } ], "action_log_index": 1, "log": [ "The game has started", "Age 1 has started", "Round 1/3", - "Player1 increased happiness in the city at C2 by 1 steps, making it Neutral and the city at B3 by 2 steps, making it Happy using Voting" + "Player1 paid 5 mood tokens to increase happiness in the city at C2 by 1 steps, making it Neutral and the city at B3 by 2 steps, making it Happy using Voting" ], "undo_limit": 0, "actions_left": 3, @@ -446,4 +446,4 @@ } } ] -} +} \ No newline at end of file diff --git a/server/tests/test_games/increase_happiness_voting_rituals.json b/server/tests/test_games/increase_happiness_voting_rituals.json new file mode 100644 index 0000000..3340d6a --- /dev/null +++ b/server/tests/test_games/increase_happiness_voting_rituals.json @@ -0,0 +1,419 @@ +{ + "state": "Playing", + "players": [ + { + "name": null, + "id": 0, + "resources": { + "food": 2, + "wood": 5, + "ore": 5, + "ideas": 5, + "gold": 5, + "mood_tokens": 9, + "culture_tokens": 9 + }, + "resource_limit": { + "food": 2, + "wood": 7, + "ore": 7, + "ideas": 7, + "gold": 7 + }, + "cities": [ + { + "city_pieces": { + "market": 1 + }, + "mood_state": "Happy", + "activations": 0, + "angry_activation": false, + "player_index": 0, + "position": "A1" + }, + { + "city_pieces": { + "academy": 1, + "port": 1 + }, + "mood_state": "Angry", + "activations": 6, + "angry_activation": true, + "player_index": 0, + "position": "C2", + "port_position": "C3" + }, + { + "city_pieces": { + "obelisk": 1, + "observatory": 1, + "fortress": 1, + "temple": 1 + }, + "mood_state": "Neutral", + "activations": 0, + "angry_activation": false, + "player_index": 0, + "position": "B1" + }, + { + "city_pieces": {}, + "mood_state": "Angry", + "activations": 4, + "angry_activation": true, + "player_index": 0, + "position": "B3" + } + ], + "units": [ + { + "player_index": 0, + "position": "C2", + "unit_type": "Infantry", + "id": 0 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Cavalry", + "id": 1, + "carrier_id": 7 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Elephant", + "id": 2, + "carrier_id": 7 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 3 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 4 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 5 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 6 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Ship", + "id": 7 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Ship", + "id": 8 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Ship", + "id": 9 + } + ], + "civilization": "test0", + "active_leader": null, + "available_leaders": [ + "Alexander", + "Kleopatra" + ], + "advances": [ + "Farming", + "Free Economy", + "Mining", + "Rituals", + "Voting" + ], + "unlocked_special_advance": [], + "wonders_build": [], + "game_event_tokens": 1, + "completed_objectives": [], + "captured_leaders": [], + "event_victory_points": 0.0, + "wonder_cards": [ + "Pyramids" + ], + "collect_options": [ + [ + "Mountain", + [ + { + "ore": 1 + } + ] + ], + [ + "Fertile", + [ + { + "food": 1 + } + ] + ], + [ + "Forest", + [ + { + "wood": 1 + } + ] + ] + ], + "next_unit_id": 10 + }, + { + "name": null, + "id": 1, + "resources": { + "food": 2, + "wood": 5, + "ore": 5, + "ideas": 5, + "gold": 5, + "mood_tokens": 9, + "culture_tokens": 9 + }, + "resource_limit": { + "food": 2, + "wood": 7, + "ore": 7, + "ideas": 7, + "gold": 7 + }, + "cities": [ + { + "city_pieces": {}, + "mood_state": "Angry", + "activations": 2, + "angry_activation": false, + "player_index": 1, + "position": "C1" + }, + { + "city_pieces": { + "port": 1 + }, + "mood_state": "Neutral", + "activations": 0, + "angry_activation": false, + "player_index": 1, + "position": "B2", + "port_position": "C3" + } + ], + "units": [ + { + "player_index": 1, + "position": "C1", + "unit_type": "Infantry", + "id": 0 + }, + { + "player_index": 1, + "position": "C1", + "unit_type": "Infantry", + "id": 1 + } + ], + "civilization": "test1", + "active_leader": null, + "available_leaders": [], + "advances": [ + "Farming", + "Mining" + ], + "unlocked_special_advance": [], + "wonders_build": [], + "game_event_tokens": 3, + "completed_objectives": [], + "captured_leaders": [], + "event_victory_points": 0.0, + "wonder_cards": [], + "collect_options": [ + [ + "Mountain", + [ + { + "ore": 1 + } + ] + ], + [ + "Fertile", + [ + { + "food": 1 + } + ] + ], + [ + "Forest", + [ + { + "wood": 1 + } + ] + ] + ], + "next_unit_id": 2 + } + ], + "map": { + "tiles": [ + [ + "A1", + "Fertile" + ], + [ + "A2", + "Water" + ], + [ + "A3", + { + "Exhausted": "Forest" + } + ], + [ + "A4", + "Mountain" + ], + [ + "B1", + "Mountain" + ], + [ + "B2", + "Forest" + ], + [ + "B3", + "Fertile" + ], + [ + "B4", + "Fertile" + ], + [ + "C1", + "Barren" + ], + [ + "C2", + "Forest" + ], + [ + "C3", + "Water" + ], + [ + "C4", + "Water" + ], + [ + "C5", + "Water" + ], + [ + "D1", + "Fertile" + ], + [ + "D2", + "Water" + ] + ] + }, + "starting_player_index": 0, + "current_player_index": 0, + "action_log": [], + "action_log_index": 0, + "log": [ + "The game has started", + "Age 1 has started", + "Round 1/3" + ], + "undo_limit": 0, + "actions_left": 3, + "successful_cultural_influence": false, + "round": 6, + "age": 1, + "messages": [ + "The game has started" + ], + "dice_roll_outcomes": [ + 1, + 1, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "rng": { + "seed": 234162992961072890508432380903651342097 + }, + "dice_roll_log": [], + "dropped_players": [], + "wonders_left": [], + "wonder_amount_left": 1, + "undo_context_stack": [ + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + } + ] +} diff --git a/server/tests/test_games/increase_happiness_voting_rituals.outcome.json b/server/tests/test_games/increase_happiness_voting_rituals.outcome.json new file mode 100644 index 0000000..08f6e34 --- /dev/null +++ b/server/tests/test_games/increase_happiness_voting_rituals.outcome.json @@ -0,0 +1,454 @@ +{ + "state": "Playing", + "players": [ + { + "name": null, + "id": 0, + "resources": { + "food": 1, + "wood": 5, + "ore": 4, + "ideas": 4, + "gold": 4, + "mood_tokens": 7, + "culture_tokens": 9 + }, + "resource_limit": { + "food": 2, + "wood": 7, + "ore": 7, + "ideas": 7, + "gold": 7 + }, + "cities": [ + { + "city_pieces": { + "market": 1 + }, + "mood_state": "Happy", + "activations": 0, + "angry_activation": false, + "player_index": 0, + "position": "A1" + }, + { + "city_pieces": { + "academy": 1, + "port": 1 + }, + "mood_state": "Neutral", + "activations": 6, + "angry_activation": false, + "player_index": 0, + "position": "C2", + "port_position": "C3" + }, + { + "city_pieces": { + "obelisk": 1, + "observatory": 1, + "fortress": 1, + "temple": 1 + }, + "mood_state": "Neutral", + "activations": 0, + "angry_activation": false, + "player_index": 0, + "position": "B1" + }, + { + "city_pieces": {}, + "mood_state": "Happy", + "activations": 4, + "angry_activation": false, + "player_index": 0, + "position": "B3" + } + ], + "units": [ + { + "player_index": 0, + "position": "C2", + "unit_type": "Infantry", + "id": 0 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Cavalry", + "id": 1, + "carrier_id": 7 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Elephant", + "id": 2, + "carrier_id": 7 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 3 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 4 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 5 + }, + { + "player_index": 0, + "position": "B3", + "unit_type": "Settler", + "id": 6 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Ship", + "id": 7 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Ship", + "id": 8 + }, + { + "player_index": 0, + "position": "C3", + "unit_type": "Ship", + "id": 9 + } + ], + "civilization": "test0", + "active_leader": null, + "available_leaders": [ + "Alexander", + "Kleopatra" + ], + "advances": [ + "Farming", + "Free Economy", + "Mining", + "Rituals", + "Voting" + ], + "unlocked_special_advance": [], + "wonders_build": [], + "game_event_tokens": 1, + "completed_objectives": [], + "captured_leaders": [], + "event_victory_points": 0.0, + "wonder_cards": [ + "Pyramids" + ], + "collect_options": [ + [ + "Mountain", + [ + { + "ore": 1 + } + ] + ], + [ + "Fertile", + [ + { + "food": 1 + } + ] + ], + [ + "Forest", + [ + { + "wood": 1 + } + ] + ] + ], + "next_unit_id": 10 + }, + { + "name": null, + "id": 1, + "resources": { + "food": 2, + "wood": 5, + "ore": 5, + "ideas": 5, + "gold": 5, + "mood_tokens": 9, + "culture_tokens": 9 + }, + "resource_limit": { + "food": 2, + "wood": 7, + "ore": 7, + "ideas": 7, + "gold": 7 + }, + "cities": [ + { + "city_pieces": {}, + "mood_state": "Angry", + "activations": 2, + "angry_activation": false, + "player_index": 1, + "position": "C1" + }, + { + "city_pieces": { + "port": 1 + }, + "mood_state": "Neutral", + "activations": 0, + "angry_activation": false, + "player_index": 1, + "position": "B2", + "port_position": "C3" + } + ], + "units": [ + { + "player_index": 1, + "position": "C1", + "unit_type": "Infantry", + "id": 0 + }, + { + "player_index": 1, + "position": "C1", + "unit_type": "Infantry", + "id": 1 + } + ], + "civilization": "test1", + "active_leader": null, + "available_leaders": [], + "advances": [ + "Farming", + "Mining" + ], + "unlocked_special_advance": [], + "wonders_build": [], + "game_event_tokens": 3, + "completed_objectives": [], + "captured_leaders": [], + "event_victory_points": 0.0, + "wonder_cards": [], + "collect_options": [ + [ + "Mountain", + [ + { + "ore": 1 + } + ] + ], + [ + "Fertile", + [ + { + "food": 1 + } + ] + ], + [ + "Forest", + [ + { + "wood": 1 + } + ] + ] + ], + "next_unit_id": 2 + } + ], + "map": { + "tiles": [ + [ + "A1", + "Fertile" + ], + [ + "A2", + "Water" + ], + [ + "A3", + { + "Exhausted": "Forest" + } + ], + [ + "A4", + "Mountain" + ], + [ + "B1", + "Mountain" + ], + [ + "B2", + "Forest" + ], + [ + "B3", + "Fertile" + ], + [ + "B4", + "Fertile" + ], + [ + "C1", + "Barren" + ], + [ + "C2", + "Forest" + ], + [ + "C3", + "Water" + ], + [ + "C4", + "Water" + ], + [ + "C5", + "Water" + ], + [ + "D1", + "Fertile" + ], + [ + "D2", + "Water" + ] + ] + }, + "starting_player_index": 0, + "current_player_index": 0, + "action_log": [ + { + "Playing": { + "Custom": { + "VotingIncreaseHappiness": { + "happiness_increases": [ + [ + "C2", + 1 + ], + [ + "B3", + 2 + ] + ], + "payment": { + "food": 1, + "ore": 1, + "ideas": 1, + "gold": 1, + "mood_tokens": 1 + } + } + } + } + } + ], + "action_log_index": 1, + "log": [ + "The game has started", + "Age 1 has started", + "Round 1/3", + "Player1 paid 1 food, 1 ore, 1 idea, 1 gold and 1 mood token to increase happiness in the city at C2 by 1 steps, making it Neutral and the city at B3 by 2 steps, making it Happy using Voting" + ], + "undo_limit": 0, + "actions_left": 3, + "successful_cultural_influence": false, + "round": 6, + "age": 1, + "messages": [ + "The game has started" + ], + "dice_roll_outcomes": [ + 1, + 1, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10 + ], + "rng": { + "seed": 234162992961072890508432380903651342097 + }, + "dice_roll_log": [], + "dropped_players": [], + "wonders_left": [], + "wonder_amount_left": 1, + "undo_context_stack": [ + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "Recruit": {} + }, + { + "IncreaseHappiness": { + "angry_activations": [ + "C2", + "B3" + ] + } + } + ] +}