--- a/hedgewars/uAI2.pas Sat Dec 14 18:07:29 2024 +0100
+++ b/hedgewars/uAI2.pas Tue Dec 17 15:44:21 2024 +0100
@@ -10,9 +10,12 @@
{$linklib hwengine_future}
+type TAmmoCounts = array[TAmmoType] of Longword;
+ PAmmoCounts = ^TAmmoCounts;
+
function create_ai(game_field: pointer): pointer; cdecl; external;
procedure ai_clear_team(ai: pointer); cdecl; external;
-procedure ai_add_team_hedgehog(ai: pointer; x, y: real); cdecl; external;
+procedure ai_add_team_hedgehog(ai: pointer; x, y: real; ammo_counts: PAmmoCounts); cdecl; external;
procedure ai_think(ai: pointer); cdecl; external;
function ai_have_plan(): boolean; cdecl; external;
procedure dispose_ai(ai: pointer); cdecl; external;
@@ -21,6 +24,8 @@
procedure ProcessBot;
var currHedgehogIndex, itHedgehog: Longword;
+ itAmmo: TAmmoType;
+ ammoCounts: TAmmoCounts;
begin
if ai = nil then
begin
@@ -35,10 +40,15 @@
with CurrentTeam^.Hedgehogs[itHedgehog] do
if (Gear <> nil) and (Effects[heFrozen] = 0) then
begin
- ai_add_team_hedgehog(ai, hwFloat2float(Gear^.X), hwFloat2float(Gear^.Y))
+ for itAmmo:= Low(TAmmoType) to High(TAmmoType) do
+ ammoCounts[itAmmo]:= HHHasAmmo(CurrentTeam^.Hedgehogs[itHedgehog], itAmmo);
+
+ ai_add_team_hedgehog(ai, hwFloat2float(Gear^.X), hwFloat2float(Gear^.Y), ammoCounts)
end;
itHedgehog:= Succ(itHedgehog) mod CurrentTeam^.HedgehogsNumber;
until (itHedgehog = currHedgehogIndex);
+
+ ai_think(ai);
end;
procedure initModule;
--- a/rust/lib-hwengine-future/src/ai/action.rs Sat Dec 14 18:07:29 2024 +0100
+++ b/rust/lib-hwengine-future/src/ai/action.rs Tue Dec 17 15:44:21 2024 +0100
@@ -1,24 +1,22 @@
#[derive(Clone)]
pub enum Direction {
Left,
- Right
+ Right,
}
#[derive(Clone)]
pub enum Action {
Walk(Direction),
LongJump,
- HighJump(usize)
+ HighJump(usize),
}
pub struct Actions {
- actions: Vec<Action>
+ actions: Vec<Action>,
}
impl Actions {
pub fn new() -> Self {
- Self {
- actions: vec![],
- }
+ Self { actions: vec![] }
}
pub fn push(&mut self, action: Action) {
@@ -28,4 +26,4 @@
pub fn pop(&mut self) -> Option<Action> {
self.actions.pop()
}
-}
\ No newline at end of file
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/lib-hwengine-future/src/ai/ammo.rs Tue Dec 17 15:44:21 2024 +0100
@@ -0,0 +1,65 @@
+#[repr(usize)]
+pub enum AmmoType {
+ Nothing,
+ Grenade,
+ ClusterBomb,
+ Bazooka,
+ Bee,
+ Shotgun,
+ PickHammer, // 6
+ Skip,
+ Rope,
+ Mine,
+ DEagle,
+ Dynamite,
+ FirePunch,
+ Whip, // 13
+ BaseballBat,
+ Parachute,
+ AirAttack,
+ MineStrike,
+ BlowTorch, // 18
+ Girder,
+ Teleport,
+ Switch,
+ Mortar,
+ Kamikaze,
+ Cake, // 24
+ Seduction,
+ Watermelon,
+ HellishBomb,
+ Napalm,
+ Drill,
+ Ballgun, // 30
+ RCPlane,
+ LowGravity,
+ ExtraDamage,
+ Invulnerable,
+ ExtraTime, // 35
+ LaserSight,
+ Vampiric,
+ SniperRifle,
+ Jetpack,
+ Molotov,
+ Birdy,
+ PortalGun, // 42
+ Piano,
+ GasBomb,
+ SineGun,
+ Flamethrower,
+ SMine,
+ Hammer, // 48
+ Resurrector,
+ DrillStrike,
+ Snowball,
+ Tardis,
+ LandGun, // 53
+ IceGun,
+ Knife,
+ Rubber,
+ AirMine,
+ Creeper,
+ Minigun,
+ Sentry, // 60
+ Count,
+}
--- a/rust/lib-hwengine-future/src/ai/mod.rs Sat Dec 14 18:07:29 2024 +0100
+++ b/rust/lib-hwengine-future/src/ai/mod.rs Tue Dec 17 15:44:21 2024 +0100
@@ -1,25 +1,28 @@
mod action;
+pub mod ammo;
-use std::collections::HashMap;
-use integral_geometry::Point;
use crate::GameField;
use action::*;
+use integral_geometry::Point;
+use std::collections::HashMap;
pub struct Target {
point: Point,
health: i32,
radius: u32,
density: f32,
-
}
pub struct Hedgehog {
pub(crate) x: f32,
pub(crate) y: f32,
+ pub(crate) ammo: [u32; ammo::AmmoType::Count as usize],
+
}
pub struct AI<'a> {
game_field: &'a GameField,
+ ammo: [u32; ammo::AmmoType::Count as usize],
targets: Vec<Target>,
team: Vec<Hedgehog>,
planned_actions: Option<Actions>,
@@ -53,12 +56,17 @@
pub fn new(game_field: &'a GameField) -> AI<'a> {
Self {
game_field,
+ ammo: [0; ammo::AmmoType::Count as usize],
targets: vec![],
team: vec![],
planned_actions: None,
}
}
+ pub fn set_available_ammo(&mut self, ammo: [u32; ammo::AmmoType::Count as usize]) {
+ self.ammo = ammo;
+ }
+
pub fn get_team_mut(&mut self) -> &mut Vec<Hedgehog> {
&mut self.team
}
@@ -67,7 +75,7 @@
let mut stack = Vec::<usize>::new();
let mut waypoints = Waypoints::default();
- waypoints.add_keypoint(Waypoint{
+ waypoints.add_keypoint(Waypoint {
x: hedgehog.x,
y: hedgehog.y,
ticks: 0,
@@ -75,9 +83,7 @@
previous_point: None,
});
- while let Some(wp) = stack.pop() {
-
- }
+ while let Some(wp) = stack.pop() {}
}
pub fn have_plan(&self) -> bool {
--- a/rust/lib-hwengine-future/src/lib.rs Sat Dec 14 18:07:29 2024 +0100
+++ b/rust/lib-hwengine-future/src/lib.rs Tue Dec 17 15:44:21 2024 +0100
@@ -2,9 +2,9 @@
use integral_geometry::{Point, Size};
+use ai::*;
use landgen::{
- outline_template_based::outline_template::OutlineTemplate,
- maze::MazeTemplate,
+ maze::MazeTemplate, outline_template_based::outline_template::OutlineTemplate,
wavefront_collapse::generator::TemplateDescription as WfcTemplate, LandGenerationParameters,
LandGenerator,
};
@@ -12,7 +12,7 @@
use mapgen::{theme::Theme, MapGenerator};
use std::fs;
use std::{ffi::CStr, path::Path};
-use ai::*;
+use std::ptr::slice_from_raw_parts;
#[repr(C)]
pub struct GameField {
@@ -24,18 +24,16 @@
#[no_mangle]
pub extern "C" fn get_game_field_parameters(
game_field: &GameField,
- width: *mut i32,
- height: *mut i32,
- play_width: *mut i32,
- play_height: *mut i32,
+ width: &mut i32,
+ height: &mut i32,
+ play_width: &mut i32,
+ play_height: &mut i32,
) {
- unsafe {
- *width = game_field.collision.width() as i32;
- *height = game_field.collision.height() as i32;
+ *width = game_field.collision.width() as i32;
+ *height = game_field.collision.height() as i32;
- *play_width = game_field.collision.play_width() as i32;
- *play_height = game_field.collision.play_height() as i32;
- }
+ *play_width = game_field.collision.play_width() as i32;
+ *play_height = game_field.collision.play_height() as i32;
}
#[no_mangle]
@@ -50,17 +48,17 @@
}
#[no_mangle]
-pub extern "C" fn generate_outline_templated_game_field(
+pub unsafe extern "C" fn generate_outline_templated_game_field(
feature_size: u32,
seed: *const i8,
template_type: *const i8,
data_path: *const i8,
) -> *mut GameField {
- let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+ let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap();
let data_path = Path::new(&data_path);
- let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap();
- let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap();
+ let seed: &str = CStr::from_ptr(seed).to_str().unwrap();
+ let template_type: &str = CStr::from_ptr(template_type).to_str().unwrap();
let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes());
@@ -90,17 +88,17 @@
}
#[no_mangle]
-pub extern "C" fn generate_wfc_templated_game_field(
+pub unsafe extern "C" fn generate_wfc_templated_game_field(
feature_size: u32,
seed: *const i8,
template_type: *const i8,
data_path: *const i8,
) -> *mut GameField {
- let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+ let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap();
let data_path = Path::new(&data_path);
- let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap();
- let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap();
+ let seed: &str = CStr::from_ptr(seed).to_str().unwrap();
+ let template_type: &str = CStr::from_ptr(template_type).to_str().unwrap();
let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes());
@@ -130,17 +128,17 @@
}
#[no_mangle]
-pub extern "C" fn generate_maze_game_field(
+pub unsafe extern "C" fn generate_maze_game_field(
feature_size: u32,
seed: *const i8,
template_type: *const i8,
data_path: *const i8,
) -> *mut GameField {
- let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+ let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap();
let data_path = Path::new(&data_path);
- let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap();
- let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap();
+ let seed: &str = CStr::from_ptr(seed).to_str().unwrap();
+ let template_type: &str = CStr::from_ptr(template_type).to_str().unwrap();
let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes());
@@ -173,15 +171,15 @@
}
#[no_mangle]
-pub extern "C" fn apply_theme(
+pub unsafe extern "C" fn apply_theme(
game_field: &mut GameField,
data_path: *const i8,
theme_name: *const i8,
) {
- let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap();
+ let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap();
let data_path = Path::new(&data_path);
- let theme_name: &str = unsafe { CStr::from_ptr(theme_name) }.to_str().unwrap();
+ let theme_name: &str = CStr::from_ptr(theme_name).to_str().unwrap();
let map_gen = MapGenerator::<()>::new(data_path);
let theme = Theme::load(
@@ -244,8 +242,8 @@
}
#[no_mangle]
-pub extern "C" fn dispose_game_field(game_field: *mut GameField) {
- unsafe { drop(Box::from_raw(game_field)) };
+pub unsafe extern "C" fn dispose_game_field(game_field: *mut GameField) {
+ drop(Box::from_raw(game_field));
}
#[no_mangle]
@@ -259,14 +257,15 @@
}
#[no_mangle]
-pub extern "C" fn ai_add_team_hedgehog(ai: &mut AI, x: f32, y: f32) {
- ai.get_team_mut().push(Hedgehog{x, y});
+pub unsafe extern "C" fn ai_add_team_hedgehog(ai: &mut AI, x: f32, y: f32, ammo_counts: *const u32) {
+ let ammo_counts = &*slice_from_raw_parts(ammo_counts, crate::ai::ammo::AmmoType::Count as usize);
+ let ammo_counts = std::array::from_fn(|i| ammo_counts[i].clone());
+
+ ai.get_team_mut().push(Hedgehog { x, y, ammo: ammo_counts });
}
#[no_mangle]
-pub extern "C" fn ai_think(ai: &AI) {
-
-}
+pub extern "C" fn ai_think(ai: &AI) {}
#[no_mangle]
pub extern "C" fn ai_have_plan(ai: &AI) -> bool {
@@ -279,6 +278,6 @@
}
#[no_mangle]
-pub extern "C" fn dispose_ai(ai: *mut AI) {
- unsafe { drop(Box::from_raw(ai)) };
+pub unsafe extern "C" fn dispose_ai(ai: *mut AI) {
+ drop(Box::from_raw(ai));
}