Jump to content


Photo

how to build turrets at LPs


13 replies to this topic

#1 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 01 February 2005 - 11:37 PM

Build turrets/banners at nearest listening post to next AI if req > 400 AND power > 200 AND turrets < 10 AND in tier 2

Add to cpu_manager.ai :

function CpuManager:FindClosestListenPost( from_pos )

   local closest_strat = nil
   local prev_distance = 0

   for strat_ai in resource_manager:GetUnlockedStrategicPointAIs() do
	
  if strat_ai:Owner() == cpu_manager.player_id and strat_ai:HasListeningPost() then
  
  	local strat_pos = strat_ai:GetEntity():GetPosition()
	
  	--determine distance  	
  	if closest_strat == nil then

      prev_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
      closest_strat = strat_pos
      --ailog("d:\\defense.txt", "First LP at : "..tostring(prev_distance))
  
  	else      
  	--check if LP closer to from_pos
    local cur_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
    if prev_distance > cur_distance then

       prev_distance = cur_distance
       closest_strat = strat_pos
          --ailog("d:\\defense.txt", "Closer LP at : "..tostring(prev_distance))

    end
  	end
  	
  end
  
	end
	
	return closest_strat
end


function CpuManager:FindClosestDefensePoint()

	local enemy = cpu_manager:FindClosestEnemyPlayer()
	dbAssert( enemy ~= nil )
	
	--find the closest strategic point I own to this enemy, and use it as my defense point
	local listen_pt = self:FindClosestListenPost( enemy:GetStartingPosition() )

	return listen_pt	
end



function CpuManager:IsTurret( build_name )

   --ailog("d:\\defense.txt", "Check turret : "..build_name)
   if build_name == "ork_waagh_banner" then
   return true
   elseif build_name == "space_marine_turret_bolter" then
   return true
   elseif build_name == "chaos_turret_bolter" then
   return true
   elseif build_name == "eldar_support_platform_scatterlaser" then
   return true
   end

   --ailog("d:\\defense.txt", "No turret : "..build_name)  
   return false
end

Modify strategy.ai :

elseif( build_type.btype == CpuPrerequisites.BT_Building ) then
	
  if( not cpu_manager.components[ CpuPlayer.CT_BuildBuildings ] ) then
  	return
  end

  local id = cpu_manager.stats:GetBuildingID( build_type.name )
  
  if( self:PlanExists("Build Building Plan", id) == false ) then
 
     local start_pos = cpu_manager.cpu_player:GetStartingPosition()
     if cpu_manager:IsTurret( build_type.name ) then

     local build_pos = cpu_manager:FindClosestDefensePoint()
     if build_pos ~= nil then
        --ailog("d:\\defense.txt", "Build defense : "..build_type.name)
     self.AddPlan( self, BuildBuildingPlan( id, build_pos ) )
     else
        --ailog("d:\\defense.txt", "Build defense Pos NIL : "..build_type.name)
     self.AddPlan( self, BuildBuildingPlan( id, start_pos ) )     
     end
  	else
      --ailog("d:\\defense.txt", "Build other : "..build_type.name)         
      self.AddPlan( self, BuildBuildingPlan( id, start_pos ) )
  	end

  end

Modify chaosbuildbasestrategy.ai or equivalent race file :

function ChaosBuildBaseStrategy:DoSecondaryBuildings()

	--build a second machine pit 
	
	--check that we have one and only one machine cult
	local num_vehicle_buildings = 0
	local num_barracks = 0
    local num_turrets = 0
	
	for build_channel in build_manager:GetBuildChannelAIs() do
	
  if build_channel:GetBlueprintID() == self.vehicle_building_id then
  	num_vehicle_buildings = num_vehicle_buildings + 1
  end
  
  if build_channel:GetBlueprintID() == self.barracks_id then
  	num_barracks = num_barracks + 1
  end

  if build_channel:GetBlueprintID() == self.turret_id then
     num_turrets = num_turrets + 1
  end

	end
	
	--build a second machine cult
	if num_vehicle_buildings == 1 and 
  resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Requisition ) > 1000 and
  resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Power ) > 500 then
  
  local build_type = CpuBuildType()
  build_type.btype = CpuPrerequisites.BT_Building
  build_type.name = self.vehicle_building_name
  self:TryBuild( build_type )

	--build a second barracks
	elseif num_barracks == 1 and
  resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Requisition ) > 1500 then
	
  local build_type = CpuBuildType()
  build_type.btype = CpuPrerequisites.BT_Building
  build_type.name = self.barracks_name
  self:TryBuild( build_type )
  --build a turret
  elseif num_turrets < 10 and 
  resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Requisition ) > 400 and	
  resource_manager:GetResourceAmount():Get( ResourceAmount.RT_Power ) > 200 then
  
  local build_type = CpuBuildType()
  build_type.btype = CpuPrerequisites.BT_Building
  build_type.name = self.turret_name
  self:TryBuild( build_type )
	
	end
	

end

Edited by LarkinVB, 01 February 2005 - 11:38 PM.


#2 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 02 February 2005 - 06:28 AM

Okie.. Just tried the above script.. worked like a charm Larkin! Great work!

Played it on 2p_Fallen City and the AI in Tier2 (once he built his HQ_Addon_1) started building up to 6 turrets around this one ListeningPost just upper-left of where the troops were gathering at a chokepoint (closer just to the north of my base). He even updated the two frontal turrets to anti-vehicle! Absolutely brillant!

Now..

I would like to see the following:

1) Build maybe 1 or 2 turrets at Tier1 at this or a second closer LP (in the case of 2p_Fallen City there are two or even three close LPs he captured and built-on). In any case, if he could at least build 1 or 2 turrets in Tier1 at this closestLP to enemy **THEN** add to it in Tier2 with maybe 2-3 more that would be optimal. I would be happy with just 3 turrets just to be a fire-line incase the AI has to retreat behind it to reorg. Granted, building turrets in Tier1 is important as it at least keeps distant yet-unupgraded LPs at least defended with something.

2) I've been looking into getting the AI to build on both Slag_Heaps (Large Thermo Generators) and Relics. For the former, the only reference is in the middle of the buildbasestrategy.ai file:

 	aitrace("trying to build bigger generator")
  	
  	--try to build a bigger generator
  	dbAssert( self.bigger_generator_id ~= nil )
  	
  	if not self:PlanExists( "Build Building Plan", self.bigger_generator_id ) then
  	
    --update where the free slag heaps are
    resource_manager:UpdateFreeSlagHeaps( self.bigger_generator_id )
    
    --look for the closest generator
    local base_pos = cpu_manager.cpu_player:GetStartingPosition() 
    
    local prev_distance = 0
    local chosen_slag_heap = nil
    
    for slag_heap in resource_manager:GetSlagHeaps() do
    
    	if chosen_slag_heap == nil then
      chosen_slag_heap = slag_heap
      prev_distance = distance_sqr( slag_heap:GetPosition(), base_pos )
    	else
    	
      local cur_distance = distance_sqr( slag_heap:GetPosition(), base_pos )
      if cur_distance < prev_distance then
      	chosen_slag_heap = slag_heap
      	prev_distance = cur_distance
      end
    	
    	end
    
    end
  	
    --add the plan to build it if it isn't any where near danger
    if chosen_slag_heap ~= nil and not cpu_manager.terrain_analyzer:HasThreat( chosen_slag_heap:GetPosition(), 50 ) then
    
    	self:AddPlan( BuildBuildingPlan( self.bigger_generator_id, chosen_slag_heap:GetPosition() ) )	
    
    else
    
    	aitrace("no bigger generators to find")
We would only need a max of 3 turrets here or a random # for a max of 4 (same with a built-upon Relic). Designating for a Large Generator might be easy but there is nothing for a Relic except here in the file: relic_struct.lua:

GameData = Inherit("strategic_point_struct")
GameData["entity_blueprint_ext"]["animator"] = "Environment/Gameplay/Relic"
GameData["entity_blueprint_ext"]["scale_z"] = 2.000
GameData["resource_ext"]["decay_amber_event"] = "aura/Pulse_AMBER_relic"
GameData["resource_ext"]["decay_green_event"] = "aura/Pulse_GREEN_relic"
GameData["resource_ext"]["decay_red_event"] = "aura/Pulse_RED_relic"
GameData["sight_ext"]["sight_radius"] = 10.000
GameData["strategic_point_ext"]["capture_time"] = 45.000
GameData["strategic_point_ext"]["is_relic"] = true
GameData["strategic_point_ext"]["right_click_fow_fx"] = "art/events/order_confirm_events/FOW_Strategic_Point_Capture"
GameData["ui_ext"]["minimap_color_b"] = 0.000
GameData["ui_ext"]["minimap_color_g"] = 255.000
GameData["ui_ext"]["minimap_color_r"] = 255.000
GameData["ui_ext"]["speech_directory"] = "Speech/environment/Relic"
GameData["ui_ext"]["ui_info"]["help_text_id"] = "$99011"
GameData["ui_ext"]["ui_info"]["help_text_list"]["text_01"] = "$99012"
GameData["ui_ext"]["ui_info"]["help_text_list"]["text_02"] = "$99013"
GameData["ui_ext"]["ui_info"]["help_text_list"]["text_03"] = "$99014"
GameData["ui_ext"]["ui_info"]["icon_name"] = "environment_icons/relic_icon"
GameData["ui_ext"]["ui_info"]["screen_name_id"] = "$99010"
I believe we can use "relic" or "relic_point" for FindClosestRelic() or GetClosestRelic.

Not too sure on this quite yet as the Relic is also considered a StrategicPoint. Hmmm.. This will require some tweaking to see what the AI considers as a Relic vs. a StrategicPoint. Worth investigating.

3) Ability for AI to build turrets back from the first closet-to-enemy LP when the AI is being beaten back. This might have to do with the ProRate (the way the AI rates itself compared to the enemy) so if his Prorate dips he will consider his forces in peril and this start prempting turrets on the closest LPs in his area. This would be more a dynamic reaction as the front may push back and forth. Would be quite the script as his forces reorg so does his frontline. Again, maybe 1-2 turrets when the ClosestLP changes. Just an idea.

Well.. wow.. Talk about one of The Holy Grail pieces being in sight! This is huge guys! Never thought I'd see turrets being created around a distant LP closest to the enemy. Now we need to take it one step further. Still.. absolutely superb!!

Edited by thudo, 02 February 2005 - 06:37 AM.

Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#3 Corsix

Corsix

    Code Monkey

  • Hosted
  • 290 posts
  • Location:Berkeley, UK
  • Projects:DoW AI, DoW Mod Studio
  •  Blue Text :)

Posted 02 February 2005 - 07:59 AM

He even updated the two frontal turrets to anti-vehicle!

<{POST_SNAPBACK}>

Good to know that bit of my script works
Posted Image

#4 giskard

giskard
  • Members
  • 155 posts

Posted 02 February 2005 - 11:05 AM

Great Job Larkin.

Been looking at that exact same thing for 3 days my self.

But here i would get one thing working and another thing would break, fix that and the original work break lol.

BTW there is code to allow the AI to build on slag heaps, seen it my self.

But ive seen other code that also allows the AI to do things that we all know it doesnt do. So I suspect the default AI code is bugged. Which is probably why some of my changes that should work or did work once, suddenly dont.

EG 2 identical turret setups, one upgrades, one doesnt. Bot use same code thats known to work yet the second one doesnt build any turrets. If i remove the first one and only use the second, then the second one starts working.

Also the random math function, i use it to control how many turrets do get built in both turret scripts. What happens when i do get both scripts working is turret script 1 works as intended and turret script 2 just keeps building.

Again, both are identifical.

Weird stuff, anyway i scrapped all that and went back to the single turret script approach.

Giskard

Edited by giskard, 02 February 2005 - 11:07 AM.


#5 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 02 February 2005 - 01:40 PM

Giskard.. can you be more specific regarding why one section of code would work but then cause another not to? I understand the part about 2 AIs using the same script where one would fire off and the other wouldn't. A real pisser indeed as most RTSes have this problem: game logic sometimes can't negoiate between 2 or more calls to the same civ using the exact scripts. Bloody wierd - was a problem in Generals/ZH and a damn annoying/frustrating one! Was usually a problem with tech-tree upgrading.

I know about the SlagHeaps - this script probably wouldn't be used too much UNLESS we force the AI to have cash in order so that it actually builds the Large Generator. No biggie really but would look cool to have the AI build a Large Generator + 2-3 turrets around it. Same with a Relic but still determining what the calls are for a Relic (aka strategic-point). Bahhh..
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#6 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 02 February 2005 - 11:16 PM

Building at big generator shouldn't be too hard. Currently I'm more interested in building at different LPs and not just one but to do it right I need to count turrets near LPs already finished. Missing the GetPosition() for buildings here.

Today I tried to get the AI to build initial turrets in front of its base but had no success so far. I tried to mod the bias paramater but the AI did ignore me :-(

Edited by LarkinVB, 03 February 2005 - 11:40 AM.


#7 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 03 February 2005 - 01:34 PM

Thanks for taking the time doing the heads-up research for expansion LP turret/building creation. This is one of the key aspects of the AI mod (being able to make the AI aware that on any given map we can specify what gets built). I know this has something to do with terrain.analyser and Relic has acknowledged our plite and continues to maintain they are putting some documentation together for us but its just a wait-and-see or mod-experimentation phase at present.

Of course I'd love to get quick answers to our questions but what game dev out there ever truly comes forth quickly to answer mod-related inquiries? None.. they are paid-devs and the mod community isn't truly their bread-and-butter. Pubs want the next money generator so either expansions or the next-big-thing.

Still.. looks like the constant asking for Relic help has paid off although slow. If we can get some idea about the basic mechanics of the API this would be huge! Its been what I've been looking for since Oct.

Anyway, keep experimenting. Best we can do right now.
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#8 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 03 February 2005 - 06:43 PM

Please modify in cpu_manager.ai to

function CpuManager:IsTurret( build_id )

	

   --ailog("d:\\defense.txt", "Check turret" )
   if build_id == cpu_manager.stats:GetBuildingID( "ork_waagh_banner" ) then
   return true
   elseif build_id == cpu_manager.stats:GetBuildingID( "space_marine_turret_bolter" ) then
   return true
   elseif build_id == cpu_manager.stats:GetBuildingID( "chaos_turret_bolter" ) then
   return true
   elseif build_id == cpu_manager.stats:GetBuildingID( "eldar_support_platform_scatterlaser" ) then
   return true
   end

   --ailog("d:\\defense.txt", "No turret" )  
   return false
end




function CpuManager:FindClosestListenPost( from_pos, no_lp )

   local closest_strat = nil
   local prev_distance = 0

   for strat_ai in resource_manager:GetUnlockedStrategicPointAIs() do
	
  if strat_ai:Owner() == cpu_manager.player_id and strat_ai:HasListeningPost() or no_lp then
  
  	local strat_pos = strat_ai:GetEntity():GetPosition()
  	local num_turrets = 0
  	
  	for build_channel in build_manager:GetBuildChannelAIs() do
	
    if self:IsTurret( build_channel:GetBlueprintID() ) and 
    	distance_sqr(build_channel:GetEntity():GetPosition(), strat_pos) < 200 then
       
          	num_turrets = num_turrets + 1
    end
  
    end
	
  	--determine distance  	
  	if closest_strat == nil and num_turrets < 3 then

      prev_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
      closest_strat = strat_pos
      --ailog("d:\\defense.txt", "First LP at : "..tostring(prev_distance).."turrets :"..tostring(num_turrets))
  
  	elseif num_turrets < 2 then      
  	--check if LP closer to from_pos

     local cur_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
     if prev_distance > cur_distance then

    prev_distance = cur_distance
    closest_strat = strat_pos
      	--ailog("d:\\defense.txt", "Closer LP at : "..tostring(prev_distance).."turrets :"..tostring(num_turrets))

    end
  	end
  	
  end
  
	end
	
	return closest_strat
end


function CpuManager:FindClosestDefensePoint()

	local enemy = cpu_manager:FindClosestEnemyPlayer()
	dbAssert( enemy ~= nil )
	
	--find the closest strategic point I own to this enemy, and use it as my defense point
	local listen_pt = self:FindClosestListenPost( enemy:GetStartingPosition(), false )

	return listen_pt	
end

and change in stratgy.ai the IsTurret() to

  if cpu_manager:IsTurret( id ) then

Result : Build only up to 3 turrets near nearest LP to clostest AI enemy and then continue to build next 2 near nextnearest LP and so on. If no LP is available build at base. Maximum is 10 turrets including the initial ones build at base.

Edited by LarkinVB, 03 February 2005 - 06:49 PM.


#9 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 03 February 2005 - 09:25 PM

Damn thats superb! So in other words there will NOT BE NO REASON to include any turrets in the buildorderstrategyinfo.ai file anymore with this new script? That could free up even more time for the AI to build troops. Right now here is my build schedule:

1) Generator
2) 2x Scouts to begin capture
3) Turret
4) 2nd Servitor created to build Barracks during 3)
5) Servitors build LPs on captured stratpoints
6) Marine Squad + Commander built during 5).

Rest is pretty much waayyy better now than when Larkin "offed" my dead-in-the-water Eldar goons! heheh. Damn that was bad to watch then do shiet in the base. Not no more.. We have Larkin's offense with my defensive mind all in good company AND GETTING BETTER I MUST SAY!

Edited by thudo, 03 February 2005 - 09:26 PM.

Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#10 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 03 February 2005 - 09:42 PM

Note that building turrets is only with tier 2 (if added to function ChaosBuildBaseStrategy:DoSecondaryBuildings() or equivalent race file) and there is enough req/power so initial turrets may be handy nevertheless. Maybe we should code to build turrets also at tier 1 depending on resources ?

I tried to fix initial base turret building to face enemy but got stuck after first turret which is ok.

#11 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 03 February 2005 - 09:48 PM

I tried to fix initial base turret building to face enemy but got stuck after first turret which is ok.

<{POST_SNAPBACK}>


Building initial turrets in the buildorder file works fine however they are position in bizzare places in the main base. If you are successful, they'd position, like a player would, facing the enemy's base. It would be good to have 2-3 turrets in the main base during Tier1 incase of some devious rusher. :sad:
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#12 Corsix

Corsix

    Code Monkey

  • Hosted
  • 290 posts
  • Location:Berkeley, UK
  • Projects:DoW AI, DoW Mod Studio
  •  Blue Text :)

Posted 03 February 2005 - 09:51 PM

Ahh yes, evil rushers - especially the Eldar team rush; 2 eldar players gets loads of BSes and teleport them into an enemy base, build loads of turrets and wipe out a player v early.
Posted Image

#13 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 03 February 2005 - 10:00 PM

That = gay!

Pretty piss-poor exploit if you ask me but yep! Takes one BoneSinger very early and >whamo< - evil Eldar bastard turrets up the YingYang! But hey.. each civ does there own thing - Ork's MekBoy for example - quickest-to-get Commander unit in the game. People hate 'em for rushes especially with the teleport upgrade (which the AI uses real well I might add!).
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!

#14 LarkinVB

LarkinVB

    title available

  • Members
  • 1,488 posts

Posted 04 February 2005 - 11:26 PM

Here is my latest. Please add. Its a safer version checking for threat and more.

function CpuManager:FindClosestListenPost( from_pos, no_lp )

   local closest_strat = nil
   local short_distance = 0

   local base_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, self.cpu_player:GetStartingPosition() )

   for strat_ai in resource_manager:GetUnlockedStrategicPointAIs() do
	
   if strat_ai:Owner() == cpu_manager.player_id and strat_ai:HasListeningPost() or no_lp then
  
   local strat_pos = strat_ai:GetEntity():GetPosition()
   dbAssert( strat_pos ~= nil )
   
   local cur_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
   
   --no building behind base or with threat
   if cur_distance <= base_distance and not cpu_manager.terrain_analyzer:HasThreat( strat_pos, 20 ) then
 	 
 	 local num_turrets = 0
 	 
 	 for build_channel in build_manager:GetBuildChannelAIs() do
      
      if self:IsTurret( build_channel:GetBlueprintID() ) and 
      distance_sqr(build_channel:GetEntity():GetPosition(), strat_pos) < 300 then
      
      num_turrets = num_turrets + 1
      end
      
 	 end
 	 
 	 --2 turrets for each LP
 	 if num_turrets < 2 then
      
      --determine distance 	 
      if closest_strat == nil then
      
      short_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
      closest_strat = strat_pos
      --ailog("d:\\defense.txt", "First LP at : "..tostring(prev_distance).."turrets :"..tostring(num_turrets))
      
      else      
      --check if LP is closer to from_pos
      
      local cur_distance = cpu_manager.terrain_analyzer:GetPathingDistance( from_pos, strat_pos )
      if short_distance > cur_distance then
      
      short_distance = cur_distance
      closest_strat = strat_pos
      --ailog("d:\\defense.txt", "Closer LP at : "..tostring(prev_distance).."turrets :"..tostring(num_turrets))
      
      end
      end
      
 	 end
   end
   
   end
   end

   return closest_strat
end


function CpuManager:FindClosestDefensePoint()

	local enemy = cpu_manager:FindClosestEnemyPlayer()
	dbAssert( enemy ~= nil )
	
	--find the closest strategic point I own to this enemy, and use it as my defense point
	local listen_pt = self:FindClosestListenPost( enemy:GetStartingPosition(), false )

	return listen_pt	
end




Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users