ПОМОЩЬ
Вход Регистрация Забыли пароль? Пользователи
Top.Mail.Ru
Сейчас на сайте:
60 человек
Серия Crysis / Crysis / • Уроки CryENGINE 2 Sandbox 2 / Создание скриптов / Добавление системы покупок в игровой режим Team Instant Action
Автор: i59   Дата: 2010-07-16 20:38   Просмотров: 8249   Рейтинг:   Комментарии: (2)
В этом руководстве, я продемонстрирую Вам, как модифицировать игровой режим Team Instant Action, добавив в него систему покупок из PowerStruggle.

Цитата:
Автор i59
Уровень квалификации Продвинутый
Совместимость Все версии Wars
Требования N/A
Дата добавления 26/12/09
Последнее изменение 26/12/09


Изменение TeamInstantAction.lua

Локализация файлов, и перемещение их

Прежде всего, нам нужно будет найти папку где находятся игровые правила.

Чтобы сделать это, зайдите в главную директорию Crysis и перейдите к папке Crysis/Game. Когда Вы окажитесь там, откройте ZPatch1.pak, или если его не существует, GameData.pak.

Когда Вы открыли любой из .pak файлов, откройте Scripts/GameRules. Это местоположение всех файлов lua (код) с игровыми правилами. Это то, куда игра смотрит, когда она хочет знать, что сделать в различных игровых режимах.

В директории Вашей модификации, создайте эти пути так, чтобы они выглядели как-то так: Mods/MyMod/Game/Scripts/GameRules. Затем переместите TeamInstantAction.lua из ZPatch1.pak или GameData.pak (предпочтительней ZPatch1, поскольку он включает в себя последние изменения от Crytek) в эту новую папку.

Когда Вы будете редактировать режим игры, всегда держите последнюю работающую копию игрового режима где-нибудь! Иначе, если Вы получите [ERROR]Runaway thread error, Вы не сможете найти ошибку, и придется переписать целый игровой режим!


Редактирование TeamInstantAction.lua

Откройте .lua в приложении, которое Вы предпочитаете. Я обычно использую PSPad или Dreamweaver. (Блокнот тоже работает)

Найдите следующую строку кода используя CTRL + F или прокрутите вниз:

Lua (teaminstantaction.lua)

Код:
-- timers
TeamInstantAction.TEAM_CHANGE_MIN_TIME = 60; -- time before allowing teamchange
TeamInstantAction.MIN_TEAM_LIMIT_WARN_TIMER = 15; -- team limit warning timer

TeamInstantAction.TIA_SPAWN_LOCATIONS = true;
TeamInstantAction.TEAM_SPAWN_LOCATIONS = true;
TeamInstantAction.NEUTRAL_SPAWN_LOCATIONS = true;

TeamInstantAction.TEAMSCORE_TEAM0_KEY = 10;
TeamInstantAction.TEAMSCORE_TEAM1_KEY = 11;
TeamInstantAction.TEAMSCORE_TEAM2_KEY = 12;


TeamInstantAction.BALANCE_ACTION_TIME = 30;
TeamInstantAction.BALANCE_ACTION_TIMERID = 7000;

TeamInstantAction.SCORE_TEAMKILLS_KEY = InstantAction.SCORE_LAST_KEY+1;
TeamInstantAction.SCORE_SELFKILLS_KEY = InstantAction.SCORE_LAST_KEY+2;


И замените его следующим:

Lua (teaminstantaction.lua)

Код:
-- timers
TeamInstantAction.TEAM_CHANGE_MIN_TIME = 60; -- time before allowing teamchange
TeamInstantAction.MIN_TEAM_LIMIT_WARN_TIMER = 15; -- team limit warning timer

TeamInstantAction.TEAM_SPAWN_LOCATIONS = true; -- spawn in teamed spawn points
TeamInstantAction.USE_SPAWN_GROUPS = true;
TeamInstantAction.NEUTRAL_SPAWN_LOCATIONS = false;

TeamInstantAction.TEAMSCORE_TEAM0_KEY = 10;
TeamInstantAction.TEAMSCORE_TEAM1_KEY = 11;
TeamInstantAction.TEAMSCORE_TEAM2_KEY = 12;

TeamInstantAction.PP_AMOUNT_KEY = 200;

TeamInstantAction.BUY_WEAPON = 1;
TeamInstantAction.BUY_VEHICLE = 2;
TeamInstantAction.BUY_EQUIPMENT = 4;
TeamInstantAction.BUY_AMMO = 8;
TeamInstantAction.BUY_PROTOTYPE = 16;

TeamInstantAction.BUY_ALL = 32-1;


TeamInstantAction.weaponList=
{
{ id="flashbang", name="@mp_eFlashbang", price=10, amount=1, ammo=true, weapon=false, category="@mp_catExplosives", loadout=1},
{ id="smokegrenade", name="@mp_eSmokeGrenade", price=10, amount=1, ammo=true, weapon=false, category="@mp_catExplosives", loadout=1 },
{ id="explosivegrenade", name="@mp_eFragGrenade", price=25, amount=1, ammo=true, weapon=false, category="@mp_catExplosives", loadout=1 },
{ id="empgrenade", name="@mp_eEMPGrenade", price=25, amount=1, ammo=true, weapon=false, category="@mp_catExplosives", loadout=1 },

{ id="pistol", name="@mp_ePistol", price=50, class="SOCOM", category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=3, uniqueloadoutcount=2},
{ id="claymore", name="@mp_eClaymore", price=50, class="Claymore", buyammo="claymoreexplosive", selectOnBuyAmmo="true", category="@mp_catExplosives", loadout=1 },
{ id="avmine", name="@mp_eMine", price=50, class="AVMine", buyammo="avexplosive", selectOnBuyAmmo="true", category="@mp_catExplosives", loadout=1 },
{ id="c4", name="@mp_eExplosive", price=150, class="C4", buyammo="c4explosive", selectOnBuyAmmo="true", category="@mp_catExplosives", loadout=1 },
{ id="ay69", name="@mp_eAY69", price=50, class="AY69", category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=4, uniqueloadoutcount=2},

{ id="shotgun", name="@mp_eShotgun", price=75, class="Shotgun", uniqueId=4, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="smg", name="@mp_eSMG", price=75, class="SMG", uniqueId=5, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="fy71", name="@mp_eFY71", price=150, class="FY71", uniqueId=6, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="macs", name="@mp_eSCAR", price=175, class="SCAR", uniqueId=7, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="rpg", name="@mp_eML", price=200, class="LAW", uniqueId=8, category="@mp_catExplosives", loadout=1},

{ id="dsg1", name="@mp_eSniper" , price=200, class="DSG1", uniqueId=9, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
};

TeamInstantAction.equipList=
{
{ id="binocs", name="@mp_eBinoculars", price=50, class="Binoculars", uniqueId=101, category="@mp_catEquipment", loadout=1 },
{ id="nsivion", name="@mp_eNightvision", price=10, class="NightVision", uniqueId=102, category="@mp_catEquipment", loadout=1 },

{ id="lockkit", name="@mp_eLockpick", price=50, class="LockpickKit", uniqueId=110, category="@mp_catEquipment", loadout=1, uniqueloadoutgroup=2, uniqueloadoutcount=1},
{ id="repairkit", name="@mp_eRepair", price=50, class="RepairKit", uniqueId=110, category="@mp_catEquipment", loadout=1, uniqueloadoutgroup=2, uniqueloadoutcount=1},
{ id="radarkit", name="@mp_eRadar", price=75, class="RadarKit", uniqueId=110, category="@mp_catEquipment", loadout=1, uniqueloadoutgroup=2, uniqueloadoutcount=1},
}

TeamInstantAction.protoList=
{
{ id="moac", name="@mp_eAlienWeapon", price=200, class="AlienMount", level=50, uniqueId=11, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="moar", name="@mp_eAlienMOAR", price=400, class="MOARAttach", level=50, uniqueId=12, category="@mp_catWeapons", loadout=1 },

{ id="minigun", name="@mp_eMinigun", price=250, class="Hurricane", level=50, uniqueId=13, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="tacgun", name="@mp_eTACLauncher", price=500, class="TACGun", level=100, restricted=1, energy=5, uniqueId=14, md=true, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},

{ id="usmoac4wd", name="@mp_eMOACVehicle", price=100, class="US_ltv", level=50, modification="MOAC", vehicle=true, buildtime=10, category="@mp_catVehicles", loadout=0 },
{ id="usmoar4wd", name="@mp_eMOARVehicle", price=200, class="US_ltv", level=50, modification="MOAR", vehicle=true, buildtime=10, category="@mp_catVehicles", loadout=0 },

{ id="ussingtank", name="@mp_eSingTank", price=500, class="US_tank", level=100, energy=10, modification="Singularity", vehicle=true, md=true, buildtime=45, category="@mp_catVehicles", loadout=0 },
{ id="ustactank", name="@mp_eTACTank", price=500, class="US_tank", level=100, energy=10, modification="TACCannon", vehicle=true, md=true, buildtime=45, category="@mp_catVehicles", loadout=0 },
{ id="nktactank", name="@mp_eLightTACTank", price=500, class="Asian_tank", level=100, energy=10, modification="TACCannon", vehicle=true, md=true, buildtime=45, category="@mp_catVehicles", loadout=0 },

{ id="gauss", name="@mp_eGauss", price=600, class="GaussRifle", level=50, uniqueId=10, category="@mp_catWeapons", loadout=1, uniqueloadoutgroup=1, uniqueloadoutcount=2},
{ id="fgl40", name="@mp_eFGL40", price=500, class="FGL40",     level=50, uniqueId=15, category="@mp_catWeapons", loadout=1},
}

TeamInstantAction.vehicleList=
{
{ id="light4wd", name="@mp_eLightVehicle", price=0, class="US_ltv", modification="Unarmed", buildtime=5, category="@mp_catVehicles", loadout=0 },
{ id="us4wd", name="@mp_eHeavyVehicle", price=0, class="US_ltv", modification="MP", buildtime=5, category="@mp_catVehicles", loadout=0 },
{ id="usgauss4wd", name="@mp_eGaussVehicle", price=200, class="US_ltv", modification="Gauss", buildtime=10, category="@mp_catVehicles", loadout=0 },

{ id="nktruck", name="@mp_eTruck", price=0, class="Asian_truck", modification="Hardtop_MP", buildtime=5, category="@mp_catVehicles", loadout=0 },

{ id="usboat", name="@mp_eSmallBoat", price=0, class="US_smallboat", modification="MP", buildtime=5, category="@mp_catVehicles", loadout=0 },
{ id="nkboat", name="@mp_ePatrolBoat", price=100, class="Asian_patrolboat", modification="MP", buildtime=10, category="@mp_catVehicles", loadout=0 },
{ id="nkgaussboat", name="@mp_eGaussPatrolBoat", price=200, class="Asian_patrolboat", modification="Gauss", buildtime=10, category="@mp_catVehicles", loadout=0 },
{ id="ushovercraft", name="@mp_eHovercraft", price=100, class="US_hovercraft", modification="MP", buildtime=10, category="@mp_catVehicles", loadout=0 },
{ id="nkaaa", name="@mp_eAAVehicle", price=200, class="Asian_aaa", modification="MP", buildtime=15, category="@mp_catVehicles", loadout=0 },

{ id="usasv", name="@mp_eASV", price=250, class="US_asv", buildtime=15, category="@mp_catVehicles", loadout=0 },
{ id="usapc", name="@mp_eICV", price=300, class="US_apc", buildtime=20, category="@mp_catVehicles", loadout=0 },
{ id="nkapc", name="@mp_eAPC", price=350, class="Asian_apc", buildtime=20, category="@mp_catVehicles", loadout=0 },

{ id="nktank", name="@mp_eLightTank", price=400, class="Asian_tank", buildtime=25, category="@mp_catVehicles", loadout=0 },
{ id="ustank", name="@mp_eBattleTank", price=450, class="US_tank", modification="MP", buildtime=30, category="@mp_catVehicles", loadout=0 },
{ id="usgausstank", name="@mp_eGaussTank", price=500, class="US_tank", modification="GaussCannon", buildtime=35,  category="@mp_catVehicles", loadout=0 },

{ id="nkhelicopter", name="@mp_eHelicopter", price=350, class="Asian_helicopter", modification="MP", buildtime=20, category="@mp_catVehicles", loadout=0 },
{ id="usvtol", name="@mp_eVTOL", price=450, class="US_vtol", modification="MP", buildtime=20, category="@mp_catVehicles", loadout=0 },
};

--us4wd,nk4wd,nktruck,ustank,ustactank,usgausstank,usapc,nktank,nktactank,nkgausstank,usspawntruck,usammotruck

TeamInstantAction.ammoList=
{
{ id="", name="@mp_eAutoBuy", price=0, category="@mp_catAmmo", loadout=1 },
{ id="bullet", name="@mp_eBullet", price=5, amount=40, category="@mp_catAmmo", loadout=1 },
{ id="fybullet", name="@mp_eFYBullet", price=5, amount=30, category="@mp_catAmmo", loadout=1 },
{ id="shotgunshell", name="@mp_eShotgunShell", price=5, amount=8, category="@mp_catAmmo", loadout=1 },
{ id="smgbullet", name="@mp_eSMGBullet", price=5, amount=50, category="@mp_catAmmo", loadout=1 },
{ id="aybullet", name="@mp_eAYBullet", price=5, amount=40, category="@mp_catAmmo", loadout=1 },
{ id="lightbullet", name="@mp_eLightBullet", price=5, amount=40, category="@mp_catAmmo", loadout=1 },

{ id="sniperbullet", name="@mp_eSniperBullet", price=10, amount=10, category="@mp_catAmmo", loadout=1 },
{ id="scargrenade", name="@mp_eRifleGrenade", price=50, amount=1, category="@mp_catAmmo", loadout=1 },
{ id="gaussbullet", name="@mp_eGaussSlug", price=100, amount=5, level=50, category="@mp_catAmmo", loadout=1 },

{ id="hurricanebullet", name="@mp_eMinigunBullet", price=100, amount=500, category="@mp_catAmmo", loadout=1 },

{ id="fgl40fraggrenade", name="@mp_eFGL40FragGrenade", price=200, amount=6, category="@mp_catAmmo", loadout=1 },
{ id="fgl40empgrenade", name="@mp_eFGL40EMPGrenade", price=100, amount=6, category="@mp_catAmmo", loadout=1 },

{ id="claymoreexplosive", price=50, amount=1, invisible=true, category="@mp_catAmmo", loadout=1 },
{ id="avexplosive", price=50, amount=1, invisible=true, category="@mp_catAmmo", loadout=1 },
{ id="c4explosive", price=150, amount=1, invisible=true, category="@mp_catAmmo", loadout=1 },

{ id="Tank_singularityprojectile", name="@mp_eSingularityShell", price=350, amount=1, category="@mp_catAmmo", loadout=0, vehicleammo=1},

{ id="towmissile", name="@mp_eAPCMissile", price=50, amount=2, category="@mp_catAmmo", loadout=0, vehicleammo=1 },
{ id="dumbaamissile", name="@mp_eAAAMissile", price=100, amount=4, category="@mp_catAmmo", loadout=0, vehicleammo=1 },
{ id="tank125", name="@mp_eTankShells", price=100, amount=10, category="@mp_catAmmo", loadout=0, vehicleammo=1 },
{ id="helicoptermissile", name="@mp_eHelicopterMissile", price=50, amount=7, category="@mp_catAmmo", loadout=0, vehicleammo=1 },

{ id="tank30", name="@mp_eAPCCannon", price=100, amount=100, category="@mp_catAmmo", loadout=0, vehicleammo=1 },
{ id="tankaa", name="@mp_eAAACannon", price=100, amount=250, category="@mp_catAmmo", loadout=0, vehicleammo=1 },
{ id="a2ahomingmissile", name="@mp_eVTOLMissile", price=150, amount=6, category="@mp_catAmmo", loadout=0, vehicleammo=1 },
{ id="gausstankbullet", name="@mp_eGaussTankSlug", price=200, amount=10, category="@mp_catAmmo", loadout=0, vehicleammo=1 },

{ id="tacprojectile", name="@mp_eTACTankShell", price=350, amount=1, ammo=true, level=100, category="@mp_catAmmo", vehicleammo=1 },

{ id="psilent", name="@mp_ePSilencer", price=10, class="SOCOMSilencer", uniqueId=121, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="plam", name="@mp_ePLAM", price=25, class="LAM", uniqueId=122, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="silent", name="@mp_eRSilencer", price=10, class="Silencer", uniqueId=123, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="lam", name="@mp_eRLAM", price=25, class="LAMRifle", uniqueId=124, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="reflex", name="@mp_eReflex", price=25, class="Reflex", uniqueId=125, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="ascope", name="@mp_eAScope", price=50, class="AssaultScope", uniqueId=126, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="scope", name="@mp_eSScope", price=100, class="SniperScope", uniqueId=127, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
{ id="gl", name="@mp_eGL", price=200, class="GrenadeLauncher", uniqueId=128, ammo=false, equip=true, category="@mp_catAddons", loadout=1 },
};

TeamInstantAction.buyList={};

for i,v in ipairs(TeamInstantAction.weaponList) do TeamInstantAction.buyList[v.id]=v; if (type(v.weapon)=="nil") then v.weapon=true; end; end;
for i,v in ipairs(TeamInstantAction.equipList) do TeamInstantAction.buyList[v.id]=v; if (type(v.equip)=="nil") then v.equip=true; end; end;
for i,v in ipairs(TeamInstantAction.protoList) do TeamInstantAction.buyList[v.id]=v; if (type(v.proto)=="nil") then v.proto=true; end; end;
for i,v in ipairs(TeamInstantAction.vehicleList) do TeamInstantAction.buyList[v.id]=v; if (type(v.vehicle)=="nil") then v.vehicle=true; end; end;
for i,v in ipairs(TeamInstantAction.ammoList) do TeamInstantAction.buyList[v.id]=v; if (type(v.ammo)=="nil") then v.ammo=true; end; end;

-- pp values
TeamInstantAction.ppList=
{
SPAWN = 100,
START = 100,
KILL = 100,
HEADSHOT = 0,
MELEE = 0,
SUICIDE = 0,
TEAMKILL = -200,

REPAIR = 1/10, -- points/per damage repaired

LOCKPICK = 50,
DISARM = 50,
TAG_ENEMY = 5,

VEHICLE_REFUND_MULT = 0.90,
VEHICLE_KILL_MIN = 10,
VEHICLE_KILL_MULT = 0.25,
};

TeamInstantAction.BALANCE_ACTION_TIME = 30;
TeamInstantAction.BALANCE_ACTION_TIMERID = 7000;


После этого, найдите следующее:

Lua (teaminstantaction.lua)

Код:
Net.Expose {
Class = TeamInstantAction,
ClientMethods = {
ClSetupPlayer = { RELIABLE_UNORDERED, NO_ATTACH, DEPENTITYID, },
ClSetSpawnGroup = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, },
ClSetPlayerSpawnGroup = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, ENTITYID },
ClSpawnGroupInvalid = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, },
ClVictory = { RELIABLE_ORDERED, POST_ATTACH, INT8, INT8 },

ClStartWorking = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID; STRINGTABLE },
ClStepWorking = { RELIABLE_ORDERED, POST_ATTACH, INT8 },
ClStopWorking = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID, BOOL },
ClWorkComplete = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID, STRINGTABLE },

ClClientConnect = { RELIABLE_UNORDERED, POST_ATTACH, STRING, BOOL },
ClClientDisconnect = { RELIABLE_UNORDERED, POST_ATTACH, STRING, },
ClClientEnteredGame = { RELIABLE_UNORDERED, POST_ATTACH, STRING, },
ClTimerAlert = { RELIABLE_UNORDERED, POST_ATTACH, INT8 },
},
ServerMethods = {
RequestRevive = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, },
RequestSpawnGroup = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, ENTITYID },
RequestSpectatorTarget= { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, INT8 },
},
ServerProperties = {
},
};


И замените это этим:

Lua (teaminstantaction.lua)

Код:
Net.Expose {
Class = TeamInstantAction,
ClientMethods = {
ClSetupPlayer = { RELIABLE_UNORDERED, NO_ATTACH, DEPENTITYID, },
ClSetSpawnGroup = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, },
ClSetPlayerSpawnGroup = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, ENTITYID },
ClSpawnGroupInvalid = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, },
ClVictory = { RELIABLE_ORDERED, POST_ATTACH, INT8, INT8 },

ClStartWorking = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID; STRINGTABLE },
ClStepWorking = { RELIABLE_ORDERED, POST_ATTACH, INT8 },
ClStopWorking = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID, BOOL },
ClWorkComplete = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID, STRINGTABLE },

ClEnterBuyZone = { RELIABLE_ORDERED, POST_ATTACH, ENTITYID, BOOL };
ClResetBuyZones = {RELIABLE_ORDERED, POST_ATTACH, };

ClBuyError = { RELIABLE_UNORDERED, POST_ATTACH, STRING, },
ClBuyOk = { RELIABLE_UNORDERED, POST_ATTACH, },

ClPP = { RELIABLE_UNORDERED, POST_ATTACH, FLOAT },

ClClientConnect = { RELIABLE_UNORDERED, POST_ATTACH, STRING, BOOL },
ClClientDisconnect = { RELIABLE_UNORDERED, POST_ATTACH, STRING, },
ClClientEnteredGame = { RELIABLE_UNORDERED, POST_ATTACH, STRING, },
ClTimerAlert = { RELIABLE_UNORDERED, POST_ATTACH, INT8 },
},
ServerMethods = {
    SvBuy = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, STRING },
SvBuyAmmo = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, STRING },
RequestRevive = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, },

SvRequestPP = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, INT32 },
RequestSpectatorTarget= { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, INT8 },
RequestSpawnGroup = { RELIABLE_UNORDERED, POST_ATTACH, ENTITYID, ENTITYID },
},
ServerProperties = {
},
};


Затем перейдите в конец документа и вставьте следующее:

Lua (teaminstantaction.lua)

Код:
----------------------------------------------------------------------------------------------------
function TeamInstantAction:ResetPlayers()
InstantAction.ResetPlayers(self);

local players=self.game:GetPlayers();
if (players) then
for i,player in pairs(players) do
if (player.actor:GetSpectatorMode()==0) then
self:ResetPP(player.id);
self:AwardPPCount(player.id, self.ppList.START);
end
end
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction:ReviveAllPlayers(keepEquip)
    InstantAction.ResetPlayers(self, keepEquip);

if(player) then
self:ResetPP(player.id);
self:AwardPPCount(player.id, self.ppList.START);
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client.OnSetBuyFlags(g_gameRules, entityId, flags)
if (HUD) then
HUD.UpdateBuyList();
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction:Reset(forcePregame)
    InstantAction.Reset(self, forcePregame);
if (g_localActor and HUD) then
HUD.ResetBuyZones();
end
self.inBuyZone={};
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:OnClientConnect(channelId, reset, name)
local player = InstantAction.Server.OnClientConnect(self, channelId, reset, name);

if (player) then
if (not CryAction.IsChannelOnHold(channelId)) then
self:ResetPP(player.id);
end
end

return player;
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:OnClientEnteredGame(channelId, player, reset)
InstantAction.Server.OnClientEnteredGame(self, channelId, player, reset);

if (player) then
self:SetPlayerPP(player.id, self.ppList.START);
self.onClient:ClResetBuyZones(player.actor:GetChannel());
if (self.inBuyZone[player.id]) then
for zoneId,yes in pairs(self.inBuyZone[player.id]) do
if (yes) then
self.onClient:ClEnterBuyZone(player.actor:GetChannel(), zoneId, true);
end
end
end
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:OnClientDisconnect(channelId)
InstantAction.Server.OnClientDisconnect(self, channelId);

local player=self.game:GetPlayerByChannelId(channelId);

if (player) then
self.inBuyZone[player.id]=nil;
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction:ProcessScores(hit, tk)
if (self:GetState()=="PostGame") then return; end

local target=hit.target;
local shooter=hit.shooter;
local headshot=self:IsHeadShot(hit);

if(tk == nil) then
tk = self:IsTeamKill(target, shooter);
end

local h=0;
if (headshot) then
h=1;
end

if (target.actor and target.actor:IsPlayer()) then
local targetTeamId=self.game:GetTeam(target.id);
if (target == shooter) then --selfkill -3
self:Award(target, 1, 0, 0, 0, 1);
return; -- no need to do anything else for suicide
elseif(not tk)then  -- if teamkill - nothing for target
self:Award(target, 1, 0, 0, 0, 0);
end
end

if (shooter and shooter.actor and shooter.actor:IsPlayer()) then
    self:AwardKillPP(hit);
local teamId=self.game:GetTeam(shooter.id);
if (target ~= shooter) then
if (not tk) then
self:Award(shooter, 0, 1, h, 0, 0);

-- update team score
self:SetTeamScore(teamId, self:GetTeamScore(teamId) + self:CalculateScore(0,1,0,0));
else
self:Award(shooter, 0, 0, 0, 1, 0);
end
end
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client:ClEnterBuyZone(zoneId, enable)
if (g_localActor and HUD) then
HUD.EnteredBuyZone(zoneId, enable);
HUD.UpdateBuyList();
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client:OnSetTeam(entityId, teamId)
    InstantAction.Client.OnSetTeam(self, entityId, teamId);
if (entityId == g_localActorId) then
HUD.UpdateBuyList();
else
--[[local entity=System.GetEntity(entityId);
if (entity.Properties and entity.Properties.buyAreaId) then -- TODO: more robust way to check if the are is a buy area
HUD.UpdateBuyList();
end]]
local entity=System.GetEntity(entityId);
if (entity.GetBuyFlags and (entity:GetBuyFlags()~=0)) then -- TODO: more robust way to check if the entity is a buy area
HUD.UpdateBuyList();
end
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:OnChangeTeam(playerId, teamId)
if (teamId ~= self.game:GetTeam(playerId)) then
local player=System.GetEntity(playerId);
if (player) then

if (player.last_team_change and teamId~=0) then
if (self:GetState()=="InGame") then
if (_time-player.last_team_change<self.TEAM_CHANGE_MIN_TIME) then
if ((not player.last_team_change_warning) or (_time-player.last_team_change_warning>=4)) then
player.last_team_change_warning=_time;
self.game:SendTextMessage(TextMessageError, "@mp_TeamChangeLimit", TextMessageToClient, playerId, self.TEAM_CHANGE_MIN_TIME-math.floor(_time-player.last_team_change+0.5));
end
return;
end
end
end

if (self:IsTeamLocked(teamId, playerId)) then
if ((not player.last_team_locked_warning) or (_time-player.last_team_locked_warning>=4)) then
player.last_team_locked_warning=_time;
Log("team change request by %s denied: team %d has too many players", EntityName(playerId), teamId);
self.game:SendTextMessage(TextMessageError, "@mp_TeamLockedTooMany", TextMessageToClient, playerId);
end
return;
end

if (player.actor:GetHealth()>0 and player.actor:GetSpectatorMode()==0) then
self:KillPlayer(player);
end

self.game:SetTeam(teamId, playerId);
player.last_team_change=_time;

            self:ResetPP(player.id);
self.game:ChangeSpectatorMode(playerId, 0, NULL_ENTITY);
self:RevivePlayer(player.actor:GetChannel(), player);
end
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:OnHit(hit)
local shooter = hit.shooter;
local target = hit.target;
if (shooter and target and shooter.actor and shooter.actor:IsPlayer()) then
local team1=self.game:GetTeam(shooter.id);
local team2=self.game:GetTeam(target.id);
if(team1 == team2 and team1~=0 and shooter.id~=target.id and (hit.type~="repair")) then
hit.damage = hit.damage*self.game:GetFriendlyFireRatio();
else
    self:AwardPPCount(shooterId, self.ppList.KILL_ASSIST);
end
end
return InstantAction.Server.OnHit(self, hit);
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client:ClBuyError(itemName)
HUD.OnItemBought(false, itemName);
end

----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client:ClBuyOk(itemName)
HUD.OnItemBought(true, itemName);
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client:ClPP(amount)
if (amount>0) then
HUD.BattleLogEvent(eBLE_Currency, "@mp_BLAwardedPP", amount);
elseif (amount<0) then
HUD.BattleLogEvent(eBLE_Currency, "@mp_BLLostPP", -amount);
end
end

----------------------------------------------------------------------------------------------------
function TeamInstantAction.Client:ClRestartGame()
self.game:EnteredGame();
end

----------------------------------------------------------------------------------------------------
function TeamInstantAction:ResetPP(playerId)
self:SetPlayerPP(playerId, 0);
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:SetPlayerPP(playerId, pp)
self.game:SetSynchedEntityValue(playerId, self.PP_AMOUNT_KEY, pp);
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:GetPlayerPP(playerId)
return self.game:GetSynchedEntityValue(playerId, self.PP_AMOUNT_KEY) or 0;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:AwardPPCount(playerId, c, why)
local total=self:GetPlayerPP(playerId)+c;
self:SetPlayerPP(playerId, math.max(0, total));

local player=System.GetEntity(playerId);
if (player) then
self.onClient:ClPP(player.actor:GetChannel(), c);
end

CryAction.SendGameplayEvent(playerId, eGE_Currency, nil, total);
CryAction.SendGameplayEvent(playerId, eGE_Currency, why, c);
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:AwardKillPP(hit)
local pp=self:CalcKillPP(hit);
local playerId=hit.shooter.id;

self:AwardPPCount(playerId, pp);
end
----------------------------------------------------------------------------------------------------

function TeamInstantAction.Client:ClResetBuyZones()
if (g_localActor and HUD) then
HUD.ResetBuyZones();
HUD.UpdateBuyList();
end
end



----------------------------------------------------------------------------------------------------
function TeamInstantAction:CalcKillPP(hit)
local target=hit.target;
local shooter=hit.shooter;

if(target ~= shooter) then
local team1=self.game:GetTeam(shooter.id);
local team2=self.game:GetTeam(target.id);

if(team1 ~= team2) then
return self.ppList.KILL;
else
return self.ppList.TEAMKILL;
end
else
return self.ppList.SUICIDE;
end
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:GetPrice(itemName)
if (not itemName) then
return 0;
end

local entry=self.buyList[itemName];
local price=0;
if (entry) then
price=entry.price;
end

if (price>0) then
g_pp_scale_price=System.GetCVar("g_pp_scale_price");
if (g_pp_scale_price) then
price=math.floor(price*math.max(0, g_pp_scale_price));
end
end

return price;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:GetItemName(itemName)
if (not itemName) then
return "";
end

local entry=self.buyList[itemName];
if (entry) then
return entry.name;
end

return itemName;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:GetItemFlag(itemName)
local item=self.buyList[itemName];
local flag=0;
if (item.ammo) then flag=bor(flag, self.BUY_AMMO); end;
if (item.equip) then flag=bor(flag, self.BUY_EQUIPMENT); end;
if (item.proto) then flag=bor(flag, self.BUY_PROTOTYPE); end;
if (item.vehicle) then flag=bor(flag, self.BUY_VEHICLE); end;
if (item.weapon) then flag=bor(flag, self.BUY_WEAPON); end;

return flag;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:GetItemDef(itemName)
local entry=self.buyList[itemName];
if (entry) then
return entry;
end
return nil;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:ItemExists(playerId, itemName)
return self.buyList[itemName]~=nil;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:EnoughPP(playerId, itemName, price)
if (itemName and not price) then
price=self:GetPrice(itemName);
end

if (not price) then
price=0;
end

if (price and (price>self:GetPlayerPP(playerId))) then
return false;
end
return true;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:Buy(itemName)
self.server:SvBuy(g_localActorId, itemName);
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:SvBuy(playerId, itemName)
local player=System.GetEntity(playerId);
if (not player) then
return;
end

local channelId=player.actor:GetChannel();
local ok=false;

if (self:ItemExists(playerId, itemName)) then
if (self:IsInBuyZone(playerId)) then
if (self:EnoughPP(playerId, itemName)) then
ok=self:BuyItem(playerId, itemName);
end
end
end

if (ok) then
self.onClient:ClBuyOk(channelId);
else
self.onClient:ClBuyError(channelId, itemName);
end
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:BuyAmmo(ammo)
if (not ammo or ammo=="") then
local vehicleId=g_localActor.actor:GetLinkedVehicleId();
local weapon;
if (vehicleId) then
local vehicle=System.GetEntity(vehicleId);
if (vehicle) then
local seat=vehicle:GetSeat(g_localActorId);
if (seat and seat.seat:GetWeaponCount()>0) then
local weaponId = seat.seat:GetWeaponId(1);
if (weaponId) then
weapon=System.GetEntity(weaponId);
end
end
end
else
weapon=g_localActor.inventory:GetCurrentItem();
end

if (weapon and weapon.weapon) then
ammo=weapon.weapon:GetAmmoType();
end
end

if (ammo and ammo~="") then
self.server:SvBuyAmmo(g_localActorId, ammo);
end
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:SvBuyAmmo(playerId, name)
--Log("PowerStruggle.Server:SvBuyAmmo(%s, %s)", EntityName(playerId), tostring(name));

local player=System.GetEntity(playerId);
if (not player) then
return;
end

local frozen=self.game:IsFrozen(playerId);
local channelId = player.actor:GetChannel();
local ok=false;

if (not frozen) then
ok=self:DoBuyAmmo(playerId, name);
end

if (ok) then
self.onClient:ClBuyOk(channelId, name);
else
self.onClient:ClBuyError(channelId, name);
end
end
----------------------------------------------------------------------------------------------------
function TeamInstantAction:DoBuyAmmo(playerId, name)
--Log("PowerStruggle.Server:SvBuyAmmo(%s, %s)", EntityName(playerId), tostring(name));

local player=System.GetEntity(playerId);
if (not player) then
return false;
end

local def=self:GetItemDef(name);
if (not def) then
return false;
end

--check item is allowed before buying
local allowed = self.game:IsItemAllowed(name);
if(not allowed) then
return;
end

--also check classnames
if(def and def.class) then
allowed = self.game:IsItemAllowed(def.class);
if(not allowed) then
return;
end
end

local revive;
local alive=true;
if (player.actor:GetHealth()<=0) then
revive=self.reviveQueue[playerId];
alive=false;
end

local result=false;

local flags=0;
local level=0;
local zones=self.inBuyZone[playerId];
local teamId=self.game:GetTeam(playerId);

local vehicleId = player and player.actor:GetLinkedVehicleId();
if (vehicleId) then
-- don't do this for spawn trucks, just use the buyzone
local vehicle=System.GetEntity(vehicleId);
if(not vehicle.buyFlags or vehicle.buyFlags == 0) then
zones=self.inServiceZone[playerId];
end
end

for zoneId,b in pairs(zones) do
if (teamId == self.game:GetTeam(zoneId)) then
local zone=System.GetEntity(zoneId);
if (zone and zone.GetPowerLevel) then
local zonelevel=zone:GetPowerLevel();
if (zonelevel>level) then
level=zonelevel;
end
end
end
end

if (def.level and def.level>0 and def.level>level) then
self.game:SendTextMessage(TextMessageError, "@mp_AlienEnergyRequired", TextMessageToClient, playerId, def.name);
return false;
end

local ammo=self.buyList[name];
if (ammo and ammo.ammo) then
local price=self:GetPrice(name);

local vehicle = vehicleId and System.GetEntity(vehicleId);
-- ignore vehicles with buyzones here (we want to buy ammo for the player not the vehicle in this case)
if (vehicleId and vehicle and not vehicle.buyFlags) then
if (alive) then
--is in vehiclebuyzone
if (self:IsInServiceZone(playerId) and (price==0 or self:EnoughPP(playerId, nil, price)) and self:VehicleCanUseAmmo(vehicle, name)) then
local c=vehicle.inventory:GetAmmoCount(name) or 0;
local m=vehicle.inventory:GetAmmoCapacity(name) or 0;

if (c<m or m==0) then
local need=ammo.amount;
if (m>0) then
need=math.min(m-c, ammo.amount);
end

-- this function takes care of synchronizing it to clients
vehicle.vehicle:SetAmmoCount(name, c+need);

if (price>0) then
if (need<ammo.amount) then
price=math.ceil((need*price)/ammo.amount);
end
self:AwardPPCount(playerId, -price);
end

return true;
end
end
end
elseif ((self:IsInBuyZone(playerId) or (not alive)) and (price==0 or self:EnoughPP(playerId, nil, price))) then
local c=player.inventory:GetAmmoCount(name) or 0;
local m=player.inventory:GetAmmoCapacity(name) or 0;

if (not alive) then
c=revive.ammo[name] or 0;
end

if (c<m or m==0) then
local need=ammo.amount;
if (m>0) then
need=math.min(m-c, ammo.amount);
end

if (alive) then
-- this function takes care of synchronizing it to clients
player.actor:SetInventoryAmmo(name, c+need, CLIENT_SIDE + SERVER_SIDE);
else
revive.ammo[name]=c+need;
player.actor:SetInventoryAmmo(name, c+need, CLIENT_SIDE + SERVER_SIDE);
end

if (price>0) then
if (need<ammo.amount) then
price=math.ceil((need*price)/ammo.amount);
end

self:AwardPPCount(playerId, -price);
end

return true;
end
end
end

return false;
end

----------------------------------------------------------------------------------------------------
function TeamInstantAction:BuyItem(playerId, itemName)
local price=self:GetPrice(itemName);
local def=self:GetItemDef(itemName);

if (not def) then
return false;
end

if (def.buyammo and self:HasItem(playerId, def.class)) then
return self:DoBuyAmmo(playerId, def.buyammo);
end

if (def.uniqueId and self:HasUniqueItem(playerId, def.uniqueId)) then
self.game:SendTextMessage(TextMessageError, "@mp_CannotCarryMoreKit", TextMessageToClient, playerId);
return false;
end

local player=System.GetEntity(playerId);
if (not player) then
return;
end

if (player.actor:GetHealth()<=0) then
return;
end

-- check inventory
local itemId;
if (player.actor:CheckInventoryRestrictions(def.class)) then
self:AwardPPCount(playerId, -price);
itemId=ItemSystem.GiveItem(def.class, playerId);
else
self.game:SendTextMessage(TextMessageError, "@mp_CannotCarryMore", TextMessageToClient, playerId);
return false;
end

return true;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:HasItem(playerId, itemName)
local player=System.GetEntity(playerId);
local inventory=player and player.inventory;
if (inventory) then
if (inventory:GetItemByClass(itemName)) then
return true;
end
end

return false;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:HasUniqueItem(playerId, uniqueId)
local player=System.GetEntity(playerId);
local inventory=player and player.inventory;
if (inventory) then
for item,def in pairs(self.buyList) do
if (def.uniqueId and def.uniqueId==uniqueId) then
if (inventory:GetItemByClass(def.class)) then
return true;
end
end
end
end

return false;
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:OnEnterBuyZone(zone, player)
if (not self.inBuyZone[player.id]) then
self.inBuyZone[player.id]={};
end

local was=self.inBuyZone[player.id][zone.id];
if (not was) then
self.inBuyZone[player.id][zone.id]=true;
self.onClient:ClEnterBuyZone(player.actor:GetChannel(), zone.id, true);
end
end

----------------------------------------------------------------------------------------------------
function TeamInstantAction:OnLeaveBuyZone(zone, player)
if (self.inBuyZone[player.id] and self.inBuyZone[player.id][zone.id]) then
self.inBuyZone[player.id][zone.id]=nil;
self.onClient:ClEnterBuyZone(player.actor:GetChannel(), zone.id, false);
end
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction:IsInBuyZone(playerId, zoneId)
local zones=self.inBuyZone[playerId];
if (not zones) then
return false;
end

local playerTeamId = self.game:GetTeam(playerId);

if (zoneId) then
local zoneTeamId = self.game:GetTeam(zoneId);
return zoneTeamId and zones[zoneId] and zoneTeamId==playerTeamId;
else
for zoneId,inside in pairs(zones) do
local zoneTeamId = self.game:GetTeam(zoneId);
if (zoneTeamId and inside and zoneTeamId==playerTeamId) then
return true;
end
end

return false;
end
end


----------------------------------------------------------------------------------------------------
function TeamInstantAction.Server:SvRequestPP(playerId, amount)
if (g_gameRules.game:CanCheat()) then
self:AwardPPCount(playerId, amount);
end
end
----------------------------------------------------------------------------------------------------
function GivePP(amt)
if (g_gameRules.isServer) then
if (g_gameRules.game:CanCheat()) then
g_gameRules:SetPlayerPP(g_localActorId, amt);
end
else
g_gameRules.server:SvRequestPP(g_localActorId, amt);
end
end


И вот оно! Но, перепроверьте, что никакие функции не заявлены дважды. Просто сделайте это, скопировав название функции и поискав другую линию той же функции, используя CTRL+F.

Завершённый и изменённый TeamInstantAction.lua

После всего этого, у Вас должно получиться (Если Вы не были ленивыми и просто пропустил на этот шаг, чтобы скачать готовый вариант) что-то вроде мода, включенного в следующий .zip: http://wiki.crymod.com/images/9/9f/MyMod.zip


Источник: http://wiki.crymod.com/index.php/Adding_Buying_to_the_Team_Instant_Action_gamemode

Перевод XRUSHT.NET


Сообщить об ошибке / дополнить материал

  Рейтинг:
Пользовательская оценка (от 1 до 10): Пока не оценено   Проголосовавших: 0

  Комментарии:

  #1   2011-01-28 22:29

  pigris   Участник   3 комментариев   Онлайн статус

 

а можно ли добавить режим покупок для однопользовательской игры?


  #2   2011-01-29 07:05

  XRUSHT.NET   ServerOp   2010 комментариев   Онлайн статус

 

Мода или инструкции по переносу системы покупок из PowerStruggle в синглплеер нет, есть системы созданные через FlowGraph, посмотрите в разделе Flowgraphs на CryMod .

* Ссылки CryMod.com восстановлены.

Crysis, Warhead, Wars, Crysis 2, Crysis 3, Remastered, Crysis 4