implement radar and fix hunt gem counter color

This commit is contained in:
RandomityGuy 2024-06-18 00:54:56 +05:30
parent b3978bb9bb
commit 870474cfed
4 changed files with 284 additions and 9 deletions

View file

@ -1,5 +1,6 @@
package src;
import src.Radar;
import rewind.InputRecorder;
import net.NetPacket.ScoreboardPacket;
import net.NetPacket.PowerupPickupPacket;
@ -135,6 +136,7 @@ class MarbleWorld extends Scheduler {
var playGui:PlayGui;
var loadingGui:LoadingGui;
var radar:Radar;
public var interiors:Array<InteriorObject> = [];
public var pathedInteriors:Array<PathedInterior> = [];
@ -380,6 +382,10 @@ class MarbleWorld extends Scheduler {
this.playGui = new PlayGui();
this.instanceManager = new InstanceManager(scene);
this.particleManager = new ParticleManager(cast this);
if (this.isMultiplayer || this.game == "ultra") {
this.radar = new Radar(cast this, this.scene2d);
radar.init();
}
var worker = new ResourceLoaderWorker(() -> {
var renderer = cast(this.scene.renderer, h3d.scene.fwd.Renderer);
@ -647,6 +653,9 @@ class MarbleWorld extends Scheduler {
this.playGui.formatGemCounter(this.gemCount, this.totalGems);
}
if (radar != null)
radar.reset();
// Record/Playback trapdoor and landmine states
if (full) {
var tidx = 0;
@ -1670,6 +1679,8 @@ class MarbleWorld extends Scheduler {
}
}
if (radar != null)
radar.update(dt);
this.updateGameState();
if (!this.isMultiplayer)
this.updateBlast(this.marble, timeState);
@ -1815,6 +1826,8 @@ class MarbleWorld extends Scheduler {
this.marble.cubemapRenderer.render(e, 0.002);
}
if (_instancesNeedsUpdate) {
if (this.radar != null)
this.radar.render();
_instancesNeedsUpdate = false;
this.instanceManager.render();
}
@ -2659,6 +2672,11 @@ class MarbleWorld extends Scheduler {
this.playGui.dispose();
scene.removeChildren();
if (radar != null) {
radar.dispose();
radar = null;
}
CollisionPool.freeMemory();
for (interior in this.interiors) {

208
src/Radar.hx Normal file
View file

@ -0,0 +1,208 @@
package src;
import hxd.res.BitmapFont;
import h3d.Matrix;
import src.DtsObject;
import h3d.Vector;
import gui.Graphics;
import src.GameObject;
import h2d.Scene;
import src.MarbleWorld;
import src.Util;
import src.Marble;
import src.Settings;
import src.ResourceLoader;
class Radar {
var level:MarbleWorld;
var scene2d:Scene;
var g:Graphics;
var marbleNameTexts:Map<Marble, h2d.Text>;
public var ellipseScreenFraction = new Vector(0.79, 0.85);
public var fullArrowLength = 60.0;
public var fullArrowWidth = 40.0;
public var maxArrowAlpha = 0.6;
public var maxTargetAlpha = 0.4;
public var minArrowFraction = 0.4;
var radarTiles:Array<h2d.Tile>;
var time:Float = 0.0;
var _dirty = false;
public function new(level:MarbleWorld, scene2d:Scene) {
this.level = level;
this.scene2d = scene2d;
this.marbleNameTexts = [];
var radarTileRedGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemRed.png").resource.toTile();
var radarTileYellowGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemYellow.png").resource.toTile();
var radarTileBlueGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemBlue.png").resource.toTile();
var radarTileGreenGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemGreen.png").resource.toTile();
var radarTileOrangeGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemOrange.png").resource.toTile();
var radarTilePinkGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemPink.png").resource.toTile();
var radarTilePurpleGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemPurple.png").resource.toTile();
var radarTileTurquoiseGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemTurquoise.png").resource.toTile();
var radarTileBlackGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemBlack.png").resource.toTile();
var radarTilePlatinumGem = ResourceLoader.getImage("data/ui/mp/radar/GemItemPlatinum.png").resource.toTile();
var radarTileEndPad = ResourceLoader.getImage("data/ui/mp/radar/EndPad.png").resource.toTile();
radarTiles = [
radarTileRedGem, radarTileYellowGem, radarTileBlueGem, radarTileGreenGem, radarTileOrangeGem, radarTilePinkGem, radarTilePurpleGem,
radarTileTurquoiseGem, radarTileBlackGem, radarTilePlatinumGem, radarTileEndPad
];
}
public function init() {
g = new Graphics(scene2d);
}
public function update(dt:Float) {
time += dt;
_dirty = true;
}
public function render() {
if (!_dirty)
return;
g.clear();
var gemCount = 0;
for (gem in level.gems) {
if (!gem.pickedUp) {
renderArrow(gem.boundingCollider.boundingBox.getCenter().toVector(), gem.radarGemColor, radarTiles[gem.radarGemIndex]);
gemCount++;
}
}
if (@:privateAccess level.endPad != null && gemCount == 0) {
renderArrow(@:privateAccess level.endPad.getAbsPos().getPosition(), 0xE6E6E6, radarTiles[10]);
}
var fadeDistance = level.scene.camera.zFar * 0.1;
for (marble => marbleName in marbleNameTexts) {
if (marbleName != null)
marbleName.alpha = 0;
}
for (marble in level.marbles) {
if (marble != level.marble) {
var shapePos = marble.getAbsPos().getPosition();
var shapeDir = shapePos.sub(level.scene.camera.pos);
var shapeDist = shapeDir.lengthSq();
if (shapeDist == 0 || shapeDist > level.scene.camera.zFar * level.scene.camera.zFar) {
dontRenderName(marble);
continue;
}
var validProjection = frustumHasPoint(level.scene.camera.frustum, shapePos);
if (!validProjection) {
dontRenderName(marble);
continue;
}
shapePos.z += 0.5; // Vertical offset
var projectedPos = level.scene.camera.project(shapePos.x, shapePos.y, shapePos.z, scene2d.width, scene2d.height);
var opacity = (shapeDist < fadeDistance) ? 1.0 : (1.0 - (shapeDist - fadeDistance) / (level.scene.camera.zFar - fadeDistance));
renderName(projectedPos, marble, opacity);
}
}
_dirty = false;
}
public function blink() {
time = 0;
}
public function reset() {
time = 0;
g.clear();
}
public function dispose() {
g.clear();
scene2d.removeChild(g);
g = null;
for (txt in marbleNameTexts) {
if (txt != null) {
scene2d.removeChild(txt);
}
}
marbleNameTexts = null;
}
inline function planeDistance(plane:h3d.col.Plane, p:Vector) {
return @:privateAccess plane.nx * p.x + @:privateAccess plane.ny * p.y + @:privateAccess plane.nz * p.z - @:privateAccess plane.d;
}
function frustumHasPoint(frustum:h3d.col.Frustum, p:Vector) {
if (planeDistance(frustum.pleft, p) < 0)
return false;
if (planeDistance(frustum.pright, p) < 0)
return false;
if (planeDistance(frustum.ptop, p) < 0)
return false;
if (planeDistance(frustum.pbottom, p) < 0)
return false;
if (frustum.checkNearFar) {
if (planeDistance(frustum.pnear, p) < 0)
return false;
if (planeDistance(frustum.pfar, p) < 0)
return false;
}
return true;
}
function renderArrow(pos:Vector, color:Int, tile:h2d.Tile) {
var validProjection = frustumHasPoint(level.scene.camera.frustum, pos);
var projectedPos = level.scene.camera.project(pos.x, pos.y, pos.z, scene2d.width, scene2d.height);
if (validProjection && tile != null) {
g.lineStyle(0, 0, 0);
g.drawTile(projectedPos.x - tile.width / 2, projectedPos.y - tile.height / 2, tile);
} else if (!validProjection) {
var centerDiff = projectedPos.sub(new Vector(scene2d.width / 2, scene2d.height / 2));
var theta = Math.atan2(centerDiff.y, centerDiff.x);
if (projectedPos.z > 1)
theta += Math.PI;
var ellipsePos = new Vector(scene2d.width * (ellipseScreenFraction.x * Math.cos(theta) + 1) / 2,
scene2d.height * (ellipseScreenFraction.y * Math.sin(theta) + 1) / 2);
var arrowDir = projectedPos.sub(new Vector(scene2d.width / 2, scene2d.height / 2)).normalized();
var arrowDirPerp = new Vector(-arrowDir.y, arrowDir.x);
if (projectedPos.z > 1)
arrowDir.scale(-1);
var tipPosition = ellipsePos.add(arrowDir.multiply(fullArrowLength));
var tipUpperPosition = ellipsePos.add(arrowDirPerp.multiply(fullArrowWidth / 2));
var tipLowerPosition = ellipsePos.add(arrowDirPerp.multiply(-fullArrowWidth / 2));
g.beginFill(color, 0.6);
g.lineStyle(1, 0, 0.6);
g.moveTo(tipPosition.x, tipPosition.y);
g.lineTo(tipUpperPosition.x, tipUpperPosition.y);
g.lineTo(tipLowerPosition.x, tipLowerPosition.y);
g.endFill();
}
}
function renderName(pos:Vector, marble:Marble, opacity:Float) {
if (!marbleNameTexts.exists(marble)) {
var arialb14fontdata = ResourceLoader.getFileEntry("data/font/Arial Bold.fnt");
var arialb14b = new BitmapFont(arialb14fontdata.entry);
@:privateAccess arialb14b.loader = ResourceLoader.loader;
var arialBold14 = arialb14b.toSdfFont(cast 16 * Settings.uiScale, MultiChannel);
var txt = new h2d.Text(arialBold14, scene2d);
marbleNameTexts.set(marble, txt);
txt.textColor = 0xFFFF00;
}
var textObj = marbleNameTexts.get(marble);
textObj.text = @:privateAccess marble.connection.getName();
textObj.setPosition(pos.x - textObj.textWidth / 2, pos.y - textObj.textHeight);
textObj.alpha = opacity;
}
function dontRenderName(marble:Marble) {
if (marbleNameTexts.exists(marble)) {
marbleNameTexts.get(marble).alpha = 0;
}
}
}

View file

@ -774,20 +774,26 @@ class PlayGui {
}
public function formatGemHuntCounter(collected:Int) {
gemCountNumbers[0].anim.visible = true;
gemCountNumbers[1].anim.visible = true;
var collectedHundredths = Math.floor(collected / 100);
var collectedTenths = Math.floor(collected / 10) % 10;
var collectedOnes = collected % 10;
if (collected >= 100)
gemCountNumbers[0].anim.visible = true;
else
gemCountNumbers[0].anim.visible = false;
if (collected >= 10)
gemCountNumbers[1].anim.visible = true;
else
gemCountNumbers[1].anim.visible = false;
gemCountNumbers[2].anim.visible = true;
gemCountNumbers[3].anim.visible = false;
gemCountNumbers[4].anim.visible = false;
gemCountNumbers[5].anim.visible = false;
var collectedHundredths = Math.floor(collected / 100);
var collectedTenths = Math.floor(collected / 10) % 10;
var collectedOnes = collected % 10;
gemCountNumbers[0].anim.currentFrame = collectedHundredths;
gemCountNumbers[1].anim.currentFrame = collectedTenths;
gemCountNumbers[2].anim.currentFrame = collectedOnes;
gemCountNumbers[0].anim.currentFrame = 10 + collectedHundredths;
gemCountNumbers[1].anim.currentFrame = 10 + collectedTenths;
gemCountNumbers[2].anim.currentFrame = 10 + collectedOnes;
gemCountSlash.bmp.visible = false;
gemImageSceneTargetBitmap.visible = true;
}

View file

@ -13,6 +13,8 @@ class Gem extends DtsObject {
public var pickedUp:Bool;
public var netIndex:Int;
public var pickUpClient:Int = -1;
public var radarGemColor:Int;
public var radarGemIndex:Int;
var gemColor:String;
@ -33,6 +35,47 @@ class Gem extends DtsObject {
this.identifier = "Gem" + color;
this.matNameOverride.set('base.gem', color + ".gem");
gemColor = color + ".gem";
var colLower = color.toLowerCase();
switch (colLower) {
case "red":
radarGemColor = 0xFF0000;
radarGemIndex = 0;
case "blue":
radarGemColor = 0x6666E6;
radarGemIndex = 2;
case "yellow":
radarGemColor = 0xFEFF00;
radarGemIndex = 1;
case "green":
radarGemColor = 0x66E666;
radarGemIndex = 3;
case "orange":
radarGemColor = 0xE6BA66;
radarGemIndex = 4;
case "pink":
radarGemColor = 0xE666E5;
radarGemIndex = 5;
case "purple":
radarGemColor = 0xC566E6;
radarGemIndex = 6;
case "turquoise":
radarGemColor = 0x66E5E6;
radarGemIndex = 7;
case "black":
radarGemColor = 0x666666;
radarGemIndex = 8;
case "platinum":
radarGemColor = 0xA5A5A5;
radarGemIndex = 9;
}
}
public override function init(level:MarbleWorld, onFinish:Void->Void) {