【兵棋学院】Vassal-VASL-LOS机制探索

一楼想念S2000大

楼主 xigemaqq  发布于 2018-10-22 16:44:00 +0800 CST  
Vasl是用于Vassal对战ASL的模组,其官网VASL.info上有github的link,今天初窥门径
看看代码配合模组来学习学习
这是github地址
https://github.com/vasl-developers/vasl
这次目标的核心问题是vasl的los是实时计算的 还是依据一个数据库来读取的


vasl/boards/src/bdy/ 是版图信息文件
ybdy.gif 是地图y基本版图,也是诸多asl玩家的初选地图y
BoardMetadata.xml 记录了图层叠加数据


vasl/dev documentation/ 是相关技术文档 不过最初更新也是五年前了
Board Archive Interface Design.doc
BoardMetadata-sample.xml
GettingStartedWithVASLDevelopment.docx 讲解如何用github,JDK,GIT工具来开发VASL


vasl/dist/ 在其中找到了LOS.txt文档 说明了los的相关操作
值得注意的是VASL的功能键
箭头上 目标层上升,箭头下 目标层下降
ctrl+上 观察者层上升,ctrl+下 观察者层下降


vasl/src/VASL/LOS/ LOSDataEditor.java 文档中找到了los部分算法

楼主 xigemaqq  发布于 2018-10-22 16:51:00 +0800 CST  
代码段


/*** Create the LOS data from the board image in the VASL archive* Assumes the file helpers have been set*/
public void createLOSData() {
// create an empty map
map = createNewLOSData();
// spin through the terrain and elevation grids and add the terrain codes
setAllTerrain();
// fix pixels that have no terrain or elevation code (E.g. the hex center dot)
setAllUnknownTerrain();
// we need to occasionally update the hex grid as the following processes need updated hex informationmap.resetHexTerrain(0);
// fix cliff elevation pixels - set them to the lower of the two hex elevations
for (int x = 0; x < map.getGridWidth(); x++)
{for (int y = 0; y < map.getGridHeight(); y++)
{if (map.getGridTerrain(x, y) == map.getTerrain("Cliff")) {Hex hex = map.gridToHex(x, y);


// DR code added to trap
hex=nullif(!(hex==null))
{Hex oppositeHex = map.getAdjacentHex(hex, hex.getLocationHexside(hex.getNearestLocation(x, y)));
if (oppositeHex == null) {map.setGridElevation(hex.getBaseHeight(), x, y);}
else {map.setGridElevation(Math.min(hex.getBaseHeight(), oppositeHex.getBaseHeight()), x, y);}}}}}


// apply building-type transformationsHashMap<String, String>
buildingTypes = boardArchive.getBuildingTypes();
for (String hex : buildingTypes.keySet()) {Hex h = map.getHex(hex);Terrain toTerrain = map.getTerrain(buildingTypes.get(hex));changeAllTerrain(h.getCenterLocation().getTerrain(), toTerrain, h.getHexBorder());}setExteriorFactoryWalls();map.resetHexTerrain(0);


// set depression elevations
for (int x = 0; x < map.getGridWidth(); x++) {for (int y = 0; y < map.getGridHeight(); y++) {if (map.getGridTerrain(x, y).isDepression()) {map.setGridElevation(map.getGridElevation(x, y) - 1, x, y);}}}map.resetHexTerrain(0)
;fixElevatedSunkenRoads();
map.resetHexTerrain(0);
addStairways();}

楼主 xigemaqq  发布于 2018-10-22 16:54:00 +0800 CST  
说明下算法顺序:
首先生成个空的LOSDataMap
再读取地图信息到该Map中
对于不足半格的格子进行补足
然后对于悬崖,建筑等特殊地形修订。
最后保存信息。

楼主 xigemaqq  发布于 2018-10-22 16:58:00 +0800 CST  
而在函数
/**
* Read the LOS data or create it if it doesn't exist
*/
public void readLOSData() {

// code added by DR to enable unlimited cropping
String offset="";
map = boardArchive.getLOSData(offset, false);

if (map == null) {

// convert the image
createLOSData();
}
}


则很明显 就是首先尝试读取,如果没有那么去生成一个

楼主 xigemaqq  发布于 2018-10-22 17:02:00 +0800 CST  
在vasl/src/VASL/LOS/Map/LOSResult.java 中
体现了LOS如何去获得结果的各个函数

/**
*@returntotal hindrances in results
*/
public int getHindrance() {
int hindrance=0;
for(Integer range : mapHindrances.keySet()) {
hindrance += mapHindrances.get(range);
}

// add the smoke hindrances
for(Integer range : smokeHindrances.keySet()) {

hindrance += smokeHindrances.get(range);
}
// add the vehicle hindrances
for(Integer range: vehicleHindrances.keySet()) {
hindrance += vehicleHindrances.get(range);
}
// add the OBA hindrances
hindrance += obaHindrances.size();

return hindrance;
}
这是LOS的hindrance函数 考虑了地形,烟雾,车辆,OBA等


然后在hindrance》6的情况下 调用firstHindrance来获取第一个block点阻碍点

/**
* add a map hindrance hex
*@paramh the hindrance hex
* @param x current x of LOS
* @param y current y of LOS
*/
public void addMapHindrance(Hex h, int hindrance, int x, int y){

setFirstHindrance(x, y);

// if there's already a terrain hindrance at this range replace if hindrance is greater
Integer range = sourceLocation.getHex().getMap().range(sourceLocation.getHex(), h, sourceLocation.getHex().getMap().getMapConfiguration());
if(!mapHindrances.containsKey(range) ||
(mapHindrances.containsKey(range) && hindrance > mapHindrances.get(range))) {
mapHindrances.put(range, hindrance);
}

setBlockedByHindrance(x, y);
}
在地图数据的情况下依据求出的X,Y来设置blocked点。




楼主 xigemaqq  发布于 2018-10-22 17:10:00 +0800 CST  
结论,vasl采用不同的地图gif图来读取颜色判断是什么地形,
然后通过程序运算或读取的方式来获取地图信息。
最后通过设置hindrance值来获取LOS的阻碍点


这也是为什么不同版本的vasl在加载地图的时候可能出现LOS不对的情况


以上,欢迎大家探索并讨论

楼主 xigemaqq  发布于 2018-10-22 17:12:00 +0800 CST  

楼主:xigemaqq

字数:4122

发表时间:2018-10-23 00:44:00 +0800 CST

更新时间:2018-11-05 12:00:57 +0800 CST

评论数:20条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看