如何在批处理游戏中制作库存



我正在尝试创造一款批量游戏,它具有类似于《天际》,《湮没》和其他知名游戏的库存。这款游戏并没有固定数量的库存插槽,而是在现有插槽被占用时创造一个新的插槽。我已经知道如何让游戏检查他们了。

if '%item1%'=='blank' (set item1=%item%) else (if '%item1%'=='%item%' set /A item1qua=%item1qua%+1)
if '%item2%'=='blank' (set item2=%item%) else (if '%item2%'=='%item%' set /A item2qua=%item2qua%+1)

我也不知道如何创建一个批处理脚本,每次更改数量,直到库存槽被发现为空白。然后游戏必须保存所有库存槽。我当前的方法是:

( Echo @echo off
Echo set item1=%item1%
Echo set item1qua=%item1qua%
Echo set item2=%item2%
Echo set item2qua=%item2qua%
Echo set item3=%item3%
Echo set item3qua=%item3qua%
Echo set item4=%item4%
Echo set item4qua=%item4qua%)>>%playername%.bat

术语"qua"只是指数量。我试过这个代码:

set num=1
:inv
if '%item%num%%'=='blank' (set %item%num%%=%item% && goto next) else (set /a num=%num%+1)
goto inv
简而言之,这将随着玩家获得更多道具而扩展库存。就像在《上古卷轴》和其他游戏中一样,道具也具有一定的重量,我希望能够添加给玩家这种神圣的烦恼,但是我也希望代码能够移除额外的"空白"道具插槽,而不是在编号系统中留下空白,例如:Item1, item2, item4, item7, item8

我以前的方法是复制一个现有的。bat文件与项目数据的母文件夹,并把它放在一个文件夹的其他地方,玩家可以查看他们的项目使用dir命令。你可以想象,这不是很有成效。

我的第二种方法是在游戏的Alpha阶段,当它基本上是一个生活模拟器时,它被遗弃了,但留在游戏文件夹中,以防我再次捡起它:

>>Users%fname%.bat Echo set weed=%weed%
>>Users%fname%.bat Echo set money=%money%
>>Users%fname%.bat Echo set water=%water%
>>Users%fname%.bat Echo set lighters=%lighters%
>>Users%fname%.bat Echo set cigarettes=%cigarettes%
>>Users%fname%.bat Echo set lightbulbs=%lightbulbs%

编辑感谢Chris Schaller提供的链接,我找到了一个可以工作的代码,并编辑到我需要的内容。


@echo off
set len=11
set obj[0]=Gold
set obj[1]=Silver
set obj[2]=Sword
set obj[3]=Knife
set obj[4]=Greenfelt
set obj[5]=Amulet
set obj[6]=Chickenleg
set obj[7]=Necklace
set obj[8]=StolenItem
set obj[9]=GoldIngot
set obj[10]=Statuette
set obj[11]=Seeds
set i=0
:loop
if /i %i% equ %len% goto :eof
for /f "usebackq delims== tokens=2" %%j in (`set obj[%i%]`) do (
echo %%j
)
pause
set /a i=%i%+1
goto loop

代码在某些方面工作得很好,但是我如何允许obj[0]每次都增加?

A.S.C

最简单的方法是将所有必须保存的变量以特殊字符(如#@~_或…)或字符串(如编辑中的obj[)开始。保存它们就像这样简单:

>Users%fname%.sav set #

(或使用Edit:>Users%fname%.sav set obj[中的示例)

,用

再读一遍
for /f "delims=" %%a in ("users%fname%.sav") do set "%%a" 

你的目标是在新物品添加到库存时增加计数。

对于这种任务类型,我建议使用一个功能,因为库存管理是批处理rpg游戏中高度重复的任务。

批处理脚本中的函数是带参数调用的标签,可执行重复操作。

在RPG游戏设计的背景下,你会希望允许在不同的情况下使用,例如在库存中添加战利品、购买或奖励。

对于一个更复杂的游戏,支持各种类似类型的物品,使用物品类型数组可以使事情变得更容易-想想菜单选项卡,你选择武器,并在你的库存中获得一个武器列表。

下面是一个示例,说明如何编写一个用于向库存添加物品的函数,该函数在添加物品之前测试两个条件是有效的- 1)成本不超过资金,2)物品的重量不使总携带重量超过最大值。

itemweight和itemcost值默认为0,如果调用时没有提供参数,则允许将没有重量的物品或找到/给定的物品添加到库存中。

@Echo off & Cls
For /F "Tokens=1 Delims==" %%G in (' Set "#"  2^> nul ')Do Set "%%G="
Set /A "#Money=100,Maxweight=25000,#weight=0"
::: redirect output of inventory to nul to suppress output of item added to inventory notifcation as desired
For %%G in ("Healing Potion" "Old Key" "Map")DO Call :Inventory %%G Miscellaneous 10 >nul
For %%G in ("Vambraces" "Boots of Luck" "Helm")DO Call :Inventory %%G Armor 1000 >nul
Call :Inventory "Dagger" OneHandedWeapon 250 >nul
Call :Inventory "Short sword" OneHandedWeapon 4000 >nul
Call :Inventory "Katana" OneHandedWeapon 4750 > nul
Set #
Endlocal
Goto :Eof
:Inventory         <itemname> <itemtype> <itemweight> <itemcost>
::: Remove item:   <itemname> /R
::: undefines all array elements containing itemname in varname or value. Use unique and descriptive Item names.
If /I "%~2" == "/R" (
For /F "Tokens=1,2* Delims==" %%G in (' Set "#" 2^> nul ^|%__Appdir__%findstr.exe /LIC:"%~1" ')Do Set "%%G="
Goto :getweight
)
Set "Itemname=%~1"
Set "Itemtype=%~2"
If "%~4"=="" (Set "cost=0")Else (
Set "cost=%~4"
For /F %%G in ('Set /A #money-%~4')Do if %%G LSS 0 (
Echo(You cannot afford %itemname%
Goto :Eof
)
)
If "%~3" == "" (Set "itemweight=0")Else (
Set "itemweight=%~3"
For /F %%G in ('Set /A maxweight-%~3-#weight')Do if %%G LSS 0 (
Echo/You are carrying too much.
Goto :Eof
)
)
Set /A "#money-=cost"
Set "#%itemname%[grams]=%itemweight%"
Set /A #Inv{i}+=1+0
Set "#Inventory[%#Inv{i}%]=%itemname%"
If Defined Itemtype (
Set /A #%ItemType%{i}+=1+0
Call Set "#%ItemType%[%%#%ItemType%{i}%%]=%itemname%"
)
Echo(%~1 added to Inventory.
:getweight
::: Updates the current weight of all inventory items by summing all itemname[grams] definitions
Set "#weight=0"
For /F "Tokens=2 Delims==" %%G in (' Set "#" ^| Findstr /LIC:"[grams]"')Do Set /A #weight+=%%G
Goto :Eof

注意:上面的示例是在评估是否可以/应该添加物品后将其添加到库存中的方法。函数的itemname/R 'remove item'组件是一个从库存数组中取消定义元素的最小示例,但是这种方法不会移动数组变量索引来填补未定义变量留下的空白-如果您要使用for/L循环遍历数组,请注意。

下面是一个结合字符登录和保存系统的例子,它利用了# perfixed变量的使用。

::: AUTHOR: T3RRY Created: 06/03/2021 Version: 1.3 Filename: RPGInventorySystem
:# Purpose:  Provide an easy to use, ready to go Template for creating Batch RPG Games
:# Features:
:# - :Login Function 
:#   - remembers last played character; offers single key login for that character.
:#   - flags if character is New or Returning
:# - :Getin Input function to restrict and validate player Input
:# - Example Template of Creating Classes with Starting Inventory { :Knight function }
:# - Multipurpose :Inventory Funtion That Saves Inventory changes Immediately
:# - :ManageInventory Function to allow players to well... manage their inventory.
:# - Menu Macro for easy menus.
@Echo off & Goto Prep
=======================================================================:# FUNCTIONS
:# Inventory Arguments and Usage Info:
:# Arg order Mandatory
======================:# ADDING ITEMS TO INVENTORY: Initial Inventory; Loot; Gifts / Rewards; Purchases
:Inventory              <ItemName> <ItemType> <ItemSubType> <ItemWeight> <ItemCost> {Optional:"ModifierType=Value"} {Optional:/F}
::::::::::::::::::::::::::::::::::::::::::::::::::
:# Optional Arg "/F": Must be last Arg; Flags the Item as free; Does not Subtract ItemCost from Players #Money
:#  Allows Items to be Looted / Gifted / Rewarded that have value stored for use when Selling Items. See Below
======================:# REMOVING / SELLING ITEMS:
:# Remove item:         <ItemName> /R <ItemSubType>
:#  Optional third Arg is used when selling an Item. May be a Sum, Integer Value or use Array: !#ItemName.Value!
:#  /R - Undefines all array elements containing ItemName in varname or value. Use unique and descriptive Item names.
:::::::::::::::::::::::::::::::::::::::::::::::::::
:# Sell item:           <ItemName> /R <ItemSubType> <ItemSaleValue>
======================:# EQUIPPING ITEMS:
:# Equip an item   :    <Itemname> /E <ItemSubtype>
======================:# CHECKPOINTS:
:# Save a Checkpoint:   <LabelName> /L
:::::::::::::::::::::::::::::::::::::::::::::::::::
:# IMPORTANT - RESERVED VARIABLES - The above Parameter names; #%1.Grams #%1.Value #Display.Weight #%3{i} #Weight List? Count
:#  - Arrays:         #%ItemName%.Grams #%ItemName%.Value #Equipped.%ItemSubType%
:#  - Lists:          #Inventory.Types #Inventory.%ItemType% #Inventory.%ItemType%.%ItemSubType%
:# RECOMMENDATION: Use a selection of Category names for ItemTypes that will be Equipped.
:# - Only one of Each ItemSubType may be Equipped at A time.
:#  - It is appropriate that only 1 pair of Boots may be worn, but multiple pieces of different Armor may be equipped:
:#  - Instead of just Defining all armors to the ItemType Armor:
:#  - Define Type Armor and Subtypes: Helm Mantle Gloves Vambraces Pauldrons Boots Pants
:# DEPENDENCIES - Defined in ':Login': #Name Game.Save
If /I "%~2" == "/L" (
Set "#Location=%~1"
Goto :Save
)
:# Removes or Sell ItemName From Inventory;  Removes ItemName From ItemSubtype List
If /I "%~2" == "/R" (
Set "Value="
If not "%~5" == "" Set "Value=%~5"
For /F "Tokens=1,2* Delims==" %%G in (' Set "#" 2^> nul ^|%__Appdir__%findstr.exe /LIC:"%~1" ')Do (
rem /* Test if Variable is a List Variable; If Not Undefines Variable */
Set "List?=%%G"
If not "!List?:~0,10!" == "#Inventory" (
Set "%%G="
)Else (
rem /* If Variable is a List Variable; Remove ItemName from ItemSubType List */
Set "%%G=!%%G: "%~1"=!"
Rem /* If ItemSubType List is Empty; Remove ItemSubtype from ItemType List */
If "!%%G!" == "" (Set "#Inventory.%~3=!#Inventory.%~3: "%~4"=!")
)
)
rem /* If Item SaleValue provided; Increment #Money by Value */
Set /A "#Money+=!Value!+0"
Goto :Save
)

:# Build Itemtype Arrays and List Using Parameters
Set "ItemName=%~1"
Set "ItemType=%~2"
Set "ItemSubtype=%~3"
Set "Count=0"
:# Limit ItemTypes to 36 max supported by Menu macro
If Not "!#Inventory.%ItemType%!" == "" (
For %%G in (!#Inventory.%ItemType%!)Do Set /A "Count+=1"
If !Count! GTR 36 (
Echo(You own too many types of %ItemType%. !ItemName! cannot be Acquired.
Exit /B 3
)
)
Set "Count=0"
:# Limit Subtypes to 36 max supported by Menu macro
If Not "!#Inventory.%ItemType%.%ItemSubType%!" == "" (
For %%G in (!#Inventory.%ItemType%.%ItemSubType%!)Do Set /A "Count+=1"
If !Count! GTR 36 (
Echo(You own too many types of %ItemSubtype%. !ItemName! cannot be Acquired.
Exit /B 3
)
)
If "%~4" == "" (Set "ItemWeight=0")Else (
Set "ItemWeight=%~4"
For /F %%G in ('Set /A #MaxWeight-%~4-#weight')Do if %%G LSS 0 (
Echo/You are carrying too much.
Exit /B 2
))
:# Determine Value of Item and If item is To be Free or Paid For
Set "Free.Item="
Echo(%*|%__APPDIR__%findstr.exe /LIC:"/F" > Nul && Set "Free.Item=Y"
If "%~5"=="" (Set "ItemCost=0")Else (
Set "ItemCost=%~5"
If Not Defined Free.Item (
For /F %%G in ('Set /A #money-%~5')Do if %%G LSS 0 (
Echo(You cannot afford %ItemName%
Exit /B 1
)
)
)
:# Define a Modifier To ItemName.modname For Items With Stat Modifiers If supplied
If not "%~6" == "" If /I not "%~6" == "/F" (
Set "#%ItemName%.%~6" 2> Nul || (
Echo(Invalid Argument "[%~6]" In %*
Echo(Required: "ModifierType=Value"
Timeout /T 3 /NoBreak
Pause
Endlocal & Goto :Eof
)
)
:# Define #ItemName Arrays for Grams and Value
Set "#%ItemName%.Grams=%Itemweight%"
Set "#%ItemName%.Value=%ItemCost%"
Echo(!ItemName! added to Inventory.
:# Search savefile for Itemtype; Itemsubtype; and Itemname; Append to relevant list if not present
%__APPDIR__%findstr.exe /LIC:"!ItemType!" "%Game.Save%" > nul 2> nul || Set "#Inventory.Types=!#Inventory.Types! "!ItemType!""
%__APPDIR__%findstr.exe /LIC:"!ItemSubType!" "%Game.Save%" > nul 2> nul || Set "#Inventory.%ItemType%=!#Inventory.%ItemType%! "!ItemSubType!""
%__APPDIR__%findstr.exe /LIC:"!ItemName!" "%Game.Save%" > nul 2> nul || Set "#Inventory.%ItemType%.%ItemSubType%=!#Inventory.%ItemType%.%ItemSubType%! "!ItemName!""
=================================================
:Save
:# Remove Item Categories from #Inventory.Types list when all Category sub items are sold / dropped.
For %%G in (!#Inventory.Types!)Do If "!#Inventory.%%~G!" == "" Set "#Inventory.Types=!#Inventory.Types: "%%~G"=!"
Set /A "#Def=#Dmg=#weight=0"
:# Updates the below Modifiers of all equipped inventory items by summing all ItemName.%%M definitions
For %%M in (DEF DMG)Do For /F "Tokens=1,2* Delims==" %%G in ('Set "#Equipped" 2^> nul')Do (
For /F "Tokens=2 Delims==" %%i in ('Set "#%%H"^|%__APPDIR__%Findstr.exe /LIC:".%%M"')Do (
Set /A "#%%M+=%%i+0"
)
)
:# Updates the current weight of all inventory items by summing all ItemName.Grams definitions
For /F "Tokens=2 Delims==" %%G in (' Set "#" ^| Findstr /LIC:".Grams"')Do Set /A #weight+=%%G
Set "#Display.weight=%#weight:~0,-3%.%#weight:~-3%"
:# Enact Save for # prefixed variables
:# Saves Game Variables prefixed by # to Game.Save cmd file to be called on Login
(For /F "tokens=1,2* Delims==" %%G in ('Set "#"')Do Echo(Set "%%G=%%H") >"%Game.Save%"
Echo(%#Name%>"%~f0:Last_Char"
Exit /B 0
=================================================
:ManageInventory {Optional:/E /S /D}
:# Control Available Inventory options by Calling ManageInventory with the Options you wish
:# to allow according to the current Gamestate.
Set "MI.Options="
If not "%~1" == "" Echo/%*|Findstr /LIC:"E" > Nul && Set "MI.Options=!MI.Options! Equip"
If not "%~1" == "" Echo/%*|Findstr /LIC:"S" > Nul && Set "MI.Options=!MI.Options! Sell"
If not "%~1" == "" Echo/%*|Findstr /LIC:"D" > Nul && Set "MI.Options=!MI.Options! Drop"
:# /R - Removes the Sell option from Invetory Action
:# RESERVED VARIABLES - Type; SubType; Action; All Menu Macro Reserved Variables
:# DEPENDENCIES -Functions: Inventory; Save -Macro: Menu -Variables: #Money #Equipped
:#                          Inventory Function Defines Lists used with Each Submenu.
:# This function returns no Errorlevels.
CLS
Echo(         Credit: !#Money! Damage: !#Dmg! Defence: !#Def! Burden: !#Display.Weight! kg /!#MaxWeight:~0,-3!.!#MaxWeight:~-3! kg.
Echo( Equipped Items:
(Set "#Equipped" 2> nul > nul ) || Echo( No items equipped.
(For /F "Delims=" %%# in ('Set #Equipped 2^> nul') Do For /F "Tokens=1,2 Delims==" %%C in ("%%#")Do (
Set "[item]=%%C"
Set "[item]=![item]:*.=!"
Set "[item]=![item]:.=: !"
<nul set /P "=> ![item]! = %%D!LF!"
)) 2> nul
:# Choose Action Type or Exit ManageInventory Function; Each Submenu can abort to this Primary Menu
%Menu% Exit !MI.Options!
CLS
Set "Action=!Option!"
Echo(Select Inventory Category:
%Menu% Return !#Inventory.Types!
If "!Option!" == "Return" (Goto :ManageInventory)Else CLS
Set "Type=!Option!"
Echo(Select a type of !Type! to !Action!:
%Menu% Return !#Inventory.%Type%!
If "!Option!" == "Return" (Goto :ManageInventory)Else CLS
Set "SubType=%Option%"
:# Apply action type to selected ItemName
:# If Equipping; Handle Two Handed / [One Handed/Off Hand] Equipment Conflict
Echo(Selecting a !Subtype! from your !Type! Will !Action! it. Return [0] To cancel.
%Menu% Return !#Inventory.%Type%.%SubType%!
If Not "!Option!" == "Return" (
If "!Action!" == "Equip" (
Set "#Equipped.%Type%.%Subtype%=%Option%"
If /I "%SubType%" == "Two Handed" (Set "#Equipped.Weapons.One Handed="&Set "#Equipped.Weapons.Off Hand=")
If /I "%SubType%" == "One Handed" (Set "#Equipped.Weapons.Two Handed=")
If /I "%SubType%" == "Off Hand" (Set "#Equipped.Weapons.Two Handed=")
Call :Save
)
If "!Action!" == "Sell" (
Echo(Sell Value: $!#%Option%.Value!. Confirm [Y/N]
For /F "Delims=" %%O in ('Choice /N /C:YN')Do If %%O==Y Call :Inventory "%Option%" /R "!Type!" "!SubType!" "!#%Option%.Value!"
)
If "!Action!" == "Drop" Call :Inventory "%Option%" /R "!Type!" "!SubType!"
)
Goto :ManageInventory
=================================================
:login
:# clear any preexisting definitions
(For /F "tokens=1,2* Delims==" %%G in ('Set "#"')Do Set "%%G=") 2> nul
:# check Alternate data stream 'Last_Char' of this file; offer single key login for last played character.
more < "%~f0:Last_Char" 2>nul >nul && For /F "Delims=" %%G in ('more ^< "%~f0:Last_Char"')Do (
Echo(Continue as %%G Y/N
For /F "Delims=" %%C in ('Choice /N /C:YN')Do if "%%C"=="Y" (
Set "Game.Save=%TEMP%%~n0_%%G_Save.cmd"
CALL "%TEMP%%~n0_%%G_Save.cmd"
Exit /B 0
)
)
(For /F "tokens=1,2* Delims==" %%G in ('Set "#"')Do Set "%%G=") 2> nul
:# Login Errorlevels: [2:User quit during Login.] [1:New Character] [0:Existing Character]
:# IMPORTANT - RESERVED VARIABLES:
:# - #Name #Pass Verify
:#   #Name used to create a .cmd file that is called when the user logs back in to the character to reassign
:#   # prefixed variables.
CLS
Echo(Existing Characters:
(Dir /B "%TEMP%%~n0_*_Save.cmd" > Nul 2> nul || Echo(None. )
For /F "Tokens=2 Delims=_" %%G in (' Dir /B "%TEMP%%~n0_*_Save.cmd" 2^> nul ')Do Echo(%%G
rem /* example definitions */
Call :GetIn #Name "[a-zA-Z ]*" /C /S /P:Enter your characters name
If Not "%Errorlevel%" == "0" Goto :login
Call :GetIn #Pass "[0-9][0-9][0-9][0-9]" /S /P:Enter your four Digit Pin
If Not "%Errorlevel%" == "0" Goto :login
Set "Verify=%#Pass%"
Set "Game.Save=%TEMP%%~n0_%#Name%_Save.cmd"
rem /* load saved values */
If Exist "%Game.Save%" Call "%Game.Save%"
If /I not "%Verify%" == "%#Pass%" (
Echo(Invalid Password
%Menu% Exit Retry
rem /* Flag quit program */
Goto :Login
)
rem /* offer delete/ login if exists */
If Exist "%Game.Save%" (
rem /* Flag Existing Character Errorlevel 0 */
%Menu% "Remove Character" "Continue"
If /I "!Option!"=="Continue" Exit /b 0
%Menu% "Abort" "Proceed"
If /I "!Option!"=="Abort" Goto :Login
Del "%Game.Save%"
Goto :Login
) Else (
rem /* Flag New Character Errorlevel 1 */
Exit /B 1
)
=====================================================
:strlen <resultVar> <stringVar>
(   
setlocal EnableDelayedExpansion
(set^ tmp=!%~2!)
if defined tmp (
set "len=1"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!tmp:~%%P,1!" NEQ "" ( 
set /a "len+=%%P"
set "tmp=!tmp:~%%P!"
)
)
) ELSE (
set len=0
)
)
( 
endlocal
set "%~1=%len%"
exit /b
)
=====================================================
:GetIn [ReturnVar] ["qouted findstr search pattern"]  [Optional:"/C" - required for patterns with spaces] [Optional "/S" - Suppress input accepted] [/P:Custom Prompt]
:# Input validation function for restricting input to desired character classes or [limited] Regex Patterns.
:# -IMPORTANT - RESERVED VARIABLES: InputParams /C /P /S rVar Pattern Exit.Code
:# - GetIn Errorlevels: 
:#  - Errorlevel 3 - User has failed to provide valid input * OR * regex pattern is
:#    invalid * OR * GetIn is a called label in a file that has recieved input
:#    from a pipe that has not been handeled before the call.
:#  - Errorlevel 2 - GetIn is a script that has been invoked by a pipe
:#  - Errorlevel 1 - GetIn has been called without Arg 2 for Regex Pattern
:#  - Errorlevel 0 - Input has been assigned that matches the Regex Pattern
:# GetIn Usage Examples - Description is replaced with Arg 1-ReturnVar:
:#  Call :GetIn Pin "[0-9][0-9][0-9][0-9]" /S /P:Enter a four Digit Pin Number
:#  Call :GetIn Alphanumeric-String "[0-9a-zA-Z]*"
:#  Call :GetIn semicolon-delimited-hexadecimal-String "[0-9a-fA-F][0-9a-fA-F][:][0-9a-fA-F][0-9a-fA-F]"
:#  Call :GetIn AlphaString-with-3-Digit-Numeric-suffix "[a-zA-Z]*[0-9][0-9][0-9]"
:#  Call :GetIn list-of-delimited-words "[a-zA-Z, ]*" /C
:#  Call :GetIn pair-of-delimited-numbers "[0-9]*[, ][0-9]*" /C
SETLOCAL EnableExtensions EnableDelayedExpansion
Set "/C=" & Set "/P=" & Set "/S="
Set InputParams=%*
If Not "!InputParams:/C=!" == "!InputParams!" Set "/C=_"
If Not "!InputParams:/S=!" == "!InputParams!" Set "/S=_"
If Not "!InputParams:/P=!" == "!InputParams!" (
Set "/P=!InputParams:*/P:=!"
Set "/P=!/P:"=!"
)
rem [ test if standalone script - if so test if accessed by pipe; reject execution if true ]
If "%~0" == "%~n0" For %%G in (!cmdcmdline!)Do Echo/%%~G|Findstr.exe /LIC:"/S" > nul 2> nul && (Set "Exit.Code=2" & Goto :Getin.Err)
:GetInRetry
Del /Q "%TEMP%%~n0_validate.~tmp" 2> nul
If !Exit.Code! GTR 5 Goto :Getin.Err
Set "rVar="
If "%~2" == "" GOTO :Getin.Err
Setlocal DISABLEdelayedExpansion & rem ::: display occurances of carets [^] in pattern
Endlocal & Set "Pattern=%~2"
If Not Defined /P (
Set /P "rVar=Input Format for %1:!LF!!Pattern!!LF!!LF!Enter %1: "
)Else  Set /P "rVar=!/P!: "
If "!rVar!" == "" (Set /A "Exit.Code+=1" & <nul Set /P"= ^! Invalid value.!LF!" & Goto :GetInRetry)
> "%TEMP%%~n0_validate.~tmp" (Echo/!rVar!)
If Defined /C (
Type "%TEMP%%~n0_validate.~tmp" | %__APPDIR__%findstr.exe /RXC:"%~2" >nul || (Set /A "Exit.Code+=1" & <nul Set /P"= ^! Invalid value. !LF!" & Goto :GetInRetry)
) Else (
Type "%TEMP%%~n0_validate.~tmp" | %__APPDIR__%findstr.exe /RX "^%~2$" >nul || (Set /A "Exit.Code+=1" & <nul Set /P"=- ^! Invalid value. !LF!" & Goto :GetInRetry)
)
If not defined /S Echo/%1: [!rVar!] Accepted
ENDLOCAL & Set "%~1=%rVar%"
Del /Q "%TEMP%%~n0_validate.~tmp"
Exit /B 0
:GetIn.Err
Exit /B %Exit.Code%
===========================:# DEFINE INITIAL INVENTORY - EXAMPLE Only
:Knight Starter Pack
:# Example of defining initial variables for a new character prior to commencing gameplay
:# IMPORTANT - Inventory function is Dependant on #Money #MaxWeight and #Weight variables.
Set /A "#Money=500,#MaxWeight=25000,#Weight=0"
:# suppress output of Inventory added notifcation by redirecting to nul as desired.
Call :Inventory "Dagger" Weapons "Off Hand" 250 50 "DMG=5" /F > nul
Call :Inventory "Buckler" Weapons "Off Hand" 400 40 "DEF=6" /F > nul
Call :Inventory "Short sword" Weapons "One Handed" 4000 250 "DMG=10" /F > nul
Call :Inventory "Twin Bladed Katana" Weapons "Two Handed" 5500 350 "DMG=12" /F > nul
Call :Inventory "Leather Cap" Armor Helm 500 25 "DEF=3" /F > nul
Call :Inventory "Faded Map" Miscellaneous Maps 20 "DEF=5" /F > nul
Call :Inventory "Healing Potion" Potions Restorative 10 25 "Heal=30" /F > nul
Call :Inventory "Old Key" Miscellaneous Keys 10 1 /F > nul
Call :Inventory "Worn Leather Vambraces" Armor Vambraces 1000 15 "DEF=2" /F > nul
Call :Inventory "Boots of Luck" Armor Boots 1500 50 "DEF=4" /F > nul
Goto :Eof
===========================:# END OF FUNCTIONS
:Prep
=====================================================:# MACRO DEFINITIONS
===================================:# MENU macro prep and Definition :::
:# IMPORTANT - RESERVED VARIABLES:
:# - LF N Game.Save
(Set LF=^
%= Linefeed var used for multi-line output in GetIn macro - Do not modify. =%)
(Set n=^^^
%= Newline var n for multi-line macro definition - Do not modify. =%)
:# Enable environment for macro expansion, Arrays and code block variable operations
Setlocal EnableExtensions EnableDelayedExpansion
==================================================================
:# Menu macro escaped for Definition with DelayedExpansion Enabled
:# IMPORTANT - RESERVED VARIABLES: Menu CH# CHCS Options Option Opt[i] Option.Output Cholist DIV
:# Key index list Allows 36 menu options. Component of Menu Macro
Set "ChoList=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
rem /* Get console width for dividing line. */
for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| %__APPDIR__%findstr.exe /LIC:"Columns"`) do Set /A "Console_Width=%%W"
:# Build dividing line for menu output.
Set "DIV="&For /L %%i in (2 1 %Console_Width%)Do Set "DIV=!DIV!-"
:# Menu macro Usage: %Menu% "quoted" "list of" "options"
==== Set Menu=For %%n in (1 2)Do if %%n==2 (%n%
%= Output Dividing Line                 =%  Echo(^^!DIV^^!%n%
%= Reset CH# index value for Opt[#]     =%  Set "CH#=0"%n%
%= Undefine choice option key list      =%  Set "CHCS="%n%
%= For Each in list;                    =%  For %%G in (^^!Options^^!)Do (%n%
%= For Option Index value               =%   For %%i in (^^!CH#^^!)Do (%n%
%= Build the Choice key list and Opt[#] =%    Set "CHCS=^!CHCS^!^!ChoList:~%%i,1^!"%n%
%= array using the character at the     =%    Set "Opt[^!ChoList:~%%i,1^!]=%%~G"%n%
%= current substring index.             =%    Set "option.output=%%~G"%n%
%= Display ; removing # variable prefix =%    Echo([^^!ChoList:~%%i,1^^!] ^^!Option.output:#=^^!%n%
%= Increment Opt[#] Index var 'CH#'     =%    Set /A "CH#+=1"%n%
%= Close CH# loop                       =%   )%n%
%= Close Options loop                   =%  )%n%
%= Output Dividing Line                 =%  Echo(^^!DIV^^!%n%
%= Select option by character index     =%  For /F "Delims=" %%o in ('Choice /N /C:^^!CHCS^^!')Do (%n%
%= Assign return var 'OPTION' with the  =%   Set "Option=^!Opt[%%o]^!"%n%
%= value selected from Opt[CH#] array.  =%   If /I "^!Option^!" == "Exit" Exit /B 2%n%
%= Return to previous script on Exit    =%  )%n%
%= Capture Macro input - Options List   =% )Else Set Options=
========================================== ::: End Menu Definition
:StartGame
:# Make the Session Local
Setlocal
==========================================:# MAIN GAME SCRIPT [ EXAMPLE ]
:# To Create / Continue a Character; Call Login. Errorlevel 0 = Returning Character
:# Modify The reponse to Errorlevel 1 [New Character] As you Wish to facilitate Creation of Character Classes.
:# Suggested: Use the Menu Macro with a list of Character Classes corresponding to functions and Call the selected class Label (IE - Call :Rogue)
Call :Login
If Errorlevel 2 Goto :Eof
If Errorlevel 1 (
Echo(Select your Class:
%Menu% Exit "Knight" "Rogue"
Call :!Option! 2>nul || (
Echo(The !Option! Class has not been created yet. Use the example of the :Knight function to create your own Classes.
Timeout /T 3 /NoBreak > Nul
Pause
Endlocal
Goto :StartGame
)
)
:# Use Labels as checkpoints by Defining them to the Variable #Location
If Errorlevel 0 If Defined #Location (Goto :!#Location!)
:# To [S]ell [E]quip or [D]rop Inventory:
:# If the Player is not in a Town / Shop; Use: Call :ManageInventory /ED to Lock out Sale of Items
Call :ManageInventory /ESD
:Home This and below Label locations are examples of using Label Checkpoints
CLS
Call :Inventory Home /L
:# Use last selected option to prevent recursive calls.
If not "!Option!" == "Home" (
%Menu% Exit "Manage Inventory" "Travel"
)Else %Menu% Exit "Manage Inventory"
If "!Option!" == "Manage Inventory" (
Call :!Option: =! /ESD
Goto :Home
)
If not "!Option!" == "Travel" Goto :Eof
:Travel
CLS
Call :Inventory Travel /L
Echo(Choose a Direction:
%Menu% Exit Home East West North South
Call :!Option: =! 2> Nul || If not Errorlevel 2 (
Echo That Direction has not been Scripted yet. You'll have to make your own Adventure.
Pause
)
Goto :Travel

相关内容

  • 没有找到相关文章

最新更新