Перейти к публикации
Планета Deus Ex

Некоторые вопросы


Рекомендованные сообщения

Необходимо сделать сабж. Пробовал сие через КонЭдит, но там чек(как и трансфер) может работать только с объектами деусовского пака(DeusEx.u), пробовал сделать название_класса.название_объекта -- безрезультатно. Это раз. Два я решился не извращаться конэдиторами и сделать все по-православному, через скрипты, создавая свой класс. Один хрен -- порылся в исходниках Дх.ю и никакого примера с использованием функции чек не нашел. Посоветовали просто поюзать if, но какой от него толк? Ведь все равно прийдется проверять содержимое инвентаря(вот и этому примера я тоже на нашёл).

Изменено пользователем mj12-kun
Ссылка на сообщение

Это отдельный класс:

class MyCustomConplay extends conplay;


// ok: Shane (that guy, of TNM fame) came up with this fix: the basic setup uses the checkobject property
// which is set by native craziness..so, use the string objectname instead and cast to class with
// dynamicloadobject (thanks UnrealWiki)

//
// ----------------------------------------------------------------------
// SetupEventCheckObject()
//
// Checks to see if the player has the given object.  If so, then we'll
// just fall through and continue running code.  Otherwise we'll jump
// to the supplied label.
// ----------------------------------------------------------------------

function EEventAction SetupEventCheckObject( ConEventCheckObject event, out String nextLabel )
{
local EEventAction nextAction;
local Name keyName;
local bool bHasObject;
	local class<inventory> CheckThing;
local string seekname;

// Okay this is some HackyHack stuff here.  We want the ability to
// check if the player has a particular nanokey.  Sooooooo.

if ((event.checkObject == None) && (Left(event.objectName, 3) == "NK_"))
{
	// Look for key
	keyName	= player.rootWindow.StringToName(Right(event.ObjectName, Len(event.ObjectName) - 3));
	bHasObject = ((player.KeyRing != None) && (player.KeyRing.HasKey(keyName)));
}
else
{
	//look for a fullstop, if not there, add deusex. to the beginning
	if(instr(event.objectname, ".") == -1)
		Seekname = "DeusEx." $ event.objectname;
	else
		Seekname = event.objectname;

	Checkthing = class<inventory>(DynamicLoadObject(Seekname, class'Class')); //grabs a class incidence from the name

	//now find it as before
	bHasObject = (player.FindInventoryType(checkthing) != None);
}

// Now branch appropriately

if (bHasObject)
{
	nextAction = EA_NextEvent;
	nextLabel  = "";
}
else
{
	nextAction = EA_JumpToLabel;
	nextLabel  = event.failLabel;
}

return nextAction;
}

// ----------------------------------------------------------------------
// SetupEventTransferObject()
//
// Gives a Pawn the specified object.  The object will be created out of
// thin air (spawned) if there's no "fromActor", otherwise it's
// transfered from one pawn to another.
//
// We now allow this to work without the From actor, which can happen
// in InfoLinks, since the FromActor may not even be on the map.
// This is useful for tranferring DataVaultImages.
// ----------------------------------------------------------------------

function EEventAction SetupEventTransferObject( ConEventTransferObject event, out String nextLabel )
{
local EEventAction nextAction;
local Inventory invItemFrom;
local Inventory invItemTo;
local ammo AmmoType;
local bool bSpawnedItem;
local bool bSplitItem;
local int itemsTransferred;
local class<inventory> CheckThing;
local string seekname;

/*
log("SetupEventTransferObject()------------------------------------------");
log("  event = " $ event);
log("  event.giveObject = " $ event.giveObject);
log("  event.fromActor  = " $ event.fromActor );
log("  event.toActor	= " $ event.toActor );
*/
itemsTransferred = 1;

if ( event.failLabel != "" )
{
	nextAction = EA_JumpToLabel;
	nextLabel  = event.failLabel;
}
else
{
	nextAction = EA_NextEvent;
	nextLabel = "";
}

// First verify that the receiver exists!
if (event.toActor == None)
{
	log("SetupEventTransferObject:  WARNING!  toActor does not exist!");
	log("  Conversation = " $ con.conName);
	return nextAction;
}


//========================
// custom stuff!!
//========================

//ok, we're going to reassign the checkobject to use checkthing instead, which
//we'll make from the objectname. Hurrah!

//look for a fullstop, if not there, add deusex. to the beginning
if(instr(event.objectname, ".") == -1)
	Seekname = "DeusEx." $ event.objectname;
else
	Seekname = event.objectname;

Checkthing = class<inventory>(DynamicLoadObject(Seekname, class'Class')); //grabs a class incidence from the name

if(checkthing == none) //oh noes!
{
	log("SHIT! I done gone fucked up teh transfer! I was trying to load up"@seekname);
	return nextAction; //assume fail, essentially
}
//Ok! Now we're reading to rock and roll!!!

// First, check to see if the giver actually has the object.  If not, then we'll
// fabricate it out of thin air.  (this is useful when we want to allow
// repeat visits to the same NPC so the player can restock on items in some
// scenarios).
//
// Also check to see if the item already exists in the recipient's inventory

if (event.fromActor != None)
	invItemFrom = Pawn(event.fromActor).FindInventoryType(Checkthing);

invItemTo   = Pawn(event.toActor).FindInventoryType(Checkthing);

//log("  invItemFrom = " $ invItemFrom);
//log("  invItemTo   = " $ invItemTo);

// If the player is doing the giving, make sure we remove it from
// the object belt.

// If the giver doesn't have the item then we must spawn a copy of it
if (invItemFrom == None)
{
	invItemFrom = Spawn(Checkthing);
	bSpawnedItem = True;
}

// If we're giving this item to the player and he does NOT yet have it,
// then make sure there's enough room in his inventory for the
// object!

if ((invItemTo == None) &&
	(DeusExPlayer(event.toActor) != None) &&
	(DeusExPlayer(event.toActor).FindInventorySlot(invItemFrom, True) == False))
{
	// First destroy the object if we previously Spawned it
	if (bSpawnedItem)
		invItemFrom.Destroy();

	return nextAction;
}

// Okay, there's enough room in the player's inventory or we're not
// transferring to the player in which case it doesn't matter.
//
// Now check if the recipient already has the item.  If so, we are just
// going to give it to him, with a few special cases.  Otherwise we
// need to spawn a new object.

if (invItemTo != None)
{
	// Check if this item was in the player's hand, and if so, remove it
	RemoveItemFromPlayer(invItemFrom);

	// If this is ammo, then we want to just increment the ammo count
	// instead of adding another ammo to the inventory

	if (invItemTo.IsA('Ammo'))
	{
		// If this is Ammo and the player already has it, make sure the player isn't
		// already full of this ammo type! (UGH!)
		if (!Ammo(invItemTo).AddAmmo(Ammo(invItemFrom).AmmoAmount))
		{
			invItemFrom.Destroy();
			return nextAction;
		}

		// Destroy our From item
		invItemFrom.Destroy();
	}

	// Pawn cannot have multiple weapons, but we do want to give the
	// player any ammo from the weapon
	else if ((invItemTo.IsA('Weapon')) && (DeusExPlayer(event.ToActor) != None))
	{

		AmmoType = Ammo(DeusExPlayer(event.ToActor).FindInventoryType(Weapon(invItemTo).AmmoName));

		if ( AmmoType != None )
		{
			// Special case for Grenades and LAMs.  Blah.
			if ((AmmoType.IsA('AmmoEMPGrenade')) ||
				(AmmoType.IsA('AmmoGasGrenade')) ||
				(AmmoType.IsA('AmmoNanoVirusGrenade')) ||
				(AmmoType.IsA('AmmoLAM')))
			{
				if (!AmmoType.AddAmmo(event.TransferCount))
				{
					invItemFrom.Destroy();
					return nextAction;
				}
			}
			else
			{
				if (!AmmoType.AddAmmo(Weapon(invItemTo).PickUpAmmoCount))
				{
					invItemFrom.Destroy();
					return nextAction;
				}

				event.TransferCount = Weapon(invItemTo).PickUpAmmoCount;
				itemsTransferred = event.TransferCount;
			}

			if (event.ToActor.IsA('DeusExPlayer'))
				DeusExPlayer(event.ToActor).UpdateAmmoBeltText(AmmoType);

			// Tell the player he just received some ammo!
			invItemTo = AmmoType;
		}
		else
		{
			// Don't want to show this as being received in a convo
			invItemTo = None;
		}

		// Destroy our From item
		invItemFrom.Destroy();
		invItemFrom = None;
	}

	// Otherwise check to see if we need to transfer more than
	// one of the given item
	else
	{
		itemsTransferred = AddTransferCount(invItemFrom, invItemTo, event, Pawn(event.toActor), False);

		// If no items were transferred, then the player's inventory is full or
		// no more of these items can be stacked, so abort.
		if (itemsTransferred == 0)
			return nextAction;

		// Now destroy the originating object (which we either spawned
		// or is sitting in the giver's inventory), but check to see if this
		// item still has any copies left first

		if (((invItemFrom.IsA('DeusExPickup')) && (DeusExPickup(invItemFrom).bCanHaveMultipleCopies) && (DeusExPickup(invItemFrom).NumCopies <= 0)) ||
		   ((invItemFrom.IsA('DeusExPickup')) && (!DeusExPickup(invItemFrom).bCanHaveMultipleCopies)) ||
		   (!invItemFrom.IsA('DeusExPickup')))
		{
			invItemFrom.Destroy();
			invItemFrom = None;
		}
	}
}

// Okay, recipient does *NOT* have the item, so it must be give
// to that pawn and the original destroyed
else
{
	// If the item being given is a stackable item and the
	// recipient isn't receiving *ALL* the copies, then we
	// need to spawn a *NEW* copy and give that to the recipient.
	// Otherwise just do a "SpawnCopy", which transfers ownership
	// of the object to the new owner.

	if ((invItemFrom.IsA('DeusExPickup')) && (DeusExPickup(invItemFrom).bCanHaveMultipleCopies) &&
		(DeusExPickup(invItemFrom).NumCopies > event.transferCount))
	{
		itemsTransferred = event.TransferCount;
		invItemTo = Spawn(checkthing);
		invItemTo.GiveTo(Pawn(event.toActor));
		DeusExPickup(invItemFrom).NumCopies -= event.transferCount;
		bSplitItem   = True;
		bSpawnedItem = True;
	}
	else
	{
		invItemTo = invItemFrom.SpawnCopy(Pawn(event.toActor));
	}

//log("  invItemFrom = "$  invItemFrom);
//log("  invItemTo   = " $ invItemTo);

	if (DeusExPlayer(event.toActor) != None)
		DeusExPlayer(event.toActor).FindInventorySlot(invItemTo);

	// Check if this item was in the player's hand *AND* that the player is
	// giving the item to someone else.
	if ((DeusExPlayer(event.fromActor) != None) && (!bSplitItem))
		RemoveItemFromPlayer(invItemFrom);

	// If this was a DataVaultImage, then the image needs to be
	// properly added to the datavault
	if ((invItemTo.IsA('DataVaultImage')) && (event.toActor.IsA('DeusExPlayer')))
	{
		DeusExPlayer(event.toActor).AddImage(DataVaultImage(invItemTo));

		if (conWinThird != None)
			conWinThird.ShowReceivedItem(invItemTo, 1);
		else
			DeusExRootWindow(player.rootWindow).hud.receivedItems.AddItem(invItemTo, 1);

		invItemFrom = None;
		invItemTo   = None;
	}

	// Special case for Credit Chits also
	else if ((invItemTo.IsA('Credits')) && (event.toActor.IsA('DeusExPlayer')))
	{
		if (conWinThird != None)
			conWinThird.ShowReceivedItem(invItemTo, Credits(invItemTo).numCredits);
		else
			DeusExRootWindow(player.rootWindow).hud.receivedItems.AddItem(invItemTo, Credits(invItemTo).numCredits);

		player.Credits += Credits(invItemTo).numCredits;

		invItemTo.Destroy();

		invItemFrom = None;
		invItemTo   = None;
	}

	// Now check to see if the transfer event specified transferring
	// more than one copy of the object
	else
	{
		itemsTransferred = AddTransferCount(invItemFrom, invItemTo, event, Pawn(event.toActor), True);

		// If no items were transferred, then the player's inventory is full or
		// no more of these items can be stacked, so abort.
		if (itemsTransferred == 0)
		{
			invItemTo.Destroy();
			return nextAction;
		}

		// Update the belt text
		if (invItemTo.IsA('Ammo'))
			player.UpdateAmmoBeltText(Ammo(invItemTo));
		else
			player.UpdateBeltText(invItemTo);
	}
}

// Show the player that he/she/it just received something!
if ((DeusExPlayer(event.toActor) != None) && (conWinThird != None) && (invItemTo != None))
{
	if (conWinThird != None)
		conWinThird.ShowReceivedItem(invItemTo, itemsTransferred);
	else
		DeusExRootWindow(player.rootWindow).hud.receivedItems.AddItem(invItemTo, itemsTransferred);
}

nextAction = EA_NextEvent;
nextLabel = "";

return nextAction;
}

defaultproperties
{}

А это нужно вставить в класс игрока (у меня это был AV_Player)

 

// ----------------------------------------------------------------------
// StartConversation()
//
// Overridden (hopefully) to allow my custom conplay
// ----------------------------------------------------------------------

function bool StartConversation(
Actor invokeActor,
EInvokeMethod invokeMethod,
optional Conversation con,
optional bool bAvoidState,
optional bool bForcePlay
)
{
local DeusExRootWindow root;

root = DeusExRootWindow(rootWindow);

// First check to see the actor has any conversations or if for some
// other reason we're unable to start a conversation (typically if
// we're alread in a conversation or there's a UI screen visible)

if ((!bForcePlay) && ((invokeActor.conListItems == None) || (!CanStartConversation())))
	return False;

// Make sure the other actor can converse
if ((!bForcePlay) && ((ScriptedPawn(invokeActor) != None) && (!ScriptedPawn(invokeActor).CanConverse())))
	return False;

// If we have a conversation passed in, use it.  Otherwise check to see
// if the passed in actor actually has a valid conversation that can be
// started.

if ( con == None )
	con = GetActiveConversation(invokeActor, invokeMethod);

// If we have a conversation, put the actor into "Conversation Mode".
// Otherwise just return false.
//
// TODO: Scan through the conversation and put *ALL* actors involved
//	   in the conversation into the "Conversation" state??

if ( con != None )
{
	// Check to see if this conversation is already playing.  If so,
	// then don't start it again.  This prevents a multi-bark conversation
	// from being abused.
	if ((conPlay != None) && (conPlay.con == con))
		return False;

	// Now check to see if there's a conversation playing that is owned
	// by the InvokeActor *and* the player has a speaking part *and*
	// it's a first-person convo, in which case we want to abort here.
	if (((conPlay != None) && (conPlay.invokeActor == invokeActor)) &&
		(conPlay.con.bFirstPerson) &&
		(conPlay.con.IsSpeakingActor(Self)))
		return False;

	// Check if the person we're trying to start the conversation
	// with is a Foe and this is a Third-Person conversation.
	// If so, ABORT!
	if ((!bForcePlay) && ((!con.bFirstPerson) && (ScriptedPawn(invokeActor) != None) && (ScriptedPawn(invokeActor).GetPawnAllianceType(Self) == ALLIANCE_Hostile)))
		return False;

	// If the player is involved in this conversation, make sure the
	// scriptedpawn even WANTS to converse with the player.
	//
	// I have put a hack in here, if "con.bCanBeInterrupted"
	// (which is no longer used as intended) is set, then don't
	// call the ScriptedPawn::CanConverseWithPlayer() function

	if ((!bForcePlay) && ((con.IsSpeakingActor(Self)) && (!con.bCanBeInterrupted) && (ScriptedPawn(invokeActor) != None) && (!ScriptedPawn(invokeActor).CanConverseWithPlayer(Self))))
		return False;

	// Hack alert!  If this is a Bark conversation (as denoted by the
	// conversation name, since we don't have a field in ConEdit),
	// then force this conversation to be first-person
	if (Left(con.conName, Len(con.conOwnerName) + 5) == (con.conOwnerName $ "_Bark"))
		con.bFirstPerson = True;

	// Make sure the player isn't ducking.  If the player can't rise
	// to start a third-person conversation (blocked by geometry) then
	// immediately abort the conversation, as this can create all
	// sorts of complications (such as the player standing through
	// geometry!!)

	if ((!con.bFirstPerson) && (ResetBasedPawnSize() == False))
		return False;

	// If ConPlay exists, end the current conversation playing
	if (conPlay != None)
	{
		// If we're already playing a third-person conversation, don't interrupt with
		// another *radius* induced conversation (frobbing is okay, though).
		if ((conPlay.con != None) && (conPlay.con.bFirstPerson) && (invokeMethod == IM_Radius))
			return False;

		conPlay.InterruptConversation();
		conPlay.TerminateConversation();
	}

	// If this is a first-person conversation _and_ a DataLink is already
	// playing, then abort.  We don't want to give the user any more
	// distractions while a DL is playing, since they're pretty important.
	if ( dataLinkPlay != None )
	{
		if (con.bFirstPerson)
			return False;
		else
			dataLinkPlay.AbortAndSaveHistory();
	}

	// Found an active conversation, so start it
	conPlay = Spawn(class'MyCustomConPlay');
	conPlay.SetStartActor(invokeActor);
	conPlay.SetConversation(con);
	conPlay.SetForcePlay(bForcePlay);
	conPlay.SetInitialRadius(VSize(Location - invokeActor.Location));

	// If this conversation was invoked with IM_Named, then save away
	// the current radius so we don't abort until we get outside
	// of this radius + 100.
	if ((invokeMethod == IM_Named) || (invokeMethod == IM_Frob))
	{
		conPlay.SetOriginalRadius(con.radiusDistance);
		con.radiusDistance = VSize(invokeActor.Location - Location);
	}

	// If the invoking actor is a ScriptedPawn, then force this person
	// into the conversation state
	if ((!bForcePlay) && (ScriptedPawn(invokeActor) != None ))
		ScriptedPawn(invokeActor).EnterConversationState(con.bFirstPerson, bAvoidState);

	// Do the same if this is a DeusExDecoration
	if ((!bForcePlay) && (DeusExDecoration(invokeActor) != None ))
		DeusExDecoration(invokeActor).EnterConversationState(con.bFirstPerson, bAvoidState);

	// If this is a third-person convo, we're pretty much going to
	// pause the game.  If this is a first-person convo, then just
	// keep on going..
	//
	// If this is a third-person convo *AND* 'bForcePlay' == True,
	// then use first-person mode, as we're playing an intro/endgame
	// sequence and we can't have the player in the convo state (bad bad bad!)

	if ((!con.bFirstPerson) && (!bForcePlay))
	{
		GotoState('Conversation');
	}
	else
	{
		if (!conPlay.StartConversation(Self, invokeActor, bForcePlay))
		{
			AbortConversation(True);
		}
	}

	return True;
}
else
{
	return False;
}
}

 

Взято отсюда: http://www.dxediting.com/forums/showthread.php?t=2285

 

Потом нужно в ConEdit указывать так: МойПакет.МойКласс. Работает 100% !

Ссылка на сообщение

Ок, благодарю.

Но я придумал кое-что свое. Картридер. Окаалось, что просто так объект нельзя поюзать нанокейрингом, просто прописав его в скрипте объекта, для этого приходится ковырять ДХПлейер, создавая свой класс плейера. Я решил заменить нанокей и нанокейринг на свои нанокард и нанокардринг соотв-но(тобешь св-ва этих объектов остаются неизменными, я просто меняю меши и сообщения(с названиями. при отсутствии объекта етц)). Также я прописал что мой будущий нанокард может применяться только к моим кардсканнерам(локпикивание убрал, хотел сделать вместо него мультитул-хак, но было лень писать литр кода, тем более, что я просто тестил):

class NanoCardRing extends SkilledTool;

var localized string NoCards;
var localized string CardsAvailableLabel;

// ----------------------------------------------------------------------
// Networking Replication
// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
// HasCard()
//
// Checks to see if we have the keyname passed in
// ----------------------------------------------------------------------

simulated function bool HasCard(Name CardToLookFor)
{
local NanoKeyInfo aCard;
local Bool bHasCard;

bHasCard = False;

if (GetPlayer() != None)
{
	aCard = GetPlayer().CardList;

	// Loop through all the keys and see if one exists
	while(aCard != None)
	{
		if (aCard.CardID == CardToLookFor)
		{
			bHasCard = True;
			break;
		}

		aCard = aCard.NextCard;
	}
}
return bHasCard;
}

// ----------------------------------------------------------------------
// GiveCard()
//
// Adds a Card to our array
// ----------------------------------------------------------------------

simulated function GiveCard(Name newCardID, String newDescription)
{
local NanoCardInfo aCard;

if (GetPlayer() != None)
{
	// First check to see if the player already has this Card
	if (HasCard(newCardID))
		return;

	// Spawn a Card
	aCard = GetPlayer().CreateNanoCardInfo();

	// Set the appropriate fields and 
	// add to the beginning of our list
	aCard.CardID	   = newCardID;
	aCard.Description = newDescription;
	aCard.NextCard	 = GetPlayer().CardList;
	GetPlayer().CardList   = aCard;

}
}

// ----------------------------------------------------------------------
// function GiveClientCard()
// ----------------------------------------------------------------------

simulated function GiveClientCard(Name newCardID, String newDescription)
{
  GiveCard(newCardID, newDescription);
}

// ----------------------------------------------------------------------
// RemoveCard()
// ----------------------------------------------------------------------

simulated function RemoveCard(Name CardToRemove)
{
local NanoCardInfo aCard;
local NanoCardInfo lastCard;

if (GetPlayer() != None)
{
	aCard = GetPlayer().CardList;

	// Loop through all the Cards and see if one exists
	while(aCard != None)
	{
		if (aCard.CardID == CardToRemove)
		{
			if (lastCard != None)
				lastCard.NextCard = aCard.NextCard;

			if (GetPlayer().CardList == aCard)
				GetPlayer().CardList = aCard.NextCard;

			CriticalDelete(aCard);
			aCard = None;

			break;
		}

		lastCard = aCard;
		aCard	= aCard.NextCard;
	}
}
}

// ----------------------------------------------------------------------
// function RemoveClientCard()
// ----------------------------------------------------------------------

simulated function RemoveClientCard(Name CardToRemove)
{
  RemoveCard(CardToRemove);
}

// ----------------------------------------------------------------------
// RemoveAllCards()
// ----------------------------------------------------------------------

simulated function RemoveAllCards()
{
local NanoCardInfo aCard;
local NanoCardInfo deadCard;

if (GetPlayer() != None)
{
	aCard = GetPlayer().CardList;

	// Loop through all the Cards and see if one exists
	while(aCard != None)
	{
		deadCard = aCard;

		CriticalDelete(aCard);
		aCard = None;

		aCard = deadCard.NextCard;
	}

	GetPlayer().CardList = None;
}
}

// ----------------------------------------------------------------------
// ClientRemoveAllCards()
// ----------------------------------------------------------------------

simulated function ClientRemoveAllCards()
{ 
  RemoveAllCards();
}

// ----------------------------------------------------------------------
// UpdateInfo()
// ----------------------------------------------------------------------

simulated function bool UpdateInfo(Object winObject)
{
local PersonaInfoWindow winInfo;
local NanoCardInfo CardInfo;
local int CardCount;

winInfo = PersonaInfoWindow(winObject);
if (winInfo == None)
	return False;

winInfo.SetTitle(itemName);
winInfo.SetText(CardsAvailableLabel);
winInfo.AddLine();

if (GetPlayer() != None)
{
	CardInfo = GetPlayer().CardList;

	if (CardInfo != None)
	{
		while(CardInfo != None)
		{
			winInfo.SetText("  " $ CardInfo.Description);
			CardInfo = CardInfo.NextCard;
			CardCount++;
		}
	}
}

if (CardCount > 0)
{
	winInfo.AddLine();
	winInfo.SetText(Description);
}
else
{
	winInfo.Clear();
	winInfo.SetTitle(itemName);
	winInfo.SetText(NoCards);
}

return True;
}

// ----------------------------------------------------------------------
// GetPlayer()
// ----------------------------------------------------------------------

simulated function TSPlayer GetPlayer()
{
return TSPlayer(Owner);
}

// ----------------------------------------------------------------------
// GetCardCount()
// ----------------------------------------------------------------------

simulated function int GetCardCount()
{
local int CardCount;
local NanoCardInfo aCard;

if (GetPlayer() != None)
{
	aCard = GetPlayer().CardList;

	// Loop through all the Cards and see if one exists
	while(aCard != None)
	{
		CardCount++;
		aCard = aCard.NextCard;
	}
}

return CardCount;
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
state UseIt
{
function PutDown()
{

}

Begin:
PlaySound(useSound, SLOT_None);
PlayAnim('UseBegin',, 0.1);
FinishAnim();
LoopAnim('UseLoop',, 0.1);
GotoState('StopIt');
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
state StopIt
{
function PutDown()
{

}

Begin:
PlayAnim('UseEnd',, 0.1);
GotoState('Idle', 'DontPlaySelect');
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

defaultproperties
{
 NoCards="No Nano Cards Available!"
 CardsAvailableLabel="Nano Cards Available:"
 UseSound=Sound'DeusExSounds.Generic.KeysRattling'
 bDisplayableInv=False
 ItemName="NanoCard Ring"
 ItemArticle="the"
 PlayerViewOffset=(X=16.000000,Y=15.000000,Z=-16.000000)
 PlayerViewMesh=LodMesh'DeusExItems.NanoKeyRingPOV'
 PickupViewMesh=LodMesh'DeusExItems.NanoKeyRing'
 ThirdPersonMesh=LodMesh'DeusExItems.NanoKeyRing'
 Icon=Texture'DeusExUI.Icons.BeltIconNanoKeyRing'
 largeIcon=Texture'DeusExUI.Icons.LargeIconNanoKeyRing'
 largeIconWidth=47
 largeIconHeight=44
 Description="A nanoCard ring can read and store the two-dimensional molecular patterns from different nanokeys, and then recreate those patterns on demand."
 beltDescription="CARD RING"
 bHidden=True
 Mesh=LodMesh'DeusExItems.NanoCardRing'
 CollisionRadius=5.510000
 CollisionHeight=4.690000
 Mass=10.000000
 Buoyancy=5.000000
}


и


class NanoCard extends DeusExPickup;

var() name			CardID;			// unique FName identifier used for movers and such

enum ESkinColor
{
SC_Level1,
SC_Level2,
SC_Level3,
SC_Level4
};

var() ESkinColor SkinColor;

// ----------------------------------------------------------------------
// BeginPlay()
// ----------------------------------------------------------------------

function BeginPlay()
{
Super.BeginPlay();

switch (SkinColor)
{
	case SC_Level1:	MultiSkins[0] = Texture'NanoKeyTex1'; break;
	case SC_Level2:	MultiSkins[0] = Texture'NanoKeyTex2'; break;
	case SC_Level3:	MultiSkins[0] = Texture'NanoKeyTex3'; break;
	case SC_Level4:	MultiSkins[0] = Texture'NanoKeyTex4'; break;
}
}

// ----------------------------------------------------------------------
// GiveTo()
//
// Called during conversations since HandlePickupQuery() isn't called
// then
// ----------------------------------------------------------------------

function GiveTo( pawn Other )
{
local DeusExPlayer player;

if (Other.IsA('DeusExPlayer'))
{
	player = DeusExPlayer(Other);
	player.PickupNanoCard(Self);
	Destroy();
}
else
{
	Super.GiveTo(Other);
}
}

// ----------------------------------------------------------------------
// HandlePickupQuery()
//
// Adds the NanoKey to the player's NanoCardRing and then destroys 
// this object
// ----------------------------------------------------------------------

function bool HandlePickupQuery( inventory Item )
{
local DeusExPlayer player;

if ( Item.Class == Class )
{
	player = DeusExPlayer(Owner);
	player.PickupNanoCard(NanoCard(item));
	item.Destroy();

	return True;
}

return Super.HandlePickupQuery(Item);
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

defaultproperties
{
 ItemName="NanoCard"
 PlayerViewOffset=(X=30.000000,Z=-12.000000)
 PlayerViewMesh=LodMesh'DeusExItems.NanoKey'
 PickupViewMesh=LodMesh'DeusExItems.NanoKey'
 ThirdPersonMesh=LodMesh'DeusExItems.NanoKey'
 Icon=Texture'DeusExUI.Icons.BeltIconNanoKey'
 Description="NO KEY DESCRIPTION - REPORT THIS AS A BUG!"
 beltDescription="NANO"
 Mesh=LodMesh'DeusExItems.NanoKey'
 CollisionRadius=2.050000
 CollisionHeight=3.110000
 Mass=1.000000
}

 

Олсо сделал и NanoCardInfo, как показано выше, таким же способом. Как видно из кода, мне пришлось убрать Networking Replication(цикл replication): ЮЦЦ ругался на GiveClientCard, RemoveClientCard, ClientRemoveAllCards. Обратно заменил слово Card на Key в цикле -- нифига, так же ругается. Для чего служит это Нетворк Репликейшн и нужно оно вообще для одиночной игры? И когда пишешь класс нового игрока, как нужно обозначать пекеджи, которые подключаешь к нему? Название_Пекеджа.Название_класса? Я пробовал и так и так. Ничего не выходит, ругается, что мол нет такого. Может их тогда нужно компилировать по отдельности, а уже потом подключать к друг другу?

Ссылка на сообщение
Для чего служит это Нетворк Репликейшн и нужно оно вообще для одиночной игры?

Для одиночной, насколько мне известно -- не нужно

 

И когда пишешь класс нового игрока, как нужно обозначать пекеджи, которые подключаешь к нему? Название_Пекеджа.Название_класса?

Приведи пример

Ссылка на сообщение

Обычно так:

if (!Owner.IsA('PlayerPawn'))
		Owner.AISendEvent('Distress', EAITYPE_Audio, volume, radius);

 

 

Что именно вывел компилятор? Есть ли у тебя такой класс (CardScanner) ?

Ссылка на сообщение
  • 3 недели спустя...
Что именно вывел компилятор? Есть ли у тебя такой класс (CardScanner) ?

есть, но я его пихнул в один пак со всеми другими скриптами. Он , видимо, не по порядку компилил и прочитал название еще не созданного класа и повис.

 

>>> if (!Owner.IsA('PlayerPawn'))

>>> Owner.AISendEvent('Distress', EAITYPE_Audio, volume, radius);

т.е. это даже если класс "Плейер Поун" не имеет никакого отношения к ДеусИкс.ю, все равно указывать нужно просто название класса?

 

А компилятор выводил "ошибочное название класса" или что-то в этом духе

Ссылка на сообщение

И так. Как сделать, чтобы броня действовала без заряда? Ну, то есть одел и носи. А когда надоест, просто жмешь определенную клавишу и она кладется обратно в инвентарь.

Ссылка на сообщение
Тема здохла? Просто хотелось все таки получить ответ на свой быдловопрос.
А компилятор выводил "ошибочное название класса" или что-то в этом духе

 

Нужно точное сообщение компилятора. Запусти cmd.exe, запусти компилятор оттуда а потом скопируй текст из окна консоли.

 

Как сделать, чтобы броня действовала без заряда?

Так сделано в HardCoreDX, но не знаю как именно.

Ссылка на сообщение

так, кажется я продвинулся. Свой класс игрока нужно создавать не под "ДХПлейер", а под "ДСДентонМэйл". Далее. Мне нужно через мой класс игрока поставить на клавишу бинд. допустим на ">", но это не важно, любая неиспользуемая клавиша. За это отвечает "exec function", правильно? по образу и подобию клавиш активации имплантов я сделал так: "exec function DualmapF1() {if (AP != None) AP.bOFF = True; }"(ну... АП это другой класс, в ктором бул-переменная bOFF, точнее класс называется ArmorPickup, но я в начале упомянул "var travel ArmorPickup AP;"). Общий вид:

class TSHuman extends JCDentonMale;

var travel ArmorPickup AP;

exec function DualmapF1() {if (AP != None) AP.bOFF = True; }

blablabla

Ссылка на сообщение
За это отвечает "exec function", правильно?

Верно

 

В твоем случае нужно отредактировать файл User.ini и прописать твою функцию DualmapF1

 

Еще давно я написала специальную программу чтобы не редактировать User.ini, ее можно взять здесь

Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас
×
×
  • Создать...