Skip to content

Commit

Permalink
Cleanup /Missile and move to share more code with gun/weapon
Browse files Browse the repository at this point in the history
  • Loading branch information
UnknownShadow200 committed Oct 28, 2020
1 parent 2839383 commit b450374
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 364 deletions.
2 changes: 1 addition & 1 deletion Changelog.txt
@@ -1,4 +1,4 @@
v 1.9.2.6
v 1.9.2.7
Fixed: Awards player has but don't exist anymore still counting towards player's awards count in /i
Fixed: Doing /b on map that had portal/MB block ids but the tables not existing in DB causing error to get logged
Fixed: Being able to /possess yourself
Expand Down
135 changes: 24 additions & 111 deletions MCGalaxy/Commands/Fun/CmdMissile.cs
@@ -1,6 +1,6 @@
/*
Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
Expand All @@ -15,126 +15,39 @@
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Ops;
using MCGalaxy.Maths;
using MCGalaxy.Tasks;
using BlockID = System.UInt16;
using System;
using MCGalaxy.Games;

namespace MCGalaxy.Commands.Fun {
public sealed class CmdMissile : WeaponCmd {

public sealed class CmdMissile : Command2 {
public override string name { get { return "Missile"; } }
protected override string Weapon { get { return "Missile"; } }

protected override void OnActivated(Player p, byte yaw, byte pitch, BlockID block) {
if (!p.staticCommands) {
p.ClearBlockchange();
p.aiming = false;
}

WeaponArgs args = new WeaponArgs();
args.player = p;
args.block = block;
args.weaponType = (WeaponType)p.blockchangeObject;
args.pos = MakePos(p);

SchedulerTask task = new SchedulerTask(MissileCallback, args,
TimeSpan.FromMilliseconds(100), true);
p.CriticalTasks.Add(task);
}

static void MissileCallback(SchedulerTask task) {
WeaponArgs args = (WeaponArgs)task.State;
if (args.moving) { PerformMove(args); return; }

args.TeleportSourcePlayer();
if (args.previous.Count > 0) {
Vec3U16 pos = args.previous[0];
args.previous.RemoveAt(0);
args.player.level.Blockchange(pos.X, pos.Y, pos.Z, Block.Air, true);
}
task.Repeating = args.previous.Count > 0;
}

static void PerformMove(WeaponArgs args) {
while (true) {
args.iterations++;
Vec3U16 target = MissileTarget(args);
FindNext(target, ref args.pos, args.buffer);

if (args.iterations <= 3) continue;
args.moving = MoveMissile(args, args.pos, target);
return;
}
}
public override string type { get { return CommandTypes.Other; } }
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
public override bool SuperUseable { get { return false; } }


static Vec3U16 MissileTarget(WeaponArgs args) {
Player p = args.player;
args.start = MakePos(p);
args.dir = DirUtils.GetDirVector(p.Rot.RotY, p.Rot.HeadX);
int i;

for (i = 1; ; i++) {
Vec3U16 target = args.PosAt(i);
BlockID block = p.level.GetBlock(target.X, target.Y, target.Z);
if (block == Block.Invalid) break;

if (block != Block.Air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, block, args.weaponType, target, false))
break;

Player hit = GetPlayer(p, target, true);
if (hit != null) return MakePos(hit);
public override void Use(Player p, string message, CommandData data) {
if (!p.level.Config.Guns) {
p.Message("Missiles cannot be used on this map!"); return;
}
return args.PosAt(i - 1);
}

static bool MoveMissile(WeaponArgs args, Vec3U16 pos, Vec3U16 target) {
Player p = args.player;
BlockID block = p.level.GetBlock(pos.X, pos.Y, pos.Z);
if (block != Block.Air && !args.allBlocks.Contains(pos) && HandlesHitBlock(p, block, args.weaponType, pos, true))
return false;

p.level.Blockchange(pos.X, pos.Y, pos.Z, args.block);
args.previous.Add(pos);
args.allBlocks.Add(pos);
if (HitsPlayer(args, pos)) return false;

if (pos == target && p.level.physics >= 3 && args.weaponType >= WeaponType.Explode) {
p.level.MakeExplosion(target.X, target.Y, target.Z, 2);
return false;
if (p.weapon != null && message.Length == 0) {
p.weapon.Disable(); return;
}

if (args.previous.Count > 12) {
pos = args.previous[0];
p.level.Blockchange(pos.X, pos.Y, pos.Z, Block.Air, true);
args.previous.RemoveAt(0);
}
return true;
}

static bool HitsPlayer(WeaponArgs args, Vec3U16 pos) {
Player pl = GetPlayer(args.player, pos, true);
if (pl == null) return false;
WeaponType weaponType = GetWeaponType(p, message);
if (weaponType == WeaponType.Invalid) { Help(p); return; }

Player p = args.player;
if (p.level.physics >= 3 && args.weaponType >= WeaponType.Explode) {
pl.HandleDeath(Block.Cobblestone, "@p %Swas blown up by " + p.ColoredName, true);
} else {
pl.HandleDeath(Block.Cobblestone, "@p %Swas hit by a missile from " + p.ColoredName);
}
return true;
Missile missile = new Missile();
missile.type = weaponType;
missile.Enable(p);
}

static Vec3U16 MakePos(Player p) { return (Vec3U16)p.Pos.BlockCoords; }

static void FindNext(Vec3U16 lookedAt, ref Vec3U16 pos, List<Vec3S32> buffer) {
LineDrawOp.DrawLine(pos.X, pos.Y, pos.Z, 2, lookedAt.X, lookedAt.Y, lookedAt.Z, buffer);
Vec3U16 end = (Vec3U16)buffer[buffer.Count - 1];
pos.X = end.X; pos.Y = end.Y; pos.Z = end.Z;
buffer.Clear();
WeaponType GetWeaponType(Player p, string mode) {
if (mode.Length == 0) return WeaponType.Normal;
if (mode.CaselessEq("destroy")) return WeaponType.Destroy;
if (mode.CaselessEq("tp") || mode.CaselessEq("teleport")) return WeaponType.Teleport;
if (mode.CaselessEq("explode")) return WeaponType.Explode;
if (mode.CaselessEq("laser")) return WeaponType.Laser;
return WeaponType.Invalid;
}

public override void Help(Player p) {
Expand Down

0 comments on commit b450374

Please sign in to comment.