a brief of context:
so, i’ll start by saying that i’m sort of greatefull that we finally got AI tanks.
but… it’s kinda like we don’t fully have them.
let me explain,
the system it self it’s good. and something that not many would have though of getting.
you can use it as a reinforcement waves, or put them as spawn. or use them as static defense.
which it’s all great, if it wasn’t… for being half baked.
because in one week of fully testing and ““playing”” around with the code trying to make tanks, was an absolute nightmare.
anyway, i can sort of teach you how to create an ai tank:
first and foremost:
type " tank " inside level__loadExtraNavMeshes ( inside the level node ) ( special thanks to @Devenddar )
then, head over entities, and make the followings
code
// crew needed to operate the vehicle with specific tags. Zombie default crew makes the game crash
ai_aircraft_crew_ger{
_override:b=yes
"zombie:tag"{
}
"zombie_no_award:tag"{
}
}
// template of AI vehicle. where you'll need to replace all it's field EXCEPT the _use:t="base_pzkpfw_iv_ausf_h"
panther_ausf_g_AI{
_use:t="base_pzkpfw_iv_ausf_h"
_use:t="germ_pzkpfw_IV_ausf_J_common_vehicle_sound"
item__iconOffset:p2=0.1, 0.15
item__iconScale:r=1.4
commanderCockpitFpsCamMaxAngle:p2=40.0, 5.0
gunner_cam_limit__useCockpitDir:b=yes
armorThicknessHull:p3=80.0, 30.0, 20.0
armorThicknessTurret:p3=50.0, 30.0, 30.0
killLogName:t="germ_pzkpfw_v_ausf_g_panther"
animchar__res:t="pzkpfw_V_ausf_g_panther_char"
collres__res:t="pzkpfw_V_ausf_g_panther_collision"
vehicle_net_phys__blk:t="content/tanks/gamedata/gen/units/tanks/pzkpfw_v_ausf_g_panther.blk:VehiclePhys"
dmg_animchar__res:t="pzkpfw_V_ausf_g_panther_dmg_char"
xray_resource__modelName:t="pzkpfw_V_ausf_g_panther"
damage_model__blk:t="content/tanks/gamedata/gen/units/tanks/pzkpfw_v_ausf_g_panther.blk"
"animchar__objTexReplace:object"{
"ger_camo_dunkelgelb*":t="ger_camo_dark_grey*"
}
"turrets__initAmmoDistribution:array"{
"ammo:object"{
slot:i=0
fill:b=yes
}
"ammo:object"{
slot:i=5
count:i=7
}
}
"turret_control__turretInfo:shared:array"{
"turretInfo:object"{
turretName:t="turret_01"
gun:t="pzkpfw_v_ausf_g_panther_turret_01_75mm_kwk42_ai+turret_with_several_types_of_shells+main_turret"
barrelDm:t="gun_barrel"
breechDm:t="cannon_breech"
verDriveDm:t="drive_turret_v"
horDriveDm:t="drive_turret_h"
salt:i=1
}
"turretInfo:object"{
turretName:t="turret_02"
gun:t="pzkpfw_iv_ausf_j_turret_02_7_92mm_mg34"
barrelDm:t="gun_barrel_01"
salt:i=1
}
"turretInfo:object"{
turretName:t="turret_03"
gun:t="pzkpfw_iv_ausf_j_turret_03_7_92mm_mg34"
barrelDm:t="gun_barrel_02"
salt:i=1
}
"turretInfo:object"{
turretName:t="turret_04"
needsAssignedGunner:b=no
turretGroup:t="smoke"
gun:t="pzkpfw_iv_ausf_j_turret_04_91mm_germ_smoke_mortar_launcher"
salt:i=1
}
}
"vehicle_seats__effectors:array"{
}
"vehicle_seats__seats:shared:array"{
"seats:object"{
name:t="main_gunner"
locName:t="vehicle_seats/gunner"
attachNode:t="gunner"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.25, -0.5, 0.0]]
seatComponent:t="isGunner"
nextSeat:t="driver"
shouldHideOwner:b=yes
receiveDamageFromDMPart:t="gunner"
cameraNodeName:t="bone_camera_gunner"
cockpitTemplate:t="germ_pzkpfw_IV_ausf_J_gunner_cockpit"
directTurretControl:b=yes
"turretNames:array"{
turret:t="turret_01"
turret:t="turret_02"
}
}
"seats:object"{
name:t="commander"
locName:t="vehicle_seats/commander"
attachNode:t="bone_turret_01"
shouldHideOwner:b=yes
hatchRotationAxis:p3=1.8, 0.0, 0.0
maxPosWithOpenHatch:r=0.6
ignoreAttachNodeRotation:b=yes
attachTm:m=[[0.945513, -0.325564, -0.0] [0.325564, 0.945513, 0.0] [0.0, -0.0, 1.0] [-0.15, -0.6, 0.07]]
seatComponent:t="isDriver"
receiveDamageFromDMPart:t="commander"
cockpitTemplate:t="germ_pzkpfw_IV_ausf_J_commander_cockpit"
cameraNodeName:t="bone_turret"
isHatchControlInversed:b=yes
"hatchNodes:array"{
node:t="hatch_10"
}
"hatchTurretNames:array"{
turret:t="turret_03"
}
"effectors:object"{
"l.hand:object"{
rel_tm:m=[[0.97117, 0.237519, 0.020345] [0.0889659, -0.440294, 0.893435] [0.221165, -0.865868, -0.448731] [0.0157318, 0.0978909, -0.0356903]]
node:t="bone_mg_aa"
}
"r.hand:object"{
rel_tm:m=[[0.457892, 0.365741, -0.810288] [-0.0172946, -0.907617, -0.419446] [-0.888839, 0.206074, -0.409265] [-0.229507, 0.231809, 0.0531616]]
node:t="bone_mg_aa"
}
"l.foot:object"{
rel_tm:m=[[0.0580978, -0.998205, -0.0145364] [0.985102, 0.0596839, -0.161282] [0.16186, -0.00494957, 0.986801] [-0.108994, -0.703663, -0.106209]]
node:t="bone_turret_01"
}
"r.foot:object"{
rel_tm:m=[[0.0380384, -0.999241, 0.00848966] [0.998773, 0.0382875, 0.0314126] [-0.0317138, 0.00728441, 0.99947] [-0.107773, -0.709267, 0.0740204]]
node:t="bone_turret_01"
}
}
}
"seats:object"{
locName:t="vehicle_seats/loader"
attachNode:t="loader"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.25, -0.5, 0.0]]
seatComponent:t="isPassenger"
shouldHideOwner:b=yes
receiveDamageFromDMPart:t="loader"
cameraNodeName:t="bone_camera_driver"
"loaderTurretNames:array"{
turret:t="turret_01"
}
}
"seats:object"{
locName:t="vehicle_seats/radioman"
attachNode:t="machine_gunner"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.25, -0.5, 0.0]]
seatComponent:t="isPassenger"
shouldHideOwner:b=yes
receiveDamageFromDMPart:t="machine_gunner"
}
}
}
// this is what you'll have to spawn with a +crew ( that you made at the top ) as a postfix
zombie_panther_g_ai_vehicle_tank{
_use:t="ai_vehicle_tank_no_objective"
_use:t="panther_ausf_g_AI"
paid_loot__pointsForKill:i=100
vehicle_seats__restrictToTeam:i=3
"dm_parts__initializeKilled:list<t>"{
part:t="engine"
}
"dontCreateNphysObstacle:tag"{
}
"zombie:tag"{
}
_group{
_tags:t="server"
ai_vehicle_tank__pathFindingState:i=1
zombie_ai_vehicle_tank__timeToDestroy:r=0.0
zombie_ai_vehicle_tank__destroyAtTime:r=0.0
ai_vehicle_tank__ignoreBattleArea:b=yes
}
}
// the new template of the weapon that your german tank is using. which you'll also have to replace over the turret initial components
pzkpfw_v_ausf_g_panther_turret_01_75mm_kwk42_ai{
_use:t="pzkpfw_v_ausf_g_panther_turret_01_75mm_kwk42"
turret__allowShootingFromBroken:b=no
_group{
_tags:t="server"
tank_turret_ai__maxBurstCount:i=0
tank_turret_ai__longPauseWaitTime:r=0.0
tank_turret_ai__attackDist:r=120.0
}
}
which in short, take the panzer IV J with the AI tags, and give it different collisions, animchar res, hitboxes, damage vehicle etc. so you’re effectively " fooling " the editor and pretty much anyone by just taking a panzer IV and give it some other tank’s properties.
then, you tweak the code of the vehicle it self by replacing the seats and turrets.
after that, you’ll have to create a new entity and replace the weapon_turret with AI properties. and you’ll have a working AI tank.
problems are:
- the process to make an AI tanks is lenghty and not so intuitive for the majority of people.
by god it took me a whole week to figure out how they work, just to be greeted with a system that is only designed to work with german tanks.
- as previously said, this new system only works on german AI tanks ( with actual turrets mind you ).
because if you try to apply said tags like the zombie event panzer IV J to any other vehicle that it’s not german, it will not work.
t_34_1941_AI{
_use:t="base_stug_iii_ausf_a"
_use:t="ussr_t_34_1941_common_vehicle_sound"
item__iconOffset:p2=0.1, 0.15
item__iconScale:r=1.4
commanderCockpitFpsCamMaxAngle:p2=40.0, 5.0
gunner_cam_limit__useCockpitDir:b=yes
armorThicknessHull:p3=80.0, 30.0, 20.0
armorThicknessTurret:p3=50.0, 30.0, 30.0
killLogName:t="ussr_t_34_1941"
animchar__res:t="t_34_1941_char"
collres__res:t="t_34_1941_collision"
vehicle_net_phys__blk:t="gamedata/gen/units/tanks/t_34_1941.blk:VehiclePhys"
dmg_animchar__res:t="t_34_1941_dmg_char"
xray_resource__modelName:t="t_34_1941"
damage_model__blk:t="gamedata/gen/units/tanks/t_34_1941.blk"
"animchar__objTexReplace:object"{
"ussr_camo_green*":t="se_camo_green*"
}
"turrets__initAmmoDistribution:array"{
"ammo:object"{
slot:i=0
fill:b=yes
}
"ammo:object"{
slot:i=5
count:i=7
}
}
"turret_control__turretInfo:shared:array"{
"turretInfo:object"{
turretName:t="turret_01"
gun:t="t_34_1941_turret_01_76mm_f34_zombie_ai+turret_with_several_types_of_shells+main_turret"
barrelDm:t="gun_barrel"
breechDm:t="cannon_breech"
verDriveDm:t="drive_turret_v"
horDriveDm:t="drive_turret_h"
salt:i=1
}
"turretInfo:object"{
turretName:t="turret_02"
gun:t="t_34_1941_turret_02_7_62mm_dt"
barrelDm:t="gun_barrel_01"
verDriveDm:t="drive_turret_v"
horDriveDm:t="drive_turret_h"
salt:i=1
}
}
"vehicle_seats__effectors:array"{
}
"vehicle_seats__seats:shared:array"{
"seats:object"{
name:t="driver"
locName:t="vehicle_seats/driver"
seatOwnsEntityControl:b=yes
attachNode:t="driver"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.25, -0.25, 0.0]]
seatComponent:t="isDriver"
nextSeat:t="main_gunner"
shouldHideOwner:b=yes
receiveDamageFromDMPart:t="driver"
cameraNodeName:t="bone_camera_driver"
cockpitTemplate:t="ussr_t_34_1941_driver_cockpit"
}
"seats:object"{
name:t="main_gunner"
locName:t="vehicle_seats/gunner"
attachNode:t="gunner"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.25, -0.5, 0.0]]
seatComponent:t="isGunner"
nextSeat:t="driver"
shouldHideOwner:b=yes
receiveDamageFromDMPart:t="gunner"
cameraNodeName:t="bone_camera_gunner"
cockpitTemplate:t="ussr_t_34_1941_gunner_cockpit"
"turretNames:array"{
turret:t="turret_01"
turret:t="turret_02"
}
}
"seats:object"{
name:t="commander"
attachNode:t="loader"
shouldHideOwner:b=yes
maxPosWithOpenHatch:r=1.2
locName:t="vehicle_seats/commander"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.15, -0.35, 0.15]]
seatComponent:t="isDriver"
receiveDamageFromDMPart:t="loader"
cockpitTemplate:t="ussr_t_34_1941_commander_cockpit"
"hatchNodes:array"{
node:t="hatch_01"
}
"loaderTurretNames:array"{
turret:t="turret_01"
}
}
"seats:object"{
locName:t="vehicle_seats/radioman"
attachNode:t="machine_gunner"
ignoreAttachNodeRotation:b=yes
attachTm:m=[[1.0, 0.0, 0.0] [0.0, 1.0, 0.0] [0.0, 0.0, 1.0] [-0.25, -0.5, 0.0]]
seatComponent:t="isPassenger"
shouldHideOwner:b=yes
receiveDamageFromDMPart:t="machine_gunner"
}
}
}
t34_1941_vehicle_tank{
_use:t="ai_vehicle_tank_no_objective"
_use:t="t_34_1941_AI"
paid_loot__pointsForKill:i=100
vehicle_seats__restrictToTeam:i=3
"dm_parts__initializeKilled:list<t>"{
part:t="engine"
}
"dontCreateNphysObstacle:tag"{
}
"zombie:tag"{
}
_group{
_tags:t="server"
ai_vehicle_tank__pathFindingState:i=1
zombie_ai_vehicle_tank__timeToDestroy:r=0.0
zombie_ai_vehicle_tank__destroyAtTime:r=0.0
ai_vehicle_tank__ignoreBattleArea:b=yes
}
}
t_34_1941_turret_01_76mm_f34_zombie_ai{
_use:t="t_34_1941_turret_01_76mm_f34"
turret__allowShootingFromBroken:b=no
_group{
_tags:t="server"
tank_turret_ai__maxBurstCount:i=0
tank_turret_ai__longPauseWaitTime:r=0.0
tank_turret_ai__attackDist:r=120.0
}
}
which, even if you use the " base_tank " not all base tank are supported. matter of fact, it seems only the panzer IV H and J are.
- AI tank tags do not work on SPGs / Halftrack vehicles
so… no AI stug or halftracks.
you can only make static halftracks with other code. that is even there, unrelated to this new system.
and small yet annoying related things to the AI tank behavior,
-
If you use a custom tank, that it’s not a panzer IV J, the vehicle upon being killed, simply disappears
-
If you use a custom tank, there is no way to make the turret face anything other 0,0,0 coordinates.
leading to situations where the enemy tank is looking behind instead of the front:
main suggestion
so… the suggestion is simple,
either:
make a dedicated section of AI tanks similar to AI soldiers over the AI tab
allow the use of base_tanks for at least basic tanks such as t34s, shermans, type 97s etc
despite many, and i mean, many attempts, i can’t still understand whether the models them selves do not have AI tags, or the turrets are not supported.
but i’m more incline to believe that any other tank do not work because of the base_tank or… something else.
and that is all from me. cheers.