Jump to content


xiongmao

Member Since 14 Feb 2008
Offline Last Active Oct 16 2009 01:14 PM

Topics I've Started

DataRun - CorruptData

09 May 2008 - 12:37 AM

Hi all,
I've implemented the corrupt data segment basis (check Wiki Appendix for further details).

Features implemented:
- the volume: replace pawn inventory by the checktool, allow the player to scan or heal the corrupt data segment
- the corrupt data segment: scan and heal mechanism implemented, display current scan or heal amount and corruptdata tag name on screen as well.
- send localmessage at scan and heal end
- 2 Damage types: (primary and secondary) used by corrupt data segment class to know what FireMode the player is using.

Temporary Feature:
- CheckTool: a basic weapon has been created, it inherits from the Enforcer (could be replaced later depends of what should the CheckTool looks like)

CheckTool secondary fire sucks but as I said it's temporary :p

Here are some pictures in Game:
Phase Scanning
Posted Image
Posted Image

Phase Healing
Posted Image
Posted Image

Message End Phase
Posted Image
Posted Image

Source Code

Corrupt Data Segment
class DataRun_CorruptDataSegment extends Actor
	  placeable;

var() string corruptDataTagName;
var() int scanDuration;
var() int healDuration;
var() string scanEndMessage;
var() string healEndMessage;

//this boolean is updated according to pawn location. true when pawn entering the
//volume and false when leaving. This is used to prevent scan or heal outside
//the volume
var bool segmentCanBeHit;

var float currentScanAmount;
var float currentHealAmount;

var float scanIncrement;
var float healIncrement;

event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
{
	if(!segmentCanBeHit || self.IsInState('healed'))
	   return;

	if(DataRun_CheckTool(DamageCauser) == None)
	   return;

	//compute scan and heal increment
	if(scanIncrement == -1 || healIncrement == -1)
	{
		scanIncrement =  DataRun_CheckTool(DamageCauser).fireInterval[0] * 100 / scanDuration;
		healIncrement =  DataRun_CheckTool(DamageCauser).fireInterval[1] * 100 / healDuration;
	}

	if(DamageType == class'DataRun_CheckTool_DmgType_PrimaryFire' && currentScanAmount < 100)
	{
	   GotoState('scanning');
	}

	if(DamageType == class'DataRun_CheckTool_DmgType_SecondaryFire' && currentScanAmount >= 100 && currentHealAmount < 100)
	{
	   GotoState('healing');
	}
}

state scanning
{

   event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
   {
	  if(!segmentCanBeHit || self.IsInState('healed') || DamageType != class'DataRun_CheckTool_DmgType_PrimaryFire')
		 return;

	  currentScanAmount += scanIncrement;
	  if(currentScanAmount >= 100)
	  {
		 PlayerController(EventInstigator).ReceiveLocalizedMessage(MessageClass,0,,,self);
		 GotoState('healing');
	  }
   }

   function BeginState(Name PreviousStateName)
   {
	  //First we enter state increase scan amount
	  currentScanAmount += scanIncrement;
   }
}

state healing
{
   event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
   {
	  if(!segmentCanBeHit || self.IsInState('healed') || DamageType != class'DataRun_CheckTool_DmgType_SecondaryFire')
		 return;

	  currentHealAmount += HealIncrement;

	  if(currentHealAmount >= 100)
	  {
		 PlayerController(EventInstigator).ReceiveLocalizedMessage(MessageClass,1,,,self);
		 GotoState('healed');
	  }
   }

   function BeginState(Name PreviousStateName)
   {
	  //First we enter state increase heal amount
	  currentHealAmount += healIncrement;
   }
}

//final state for corrup data segment
state healed
{
   function BeginState(Name PreviousStateName)
   {
   }
}


simulated event PostRenderFor(PlayerController PC, Canvas Canvas, vector CameraPosition, vector CameraDir)
{
	local float XL, YL, HealthX, TextXL;
	local vector ScreenLoc;
	local string ScreenName;

	ScreenLoc = Canvas.Project(Location);

	// make sure not clipped out
	if (screenLoc.X < 0 ||
		screenLoc.X >= Canvas.ClipX ||
		screenLoc.Y < 0 ||
		screenLoc.Y >= Canvas.ClipY)
	{
		return;
	}

	   if(currentScanAmount > 0 && currentScanAmount < 100)
	   {
		 ScreenName = corruptDataTagName@"Scan Phase in Progress ...";
	   }
	   else  if(currentHealAmount > 0 && currentHealAmount < 100)
	   {
		 ScreenName = corruptDataTagName@"Heal Phase in Progress ...";
	   }
	   else
	   {
		 ScreenName = "";
	   }

	   if(ScreenName != "")
	   {
		 Canvas.StrLen(ScreenName, TextXL, YL);
		 Canvas.DrawColor = class'UTHUD'.default.LightGreenColor;
		 Canvas.SetPos(ScreenLoc.X-0.5*TextXL,ScreenLoc.Y-60);
		 Canvas.DrawTextClipped(ScreenName, true);
	   }
	   if(currentScanAmount < 100)
	   {
		 HealthX = currentScanAmount;
	   }
	   else
	   {
		 HealthX = currentHealAmount;
	   }
	   XL = 100;
	   class'UTHUD'.static.DrawHealth(ScreenLoc.X-0.5*XL, ScreenLoc.Y - 50, HealthX, XL, 20, Canvas);

}

defaultproperties
{
	scanDuration = 2
	healDuration = 5
	scanEndMessage = "scanning complete"
	healEndMessage = "healing complete"
	scanIncrement = -1
	healIncrement = -1
	currentScanAmount = -1
	currentHealAmount = -1
	MessageClass = class'DataRun_CorruptDataSegmentMessage';

	  Begin Object class=DynamicLightEnvironmentComponent Name=OnslaughtFlagLightEnvironment
		bDynamic=FALSE
		bCastShadows=FALSE
	End Object
	Components.Add(OnslaughtFlagLightEnvironment)

	Begin Object class=CylinderComponent Name=CollisionCylinder ObjName=CollisionCylinder Archetype=CylinderComponent'Engine.Default__CylinderComponent'
	  CollisionHeight=25.000000
	  CollisionRadius=25.000000
	  CollideActors=True
	  BlockActors=true
	  BlockZeroExtent=true
	  BlockNonZeroExtent=true
	  HiddenGame=false
	  Name="CollisionCylinder"
	  ObjectArchetype=CylinderComponent'Engine.Default__CylinderComponent'
   End Object
   Components.Add(CollisionCylinder)

	Begin Object class=StaticMeshComponent Name=StaticMeshComponent0
	  StaticMesh=StaticMesh'Pickups.PowerCell.Mesh.S_Pickups_PowerCell_Cell01'
	  LightEnvironment=OnslaughtFlagLightEnvironment
	  scale=2
	End Object
 	Components.Add(StaticMeshComponent0)

   bCanBeDamaged = true
   bCollideActors = true
   bBlockActors = true
   CollisionComponent=CollisionCylinder
   CollisionType=COLLIDE_CustomDefault
   name="Default__DataRun_CorruptDataSegment"
   ObjectArchetype=Actor'Engine.Default__Actor'
}

Corrupt Data Volume
class DataRun_CorruptDataVolume extends PhysicsVolume
	placeable;

var DataRun_CorruptDataSegment segmentActor;
var(ExistingSegment) string segmentTag;
var class<Weapon> checkToolClass;

var InventoryManager PawnBackupInvManager;
var Weapon PawnBackupWeapon;

simulated function PostBeginPlay()
{
   local DataRun_CorruptDataSegment a;

   foreach WorldInfo.AllActors(class'DataRun_CorruptDataSegment', a)
   {
	  if(a.corruptDataTagName == segmentTag)
	  {
		 segmentActor = a;
		 break;
	  }
   }
}

event PawnEnteredVolume(Pawn Other)
{
   local PlayerController PC;
   PC = PlayerController(Other.Controller);
   if(PC != None)
   {
	   //enable segment
	   segmentActor.segmentCanBeHit = true;

	   //enable postRender
	   UTHUD(PC.myHUD).AddPostRenderedActor(segmentActor);

	   giveCheckTool(Other);
   }
}

event PawnLeavingVolume(Pawn Other)
{
   local PlayerController PC;
   PC = PlayerController(Other.Controller);
   if(PC != None)
   {
	  //disable segment
	  segmentActor.segmentCanBeHit = false;

	  //disable postRender
	  UTHUD(PC.myHUD).RemovePostRenderedActor(segmentActor);

	  restituteInventory(Other);
   }
}

function giveCheckTool(Pawn P)
{
  local Inventory inv;
  local InventoryManager checkToolInvManager;
  //backup inventoryManager and weapon
  PawnBackupInvManager = P.InvManager;
  PawnBackupWeapon = P.Weapon;

  //set new inventory and select CheckTool Weapon
  checkToolInvManager = spawn(class'UTInventoryManager');
  UTInventoryManager(checkToolInvManager).bInfiniteAmmo = true;
  checkToolInvManager.SetupFor(P);
  P.InvManager = checkToolInvManager;
  P.InvManager.CreateInventory(checkToolClass, true);

  //we have to force CheckTool selection
  Inv = P.FindInventoryType(checkToolClass);
  P.InvManager.SetPendingWeapon(Weapon(Inv));
  P.InvManager.ChangedWeapon();

}

function restituteInventory(Pawn P)
{
  //restitute previous inventory
  P.InvManager = PawnBackupInvManager;
  if(PawnBackupWeapon != None)
  {
	 P.InvManager.SetPendingWeapon(PawnBackupWeapon);
	 P.InvManager.ChangedWeapon();
  }
}

defaultproperties
{
   checkToolClass = class'DataRun_CheckTool'
}

Corrupt Data Message
class DataRun_CorruptDataSegmentMessage extends UTLocalMessage;

static function string GetString(
		optional int Switch,
		optional bool bPRI1HUD,
		optional PlayerReplicationInfo RelatedPRI_1,
		optional PlayerReplicationInfo RelatedPRI_2,
		optional Object OptionalObject
		)
{
	local DataRun_CorruptDataSegment CR;

	CR = DataRun_CorruptDataSegment(OptionalObject);

	if( CR != None)
	{
		   switch(Switch)
		   {
			 case 0:
				return CR.scanEndMessage;
			 case 1:
				return CR.healEndMessage;
		   }
	}

	return "";
}

defaultproperties
{
	bIsUnique=true
	bCountInstances=true
	DrawColor=(R=255,G=255,B=128,A=255)
	FontSize=2
	bIsConsoleMessage=false
	MessageArea=5
}

Temporary CheckTool
class DataRun_CheckTool extends UTWeap_Enforcer;


defaultproperties
{
	WeaponFireTypes[0]=EWFT_InstantHit
	WeaponFireTypes[1]=EWFT_InstantHit

	InstantHitDamageTypes(0)=class'DataRun_CheckTool_DmgType_PrimaryFire'
	InstantHitDamageTypes(1)=class'DataRun_CheckTool_DmgType_SecondaryFire'

	  FireInterval(0)=+0.25
	FireInterval(1)=+0.25

	InstantHitDamage(0)=0
	InstantHitDamage(1)=0

	FiringStatesArray(0)=WeaponFiring
	FiringStatesArray(1)=WeaponFiring

 }

PrimaryFireDamageType
class DataRun_CheckTool_DmgType_PrimaryFire extends UTDamageType;

static function DoCustomDamageEffects(UTPawn ThePawn, class<UTDamageType> TheDamageType, const out TraceHitInfo HitInfo, vector HitLocation)
{
	//Ze goggles! Zey do nuthing!!
}

defaultproperties
{
	bUseTearOffMomentum=false
	bCausedByWorld=false
	bOverrideHitEffectColor=true
	HitEffectColor=(R=0,G=0,B=0)
}

SecondaryFireDamageType
class DataRun_CheckTool_DmgType_SecondaryFire extends UTDamageType;

static function DoCustomDamageEffects(UTPawn ThePawn, class<UTDamageType> TheDamageType, const out TraceHitInfo HitInfo, vector HitLocation)
{
	//Ze goggles! Zey do nuthing!!
}

defaultproperties
{
	bUseTearOffMomentum=false
	bCausedByWorld=false
	bOverrideHitEffectColor=true
	HitEffectColor=(R=0,G=0,B=0)
}

Questions? Comments? :rolleyes:

DataRun - Online Statistics

05 May 2008 - 10:28 PM

Hi all,
I've worked on the OnlineStatistics (Further informations) this evening and manage to send post request to Ash's server.
Ash is the person in charge of creating DataRun Website, he provided us a test page to send post and get request at the following address: http://kyuu.co.uk/datarun.php

If you enter the following url for example http://kyuu.co.uk/da...hp?game=dataRun
the web browser will displayed
post vars

get vars
"game" = dataRun

The Objective was to send this kind of request using TcpLink UnrealScript class and here is the code which do that:

Use Class
var DataRun_TcpLink wConn;
wConn = spawn(class'DataRun_TcpLink');
wConn.sendPlayerStat("1664", "BeerLand", "124", "51");

TCPLink Class
class DataRun_TcpLink extends TcpLink
	 config(DataRun);

var config String ipWebSite, urlWebSite, pathFile;
var config int portNumber;

var IpAddr ipA;

function PostBeginPlay()
{

   super.PostBeginPlay();

   StringToIpAddr(ipWebSite, ipA);
   ipA.Port = portNumber;

   BindPort();

   // receive events rather than get data manually
   ReceiveMode = EReceiveMode.RMODE_Event;

   //method receiveText call
   LinkMode = ELinkMode.MODE_Text;
}

/*
 Send a Post Request as follow

  POST /datarun.php HTTP/1.0
  From: xiongmao@datarun.com
  User-Agent: HTTPTool/1.0
  Content-Type: application/x-www-form-urlencoded
  Content-Length: 27
  [Blank Line]
  userid=xiongmao&password=guessme
*/
function sendPlayerStat(String playerID, String level, String totalTime, String energy)
{
  local String httpRequest, request;

  request = getRequest(playerID, level, totalTime, energy);
  httpRequest = getStandardHeader();
  httpRequest $= getContentLength(request);
  httpRequest $= Chr(13)$Chr(10); // add the blank line
  httpRequest $= request;

  if(!IsConnected())
	Open(ipA);

  SendText(httpRequest);
}

function String getStandardHeader()
{
  local String header;

  //set the path of the file which will receive the post request
  header =  "POST /"$pathFile$" HTTP/1.0"$Chr(13)$Chr(10);

  //set the sender (optional)
  header $= "From: xiongmao@datarun.com"$Chr(13)$Chr(10);

  //set user agent
  header $= "User-Agent: HTTPTool/1.0"$Chr(13)$Chr(10);

  //set encode type
  header $= "Content-Type: application/x-www-form-urlencoded"$Chr(13)$Chr(10);

  return header;
}

function String getContentLength(String request)
{
  local String cLength;
  cLength = "Content-Length: "$len(request)$Chr(13)$Chr(10);
  return cLength;
}

function String getRequest(String playerID, String level, String totalTime, String energy)
{
  local String request;
  request = "playerID="$playerID$"&level="$level$"&totalTime="$totalTime$"&energy="$energy;
  return request;
}

event ReceivedText( string Text )
{
   LogInternal("text: "$Text);
}

defaultproperties
{
  pathFile =  "datarun.php"
  ipWebSite =  "82.17.97.168"
  urlWebSite = "http://kyuu.co.uk"
  portNumber = 80
}

and you will see a great trace in your logfile:

HTTP/1.1 200 OK
Date: Mon, 05 May 2008 22:11:59 GMT
Server: Apache
X-Powered-By: PHP/5.2.6RC1-pl1-gentoo
Content-Length: 493
Connection: close
Content-Type: text/html

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
	<title>kyuu</title>
  </head>
<body>
<h1>post vars</h1>
<ul>
<li>"playerID" = 1664</li><li>"level" = BeerLand</li><li>"totalTime" = 124</li><li>"energy" = 51</li></ul>
<h1>get vars</h1>
</body>
</html>

I can't figure out how to find gameSpyId if anyone has a clue ? if not players will have to create a kind of account on the website.
I don't know if it's necessary to take care of receive message (maybe the first line to see if the request has succeeded)

Comment? questions?

DataRun Project

05 May 2008 - 05:21 PM

All right guys,
DataRun project has started. Project has been setup and code from FiveWeek has been ported. You can download the project from SVN : svn://gamemod.net/sheelabs/DataRun
Here you can find:
- Content: UPK File and maps -> Maps of datarun in fiveweek project have to be moved
- Documentation
- Src -> Uscript sources
- Test -> may be renamed to Misc,a folder to put everything such as test videos,...

There's also the Wiki where you can see the project's aim and features ==> WIKI

This thread is dedicated to speak about the project and put any ideas which come to mind.
Here we go !!! :p

DataRun - CameraVolume

01 May 2008 - 07:53 PM

Hi all,
after speaking with Luke, I implemented the prototype of CameraVolume.

What is CameraVolume?
When a playerController enters the volume, his Point Of View switches to CameraVolume Point Of View. The cameravolume is linked to a cameraActor which become CameraVolume's Point of View.

2 ways to set the CameraActor:
- add a CameraActor in the Map set cameratag field and set the same tagname in CameraVolume properties
- set relative position and rotation to a camera which will spawned when game start

2 CameraActors are currently available
- fixedCameraActor: fixed location and rotation
- rotateCameraActor: fixed location rotation (face the PlayerOwner)

Here is a video of the rotate camera: Rotate Camera

CameraVolume
class DataRun_CameraVolume extends PhysicsVolume
	placeable;

var DataRun_FixedCameraActor cameraActor;


enum CameraActorType
{
 TYPE_FIXED, TYPE_ROTATE
};
enum CameraType
{
 TYPE_EXTERNAL_CAMERA, TYPE_MANUAL_CAMERA
};

var() CameraType camType;

var(ExistingCamera) string cameraTag;

var(OwnCamera) CameraActorType camActorType;
var(OwnCamera) vector cameraRelativePosition;
var(OwnCamera) rotator cameraRelativeRotation;


simulated function PostBeginPlay()
{
   local box ActorBox;
   local DataRun_FixedCameraActor a;

   switch(camType)
   {
	 case CameraType.TYPE_MANUAL_CAMERA:

		cameraRelativePosition += location;
		cameraRelativeRotation += rotation;
		//GetComponentsBoundingBox(ActorBox);
		switch(camActorType)
		{
		   case  CameraActorType.TYPE_FIXED:
				cameraActor = Spawn(class'DataRun_FixedCameraActor', self,,,,, TRUE);
				break;

		   case  CameraActorType.TYPE_ROTATE:
				cameraActor = Spawn(class'DataRun_RotateCameraActor', self,,,,, TRUE);
				break;
		}

		cameraActor.SetLocation(cameraRelativePosition);
		cameraActor.SetRotation(cameraRelativeRotation);

	 break;
	 case  CameraType.TYPE_EXTERNAL_CAMERA:

	   foreach WorldInfo.AllActors(class'DataRun_FixedCameraActor', a)
		{
		   if(a.cameraTag == cameraTag)
		   {
			  cameraActor = a;
			  break;
		   }
		}
   }

   LogInternal("CameraActor: "$cameraActor);
}

event PawnEnteredVolume(Pawn Other)
{
   if(PlayerController(Other.Controller) != None)
   {
	  cameraActor.PC = UTPlayerController(Other.Controller);
	  UTPlayerController(Other.Controller).MatineeCameraClass = class'DataRun_FixedCamera';
	  UTPlayerController(Other.Controller).SpawnCamera();
	  UTPlayerController(Other.Controller).PlayerCamera.SetViewTarget(cameraActor);

   }
}


event PawnLeavingVolume(Pawn Other)
{
   if(PlayerController(Other.Controller) != None)
   {
	  UTPlayerController(Other.Controller).MatineeCameraClass = none;
	  if(UTPlayerController(Other.Controller).PlayerCamera != None)
	  {

		UTPlayerController(Other.Controller).PlayerCamera.SetViewTarget(Other);
		UTPlayerController(Other.Controller).PlayerCamera.Destroy();
		UTPlayerController(Other.Controller).PlayerCamera = none;
	  }
   }
}



function Vector getVolumeCenter()
{
  local box ActorBox;
  local Vector diagonal;
  GetComponentsBoundingBox(ActorBox);
  diagonal = ActorBox.Max - ActorBox.Min;
  return diagonal / 2;
}

defaultproperties
{
  camType =TYPE_MANUAL_CAMERA
  camActorType = TYPE_ROTATE
}

FixedCameraActor
class DataRun_FixedCameraActor extends DynamicCameraActor
	placeable;

var() string cameraTag;
var PlayerController PC;

simulated function GetCameraView(float DeltaTime, out TPOV OutPOV)
{
	GetActorEyesViewPoint(OutPOV.Location, OutPOV.Rotation);
	OutPOV.FOV = FOVAngle;
}

defaultproperties
{
 cameraTag="DataRun_FixedCameraActor";
}

RotateCameraActor
class DataRun_RotateCameraActor extends DataRun_FixedCameraActor
	  placeable;

simulated function GetCameraView(float DeltaTime, out TPOV OutPOV)
{
	super.GetCameraView(DeltaTime, OutPOV);
	if(PC == None)
	  return;
	OutPOV.Rotation = rotator(PC.Pawn.Location-Location);
}
defaultproperties
{
  cameraTag="DataRun_RotateCameraActor";
}

Camera
class DataRun_FixedCamera extends Camera;

Comment ?

TcpLink Communication with Server

11 March 2008 - 11:44 PM

Hi all, create a new topic for this release.
Name:Server Writer
Version:v0.1
Compatibility: v1.2 at least (need TCPLink class)
Description:allow uscript developer to write, append or read from a remote file
Comments:The purpose of this dev is to help modders for persistant storage. Java has been chosen for its interoperability (the server can run on both window and unix platform)
Screenshot:
Credits: Erwan "Xiongmao" Allain
Homepage:
Download: TCPLink.zip


I'm happy to show you my new creation. As it's written in the title, I extend the TCPLink to communicate with a remote Java Server.
For now, it can receive 3 type of requests:
- WRITE_TO_FILE
- APPEND_TO_FILE
- READ_FROM_FILE

Basically, you need to specify the port on which the JavaServer will listen to requests. You also define the ip and port on which the UScript client will create the socket (bridge between client and server) and that's all configuration is setup.
The Unit tests have been passed, although some points stay opened such as communication with proxy.
The next step would be communication with database. As the network part works, it's only new type of request to add and String parsing to handle SQL request.

In the archive, you can find two parts:
- the UScript side which contains a mutator using the new feature
- the JavaSide with the binaries and sources of the server
Don't forget to read the ReadMe.txt first !!!

I appreciate if some people has the courage to test it :p

Edit: Epics Games header like added