Skip to content

Commit 36a8a78

Browse files
authored
Merge pull request #697 from distributive/main
Updated the name of the organisation
2 parents d524345 + 14ba267 commit 36a8a78

File tree

6 files changed

+165
-165
lines changed

6 files changed

+165
-165
lines changed
Lines changed: 156 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,156 @@
1-
{% extends '/layout.html.twig' %}
2-
3-
{% block title %}Ban Lists{% endblock %}
4-
5-
{% block body %}
6-
{% include '/Scripts/api.html.twig' %}
7-
{% include '/Scripts/panels.html.twig' %}
8-
<div class="container" id="banlists">
9-
<h1>{{ block('title') }}</h1>
10-
<div>
11-
<p>There are currently three official <a href="{{ path('formats') }}">formats</a> supported by NISEI: Startup, Standard, and Eternal. This page displays the ban lists for each.</p>
12-
<h2>Explanation</h2>
13-
<ul>
14-
<li><b>Banned:</b> You cannot include any copies of a banned card in your deck.</li>
15-
<li><b>Points:</b> Including any number of copies of a card with points in Eternal adds points to your deck. Eternal decks must have 7 points or fewer.</li>
16-
<li><b>Restricted (deprecated):</b> You may include up to a full playset of only one restricted card.</li>
17-
<li><b>Universal Influence (deprecated):</b> Cards with universal influence cost additional influence to include in a deck.</li>
18-
<li><b>Identity Influence Reduction (deprecated):</b> These cards reduce your identity's influence limit by 1 for each copy (to a minimum of 1).</li>
19-
</ul>
20-
<p>See <a href="https://nisei.net/players/supported-formats/">NISEI's Supported Formats page</a> for more information.</p>
21-
</div>
22-
<hr>
23-
<div id="restrictions-root" role="tabpanel" style="display: none;">
24-
<!-- Nav tabs -->
25-
<ul class="nav nav-pills nav-justified" role="tablist" style="margin-bottom:20px">
26-
<li role="presentation"><a href="#tab-pane-startup" role="tab" data-toggle="tab">Startup</a></li>
27-
<li role="presentation" class="active"><a href="#tab-pane-standard" role="tab" data-toggle="tab">Standard</a></li>
28-
<li role="presentation"><a href="#tab-pane-eternal" role="tab" data-toggle="tab">Eternal</a></li>
29-
</ul>
30-
<hr>
31-
<!-- Tab panes -->
32-
<div class="tab-content">
33-
<div role="tabpanel" class="tab-pane" id="tab-pane-startup"></div>
34-
<div role="tabpanel" class="tab-pane active" id="tab-pane-standard"></div>
35-
<div role="tabpanel" class="tab-pane" id="tab-pane-eternal"></div>
36-
</div>
37-
</div>
38-
39-
<noscript>
40-
<p class="text-center">Please enable JavaScript to view this page fully.</p>
41-
<hr>
42-
</noscript>
43-
</div>
44-
45-
<script>
46-
// Takes a list of cards and an object mapping integers to lists of card IDs
47-
// Returns a new object with the cards in place of their IDs
48-
function makeCardMap(cards, obj) {
49-
return Object.keys(obj).reduce(function(newObj, key) {
50-
newObj[key] = cards.filter(card => obj[key].includes(card.id));
51-
return newObj
52-
}, {});
53-
}
54-
55-
// Creates a list of cards with the given header
56-
function generateList(header, cards, pre='') {
57-
if (pre.length > 0) {
58-
pre = `<li>${pre}</li>`;
59-
}
60-
return cards.reduce((text, card) => {
61-
return text + `<li><a href="${cardToLatestPrintingLink(card)}">${card.attributes.title}</a></li>`;
62-
}, `<li><strong>${header}</strong><ul>${pre}`) + '</ul></li>';
63-
}
64-
65-
async function buildBanlistsView() {
66-
// Unhide the restrictions view (accounting for browsers with JS disabled)
67-
$('#restrictions-root').show();
68-
69-
// Add a temporary loading indicator
70-
$('.tab-pane').append(loading_icon);
71-
72-
// Load data from API
73-
const desiredFormats = ['startup', 'standard', 'eternal'];
74-
const [formats, cards, restrictions] = await Promise.all([
75-
fetchData(`{{ v3_api_url }}/api/v3/public/formats`).then(fs => fs.filter(f => desiredFormats.includes(f.id))),
76-
fetchCards(`?include=card_subtypes&filter[search]=in_restriction:true`, 250).then(splitBySide),
77-
fetchData(`{{ v3_api_url }}/api/v3/public/restrictions?sort=-date_start`)
78-
]);
79-
80-
// Remove the loading indicator
81-
$('.temp-loading').remove();
82-
83-
// Add each format to the page
84-
formats.forEach(f => {
85-
const jqPane = $(`#tab-pane-${f.id}`);
86-
const formatRestrictions = restrictions.filter(r => f.attributes.restriction_ids.includes(r.id));
87-
if (formatRestrictions.length == 0) {
88-
jqPane.append(`<p>No cards are currently banned in ${f.attributes.name}. Have a blast!</p>`);
89-
} else {
90-
const panelList = new PanelList(jqPane, null, false, "toggle", "search");
91-
formatRestrictions.forEach(r => {
92-
const active = r.id == f.attributes.active_restriction_id;
93-
const visible = active || r.id == formatRestrictions[0].id;
94-
95-
// Create panel
96-
const panel = panelList.createPanel(r.id, visible);
97-
panel.addHeader(r.attributes.name);
98-
panel.addSubheader(`<a href=${Routing.generate('cards_find', {type:'find', 'view':'list', 'q':`b!${r.id.replaceAll('_', '-')}`})}>${r.attributes.size} cards</a>. Start Date: ${r.attributes.date_start}.`);
99-
100-
// Get content data
101-
const v = r.attributes.verdicts;
102-
// Lists (bans, restricted cards, global penalty cards)
103-
const [corpBan, runnerBan] = cards.map(cs => cs.filter(card => v.banned?.includes(card.id)));
104-
const [corpRes, runnerRes] = cards.map(cs => cs.filter(card => v.restricted?.includes(card.id)));
105-
const [corpPen, runnerPen] = cards.map(cs => cs.filter(card => v.global_penalty?.includes(card.id)));
106-
// Mappings (points, universal faction costs)
107-
const [corpUFC, runnerUFC] = cards.map(cs => makeCardMap(cs, v.universal_faction_cost));
108-
const [corpPts, runnerPts] = cards.map(cs => makeCardMap(cs, v.points));
109-
110-
// Add body
111-
panel.addBody();
112-
panel.addBodyContent(`<div class="container-fluid"><div class="row flex-fill"><div class="col-md-6"><h3>Corp Cards</h3><ul class="corp"></ul></div><div class="col-md-6"><h3>Runner Cards</h3><ul class="runner"></ul></div></div></div>`);
113-
114-
// Generate corp restrictions
115-
const jqCorp = panel.body.find('ul.corp');
116-
// Bans (banned subtypes (i.e. currents) are removed beforehand to reduce length)
117-
if (corpBan.length > 0) {
118-
if (r.attributes.banned_subtypes.length > 0) { // NOTE: currently hardcoded to only be currents
119-
const pre = `All cards with the <strong><a href="${Routing.generate('cards_find', {type:'find', 'view':'list', 'q':'s:current d:corp'})}">Current</a></strong> subtype.`;
120-
jqCorp.append(generateList('Banned', removeCurrents(corpBan), pre));
121-
} else {
122-
jqCorp.append(generateList('Banned', corpBan));
123-
}
124-
}
125-
// The others
126-
if (corpRes.length > 0) { jqCorp.append(generateList('Restricted', corpRes)); }
127-
Object.keys(corpUFC).sort().reverse().forEach(p => { jqCorp.append(generateList(`+${p} Universal Influence`, corpUFC[p])); });
128-
if (corpPen.length > 0) { jqCorp.append(generateList('Identity Influence Reduction', corpPen)); }
129-
Object.keys(corpPts).sort().reverse().forEach(p => { jqCorp.append(generateList(`${p} ${p == 1 ? 'Point' : 'Points'}`, corpPts[p])); });
130-
131-
// Generate runner restrictions
132-
const jqRunner = panel.body.find('ul.runner');
133-
// Bans (banned subtypes (i.e. currents) are removed beforehand to reduce length)
134-
if (runnerBan.length > 0) {
135-
if (r.attributes.banned_subtypes.length > 0) { // NOTE: currently hardcoded to only be currents
136-
const pre = `All cards with the <strong><a href="${Routing.generate('cards_find', {type:'find', 'view':'list', 'q':'s:current d:runner'})}">Current</a></strong> subtype.`;
137-
jqRunner.append(generateList('Banned', removeCurrents(runnerBan), pre));
138-
} else {
139-
jqRunner.append(generateList('Banned', runnerBan));
140-
}
141-
}
142-
// The others
143-
if (runnerRes.length > 0) { jqRunner.append(generateList('Restricted', runnerRes)); }
144-
Object.keys(runnerUFC).sort().reverse().forEach(p => { jqRunner.append(generateList(`+${p} Universal Influence`, runnerUFC[p])); });
145-
if (runnerPen.length > 0) { jqRunner.append(generateList('Identity Influence Reduction', runnerPen)); }
146-
Object.keys(runnerPts).sort().reverse().forEach(p => { jqRunner.append(generateList(`${p} ${p == 1 ? 'Point' : 'Points'}`, runnerPts[p])); });
147-
});
148-
}
149-
});
150-
}
151-
152-
// Create the banlists view on load
153-
buildBanlistsView();
154-
</script>
155-
156-
{% endblock %}
1+
{% extends '/layout.html.twig' %}
2+
3+
{% block title %}Ban Lists{% endblock %}
4+
5+
{% block body %}
6+
{% include '/Scripts/api.html.twig' %}
7+
{% include '/Scripts/panels.html.twig' %}
8+
<div class="container" id="banlists">
9+
<h1>{{ block('title') }}</h1>
10+
<div>
11+
<p>There are currently three official <a href="{{ path('formats') }}">formats</a> supported by Null Signal Games: Startup, Standard, and Eternal. This page displays the ban lists for each.</p>
12+
<h2>Explanation</h2>
13+
<ul>
14+
<li><b>Banned:</b> You cannot include any copies of a banned card in your deck.</li>
15+
<li><b>Points:</b> Including any number of copies of a card with points in Eternal adds points to your deck. Eternal decks must have 7 points or fewer.</li>
16+
<li><b>Restricted (deprecated):</b> You may include up to a full playset of only one restricted card.</li>
17+
<li><b>Universal Influence (deprecated):</b> Cards with universal influence cost additional influence to include in a deck.</li>
18+
<li><b>Identity Influence Reduction (deprecated):</b> These cards reduce your identity's influence limit by 1 for each copy (to a minimum of 1).</li>
19+
</ul>
20+
<p>See <a href="https://nullsignal.games/players/supported-formats/">Null Signal Games' Supported Formats page</a> for more information.</p>
21+
</div>
22+
<hr>
23+
<div id="restrictions-root" role="tabpanel" style="display: none;">
24+
<!-- Nav tabs -->
25+
<ul class="nav nav-pills nav-justified" role="tablist" style="margin-bottom:20px">
26+
<li role="presentation"><a href="#tab-pane-startup" role="tab" data-toggle="tab">Startup</a></li>
27+
<li role="presentation" class="active"><a href="#tab-pane-standard" role="tab" data-toggle="tab">Standard</a></li>
28+
<li role="presentation"><a href="#tab-pane-eternal" role="tab" data-toggle="tab">Eternal</a></li>
29+
</ul>
30+
<hr>
31+
<!-- Tab panes -->
32+
<div class="tab-content">
33+
<div role="tabpanel" class="tab-pane" id="tab-pane-startup"></div>
34+
<div role="tabpanel" class="tab-pane active" id="tab-pane-standard"></div>
35+
<div role="tabpanel" class="tab-pane" id="tab-pane-eternal"></div>
36+
</div>
37+
</div>
38+
39+
<noscript>
40+
<p class="text-center">Please enable JavaScript to view this page fully.</p>
41+
<hr>
42+
</noscript>
43+
</div>
44+
45+
<script>
46+
// Takes a list of cards and an object mapping integers to lists of card IDs
47+
// Returns a new object with the cards in place of their IDs
48+
function makeCardMap(cards, obj) {
49+
return Object.keys(obj).reduce(function(newObj, key) {
50+
newObj[key] = cards.filter(card => obj[key].includes(card.id));
51+
return newObj
52+
}, {});
53+
}
54+
55+
// Creates a list of cards with the given header
56+
function generateList(header, cards, pre='') {
57+
if (pre.length > 0) {
58+
pre = `<li>${pre}</li>`;
59+
}
60+
return cards.reduce((text, card) => {
61+
return text + `<li><a href="${cardToLatestPrintingLink(card)}">${card.attributes.title}</a></li>`;
62+
}, `<li><strong>${header}</strong><ul>${pre}`) + '</ul></li>';
63+
}
64+
65+
async function buildBanlistsView() {
66+
// Unhide the restrictions view (accounting for browsers with JS disabled)
67+
$('#restrictions-root').show();
68+
69+
// Add a temporary loading indicator
70+
$('.tab-pane').append(loading_icon);
71+
72+
// Load data from API
73+
const desiredFormats = ['startup', 'standard', 'eternal'];
74+
const [formats, cards, restrictions] = await Promise.all([
75+
fetchData(`{{ v3_api_url }}/api/v3/public/formats`).then(fs => fs.filter(f => desiredFormats.includes(f.id))),
76+
fetchCards(`?include=card_subtypes&filter[search]=in_restriction:true`, 250).then(splitBySide),
77+
fetchData(`{{ v3_api_url }}/api/v3/public/restrictions?sort=-date_start`)
78+
]);
79+
80+
// Remove the loading indicator
81+
$('.temp-loading').remove();
82+
83+
// Add each format to the page
84+
formats.forEach(f => {
85+
const jqPane = $(`#tab-pane-${f.id}`);
86+
const formatRestrictions = restrictions.filter(r => f.attributes.restriction_ids.includes(r.id));
87+
if (formatRestrictions.length == 0) {
88+
jqPane.append(`<p>No cards are currently banned in ${f.attributes.name}. Have a blast!</p>`);
89+
} else {
90+
const panelList = new PanelList(jqPane, null, false, "toggle", "search");
91+
formatRestrictions.forEach(r => {
92+
const active = r.id == f.attributes.active_restriction_id;
93+
const visible = active || r.id == formatRestrictions[0].id;
94+
95+
// Create panel
96+
const panel = panelList.createPanel(r.id, visible);
97+
panel.addHeader(r.attributes.name);
98+
panel.addSubheader(`<a href=${Routing.generate('cards_find', {type:'find', 'view':'list', 'q':`b!${r.id.replaceAll('_', '-')}`})}>${r.attributes.size} cards</a>. Start Date: ${r.attributes.date_start}.`);
99+
100+
// Get content data
101+
const v = r.attributes.verdicts;
102+
// Lists (bans, restricted cards, global penalty cards)
103+
const [corpBan, runnerBan] = cards.map(cs => cs.filter(card => v.banned?.includes(card.id)));
104+
const [corpRes, runnerRes] = cards.map(cs => cs.filter(card => v.restricted?.includes(card.id)));
105+
const [corpPen, runnerPen] = cards.map(cs => cs.filter(card => v.global_penalty?.includes(card.id)));
106+
// Mappings (points, universal faction costs)
107+
const [corpUFC, runnerUFC] = cards.map(cs => makeCardMap(cs, v.universal_faction_cost));
108+
const [corpPts, runnerPts] = cards.map(cs => makeCardMap(cs, v.points));
109+
110+
// Add body
111+
panel.addBody();
112+
panel.addBodyContent(`<div class="container-fluid"><div class="row flex-fill"><div class="col-md-6"><h3>Corp Cards</h3><ul class="corp"></ul></div><div class="col-md-6"><h3>Runner Cards</h3><ul class="runner"></ul></div></div></div>`);
113+
114+
// Generate corp restrictions
115+
const jqCorp = panel.body.find('ul.corp');
116+
// Bans (banned subtypes (i.e. currents) are removed beforehand to reduce length)
117+
if (corpBan.length > 0) {
118+
if (r.attributes.banned_subtypes.length > 0) { // NOTE: currently hardcoded to only be currents
119+
const pre = `All cards with the <strong><a href="${Routing.generate('cards_find', {type:'find', 'view':'list', 'q':'s:current d:corp'})}">Current</a></strong> subtype.`;
120+
jqCorp.append(generateList('Banned', removeCurrents(corpBan), pre));
121+
} else {
122+
jqCorp.append(generateList('Banned', corpBan));
123+
}
124+
}
125+
// The others
126+
if (corpRes.length > 0) { jqCorp.append(generateList('Restricted', corpRes)); }
127+
Object.keys(corpUFC).sort().reverse().forEach(p => { jqCorp.append(generateList(`+${p} Universal Influence`, corpUFC[p])); });
128+
if (corpPen.length > 0) { jqCorp.append(generateList('Identity Influence Reduction', corpPen)); }
129+
Object.keys(corpPts).sort().reverse().forEach(p => { jqCorp.append(generateList(`${p} ${p == 1 ? 'Point' : 'Points'}`, corpPts[p])); });
130+
131+
// Generate runner restrictions
132+
const jqRunner = panel.body.find('ul.runner');
133+
// Bans (banned subtypes (i.e. currents) are removed beforehand to reduce length)
134+
if (runnerBan.length > 0) {
135+
if (r.attributes.banned_subtypes.length > 0) { // NOTE: currently hardcoded to only be currents
136+
const pre = `All cards with the <strong><a href="${Routing.generate('cards_find', {type:'find', 'view':'list', 'q':'s:current d:runner'})}">Current</a></strong> subtype.`;
137+
jqRunner.append(generateList('Banned', removeCurrents(runnerBan), pre));
138+
} else {
139+
jqRunner.append(generateList('Banned', runnerBan));
140+
}
141+
}
142+
// The others
143+
if (runnerRes.length > 0) { jqRunner.append(generateList('Restricted', runnerRes)); }
144+
Object.keys(runnerUFC).sort().reverse().forEach(p => { jqRunner.append(generateList(`+${p} Universal Influence`, runnerUFC[p])); });
145+
if (runnerPen.length > 0) { jqRunner.append(generateList('Identity Influence Reduction', runnerPen)); }
146+
Object.keys(runnerPts).sort().reverse().forEach(p => { jqRunner.append(generateList(`${p} ${p == 1 ? 'Point' : 'Points'}`, runnerPts[p])); });
147+
});
148+
}
149+
});
150+
}
151+
152+
// Create the banlists view on load
153+
buildBanlistsView();
154+
</script>
155+
156+
{% endblock %}

app/Resources/views/Default/donators.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<h1>The Gracious Donators</h1>
99
<p class="lead">NetrunnerDB wouldn't be the same without them. Many, many thanks.</p>
1010
<p>This website is ad-free due to the generous donations of our generous Patreon supporters. Thank you all! We are working on new supporter perks as of October 2021, so please stay tuned!</p>
11-
<p>To become a Donator and help run the site, you can use <a href="https://paypal.me/niseiproject">Paypal</a> or join the Project NISEI <a href="https://www.patreon.com/NISEI">Patreon</a>.</p>
11+
<p>To become a Donator and help run the site, you can use <a href="https://paypal.me/niseiproject">Paypal</a> or join the Null Signal Games <a href="https://www.patreon.com/NullSignalGames">Patreon</a>.</p>
1212
<ul>
1313
{% for donator in donators %}
1414
<li>

app/Resources/views/Formats/formats.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
<div class="row">
1414
<div class="col-sm-12">
15-
<h2>NISEI Supported Formats</h2>
15+
<h2>Null Signal Games' Supported Formats</h2>
1616
<p>Card Pools and links to deck searches legal in those formats.</p>
17-
<p>See <a href="https://nisei.net/players/supported-formats/">NISEI's Supported Formats page</a> for more information.</p>
17+
<p>See <a href="https://nullsignal.games/players/supported-formats/">Null Signal Games' Supported Formats page</a> for more information.</p>
1818
</div>
1919
</div>
2020

app/Resources/views/layout.html.twig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
</ul>
214214

215215
<p>
216-
Designed and built by <a href="//twitter.com/alsciende">@alsciende</a>. Maintained by <a href="http://nisei.net/">NISEI</a>.
216+
Designed and built by <a href="//twitter.com/alsciende">@alsciende</a>. Maintained by <a href="http://nullsignal.games/">Null Signal Games</a>.
217217
</p>
218218

219219
<p>
@@ -224,14 +224,14 @@
224224
You may contribute by giving money on <a href="https://paypal.me/niseiproject">Paypal</a>. (Please add a note with your username so that we can add you to the <a href="{{ path('donators') }}">Donators</a> list.)
225225
</p>
226226
<p>
227-
Alternatively, you can check out the Project NISEI <a href="https://www.patreon.com/join/NISEI">Patreon</a>.
228-
<a href="https://www.patreon.com/join/NISEI" class="patreon-button"><img src=" {{ asset('/become_a_patron_button.png') }} " height="40" alt="Become a Patron of NISEI!"/></a>
227+
Alternatively, you can check out the Null Signal Games <a href="https://www.patreon.com/join/NullSignalGames">Patreon</a>.
228+
<a href="https://www.patreon.com/join/NullSignalGames" class="patreon-button"><img src=" {{ asset('/become_a_patron_button.png') }} " height="40" alt="Become a Patron of Null Signal Games!"/></a>
229229
</ul>
230230

231231
</p>
232232

233233
<p style="color:#333">
234-
The information presented on this site about Android: Netrunner, both literal and graphical, is copyrighted by Fantasy Flight Games and/or NISEI.
234+
The information presented on this site about Android: Netrunner, both literal and graphical, is copyrighted by Fantasy Flight Games and/or Null Signal Games.
235235
</p>
236236
<p style="color:#333">
237237
This website is not produced, endorsed, supported, or affiliated with Fantasy Flight Games.

0 commit comments

Comments
 (0)