Creating Console Functions

My latest test is creating console functions that call code in the engine

My test was wrapping "GuiTSCtrl::project" into a script function, so you can call it like: playgui.project("0 0 100");. which will return to you where the point "0 0 100" will appear on your screen.

That was largely successful, and I used it to make this thing that puts a 2d box around every player in your view

Edit: another screenshot
  • screen2.JPG
  • screen1.jpg

Comments

  • For any of you who are curious

    Here's the code to implement the console function, written for nasm assmbler
    The compiled binary is loaded into a new segment that is loaded to a3a000h, and during intialization of other console functions i have t2 call the init function
    %define addCommandRetStr    0x426410 
    %define ConGetReturnBuffer  0x42caa0
    %define dSscanf             0x55b640
    %define dSprintf            0x55b5e0
    %define GuiTSCtrl_project   0x4d0b40
    
    USE32
    CPU PENTIUM
    
    section .seg7 vstart=0xa3a000
    
    init:
      push 3
      push 3
      push strProject
      push GuiTsCtrlProject
      push strProject
      push strGuiTSCtrl
      call addCommandRetStr
      add esp, 0x18
      retn
    
    
    GuiTsCtrlProject:
      push ebp
      mov ebp,esp
      push esi
      sub esp,20h
      
      lea eax, [ebp+-8h]
      push eax
      lea eax, [ebp+-0ch]
      push eax
      lea eax, [ebp+-10h]
      push eax
      push strGGG 
      mov eax, [ebp+10h]
      mov eax, [eax+8h]  
      push eax
      call dSscanf
      add esp, 14h 
      
      lea eax, [ebp+-1Ch]
      push eax
      lea eax, [ebp+-10h]
      push eax
      mov ecx, [ebp+8h]    
      call GuiTSCtrl_project
    
      add esp, 8h
      push 100h
      call ConGetReturnBuffer
      add esp, 4h
      mov esi, eax 
    
      push eax
      push eax
      fld dword [ebp+-1ch]
      fstp qword [esp]
      push eax
      push eax
      fld dword [ebp+-18h]
      fstp qword [esp]
      push eax
      push eax
      fld dword [ebp+-14h]
      fstp qword [esp]
      push strGGG 
      push 100h
      push esi
      call dSprintf
      add esp, 36
      mov eax, esi
    
      lea esp, [ebp-4]
      pop esi
      pop ebp
      retn
    
    strProject: db 'project',0
    strGuiTSCtrl: db 'GuiTSCtrl',0
    strGGG: db '%g %g %g',0
    

    here's the code to the box player thing, which is largly useless unless you have a modified executable that can do "project" (or a in-script version), and a way of getting the worldbox of the objects of interest
    $BP::boxCount=0;
    
    function BP_Loop() {
      cancel($bploopsch);
      BP_ResetPool();
      
      %screenX = getword(playgui.getExtent(),0);
      %screenY = getword(playgui.getExtent(),1);
      for(%i=0;%i<ServerConnection.getCount();%i++) {
        %obj = ServerConnection.getObject(%i);
        if(%obj.getClassName() $= "Player") {
          //display the player if he faces the screen
          //is his center onscreen?
          %res = PlayGui.project(%obj.getWorldBoxCenter());
          if ( getWord(%res,0) > 0.8 && 
              getWord(%res,2) > 0 && getWord(%res,1) > 0 &&
              getWord(%res,2) < %screenX && getWord(%res,1) < %screenY) {
            //yes, he is, draw box
            BP_boxPlayer(%obj);
          }
        }
      }
      
      BP_HideRemainingBoxes();
      $bploopsch=schedule(16,0,"bp_loop");
    }
    
    function BP_boxPlayer(%obj) {
      %ctrl = BP_GetNextBox();
      
      //create a box that will encompass all the points of his worldbox
      %worldBox = %obj.getWorldBox();
      %minx = getword(%worldBox,0);
      %miny = getword(%worldBox,1);
      %minz = getword(%worldBox,2);
      %maxx = getword(%worldBox,3);
      %maxy = getword(%worldBox,4);
      %maxz = getWord(%worldBox,5);
      
      %pt0 = %minx SPC %miny SPC %minz;
      %pt1 = %maxx SPC %miny SPC %minz;  
      %pt2 = %maxx SPC %maxy SPC %minz;
      %pt3 = %minx SPC %maxy SPC %minz;
      %pt4 = %minx SPC %miny SPC %maxz;
      %pt5 = %maxx SPC %miny SPC %maxz;  
      %pt6 = %maxx SPC %maxy SPC %maxz;
      %pt7 = %minx SPC %maxy SPC %maxz;
      
      %screenX = getword(playgui.getExtent(),0);
      %screenY = getword(playgui.getExtent(),1);
      %minx=%screenX;
      %maxx=0;
      %miny=%screenY;
      %maxy=0;
      
      for(%i=0;%i<8;%i++) {
        %pt[%i]=getWords(PlayGui.project(%pt[%i]),1,2);
        %x = getWord(%pt[%i],1);
        %y = getWord(%pt[%i],0);
        if (%x < %minx && %x > 0)
          %minx=%x;
        if (%x > %maxx && %x < %screenX)
          %maxx=%x;
        if (%y < %miny && %y > 0)
          %miny=%y;
        if (%y > %maxy && %y < %screenY)
          %maxy=%y;
      }
      
      %ctrl.resize(%minx,%miny,%maxx-%minx,%maxy-%miny);
      
      %ctrl.setVisible(true);
    }
    
    //box pools
    function BP_ResetPool() {
      $BP::nextBox=0;
    }
    
    function BP_GetNextBox() {
      if ($BP::nextBox == $BP::boxCount) {
        //create new box
        $BP::box[$BP::boxCount] = new HudZoom() {
        	profile = "ZoomHudProfile";
        	position = "0 0";
        	extent = "8 8";
        	visible = "0";
        	fillColor = "0.250000 0.250000 0.250000 0.250000";
        	frameColor = "0.000000 1.000000 0.000000 1.000000";
        	opacity = "1";
        	bp = true;
        };
        playgui.add($BP::box[$BP::boxCount]);
        $BP::boxCount++;
      }
      %ret = $BP::box[$BP::nextBox];
      $BP::nextBox++;
      return %ret;
    }
    
    function BP_HideRemainingBoxes() {
      for(%i=0;$BP::nextBox < $BP::boxCount;$BP::nextBox++)
        $BP::box[$BP::nextBox].setVisible(false);
    }
    
    function BP_cleanupErrantBoxes() {
      $BP::boxCount=0;
      for (%i=0;%i<playgui.getCount();%i++) {
        %obj = playgui.getObject(%i);
        if (%obj.getClassName() $= "HudZoom" && %obj.bp) {
          %obj.delete();
          %i--;
        }
      }
    }
    
  • No one knows what to say.
  • Or we're too busy hacking our games to make ServerConnection.getCount(), ServerConnection.getObject(%i), and %obj.blah() work.
  • Who's we? you and Link?

    I'm talking about the general population of ConMod.

    ServerConnection.GetCount() already works in TGE :)
    so does every group for that matter. in server tree
    called by Tree(); (i found that function by accident too :D)
  • "We" is "me". Linker has already patched the relevant functions in his game, which is why he is able to use the script he created.

    I just haven't had the time to stab at the game in IDA.
  • Or perhaps trying to guess at what the new mod is gonna be like when its finished....
    ...eh alv *shove* eh, eh....*shove*
  • Yes Emp, the protection isn't there in Torque... its like they just removed it because they want to screw over n00b devs who don't pay attention

    As for patching
    437462 - listobjects
    4376BC - getobject
    42E93B - %obj.blah()

    getCount already returns the right count.
Sign In or Register to comment.