Files
2018-07-17 14:15:37 +02:00

313 lines
6.6 KiB
ActionScript

import navigation.SmartCamera;
from input import activeCamera, mouseToGrid;
from gui import isGuiHovered;
import abilities;
import targeting.targeting;
import tabs.Tab;
import tabs.tabbar;
import Tab@ createGalaxyTab() from "tabs.GalaxyTab";
class PointTargeting {
Tab@ returnTo;
Sprite icon(spritesheet::ContextIcons, 1);
bool allowMultiple = false;
bool valid(const vec3d& pos) {
return true;
}
string message(const vec3d& pos, bool valid) {
return "";
}
void call(const vec3d& pos) {
}
string desc(const vec3d& point, bool valid) {
return "";
}
double radius(const vec3d& point) {
return 0.0;
}
Color get_color() {
return Color(0x00000000);
}
};
class AbilityTargetPoint : PointTargeting {
Ability@ abl;
Targets@ targs;
AbilityTargetPoint(Ability@ abl) {
@this.abl = abl;
icon = abl.type.icon;
@targs = Targets(abl.type.targets);
}
bool valid(const vec3d& target) override {
targs.fill(0).point = target;
return abl.canActivate(targs);
}
void call(const vec3d& target) override {
double range = abl.getRange(targs);
if(abl.obj !is null && abl.obj.hasLeaderAI && range != INFINITY)
abl.obj.addAbilityOrder(abl.id, target, range, shiftKey);
else if(abl.obj !is null)
abl.obj.activateAbility(abl.id, target);
else
abl.emp.activateAbility(abl.id, target);
if(abl.type.activateSound !is null)
abl.type.activateSound.play(priority=true);
}
string message(const vec3d& target, bool valid) override {
return abl.type.name;
}
string desc(const vec3d& point, bool valid) {
if(!valid) {
string err = abl.getTargetError(targs);
if(err.length != 0)
return err;
}
double cost = abl.getEnergyCost(targs);
if(cost != 0 && cost != abl.type.energyCost)
return format("$1 $2", toString(cost,0), locale::RESOURCE_ENERGY);
return "";
}
};
class PointTargetMode : TargetMode {
PointTargeting@ targ;
vec3d hovered;
bool hover(const vec2i& mouse) override {
hovered = mouseToGrid(mouse);
if(!targ.valid(hovered))
return false;
return true;
}
bool click() override {
if(!targ.valid(hovered))
return false;
return true;
}
string get_message() override {
return targ.message(hovered, valid);
}
string get_desc() override {
return targ.desc(hovered, valid);
}
double get_radius() {
return targ.radius(hovered);
}
};
class PointTargetDisplay : TargetVisuals {
PointTargeting@ targ;
void draw(TargetMode@ mode) override {
if(isGuiHovered())
return;
Color color = targ.color;
if(color.a == 0) {
if(mode.valid)
color = Color(0x00ff00ff);
else
color = Color(0xff0000ff);
}
//Draw the cursor
drawLine(mousePos-vec2i(40, 0), mousePos+vec2i(40,0), color, 2);
drawLine(mousePos-vec2i(0, 40), mousePos+vec2i(0,40), color, 2);
targ.icon.draw(recti_area(mousePos-vec2i(20,20), vec2i(40,40)), color);
//Draw the message
const Font@ ft = font::DroidSans_11_Bold;
string err = mode.desc;
if(err.length != 0) {
ft.draw(recti_area(mousePos-vec2i(200,85), vec2i(400, 20)), mode.message, horizAlign=0.5, color=color);
@ft = font::OpenSans_11_Italic;
ft.draw(recti_area(mousePos-vec2i(200,65), vec2i(400, 20)), err, horizAlign=0.5, color=color);
}
else {
ft.draw(recti_area(mousePos-vec2i(200,65), vec2i(400, 20)), mode.message, horizAlign=0.5, color=color);
}
}
};
class PointTargetCB : TargetCallback {
PointTargeting@ targ;
void call(TargetMode@ mode) override {
if(targ.returnTo !is null) {
if(targ.returnTo is ActiveTab.previous)
popTab(ActiveTab);
else
switchToTab(targ.returnTo);
}
targ.call(cast<PointTargetMode>(mode).hovered);
}
};
void targetPoint(PointTargeting@ target, Tab@ returnTo = null, bool gotoTab = true) {
PointTargetMode targ;
PointTargetDisplay disp;
PointTargetCB cb;
@target.returnTo = returnTo;
@targ.targ = target;
@disp.targ = target;
@cb.targ = target;
startTargeting(targ, disp, cb);
if(target.allowMultiple)
targ.autoMultiple = true;
if(gotoTab) {
Tab@ tab = findTab(TC_Galaxy);
if(tab !is null) {
switchToTab(tab);
}
else {
if(returnTo !is null)
browseTab(ActiveTab, createGalaxyTab(), true);
else
switchToTab(newTab(createGalaxyTab()));
}
}
}
class PointTarget : TargetMode {
Object@ originObj;
vec3d originPos;
vec3d hovered;
double range = -1.0;
vec3d get_origin() {
if(originObj !is null)
return originObj.node_position;
return originPos;
}
bool hover(const vec2i& mouse) override {
hovered = mouseToGrid(mouse);
return true;
}
bool click() override {
return true;
}
vec3d get_position() override {
return hovered;
}
double get_distance() {
return origin.distanceTo(position);
}
double get_radius() {
return 0.0;
}
};
class PointDisplay : TargetVisuals {
BeamNode@ node;
BeamNode@ node2;
PlaneNode@ plane;
Color inColor = colors::Green;
Color outColor = colors::Red;
Color radiusColor = Color(0x00c0ff80);
PointDisplay() {
@node = BeamNode(material::MoveBeam, 0.002f, vec3d(), vec3d(), true);
node.visible = false;
@node2 = BeamNode(material::MoveBeam, 0.002f, vec3d(), vec3d(), true);
node2.visible = false;
@plane = PlaneNode(material::Circle, 0.0);
plane.visible = false;
plane.color = radiusColor;
}
~PointDisplay() {
node.visible = false;
node.markForDeletion();
node2.visible = false;
node2.markForDeletion();
plane.visible = false;
plane.markForDeletion();
}
void render(TargetMode@ mode) override {
PointTarget@ pt = cast<PointTarget>(mode);
if(pt is null)
return;
if(pt.range >= 0.0 && pt.distance > pt.range) {
vec3d origin = pt.origin;
vec3d target = pt.position;
vec3d dir = (target - origin).normalize(pt.range);
vec3d midpos = origin + dir;
//In range section
node.position = origin;
node.endPosition = midpos;
node.rebuildTransform();
node.color = inColor;
node.visible = true;
//Out of range section
node2.position = midpos;
node2.endPosition = target;
node2.rebuildTransform();
node2.color = outColor;
node2.visible = true;
}
else {
node.position = pt.origin;
node.endPosition = pt.position;
node.rebuildTransform();
node.color = inColor;
node.visible = true;
node2.visible = false;
}
double rad = pt.radius;
if(rad != 0) {
plane.position = pt.position;
plane.scale = rad;
plane.rebuildTransform();
plane.visible = true;
}
else {
plane.visible = false;
}
}
};
void toggleAbilityTargetPoint(Ability@ abl) {
auto@ om = cast<PointTargetMode>(mode);
if(om !is null) {
auto@ t = cast<AbilityTargetPoint>(om.targ);
if(t !is null) {
if(t.abl.obj is abl.obj && t.abl.id == abl.id) {
return;
}
}
}
targetPoint(AbilityTargetPoint(abl));
}