function duck_ai_module_shoot_on_timer(interval, offset) {
static states = {
hold: undefined,
base: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
var p = "shoot#";
var max_ammo_key = p + "max-ammo";
var interval_key = p + "interval";
self.max_ammo = data[? max_ammo_key];
self.ammo = self.max_ammo;
self.interval = data[? interval_key];
self.next_fire_time = current_time + self.interval;
Act = function() {
if (ammo <= 0) return states.seek_water;
if (interval > current_time) return states.hold;
ammo--;
duck_data.pawn.DuckCast(DuckElementMasks.FIRE);
return states.hold;
};
},
seek_water: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
var p = "shoot#";
var radius_key = p + "radius";
self.seek_radius = data[? radius_key];
Act = function() {
var dest = active_map.GetNearestWater(duck_data.pawn.xx, duck_data.pawn.yy, duck_data.pawn.zz, seek_radius);
if (dest) {
duck_ai_module_navigate_to_point(dest.x, dest.y, dest.z, seek_radius);
if (path_exists(duck_data.path)) return states.go_water;
}
var tries = 0;
var max_tries = 10;
do {
var tx = random_range(max(duck_data.pawn.xx - seek_radius, 0), min(duck_data.pawn.xx + seek_radius, active_map.xx - 1));
var ty = random_range(max(duck_data.pawn.yy - seek_radius, 0), min(duck_data.pawn.yy + seek_radius, active_map.yy - 1));
var tz = random_range(max(duck_data.pawn.zz - seek_radius, 0), min(duck_data.pawn.zz + seek_radius, active_map.zz - 1));
duck_ai_module_navigate_to_point(tx, ty, tz, seek_radius);
} until (((tx != duck_data.pawn.xx || ty != duck_data.pawn.yy || tz != duck_data.pawn.zz) && path_exists(duck_data.path)) || tries >= max_tries);
if (path_exists(duck_data.path)) return states.go_water;
return states.repeat_water;
};
},
go_water: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
Act = function() {
if (!path_exists(duck_data.path)) return states.refilling;
with (duck_data) duck_ai_module_follow_path();
return states.hold;
};
},
repeat_water: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
self.end_time = current_time + 5000;
Act = function() {
if (current_time >= end_time) return states.seek_water;
return states.hold;
};
},
refilling: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
self.end_time = current_time + 2000;
Act = function() {
// todo: play animation
if (current_time >= end_time) return states.seek_return;
return states.hold;
};
},
seek_return: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
var p = "shoot#";
var x_key = p + "x";
var y_key = p + "y";
var z_key = p + "z";
self.start_x = data[? x_key];
self.start_y = data[? y_key];
self.start_z = data[? z_key];
Act = function() {
with (duck_data) duck_ai_module_navigate_to_point(start_x, start_y, start_z);
if (path_exists(duck_data.path)) return states.repeat_return;
return states.go_return;
};
},
go_return: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
Act = function() {
if (!path_exists(duck_data.path)) return states.base;
with (duck_data) duck_ai_module_follow_path();
return states.hold;
};
},
repeat_return: function(states, duck_data) constructor {
self.states = states;
self.duck_data = duck_data;
self.end_time = current_time + 5000;
Act = function() {
if (current_time >= end_time) return states.seek_return;
return states.hold;
};
},
};
var ammo_quantity = 3;
var seek_radius = 5;
var wait_time = 5000;
var p = "shoot#";
var states_key = p + "states";
var state_key = p + "state";
var x_key = p + "x";
var y_key = p + "y";
var z_key = p + "z";
if (!data[? state_key]) {
data[? states_key] = states;
data[? state_key] = new states.state_base(states, duck_data);
data[? x_key] = pawn.xx;
data[? y_key] = pawn.yy;
data[? z_key] = pawn.zz;
}
var result = data[? state_key].Act();
if (result) data[? state_key] = new result(states, duck_data);
};
Comments
0 B
|👍
/👎
0 B
|👍
/👎