Author Topic: Remove need for commander to be at a radio?  (Read 1777 times)

Offline killerbee256

  • Newbie
  • *
  • Posts: 11
    • View Profile
Remove need for commander to be at a radio?
« on: 01-09-2014, 16:09:51 »
Would it possible to remove the need for the commander to at a radio in single player? I ask this because the AI lacks any type of tactical sense and will focus on the wrong flags thus loses the map.  If it were possible to for the player to be the commander and give orders from anywhere this would solve the problem to a degree. If this is simple to fix on the my end let me know.

Offline Harmonikater

  • FH-Betatester
  • ***
  • Posts: 370
  • Resident Crazy Composer
    • View Profile
Re: Remove need for commander to be at a radio?
« Reply #1 on: 06-09-2014, 00:09:38 »
You can try this: (at your own risk)
Go to your /Battlefield 2/ folder and navigate to /mods/fh2/python/game/plugins/
In the /plugins folder create an empty .txt file.
Copy this code into the text file:
Code: [Select]
import bf2
import host
import bf2.Timer
from game.gameplayPlugin import base
import game.utilities as game
chairTemplates = [
    'gercommradio',
    'britcommradio',
    'aecdorchester_passenger',
    'aecdorchester_de_passenger',
    'aecdorchester_france_passenger',
    'storch_france_rearspotter',
    'storch_trop_rearspotter',
    'pipercub_gb_frontspotter',
    'pipercub_us_frontspotter',
    'sdkfz250_3_commander']
SPAM_TIME = 9

# Change The next Line to "ALWAYS_ENABLE = False" If you want to go back to normal FH2 Commander
ALWAYS_ENABLE = True

class commanderChair(base):
   
    def __init__(self):
        self.timer = None
        self.ids = []

   
    def round_start(self, hooker):
        hooker.register('EnterVehicle', self.enterhook)
        hooker.register('ExitVehicle', self.exithook)
        hooker.register('PlayerDeath', self.deathhook)
        hooker.register('ChangedCommander', self.chcomhook)

   
    def round_end(self, hooker):
        self.ids = []
        if self.timer:
            self.timer.destroy()
            self.timer = None
       

   
    def deathhook(self, player, soldier):
if not ALWAYS_ENABLE:
self.removeplayer(player)

   
    def chcomhook(self, teamid, old_commander, new_commander):
        if old_commander:
            self.removeplayer(old_commander)
       
        if new_commander:
if not ALWAYS_ENABLE:
self.removeplayer(new_commander)
else:
if self.timer == None:
self.timer = bf2.Timer(self.rankevent, SPAM_TIME, 1)
self.timer.setRecurring(SPAM_TIME)

self.ids.append(new_commander.index)
self.rankevent(0)

       

   
    def enterhook(self, player, vehicle, *args):
if not ALWAYS_ENABLE:
if vehicle.templateName.lower() not in chairTemplates:
return None

if player.isCommander():
if self.timer == None:
self.timer = bf2.Timer(self.rankevent, SPAM_TIME, 1)
self.timer.setRecurring(SPAM_TIME)

self.ids.append(player.index)
self.rankevent(0)
       

   
    def exithook(self, player, vehicle):
if not ALWAYS_ENABLE:
if vehicle.templateName.lower() not in chairTemplates:
return None

if player.isCommander():
self.removeplayer(player)
       

   
    def removeplayer(self, player):
        if player.index in self.ids:
            self.ids.remove(player.index)
       
        if len(self.ids) == 0:
            if self.timer:
                self.timer.destroy()
                self.timer = None
           
       

   
    def rankevent(self, ignore):
        for id in self.ids:
            host.sgl_sendRankEvent(id, 1, 2)

Rename the file to "commanderChair.py"
Now you should be able to command also while not in a radio.
If you want to revert back to the old way, replace "ALWAYS_ENABLE = True" with "ALWAYS_ENABLE = False". It will also go back if you delete the commanderChair.py file (don't delete the .pyc file!)

Note that this has no effect if you join a multiplayer server, so you don't have to be afraid of getting kicked for modified content.
I do bad things to the BF2 engine.

Offline Michael Z Freeman

  • Jr. Member
  • **
  • Posts: 811
  • The Few are many ;)
    • View Profile
    • Homepage
Re: Remove need for commander to be at a radio?
« Reply #2 on: 15-03-2015, 20:03:49 »
Thanks for the Python ! I'll give this a go sometime. It also looks like a good way of getting back commander artillery if you can just run around issuing the arty order, rather than requesting it from an AI commander that always ignores the order.

Offline Michael Z Freeman

  • Jr. Member
  • **
  • Posts: 811
  • The Few are many ;)
    • View Profile
    • Homepage
Re: Remove need for commander to be at a radio?
« Reply #3 on: 20-03-2015, 18:03:20 »
Was going to apply this, but then it occurred to me that it will give me a huge game play balance destroying advantage in bot only play. Why ? Because I don't think the enemy AI commander is using artillery. Odd, because I thought it was only the squad leader artillery request that no longer works with the latest BF2 patches. Or maybe I'm wrong and AI commander cannot use drops or artillery at all ?

EDIT: Been thinking about this, and apart from my observation that it would unbalance the game play with just one commander, of course the focus should really be Coop. In a Coop game then its likely that (obviously) there will be at least 2 players so the recommendation would be to play as Commander or have at least one Coop team member playing as Commander. Problem solved ?
« Last Edit: 09-04-2016, 17:04:22 by DJ Barney »

Offline Michael Z Freeman

  • Jr. Member
  • **
  • Posts: 811
  • The Few are many ;)
    • View Profile
    • Homepage
Re: Remove need for commander to be at a radio?
« Reply #4 on: 09-04-2016, 17:04:44 »
I tried this and the script no longer works probably because of updated python. Here's a decompiled "commanderChair.pyc" ...

# File: c (Python 2.3)

Code: [Select]
import bf2
import host
from game.gameplayPlugin import base
from game import fhlog
log = fhlog(__name__)
CHAIR_TEMPLATES = (
'gercommradio', 'britcommradio',
'aecdorchester_passenger',
'aecdorchester_de_passenger',
'aecdorchester_france_passenger',
'storch_france_rearspotter',
'storch_trop_rearspotter',
'pipercub_gb_frontspotter',
'pipercub_us_frontspotter',
'sdkfz250_3_commander')
SPAM_TIME = 9

class commanderChair(base):
   
    def __init__(self):
        self.timers = []

   
    def round_start(self, hooker):
        hooker.register('EnterVehicle', self.on_enter_vehicle)
        hooker.register('ExitVehicle', self.on_exit_hook)
        hooker.register('PlayerDeath', self.on_player_death)
        hooker.register('ChangedCommander', self.on_changed_commander)

   
    def round_end(self, hooker):
        for t in self.timers:
            t.destroy()
       
        self.timers = []

   
    def on_enter_vehicle(self, player, vehicle, *args):
        if player.isCommander():
            self.update_commander(player)
       

   
    def on_exit_hook(self, player, vehicle):
        if player.isCommander():
            self.update_commander(player)
       

   
    def on_player_death(self, player, soldier):
        if player.isCommander():
            self.update_commander(player)
       

   
    def on_changed_commander(self, teamid, old_commander, new_commander):
        if old_commander:
            self.update_commander(old_commander)
       
        if new_commander:
            self.update_commander(new_commander)
       

   
    def update_commander(self, player):
        if not player:
            return None
       
        commander_in_chair = False
        if player.isValid() and player.isCommander() and player.isAlive():
            v = player.getVehicle()
            if v and v.templateName.lower() in CHAIR_TEMPLATES and v.isValid():
                commander_in_chair = True
           
       
        player_timer = None
        for t in self.timers:
            if t.data == player:
                player_timer = t
                break
                continue
       
        if commander_in_chair:
            if player_timer:
                return None
           
            self.spam_commander(player)
            player_timer = bf2.Timer(self.spam_commander, SPAM_TIME, 1, player)
            player_timer.setRecurring(SPAM_TIME)
            self.timers.append(player_timer)
        elif not player_timer:
            return None
       
        self.timers.remove(player_timer)
        player_timer.destroy()

   
    def spam_commander(self, player):
        host.sgl_sendRankEvent(player.index, 1, 2)


(Tell me if you don't want decompiled code being posted and I'll remove it).

What do I need to change to prevent FH from blocking the commander interface when I leave the chair ?

Offline LuckyOne

  • Hero Member
  • ****
  • Posts: 2.722
  • Purple Heart Collector
    • View Profile
Re: Remove need for commander to be at a radio?
« Reply #5 on: 12-04-2016, 10:04:39 »
^ From a quick glance at the code above I'd say commenting out the first line in lines:
Code: [Select]
if v and v.templateName.lower() in CHAIR_TEMPLATES and v.isValid():
                commander_in_chair = True

that's it changing it to:

Code: [Select]
# if v and v.templateName.lower() in CHAIR_TEMPLATES and v.isValid():
commander_in_chair = True

would enable access to the commander interface no matter where the player is.

But this is just my guess, I haven't tested this in game. There might be some unforeseen consequences... Try at your own risk.

EDIT: maybe it will just work in any vehicle, I don't really have an idea how the code in bf2 is layed out nor where this class is used.
« Last Edit: 12-04-2016, 10:04:31 by LuckyOne »
This sentence is intentionally left unfinished...