Compare commits

...

5 Commits

Author SHA1 Message Date
Vitaliy 986eb94494
Mobile: use extended view range instead full (#230) 2022-01-30 11:04:03 +02:00
MoNTE48 91b4202e56 iOS: improve consent dialog 2022-01-19 21:34:27 +01:00
numzero 7fea51579d Optimize clouds 2022-01-15 19:55:37 +01:00
MoNTE48 41b3b70e23 Mobile: improve simple Settings Menu 2022-01-15 19:52:42 +01:00
MoNTE48 f4848f1a71 Improve GUI scaling 2022-01-14 09:52:31 +01:00
15 changed files with 335 additions and 312 deletions

View File

@ -43,9 +43,9 @@
84A4380425535BA5002571D4 /* soft_oal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84A4380325535BA5002571D4 /* soft_oal.framework */; };
84A4380525535BA5002571D4 /* soft_oal.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84A4380325535BA5002571D4 /* soft_oal.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
84A608A425F0A02900D79FCD /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 84A608A325F0A02900D79FCD /* Sentry */; };
84B1647F27988B92002A670A /* Bundle+AppIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B1647E27988B92002A670A /* Bundle+AppIcon.swift */; };
84B9C11724A4D82400016BCE /* ConsentAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B9C11524A4D82400016BCE /* ConsentAlertViewController.swift */; };
84B9C11824A4D82400016BCE /* ConsentAlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84B9C11624A4D82400016BCE /* ConsentAlertViewController.xib */; };
84C32A3724AF7A4500445E92 /* Nantes in Frameworks */ = {isa = PBXBuildFile; productRef = 84C32A3624AF7A4500445E92 /* Nantes */; };
84C32A3924AF7DDE00445E92 /* UITextViewPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C32A3824AF7DDE00445E92 /* UITextViewPlaceholder.swift */; };
84C67B1E25D5E06B002E2735 /* AppTrackingTransparency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C67B1D25D5E06B002E2735 /* AppTrackingTransparency.framework */; };
84CD4A64248782720019B81D /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CD4A59248782720019B81D /* MainWindow.swift */; };
@ -323,6 +323,7 @@
8473ED8325C0562C0053293B /* unidata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unidata.h; path = ../../../../lib/luautf8/unidata.h; sourceTree = "<group>"; };
849C4F85209656D2005EB041 /* ru.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ru.lproj; sourceTree = "<group>"; };
84A4380325535BA5002571D4 /* soft_oal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = soft_oal.framework; path = ../deps/soft_oal.framework; sourceTree = "<group>"; };
84B1647E27988B92002A670A /* Bundle+AppIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+AppIcon.swift"; sourceTree = "<group>"; };
84B9C11524A4D82400016BCE /* ConsentAlertViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsentAlertViewController.swift; sourceTree = "<group>"; };
84B9C11624A4D82400016BCE /* ConsentAlertViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConsentAlertViewController.xib; sourceTree = "<group>"; };
84C32A3824AF7DDE00445E92 /* UITextViewPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextViewPlaceholder.swift; sourceTree = "<group>"; };
@ -748,7 +749,6 @@
F8E6C7D51DCA476800F64426 /* libIrrlicht.a in Frameworks */,
84A608A425F0A02900D79FCD /* Sentry in Frameworks */,
843F4C3126617D0D005277FA /* ZipArchive in Frameworks */,
84C32A3724AF7A4500445E92 /* Nantes in Frameworks */,
F8E6C7C91DCA430300F64426 /* OpenGLES.framework in Frameworks */,
8E0FFE3234B35EC9603EC82A /* Pods_MultiCraft.framework in Frameworks */,
F8E6C7C51DCA42F300F64426 /* QuartzCore.framework in Frameworks */,
@ -800,6 +800,22 @@
name = irrlicht_changes;
sourceTree = "<group>";
};
84B1647C27988B92002A670A /* Extensions */ = {
isa = PBXGroup;
children = (
84B1647D27988B92002A670A /* Bundle */,
);
path = Extensions;
sourceTree = "<group>";
};
84B1647D27988B92002A670A /* Bundle */ = {
isa = PBXGroup;
children = (
84B1647E27988B92002A670A /* Bundle+AppIcon.swift */,
);
path = Bundle;
sourceTree = "<group>";
};
84CD4A56248782720019B81D /* Main */ = {
isa = PBXGroup;
children = (
@ -882,6 +898,7 @@
F8E6C4DC1DCA3B7900F64426 /* Supporting Files */ = {
isa = PBXGroup;
children = (
84B1647C27988B92002A670A /* Extensions */,
84CD4A56248782720019B81D /* Main */,
84CD4A5A248782720019B81D /* UI */,
84CD4A55248781420019B81D /* Bridge-Header.h */,
@ -1451,7 +1468,6 @@
);
name = MultiCraft;
packageProductDependencies = (
84C32A3624AF7A4500445E92 /* Nantes */,
84A608A325F0A02900D79FCD /* Sentry */,
843F4C3026617D0D005277FA /* ZipArchive */,
);
@ -1491,7 +1507,6 @@
);
mainGroup = F8E6C4D01DCA3B7900F64426;
packageReferences = (
84C32A3524AF7A4500445E92 /* XCRemoteSwiftPackageReference "Nantes" */,
84A608A225F0A02900D79FCD /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
843F4C2F26617D0D005277FA /* XCRemoteSwiftPackageReference "ZipArchive" */,
);
@ -1663,6 +1678,7 @@
F8E6C6F61DCA41DB00F64426 /* c_content.cpp in Sources */,
4B35A9EA1EEE010D00274961 /* l_metadata.cpp in Sources */,
F8E6C6551DCA3F9900F64426 /* shader.cpp in Sources */,
84B1647F27988B92002A670A /* Bundle+AppIcon.swift in Sources */,
F8E6C7491DCA420A00F64426 /* l_env.cpp in Sources */,
F8E6C6381DCA3F9900F64426 /* mapsector.cpp in Sources */,
F8E6C7B81DCA428800F64426 /* auth.cpp in Sources */,
@ -2073,14 +2089,6 @@
minimumVersion = 7.5.0;
};
};
84C32A3524AF7A4500445E92 /* XCRemoteSwiftPackageReference "Nantes" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/instacart/Nantes";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.1.2;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@ -2094,11 +2102,6 @@
package = 84A608A225F0A02900D79FCD /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
productName = Sentry;
};
84C32A3624AF7A4500445E92 /* Nantes */ = {
isa = XCSwiftPackageProductDependency;
package = 84C32A3524AF7A4500445E92 /* XCRemoteSwiftPackageReference "Nantes" */;
productName = Nantes;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = F8E6C4D11DCA3B7900F64426 /* Project object */;

View File

@ -0,0 +1,14 @@
import UIKit
extension Bundle {
var appIcon: UIImage? {
if let icons = infoDictionary?["CFBundleIcons"] as? [String: Any],
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
let lastIcon = iconFiles.last {
return UIImage(named: lastIcon)
}
return nil
}
}

View File

@ -1,16 +1,15 @@
import UIKit
import Nantes
private enum Constants {
static let oldInfoStatusKey = "personalized_ad_status"
static let newInfoStatusKey = "new_personalized_ad_status"
}
final class ConsentAlertViewController: BasePresentViewController, NantesLabelDelegate {
final class ConsentAlertViewController: BasePresentViewController {
@IBOutlet private weak var buttonRelevant: UIButton!
@IBOutlet private weak var buttonAllow: UIButton!
@IBOutlet private weak var viewContainer: UIView!
@IBOutlet private weak var labelPrivacy: NantesLabel!
@IBOutlet private weak var privacyTextView: UITextView!
@IBOutlet private weak var viewFirst: UIView!
@IBOutlet private weak var viewSecond: UIView!
@IBOutlet private weak var buttonAgree: UIButton!
@ -26,6 +25,8 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
var finishTapped: (() -> Void)?
let screenWidth = UIScreen.main.bounds.size.width
private enum Status: String, Codable {
case unknown
case personalized
@ -50,8 +51,13 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
imageAppIcon.layer.cornerRadius = imageAppIcon.frame.size.height * 0.22
setupContentHeight()
if (isShowFirstPage && screenWidth <= 568.0) {
buttonAllow.titleLabel?.font = .boldSystemFont(ofSize: 15)
buttonRelevant.titleLabel?.font = .boldSystemFont(ofSize: 15)
}
}
private func setupContentHeight() {
@ -60,12 +66,16 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
}
private func setupUI() {
if UIScreen.main.bounds.size.width <= 667 {
leftPadding.constant = 30
rightPadding.constant = 30
var widthMultiplierValue: CGFloat = 0.7
if screenWidth <= 568.0 {
widthMultiplierValue = 0.95
} else if screenWidth <= 667.0 {
widthMultiplierValue = 0.91
}
imageAppIcon.image = Bundle.main.icon
viewContainer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: widthMultiplierValue).isActive = true
imageAppIcon.image = Bundle.main.appIcon
buttonAgree.layer.cornerRadius = 6
buttonBack.layer.borderWidth = 1
@ -75,12 +85,10 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
buttonAllow.layer.cornerRadius = 8
buttonAllow.layer.borderWidth = 3
buttonAllow.layer.borderColor = UIColor(220, 220, 220).cgColor
buttonAllow.titleLabel?.numberOfLines = 2
buttonRelevant.layer.cornerRadius = 8
buttonRelevant.layer.borderWidth = 3
buttonRelevant.layer.borderColor = UIColor(220, 220, 220).cgColor
buttonRelevant.titleLabel?.numberOfLines = 2
viewContainer.layer.shadowColor = UIColor.black.cgColor
viewContainer.layer.shadowRadius = 6
@ -88,20 +96,27 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
viewContainer.layer.shadowOffset = .init(width: 0, height: 3)
viewContainer.layer.cornerRadius = 8
labelPrivacy.delegate = self
let text = "Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on Privacy Policy."
labelPrivacy.text = text
setupTextView()
}
labelPrivacy.linkAttributes = [NSAttributedString.Key.underlineColor: NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.foregroundColor: UIColor(0, 98, 232)]
private func setupTextView() {
privacyTextView.delegate = self
privacyTextView.backgroundColor = .clear
privacyTextView.textContainerInset = UIEdgeInsets(top: 0.0, left: privacyTextView.textContainerInset.left, bottom: 0.0, right: privacyTextView.textContainerInset.right)
privacyTextView.textContainer.lineFragmentPadding = 0
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
privacyTextView.linkTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.blue]
labelPrivacy.activeLinkAttributes = [NSAttributedString.Key.backgroundColor: UIColor(white: 0.5, alpha: 0.5),
NSAttributedString.Key.underlineColor: NSUnderlineStyle.single.rawValue]
let attributedString = NSMutableAttributedString(string: "Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on ", attributes: [NSAttributedString.Key.paragraphStyle : paragraphStyle, NSAttributedString.Key.foregroundColor : UIColor.darkGray])
labelPrivacy.lineSpacing = 3
labelPrivacy.textColor = .lightGray
labelPrivacy.addLink(to: privacyURL, withRange: (text as NSString).range(of: "Privacy Policy"))
let linkAttrString = NSMutableAttributedString(string: "Privacy Policy", attributes: [NSAttributedString.Key.link : privacyURL.absoluteString])
attributedString.append(linkAttrString)
attributedString.append(NSMutableAttributedString(string: "."))
privacyTextView.attributedText = attributedString
}
@IBAction private func showMulticraftUses(_ sender: Any) {
@ -120,12 +135,6 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
}
}
@IBAction private func showPrivacy(_ sender: Any) {
if UIApplication.shared.canOpenURL(privacyURL) {
UIApplication.shared.open(privacyURL)
}
}
@IBAction private func allowTapped(_ sender: Any) {
Self.setPersonalizedConsentStatus(.personalized)
finishTapped?()
@ -147,12 +156,6 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
self.view.layoutIfNeeded()
}
}
func attributedLabel(_ label: NantesLabel, didSelectLink link: URL) {
if UIApplication.shared.canOpenURL(link) {
UIApplication.shared.open(link)
}
}
}
extension ConsentAlertViewController {
@ -215,14 +218,8 @@ extension ConsentAlertViewController {
}
}
extension Bundle {
var icon: UIImage? {
if let icons = infoDictionary?["CFBundleIcons"] as? [String: Any],
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
let lastIcon = iconFiles.last {
return UIImage(named: lastIcon)
}
return nil
extension ConsentAlertViewController: UITextViewDelegate {
func textViewDidChangeSelection(_ textView: UITextView) {
textView.selectedTextRange = nil
}
}

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_5" orientation="landscape" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -14,9 +17,7 @@
<outlet property="buttonRelevant" destination="Rxj-Jo-vAL" id="fSr-Od-uZN"/>
<outlet property="containerHeight" destination="mdm-AS-So4" id="dVy-Df-6N4"/>
<outlet property="imageAppIcon" destination="ju7-3g-6gQ" id="AW9-2J-l6P"/>
<outlet property="labelPrivacy" destination="qle-ba-Sha" id="Q17-98-lxH"/>
<outlet property="leftPadding" destination="Ryb-ju-2gI" id="YfH-nI-hcr"/>
<outlet property="rightPadding" destination="ima-Vy-JsH" id="KoJ-yU-zSl"/>
<outlet property="privacyTextView" destination="UIS-L6-1Hk" id="goB-1D-Upq"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
<outlet property="viewContainer" destination="jN6-lz-Z5i" id="b4F-U0-QNA"/>
<outlet property="viewFirst" destination="no2-jY-28I" id="a62-Vq-hlY"/>
@ -29,146 +30,191 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jN6-lz-Z5i">
<rect key="frame" x="80" y="67" width="736" height="280"/>
<rect key="frame" x="89.666666666666686" y="72" width="716.66666666666652" height="270"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bbD-X9-thg">
<rect key="frame" x="300.5" y="10" width="135.5" height="50"/>
<rect key="frame" x="287.33333333333331" y="10" width="142.33333333333331" height="40"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ju7-3g-6gQ">
<rect key="frame" x="0.0" y="5" width="40" height="40"/>
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="MF5-dK-QZm"/>
<constraint firstAttribute="width" constant="40" id="gyE-ko-6qD"/>
<constraint firstAttribute="width" constant="40" id="gyE-ko-6qD">
<variation key="heightClass=regular-widthClass=regular" constant="60"/>
</constraint>
<constraint firstAttribute="width" secondItem="ju7-3g-6gQ" secondAttribute="height" multiplier="1:1" id="omA-jD-JXD"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MultiCraft" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VL7-9o-er1">
<rect key="frame" x="55" y="14.5" width="80.5" height="21.5"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<rect key="frame" x="54.999999999999993" y="9.3333333333333304" width="87.333333333333314" height="21.666666666666671"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
</variation>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="ju7-3g-6gQ" firstAttribute="centerY" secondItem="bbD-X9-thg" secondAttribute="centerY" id="9BN-kH-3SV"/>
<constraint firstItem="VL7-9o-er1" firstAttribute="centerY" secondItem="bbD-X9-thg" secondAttribute="centerY" id="LRC-gB-qkY"/>
<constraint firstAttribute="height" constant="50" id="Ox3-ju-Z6g"/>
<constraint firstItem="VL7-9o-er1" firstAttribute="leading" secondItem="ju7-3g-6gQ" secondAttribute="trailing" constant="15" id="PvL-dV-kaL"/>
<constraint firstItem="ju7-3g-6gQ" firstAttribute="top" secondItem="bbD-X9-thg" secondAttribute="top" id="hH8-J1-ABV"/>
<constraint firstItem="ju7-3g-6gQ" firstAttribute="leading" secondItem="bbD-X9-thg" secondAttribute="leading" id="iPB-7V-PH7"/>
<constraint firstAttribute="bottom" secondItem="ju7-3g-6gQ" secondAttribute="bottom" id="m0q-dQ-YcL"/>
<constraint firstAttribute="trailing" secondItem="VL7-9o-er1" secondAttribute="trailing" id="pco-lS-gvm"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FVI-kf-H4t">
<rect key="frame" x="0.0" y="70" width="736" height="200"/>
<rect key="frame" x="0.0" y="60" width="716.66666666666663" height="200"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="no2-jY-28I" userLabel="first">
<rect key="frame" x="0.0" y="9.5" width="736" height="181"/>
<rect key="frame" x="0.0" y="2" width="716.66666666666663" height="196"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="We care about your privacy and data security. We keep this app free by showing ads." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="reR-NS-ZXk">
<rect key="frame" x="50" y="0.0" width="636" height="38.5"/>
<rect key="frame" x="50" y="0.0" width="616.66666666666663" height="38.333333333333336"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="21"/>
</variation>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Can we continue to use your data to tailor ads for you?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rbf-k7-ND1">
<rect key="frame" x="30" y="53.5" width="676" height="20.5"/>
<rect key="frame" x="30" y="53.333333333333343" width="656.66666666666663" height="20.333333333333329"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
</variation>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qle-ba-Sha" customClass="NantesLabel" customModule="Nantes">
<rect key="frame" x="20" y="89" width="696" height="27"/>
<string key="text">Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on Privacy Policy</string>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" editable="NO" textAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="UIS-L6-1Hk">
<rect key="frame" x="20" y="88.666666666666657" width="676.66666666666663" height="42.333333333333343"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<string key="text">Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on </string>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rxj-Jo-vAL">
<rect key="frame" x="375.5" y="131" width="345.5" height="50"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="No, see ads that are less releant"/>
<connections>
<action selector="relevantTapped:" destination="-1" eventType="touchUpInside" id="g2V-dM-M7Y"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qsc-Xi-g92">
<rect key="frame" x="15" y="131" width="345.5" height="50"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="16"/>
</variation>
</textView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="hAu-gU-FOo">
<rect key="frame" x="15" y="146" width="686.66666666666663" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qsc-Xi-g92">
<rect key="frame" x="0.0" y="0.0" width="336" height="50"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="Yes, I allow to use my data">
<color key="titleColor" red="0.0" green="0.50196078431372548" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="22"/>
</variation>
<connections>
<action selector="allowTapped:" destination="-1" eventType="touchUpInside" id="Dj8-nb-viX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rxj-Jo-vAL">
<rect key="frame" x="351" y="0.0" width="335.66666666666674" height="50"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="No, see ads that are less releant">
<color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="22"/>
</variation>
<connections>
<action selector="relevantTapped:" destination="-1" eventType="touchUpInside" id="g2V-dM-M7Y"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="50" id="UQv-WK-cC3"/>
<constraint firstAttribute="height" constant="50" id="fME-oB-mgo">
<variation key="heightClass=regular-widthClass=regular" constant="70"/>
</constraint>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="Yes, I allow to use my data"/>
<connections>
<action selector="allowTapped:" destination="-1" eventType="touchUpInside" id="Dj8-nb-viX"/>
</connections>
</button>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Rbf-k7-ND1" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="30" id="2Br-ef-GGz"/>
<constraint firstAttribute="bottom" secondItem="qsc-Xi-g92" secondAttribute="bottom" id="2Mx-zx-h7L"/>
<constraint firstItem="qsc-Xi-g92" firstAttribute="width" secondItem="Rxj-Jo-vAL" secondAttribute="width" id="2Ue-Yh-2qf"/>
<constraint firstAttribute="trailing" secondItem="Rbf-k7-ND1" secondAttribute="trailing" constant="30" id="2l2-ee-69m"/>
<constraint firstAttribute="trailing" secondItem="Rxj-Jo-vAL" secondAttribute="trailing" constant="15" id="59i-dn-8ok"/>
<constraint firstItem="Rxj-Jo-vAL" firstAttribute="leading" secondItem="qsc-Xi-g92" secondAttribute="trailing" constant="15" id="5xv-IS-Bs3"/>
<constraint firstAttribute="trailing" secondItem="reR-NS-ZXk" secondAttribute="trailing" constant="50" id="8Nh-tt-z0k"/>
<constraint firstItem="qsc-Xi-g92" firstAttribute="top" secondItem="qle-ba-Sha" secondAttribute="bottom" constant="15" id="DoF-Us-qDK"/>
<constraint firstItem="Rxj-Jo-vAL" firstAttribute="height" secondItem="qsc-Xi-g92" secondAttribute="height" id="HVP-2W-nY0"/>
<constraint firstItem="hAu-gU-FOo" firstAttribute="top" secondItem="UIS-L6-1Hk" secondAttribute="bottom" constant="15" id="N9p-41-frs"/>
<constraint firstItem="hAu-gU-FOo" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="15" id="SAj-br-Qgz"/>
<constraint firstItem="Rbf-k7-ND1" firstAttribute="top" secondItem="reR-NS-ZXk" secondAttribute="bottom" constant="15" id="Twf-aC-yrB"/>
<constraint firstAttribute="trailing" secondItem="qle-ba-Sha" secondAttribute="trailing" constant="20" id="VYy-4Q-DpO"/>
<constraint firstItem="reR-NS-ZXk" firstAttribute="top" secondItem="no2-jY-28I" secondAttribute="top" id="YPQ-2N-HjD"/>
<constraint firstItem="Rxj-Jo-vAL" firstAttribute="top" secondItem="qsc-Xi-g92" secondAttribute="top" id="a91-QX-7fT"/>
<constraint firstItem="qsc-Xi-g92" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="15" id="cyc-yq-fD7"/>
<constraint firstAttribute="bottom" secondItem="hAu-gU-FOo" secondAttribute="bottom" id="b9P-Ld-nZA"/>
<constraint firstAttribute="trailing" secondItem="hAu-gU-FOo" secondAttribute="trailing" constant="15" id="cgs-UN-bn9"/>
<constraint firstItem="UIS-L6-1Hk" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="20" id="ds9-ho-fos"/>
<constraint firstItem="reR-NS-ZXk" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="50" id="j30-js-cgR"/>
<constraint firstItem="qle-ba-Sha" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="20" id="jyb-F3-agL"/>
<constraint firstItem="qle-ba-Sha" firstAttribute="top" secondItem="Rbf-k7-ND1" secondAttribute="bottom" constant="15" id="njl-xJ-UHL"/>
<constraint firstAttribute="trailing" secondItem="UIS-L6-1Hk" secondAttribute="trailing" constant="20" id="lPE-Yd-wYR"/>
<constraint firstItem="UIS-L6-1Hk" firstAttribute="top" secondItem="Rbf-k7-ND1" secondAttribute="bottom" constant="15" id="ylc-Ol-Zoc"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="b0v-eJ-u4n" userLabel="second">
<rect key="frame" x="0.0" y="36" width="736" height="128.5"/>
<rect key="frame" x="0.0" y="36" width="716.66666666666663" height="128.33333333333334"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Well partner with Appodeal and use a unique identifier on your device to respect your data usage choice." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lKc-3Y-oYd">
<rect key="frame" x="40" y="0.0" width="656" height="38.5"/>
<rect key="frame" x="40" y="0.0" width="636.66666666666663" height="38.333333333333336"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="21"/>
</variation>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FtZ-2K-YYB">
<rect key="frame" x="264" y="43.5" width="208" height="40"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FtZ-2K-YYB">
<rect key="frame" x="254.33333333333331" y="43.333333333333343" width="208" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="6eW-eW-3sn"/>
</constraints>
<state key="normal" title="How MultiCraft uses your data"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="20"/>
</variation>
<connections>
<action selector="showMulticraftUses:" destination="-1" eventType="touchUpInside" id="LCL-n2-viJ"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kok-zY-LLa">
<rect key="frame" x="268" y="88.5" width="200" height="40"/>
<rect key="frame" x="258.33333333333331" y="88.333333333333314" width="200" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fHL-HQ-Ax8">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fHL-HQ-Ax8">
<rect key="frame" x="120" y="0.0" width="80" height="40"/>
<color key="backgroundColor" red="0.0" green="0.38431372549019605" blue="0.90980392156862744" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="80" id="IA1-gD-Usp"/>
<constraint firstAttribute="width" constant="80" id="IA1-gD-Usp">
<variation key="heightClass=regular-widthClass=regular" constant="120"/>
</constraint>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
<state key="normal" title="Agree">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
</variation>
<connections>
<action selector="agreeTapped:" destination="-1" eventType="touchUpInside" id="L3x-I7-rA9"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1nL-wW-oAr">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1nL-wW-oAr">
<rect key="frame" x="0.0" y="0.0" width="100" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Npb-sR-MK2"/>
<constraint firstAttribute="width" constant="100" id="Npb-sR-MK2">
<variation key="heightClass=regular-widthClass=regular" constant="140"/>
</constraint>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<inset key="titleEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-10" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="Back" image="icon_back"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="21"/>
</variation>
<connections>
<action selector="backTapped:" destination="-1" eventType="touchUpInside" id="Bnq-48-ydl"/>
</connections>
@ -177,12 +223,12 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="1nL-wW-oAr" secondAttribute="bottom" id="1yD-Ct-4mA"/>
<constraint firstItem="fHL-HQ-Ax8" firstAttribute="leading" secondItem="1nL-wW-oAr" secondAttribute="trailing" constant="20" id="EM0-lY-QWh"/>
<constraint firstItem="fHL-HQ-Ax8" firstAttribute="top" secondItem="kok-zY-LLa" secondAttribute="top" id="J02-9n-GkM"/>
<constraint firstAttribute="trailing" secondItem="fHL-HQ-Ax8" secondAttribute="trailing" id="Jh5-HG-QGM"/>
<constraint firstAttribute="height" constant="40" id="cgR-IG-iWU"/>
<constraint firstItem="1nL-wW-oAr" firstAttribute="top" secondItem="kok-zY-LLa" secondAttribute="top" id="cvK-7Q-DcV"/>
<constraint firstAttribute="bottom" secondItem="fHL-HQ-Ax8" secondAttribute="bottom" id="gYN-KQ-Eh0"/>
<constraint firstAttribute="width" constant="200" id="gZr-LH-Jho"/>
<constraint firstItem="1nL-wW-oAr" firstAttribute="leading" secondItem="kok-zY-LLa" secondAttribute="leading" id="kmj-ly-5MP"/>
</constraints>
</view>
@ -223,17 +269,20 @@
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" white="0.0" alpha="0.20000000000000001" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="width" secondItem="i5M-Pr-FkT" secondAttribute="width" multiplier="0.8" placeholder="YES" id="6oa-4n-J1R"/>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="79d-ga-FPU"/>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="80" id="Ryb-ju-2gI"/>
<constraint firstAttribute="trailing" secondItem="jN6-lz-Z5i" secondAttribute="trailing" constant="80" id="ima-Vy-JsH"/>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="centerX" secondItem="fnl-2z-Ty3" secondAttribute="centerX" id="XBL-cD-ih3"/>
</constraints>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<point key="canvasLocation" x="48.883928571428569" y="34.782608695652179"/>
<point key="canvasLocation" x="48.755490483162518" y="34.5703125"/>
</view>
</objects>
<resources>
<image name="icon_back" width="10" height="18"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@ -76,7 +76,7 @@ local function get_formspec(_, _, tabdata)
esc(core.settings:get("name")) .. "]" ..
-- Description Background
"box[7.1,2.1;4.8,2.65;#999999]" ..
"box[7.1,2.1;4.8,2.65;#33314B99]" ..
-- Connect
"image_button[8.8,4.88;3.3,0.9;" ..
@ -143,7 +143,8 @@ local function get_formspec(_, _, tabdata)
table.insert(menudata.favorites, i, table.remove(menudata.favorites, j))
end
end
if favs[i].address ~= menudata.favorites[i].address then
if favs[i] and menudata.favorites[i] and
favs[i].address ~= menudata.favorites[i].address then
table.insert(menudata.favorites, i, favs[i])
end
end

View File

@ -46,7 +46,7 @@ local getSettingIndex = {
local function formspec(tabview, name, tabdata)
local fps = tonumber(core.settings:get("fps_max"))
local range = tonumber(core.settings:get("viewing_range"))
local touchthreshold = tonumber(core.settings:get("touchscreen_threshold")) or 0
local sensitivity = tonumber(core.settings:get("mouse_sensitivity")) * 2000
local touchtarget = core.settings:get_bool("touchtarget") or false
local sound = tonumber(core.settings:get("sound_volume")) ~= 0 and true or false
@ -88,9 +88,8 @@ local function formspec(tabview, name, tabdata)
"dropdown[4.25,3.3;3.5;dd_node_highlighting;" .. dd_options.node_highlighting[1] .. ";"
.. getSettingIndex.NodeHighlighting() .. "]" ..
"label[4.25,4.2;" .. fgettext("Touchthreshold (px)") .. ":]" ..
"dropdown[4.25,4.65;3.5;dd_touchthreshold;0,10,20,30,40,50;" ..
(touchthreshold / 10) + 1 .. "]" ..
"label[4.25,4.2;" .. fgettext("Mouse sensitivity") .. ":]" ..
"scrollbar[4.25,4.65;3.22,0.5;horizontal;sb_sensitivity;" .. sensitivity .. "]" ..
-- "box[8,0;3.75,4.5;#999999]"
"box[8,0;3.75,5.5;#999999]"
@ -178,7 +177,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
return true
end
if fields["cb_fancy_leaves"] then
core.settings:set("dd_leaves_style", fields["dd_touchthreshold"] and "fancy" or "opaque")
core.settings:set("dd_leaves_style", fields["cb_fancy_leaves"] and "fancy" or "opaque")
ddhandled = true
end
if fields["cb_touchtarget"] then
@ -234,9 +233,18 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
core.settings:set("viewing_range", fields["dd_viewing_range"])
ddhandled = true
end
if fields["dd_touchthreshold"] then
core.settings:set("touchscreen_threshold", fields["dd_touchthreshold"])
ddhandled = true
if fields["sb_sensitivity"] then
-- reset old setting
core.settings:remove("touchscreen_threshold")
local event = core.explode_scrollbar_event(fields["sb_sensitivity"])
if event.type == "CHG" then
core.settings:set("mouse_sensitivity", event.value / 2000)
-- The formspec cannot be updated or the scrollbar movement will
-- break.
ddhandled = false
end
end
return ddhandled

View File

@ -489,13 +489,11 @@ void Camera::updateViewingRange()
{
f32 viewing_range = g_settings->getFloat("viewing_range");
f32 near_plane = g_settings->getFloat("near_plane");
if (m_draw_control.extended_range)
viewing_range *= 3;
m_draw_control.wanted_range = viewing_range;
m_cameranode->setNearValue(rangelim(near_plane, 0.0f, 0.5f) * BS);
if (m_draw_control.range_all) {
m_cameranode->setFarValue(100000.0);
return;
}
m_cameranode->setFarValue((viewing_range < 2000) ? 2000 * BS : viewing_range * BS);
m_cameranode->setFarValue(m_draw_control.range_all ? 100000.0 : std::max(2000.0f, viewing_range) * BS);
}
void Camera::setDigging(s32 button)

View File

@ -156,7 +156,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
if (!g_menuclouds)
g_menuclouds = new Clouds(g_menucloudsmgr->getRootSceneNode(),
g_menucloudsmgr, -1, rand(), 100);
g_menuclouds->update(v2f(0, 0), video::SColor(255, 200, 200, 255));
g_menuclouds->update({0, 0, 0}, video::SColor(255, 200, 200, 255));
scene::ICameraSceneNode* camera;
camera = g_menucloudsmgr->addCameraSceneNode(0,
v3f(0, 0, 0), v3f(0, 60, 100));

View File

@ -40,6 +40,7 @@ struct MapDrawControl
}
// Overrides limits by drawing everything
bool range_all;
bool extended_range = false;
// Wanted drawing range
float wanted_range;
// Maximum number of blocks to draw

View File

@ -36,6 +36,21 @@ static void cloud_3d_setting_changed(const std::string &settingname, void *data)
((Clouds *)data)->readSettings();
}
static const std::vector<u16> quad_indices = []() {
int quad_count = 0x10000 / 4; // max number of quads that can be drawn with 16-bit indices
std::vector<u16> indices;
indices.reserve(quad_count * 6);
for (int k = 0; k < quad_count; k++) {
indices.push_back(4 * k + 0);
indices.push_back(4 * k + 1);
indices.push_back(4 * k + 2);
indices.push_back(4 * k + 2);
indices.push_back(4 * k + 3);
indices.push_back(4 * k + 0);
}
return indices;
}();
Clouds::Clouds(
scene::ISceneNode* parent,
scene::ISceneManager* mgr,
@ -45,7 +60,7 @@ Clouds::Clouds(
):
scene::ISceneNode(parent, mgr, id),
m_seed(seed),
m_camera_pos(0.0f, 0.0f),
m_camera_pos(0.0f, 0.0f, 0.0f),
m_origin(0.0f, 0.0f),
m_camera_offset(0.0f, 0.0f, 0.0f),
m_color(1.0f, 1.0f, 1.0f, 1.0f)
@ -90,8 +105,6 @@ void Clouds::OnRegisterSceneNode()
ISceneNode::OnRegisterSceneNode();
}
#define MYROUND(x) (x > 0.0 ? (int)x : (int)x - 1)
void Clouds::render()
{
@ -122,13 +135,13 @@ void Clouds::render()
const float cloud_full_radius = cloud_size * m_cloud_radius_i;
// Position of cloud noise origin from the camera
v2f cloud_origin_from_camera_f = m_origin - m_camera_pos;
v2f cloud_origin_from_camera_f = m_origin - v2f(m_camera_pos.X, m_camera_pos.Z);
// The center point of drawing in the noise
v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f;
// The integer center point of drawing in the noise
v2s16 center_of_drawing_in_noise_i(
MYROUND(center_of_drawing_in_noise_f.X / cloud_size),
MYROUND(center_of_drawing_in_noise_f.Y / cloud_size)
std::floor(center_of_drawing_in_noise_f.X / cloud_size),
std::floor(center_of_drawing_in_noise_f.Y / cloud_size)
);
// The world position of the integer center point of drawing in the noise
v2f world_center_of_drawing_in_noise_f = v2f(
@ -175,8 +188,14 @@ void Clouds::render()
// Read noise
bool *grid = new bool[m_cloud_radius_i * 2 * m_cloud_radius_i * 2];
const int grid_length = 2 * m_cloud_radius_i;
std::vector<bool> grid(grid_length * grid_length);
auto grid_index = [&] (int x, int z) -> int {
return (z + m_cloud_radius_i) * grid_length + (x + m_cloud_radius_i);
};
auto grid_point = [&] (int x, int z) -> bool {
return grid[grid_index(x, z)];
};
float cloud_size_noise = cloud_size / BS / 200;
for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) {
@ -201,150 +220,78 @@ void Clouds::render()
}
}
#define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius))
#define INAREA(x, z, radius) \
((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius))
const float camera_y = m_camera_pos.Y;
const float rel_y = camera_y - m_params.height * BS;
const bool draw_top = !m_enable_3d || rel_y >= m_params.thickness * BS;
const bool draw_bottom = rel_y < 0.0f;
for (s16 zi0= -m_cloud_radius_i; zi0 < m_cloud_radius_i; zi0++)
for (s16 xi0= -m_cloud_radius_i; xi0 < m_cloud_radius_i; xi0++)
const v3f origin = v3f(world_center_of_drawing_in_noise_f.X, m_params.height * BS, world_center_of_drawing_in_noise_f.Y) - intToFloat(m_camera_offset, BS);
const f32 rx = cloud_size;
// if clouds are flat, the top layer should be at the given height
const f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f;
const f32 rz = cloud_size;
// std::vector is great but it is slow
// reserve+push/insert is slow because extending needs to check vector size
// resize+direct access is slow because resize initializes the whole vector
// so... malloc! it can't overflow as there can't be more than 6 quads per grid cell
video::S3DVertex *buf = (video::S3DVertex *)malloc(grid.size() * num_faces_to_draw * 4 * sizeof(video::S3DVertex));
video::S3DVertex *pv = buf;
const v3f faces[6][4] = {
{{0, ry, 0}, {0, ry, rz}, {rx, ry, rz}, {rx, ry, 0}}, // top
{{0, ry, 0}, {rx, ry, 0}, {rx, 0, 0}, {0, 0, 0}}, // back
{{rx, ry, 0}, {rx, ry, rz}, {rx, 0, rz}, {rx, 0, 0}}, // right
{{rx, ry, rz}, {0, ry, rz}, {0, 0, rz}, {rx, 0, rz}}, // front
{{0, ry, rz}, {0, ry, 0}, {0, 0, 0}, {0, 0, rz}}, // left
{{rx, 0, rz}, {0, 0, rz}, {0, 0, 0}, {rx, 0, 0}}, // bottom
};
const v3f normals[6] = {{0, 1, 0}, {0, 0, -1}, {1, 0, 0}, {0, 0, 1}, {-1, 0, 0}, {0, -1, 0}};
const video::SColor colors[6] = {c_top, c_side_1, c_side_2, c_side_1, c_side_2, c_bottom};
const v2f tex_coords[4] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
// Draw from back to front for proper transparency
for (s16 zi0= 1-(int)m_cloud_radius_i; zi0 < m_cloud_radius_i-1; zi0++)
for (s16 xi0= 1-(int)m_cloud_radius_i; xi0 < m_cloud_radius_i-1; xi0++)
{
s16 zi = zi0;
s16 xi = xi0;
// Draw from front to back (needed for transparency)
/*if(zi <= 0)
zi = -m_cloud_radius_i - zi;
if(xi <= 0)
xi = -m_cloud_radius_i - xi;*/
// Draw from back to front
if(zi >= 0)
zi = m_cloud_radius_i - zi - 1;
if(xi >= 0)
xi = m_cloud_radius_i - xi - 1;
if (zi >= 0)
zi = m_cloud_radius_i - zi - 2;
if (xi >= 0)
xi = m_cloud_radius_i - xi - 2;
u32 i = GETINDEX(xi, zi, m_cloud_radius_i);
if(grid[i] == false)
if (!grid_point(xi, zi))
continue;
v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f;
video::S3DVertex v[4] = {
video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1),
video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1),
video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0),
video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0)
bool do_draw[6] = {
draw_top,
zi > 0 && !grid_point(xi, zi - 1),
xi < 0 && !grid_point(xi + 1, zi),
zi < 0 && !grid_point(xi, zi + 1),
xi > 0 && !grid_point(xi - 1, zi),
draw_bottom,
};
/*if(zi <= 0 && xi <= 0){
v[0].Color.setBlue(255);
v[1].Color.setBlue(255);
v[2].Color.setBlue(255);
v[3].Color.setBlue(255);
}*/
f32 rx = cloud_size / 2.0f;
// if clouds are flat, the top layer should be at the given height
f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f;
f32 rz = cloud_size / 2;
for(int i=0; i<num_faces_to_draw; i++)
{
switch(i)
{
case 0: // top
for(int j=0;j<4;j++){
v[j].Normal.set(0,1,0);
}
v[0].Pos.set(-rx, ry,-rz);
v[1].Pos.set(-rx, ry, rz);
v[2].Pos.set( rx, ry, rz);
v[3].Pos.set( rx, ry,-rz);
break;
case 1: // back
if (INAREA(xi, zi - 1, m_cloud_radius_i)) {
u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_1;
v[j].Normal.set(0,0,-1);
}
v[0].Pos.set(-rx, ry,-rz);
v[1].Pos.set( rx, ry,-rz);
v[2].Pos.set( rx, 0,-rz);
v[3].Pos.set(-rx, 0,-rz);
break;
case 2: //right
if (INAREA(xi + 1, zi, m_cloud_radius_i)) {
u32 j = GETINDEX(xi+1, zi, m_cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_2;
v[j].Normal.set(1,0,0);
}
v[0].Pos.set( rx, ry,-rz);
v[1].Pos.set( rx, ry, rz);
v[2].Pos.set( rx, 0, rz);
v[3].Pos.set( rx, 0,-rz);
break;
case 3: // front
if (INAREA(xi, zi + 1, m_cloud_radius_i)) {
u32 j = GETINDEX(xi, zi + 1, m_cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_1;
v[j].Normal.set(0,0,-1);
}
v[0].Pos.set( rx, ry, rz);
v[1].Pos.set(-rx, ry, rz);
v[2].Pos.set(-rx, 0, rz);
v[3].Pos.set( rx, 0, rz);
break;
case 4: // left
if (INAREA(xi-1, zi, m_cloud_radius_i)) {
u32 j = GETINDEX(xi-1, zi, m_cloud_radius_i);
if(grid[j])
continue;
}
for(int j=0;j<4;j++){
v[j].Color = c_side_2;
v[j].Normal.set(-1,0,0);
}
v[0].Pos.set(-rx, ry, rz);
v[1].Pos.set(-rx, ry,-rz);
v[2].Pos.set(-rx, 0,-rz);
v[3].Pos.set(-rx, 0, rz);
break;
case 5: // bottom
for(int j=0;j<4;j++){
v[j].Color = c_bottom;
v[j].Normal.set(0,-1,0);
}
v[0].Pos.set( rx, 0, rz);
v[1].Pos.set(-rx, 0, rz);
v[2].Pos.set(-rx, 0,-rz);
v[3].Pos.set( rx, 0,-rz);
break;
v3f const pos = origin + v3f(xi, 0.0f, zi) * cloud_size;
for (int i = 0; i < num_faces_to_draw; i++) {
if (!do_draw[i])
continue;
for (int k = 0; k < 4; k++) {
pv->Pos = pos + faces[i][k];
pv->Normal = normals[i];
pv->Color = colors[i];
pv->TCoords = tex_coords[k];
pv++;
}
v3f pos(p0.X, m_params.height * BS, p0.Y);
pos -= intToFloat(m_camera_offset, BS);
for(u16 i=0; i<4; i++)
v[i].Pos += pos;
u16 indices[] = {0,1,2,2,3,0};
driver->drawVertexPrimitiveList(v, 4, indices, 2,
video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
}
}
int vertex_count = pv - buf;
int quad_count = vertex_count / 4;
driver->drawVertexPrimitiveList(buf, vertex_count, quad_indices.data(), 2 * quad_count,
video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
free(buf);
delete[] grid;
// Restore fog settings
driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density,
fog_pixelfog, fog_rangefog);
@ -355,7 +302,7 @@ void Clouds::step(float dtime)
m_origin = m_origin + dtime * BS * m_params.speed;
}
void Clouds::update(v2f camera_p, video::SColorf color_diffuse)
void Clouds::update(v3f camera_p, video::SColorf color_diffuse)
{
m_camera_pos = camera_p;
m_color.r = MYMIN(MYMAX(color_diffuse.r * m_params.color_bright.getRed(),

View File

@ -75,7 +75,7 @@ public:
void step(float dtime);
void update(v2f camera_p, video::SColorf color);
void update(v3f camera_p, video::SColorf color);
void updateCameraOffset(v3s16 camera_offset)
{
@ -133,7 +133,7 @@ private:
u16 m_cloud_radius_i;
bool m_enable_3d;
u32 m_seed;
v2f m_camera_pos;
v3f m_camera_pos;
v2f m_origin;
v2f m_speed;
v3s16 m_camera_offset;

View File

@ -1291,6 +1291,7 @@ protected:
void increaseViewRange();
void decreaseViewRange();
void toggleExtendedViewRange();
void toggleFullViewRange();
void updateCameraDirection(CameraOrientation *cam, float dtime);
@ -2624,7 +2625,11 @@ void Game::processKeyInput()
} else if (wasKeyDown(KeyType::DECREASE_VIEWING_RANGE)) {
decreaseViewRange();
} else if (wasKeyDown(KeyType::RANGESELECT)) {
#if defined(__ANDROID__) || defined(__IOS__)
toggleExtendedViewRange();
#else
toggleFullViewRange();
#endif
} else if (wasKeyDown(KeyType::QUICKTUNE_NEXT)) {
quicktune->next();
} else if (wasKeyDown(KeyType::QUICKTUNE_PREV)) {
@ -3028,19 +3033,26 @@ void Game::decreaseViewRange()
}
void Game::toggleFullViewRange()
void Game::toggleExtendedViewRange()
{
#if defined(__ANDROID__) || defined(__IOS__)
static const wchar_t *msg[] = {
L"Disabled far viewing range",
L"Enabled far viewing range"
};
#else
draw_control->extended_range = !draw_control->extended_range;
infostream << msg[draw_control->extended_range] << std::endl;
m_statustext = msg[draw_control->extended_range];
runData.statustext_time = 0;
}
void Game::toggleFullViewRange()
{
static const wchar_t *msg[] = {
L"Normal view range",
L"Infinite view range"
};
#endif
draw_control->range_all = !draw_control->range_all;
infostream << msg[draw_control->range_all] << std::endl;
@ -4221,12 +4233,10 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
Update clouds
*/
if (clouds) {
v3f player_position = player->getPosition();
if (sky->getCloudsVisible()) {
clouds->setVisible(true);
clouds->step(dtime);
clouds->update(v2f(player_position.X, player_position.Z),
sky->getCloudColor());
clouds->update(camera->getPosition(), sky->getCloudColor());
} else {
clouds->setVisible(false);
}

View File

@ -383,7 +383,7 @@ void GUIEngine::cloudInit()
{
m_cloud.clouds = new Clouds(m_smgr->getRootSceneNode(),
m_smgr, -1, rand(), 100);
m_cloud.clouds->update(v2f(0, 0), video::SColor(255,200,200,255));
m_cloud.clouds->update({0, 0, 0}, video::SColor(255,200,200,255));
m_cloud.camera = m_smgr->addCameraSceneNode(0,
v3f(0,0,0), v3f(0, 60, 100));

View File

@ -2101,6 +2101,20 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
double fitx_imgsize;
double fity_imgsize;
#if defined(__ANDROID__) || defined(__IOS__)
fitx_imgsize = mydata.screensize.X /
((5.0 / 4.0) * (0.5 + mydata.invsize.X));
fity_imgsize = mydata.screensize.Y /
((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
// In Android, the preferred imgsize should be larger to accommodate the
// smaller screensize.
double prefer_imgsize = mydata.screensize.Y / 10 * gui_scaling;
// Try to fit 13 coordinates on large tablets.
if (g_settings->getBool("device_is_tablet"))
prefer_imgsize = mydata.screensize.Y / 13 * gui_scaling;
#else
// Pad the screensize with 5% of the screensize on all sides to ensure
// that even the largest formspecs don't touch the screen borders.
v2f padded_screensize(
@ -2108,32 +2122,13 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
mydata.screensize.Y * 0.9f
);
fitx_imgsize = mydata.screensize.X /
((5.0 / 4.0) * (0.5 + mydata.invsize.X));
fity_imgsize = mydata.screensize.Y /
((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
#if defined(__ANDROID__) || defined(__IOS__)
// In Android, the preferred imgsize should be larger to accommodate the
// smaller screensize.
double prefer_imgsize = mydata.screensize.Y / 10 * gui_scaling;
// Try to fit 13 coordinates on large tablets.
if (g_settings->getBool("device_is_tablet"))
prefer_imgsize = padded_screensize.Y / 13 * gui_scaling;
fitx_imgsize = floor(mydata.screensize.X /
(1.5 * (0.5 + mydata.invsize.X)));
fity_imgsize = floor(mydata.screensize.Y /
(1.15 * (0.85 + mydata.invsize.Y)));
#else
// Desktop computers have more space, so try to fit 15 coordinates.
double prefer_imgsize = padded_screensize.Y / 15 * gui_scaling;
fitx_imgsize = padded_screensize.X /
((5.0 / 4.0) * (0.5 + mydata.invsize.X));
fity_imgsize = padded_screensize.Y /
((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
// Desktop computers have more space, so try to fit 15 coordinates.
double prefer_imgsize = padded_screensize.Y / 15 * gui_scaling;
#endif
// Try to use the preferred imgsize, but if that's bigger than the maximum
// size, use the maximum size.

View File

@ -657,7 +657,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
s32 dy = Y - m_pointerpos[event.TouchInput.ID].Y;
// adapt to similar behaviour as pc screen
double d = g_settings->getFloat("mouse_sensitivity");
double d = rangelim(g_settings->getFloat("mouse_sensitivity"), 0.1, 1.0);
m_camera_yaw_change -= dx * d;
m_camera_pitch = MYMIN(MYMAX(m_camera_pitch + (dy * d), -180), 180);