mirror of
				https://github.com/bra1n/townsquare.git
				synced 2025-10-21 16:55:12 +00:00 
			
		
		
		
	allow selecting multiple characters (closes #77)
This commit is contained in:
		
							parent
							
								
									c3c753f5b3
								
							
						
					
					
						commit
						1c31de430a
					
				
					 1 changed files with 44 additions and 7 deletions
				
			
		| 
						 | 
					@ -7,16 +7,24 @@
 | 
				
			||||||
    <h3>Select the characters for {{ nonTravelers }} players:</h3>
 | 
					    <h3>Select the characters for {{ nonTravelers }} players:</h3>
 | 
				
			||||||
    <ul class="tokens" v-for="(teamRoles, team) in roleSelection" :key="team">
 | 
					    <ul class="tokens" v-for="(teamRoles, team) in roleSelection" :key="team">
 | 
				
			||||||
      <li class="count" :class="[team]">
 | 
					      <li class="count" :class="[team]">
 | 
				
			||||||
        {{ teamRoles.filter(role => role.selected).length }} /
 | 
					        {{ teamRoles.reduce((a, { selected }) => a + selected, 0) }} /
 | 
				
			||||||
        {{ game[nonTravelers - 5][team] }}
 | 
					        {{ game[nonTravelers - 5][team] }}
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
      <li
 | 
					      <li
 | 
				
			||||||
        v-for="role in teamRoles"
 | 
					        v-for="role in teamRoles"
 | 
				
			||||||
        :class="[role.team, role.selected ? 'selected' : '']"
 | 
					        :class="[role.team, role.selected ? 'selected' : '']"
 | 
				
			||||||
        :key="role.id"
 | 
					        :key="role.id"
 | 
				
			||||||
        @click="role.selected = !role.selected"
 | 
					        @click="role.selected = role.selected ? 0 : 1"
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <Token :role="role" />
 | 
					        <Token :role="role" />
 | 
				
			||||||
 | 
					        <div class="buttons">
 | 
				
			||||||
 | 
					          <font-awesome-icon
 | 
				
			||||||
 | 
					            icon="minus-circle"
 | 
				
			||||||
 | 
					            @click.stop="role.selected--"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					          <span>{{ role.selected > 1 ? "x" + role.selected : "" }}</span>
 | 
				
			||||||
 | 
					          <font-awesome-icon icon="plus-circle" @click.stop="role.selected++" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
    <div class="warning" v-if="hasSelectedSetupRoles">
 | 
					    <div class="warning" v-if="hasSelectedSetupRoles">
 | 
				
			||||||
| 
						 | 
					@ -64,7 +72,7 @@ export default {
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    selectedRoles: function() {
 | 
					    selectedRoles: function() {
 | 
				
			||||||
      return Object.values(this.roleSelection)
 | 
					      return Object.values(this.roleSelection)
 | 
				
			||||||
        .map(roles => roles.filter(role => role.selected).length)
 | 
					        .map(roles => roles.reduce((a, { selected }) => a + selected, 0))
 | 
				
			||||||
        .reduce((a, b) => a + b, 0);
 | 
					        .reduce((a, b) => a + b, 0);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    hasSelectedSetupRoles: function() {
 | 
					    hasSelectedSetupRoles: function() {
 | 
				
			||||||
| 
						 | 
					@ -84,7 +92,7 @@ export default {
 | 
				
			||||||
          this.$set(this.roleSelection, role.team, []);
 | 
					          this.$set(this.roleSelection, role.team, []);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.roleSelection[role.team].push(role);
 | 
					        this.roleSelection[role.team].push(role);
 | 
				
			||||||
        this.$set(role, "selected", false);
 | 
					        this.$set(role, "selected", 0);
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      delete this.roleSelection["traveler"];
 | 
					      delete this.roleSelection["traveler"];
 | 
				
			||||||
      const playerCount = Math.max(5, this.nonTravelers);
 | 
					      const playerCount = Math.max(5, this.nonTravelers);
 | 
				
			||||||
| 
						 | 
					@ -93,10 +101,10 @@ export default {
 | 
				
			||||||
        for (let x = 0; x < composition[team]; x++) {
 | 
					        for (let x = 0; x < composition[team]; x++) {
 | 
				
			||||||
          if (this.roleSelection[team]) {
 | 
					          if (this.roleSelection[team]) {
 | 
				
			||||||
            const available = this.roleSelection[team].filter(
 | 
					            const available = this.roleSelection[team].filter(
 | 
				
			||||||
              role => role.selected !== true
 | 
					              role => !role.selected
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            if (available.length) {
 | 
					            if (available.length) {
 | 
				
			||||||
              randomElement(available).selected = true;
 | 
					              randomElement(available).selected = 1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -106,7 +114,12 @@ export default {
 | 
				
			||||||
      if (this.selectedRoles <= this.nonTravelers && this.selectedRoles) {
 | 
					      if (this.selectedRoles <= this.nonTravelers && this.selectedRoles) {
 | 
				
			||||||
        // generate list of selected roles and randomize it
 | 
					        // generate list of selected roles and randomize it
 | 
				
			||||||
        const roles = Object.values(this.roleSelection)
 | 
					        const roles = Object.values(this.roleSelection)
 | 
				
			||||||
          .map(roles => roles.filter(role => role.selected))
 | 
					          .map(roles =>
 | 
				
			||||||
 | 
					            roles
 | 
				
			||||||
 | 
					              // duplicate roles selected more than once and filter unselected
 | 
				
			||||||
 | 
					              .reduce((a, r) => [...a, ...Array(r.selected).fill(r)], [])
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					          // flatten into a single array
 | 
				
			||||||
          .reduce((a, b) => [...a, ...b], [])
 | 
					          .reduce((a, b) => [...a, ...b], [])
 | 
				
			||||||
          .map(a => [Math.random(), a])
 | 
					          .map(a => [Math.random(), a])
 | 
				
			||||||
          .sort((a, b) => a[0] - b[0])
 | 
					          .sort((a, b) => a[0] - b[0])
 | 
				
			||||||
| 
						 | 
					@ -152,6 +165,9 @@ ul.tokens {
 | 
				
			||||||
    transition: all 250ms;
 | 
					    transition: all 250ms;
 | 
				
			||||||
    &.selected {
 | 
					    &.selected {
 | 
				
			||||||
      opacity: 1;
 | 
					      opacity: 1;
 | 
				
			||||||
 | 
					      .buttons {
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    &.townsfolk {
 | 
					    &.townsfolk {
 | 
				
			||||||
      box-shadow: 0 0 10px $townsfolk, 0 0 10px #004cff;
 | 
					      box-shadow: 0 0 10px $townsfolk, 0 0 10px #004cff;
 | 
				
			||||||
| 
						 | 
					@ -172,6 +188,27 @@ ul.tokens {
 | 
				
			||||||
      transform: scale(1.2);
 | 
					      transform: scale(1.2);
 | 
				
			||||||
      z-index: 10;
 | 
					      z-index: 10;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    .buttons {
 | 
				
			||||||
 | 
					      display: none;
 | 
				
			||||||
 | 
					      position: absolute;
 | 
				
			||||||
 | 
					      top: 95%;
 | 
				
			||||||
 | 
					      text-align: center;
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					      z-index: 30;
 | 
				
			||||||
 | 
					      font-weight: bold;
 | 
				
			||||||
 | 
					      filter: drop-shadow(0 0 5px rgba(0, 0, 0, 1));
 | 
				
			||||||
 | 
					      span {
 | 
				
			||||||
 | 
					        flex-grow: 1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      svg {
 | 
				
			||||||
 | 
					        opacity: 0.25;
 | 
				
			||||||
 | 
					        cursor: pointer;
 | 
				
			||||||
 | 
					        &:hover {
 | 
				
			||||||
 | 
					          opacity: 1;
 | 
				
			||||||
 | 
					          color: red;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  .count {
 | 
					  .count {
 | 
				
			||||||
    opacity: 1;
 | 
					    opacity: 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue