Translator in MH

Discussions about GameTypes
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Translator in MH

Post 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.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Translator in MH

Post 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.
So long, and thanks for all the fish
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Translator in MH

Post 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.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Translator in MH

Post 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 99 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.
So long, and thanks for all the fish
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Translator in MH

Post 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:
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Translator in MH

Post by JackGriffin »

ServerPackage line. Everyone forgets that.
So long, and thanks for all the fish
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Translator in MH

Post by Barbie »

JackGriffin wrote:ServerPackage line. Everyone forgets that.
Did that even before copying .U and .INT files to the server... :D
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Translator in MH

Post 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.
So long, and thanks for all the fish
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Translator in MH

Post 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.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
JackGriffin
Godlike
Posts: 3774
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: Translator in MH

Post 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.
So long, and thanks for all the fish
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Translator in MH

Post by Barbie »

No problem, take your time, it's not urgent.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
Posts: 2802
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Translator in MH

Post 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.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
sektor2111
Godlike
Posts: 6410
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Translator in MH

Post by sektor2111 »

A good reminder for me to do something simple here - simple is the best :wink: .
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: Translator in MH

Post 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.
User avatar
papercoffee
Godlike
Posts: 10447
Joined: Wed Jul 15, 2009 11:36 am
Personal rank: coffee addicted !!!
Location: Cologne, the city with the big cathedral.
Contact:

Re: Translator in MH

Post 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.
Post Reply