Adds a 3D compass to the statistics block. Unfortunately, this change removes...

Adds a 3D compass to the statistics block. Unfortunately, this change removes the health indicator, so that will need to be added as a 3d element.
parent 425e9ffb
......@@ -28,7 +28,6 @@ import Roguestar.Lib.Core2.Monster
import Roguestar.Lib.Core.Plane as Plane
import Roguestar.Lib.DB as DB
import Roguestar.Lib.Data.FacingData
import Roguestar.Lib.Data.FactionData
import Roguestar.Lib.Data.MonsterData
import Roguestar.Lib.Data.ReferenceTypes
import Roguestar.Lib.Data.TerrainData
......@@ -36,7 +35,6 @@ import Roguestar.Lib.Data.TravelData
import Roguestar.Lib.Graph
import Roguestar.Lib.Core2.Realization
import Roguestar.Lib.Logging
import Roguestar.Lib.PlaneVisibility
import Roguestar.Lib.Position as Position
import Roguestar.Lib.Time
import Roguestar.Lib.Utility.DetailedLocation
......@@ -221,12 +219,12 @@ resolveStepWithHolographicTrail facing monster_ref =
do when (not $ facing `elem` [North,South,East,West]) $
throwError $ DBError "resolveStepWithHolographicTrail: only allowed in the four NSEW directions"
move_outcome <- stepMonster facing monster_ref
let (plane_ref :: PlaneRef, position :: Position) = (standing_plane $ move_from move_outcome, standing_position $ move_from move_outcome)
old_terrain_type <- terrainAt plane_ref position
let (plane_ref :: PlaneRef, pos :: Position) = (standing_plane $ move_from move_outcome, standing_position $ move_from move_outcome)
old_terrain_type <- terrainAt plane_ref pos
return $ OutcomeWithEffect
move_outcome
(move_outcome,
if old_terrain_type `elem` difficult_terrains then Nothing else Just $ SetTerrainEffect position plane_ref ForceField)
if old_terrain_type `elem` difficult_terrains then Nothing else Just $ SetTerrainEffect pos plane_ref ForceField)
(getDuration move_outcome)
--------------------------------------------------------------------------------
......@@ -236,14 +234,11 @@ resolveStepWithHolographicTrail facing monster_ref =
resolveStepWithTemporalWeb :: (MonadRandom db, DBReadable db) => Facing -> MonsterRef -> db (OutcomeWithEffect MoveOutcome (MoveOutcome,Set.Set SlowMonsterEffect))
resolveStepWithTemporalWeb facing monster_ref =
do move_outcome <- stepMonster facing monster_ref
let (plane_ref :: PlaneRef, position :: Position) = (standing_plane $ move_from move_outcome, standing_position $ move_from move_outcome)
t <- getDuration move_outcome
faction <- getMonsterFaction monster_ref
(vobs :: [MonsterRef]) <- liftM (mapMaybe coerceReference) $ dbGetVisibleObjectsForFaction (const $ return True) faction plane_ref
me <- realizeMonsterM monster_ref
let slowByDistance :: Monster -> Monster -> SlowMonsterEffect
slowByDistance me enemy = SlowMonsterEffect (toReference enemy) $ t / fromInteger (Position.distanceBetweenSquared me enemy)
slows = Set.map (slowByDistance me) $ enemies me
let slowByDistance :: Monster -> SlowMonsterEffect
slowByDistance enemy = SlowMonsterEffect (toReference enemy) $ t / fromInteger (Position.distanceBetweenSquared me enemy)
slows = Set.map slowByDistance $ enemies me
return $ OutcomeWithEffect
move_outcome
(move_outcome, slows)
......
......@@ -6,7 +6,6 @@ module Roguestar.Lib.Core2.Monster
import Roguestar.Lib.Graph
import Roguestar.Lib.Data.FactionData
import Roguestar.Lib.Data.MonsterData
import qualified Data.Set as Set
-- | Monsters, other than this monster, on the same plane as this monster.
......@@ -17,9 +16,6 @@ comonsters m = Set.filter (/= m) $ monsters $ plane m
enemies :: Monster -> Set.Set Monster
enemies me = Set.filter (isEnemy me) $ comonsters me
instance GetFaction Monster where
getFaction = getFaction . monster_to_data
-- | True if two monsters are from enemy factions.
isEnemy :: Monster -> Monster -> Bool
isEnemy m1 m2 = (getFaction m1 /= getFaction m2)
......@@ -11,6 +11,7 @@ module Roguestar.Lib.Data.FacingData
where
import Roguestar.Lib.Position
import Data.Aeson
import Data.Ord
import Data.List
import qualified Data.ByteString.Char8 as B
......@@ -26,6 +27,9 @@ data Facing = North
| Here
deriving (Eq,Ord,Enum,Bounded,Read,Show)
instance ToJSON Facing where
toJSON = toJSON . show
-- |
-- Takes an abbreviation (n,e,sw, etc) and answers a facing.
-- The input string must be lower case.
......
--Data
{-# LANGUAGE OverloadedStrings #-}
module Roguestar.Lib.Data.MonsterData
(MonsterData(..),
MonsterTrait(..),
......@@ -15,7 +15,9 @@ module Roguestar.Lib.Data.MonsterData
import Roguestar.Lib.Data.PersistantData
import Data.Ratio
import qualified Data.Text as Text
import Data.Maybe
import Data.Aeson
import Roguestar.Lib.Data.FactionData
import Data.Monoid
import qualified Data.Map as Map
......@@ -67,6 +69,13 @@ data MonsterHealth = MonsterHealth {
creature_health :: Rational,
creature_max_health :: Integer }
instance ToJSON MonsterHealth where
toJSON health = object [
"absolute-health" .= creature_absolute_health health,
"absolute-damage" .= creature_absolute_damage health,
"fraction-health" .= (fromRational $ creature_health health :: Double),
"max-health" .= creature_max_health health ]
-- | The seven aptitudes.
data MonsterTrait =
Aggression
......
......@@ -11,6 +11,7 @@ import qualified Roguestar.Lib.Data.MonsterData as MonsterData
import Roguestar.Lib.Data.PlaneData as PlaneData
import Roguestar.Lib.Data.ReferenceTypes as References
import Roguestar.Lib.Position
import Roguestar.Lib.Data.FactionData
data Monster = Monster {
monster_to_reference :: References.MonsterRef,
......@@ -77,4 +78,7 @@ instance ToPosition Monster where
instance ToMultiPosition Monster where
toMultiPosition = toMultiPosition . toPosition
\ No newline at end of file
instance GetFaction Monster where
getFaction = getFaction . monster_to_data
......@@ -4,9 +4,7 @@ module Roguestar.Lib.Graph.TestExampleEntities
import qualified Roguestar.Lib.Data.ReferenceTypes as References
import Roguestar.Lib.Graph.Graph
import Roguestar.Lib.Graph.Classes
import qualified Data.Set as Set
import Test.HUnit
equestria :: Plane
equestria = Plane {
......
......@@ -409,26 +409,15 @@ generateMapContent_ player_state (width,height) (MapData visible_terrain visible
() | otherwise -> object [ "t" .= ' ' ]
in rendered_json
data StatsData = StatsData {
stats_health :: MonsterHealth,
stats_compass :: Facing }
createStatsBlock :: Handler App App [T.Text]
createStatsBlock :: Handler App App Aeson.Value
createStatsBlock =
do g <- getGame
stats <- oops $ liftIO $ perceiveSnapshot g $
oops $ liftIO $ perceiveSnapshot g $
do health <- myHealth
facing <- compass
return $ StatsData {
stats_health = health,
stats_compass = facing }
return $ [
T.concat ["Health: ",
T.pack $ show $ creature_absolute_health $ stats_health stats,
"/",
T.pack $ show $ creature_max_health $ stats_health stats],
T.concat ["Compass: ",
T.pack $ show $ stats_compass stats]]
return $ object [
"health" .= health,
"compass" .= facing ]
getValidControls :: Handler App App Aeson.Value
getValidControls =
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -5,8 +5,8 @@
<script src="/static/scripts/jquery.cookie-1.2.js" type="application/javascript"></script>
<script src="/static/scripts/jquery.xcolor-1.8.js" type="application/javascript"></script>
<script src="/static/themes/glass/style.js" type="application/javascript"></script>
</head>
<script src="/static/scripts/three.min.js" type="application/javascript"></script>
<script src="/static/webgl/webgl.js" type="application/javascript"></script>
</body>
</html>
......@@ -11,15 +11,31 @@
<div id="messagebox" class="roguebox">
{{#messages}}
<p>{{{text}}}</p>
<p>{{text}}</p>
{{/messages}}
</div>
<div id="controls" class="roguebox">
<div id="status-block" class="webgl-container">
{{#statsblock}}
<pre>{{{text}}}</pre>
<pre>
Health: {{#health}}{{absolute-health}}/{{max-health}}{{/health}}
Compass: {{compass}}
</pre>
<script class="webgl-payload" type="application/json">
{
"compass" : "{{compass}}"
{{#health}}
, "health" : {
"absolute-health" : {{absolute-health}},
"max-health" : {{max-health}}
}
{{/health}}
}
</script>
{{/statsblock}}
</div>
{{#controls}}
<form action="/play/move" method="post">
......
......@@ -13,15 +13,12 @@ $('document').ready(function() {
return false;
});
//When the user selects an action type, disable all but the four cardinal directions on the direction pad.
//Some action types can only be used in the four cardinal directions.
//If that action type is selected, disable all the other movement directions.
$("input[name=mode]").change( function() {
$(".diagonal-direction-button").prop("disabled", $(".four-directions:checked").size() > 0 );
});;
//Form buttons that need to be automatically submitted, possibly after a pause while we do an animation.
$('.autosubmit').hide();
$('.autosubmit-after-pause').hide();
//Set up user interface elements.
$('.roguestar-accordion').accordion( { heightStyle: "content", collapsible:true } );
$('.roguestar-tabs').tabs();
......@@ -31,6 +28,10 @@ $('document').ready(function() {
tooltipClass: "tooltip-box"
});
//Form buttons that need to be automatically submitted, possibly after a pause while we do an animation.
$('.autosubmit').hide();
$('.autosubmit-after-pause').hide();
setTimeout(
function() {
$('.autosubmit').submit();
......
var RSGL = {};
RSGL.GOLDEN_RATIO = 1.618;
RSGL.TAU = 2*Math.PI;
RSGL.DEFAULT_COMPASS = {
body : {
inner_diameter : 10,
inner_thickness : 1,
rim_diameter : 12,
rim_thickness : 1,
color : 0xffffff,
},
needle : {
needle_width : 1,
needle_length : 9,
color : 0xff0000,
}
};
RSGL.facingToRadians = function( str )
{
str = str.toLowerCase();
if( str === "north" )
return 0;
if( str === "northeast" )
return 1/8*RSGL.TAU;
if( str === "east" )
return 2/8*RSGL.TAU;
if( str === "southeast" )
return 3/8*RSGL.TAU;
if( str === "south" )
return 4/8*RSGL.TAU;
if( str === "southwest" )
return 5/8*RSGL.TAU;
if( str === "west" )
return 6/8*RSGL.TAU;
if( str === "northwest" )
return 7/8*RSGL.TAU;
return 0;
}
RSGL.createCompass = function( compass_description )
{
var compass_body = RSGL.createCompassBody( compass_description.body );
var compass_needle = RSGL.createCompassNeedle( compass_description.needle );
compass_needle.position.z = 0.1;
compass_needle.rotation.z = Math.PI;
return function(scene, environment) {
var animated_needle = new THREE.Object3D();
animated_needle.add(compass_needle);
animated_needle.applyMatrix(new THREE.Matrix4().makeRotationZ( -RSGL.facingToRadians( environment.payload.compass ) ) );
scene.add( compass_body );
scene.add( animated_needle );
};
}
RSGL.createCompassBody = function( compass_body_description )
{
//Unpacking the parameters as a way of documenting them:
var inner_thickness = compass_body_description.inner_thickness;
var inner_diameter = compass_body_description.inner_diameter;
var rim_diameter = compass_body_description.rim_diameter;
var rim_thickness = compass_body_description.rim_thickness;
var color = compass_body_description.color;
var pts = [
new THREE.Vector3(0, 0, -inner_thickness),
new THREE.Vector3(inner_diameter, 0, -inner_thickness),
new THREE.Vector3(rim_diameter, 0, 0),
new THREE.Vector3(rim_diameter, 0, rim_thickness),
new THREE.Vector3(inner_diameter, 0, rim_thickness),
new THREE.Vector3(inner_diameter, 0, 0),
new THREE.Vector3(0, 0, 0)
];
var geometry = new THREE.LatheGeometry( pts, 24 );
var material = new THREE.MeshPhongMaterial( { color: color, shading:THREE.FlatShading } );
var mesh = new THREE.Mesh( geometry, material );
return mesh;
}
RSGL.createCompassNeedle = function( needle_description ) {
//Unpacking the parameters as a way of documenting them:
var needle_width = needle_description.needle_width;
var needle_length = needle_description.needle_length;
var color = needle_description.color;
var needle_shape = new THREE.Shape();
needle_shape.moveTo( -needle_width,0 );
needle_shape.lineTo( needle_width, 0 );
needle_shape.lineTo( 0, needle_length );
needle_shape.lineTo( -needle_width, 0 );
var needle_geom = new THREE.ShapeGeometry( needle_shape );
return new THREE.Mesh( needle_geom, new THREE.MeshPhongMaterial( { color: 0xff0000 } ) );
}
RSGL.createCamera = function(width, height) {
var camera = new THREE.PerspectiveCamera(
65, //fov degrees
width/height, //aspect ratio
1, //near
100 //far
);
camera.position.set( 0, 20, 20/RSGL.GOLDEN_RATIO );
camera.up.set( 0, 0, 1 );
return function(scene, environment) {
camera.lookAt( scene.position );
return camera;
}
}
RSGL.createLighting = function() {
var sunlight = new THREE.SpotLight( 0xAAAA88 );
sunlight.position.set( -15, 0, 15 );
var skylight = new THREE.HemisphereLight( 0x666688, 0x663300 );
skylight.position.set(0,0,100);
return function( scene, environment ) {
scene.add( sunlight );
scene.add( skylight );
};
}
RSGL.initialize = function(container) {
var width = container.width();
var height = container.height();
if( height < width / 2 )
height = width / 2;
var environment = {
payload : JSON.parse(container.find('.webgl-payload').html() )};
console.log( "Payload is: " + JSON.stringify(environment) );
var renderer = new THREE.WebGLRenderer();
var scene = new THREE.Scene();
renderer.setSize(width, height);
container.replaceWith(renderer.domElement);
RSGL.createLighting()(scene, environment);
RSGL.createCompass( RSGL.DEFAULT_COMPASS )(scene, environment);
renderer.render( scene, RSGL.createCamera(width, height)(scene, environment) );
}
$('.webgl-container').each(function(i,container){ RSGL.initialize($(container)) });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment