找回密码
 Register
搜索
查看: 11943|回复: 5

Vassal-VASL-LOS机制探索

[复制链接]
发表于 2018-10-23 09:13:33 | 显示全部楼层 |阅读模式
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部分算法

代码段


/*** 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();}
说明下算法顺序:
首先生成个空的LOSDataMap
再读取地图信息到该Map中
对于不足半格的格子进行补足
然后对于悬崖,建筑等特殊地形修订。
最后保存信息。

而在函数
/**
* 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();
}
}


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

在vasl/src/VASL/LOS/Map/LOSResult.java 中
体现了LOS如何去获得结果的各个函数

/**
* @return total 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
* @param h 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点。

结论,vasl采用不同的地图gif图来读取颜色判断是什么地形,
然后通过程序运算或读取的方式来获取地图信息。
最后通过设置hindrance值来获取LOS的阻碍点



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

评分

参与人数 2金币 +50 收起 理由
Der_Ring + 30 很给力!
无趣无聊 + 20 淡定

查看全部评分

发表于 2018-10-23 09:18:21 | 显示全部楼层
因为看不懂,所以觉得应该多给些金币。。。。
发表于 2018-10-23 14:16:19 | 显示全部楼层
西格玛大佬这贴可以说是硬核中的硬核
发表于 2018-10-28 01:08:19 | 显示全部楼层
我不知道该说些啥,因为要看懂比较费劲。不过还是要顶一下。
发表于 2018-10-28 20:33:40 | 显示全部楼层
原来直带los判断的吗。。。只会拉线的路过
发表于 2018-10-29 21:47:44 | 显示全部楼层
大大實在太強了!

代碼以外,其他都還看得懂。

難怪每次拉線,有些LOS很奇怪......
您需要登录后才可以回帖 登录 | Register

本版积分规则

QQ|Archiver|手机版|小黑屋|Velonica

GMT+8, 2024-11-28 23:32 , Processed in 0.028443 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表