Page 1 of 3

Translator in MH

Posted: Wed Dec 16, 2015 2:03 pm
by Barbie
Instead of converting all TranslatorEvents in existing old Unreal maps into SpecialEvents or even introducing a new Actor that handles these Events: Is there an existing solution for it? I only found this thread as an announcement here.

Re: Translator in MH

Posted: Wed Dec 16, 2015 4:02 pm
by JackGriffin
I handled this in my Unreal coop controller and you are welcome to the code if you want to use it. What it does it go through the map and spawn exclamation points that circle where the events are located. It looks like this:
http://www.unrealsp.org/viewtopic.php?f ... fix#p66643

Inside the HUD code I inserted the behavior of the translator to automatically pop-up if you walked up and touched the event. To make it go away you just move off it. It's simple, easy, and clean. You can redo it however you like if you want me to send it to you.

And yeah, there are a ton of them and most never have been seen. You'll be surprised when you add my exclamation mod to the maps at how many there are all over the place. Whole stories go untold.

Re: Translator in MH

Posted: Wed Dec 16, 2015 7:46 pm
by Barbie
Yes, that sounds interesting. Is it possible to have this in a small mutator? I prefer this solution because of modularity. And maybe other MH server maintainer want to use that, too.

Re: Translator in MH

Posted: Wed Dec 16, 2015 8:07 pm
by JackGriffin
You are welcome to make it. Put this in post:

Code: Select all

   foreach AllActors(class'TranslatorEvent', TE)
   {
      if(TE !=none)
      {
         TE.bHidden=False;
         TE.DrawType=DT_Mesh;
         TE.Mesh=Mesh'YOURMOD.SV_Invincible';
         TE.bFixedRotationDir=True;
         TE.SetPhysics(PHYS_Rotating);
         TE.RotationRate.Yaw=6000;
         TE.Velocity.Z=6000;
		}
   }
Here's the import code:

Code: Select all

#exec TEXTURE IMPORT NAME=exclamation FILE=Textures\exclamation.bmp FLAGS=2
#exec TEXTURE IMPORT NAME=Blak FILE=Textures\Blak.pcx

#exec mesh import mesh=SV_Invincible anivfile=Models\SV_Invincible_a.3d datafile=Models\SV_Invincible_d.3d x=0 y=0 z=0 mlod=0
#exec mesh origin mesh=SV_Invincible x=0 y=0 z=0
#exec mesh sequence mesh=SV_Invincible seq=All startframe=0 numframes=1
#exec meshmap new meshmap=SV_Invincible mesh=SV_Invincible
#exec meshmap scale meshmap=SV_Invincible x=0.062500 y=0.062500 z=0.125000

#exec MESHMAP SETTEXTURE MESHMAP=SV_Invincible NUM=0 TEXTURE=Blak
#exec MESHMAP SETTEXTURE MESHMAP=SV_Invincible NUM=1 TEXTURE=exclamation
Now in your hud code add this to the end of postrender:

Code: Select all

// Translator event 
	DrawActorTip(Canvas);
and tack this into the class:

Code: Select all

//Add
simulated function DrawActorTip(Canvas Canvas)
{
  local Actor FocusedActor;
//  local vector ScreenPos;

  // Find Target
  FocusedActor = GetFocusedActor();

  // Label Target
  if (FocusedActor != None)
     DrawMyInventory(Canvas);
}

simulated function Actor GetFocusedActor()
{
  local vector Look, EyePos;
  local TranslatorEvent Candidate, Winner;
  local float Score, HiScore;

  EyePos = Owner.Location;
  EyePos.Z += Pawn(Owner).EyeHeight;
  Look = vector(Pawn(Owner).ViewRotation);

  // Iterate through all actors closer than 200 UUs to the player,
  // trying to find the one most directly in front of him:
  HiScore = 0;
  foreach VisibleActors(class'TranslatorEvent', Candidate, 100.0, EyePos)
  {
    // The dot product of two normalised vectors is a nice
    // measure of the angle between them:
    // (1 = perfect match, 0 = right angles, -1 = direct opposites)
    Score = Normal(Candidate.Location - EyePos) dot Look;

    // Ignore actors too far to the sides (too low scores):
    if (Score >= 0.9) // adjust this threshold to taste
    {
      if (Score > HiScore)
      {
        HiScore = Score;
        Winner = Candidate;
      }
    }
  }
  return Winner;
}

//Translator drawing
simulated function DrawMyInventory(Canvas Canvas)
{	
	local inventory Inv; //,Prev, Next, SelectedItem;
	local translator Translator;
	local int TempX,TempY;
	local TranslatorEvent TE;

	if ( Owner.Inventory==None) 
		Return;

	for ( Inv=Owner.Inventory; Inv!=None; Inv=Inv.Inventory )
	{
		if ( Translator(Inv) != None )
			Translator = Translator(Inv);
	}

   ForEach VisibleCollidingActors (Class'TranslatorEvent', TE, 60, Owner.Location)
   {
   	if(TE != None)
   	{
  			Canvas.bCenter = false;
			Canvas.Font = Canvas.MedFont;
			TempX = Canvas.ClipX;
			TempY = Canvas.ClipY;
			CurrentMessage = Translator.NewMessage;
			Canvas.Style = 2;	
			Canvas.SetPos(Canvas.ClipX/2-208, Canvas.ClipY/2-212);
         Canvas.Style = ERenderStyle.STY_Modulated;
         Canvas.DrawIcon(texture'myctrans', 1.0);
         Canvas.Style = ERenderStyle.STY_Normal;
			Canvas.SetOrigin(Canvas.ClipX/2-110,Canvas.ClipY/2-52);
			Canvas.SetClip(256,384);
			Canvas.SetPos(0,0);
			Canvas.Style = 1;	
			Canvas.DrawText(CurrentMessage, False);	
			HUDSetup(canvas);
			Canvas.ClipX = TempX;
			Canvas.ClipY = TempY;
		}
	}
}
Attached are the extras you'll need. I'll send you the entire controller if you want it. It has the scanner tool, etc. Everything you see in my Unreal coop server.
Stuff.zip
(137.86 KiB) Downloaded 100 times
EDIT: I added access to my personal FTP in my sig. I just put the entire Unreal coop controller source code in there if you want it. It depends on JGrass to work but you can extract things from it to use any way you like. All mods in this FTP are for Unreal, NOT UT specifically.

Re: Translator in MH

Posted: Wed Dec 16, 2015 11:47 pm
by Barbie
Thanks a lot. The mutator is now ready so far and works if used on client but still not if on server -- enough for today, error hunting is moved to tomorrow. :sleep:

Re: Translator in MH

Posted: Wed Dec 16, 2015 11:56 pm
by JackGriffin
ServerPackage line. Everyone forgets that.

Re: Translator in MH

Posted: Thu Dec 17, 2015 12:21 am
by Barbie
JackGriffin wrote:ServerPackage line. Everyone forgets that.
Did that even before copying .U and .INT files to the server... :D

Re: Translator in MH

Posted: Thu Dec 17, 2015 4:22 am
by JackGriffin
Check your logs, it could be a simple textual mistake. I have to work tomorrow but you are welcome to drop me a message on skype if you are stuck on something.

Re: Translator in MH

Posted: Wed Dec 23, 2015 3:15 pm
by Barbie
Cannot get it to work with server/client. If I add the mutator on client and play locally, it works fine. If I put the U- and int-files on server, add it there to the mutator list and to ServerPackages, it runs on server (these rotating things are visible) and the U-file is send to the client, but nothing happens on client side - even the Tick function seems not being executed. I even tried to add the mutator to clients MyHUD in function ModifyPlayer but MyHUD is None there. I guess I get confused by what is executed where...
A current snapshot of my tries can be found here for some time (don't run make.cmd without modifications ;)); if the source code is enough, have a look into the spoiler.
Spoiler

Code: Select all

class SBMutTranslator extends Mutator;

#exec TEXTURE IMPORT NAME=exclamation	FILE=Textures\exclamation.bmp FLAGS=2
#exec TEXTURE IMPORT NAME=Blak			FILE=Textures\Blak.pcx
#exec TEXTURE IMPORT NAME=myctrans		FILE=Textures\myctrans.bmp


#exec mesh import mesh=SV_Invincible anivfile=Models\SV_Invincible_a.3d datafile=Models\SV_Invincible_d.3d x=0 y=0 z=0 mlod=0
#exec mesh origin mesh=SV_Invincible x=0 y=0 z=0
#exec mesh sequence mesh=SV_Invincible seq=All startframe=0 numframes=1
#exec meshmap new meshmap=SV_Invincible mesh=SV_Invincible
#exec meshmap scale meshmap=SV_Invincible x=0.062500 y=0.062500 z=0.125000

#exec MESHMAP SETTEXTURE MESHMAP=SV_Invincible NUM=0 TEXTURE=Blak
#exec MESHMAP SETTEXTURE MESHMAP=SV_Invincible NUM=1 TEXTURE=exclamation


var bool bInitialized;
var int TranslatorEvents; // counter for TranslatorEvents in a map
var PlayerPawn CurrentPlayer; // the owner of the Canvas
var HUD CurrentHUD; // HUD of *CurrentPlayer*



replication {
	reliable if ( Role == ROLE_Authority )
		TranslatorEvents;
}


simulated function DrawActorTip(Canvas Canvas) {
local Actor FocusedActor;
//  local vector ScreenPos;

	log("DEBUG: DrawActorTip starts");
	CurrentPlayer = Canvas.Viewport.Actor;
	if ( CurrentPlayer != None )
		CurrentHUD = CurrentPlayer.myHUD;
 
	// Find Target
	FocusedActor = GetFocusedActor();

	// Label Target
	if (FocusedActor != None)
		DrawMyInventory(Canvas);
}


simulated function Actor GetFocusedActor() {
local vector Look, EyePos;
local TranslatorEvent Candidate, Winner;
local float Score, HiScore;

	EyePos = CurrentPlayer.Location;
	EyePos.Z += CurrentPlayer.EyeHeight;
	Look = vector(CurrentPlayer.ViewRotation);

	// Iterate through all actors closer than 200 UUs to the player,
	// trying to find the one most directly in front of him:
	HiScore = 0;
	foreach VisibleActors(class'TranslatorEvent', Candidate, 100.0, EyePos)
	{
		// The dot product of two normalised vectors is a nice
		// measure of the angle between them:
		// (1 = perfect match, 0 = right angles, -1 = direct opposites)
		Score = Normal(Candidate.Location - EyePos) dot Look;

		// Ignore actors too far to the sides (too low scores):
		if (Score >= 0.9) // adjust this threshold to taste
		{
			if (Score > HiScore)
			{
				HiScore = Score;
				Winner = Candidate;
			}
		}
	}
	return Winner;
}


//Translator drawing
simulated function DrawMyInventory(Canvas Canvas) {
local string CurrentMessage;
local inventory Inv; //,Prev, Next, SelectedItem;
local translator Translator;
local int TempX,TempY;
local TranslatorEvent TE;

	log("DEBUG: DrawMyInventory starts");
	if (CurrentPlayer.Inventory == None)
		Return;

	for (Inv = CurrentPlayer.Inventory; Inv != None; Inv = Inv.Inventory)
		if (Translator(Inv) != None)
		{
			Translator = Translator(Inv);
			break;
		}
	if (Translator == None)
	{
		warn("Translator == None");
		return;
	}

	ForEach VisibleCollidingActors(Class'TranslatorEvent', TE, 60, CurrentPlayer.Location)
	{
		if(TE != None)
		{
			Canvas.bCenter = false;
			Canvas.Font = Canvas.MedFont;
			TempX = Canvas.ClipX;
			TempY = Canvas.ClipY;
			CurrentMessage = Translator.NewMessage;
			Canvas.Style = 2;
			Canvas.SetPos(Canvas.ClipX/2-208, Canvas.ClipY/2-212);
			Canvas.Style = ERenderStyle.STY_Modulated;
			Canvas.DrawIcon(texture'myctrans', 1.0);
			Canvas.Style = ERenderStyle.STY_Normal;
			Canvas.SetOrigin(Canvas.ClipX/2-110,Canvas.ClipY/2-52);
			Canvas.SetClip(256,384);
			Canvas.SetPos(0,0);
			Canvas.Style = 1;
			log("DEBUG: Canvas.DrawText=" $ CurrentMessage);
			Canvas.DrawText(CurrentMessage, False);
			//SB: HUDSetup(canvas);
			Canvas.ClipX = TempX;
			Canvas.ClipY = TempY;
		}
	}
}



function bool GiveTranslator(PlayerPawn P) {
local Translator T;

	if (P.FindInventoryType(class'Translator') != None)
		return false;
	T = Spawn(class'Translator');
	if (T != None)
	{
		T.RespawnTime = 0.0;
		T.GiveTo(P);
		T.bHeldItem = true;
		return true;
	}
	return false;
}



function ModifyPlayer(Pawn Other) {
/******************************************************************************
log shows following:

if played locally:
	ScriptLog: MH-Bluff.SBMutTranslator0.ModifyPlayer DEBUG: function entry for Other=MH-Bluff.TFemale2
	ScriptLog: MH-Bluff.SBMutTranslator0.ModifyPlayer DEBUG: PlayerPawn(Other).myHUD.HUDMutator=MH-Bluff.SBMutTranslator0

if mutator runs on server:
	MH-Bluff+SBFix.SBMutTranslator0.ModifyPlayer DEBUG: function entry for Other=MH-Bluff+SBFix.TFemale0
	MH-Bluff+SBFix.SBMutTranslator0.ModifyPlayer DEBUG: PlayerPawn(Other).myHUD == None!

******************************************************************************/
	log(self $ ".ModifyPlayer DEBUG: function entry for Other=" $ Other);
	Super.ModifyPlayer(Other);
	if (PlayerPawn(Other) != None)
		if (TranslatorEvents > 0)
		{
			if (PlayerPawn(Other).myHUD != None)
			{
				PlayerPawn(Other).myHUD.HUDMutator = Self;
				log(self $ ".ModifyPlayer DEBUG: PlayerPawn(Other).myHUD.HUDMutator=" $ PlayerPawn(Other).myHUD.HUDMutator);
			}
			else
				log(self $ ".ModifyPlayer DEBUG: PlayerPawn(Other).myHUD == None!");
			GiveTranslator(PlayerPawn(Other));
		}
}




function PostBeginPlay() {
/******************************************************************************
******************************************************************************/
local TranslatorEvent TE;

	if (bInitialized)
		return;
	
	foreach AllActors(class'TranslatorEvent', TE)
	{
		TranslatorEvents++;
		TE.bHidden = False;
		TE.DrawType = DT_Mesh;
		TE.Mesh = Mesh'SV_Invincible';
		TE.bFixedRotationDir = True;
		TE.SetPhysics(PHYS_Rotating);
		TE.RotationRate.Yaw = 6000;
		TE.Velocity.Z = 6000;
	}
	log("map has" @ TranslatorEvents @ "TranslatorEvents");
	if (TranslatorEvents > 0)
		RegisterHUDMutator();
	bInitialized = true;
	
}

simulated function PostRender(canvas Canvas) {
/******************************************************************************
******************************************************************************/
	super.PostRender(Canvas);
	DrawActorTip(Canvas);
}


simulated function Tick(float DeltaTime) {

	// this one spams the log (= it works) if played locally but nothing happens if mutator runs on server
	/***
	if (Level.NetMode != NM_DedicatedServer)
		log("DEBUG simulated function Tick: bHUDMutator=" $ bHUDMutator $ ", Level.NetMode=" $ Level.NetMode $ ", TranslatorEvents=" $ TranslatorEvents);
	***/

	if ( !bHUDMutator && Level.NetMode != NM_DedicatedServer && TranslatorEvents > 0)
		RegisterHUDMutator();
}



defaultproperties
{
	bInitialized=false
}
Apart from this some functionality needs to be added: until now the code does not distinguish between activated and deactivated TranslatorEvents.

Re: Translator in MH

Posted: Wed Dec 23, 2015 3:19 pm
by JackGriffin
B I see this and I'll answer but the next two days are going to be insane for me. I'll reply back Christmas day at the very latest. It's something simple, the mutator only adds the functionality. Everything is run client side so it's just a switch somewhere you are missing. Probably in how your HUD is set up but I'll sort it shortly.

Re: Translator in MH

Posted: Wed Dec 23, 2015 3:48 pm
by Barbie
No problem, take your time, it's not urgent.

Re: Translator in MH

Posted: Wed Dec 23, 2015 4:30 pm
by Barbie
Meanwhile I had a look in Epics Translator.uc: I expected some drawings and displaying message text there but nothing real nor unreal happens there - it looks like a stub.

Re: Translator in MH

Posted: Thu Dec 24, 2015 7:39 am
by sektor2111
A good reminder for me to do something simple here - simple is the best :wink: .

Re: Translator in MH

Posted: Thu Dec 24, 2015 9:32 am
by Higor
Attach a 'translator' weapon in slot 1.
Use it's PostRender() to draw the latest message on screen.

...
Make a translator 3d weapon model... draw text onto a scripted texture... now you got something like SiegeIV's constructor.

Re: Translator in MH

Posted: Thu Dec 24, 2015 4:34 pm
by papercoffee
Higor wrote:Attach a 'translator' weapon in slot 1.
Use it's PostRender() to draw the latest message on screen.

...
Make a translator 3d weapon model... draw text onto a scripted texture... now you got something like SiegeIV's constructor.
I like this idea.