• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FreeTrainの進化系を目指す


Commit MetaInfo

Revision21 (tree)
Time2014-06-29 22:56:11
Authorc477

Log Message

StructureSkin 構造物のスキンクラスの実装

Change Summary

Incremental Difference

--- trunk/core/contributions/graphics/OverrideTable.cs (revision 20)
+++ trunk/core/contributions/graphics/OverrideTable.cs (nonexistent)
@@ -1,24 +0,0 @@
1-using System;
2-using System.Collections.Generic;
3-using System.Text;
4-using System.Xml;
5-
6-namespace nft.contributions.graphics {
7- /// <summary>
8- /// 画像などのオーバライドテーブルを保持する
9- /// </summary>
10- /// 2014/03/02 現時点で未使用、破棄の方向
11- /// <typeparam name="Type"></typeparam>
12- public class OverrideTable<Type> {
13- public delegate Type ElementParser(XmlElement e);
14-
15- public void ParseXml(XmlElement e, ElementParser parser) {
16- }
17-
18- public Type this[DateTime datetime] {
19- get {
20- return default(Type);
21- }
22- }
23- }
24-}
--- trunk/core/contributions/graphics/CtbStructureSkin.cs (nonexistent)
+++ trunk/core/contributions/graphics/CtbStructureSkin.cs (revision 21)
@@ -0,0 +1,85 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using nft.framework.plugin;
5+using nft.framework;
6+using nft.core.structure;
7+using nft.framework.drawing;
8+using nft.core.view;
9+using nft.core.geometry;
10+using nft.util;
11+using System.Diagnostics;
12+using nft.core;
13+using System.Drawing;
14+using nft.core.graphics;
15+
16+
17+namespace nft.contributions.graphics {
18+ public class CtbStructureSkin : Contribution{
19+ protected ISiteDefiner site;
20+ protected ConditionedResource<TextureSrc>[] textures = new ConditionedResource<TextureSrc>[4];
21+ //protected
22+
23+ public static InterCardinalDirection ToDirection(int rotate_val) {
24+ // if the value is in between 1 to 4, it is recognized as multiplier to PI (1PI = 90degree).
25+ // if the value is greater than 4, it is recognized as a value in degree.
26+ if (Math.Abs(rotate_val) > 4) {
27+ // Normalize degree value into PI multiplier (form -3 to 3).
28+ rotate_val /= 90;
29+ rotate_val %= 4;
30+ }
31+ // Normalize negative multiplier to positive.
32+ if (rotate_val < 0) rotate_val += 4;
33+ // Now, rotate_val have been converted to one of the values {0,1,2,3}.
34+ InterCardinalDirection ret = Direction.GetInterCardinalDirectionByZeroBaseIndex(rotate_val);
35+ return ret;
36+ }
37+
38+ public CtbStructureSkin(Plugin owenr, ParamsReader reader)
39+ : base(owenr, reader) {
40+ site = ParseSite(reader);
41+ foreach (ParamsReader pr in reader["sprite"].Each) {
42+ string[] args = pr["rotation"].InnerTextOr("0").Split(',');
43+ ConditionedResource<TextureSrc> _texture
44+ = ConditionedResourceFactory.LoadAsConditiondResources<TextureSrc>(pr, new ResourceParser<TextureSrc>(ParseTexture));
45+ foreach (string arg in args) {
46+ int rotate = int.Parse(arg);
47+ InterCardinalDirection dir = CtbStructureSkin.ToDirection(rotate);
48+ textures[Direction.ToZeroBaseIndex(dir)] = _texture;
49+ }
50+ }
51+ }
52+
53+ protected virtual ISiteDefiner ParseSite(ParamsReader reader) {
54+ ParamsReader pr2 = reader["site"];
55+ return new BasicSiteDefiner(pr2);
56+ }
57+
58+ protected virtual TextureSrc ParseTexture(ParamsReader reader) {
59+ ParamsReader imageref = reader["image"]["ref"];
60+ if (imageref.IsNull) {
61+ throw new PluginXmlException(this, reader, "An 'ref' attribute under 'image' element is required.");
62+ }
63+ Rectangle rect = SiteDefiner.GetTextureRect(reader);
64+ CtbImageResource res = (CtbImageResource)GetOtherContribution(imageref.InnerText);
65+ return new TextureSrc(res, rect);
66+ }
67+
68+ public ISiteDefiner SiteDefiner {
69+ get {
70+ return site;
71+ }
72+ }
73+
74+ public ConditionedResource<TextureSrc>[] TextureSources {
75+ get {
76+ return textures;
77+ }
78+ }
79+
80+ public StructureSkin GetRotated(InterCardinalDirection view_upper) {
81+ return new StructureSkin(this, view_upper);
82+ }
83+
84+ }
85+}
--- trunk/core/debug/TestDirection.cs (revision 20)
+++ trunk/core/debug/TestDirection.cs (revision 21)
@@ -20,8 +20,8 @@
2020 foreach(Direction16 d in da)
2121 {
2222 Direction dir = Direction.Get(d);
23- Debug.Write(string.Format("{0}:c={1},ic={2},mj={3},",dir.Name,dir.IsCardinal,dir.IsInterCardinal,dir.IsMajor));
24- Debug.WriteLine(string.Format("opposite={0},left={1},left_q={2},right={3},right_q={4}",dir.Opposite.Name,dir.Left.Name,dir.LeftQuater.Name,dir.Right.Name,dir.RightQuater.Name));
23+ Debug.Write(string.Format("{0}:c={1},ic={2},mj={3},",dir.LocalizedName,dir.IsCardinal,dir.IsInterCardinal,dir.IsMajor));
24+ Debug.WriteLine(string.Format("opposite={0},left={1},left_q={2},right={3},right_q={4}",dir.Opposite.LocalizedName,dir.Left.LocalizedName,dir.LeftQuater.LocalizedName,dir.Right.LocalizedName,dir.RightQuater.LocalizedName));
2525 }
2626 Debug.WriteLine("--test2--");
2727 for(int i=0; i<da.Length; i++)
@@ -30,7 +30,7 @@
3030 {
3131 Direction d1 = (Direction16)da.GetValue(i);
3232 Direction d2 = (Direction16)da.GetValue(j);
33- Debug.Write(string.Format("{0}<->{1}:",d1.Name,d2.Name));
33+ Debug.Write(string.Format("{0}<->{1}:",d1.LocalizedName,d2.LocalizedName));
3434 Debug.WriteIf(d1==d2,"==,");
3535 Debug.WriteIf(d1.Equals(d2),"Equals,");
3636 Debug.WriteIf(d1.IsParallel(d2),"Parallel,");
--- trunk/core/core/geometry/Direction.cs (revision 20)
+++ trunk/core/core/geometry/Direction.cs (revision 21)
@@ -2,6 +2,7 @@
22 using System.Diagnostics;
33 using System.Drawing;
44 using System.Runtime.Serialization;
5+using System.Collections.Generic;
56
67 namespace nft.core.geometry {
78 /// <summary>
@@ -50,6 +51,7 @@
5051 public sealed class Direction : ISerializable {
5152 private static readonly string[] DirNames;
5253 private static readonly Direction[] directions;
54+ private static readonly Dictionary<string, Direction> aliasMap;
5355 // rearranged by clockwise rotation order
5456 private static readonly Direction16[] rotateMap = {
5557 Direction16.NORTH,Direction16.NORTHNORTHEAST,Direction16.NORTHEAST,Direction16.EASTNORTHEAST,
@@ -70,7 +72,7 @@
7072 directions[i] = new Direction((int)(Direction16)db.GetValue(i));
7173 angles[(int)rotateMap[i]] = i;
7274 }
73-
75+ aliasMap = PrepareNameAliases();
7476 }
7577
7678 private Direction(int idx) {
@@ -104,6 +106,10 @@
104106 return ((int)dir) - 4;
105107 }
106108
109+ public static InterCardinalDirection GetInterCardinalDirectionByZeroBaseIndex(int idx) {
110+ return (InterCardinalDirection)(idx + 4);
111+ }
112+
107113 /// <summary>
108114 /// index can parse to <code>Direction16</code>
109115 /// </summary>
@@ -126,13 +132,75 @@
126132 public static Direction WESTSOUTHWEST { get { return Get(Direction16.WESTSOUTHWEST); } }
127133 public static Direction NORTHNORTHWEST { get { return Get(Direction16.NORTHNORTHWEST); } }
128134
135+ public static Direction Parse(string s) {
136+ return aliasMap[s.ToUpper()];
137+ }
138+ private static Dictionary<string, Direction> PrepareNameAliases() {
139+ Dictionary<string, Direction> aliases = new Dictionary<string, Direction>((4 + 8 + 12) * 2);
140+ foreach(Direction4 d4 in Enum.GetValues(typeof(Direction4))){
141+ string nam = Enum.GetName(typeof(Direction4),d4);
142+ aliases.Add(nam, d4);
143+ aliases.Add(new String(nam[0],1), d4);
144+ }
145+ string[,] cardinal= new string[2,2]{{NORTH.Name,SOUTH.Name},{EAST.Name,WEST.Name}};
146+ for (int i = 0; i < 2; i++) {
147+ string cd1 = cardinal[0,i];
148+ for (int j = 0; j < 2; j++) {
149+ string cd2 = cardinal[1,j];
150+ //Intercardinal directions
151+ //NE,NW,SE,SW
152+ string nam2 = cd1 + cd2;
153+ Direction d8 = Get((Direction8)Enum.Parse(typeof(Direction8), nam2));
154+ aliases.Add(nam2, d8);
155+ aliases.Add(cd2+cd1, d8); // reverse order
156+ aliases.Add(new String(new char[] { cd1[0], cd2[0] }), d8); // first letter abbreviation
157+ aliases.Add(new String(new char[] { cd2[0], cd1[0] }), d8); // abbreviation reverse order
158+
159+ //minor directions
160+ //NNE,NNW,SSE,SSW
161+ string nam3a = cd1 + cd1 + cd2;
162+ Direction d16a = Get((Direction16)Enum.Parse(typeof(Direction16), nam3a));
163+ aliases.Add(nam3a, d16a);
164+ aliases.Add(cd2 + cd1 + cd1, d16a); // other order 1
165+ aliases.Add(cd1 + cd2 + cd1, d16a); // other order 2
166+ aliases.Add(new String(new char[] { cd1[0], cd1[0], cd2[0] }), d16a); // first letter abbreviation
167+ aliases.Add(new String(new char[] { cd2[0], cd1[0], cd1[0] }), d16a); // abbreviation other order 1
168+ aliases.Add(new String(new char[] { cd1[0], cd2[0], cd1[0] }), d16a); // abbreviation other order 2
169+ //minor directions
170+ //ENE,WNW,ESE,WSW
171+ string nam3b = cd2 + cd1 + cd2;
172+ Direction d16b = Get((Direction16)Enum.Parse(typeof(Direction16), nam3b));
173+ aliases.Add(nam3b, d16b);
174+ aliases.Add(cd2 + cd2 + cd1, d16b); // other order 1
175+ aliases.Add(cd1 + cd2 + cd2, d16b); // other order 2
176+ aliases.Add(new String(new char[] { cd2[0], cd1[0], cd2[0] }), d16b); // first letter abbreviation
177+ aliases.Add(new String(new char[] { cd2[0], cd2[0], cd1[0] }), d16b); // abbreviation other order 1
178+ aliases.Add(new String(new char[] { cd1[0], cd2[0], cd2[0] }), d16b); // abbreviation other order 2
179+ }
180+ }
181+#if DEBUG
182+ Debug.WriteLine("--------Direction alias mapping-------");
183+ foreach (KeyValuePair<string, Direction> pair in aliases) {
184+ Debug.WriteLine(pair.Key+" -> "+pair.Value.Name);
185+ }
186+ Debug.WriteLine("--------END OF LIST-------");
187+#endif
188+ return aliases;
189+ }
190+
129191 /// <summary>
130192 /// Displayable name in local language.
131193 /// </summary>
132- public string Name {
194+ public string LocalizedName {
133195 get { return DirNames[index]; }
134196 }
135197
198+ public string Name {
199+ get {
200+ return Enum.GetName(typeof(Direction16),(Direction16)this);
201+ }
202+ }
203+
136204 /// <summary>
137205 /// Returns true if the direction is one of N,E,S, or W.
138206 /// </summary>
--- trunk/core/core/structure/SiteDefiner.cs (nonexistent)
+++ trunk/core/core/structure/SiteDefiner.cs (revision 21)
@@ -0,0 +1,71 @@
1+using System;
2+using System.Drawing;
3+using nft.core.geometry;
4+using nft.framework;
5+using nft.util;
6+
7+namespace nft.core.structure
8+{
9+ public interface ISiteDefiner{
10+ Rectangle GetTextureRect(ParamsReader reader);
11+ ISiteDefiner GetRotated(InterCardinalDirection view_upper);
12+ }
13+
14+ [Serializable]
15+ public class BasicSiteDefiner : ISiteDefiner
16+ {
17+ static protected readonly string ORG_TOPLEFT = "top_left";
18+ static protected readonly string ORG_BOTTOMLEFT = "bottom_left";
19+ static protected readonly string ORG_VTX_LOWERLEFT = "vertex_lower_left";
20+ static protected readonly string ORG_VTX_LOWEST = "vertex_lowest";
21+
22+ private Size3D size;
23+ private InterCardinalDirection upper_dir;
24+ public BasicSiteDefiner(ParamsReader reader) {
25+ Init(reader);
26+ }
27+
28+ protected BasicSiteDefiner(Size3D sz) {
29+ size = sz;
30+ }
31+
32+ protected void Init(ParamsReader reader) {
33+ Size sz = StringParseUtil.CreateSize(reader["size"].InnerText);
34+ int height = int.Parse(reader["height"].InnerText);
35+ upper_dir = (InterCardinalDirection)Direction.Parse(reader["upper-direction"].InnerText).index;
36+ size = new Size3D(sz, height);
37+ }
38+
39+ public Rect3D Bounds {
40+ get {
41+ return new Rect3D(new Location(), size);
42+ }
43+ }
44+
45+ public Rectangle GetTextureRect(ParamsReader reader) {
46+ Size sz = size.ProjectionSize;
47+ ParamsReader orgin = reader["origin"];
48+ Point pt = StringParseUtil.CreatePoint(orgin.InnerText);
49+ String _as = orgin["as"].InnerTextOr(ORG_TOPLEFT);
50+ if (ORG_TOPLEFT.Equals(_as)) {
51+ // do nothing
52+ } else if (ORG_VTX_LOWEST.Equals(_as)) {
53+ pt.Y -= sz.Height;
54+ pt.X += size.sx;
55+ } else if (ORG_BOTTOMLEFT.Equals(_as)) {
56+ pt.Y -= sz.Height;
57+ } else if (ORG_VTX_LOWEST.Equals(_as)) {
58+ pt.Y -= (size.sz + size.sy / 2);
59+ }
60+ return new Rectangle(pt, sz);
61+ }
62+
63+ public ISiteDefiner GetRotated(InterCardinalDirection view_upper) {
64+ if (Direction.IsPerpendiculer(upper_dir, view_upper)) {
65+ return new BasicSiteDefiner(new Size3D(size.sy, size.sx, size.sz));
66+ } else {
67+ return new BasicSiteDefiner(size);
68+ }
69+ }
70+ }
71+}
--- trunk/core/core/graphics/IStructureSkin.cs (nonexistent)
+++ trunk/core/core/graphics/IStructureSkin.cs (revision 21)
@@ -0,0 +1,60 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using nft.framework.drawing;
5+using nft.core.view;
6+using nft.contributions.graphics;
7+using nft.core.structure;
8+using nft.core.geometry;
9+using nft.core.graphics;
10+using System.Drawing;
11+
12+namespace nft.core.graphics {
13+ public interface IStructureSkin {
14+ ITexture this[ISceneParams p] {
15+ get;
16+ }
17+
18+ CtbStructureSkin Contribution {
19+ get;
20+ }
21+
22+ ISiteDefiner SiteDefiner {
23+ get;
24+ }
25+ }
26+
27+ public class StructureSkin : IStructureSkin {
28+ private CtbStructureSkin contrib;
29+ private InterCardinalDirection view_upper;
30+
31+ public StructureSkin(CtbStructureSkin ctb, InterCardinalDirection upper) {
32+ this.contrib = ctb;
33+ this.view_upper = upper;
34+ }
35+
36+ public CtbStructureSkin Contribution {
37+ get {
38+ return contrib;
39+ }
40+ }
41+
42+ public virtual ITexture this[ISceneParams p] {
43+ get {
44+ int rot_idx = (int)view_upper;
45+ TextureSrc src = Contribution.TextureSources[rot_idx][p];
46+ GraphicManagerEx gm = GraphicManagerEx.GraphicManager;
47+ ResourceKey key = ResourceKey.CreateKey(Contribution, (ushort)rot_idx);
48+ ITexture tex = gm.CreateStaticTexture(key, src.ImageResource.Data[p].ImageSrc, src.Region);
49+ return tex;
50+ }
51+ }
52+
53+ public ISiteDefiner SiteDefiner {
54+ get {
55+ return Contribution.SiteDefiner;
56+ }
57+ }
58+
59+ }
60+}
--- trunk/core/core/graphics/TextureSrc.cs (nonexistent)
+++ trunk/core/core/graphics/TextureSrc.cs (revision 21)
@@ -0,0 +1,17 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using nft.contributions.graphics;
5+using System.Drawing;
6+
7+namespace nft.core.graphics {
8+ public class TextureSrc {
9+ public readonly CtbImageResource ImageResource;
10+ public readonly Rectangle Region;
11+
12+ public TextureSrc(CtbImageResource res, Rectangle rect) {
13+ this.ImageResource = res;
14+ this.Region = rect;
15+ }
16+ }
17+}
--- trunk/core/core/graphics/SkinLibrary.cs (nonexistent)
+++ trunk/core/core/graphics/SkinLibrary.cs (revision 21)
@@ -0,0 +1,9 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+
5+namespace nft.core.graphics {
6+ public class SkinLibrary {
7+
8+ }
9+}
--- trunk/framework/framework/plugin/Contribution.cs (revision 20)
+++ trunk/framework/framework/plugin/Contribution.cs (revision 21)
@@ -226,6 +226,19 @@
226226 }
227227 }
228228
229+ protected Contribution GetOtherContribution(string pathorid) {
230+ string id;
231+ int n = pathorid.IndexOf(PID_Sepalator);
232+ if (n == -1) {
233+ id = GenerateID(parent, pathorid);
234+ } else if(n==1 && pathorid[0]=='.'){
235+ id = GenerateID(parent, pathorid.Substring(2));
236+ } else{
237+ id = pathorid;
238+ }
239+ return PluginManager.theInstance.GetContribution(id);
240+ }
241+
229242 /// <summary>
230243 /// return true if specified class has 'PrimitiveContribution' Attribute.
231244 /// </summary>
--- trunk/TestLauncher/test/SomeTest.cs (revision 20)
+++ trunk/TestLauncher/test/SomeTest.cs (revision 21)
@@ -10,7 +10,6 @@
1010 {
1111 class SomeTest
1212 {
13-
1413 [TestEntry]
1514 static private bool TestConverter() {
1615 object o;
--- trunk/plugins/jp.sourceforge.c477.structures.sample01/plugin.xml (revision 20)
+++ trunk/plugins/jp.sourceforge.c477.structures.sample01/plugin.xml (revision 21)
@@ -9,28 +9,34 @@
99 <condition when="night" src="stationMDNDepart_n.bmp"/>
1010 </contribution>
1111
12- <contribution type="ignore" id="ModernDepartment01">
13- <group>デパート駅舎(土色:A)</group>
12+ <contribution type="StructureSkin" id="ModernDepartment01">
13+ <name>デパート駅舎(土色:A)</name>
1414 <price>18000</price>
15- <height>2</height>
16- <operationCost>500</operationCost>
15+ <operationCost>500</operationCost>
16+ <site upper-direction="NW">
17+ <height>2</height>
18+ <size>2,1</size>
19+ </site>
1720 <population>
1821 <class name="freetrain.contributions.population.ShopperPopulation"/>
1922 <base>200</base>
2023 </population>
21- <size>2,1</size>
22- <sprite origin=" 0, 0" offset="40">
24+ <sprite rotation="0">
2325 <image ref="pic.ModernDepartment" />
26+ <origin>0,0</origin>
2427 </sprite>
25- <sprite origin="48, 0" offset="32" opposite="true">
28+ <sprite rotation="90">
2629 <image ref="pic.ModernDepartment" />
30+ <origin>48,0</origin>
2731 </sprite>
28- <sprite origin="96, 0" offset="40">
32+ <sprite rotation="180">
2933 <image ref="pic.ModernDepartment" />
30- </sprite>
31- <sprite origin="144, 0" offset="32" opposite="true">
34+ <origin>96,0</origin>
35+ </sprite>
36+ <sprite rotation="270">
3237 <image ref="pic.ModernDepartment" />
33- </sprite>
38+ <origin>144,0</origin>
39+ </sprite>
3440 </contribution>
3541
3642 <contribution type="image" id="pic.ArbanShop">
@@ -38,23 +44,29 @@
3844 <condition when="night" src="station_shop_n.bmp"/>
3945 </contribution>
4046
41- <contribution type="ignore" id="ArbanShop01">
42- <group>都市近郊の駅舎</group>
47+ <contribution type="StructureSkin" id="ArbanShop01">
48+ <name>都市近郊の駅舎</name>
4349 <price>370</price>
44- <height>1</height>
45- <size>3,1</size>
46- <sprite origin=" 0,0" offset="32">
50+ <site upper-direction="NW">
51+ <height>1</height>
52+ <size>3,1</size>
53+ </site>
54+ <sprite rotation="0">
4755 <image ref="pic.ArbanShop" />
56+ <origin>0,0</origin>
4857 </sprite>
49- <sprite origin="64,0" offset="16" opposite="true">
58+ <sprite rotation="90">
5059 <image ref="pic.ArbanShop" />
51- </sprite>
52- <sprite origin="0,48" offset="32">
60+ <origin>64,0</origin>
61+ </sprite>
62+ <sprite rotation="180">
5363 <image ref="pic.ArbanShop" />
54- </sprite>
55- <sprite origin="64,48" offset="16" opposite="true">
64+ <origin>0,48</origin>
65+ </sprite>
66+ <sprite rotation="270">
5667 <image ref="pic.ArbanShop" />
57- </sprite>
68+ <origin>64,48</origin>
69+ </sprite>
5870 </contribution>
5971
6072 <contribution type="image" id="pic.LargeDome">
@@ -62,28 +74,34 @@
6274 <condition when="night" src="terminal_domeA_n.bmp"/>
6375 </contribution>
6476
65- <contribution type="ignore" id="LargeDome">
66- <group>空港国際線ターミナル</group>
77+ <contribution type="StructureSkin" id="LargeDome">
78+ <name>空港国際線ターミナル</name>
6779 <design>大型ドーム</design>
6880 <price>100000</price>
69- <size>8,3</size>
70- <height>2</height>
81+ <site upper-direction="NW">
82+ <size>8,3</size>
83+ <height>2</height>
84+ </site>
7185 <structure>
7286 <category byname="旅客ターミナル"/>
7387 </structure>
7488 <computerCannotBuild/>
75- <sprite origin="0,0" offset="80">
89+ <sprite rotation="0">
7690 <image ref="pic.LargeDome"/>
77- </sprite>
78- <sprite origin="176,0" offset="40" opposite="true">
91+ <origin>0,0</origin>
92+ </sprite>
93+ <sprite rotation="90">
7994 <image ref="pic.LargeDome"/>
80- </sprite>
81- <sprite origin="0,112" offset="80">
95+ <origin>176,0</origin>
96+ </sprite>
97+ <sprite rotation="180">
8298 <image ref="pic.LargeDome"/>
83- </sprite>
84- <sprite origin="176,112" offset="40" opposite="true">
99+ <origin>0,112</origin>
100+ </sprite>
101+ <sprite rotation="270">
85102 <image ref="pic.LargeDome"/>
86- </sprite>
103+ <origin>176,112</origin>
104+ </sprite>
87105 </contribution>
88106
89107 <contribution type="image" id="pic.AtractionWheel">
@@ -91,8 +109,8 @@
91109 <condition when="night" src="ampark_wheelL_n.bmp"/>
92110 </contribution>
93111
94- <contribution type="ignore" id="AmusementPark.Wheel">
95- <group>観覧車</group>
112+ <contribution type="StructureSkin" id="AmusementPark.Wheel">
113+ <name>観覧車</name>
96114 <design>大型</design>
97115 <structure>
98116 <category byname="遊園地"/>
@@ -102,15 +120,19 @@
102120 <class name="freetrain.contributions.population.ShopperPopulation"/>
103121 <base>200</base>
104122 </population>
105- <height>5</height>
106- <size>5,2</size>
123+ <site upper-direction="NW">
124+ <height>5</height>
125+ <size>5,2</size>
126+ </site>
107127 <computerCannotBuild/>
108- <sprite origin="0,0" offset="112">
128+ <sprite rotation="0,180">
109129 <image ref="pic.AtractionWheel"/>
110- </sprite>
111- <sprite origin="112,0" offset="88" opposite="true">
130+ <origin>0,0</origin>
131+ </sprite>
132+ <sprite rotation="90,270">
112133 <image ref="pic.AtractionWheel"/>
113- </sprite>
134+ <origin>112,0</origin>
135+ </sprite>
114136 </contribution>
115137
116138 <contribution type="image" id="pic.CableTower_L">
@@ -123,61 +145,75 @@
123145 <default src="tettou-s.bmp"/>
124146 </contribution>
125147
126- <contribution type="ignore" id="CableTower_L-1">
127- <group>高圧線鉄塔</group>
148+ <contribution type="StructureSkin" id="CableTower_L-1">
149+ <name>高圧線鉄塔</name>
128150 <structure>
129151 <category byname="送電線鉄塔"/>
130152 </structure>
131- <size>1,1</size>
132- <computerCannotBuild/>
133- <price>10</price>
134- <height>7</height>
135- <sprite origin="0,0" offset="96">
153+ <computerCannotBuild/>
154+ <price>10</price>
155+ <site upper-direction="NW">
156+ <size>1,1</size>
157+ <height>7</height>
158+ </site>
159+ <sprite rotation="0,180">
136160 <image ref="pic.CableTower_L"/>
137- </sprite>
138- <sprite origin="32,0" offset="96">
161+ <origin>0,0</origin>
162+ </sprite>
163+ <sprite rotation="90,270">
139164 <image ref="pic.CableTower_L"/>
140- </sprite>
165+ <origin>32,0</origin>
166+ </sprite>
141167 </contribution>
142168
143- <contribution type="ignore" id="CableTower_M-1">
144- <group>高圧線鉄塔</group>
169+ <contribution type="StructureSkin" id="CableTower_M-1">
170+ <name>高圧線鉄塔</name>
145171 <structure>
146172 <category byname="送電線鉄塔"/>
147173 </structure>
148- <size>1,1</size>
149- <computerCannotBuild/>
150- <price>8</price>
151- <height>6</height>
152- <sprite origin="0,0" offset="80">
174+ <site upper-direction="NW">
175+ <size>1,1</size>
176+ <height>6</height>
177+ </site>
178+ <computerCannotBuild/>
179+ <price>8</price>
180+ <sprite rotation="0,180">
153181 <image ref="pic.CableTower_M"/>
154- </sprite>
155- <sprite origin="32,0" offset="80">
182+ <origin>0,0</origin>
183+ </sprite>
184+ <sprite rotation="90,270">
156185 <image ref="pic.CableTower_M"/>
157- </sprite>
186+ <origin>32,0</origin>
187+ </sprite>
158188 </contribution>
159189
160- <contribution type="ignore" id="CableTower_S-1">
161- <group>高圧線鉄塔</group>
190+ <contribution type="StructureSkin" id="CableTower_S-1">
191+ <name>高圧線鉄塔</name>
162192 <structure>
163193 <category byname="送電線鉄塔"/>
164194 </structure>
165- <size>1,1</size>
166- <computerCannotBuild/>
167- <price>6</price>
168- <height>5</height>
169- <sprite origin="0,0" offset="64">
195+ <computerCannotBuild/>
196+ <price>6</price>
197+ <site upper-direction="NW">
198+ <size>1,1</size>
199+ <height>5</height>
200+ </site>
201+ <sprite rotation="0">
170202 <image ref="pic.CableTower_S"/>
171- </sprite>
172- <sprite origin="32,0" offset="64">
203+ <origin>0,0</origin>
204+ </sprite>
205+ <sprite rotation="90">
173206 <image ref="pic.CableTower_S"/>
174- </sprite>
175- <sprite origin="64,0" offset="64">
207+ <origin>32,0</origin>
208+ </sprite>
209+ <sprite rotation="180">
176210 <image ref="pic.CableTower_S"/>
177- </sprite>
178- <sprite origin="96,0" offset="64">
211+ <origin>64,0</origin>
212+ </sprite>
213+ <sprite rotation="270">
179214 <image ref="pic.CableTower_S"/>
180- </sprite>
215+ <origin>96,0</origin>
216+ </sprite>
181217 </contribution>
182218
183219 <contribution type="image" id="pic.Hospital_A">
@@ -189,7 +225,7 @@
189225 <condition when="night" src="gene_hospitalA3_n.bmp"/>
190226 </contribution>
191227
192- <contribution type="ignore" id="Hospital_A">
228+ <contribution type="StructureSkin" id="Hospital_A">
193229 <name>総合病院</name>
194230 <design>郊外型(主)</design>
195231 <structure>
@@ -196,22 +232,28 @@
196232 <category byname="病院"/>
197233 </structure>
198234 <price>32000</price>
199- <size>6,5</size>
200- <height>2</height>
201- <sprite origin="0,0" offset="72">
235+ <site upper-direction="NW">
236+ <size>6,5</size>
237+ <height>2</height>
238+ </site>
239+ <sprite rotation="0">
202240 <image ref="pic.Hospital_A"/>
203- </sprite>
204- <sprite origin="176,0" offset="64" opposite="true">
241+ <origin>0,0</origin>
242+ </sprite>
243+ <sprite rotation="90">
205244 <image ref="pic.Hospital_A"/>
206- </sprite>
207- <sprite origin="352,0" offset="72">
245+ <origin>176,0</origin>
246+ </sprite>
247+ <sprite rotation="180">
208248 <image ref="pic.Hospital_A"/>
209- </sprite>
210- <sprite origin="528,0" offset="64" opposite="true">
211- <image ref="pic.Hospital_A"/>
212- </sprite>
249+ <origin>352,0</origin>
250+ </sprite>
251+ <sprite rotation="270">
252+ <image ref="pic.Hospital_A"/>
253+ <origin>528,0</origin>
254+ </sprite>
213255 </contribution>
214- <contribution type="ignore" id="Hospital_B">
256+ <contribution type="StructureSkin" id="Hospital_B">
215257 <name>総合病院</name>
216258 <design>郊外型(副)</design>
217259 <structure>
@@ -218,20 +260,26 @@
218260 <category byname="病院"/>
219261 </structure>
220262 <price>32000</price>
221- <size>5,4</size>
222- <height>2</height>
223- <sprite origin="0,0" offset="64">
263+ <site upper-direction="NW">
264+ <size>5,4</size>
265+ <height>2</height>
266+ </site>
267+ <sprite rotation="0">
224268 <image ref="pic.Hospital_B"/>
225- </sprite>
226- <sprite origin="144,0" offset="56" opposite="true">
269+ <origin>0,0</origin>
270+ </sprite>
271+ <sprite rotation="90">
227272 <image ref="pic.Hospital_B"/>
228- </sprite>
229- <sprite origin="288,0" offset="64">
273+ <origin>144,0</origin>
274+ </sprite>
275+ <sprite rotation="180">
230276 <image ref="pic.Hospital_B"/>
231- </sprite>
232- <sprite origin="432,0" offset="56" opposite="true">
277+ <origin>288,0</origin>
278+ </sprite>
279+ <sprite rotation="270">
233280 <image ref="pic.Hospital_B"/>
234- </sprite>
281+ <origin>432,0</origin>
282+ </sprite>
235283 </contribution>
236284
237285
@@ -261,8 +309,8 @@
261309 </contribution>
262310
263311 <!-- 01 -->
264- <contribution type="ignore" id="CampusBuilding-01">
265- <group>大学</group>
312+ <contribution type="StructureSkin" id="CampusBuilding-01">
313+ <name>大学</name>
266314 <structure>
267315 <category byname="公立教育施設"/>
268316 </structure>
@@ -272,20 +320,24 @@
272320 <class name="freetrain.contributions.population.OfficePopulation"/>
273321 <base>600</base>
274322 </population>
275- <height>3</height>
276- <size>2,2</size>
323+ <site upper-direction="NW">
324+ <height>3</height>
325+ <size>2,2</size>
326+ </site>
277327 <computerCannotBuild/>
278- <sprite origin=" 0,0" offset="40">
328+ <sprite rotation="0,180">
279329 <image ref="pic.CampusBldg-01"/>
280- </sprite>
281- <sprite origin="64,0" offset="40">
330+ <origin>0,0</origin>
331+ </sprite>
332+ <sprite rotation="90,270">
282333 <image ref="pic.CampusBldg-01"/>
283- </sprite>
334+ <origin>64,0</origin>
335+ </sprite>
284336 </contribution>
285337
286338 <!--02-->
287- <contribution type="ignore" id="CampusBuilding-02">
288- <group>大学</group>
339+ <contribution type="StructureSkin" id="CampusBuilding-02">
340+ <name>大学</name>
289341 <structure>
290342 <category byname="公立教育施設"/>
291343 </structure>
@@ -295,20 +347,24 @@
295347 <class name="freetrain.contributions.population.OfficePopulation"/>
296348 <base>360</base>
297349 </population>
298- <height>2</height>
299- <size>3,3</size>
350+ <site upper-direction="NW">
351+ <height>2</height>
352+ <size>3,3</size>
353+ </site>
300354 <computerCannotBuild/>
301- <sprite origin=" 0,0" offset="32">
355+ <sprite rotation="0,180">
302356 <image ref="pic.CampusBldg-02"/>
303- </sprite>
304- <sprite origin="96,0" offset="32">
357+ <origin>0,0</origin>
358+ </sprite>
359+ <sprite rotation="90,270">
305360 <image ref="pic.CampusBldg-02"/>
306- </sprite>
361+ <origin>96,0</origin>
362+ </sprite>
307363 </contribution>
308364
309365 <!--03-->
310- <contribution type="ignore" id="CampusBuilding-03">
311- <group>大学</group>
366+ <contribution type="StructureSkin" id="CampusBuilding-03">
367+ <name>大学</name>
312368 <structure>
313369 <category byname="公立教育施設"/>
314370 </structure>
@@ -318,20 +374,24 @@
318374 <class name="freetrain.contributions.population.OfficePopulation"/>
319375 <base>520</base>
320376 </population>
321- <height>2</height>
322- <computerCannotBuild/>
323- <size>3,5</size>
324- <sprite origin="256,0" offset="40">
377+ <computerCannotBuild/>
378+ <site upper-direction="NW">
379+ <height>2</height>
380+ <size>3,5</size>
381+ </site>
382+ <sprite rotation="0,180">
325383 <image ref="pic.CampusBldg-03"/>
326- </sprite>
327- <sprite origin="384,0" offset="56" opposite="true">
328- <image ref="pic.CampusBldg-03"/>
329- </sprite>
384+ <origin>256,0</origin>
385+ </sprite>
386+ <sprite rotation="90,270">
387+ <image ref="pic.CampusBldg-03"/>
388+ <origin>384,0</origin>
389+ </sprite>
330390 </contribution>
331391
332392 <!--tower-->
333- <contribution type="ignore" id="CampusBuilding-tower">
334- <group>大学</group>
393+ <contribution type="StructureSkin" id="CampusBuilding-tower">
394+ <name>大学</name>
335395 <structure>
336396 <category byname="公立教育施設"/>
337397 </structure>
@@ -341,20 +401,24 @@
341401 <class name="freetrain.contributions.population.OfficePopulation"/>
342402 <base>800</base>
343403 </population>
344- <height>3</height>
345- <computerCannotBuild/>
346- <size>3,5</size>
347- <sprite origin="0,0" offset="40">
404+ <computerCannotBuild/>
405+ <site upper-direction="NW">
406+ <height>3</height>
407+ <size>3,5</size>
408+ </site>
409+ <sprite rotation="0,180">
348410 <image ref="pic.CampusBldg-03"/>
349- </sprite>
350- <sprite origin="128,0" offset="56" opposite="true">
351- <image ref="pic.CampusBldg-03"/>
352- </sprite>
411+ <origin>0,0</origin>
412+ </sprite>
413+ <sprite rotation="90,270">
414+ <image ref="pic.CampusBldg-03"/>
415+ <origin>128,0</origin>
416+ </sprite>
353417 </contribution>
354418
355419 <!--04-->
356- <contribution type="ignore" id="CampusBuilding-04">
357- <group>大学</group>
420+ <contribution type="StructureSkin" id="CampusBuilding-04">
421+ <name>大学</name>
358422 <structure>
359423 <category byname="公立教育施設"/>
360424 </structure>
@@ -364,20 +428,24 @@
364428 <class name="freetrain.contributions.population.OfficePopulation"/>
365429 <base>700</base>
366430 </population>
367- <height>2</height>
368- <size>4,4</size>
431+ <site upper-direction="NW">
432+ <height>2</height>
433+ <size>4,4</size>
434+ </site>
369435 <computerCannotBuild/>
370- <sprite origin=" 0,0" offset="48">
436+ <sprite rotation="0,180">
371437 <image ref="pic.CampusBldg-04"/>
372- </sprite>
373- <sprite origin="128,0" offset="48">
438+ <origin>0,0</origin>
439+ </sprite>
440+ <sprite rotation="90,270">
374441 <image ref="pic.CampusBldg-04"/>
375- </sprite>
442+ <origin>128,0</origin>
443+ </sprite>
376444 </contribution>
377445
378446 <!--05-->
379- <contribution type="ignore" id="CampusBuilding-05">
380- <group>大学</group>
447+ <contribution type="StructureSkin" id="CampusBuilding-05">
448+ <name>大学</name>
381449 <structure>
382450 <category byname="公立教育施設"/>
383451 </structure>
@@ -387,26 +455,32 @@
387455 <class name="freetrain.contributions.population.OfficePopulation"/>
388456 <base>180</base>
389457 </population>
390- <height>2</height>
391- <computerCannotBuild/>
392- <size>3,1</size>
393- <sprite origin=" 0,0" offset="56">
458+ <computerCannotBuild/>
459+ <site upper-direction="NW">
460+ <height>2</height>
461+ <size>3,1</size>
462+ </site>
463+ <sprite rotation="0">
394464 <image ref="pic.CampusBldg-05"/>
395- </sprite>
396- <sprite origin="64,0" offset="40" opposite="true">
465+ <origin>0,0</origin>
466+ </sprite>
467+ <sprite rotation="90">
397468 <image ref="pic.CampusBldg-05"/>
398- </sprite>
399- <sprite origin="128,0" offset="56">
400- <image ref="pic.CampusBldg-05"/>
401- </sprite>
402- <sprite origin="192,0" offset="40" opposite="true">
403- <image ref="pic.CampusBldg-05"/>
404- </sprite>
469+ <origin>64,0</origin>
470+ </sprite>
471+ <sprite rotation="180">
472+ <image ref="pic.CampusBldg-05"/>
473+ <origin>128,0</origin>
474+ </sprite>
475+ <sprite rotation="270">
476+ <image ref="pic.CampusBldg-05"/>
477+ <origin>192,0</origin>
478+ </sprite>
405479 </contribution>
406480
407481 <!--06-->
408- <contribution type="ignore" id="CampusBuilding-06">
409- <group>大学</group>
482+ <contribution type="StructureSkin" id="CampusBuilding-06">
483+ <name>大学</name>
410484 <structure>
411485 <category byname="公立教育施設"/>
412486 </structure>
@@ -416,20 +490,24 @@
416490 <class name="freetrain.contributions.population.OfficePopulation"/>
417491 <base>580</base>
418492 </population>
419- <height>2</height>
420- <computerCannotBuild/>
421- <size>2,3</size>
422- <sprite origin="256,0" offset="40">
493+ <computerCannotBuild/>
494+ <site upper-direction="NW">
495+ <height>2</height>
496+ <size>2,3</size>
497+ </site>
498+ <sprite rotation="0,180">
423499 <image ref="pic.CampusBldg-05"/>
424- </sprite>
425- <sprite origin="336,0" offset="48" opposite="true">
426- <image ref="pic.CampusBldg-05"/>
427- </sprite>
500+ <origin>256,0</origin>
501+ </sprite>
502+ <sprite rotation="90,270">
503+ <image ref="pic.CampusBldg-05"/>
504+ <origin>336,0</origin>
505+ </sprite>
428506 </contribution>
429507
430508 <!--07-->
431- <contribution type="ignore" id="CampusBuilding-07">
432- <group>大学</group>
509+ <contribution type="StructureSkin" id="CampusBuilding-07">
510+ <name>大学</name>
433511 <structure>
434512 <category byname="公立教育施設"/>
435513 </structure>
@@ -439,20 +517,26 @@
439517 <class name="freetrain.contributions.population.OfficePopulation"/>
440518 <base>700</base>
441519 </population>
442- <height>2</height>
443- <size>3,3</size>
520+ <site upper-direction="NW">
521+ <height>2</height>
522+ <size>3,3</size>
523+ </site>
444524 <computerCannotBuild/>
445- <sprite origin="0,0" offset="40">
525+ <sprite rotation="0">
446526 <image ref="pic.CampusBldg-06"/>
447- </sprite>
448- <sprite origin="96,0" offset="40">
527+ <origin>0,0</origin>
528+ </sprite>
529+ <sprite rotation="90">
530+ <image ref="pic.CampusBldg-06"/>
531+ <origin>96,0</origin>
532+ </sprite>
533+ <sprite rotation="180">
534+ <image ref="pic.CampusBldg-06"/>
535+ <origin>192,0</origin>
536+ </sprite>
537+ <sprite rotation="270">
449538 <image ref="pic.CampusBldg-06"/>
450- </sprite>
451- <sprite origin="192,0" offset="40">
452- <image ref="pic.CampusBldg-06"/>
453- </sprite>
454- <sprite origin="288,0" offset="40">
455- <image ref="pic.CampusBldg-06"/>
456- </sprite>
539+ <origin>288,0</origin>
540+ </sprite>
457541 </contribution>
458542 </plug-in>
--- trunk/plugins/system/plugin.xml (revision 20)
+++ trunk/plugins/system/plugin.xml (revision 21)
@@ -82,7 +82,11 @@
8282 <class name="nft.contributions.terrain.CtbHeightCutSlopeTexture" codebase=".Core"/>
8383 <factory-class name="nft.contributions.terrain.CtbHeightCutSlopeTextureFactory" codebase=".Core"/>
8484 </declare-contribution>
85-
85+ <declare-contribution type="StructureSkin">
86+ <name>Texture skin for structures and objects in the scene.)</name>
87+ <class name="nft.contributions.graphics.CtbStructureSkin" codebase=".Core"/>
88+ </declare-contribution>
89+
8690 <contribution type="MenuItems" id="BaseMenu">
8791 <name>システム基本メニュー</name>
8892 <location parent="ROOT"/>