4
#include "current_generator.hpp"
5
#include "formatter.hpp"
6
#include "wml_node.hpp"
7
#include "wml_utils.hpp"
9
current_generator_ptr current_generator::create(wml::const_node_ptr node)
11
const std::string& type = node->attr("type");
12
if(type == "radial") {
13
return current_generator_ptr(new radial_current_generator(node));
14
} else if(type == "rect") {
15
return current_generator_ptr(new rect_current_generator(node));
21
current_generator::~current_generator() {
24
variant current_generator::get_value(const std::string& key) const
29
radial_current_generator::radial_current_generator(int intensity, int radius)
30
: intensity_(intensity), radius_(radius)
33
radial_current_generator::radial_current_generator(wml::const_node_ptr node)
34
: intensity_(wml::get_int(node, "intensity")),
35
radius_(wml::get_int(node, "radius"))
38
void radial_current_generator::generate(int center_x, int center_y, int target_x, int target_y, int target_mass, int* velocity_x, int* velocity_y) {
39
if(center_x == target_x && center_y == target_y) {
43
const float xdiff = target_x - center_x;
44
const float ydiff = target_y - center_y;
45
if(abs(xdiff) >= radius_ || abs(ydiff) > radius_) {
49
const float distance = sqrt(xdiff*xdiff + ydiff*ydiff);
50
if(distance >= radius_) {
54
const float intensity = intensity_*(1.0 - distance/radius_);
55
const float xdiff_normalized = xdiff/(abs(xdiff) + abs(ydiff));
56
const float ydiff_normalized = ydiff/(abs(xdiff) + abs(ydiff));
58
std::cerr << "DO_CURRENT: " << center_x << "," << center_y << " ~ " << target_x << "," << target_y << ": "<< intensity << " x " << xdiff_normalized << "," << ydiff_normalized << "\n";
59
*velocity_x += xdiff_normalized*intensity;
60
*velocity_y += ydiff_normalized*intensity;
63
wml::node_ptr radial_current_generator::write() const
65
wml::node_ptr result(new wml::node("current_generator"));
66
result->set_attr("type", "radial");
67
result->set_attr("intensity", formatter() << intensity_);
68
result->set_attr("radius", formatter() << radius_);
72
rect_current_generator::rect_current_generator(const rect& r, int xvelocity, int yvelocity, int strength)
73
: rect_(r), xvelocity_(xvelocity), yvelocity_(yvelocity), strength_(strength)
76
rect_current_generator::rect_current_generator(wml::const_node_ptr node)
77
: rect_(node->attr("rect")), xvelocity_(wml::get_int(node, "xvelocity")), yvelocity_(wml::get_int(node, "yvelocity")), strength_(wml::get_int(node, "strength"))
80
void rect_current_generator::generate(int center_x, int center_y, int target_x, int target_y, int target_mass, int* velocity_x, int* velocity_y)
82
const int strength = strength_;
83
if(point_in_rect(point(target_x, target_y), rect_)) {
84
if(xvelocity_ > 0 && *velocity_x < xvelocity_) {
85
int amount = (xvelocity_ - std::max(0, *velocity_x))*strength/(target_mass*1000);
86
const int distance = rect_.x2() - target_x;
87
amount = (amount*distance*distance)/(rect_.h()*rect_.h());
88
*velocity_x += amount;
89
if(*velocity_x > xvelocity_) {
90
*velocity_x = xvelocity_;
92
} else if(xvelocity_ < 0 && *velocity_x > xvelocity_) {
93
int amount = (xvelocity_ - std::min(0, *velocity_x))*strength/(target_mass*1000);
94
const int distance = target_x - rect_.x();
95
amount = (amount*distance*distance)/(rect_.h()*rect_.h());
96
*velocity_x += amount;
97
if(*velocity_x < xvelocity_) {
98
*velocity_x = xvelocity_;
102
if(yvelocity_ > 0 && *velocity_y < yvelocity_) {
103
int amount = (yvelocity_ - std::max(0, *velocity_y))*strength/(target_mass*1000);
104
const int distance = rect_.y2() - target_y;
105
amount = (amount*distance*distance)/(rect_.h()*rect_.h());
106
*velocity_y += amount;
107
if(*velocity_y > yvelocity_) {
108
*velocity_y = yvelocity_;
110
} else if(yvelocity_ < 0 && *velocity_y > yvelocity_) {
111
int amount = yvelocity_*strength/(target_mass*1000);
112
const int distance = target_y - rect_.y();
113
// amount = (amount*distance*distance)/(rect_.h()*rect_.h());
114
std::cerr << "DIST: " << distance << "/" << rect_.h() << " " << *velocity_y << "\n";
115
if(distance < rect_.h()/2 && *velocity_y > 0) {
116
std::cerr << "CANCEL\n";
119
*velocity_y += amount;
120
if(*velocity_y < yvelocity_) {
121
// *velocity_y = yvelocity_;
127
wml::node_ptr rect_current_generator::write() const
129
wml::node_ptr node(new wml::node("current_generator"));
130
node->set_attr("type", "rect");
131
node->set_attr("rect", rect_.to_string());
132
node->set_attr("xvelocity", formatter() << xvelocity_);
133
node->set_attr("yvelocity", formatter() << yvelocity_);
134
node->set_attr("strength", formatter() << strength_);