New research and technology page
* Added legacyworlds-server-beans-technologies Maven module, including the player-level DAO and controller. * Added session classes to carry technology information, modified web client session façade accordingly * Various changes to common UI elements (forms, lists, etc...) so the start and end of some element can be drawn separately * Added controller, templates and JavaScript for research page
This commit is contained in:
parent
154f215e24
commit
6dcd59d7bc
45 changed files with 2314 additions and 178 deletions
legacyworlds-web-main
Content/Raw
WEB-INF/fm
en
fr
layout
css
js
src/main/java/com/deepclone/lw/web/main/game
|
@ -63,6 +63,9 @@
|
|||
<div class="button">
|
||||
<a href="map" title="Map of the universe">Map</a>
|
||||
</div>
|
||||
<div class="button">
|
||||
<a href="research" title="Manage research priorities, implement new technologies and browse known technologies">Research</a>
|
||||
</div>
|
||||
<div class="button">
|
||||
<a href="alliance" title="Alliance">Alliance</a>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<@page title="Empire">
|
||||
|
||||
<#assign ov = data.overview >
|
||||
<#assign rs = data.research >
|
||||
|
||||
<@tabs>
|
||||
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
<#--
|
||||
Macro that starts a research tab for one of the 3 existing modes
|
||||
|
||||
Parameters:
|
||||
curMode The tab to start: R for "in progress", P for pending, K for implemented
|
||||
-->
|
||||
<#macro startResearchTab curMode>
|
||||
<#switch curMode>
|
||||
|
||||
<#case 'R'>
|
||||
<@tabStart "research" "In progress" />
|
||||
<@rawFormStart "research-set-priorities" "form-priorities" "research" />
|
||||
<@listviewStart />
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=150>Category</@lv_column>
|
||||
<@lv_column width="x">Name</@lv_column>
|
||||
<@lv_column width=100 centered=true>Progress</@lv_column>
|
||||
<@lv_column width=150 centered=true>Priority</@lv_column>
|
||||
</@lv_line>
|
||||
<#break>
|
||||
|
||||
<#case 'P'>
|
||||
<@tabStart "pending" "Pending implementation" />
|
||||
<@listviewStart />
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=150>Category</@lv_column>
|
||||
<@lv_column width="x">Name</@lv_column>
|
||||
<@lv_column width=150 right=true>Cost</@lv_column>
|
||||
<@lv_column width=100 centered=true> </@lv_column>
|
||||
</@lv_line>
|
||||
<#break>
|
||||
|
||||
<#case 'K'>
|
||||
<@tabStart "implemented" "Implemented" />
|
||||
<@listviewStart />
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=150>Category</@lv_column>
|
||||
<@lv_column width="x">Name</@lv_column>
|
||||
</@lv_line>
|
||||
<#break>
|
||||
|
||||
</#switch>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that finishes a research tab depending on its type
|
||||
|
||||
Parameters:
|
||||
mode The type of tab that is being closed
|
||||
-->
|
||||
<#macro endResearchTab mode>
|
||||
<#switch mode>
|
||||
|
||||
<#case 'R'>
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width="x" colspan=4> </@lv_column>
|
||||
</@lv_line>
|
||||
<@lv_line>
|
||||
<@lv_column colspan=3> </@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<input type="submit" value="Update" class="input" style="margin: 15px 0 0 0" />
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
<@listviewEnd />
|
||||
</form>
|
||||
<#break>
|
||||
|
||||
<#case 'P'>
|
||||
<#case 'K'>
|
||||
<@listviewEnd />
|
||||
<#break>
|
||||
|
||||
</#switch>
|
||||
<@tabEnd />
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders an in-progress research entry
|
||||
|
||||
Parameters:
|
||||
entry the entry
|
||||
-->
|
||||
<#macro drawInProgressResearch entry>
|
||||
<@lv_line id="tl-${entry.identifier?xhtml}" class="tech-line">
|
||||
<@lv_column>${entry.category?xhtml}</@lv_column>
|
||||
<@lv_column>
|
||||
<#if entry.name?has_content>
|
||||
<strong>${entry.name?xhtml}</strong>
|
||||
<#else>
|
||||
Unknown technology
|
||||
</#if>
|
||||
</@lv_column>
|
||||
<@lv_column centered=true>${entry.completion} %</@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<select name="rp-${entry.identifier?xhtml}" class="input">
|
||||
<option style="padding: 0 5px" value="0" <#if entry.priority = 0>selected="selected"</#if>>lowest</option>
|
||||
<option style="padding: 0 5px" value="1" <#if entry.priority = 1>selected="selected"</#if>>low</option>
|
||||
<option style="padding: 0 5px" value="2" <#if entry.priority = 2>selected="selected"</#if>>normal</option>
|
||||
<option style="padding: 0 5px" value="3" <#if entry.priority = 3>selected="selected"</#if>>high</option>
|
||||
<option style="padding: 0 5px" value="4" <#if entry.priority = 4>selected="selected"</#if>>highest</option>
|
||||
</select>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders a pending technology
|
||||
|
||||
Parameters:
|
||||
entry the technology
|
||||
-->
|
||||
<#macro drawPendingTechnology entry>
|
||||
<@lv_line id="tl-${entry.identifier?xhtml}" class="tech-line">
|
||||
<@lv_column>${entry.category?xhtml}</@lv_column>
|
||||
<@lv_column>
|
||||
<strong>${entry.name?xhtml}</strong>
|
||||
</@lv_column>
|
||||
<@lv_column right=true>
|
||||
<strong>${entry.price?string(",##0")}</strong> <@abbr_bgc/>
|
||||
</@lv_column>
|
||||
<@lv_column right=true>
|
||||
<#if data.page.cash >= entry.price>
|
||||
<@rawFormStart "research-implement" "form-implement-${entry.identifier}" entry.identifier />
|
||||
<input type="hidden" name="technology" value="${entry.identifier?xhtml}" />
|
||||
<input type="submit" value="Implement" class="input" />
|
||||
</form>
|
||||
<#else>
|
||||
|
||||
</#if>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders an implemented technology
|
||||
|
||||
Parameters:
|
||||
entry the technology
|
||||
-->
|
||||
<#macro drawImplementedTechnology entry>
|
||||
<@lv_line id="tl-${entry.identifier?xhtml}" class="tech-line">
|
||||
<@lv_column>${entry.category?xhtml}</@lv_column>
|
||||
<@lv_column>
|
||||
<strong>${entry.name?xhtml}</strong>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders a single entry
|
||||
|
||||
Parameters:
|
||||
mode the current tab (see startResearchTab for details)
|
||||
entry the entry
|
||||
-->
|
||||
<#macro drawResearchEntry mode entry>
|
||||
<#switch mode>
|
||||
|
||||
<#case 'R'>
|
||||
<@drawInProgressResearch entry />
|
||||
<#break>
|
||||
|
||||
<#case 'P'>
|
||||
<@drawPendingTechnology entry />
|
||||
<#break>
|
||||
|
||||
<#case 'K'>
|
||||
<@drawImplementedTechnology entry />
|
||||
<#break>
|
||||
|
||||
</#switch>
|
||||
</#macro>
|
||||
<#--
|
||||
Render the visible part of the research page
|
||||
|
||||
Parameters:
|
||||
entries the sorted list of research entries
|
||||
-->
|
||||
<#macro renderResearchTabs entries>
|
||||
<#local prevMode = ''>
|
||||
|
||||
<@tabs>
|
||||
<#list entries as entry>
|
||||
|
||||
<#-- Determine type of entry to display -->
|
||||
<#if entry.implemented?has_content>
|
||||
<#if entry.implemented>
|
||||
<#local curMode = 'K'>
|
||||
<#else>
|
||||
<#local curMode = 'P'>
|
||||
</#if>
|
||||
<#else>
|
||||
<#local curMode = 'R'>
|
||||
</#if>
|
||||
|
||||
<#-- Start/end tabs -->
|
||||
<#if curMode != prevMode>
|
||||
<#if prevMode != ''>
|
||||
<@endResearchTab prevMode />
|
||||
</#if>
|
||||
<@startResearchTab curMode />
|
||||
<#local prevMode = curMode>
|
||||
</#if>
|
||||
|
||||
|
||||
<@drawResearchEntry curMode entry />
|
||||
|
||||
</#list>
|
||||
<@endResearchTab prevMode />
|
||||
</@tabs>
|
||||
</#macro>
|
||||
<#--
|
||||
Render all research information in a hidden layer which will be used by
|
||||
the client-side code to display more information.
|
||||
-->
|
||||
<#macro renderFullResearchData entries>
|
||||
<div style="display: none">
|
||||
<#list entries as tech>
|
||||
<div class="tech-description" id="tdesc-${tech.identifier?xhtml}">
|
||||
<h4><#if tech.name?has_content>${tech.name?xhtml}<#else>Unknown technology</#if></h4>
|
||||
<div class="tech-info"><strong>Category:</strong> ${tech.category?xhtml}</div>
|
||||
<#if tech.description?has_content><div class="tech-info">${tech.description?xhtml}</div></#if>
|
||||
<#if tech.price?has_content>
|
||||
<div class="tech-info"><strong>Implementation cost:</strong> ${tech.price?string(",##0")} <@abbr_bgc /></div>
|
||||
</#if>
|
||||
<#if tech.dependencies?has_content>
|
||||
<div class="tech-info"><strong>Depends on:</strong>
|
||||
<ul>
|
||||
<#list tech.dependencies as depId>
|
||||
<li class="dep">${depId}</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</div>
|
||||
</#if>
|
||||
<#if tech.reverseDependencies?has_content>
|
||||
<div class="tech-info"><strong>Required by:</strong>
|
||||
<ul>
|
||||
<#list tech.reverseDependencies as depId>
|
||||
<li class="dep">${depId}</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
</#list>
|
||||
</div>
|
||||
<script type="text/javascript" charset="utf-8" src="js/research.js"></script>
|
||||
</#macro>
|
||||
<#--
|
||||
Main research page
|
||||
-->
|
||||
<#macro render>
|
||||
<@page title="Research">
|
||||
|
||||
<#local entries = data.researchData>
|
||||
<@renderResearchTabs entries />
|
||||
<@renderFullResearchData entries />
|
||||
|
||||
</@page>
|
||||
</#macro>
|
|
@ -63,11 +63,14 @@
|
|||
<div class="button">
|
||||
<a href="map" title="Carte de l'univers">Carte</a>
|
||||
</div>
|
||||
<div class="button">
|
||||
<a href="research" title="Gestion des priorités de recherche, implémentation et visualisation de technologies">Recherche</a>
|
||||
</div>
|
||||
<div class="button">
|
||||
<a href="alliance" title="Alliance">Alliance</a>
|
||||
</div>
|
||||
<div class="button">
|
||||
<a href="enemies" title="Gèstion des listes de joueurs et alliances ennemis">Listes d'ennemis</a>
|
||||
<a href="enemies" title="Gestion des listes de joueurs et alliances ennemis">Listes d'ennemis</a>
|
||||
</div>
|
||||
<div class="button">
|
||||
<a href="messages" title="Messages">Messages</a>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<@page title="Empire">
|
||||
|
||||
<#assign ov = data.overview >
|
||||
<#assign rs = data.research >
|
||||
|
||||
<@tabs>
|
||||
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
<#--
|
||||
Macro that starts a research tab for one of the 3 existing modes
|
||||
|
||||
Parameters:
|
||||
curMode The tab to start: R for "in progress", P for pending, K for implemented
|
||||
-->
|
||||
<#macro startResearchTab curMode>
|
||||
<#switch curMode>
|
||||
|
||||
<#case 'R'>
|
||||
<@tabStart "research" "En cours" />
|
||||
<@rawFormStart "research-set-priorities" "form-priorities" "research" />
|
||||
<@listviewStart />
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=150>Catégorie</@lv_column>
|
||||
<@lv_column width="x">Nom</@lv_column>
|
||||
<@lv_column width=100 centered=true>Progrès</@lv_column>
|
||||
<@lv_column width=150 centered=true>Priorité</@lv_column>
|
||||
</@lv_line>
|
||||
<#break>
|
||||
|
||||
<#case 'P'>
|
||||
<@tabStart "pending" "En attente" />
|
||||
<@listviewStart />
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=150>Catégorie</@lv_column>
|
||||
<@lv_column width="x">Nom</@lv_column>
|
||||
<@lv_column width=150 right=true>Coût</@lv_column>
|
||||
<@lv_column width=100 centered=true> </@lv_column>
|
||||
</@lv_line>
|
||||
<#break>
|
||||
|
||||
<#case 'K'>
|
||||
<@tabStart "implemented" "Recherchées" />
|
||||
<@listviewStart />
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=150>Catégorie</@lv_column>
|
||||
<@lv_column width="x">Nom</@lv_column>
|
||||
</@lv_line>
|
||||
<#break>
|
||||
|
||||
</#switch>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that finishes a research tab depending on its type
|
||||
|
||||
Parameters:
|
||||
mode The type of tab that is being closed
|
||||
-->
|
||||
<#macro endResearchTab mode>
|
||||
<#switch mode>
|
||||
|
||||
<#case 'R'>
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width="x" colspan=4> </@lv_column>
|
||||
</@lv_line>
|
||||
<@lv_line>
|
||||
<@lv_column colspan=3> </@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<input type="submit" value="Modifier" class="input" style="margin: 15px 0 0 0" />
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
<@listviewEnd />
|
||||
</form>
|
||||
<#break>
|
||||
|
||||
<#case 'P'>
|
||||
<#case 'K'>
|
||||
<@listviewEnd />
|
||||
<#break>
|
||||
|
||||
</#switch>
|
||||
<@tabEnd />
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders an in-progress research entry
|
||||
|
||||
Parameters:
|
||||
entry the entry
|
||||
-->
|
||||
<#macro drawInProgressResearch entry>
|
||||
<@lv_line id="tl-${entry.identifier?xhtml}" class="tech-line">
|
||||
<@lv_column>${entry.category?xhtml}</@lv_column>
|
||||
<@lv_column>
|
||||
<#if entry.name?has_content>
|
||||
<strong>${entry.name?xhtml}</strong>
|
||||
<#else>
|
||||
Technologie inconnue
|
||||
</#if>
|
||||
</@lv_column>
|
||||
<@lv_column centered=true>${entry.completion} %</@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<select name="rp-${entry.identifier?xhtml}" class="input">
|
||||
<option style="padding: 0 5px" value="0" <#if entry.priority = 0>selected="selected"</#if>>très basse</option>
|
||||
<option style="padding: 0 5px" value="1" <#if entry.priority = 1>selected="selected"</#if>>basse</option>
|
||||
<option style="padding: 0 5px" value="2" <#if entry.priority = 2>selected="selected"</#if>>normale</option>
|
||||
<option style="padding: 0 5px" value="3" <#if entry.priority = 3>selected="selected"</#if>>élevée</option>
|
||||
<option style="padding: 0 5px" value="4" <#if entry.priority = 4>selected="selected"</#if>>très élevée</option>
|
||||
</select>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders a pending technology
|
||||
|
||||
Parameters:
|
||||
entry the technology
|
||||
-->
|
||||
<#macro drawPendingTechnology entry>
|
||||
<@lv_line id="tl-${entry.identifier?xhtml}" class="tech-line">
|
||||
<@lv_column>${entry.category?xhtml}</@lv_column>
|
||||
<@lv_column>
|
||||
<strong>${entry.name?xhtml}</strong>
|
||||
</@lv_column>
|
||||
<@lv_column right=true>
|
||||
<strong>${entry.price?string(",##0")}</strong> <@abbr_bgc/>
|
||||
</@lv_column>
|
||||
<@lv_column right=true>
|
||||
<#if data.page.cash >= entry.price>
|
||||
<@rawFormStart "research-implement" "form-implement-${entry.identifier}" entry.identifier />
|
||||
<input type="hidden" name="technology" value="${entry.identifier?xhtml}" />
|
||||
<input type="submit" value="Implémenter" class="input" />
|
||||
</form>
|
||||
<#else>
|
||||
|
||||
</#if>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders an implemented technology
|
||||
|
||||
Parameters:
|
||||
entry the technology
|
||||
-->
|
||||
<#macro drawImplementedTechnology entry>
|
||||
<@lv_line id="tl-${entry.identifier?xhtml}" class="tech-line">
|
||||
<@lv_column>${entry.category?xhtml}</@lv_column>
|
||||
<@lv_column>
|
||||
<strong>${entry.name?xhtml}</strong>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
</#macro>
|
||||
<#--
|
||||
Macro that renders a single entry
|
||||
|
||||
Parameters:
|
||||
mode the current tab (see startResearchTab for details)
|
||||
entry the entry
|
||||
-->
|
||||
<#macro drawResearchEntry mode entry>
|
||||
<#switch mode>
|
||||
|
||||
<#case 'R'>
|
||||
<@drawInProgressResearch entry />
|
||||
<#break>
|
||||
|
||||
<#case 'P'>
|
||||
<@drawPendingTechnology entry />
|
||||
<#break>
|
||||
|
||||
<#case 'K'>
|
||||
<@drawImplementedTechnology entry />
|
||||
<#break>
|
||||
|
||||
</#switch>
|
||||
</#macro>
|
||||
<#--
|
||||
Render the visible part of the research page
|
||||
|
||||
Parameters:
|
||||
entries the sorted list of research entries
|
||||
-->
|
||||
<#macro renderResearchTabs entries>
|
||||
<#local prevMode = ''>
|
||||
|
||||
<@tabs>
|
||||
<#list entries as entry>
|
||||
|
||||
<#-- Determine type of entry to display -->
|
||||
<#if entry.implemented?has_content>
|
||||
<#if entry.implemented>
|
||||
<#local curMode = 'K'>
|
||||
<#else>
|
||||
<#local curMode = 'P'>
|
||||
</#if>
|
||||
<#else>
|
||||
<#local curMode = 'R'>
|
||||
</#if>
|
||||
|
||||
<#-- Start/end tabs -->
|
||||
<#if curMode != prevMode>
|
||||
<#if prevMode != ''>
|
||||
<@endResearchTab prevMode />
|
||||
</#if>
|
||||
<@startResearchTab curMode />
|
||||
<#local prevMode = curMode>
|
||||
</#if>
|
||||
|
||||
|
||||
<@drawResearchEntry curMode entry />
|
||||
|
||||
</#list>
|
||||
<@endResearchTab prevMode />
|
||||
</@tabs>
|
||||
</#macro>
|
||||
<#--
|
||||
Render all research information in a hidden layer which will be used by
|
||||
the client-side code to display more information.
|
||||
-->
|
||||
<#macro renderFullResearchData entries>
|
||||
<div style="display: none">
|
||||
<#list entries as tech>
|
||||
<div class="tech-description" id="tdesc-${tech.identifier?xhtml}">
|
||||
<h4><#if tech.name?has_content>${tech.name?xhtml}<#else>Technologie inconnue</#if></h4>
|
||||
<div class="tech-info"><strong>Catégorie:</strong> ${tech.category?xhtml}</div>
|
||||
<#if tech.description?has_content><div class="tech-info">${tech.description?xhtml}</div></#if>
|
||||
<#if tech.price?has_content>
|
||||
<div class="tech-info"><strong>Coût d'implémentation:</strong> ${tech.price?string(",##0")} <@abbr_bgc /></div>
|
||||
</#if>
|
||||
<#if tech.dependencies?has_content>
|
||||
<div class="tech-info"><strong>Requiert:</strong>
|
||||
<ul>
|
||||
<#list tech.dependencies as depId>
|
||||
<li class="dep">${depId}</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</div>
|
||||
</#if>
|
||||
<#if tech.reverseDependencies?has_content>
|
||||
<div class="tech-info"><strong>Requis par:</strong>
|
||||
<ul>
|
||||
<#list tech.reverseDependencies as depId>
|
||||
<li class="dep">${depId}</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
</#list>
|
||||
</div>
|
||||
<script type="text/javascript" charset="utf-8" src="js/research.js"></script>
|
||||
</#macro>
|
||||
<#--
|
||||
Main research page
|
||||
-->
|
||||
<#macro render>
|
||||
<@page title="Recherche">
|
||||
|
||||
<#local entries = data.researchData>
|
||||
<@renderResearchTabs entries />
|
||||
<@renderFullResearchData entries />
|
||||
|
||||
</@page>
|
||||
</#macro>
|
|
@ -1,12 +1,21 @@
|
|||
<#macro form action name="" hash="">
|
||||
<#macro rawFormStart action name="" hash="">
|
||||
<form action="${action?url}.action<#if hash != "">#${hash?url}</#if>" method="post">
|
||||
</#macro>
|
||||
<#macro formStart action name="" hash="">
|
||||
<div class="form-container">
|
||||
<form action="${action?url}.action<#if hash != "">#${hash?url}</#if>" method="post">
|
||||
<@rawFormStart action name hash />
|
||||
<table>
|
||||
<#nested>
|
||||
</#macro>
|
||||
<#macro formEnd>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</#macro>
|
||||
<#macro form action name="" hash="">
|
||||
<@formStart action name hash />
|
||||
<#nested>
|
||||
<@formEnd />
|
||||
</#macro>
|
||||
<#macro form_field_line label id>
|
||||
<tr class="form-field">
|
||||
<th><label for="ff-${id?xhtml}">${label?xhtml}:</label></th>
|
||||
|
|
|
@ -1,24 +1,30 @@
|
|||
<#macro listview>
|
||||
<#macro listviewStart>
|
||||
<table class="list-view">
|
||||
<#nested>
|
||||
</#macro>
|
||||
<#macro listviewEnd>
|
||||
</table>
|
||||
</#macro>
|
||||
<#macro listview>
|
||||
<@listviewStart />
|
||||
<#nested>
|
||||
<@listviewEnd />
|
||||
</#macro>
|
||||
<#macro lv_line headers=false class="">
|
||||
<tr<#if class != ""> class="${class}<#if headers>headers</#if>"<#elseif headers> class="headers"</#if>>
|
||||
<#macro lv_line headers=false class="" id="">
|
||||
<tr<#if class != ""> class="${class}<#if headers>headers</#if>"<#elseif headers> class="headers"</#if><#if id != ""> id="${id?xhtml}"</#if>>
|
||||
<#nested>
|
||||
</tr>
|
||||
</#macro>
|
||||
<#macro lv_column width=0 centered=false right=false colspan=0>
|
||||
<#macro lv_column width=0 centered=false right=false colspan=0 id="">
|
||||
<#if width?is_string>
|
||||
<th style="text-align: <#if centered>center<#elseif right>right<#else>left</#if>"<#if colspan gt 1> colspan="${colspan}"</#if>>
|
||||
<th style="text-align: <#if centered>center<#elseif right>right<#else>left</#if>"<#if colspan gt 1> colspan="${colspan}"</#if><#if id != ""> id="${id?xhtml}"</#if>>
|
||||
<#nested>
|
||||
</th>
|
||||
<#elseif width gt 0>
|
||||
<th style="width: ${width}px; text-align: <#if centered>center<#elseif right>right<#else>left</#if>"<#if colspan gt 1> colspan="${colspan}"</#if>>
|
||||
<th style="width: ${width}px; text-align: <#if centered>center<#elseif right>right<#else>left</#if>"<#if colspan gt 1> colspan="${colspan}"</#if><#if id != ""> id="${id?xhtml}"</#if>>
|
||||
<#nested>
|
||||
</th>
|
||||
<#else>
|
||||
<td style="text-align: <#if centered>center<#elseif right>right<#else>left</#if>"<#if colspan gt 1> colspan="${colspan}"</#if>>
|
||||
<td style="text-align: <#if centered>center<#elseif right>right<#else>left</#if>"<#if colspan gt 1> colspan="${colspan}"</#if><#if id != ""> id="${id?xhtml}"</#if>>
|
||||
<#nested>
|
||||
</td>
|
||||
</#if>
|
||||
|
|
|
@ -3,11 +3,17 @@
|
|||
<#nested>
|
||||
</div>
|
||||
</#macro>
|
||||
<#macro tab id title>
|
||||
<#macro tabStart id title>
|
||||
<div class="tab" id="${id?xhtml}">
|
||||
<h3>${title?xhtml}</h3>
|
||||
<div class="tab-contents">
|
||||
<#nested>
|
||||
</#macro>
|
||||
<#macro tabEnd>
|
||||
</div>
|
||||
</div>
|
||||
</#macro>
|
||||
<#macro tab id title>
|
||||
<@tabStart id title />
|
||||
<#nested>
|
||||
<@tabEnd />
|
||||
</#macro>
|
|
@ -266,10 +266,10 @@ div.button a:focus,div.button a:hover {
|
|||
|
||||
/* Forms */
|
||||
.form-container {
|
||||
width: -moz-calc( 100% - 128px );
|
||||
width: -webkit-calc( 100% - 128px );
|
||||
width: -o-calc( 100% - 128px );
|
||||
width: calc( 100% - 128px );
|
||||
width: -moz-calc(100% - 128px);
|
||||
width: -webkit-calc(100% - 128px);
|
||||
width: -o-calc(100% - 128px);
|
||||
width: calc(100% - 128px);
|
||||
margin: 0 64px;
|
||||
}
|
||||
|
||||
|
@ -304,10 +304,10 @@ div.button a:focus,div.button a:hover {
|
|||
padding: 5px 20px;
|
||||
}
|
||||
|
||||
.form-submit .input:hover , .form-submit .input:focus {
|
||||
.form-submit .input:hover,.form-submit .input:focus {
|
||||
padding: 5px 20px;
|
||||
border-color: #dfdfdf;
|
||||
background-color: rgba(127,127,127,0.6);
|
||||
background-color: rgba(127, 127, 127, 0.6);
|
||||
}
|
||||
|
||||
.form-extra td {
|
||||
|
@ -323,7 +323,7 @@ div.button a:focus,div.button a:hover {
|
|||
.form-error td {
|
||||
font-size: 11pt;
|
||||
color: white;
|
||||
background-color: rgba(255,0,0,0.4);
|
||||
background-color: rgba(255, 0, 0, 0.4);
|
||||
font-weight: bold;
|
||||
margin: 2px 0px;
|
||||
padding: 5px 10px;
|
||||
|
@ -334,7 +334,7 @@ div.button a:focus,div.button a:hover {
|
|||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #afafaf;
|
||||
background-color: rgba(63,63,63,0.6);
|
||||
background-color: rgba(63, 63, 63, 0.6);
|
||||
color: white;
|
||||
font-size: 10pt;
|
||||
margin: 1px 0px;
|
||||
|
@ -371,10 +371,10 @@ div.button a:focus,div.button a:hover {
|
|||
|
||||
/* List display */
|
||||
.list-view {
|
||||
width: -moz-calc( 100% - 64px );
|
||||
width: -webkit-calc( 100% - 64px );
|
||||
width: -o-calc( 100% - 64px );
|
||||
width: calc( 100% - 64px );
|
||||
width: -moz-calc(100% - 64px);
|
||||
width: -webkit-calc(100% - 64px);
|
||||
width: -o-calc(100% - 64px);
|
||||
width: calc(100% - 64px);
|
||||
margin: 0 32px 20px 32px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
@ -604,20 +604,20 @@ table.fleets-planet,table.fleets-moving {
|
|||
border: 1px solid white;
|
||||
border-collapse: collapse;
|
||||
margin: 0 0 20px 5px;
|
||||
width: -moz-calc( 100% - 20px );
|
||||
width: -webkit-calc( 100% - 20px );
|
||||
width: -o-calc( 100% - 20px );
|
||||
width: calc( 100% - 20px );
|
||||
width: -moz-calc(100% - 20px);
|
||||
width: -webkit-calc(100% - 20px);
|
||||
width: -o-calc(100% - 20px);
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
table.selected-fleets {
|
||||
border: 1px solid white;
|
||||
border-collapse: collapse;
|
||||
margin: 10px 0 20px 15px;
|
||||
width: -moz-calc( 100% - 30px );
|
||||
width: -webkit-calc( 100% - 30px );
|
||||
width: -o-calc( 100% - 30px );
|
||||
width: calc( 100% - 30px );
|
||||
width: -moz-calc(100% - 30px);
|
||||
width: -webkit-calc(100% - 30px);
|
||||
width: -o-calc(100% - 30px);
|
||||
width: calc(100% - 30px);
|
||||
}
|
||||
|
||||
table.fleets-planet td {
|
||||
|
@ -799,4 +799,20 @@ tr.alliance-msg * {
|
|||
|
||||
tr.empire-msg * {
|
||||
color: #afafaf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Research page
|
||||
*/
|
||||
.tech-line {
|
||||
height: 22px;
|
||||
}
|
||||
.tech-view h4 {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.tech-view .tech-info {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
.tech-line.selected, .tech-line.selected td {
|
||||
background-color: rgba(127, 127, 127, 0.25);
|
||||
}
|
87
legacyworlds-web-main/Content/Raw/js/research.js
Normal file
87
legacyworlds-web-main/Content/Raw/js/research.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
$(function() {
|
||||
|
||||
/* Replace dependency identifiers */
|
||||
$('.tech-info li.dep').each(
|
||||
function() {
|
||||
var _id = this.innerHTML;
|
||||
var _targetTitle = $('#tdesc-' + _id + ' h4');
|
||||
this.innerHTML = '';
|
||||
$('<a/>').attr('href', '#tl-' + _id)
|
||||
.append(_targetTitle.html()).appendTo($(this));
|
||||
});
|
||||
|
||||
/* Map entries to tabs */
|
||||
var _entries = {};
|
||||
var _tabs = {};
|
||||
$('.tech-line').each(
|
||||
function() {
|
||||
var _id = $(this).attr('id').replace(/^tl-/, '');
|
||||
var _tab = $(this).parents('.tab-contents').attr('id').replace(
|
||||
/^tabc-/, '');
|
||||
_entries[_id] = _tab;
|
||||
if (!_tabs[_tab]) {
|
||||
_tabs[_tab] = [];
|
||||
}
|
||||
_tabs[_tab].push(_id);
|
||||
});
|
||||
var _selected = {};
|
||||
for ( var _tab in _tabs) {
|
||||
_selected[_tab] = _tabs[_tab][0];
|
||||
$('#tl-' + _selected[_tab]).toggleClass('selected');
|
||||
}
|
||||
|
||||
/* Insert viewing area */
|
||||
var _viewingArea = $('<div/>').css({
|
||||
'float' : 'right',
|
||||
'width' : '300px',
|
||||
'position' : 'relative',
|
||||
}).attr('class', 'tech-view').prependTo($('#page-contents'));
|
||||
$('div.tabs').css({
|
||||
'margin-right' : '300px'
|
||||
});
|
||||
|
||||
/* When an entry is clicked, set contents of viewing area */
|
||||
var _displayed = '';
|
||||
$('.tech-line').click(function() {
|
||||
var _id = $(this).attr('id').replace(/^tl-/, '');
|
||||
if (_id == _displayed) {
|
||||
return;
|
||||
}
|
||||
_viewingArea.html($('#tdesc-' + _id).html());
|
||||
$('a', _viewingArea).click(function() {
|
||||
var _target = $(this).attr('href').replace(/^#tl-/, '');
|
||||
$('#tabb-' + _entries[_target]).click();
|
||||
$('#tl-' + _target).click();
|
||||
});
|
||||
if (_selected[_entries[_id]] != _id) {
|
||||
$('#tl-' + _selected[_entries[_id]]).toggleClass('selected');
|
||||
$(this).toggleClass('selected');
|
||||
_selected[_entries[_id]] = _id;
|
||||
}
|
||||
location.hash = '#tl-'+_id;
|
||||
return true;
|
||||
});
|
||||
|
||||
/* When a tab button is clicked, select the appropriate entry */
|
||||
$('.tab-buttons a').click(function() {
|
||||
var _id = $(this).attr('id').replace(/^tabb-/, '');
|
||||
var _tech = _selected[_id];
|
||||
$('#tl-' + _tech).click();
|
||||
});
|
||||
|
||||
(function() {
|
||||
var _current = location.hash;
|
||||
if (_current.match(/^#tl-/)) {
|
||||
_current = _current.replace(/#tl-/, '');
|
||||
} else if (_current.match(/^#/)) {
|
||||
_current = _selected[_current.replace(/^#/, '')];
|
||||
} else {
|
||||
for ( var _tab in _selected) {
|
||||
_current = _selected[_tab];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$('#tabb-' + _entries[_current]).click();
|
||||
$('#tl-' + _current).click();
|
||||
})();
|
||||
});
|
|
@ -10,7 +10,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
|
@ -73,21 +72,15 @@ public class OverviewPage
|
|||
|
||||
|
||||
/**
|
||||
* "Implement technology" command
|
||||
* Empire-wide mining settings update command
|
||||
*
|
||||
* <p>
|
||||
* This method is mapped to the technology implementation command URL.
|
||||
* This method is called when a command to update empire-wide mining settings is received.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
* @param language
|
||||
* the language from the session
|
||||
* @param model
|
||||
* the model
|
||||
* @param tech
|
||||
* the technology identifier
|
||||
*
|
||||
* @return the overview page rendering order
|
||||
* @return a redirection to the overview page's "economy" tab
|
||||
*
|
||||
* @throws SessionException
|
||||
* if some error occurs on the server
|
||||
|
@ -96,26 +89,8 @@ public class OverviewPage
|
|||
* @throws SessionMaintenanceException
|
||||
* if the game is under maintenance
|
||||
*/
|
||||
@RequestMapping( value = "/implement-{tech}.action" , method = RequestMethod.POST )
|
||||
public String implement( HttpServletRequest request , @ModelAttribute( "language" ) String language , Model model ,
|
||||
@PathVariable String tech )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
int techId;
|
||||
try {
|
||||
techId = Integer.parseInt( tech );
|
||||
} catch ( NumberFormatException e ) {
|
||||
return this.redirect( "overview" );
|
||||
}
|
||||
|
||||
PlayerSession pSession = this.getSession( PlayerSession.class , request );
|
||||
return this.render( model , "game" , language , "overview" , pSession.implementTechnology( techId ) );
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping( value = "/update-mining-settings.action" , method = RequestMethod.POST )
|
||||
public String updateMiningSettings( HttpServletRequest request , @ModelAttribute( "language" ) String language ,
|
||||
Model model )
|
||||
public String updateMiningSettings( HttpServletRequest request )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
Map< String , Integer > miningSettings = this.getMiningSettings( request );
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
package com.deepclone.lw.web.main.game;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
|
||||
import com.deepclone.lw.session.SessionException;
|
||||
import com.deepclone.lw.web.beans.intercept.SessionRequirement;
|
||||
import com.deepclone.lw.web.beans.session.SessionMaintenanceException;
|
||||
import com.deepclone.lw.web.beans.session.SessionServerException;
|
||||
import com.deepclone.lw.web.beans.view.PageControllerBase;
|
||||
import com.deepclone.lw.web.csess.PlayerSession;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Controller for the Research page
|
||||
*
|
||||
* <p>
|
||||
* This controller contains all URL handlers associated with the research page: viewing research
|
||||
* state, setting research priorities, and implementing technologies.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@Controller
|
||||
@SessionRequirement( value = true , redirectTo = "player-session" , subType = "game" )
|
||||
@SessionAttributes( "language" )
|
||||
public class ResearchPage
|
||||
extends PageControllerBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Research page view
|
||||
*
|
||||
* <p>
|
||||
* This method fetches all research information from the game server then requests the page
|
||||
* rendering.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
* @param language
|
||||
* the language from the session
|
||||
* @param model
|
||||
* the model
|
||||
*
|
||||
* @return the research page rendering information
|
||||
*
|
||||
* @throws SessionException
|
||||
* if some error occurs on the server
|
||||
* @throws SessionServerException
|
||||
* if the server is unreachable
|
||||
* @throws SessionMaintenanceException
|
||||
* if the game is under maintenance
|
||||
*/
|
||||
@RequestMapping( "/research" )
|
||||
public String view( HttpServletRequest request , @ModelAttribute( "language" ) String language , Model model )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
PlayerSession pSession = this.getSession( PlayerSession.class , request );
|
||||
return this.render( model , "game" , language , "research" , pSession.getResearch( ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Research priorities update command
|
||||
*
|
||||
* <p>
|
||||
* This method handles the research priorities update command, which is triggered when the
|
||||
* "Update" button is clicked on the "In progress" tab of the research page.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
*
|
||||
* @return a redirection to the research page's "in progress" tab
|
||||
*
|
||||
* @throws SessionException
|
||||
* if some error occurs on the server
|
||||
* @throws SessionServerException
|
||||
* if the server is unreachable
|
||||
* @throws SessionMaintenanceException
|
||||
* if the game is under maintenance
|
||||
*/
|
||||
@RequestMapping( value = "/research-set-priorities.action" , method = RequestMethod.POST )
|
||||
public String setPriorities( HttpServletRequest request )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
Map< String , Integer > priorities = this.getPriorities( request );
|
||||
if ( priorities != null ) {
|
||||
this.getSession( PlayerSession.class , request ).updateResearchPriorities( priorities );
|
||||
}
|
||||
return this.redirect( "research#research" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract research priorities from the HTTP request
|
||||
*
|
||||
* <p>
|
||||
* Look for all submitted fields that begin with "rp-" then try to extract their values into a
|
||||
* map that associates technology identifiers to priorities.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
*
|
||||
* @return the map containing the submitted priorities, or <code>null</code> if one of the
|
||||
* values was incorrect.
|
||||
*/
|
||||
private Map< String , Integer > getPriorities( HttpServletRequest request )
|
||||
{
|
||||
Map< String , Object > input = this.getInput( request );
|
||||
Map< String , Integer > priorities = new HashMap< String , Integer >( );
|
||||
for ( Entry< String , Object > entry : input.entrySet( ) ) {
|
||||
// Ignore items which are not priorities
|
||||
String name = entry.getKey( );
|
||||
if ( !name.startsWith( "rp-" ) ) {
|
||||
continue;
|
||||
}
|
||||
name = name.substring( 3 );
|
||||
|
||||
// Get values
|
||||
if ( ! ( entry.getValue( ) instanceof String[] ) ) {
|
||||
continue;
|
||||
}
|
||||
String[] values = (String[]) entry.getValue( );
|
||||
if ( values.length < 1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pre-validate them
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt( values[ 0 ] );
|
||||
} catch ( NumberFormatException e ) {
|
||||
value = -1;
|
||||
}
|
||||
if ( value < 0 || value > 4 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
priorities.put( name , value );
|
||||
}
|
||||
return priorities;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Technology implementation command
|
||||
*
|
||||
* <p>
|
||||
* This method handles the technology implementation command, which is triggered when the
|
||||
* "Implement" button is clicked on the "Pending" tab of the research page.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
* @param tech
|
||||
* the identifier of the technology
|
||||
*
|
||||
* @return a redirection to the research page's "Implemented" tab
|
||||
*
|
||||
* @throws SessionException
|
||||
* if some error occurs on the server
|
||||
* @throws SessionServerException
|
||||
* if the server is unreachable
|
||||
* @throws SessionMaintenanceException
|
||||
* if the game is under maintenance
|
||||
*/
|
||||
@RequestMapping( value = "/research-implement.action" , method = RequestMethod.POST )
|
||||
public String implement( HttpServletRequest request , @RequestParam( "technology" ) String technology )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
this.getSession( PlayerSession.class , request ).implementTechnology( technology );
|
||||
return this.redirect( "research#implemented" );
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue