-
Notifications
You must be signed in to change notification settings - Fork 4
/
vellum-attack.js
128 lines (108 loc) · 2.83 KB
/
vellum-attack.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { LitElement, html, css } from 'lit-element'
import { averageDie } from './lib/monster.js'
class Attack extends LitElement {
static get styles() {
return css`
.attack-name {
font-weight: bold;
font-style: italic;
}
.attack-type {
font-style: italic;
}
ol.random-effects {
list-style: none;
padding: 0;
margin-bottom: 0;
}
.random-effects li {
text-indent: 1em;
margin-bottom: 0;
}
.effect-title {
font-style: italic;
}`
}
static get is() { return 'vellum-attack' }
static get properties() {
return {
name: String,
type: String,
bonus: String,
reach: String,
range: String,
target: String,
damage: String,
damageType: String,
notes: String,
limitedUsage: String,
effects: Array
}
}
static _attributeNameForProperty(name, options) {
const camel2Dash = name => name.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase()
return super._attributeNameForProperty(camel2Dash(name), options)
}
render() {
return html`
<p class="attack">
<span class="attack-name">${this.name}${this.limitedUsage ? html` (${this.limitedUsage})` : html``}.</span>
<span class="attack-description">
<span class="attack-type">${this.attackTypeDescription()}:</span>
${this.bonus} to hit,
${this.reachOrRange()},
${this.target}.
<em>Hit:</em> ${this.averageDamage()} (${this.damage}) ${this.damageType} damage${this.notes}.
</span>
</p>
${this.renderEffects()}`
}
renderEffects() {
let array = this.effects
if (array && !Array.isArray(array)) {
array = JSON.parse(this.effects)
}
return this.effects
? html`
<ol class="random-effects">
${array.sort(this.sortRandomEffects).map(effect => this.renderEffect(effect))}</li>
</ol>`
: html``
}
renderEffect(effect) {
return html`
<li>
<span class="effect-title">${effect.roll}. ${effect.name}.</span>
${effect.effect}
</li>`
}
attackTypeDescription() {
switch (this.type) {
case 'melee-attack':
return 'Melee Weapon Attack'
case 'ranged-attack':
return 'Ranged Weapon Attack'
case 'melee-or-ranged-attack':
return 'Melee or Ranged Weapon Attack'
}
}
reachOrRange() {
switch (this.type) {
case 'melee-attack':
return 'reach ' + this.reach
case 'ranged-attack':
return 'range ' + this.range
case 'melee-or-ranged-attack':
return 'reach ' + this.reach + ' or range ' + this.range
}
}
sortRandomEffects(a, b) {
if (a.roll < b.roll) return -1
if (a.roll > b.roll) return 1
return 0
}
averageDamage() {
return averageDie(this.damage)
}
}
customElements.define(Attack.is, Attack)