Add existing file
This commit is contained in:
parent
9bedcb263d
commit
d6a4b8bf20
320 changed files with 20855 additions and 0 deletions
550
docs/Change Log.txt
Normal file
550
docs/Change Log.txt
Normal file
|
@ -0,0 +1,550 @@
|
|||
A mostly-complete history log of engine updates can be found here.
|
||||
|
||||
1.32b
|
||||
Changes:
|
||||
- All functions and actions that change a shot's graphic ID has an additional feature:
|
||||
- The actual graphic ID will be the absolute value of the value received.
|
||||
- If the value received was negative, the graphic change operation will preserve the shot's previous spin angular velocity and Z-angle.
|
||||
- Affected functions and actions:
|
||||
- ObjShot_SetGraphic
|
||||
- ObjMove_AddPatternA3
|
||||
- ObjMove_AddPatternA4
|
||||
- ObjMove_AddPatternB3
|
||||
- ObjMove_AddPatternC3
|
||||
- ObjMove_AddPatternC4
|
||||
- TRANSFORM_GRAPHIC_CHANGE
|
||||
Additions:
|
||||
- Added an instruction on how to get ph3sx to work with Wine. (Check readme.txt)
|
||||
- Added SetIntersectionVisualizationRenderPriority.
|
||||
Bug fixes:
|
||||
- Fixed incorrect documentation for some functions.
|
||||
- Fixed AddPoint not working correctly.
|
||||
- Fixed some issues with acceleration and max speed when converting from B-movement to A-movement or C-movement with AddPattern.
|
||||
|
||||
1.32a
|
||||
Changes:
|
||||
- Renamed "real" to "float".
|
||||
- r (number suffix) -> f (number suffix)
|
||||
- 45.22r -> 45.22f
|
||||
- real -> float
|
||||
- as_real -> as_float
|
||||
- as_real_array -> as_float_array
|
||||
- VAR_REAL -> VAR_FLOAT
|
||||
- Changed how setting curvy laser node widths work. Instead of directly setting the width, the functions will set the nodes' width scales.
|
||||
- Renamed ObjCrLaser_SetNodeWidth to ObjCrLaser_SetNodeWidthScale.
|
||||
- Renamed ObjCrLaser_GetNodeWidth to ObjCrLaser_GetNodeWidthScale.
|
||||
- Improved cross-compatibility between different movement types of the following functions:
|
||||
- ObjMove_SetSpeed
|
||||
- ObjMove_SetAngle
|
||||
- ObjMove_SetAcceleration
|
||||
- ObjMove_SetMaxSpeed
|
||||
- ObjMove_SetAngularVelocity
|
||||
- Swapped the "shot graphic ID" and "target ID" arguments in ObjMove_AddPatternA4.
|
||||
- Swapped the "max speed" and "angular velocity" arguments of the following functions:
|
||||
- ObjMove_AddPatternA2
|
||||
- ObjMove_AddPatternA3
|
||||
- ObjMove_AddPatternA4
|
||||
- TRANSFORM_ADDPATTERN_A2 in ObjPatternShot transforms
|
||||
- Completely removed shot scripts.
|
||||
- Moved SetShotDeleteEventEnable to the stage script.
|
||||
- Default values for all three delete events are true.
|
||||
- Furthermore, fixed EV_DELETE_SHOT_IMMEDIATE and EV_DELETE_SHOT_FADE not being notified properly.
|
||||
- Restructed event arguments of EV_DELETE_SHOT_TO_ITEM.
|
||||
- The third event argument; "player collision", has been removed.
|
||||
- Collision with the player will now trigger EV_DELETE_SHOT_IMMEDIATE instead of EV_DELETE_SHOT_TO_ITEM.
|
||||
- Increased the minimum width for straight and curve lasers, primarily for delay visibility purposes. (Thanks to Naudiz)
|
||||
- Allowed lasers to lose penetration (life) points. (Thanks to Naudiz)
|
||||
- Like with any shot object, this will only occur when a laser lacks spell resistance (which it has by default).
|
||||
- Removed #BGM.
|
||||
- Made it so that the window sizes list will be autogenerated instead of defaulting to [640x480, 800x600, 960x720, 1280x960] when window.size.list in th_dnh.def doesn't exist.
|
||||
- Size multipliers are [x1, x1.25, x1.5, x2], with screen.width and screen.height being the base resolution.
|
||||
- Made it so that the engine will check for the required .dll modules during initialization.
|
||||
- d3d9.dll
|
||||
- d3dx9_43.dll
|
||||
- d3dcompiler_43.dll
|
||||
- dinput8.dll
|
||||
- dsound.dll
|
||||
- In the event where the Direct3D device enters a lost state, the engine will now attempt to restore up to 60 times before throwing an error, rather than only once.
|
||||
- Removed ObjItem_SetAutoCollectEnable, and replaced it with ObjItem_SetAutoCollectEnableFlags.
|
||||
Additions:
|
||||
- Added Interpolate_X_Array, Interpolate_X_Angle, and Interpolate_X_AngleR. (Thanks to Naudiz)
|
||||
- Added ObjShot_SetEnemyIntersectionInvalidFrame and ObjShot_SetPenetrateShotEnable. (Thanks to Naudiz)
|
||||
- Added SetShotTextureFilter, SetItemTextureFilter, ObjRender_SetTextureFilter, and ObjShot_SetAngleRounding. (Thanks to Naudiz)
|
||||
- Added SetEnemyAutoDeleteClip, ObjEnemy_SetAutoDelete, and ObjEnemy_SetDeleteFrame. (Thanks to NicholasLogan)
|
||||
- Added ObjMove_SetAngularAcceleration, ObjMove_SetAngularMaxVelocity, and ObjMove_AddPatternA5. (Thanks to NicholasLogan)
|
||||
- Added an overload to CreateShotA2, adding an angular velocity argument in between the acceleration and max speed ones. (Thanks to Naudiz)
|
||||
- Added ObjMove_GetMovementType. (Thanks to Naudiz)
|
||||
- Added constants:
|
||||
- MOVE_NONE
|
||||
- MOVE_ANGLE
|
||||
- MOVE_XY
|
||||
- MOVE_XY_ANGLE
|
||||
- MOVE_LINE
|
||||
- Added the C-movement type for ObjMove. (Thanks to Naudiz)
|
||||
- CreateShotC1
|
||||
- CreateShotC2
|
||||
- CreateShotOC1
|
||||
- ObjMove_AddPatternC1
|
||||
- ObjMove_AddPatternC2
|
||||
- ObjMove_AddPatternC3
|
||||
- Added AddPattern functions for line-movement. (Thanks to Naudiz)
|
||||
- ObjMove_AddPatternD1 (AddPattern version of ObjMove_SetDestAtSpeed)
|
||||
- ObjMove_AddPatternD2 (AddPattern version of ObjMove_SetDestAtFrame)
|
||||
- ObjMove_AddPatternD3 (AddPattern version of ObjMove_SetDestAtWeight)
|
||||
- Added ObjMove_CancelMovement.
|
||||
- Added new transformations to pattern shot objects. (Thanks to Naudiz)
|
||||
- TRANSFORM_ADDPATTERN_C1
|
||||
- TRANSFORM_ADDPATTERN_C2
|
||||
- Added psrand.
|
||||
- Added array overloads to the following functions:
|
||||
- ObjSprite2D_SetSourceRect
|
||||
- ObjSprite2D_SetDestRect
|
||||
- ObjSpriteList2D_SetSourceRect
|
||||
- ObjSpriteList2D_SetDestRect
|
||||
- ObjSprite3D_SetSourceRect
|
||||
- ObjSprite3D_SetDestRect
|
||||
- ObjSprite3D_SetSourceDestRect
|
||||
- Added support for hexadecimal numbers in text color tags.
|
||||
- "[f tc=0xffffff]" is equivalent to "[f tc=(255,255,255)]".
|
||||
- Added GetWorkingDirectory.
|
||||
- Added an option to allow the engine to keep running while the window is unfocused. (Thanks to Naudiz)
|
||||
- Added SetEnableUnfocusedProcessing and IsWindowFocused.
|
||||
- Added the property "unfocused.processing" to th_dnh.def.
|
||||
- Added EV_APP_LOSE_FOCUS and EV_APP_RESTORE_FOCUS.
|
||||
- Added exponent format for numbers.
|
||||
- "5.462e3" or "-231.9e-2" are now valid numbers.
|
||||
- Added ObjItem_SetAutoCollectEnableFlags.
|
||||
- ITEM_AUTOCOLLECT_PLAYER_SCOPE
|
||||
- ITEM_AUTOCOLLECT_COLLECT_ALL
|
||||
- ITEM_AUTOCOLLECT_POC_LINE
|
||||
- ITEM_AUTOCOLLECT_COLLECT_CIRCLE
|
||||
- ITEM_AUTOCOLLECT_ALL
|
||||
- Added an overload to atoi.
|
||||
- Added SetScore, SetGraze, and SetPoint.
|
||||
Bug fixes:
|
||||
- Fixed .dat archives not working.
|
||||
- Fixed incorrect null checks, resulting in the game crashing when trying to operate on a null value.
|
||||
- For example, using Obj_GetValue on a non-existent key will yield a null value.
|
||||
- Fixed a crash bug which may sometimes happen when trying to parse a script file that ends with a line comment.
|
||||
- Fixed ObjMove_AddPatternXX's shot graphic change not working with loose and curvy lasers.
|
||||
- Fixed SetShotIntersectionCircle/Line not registering intersection, despite showing up in intersection visualization.
|
||||
|
||||
1.31b
|
||||
Bug fixes:
|
||||
- Fixed a bug where the game would freeze when compiling a script with a syntax error.
|
||||
- Fixed a minor visual bug where the LogWindow's sub-info fields would all try to display over each other on initialization.
|
||||
|
||||
1.31a
|
||||
Changes:
|
||||
- This version breaks replay, common data, and .dat archive backwards compatibility.
|
||||
- Replaced the default script select backgrounds with a radder version. (Thanks to Naudiz)
|
||||
- Renamed GetShotIdAll to GetAllShotID.
|
||||
- Changed the text representation of script value types in error messages.
|
||||
- "real-array-array" -> "real[][]"
|
||||
- Script matrix functions can now take in a 4x4 array instead of only a 1x16 array previously.
|
||||
- The element type is also no longer limited to real.
|
||||
- Made setting ObjRender_SetEnableDefaultTransformMatrix to false still load the camera matrix.
|
||||
- Allowed multiple ObjSounds to independently stream the same sound file.
|
||||
- Shortened the module directory in Log messages of the LogWindow to "../".
|
||||
- Removed the behaviour where the 2D and 3D camera resets upon transitioning from the package scene to the stage scene.
|
||||
- Fog data is no longer split between package-level and stage-level scripts.
|
||||
- The default FPS counter no longer briefly appears when starting with package.script.main.
|
||||
- Maximizing the window now triggers fullscreen mode.
|
||||
- Objects now have separate tables each for string-indexed and int-indexed.
|
||||
- Improved support for particle list objects for older PCs.
|
||||
- Made it so that curvy lasers can be shortened. (Thanks to Naudiz)
|
||||
- ObjFileT_SplitLineText now splits from pattern rather than from a list of delimiters.
|
||||
- Reduced the float truncation epsilon. (0.01 -> 0.000001)
|
||||
- #include in shader source files now behaves like regular script includes.
|
||||
- Normal shot objects can now have multiple hitboxes again.
|
||||
- Change loose and curvy lasers behaviour when delay motion is enabled. (Thanks to Naudiz)
|
||||
- Text objects can now be centered around their object positions. No need to use ObjText_SetMaxWidth for that anymore. (Thanks to Naudiz)
|
||||
Additions:
|
||||
- Added missing function documentation for GetAllEnemyID.
|
||||
- Added an overload each for Rotate2D and Rotate3D, taking in the rotation origin point.
|
||||
- Expanded the variety of intersection-checking functions:
|
||||
- IsIntersected_Point_Polygon
|
||||
- IsIntersected_Point_Circle
|
||||
- IsIntersected_Point_Ellipse
|
||||
- IsIntersected_Point_Line
|
||||
- IsIntersected_Point_RegularPolygon
|
||||
- IsIntersected_Circle_Polygon
|
||||
- IsIntersected_Circle_Circle
|
||||
- IsIntersected_Circle_Ellipse
|
||||
- IsIntersected_Circle_RegularPolygon
|
||||
- IsIntersected_Line_Polygon
|
||||
- IsIntersected_Line_Circle
|
||||
- IsIntersected_Line_Ellipse
|
||||
- IsIntersected_Line_Line
|
||||
- IsIntersected_Line_RegularPolygon
|
||||
- IsIntersected_Polygon_Polygon
|
||||
- IsIntersected_Polygon_Ellipse
|
||||
- IsIntersected_Polygon_RegularPolygon
|
||||
- Added ReflectAngle and ReflectAngleR. (Thanks to Naudiz)
|
||||
- Added Python-style reverse indexing of arrays. (Thanks to Naudiz)
|
||||
- See "New Scripting Features".
|
||||
- arr[-n] is equivalent to arr[length(arr) - n]
|
||||
- Also works in erase and insert.
|
||||
- Added replace and remove. (Thanks to Naudiz)
|
||||
- #ifdef, #ifndef, #else, and #endif preprocessor directives for scripts.
|
||||
- Several script macros were added:
|
||||
- _DNH_PH3SX_
|
||||
- SCRIPT_PACKAGE (defined in package-level scripts)
|
||||
- SCRIPT_STAGE (defined in stage-level scripts)
|
||||
- #define is not yet supported.
|
||||
- Added ObjItem_GetIntersectionEnable. (Thanks to Naudiz)
|
||||
- Added ObjRender_GetColorHex, ObjPrim_GetVertexColorHex, and ObjCrLaser_GetNodeColorHex. (Thanks to Naudiz)
|
||||
- Added ColorHexRGBtoHSV.
|
||||
- Added another event argument to EV_DELETE_SHOT_PLAYER.
|
||||
- Added a "Sound Memory" display to the Sound tab of the LogWindow.
|
||||
- Added INFO_IS_REQUIRE_ALL_DOWN to ObjEnemyBossScene_GetInfo. (Thanks to Naudiz)
|
||||
- Added ObjEnemy_SetMaximumDamage and ObjEnemy_AddLifeEx.
|
||||
- Added INFO_DAMAGE_PREVIOUS_FRAME to ObjEnemy_GetInfo.
|
||||
- Added ObjText_SetFixedWidth.
|
||||
- Added ObjText_GetText. (Thanks to Naudiz)
|
||||
- Added ObjText_SetVerticalAlignment. (Thanks to Naudiz)
|
||||
- Added ObjCrLaser_SetTipCapping, ObjCrLaser_GetNodeRenderWidth, and ObjCrLaser_SetNodeRenderWidth. (Thanks to Naudiz)
|
||||
- Added overloads to ObjCrLaser_SetNode and ObjCrLaser_AddNode. (Thanks to Naudiz)
|
||||
- Added ObjShot_SetFixedAngle and ObjShot_SetDelayAngularVelocity. (Thanks to Naudiz)
|
||||
- Added SplitString2.
|
||||
- Added Obj_GetValueCount and Obj_GetValueCountI.
|
||||
- Added a progress bar to the FileArchiver.
|
||||
- Added an overload to SetStgFrame. (Thanks to Naudiz)
|
||||
- Added GetConfigVirtualKeyMapping and GetVirtualKeyMapping. (Thanks to Naudiz)
|
||||
Bug fixes:
|
||||
- Fixed incorrect documentation of IsIntersected_Circle_RegularPolygon.
|
||||
- Fixed the Y shot intersection scale not functioning properly on loose lasers.
|
||||
- Fixed the engine crashing upon trying to parse an excess comma in function parameter lists.
|
||||
- Fixed type-checking bugs with array-index-assignment operations.
|
||||
- Fixed an issue where the parser would indefinitely hang upon trying to parse an ill-formed for-loop.
|
||||
- Fixed a bug where .wav files over 1MB large would get cut off at the end.
|
||||
- Fixed a bug where multiple streaming ObjSounds playing the same file would not function correctly.
|
||||
- Fixed ObjSound_IsPlaying returning false if called in the same frame of ObjSound_Play.
|
||||
- Fixed a bug where shot objects colliding with the player gets deleted before EV_HIT is notified.
|
||||
- Fixed GetShotIdInCircleA1 incorrectly returning player shot IDs instead of enemy shot IDs.
|
||||
- Fixed ObjShot_Regist in a player script returning null if IsPermitPlayerShot is true.
|
||||
- Fixed a bug where the shot object colliding with the player is deleted before the notification of EV_HIT.
|
||||
- Fixed off-centered shot and item graphics.
|
||||
- Fixed the game crashing upon trying to parse an ill-formed argument list in user shot/item data files.
|
||||
- Fixed a bug where 3D render objects drawn below the min STG frame render priority would get abnormally stretched out.
|
||||
- Fixed ObjMove_GetSpeedX/Y returning incorrect values for ObjMove_SetDestAtXXX functions.
|
||||
- Fixed the game crashing when setting ObjRender_SetEnableDefaultTransformMatrix to false for 3D objects.
|
||||
- Fixed incorrect conversion of A-movement to B-movement for ObjMove.
|
||||
- Fixed CreateItemU1/2 causing the created item to render at (0, 0) for a single frame. (Thanks to Naudiz)
|
||||
- Fixed ObjMove_AddPatternXX not working on move objects that do not have an existing movement pattern. (Thanks to Naudiz)
|
||||
- Fixed a rare bug with array initialization.
|
||||
- Fixed a bug where ObjShot_SetPenetration(obj, 0) would not notify EV_DELETE_SHOT_PLAYER.
|
||||
- Fixed a rare crash during enemy boss scene loading.
|
||||
- Fixed a bug where the game would freeze when trying to restart the stage scene in a package script while an enemy boss scene hasn't finished loading.
|
||||
- Fixed a rare crash with script object deletion.
|
||||
|
||||
1.30a:
|
||||
Changes:
|
||||
- Greatly improved the speed of the script code interpreter.
|
||||
- Made the maximum sizes of render targets respect the Direct3D device capabilities.
|
||||
- EV_REQUEST_LIFE now accepts all types of values (will be converted to reals).
|
||||
- In case that an array was passed (multiple bosses), each elements will also be converted to reals.
|
||||
- Direct3D device capabilities will now be checked at the start, and the user will be notified if they are insufficient to run the engine.
|
||||
- Changed the default render priority of items to 40. (Previously 60, what the fuck mkm)
|
||||
- Changed the behaviour of resource pre-loading. (LoadTexture, LoadMesh, etc.)
|
||||
- Loaded resources are no longer script-dependent, they will remain loaded even if the script that loaded them has been closed.
|
||||
- Changed the arguments of ObjPatternShot_AddTransform/ObjPatternShot_SetTransform.
|
||||
- Additionally, the above two functions now take in varargs.
|
||||
- Improved GetObjectDistance.
|
||||
- Introduced the ability to use StartScript a second time without having to use LoadScript again.
|
||||
- Renamed ObjSound_SetRestartEnable to ObjSound_SetResumeEnable.
|
||||
- Usage unchanged.
|
||||
- Rearranged the arguments of ObjPatternShot_Add/SetTransform.
|
||||
- ObjFile_Store now use the source file's original line endings.
|
||||
- Binary, octal, and hexadecimal number literals now default to int.
|
||||
- Changed the usage of the function "resize".
|
||||
- Improved the speed of boss scene scripts loading.
|
||||
Additions:
|
||||
- Many new additions to the scripting language.
|
||||
- See "New Scripting Features".
|
||||
- Added GetObjectDistanceSq and GetObjectDeltaAngle.
|
||||
- Added an overload each for GetCommonData and GetAreaCommonData.
|
||||
- Added GetSystemTimeMilliS and GetSystemTimeNanoS.
|
||||
- Added SetInvalidPositionReturn, a function for changing the "invalid position" from (0, 0).
|
||||
- Added functions for pointer-based common data access:
|
||||
- LoadCommonDataValuePointer
|
||||
- LoadAreaCommonDataValuePointer
|
||||
- IsValidCommonDataValuePointer
|
||||
- SetCommonDataPtr
|
||||
- GetCommonDataPtr
|
||||
- Added IsVertexShaderSupported.
|
||||
- Added the ability to set the read offset of .dat archives.
|
||||
- Added new ObjPatternShot transforms:
|
||||
- TRANSFORM_ADDPATTERN_B1
|
||||
- TRANSFORM_ADDPATTERN_B2
|
||||
- Renamed TRANSFORM_ADDPATTERNA1 to TRANSFORM_ADDPATTERN_A1
|
||||
- Renamed TRANSFORM_ADDPATTERNA2 to TRANSFORM_ADDPATTERN_A2
|
||||
- Added new ObjPatternShot patterns: (thanks to Naudiz)
|
||||
- PATTERN_LINE
|
||||
- PATTERN_ROSE
|
||||
- Added back in script source caching, plus the ability to remove a script from the cache.
|
||||
- Added ObjEnemyBossScene_SetUnloadCache.
|
||||
- Added a "Cached Scripts" panel to the Script tab of the LogWindow.
|
||||
- Added a "CPU Time" column to the Script tab of the LogWindow.
|
||||
- Added a "Shader" tab to the LogWindow.
|
||||
- Added an overload for ColorARGBToHex.
|
||||
- Added ObjItem_SetPositionRounding.
|
||||
- Added new maths functions:
|
||||
- log2
|
||||
- logn
|
||||
- erf
|
||||
- gamma
|
||||
- distance
|
||||
- distancesq
|
||||
- dottheta
|
||||
- rdottheta
|
||||
- cbrt
|
||||
- AngularDistance
|
||||
- AngularDistanceR
|
||||
- Rotate2D
|
||||
- Rotate3D
|
||||
- Added count_rand, count_prand, reset_count_rand, and reset_count_prand.
|
||||
- Added Interpolate_X and Interpolate_X_PackedInt.
|
||||
- Added GetScriptStatus.
|
||||
- STATUS_LOADING
|
||||
- STATUS_LOADED
|
||||
- STATUS_RUNNING
|
||||
- STATUS_PAUSED
|
||||
- STATUS_CLOSING
|
||||
- STATUS_INVALID
|
||||
- Added implicit array casting for initialization, assignment, and concatenation.
|
||||
- Only applicable for int[] <-> real[] <-> null
|
||||
- Added array casting functions:
|
||||
- as_int_array
|
||||
- as_real_array
|
||||
- as_bool_array
|
||||
- as_char_array
|
||||
- as_x_array
|
||||
- Added StringFormat, a string formatting function in the style of C's sprintf.
|
||||
- Added IsIntersected_Circle_RegularPolygon and IsIntersected_Circle_Ellipse.
|
||||
- Added new array functions: contains, insert.
|
||||
- Added ObjRender_SetEnableDefaultTransformMatrix.
|
||||
- Added ObjPrim_GetTexture.
|
||||
Bug fixes:
|
||||
- Fixed LoadMesh crashing the engine.
|
||||
- Fixed ObjCol_GetListOfIntersectedShotID incorrectly expecting only 1 argument.
|
||||
- Fixed a bug where whitespaces in parameter lists in text object tags are incorrectly parsed.
|
||||
- Fixed a bug where the "Show LogWindow" option would disappear if the game was set to start in (borderless) fullscreen mode.
|
||||
- Fixed the sound streamer behaving incorrectly when playing a .wav file larger than 1MB a second time.
|
||||
- Fixed a bug where ObjSound_Seek would be ineffectual if used when the sound isn't playing or within 2 frames after being played.
|
||||
- Fixed the Y hitbox scale not affecting the hitboxes of laser objects.
|
||||
- Fixed the LogWindow not able to output logs to file.
|
||||
- Fixed a bug where penetrating player shots may randomly not correctly collide with enemy hitboxes and mess up replays.
|
||||
- Fixed the engine crashing if the stage scene is quit and there is an ObjPatternShot, whose parent is a dead boss object, that wasn't manually deleted.
|
||||
- Fixed the LogWindow's Log tab not horizontally scrolling the newest line into view.
|
||||
- Fixed a bug with the remainder operation where using (kn % -n) or (-kn % n) where (k) is an integer results in (-n).
|
||||
- Fixed crash bugs with ternary statements in the following cases:
|
||||
- let a = [condition ? 0 : 1];
|
||||
- a[condition ? 0 : 1] = 100;
|
||||
- Fixed a package crash that happens when LoadScriptInLoadThread loads a stage script that contains a parser error.
|
||||
- Fixed a bug that made variable-overshadowing a function throw a parser error.
|
||||
- let power = 100; //This is possible again.
|
||||
- Fixed a bug where an ObjMove would lag for one frame after applying its last AddPattern transform.
|
||||
- Fixed a "feature" where a multidimensional array can host values of different types.
|
||||
- Fixed a bug where Windows' list-searching feature was interfering with key remapping in the config.
|
||||
- Fixed a bug where empty lines in text file object are skipped over in some devices.
|
||||
- Fixed ObjFileT_SplitLineText having an incorrect return value if the object is invalid.
|
||||
- Fixed an issue where the engine's default 3D render shader and 3D particle list shader don't work on AMD graphics cards.
|
||||
- Also updated the shader source files in the sample scripts with this fix.
|
||||
- Fixed a null pointer read crash bug during engine initialization.
|
||||
- Fixed a bug where short-circuited logical expressions would not convert to boolean.
|
||||
|
||||
1.21a:
|
||||
- Fixed MatrixMultiply and MatrixDivide functioning incorrectly.
|
||||
- Added MatrixTransformVector for transforming a Vector3 by a transformation matrix.
|
||||
- Added a hex overload for SetFogParam.
|
||||
- Added a floored division operation. ("~/" and "~/=")
|
||||
- Added "resize", a function for resizing arrays.
|
||||
- Modified the functionality of the array slice operation and operator.
|
||||
- Upper slice bound is automatically capped at the array's size.
|
||||
- More options for text object tags.
|
||||
- Increased the smoothness of rendered fonts.
|
||||
- Fixed SetShotIntersectionCircle and SetShotIntersectionLine not working.
|
||||
- Fixed a memory leak issue that was causing the "too many open files" error message.
|
||||
- Using ObjRender_SetAlpha on a 2D sprite list object whose vertices were closed will now have an alpha-multiply effect.
|
||||
- Optimizations.
|
||||
|
||||
1.20b:
|
||||
- Fixed a bug that caused for loops using new variables to not function correctly.
|
||||
- Fixed a bug that caused all GetColor functions to return incorrect values. (Including GetShotDataInfoA1)
|
||||
- Fixed a bug where off-centered player hitboxes would behave strangely.
|
||||
- Fixed the game crashing on script end/retry. (How the fuck did I not notice this before 1.20a release bloody hell)
|
||||
- Added ObjShot_SetSpinAngularVelocity.
|
||||
|
||||
1.20a:
|
||||
- Reworked some math calculations. SIMD instructions are utilized.
|
||||
- A legacy version will also be provided in case your CPU do not support vectorization.
|
||||
- The vectorized version requires the following instruction sets:
|
||||
- SSE
|
||||
- SSE2
|
||||
- SSE3
|
||||
- SSE4.1
|
||||
- Generally, you should be able to run it unless your PC is from 30000BC or you're using a literal potato.
|
||||
- Added a native hitbox visualization mode.
|
||||
- Improved the line-circle intersection algorithm. New algorithm behaves like a circle-polygon intersection.
|
||||
- Overloaded ObjMove_SetDestAtFrame, where movement interpolation mode can be specified.
|
||||
- Fixed a bug where the graze count obtained via GetGraze() may desync with the one obtained via EV_GRAZE's event argument.
|
||||
- Fixed a bug where ObjText_GetTotalWidth/Height may break the font tag.
|
||||
- Fixed a bug where font text tag properties do not get reset after using ObjText_SetText.
|
||||
- Obj_GetValue will now ACTUALLY NOT crash the game if the requested value does not exist.
|
||||
- Renamed the "Obj_[..]ValueR" function series to "Obj_[..]ValueI".
|
||||
- Removed the constant 'pi'. Please use 'M_PI' instead.
|
||||
- Changed error messages of some default functions to be more descriptive to aid debugging.
|
||||
- Greatly improved script variable allocation.
|
||||
- Added a concatenate-assign operator. (~=)
|
||||
- Added bitwise operators. (~, &, |, ^^)
|
||||
- Int values can now be declared with a suffix 'i' or 'I'.
|
||||
- Static type declaration is planned.
|
||||
- Added implicit type casting in default script operations, including comparison and assignment.
|
||||
- Optimized the process of calling default constants.
|
||||
- The default constants SCREEN_WIDTH and SCREEN_HEIGHT will now change to reflect the settings in th_dnh.def.
|
||||
- Some functions will now return int values rather than real values.
|
||||
- Fixed a bug where itoa, atoi, and IntToString would underflow if the input is larger than 2^31-1. (New limit is 2^63-1)
|
||||
- Fixed a bug where the 3D viewport would get stretched out based on the size of the STG frame.
|
||||
- Made the game no longer freeze and crash after Alt-Tab'ing out of true fullscreen mode or after waking the desktop from sleep.
|
||||
- Pseudo-fullscreen mode now stops Windows from drifting off to Dreamland.
|
||||
- Fixed a mistake involving matrix multiplication order in the internal shader for particle list objects.
|
||||
- Removed CollectItemsByType and SetItemIntersectionRadius.
|
||||
- Added new event, EV_COLLECT_ITEM, which triggers when the item starts to move towards the player.
|
||||
- Fixed a bug where ObjShot_SetIntersectionScale[XY] does not scale the position offset.
|
||||
- If ObjFile_Open/ObjFile_OpenNW fails, the reason for failure will now be written to the LogWindow.
|
||||
- The ObjFileB_Read[...] functions no longer throw an error when attempting to read past EOF.
|
||||
- ObjFileB_GetLastRead can be used to obtain the amount of bytes read in the last read operation.
|
||||
- Various optimizations.
|
||||
- Un-Utilized UPX Executable Packer to not-reduce file size.
|
||||
|
||||
1.10c:
|
||||
- Fixed a bug in the UserShotData where rect can override animation_data.
|
||||
- Fixed a bug in the UserShotData where collision did not work at all.
|
||||
- Added functionality to change the color of the delay cloud per-shot.
|
||||
- Fixed a parser bug with nested single-lined statements.
|
||||
- Fixed a rare bug where object IDs may get duplicated when objects are created in rapid succession.
|
||||
- Fixed a bug where the default charset for some fonts are incorrectly determined.
|
||||
- Utilized UPX Executable Packer to reduce file size.
|
||||
|
||||
1.10b:
|
||||
- Fixed bugs with logical and ternary statements.
|
||||
- Improved data packing of common data files. (Files saved with 1.10a are now incompatible.)
|
||||
- Bug fixes and optimizations.
|
||||
|
||||
1.10a:
|
||||
- Fixed some random and function-related crashes.
|
||||
- RenderToTextureXX alpha fix ported+modified from th_dnh_woo.
|
||||
- Replaced ObjLaser_SetGrazeInvalidFrame with ObjShot_SetGrazeInvalidFrame.
|
||||
- Alpha channel blending now exists in all blend modes except BLEND_NONE and BLEND_ADD_RGB.
|
||||
- Fixed a bug where NotifyEvent and SetScriptArgument could not reach package-level scripts when called from a stage-level script.
|
||||
- Event arguments will no longer be overwritten when notifying nested events inside @Event.
|
||||
- Utilized variadic argument counts for the functions in the NotifyEvent series.
|
||||
- Utilized variadic argument counts for the WriteLog function.
|
||||
- Added transform functions for ObjPatternShot and relevant sample scripts, for former and current ECL modders.
|
||||
- Please note that they may not be able to fully emulate ECL's behaviours.
|
||||
- Added functionality to customize delay clouds.
|
||||
- Added an option to use true fullscreen mode in the config.
|
||||
- "Operation-assign" operators (+=, -=, ++, etc.) now work on indexed arrays.
|
||||
- Given: a = [1, 2, 3]
|
||||
- a[0]++ = [2, 2, 3]
|
||||
- a[2] *= 3 = [1, 2, 9]
|
||||
- a += [5, 6] = [6, 8, 3]
|
||||
- Given: b = [[1, 2], [3, 4], [5, 6]]
|
||||
- b[0] += 3 = [[4, 5], [3, 4], [5, 6]]
|
||||
- b[2]-- = [[1, 2], [3, 4], [4, 5]]
|
||||
- Array indexing/slicing operations now automatically truncate indices.
|
||||
- Array slicing operation can now reverse an array.
|
||||
- Given: a = [10, 12, 14, 16, 18, 20]
|
||||
- a[0..3] = [10, 12, 14]
|
||||
- a[3..0] = [14, 12, 10]
|
||||
- a[1..0] = [10]
|
||||
- a[6..2] = [20, 18, 16, 14]
|
||||
- a[2..2] = []
|
||||
- Added ternary statements.
|
||||
- NO_CHANGE can now be used in the ObjMove_AddPatternBX functions.
|
||||
- ObjMove_SetAngle and ObjMove_SetSpeed can now be used on B-pattern objects.
|
||||
- Line-line intersection is now properly implemented.
|
||||
- IsIntersected_Line_Circle can now be used in package-level scripts.
|
||||
- Added a particle renderer object (ObjParticleList) and new relevant sample scripts.
|
||||
- Added support for vertex indexing.
|
||||
- Added support for basic directional lighting.
|
||||
- Improved vertex shader support, and added sample scripts for demonstration.
|
||||
- Fixed underflowing and overflowing issues with SetColor/SetAlpha functions.
|
||||
- Fixed a bug where ObjText_SetFontCharacterSet doesn't work at all.
|
||||
- Added more options to the [font] text tag.
|
||||
- Available tag options:
|
||||
- reset
|
||||
- Resets the text to its original settings. Present in vanilla ph3 as "clear".
|
||||
- size
|
||||
- Adjusts font size. Unchanged from vanilla ph3.
|
||||
- ox/oy
|
||||
- Adjusts position offset.
|
||||
- it
|
||||
- Toggles italic. (true/false or 1/0)
|
||||
- wg
|
||||
- Adjusts font weight.
|
||||
- br/bg/bb
|
||||
- Adjusts font bottom color.
|
||||
- tr/tg/tb
|
||||
- Adjusts font top color.
|
||||
- or/og/ob
|
||||
- Adjusts font border color.
|
||||
- bc
|
||||
- Adjusts font bottom color as an (r, g, b) list.
|
||||
- tc
|
||||
- Adjusts font top color as an (r, g, b) list.
|
||||
- oc
|
||||
- Adjusts font border color as an (r, g, b) list.
|
||||
- Added more options to the [ruby] text tag.
|
||||
- Available tag options:
|
||||
- rb
|
||||
- Sets text. Unchanged from vanilla ph3.
|
||||
- rt
|
||||
- Sets ruby(furigana) text. Unchanged from vanilla ph3.
|
||||
- sz
|
||||
- Adjusts the ruby text's font size.
|
||||
- wg
|
||||
- Adjusts the ruby text's font weight.
|
||||
- ox
|
||||
- Adjusts the ruby text's left margin.
|
||||
- op
|
||||
- Adjusts the ruby text's side pitch.
|
||||
- Improved spacing of ruby text.
|
||||
- ObjFileT now properly reads from and writes to UTF-8 text files.
|
||||
- ObjFile_OpenNW now allows both reading and writing, unless the file was stored in a .dat archive, in which case all write functions will fail.
|
||||
- Pulled the plug on Shift-JIS support in favour of proper Unicode (UTF-8 and UTF-8-BOM) handling.
|
||||
- Better Metasequoia mesh support, and temporarily(?) suspended Elfreina mesh support. Blender .obj mesh support is planned.
|
||||
- The player object will now set its own movement speed and angle according to user key input.
|
||||
- Collecting user-defined items now notify EV_GET_ITEM to the player script.
|
||||
- Minimum custom window size is reduced to 320*240.
|
||||
- GetShotDataInfoA1 no longer throws an error upon receiving an invalid graphic ID, and will instead return default values.
|
||||
- Fixed a bug where the right and bottom source rect set with ObjSprite3D_SetSourceDestRect are 1 greater than expected.
|
||||
- Improved loading of .wav files.
|
||||
- Attempted to fix a bug where multiple sound objects simultaneously playing the same sound file (>1MB .wav, .ogg, or .mp3) would display strange behaviours.
|
||||
- Improved the precision of ObjSound_GetWavePosition, and fixed an issue where ObjSound_GetTotalLength would work incorrectly with .ogg files.
|
||||
- Added bitwise operators.
|
||||
- Greatly improved the LogWindow's Script panel.
|
||||
- Added a text showing the available video memory in the LogWindow's Texture panel.
|
||||
- Added a text showing the used RAM and CPU in the LogWindow's Info panel.
|
||||
- Enforced semicolons before closing braces.
|
||||
- Removed ObjShot_AddShotA1/2.
|
||||
- Various optimizations.
|
||||
|
||||
1.00a:
|
||||
- Multidimensional array assignments are now possible.
|
||||
- Arithmetic operations on array(s) are possible. (Left-right order is important)
|
||||
- [1, 2, 3] + 5 = [6, 7, 8]
|
||||
- [5, 5, 1] * 2 = [10, 10, 2]
|
||||
- [2, 3, 4] - [7, 0, 2] = [-5, 3, 1]
|
||||
- [10, 10, 10] / [5, 2] = [2, 5, 10]
|
||||
- [2, 3] % [4, 2, 1, 6] = [2, 1]
|
||||
- 4 + [2, 3, 6, 2] = 8
|
||||
- Added support for multiple-pass shaders.
|
||||
- Shot and item objects no longer respond to changes in X and Y angles.
|
||||
- Bullet limit of 8192 for performance reasons.
|
||||
- Multiple hitbox support for shot objects has been removed.
|
||||
- Vertex shader support.
|
||||
- Much smaller replay files.
|
||||
- Added an option to specify the skip mode speed in th_dnh.def.
|
||||
- Obj_GetValue will not crash the game if the requested value does not exist.
|
5
docs/GitHub Repository.url
Normal file
5
docs/GitHub Repository.url
Normal file
|
@ -0,0 +1,5 @@
|
|||
[{000214A0-0000-0000-C000-000000000046}]
|
||||
Prop3=19,11
|
||||
[InternetShortcut]
|
||||
IDList=
|
||||
URL=https://github.com/Natashi/Touhou-Danmakufu-ph3sx-2
|
605
docs/Naudiz's Style Guide.txt
Normal file
605
docs/Naudiz's Style Guide.txt
Normal file
|
@ -0,0 +1,605 @@
|
|||
Preamble:
|
||||
|
||||
The following keywords are used to clarify the importance of each convention: MUST, SHOULD, MAY, SHOULD NOT, MUST NOT.
|
||||
|
||||
In the code examples below, the sequence "// ..." (two slashes, one space, three full stops) denotes a line where, in most cases, more code should be written.
|
||||
However, such code is unnecessary for the purposes of each example.
|
||||
|
||||
Comments from the writer that do not necessarily dictate style guidelines are preceded by the sequence "// NAZ: ".
|
||||
|
||||
1: Identifiers
|
||||
|
||||
1.1: Variables and Constants
|
||||
|
||||
Note:
|
||||
|
||||
Variables and constants SHOULD be declared with explicit type keywords (float, int, bool, char, string, etc.), unless the type is unknown,
|
||||
in which case either "let" or "var" is used. These keywords are interchangeable, but the scripter MUST decide on one to use consistently.
|
||||
|
||||
Variables MUST be written using camelCase*, while constants MUST use SCREAMING_SNAKE_CASE.
|
||||
Related identifiers SHOULD share the leading parts of their names for alphabetization purposes.
|
||||
|
||||
In cases where variables have short names or are uninitialized, multiple variables MAY be declared on the same line, separated by commas.
|
||||
They SHOULD be of the same type, so fewer keywords are necessary.
|
||||
|
||||
*If necessary, a prefix or suffix MAY be added to a variable in the snake_case style.
|
||||
|
||||
DO:
|
||||
|
||||
float posX, posY;
|
||||
const int BOSS_RUMIA = 0;
|
||||
const int BOSS_CIRNO = 1;
|
||||
|
||||
DON'T:
|
||||
|
||||
let xPos;
|
||||
let yPos;
|
||||
const RUMIA_BOSS = 0, CIRNO_BOSS = 1;
|
||||
|
||||
|
||||
1.1.1: Local Variables
|
||||
|
||||
Variables defined within a local scope, such as inside a function or task, MUST use camelCase without any underscores.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
function<void> DoSomething()
|
||||
{
|
||||
float posX, posY;
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.1.2: Global Variables
|
||||
|
||||
Variables defined globally in any script SHOULD be denoted with a leading underscore.
|
||||
This is similar to the notation used for tasks, but with camelCase instead of PascalCase.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
int _objEnemy;
|
||||
int _objPlayer;
|
||||
|
||||
@Initialize
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.1.3: Parameters
|
||||
|
||||
Function and task parameters SHOULD be denoted with a trailing underscore.
|
||||
|
||||
Parameters SHOULD be declared with type keywords, or either "let" or "var" if unknown.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
function<void> DoSomethingElse(int foo_, float bar_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.1.4: Iterators
|
||||
|
||||
Iterator variables declared in for-loops, ascent-loops, and descent-loops SHOULD be named lowercase letters of the alphabet starting with "i",
|
||||
progressing to the next letter for each nested loop. This convention MAY be bypassed if more semantic information is necessary.
|
||||
|
||||
Iterator variables declared in for-each-loops SHOULD have single-word names prefixed with "i".
|
||||
|
||||
Fun fact: It is possible to add a second iterator to a for-each-loop, which is listed before the first and iterates through the array's indices (starting from 0) instead of its elements.
|
||||
This variable SHOULD follow the same rules as those declared in for-loops.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ascent (j in 0 .. 3) {
|
||||
descent (k in 0 .. 4) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for each (iObj in arrObj) {
|
||||
// ...
|
||||
}
|
||||
|
||||
for each ((i, iObj) in arrObj) {
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.1.5: Constants
|
||||
|
||||
As mentioned previously, constants MUST use SCREAMING_SNAKE_CASE. All constants SHOULD be defined in a dedicated constant library.
|
||||
Numeric constants SHOULD be integers instead of float numbers (denoted in decimal literals by appending the character "i" at the end,
|
||||
but this is not necessary if the constant type is explicitly defined).
|
||||
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
const int PLAYER_REIMU = 0;
|
||||
const int PLAYER_MARISA = 1;
|
||||
const int PLAYER_SAKUYA = 2;
|
||||
const int PLAYER_SANAE = 3;
|
||||
|
||||
|
||||
|
||||
1.2: Functions, Tasks, and Subroutines
|
||||
|
||||
Note:
|
||||
|
||||
|
||||
Function, task, and subroutine names all MUST use PascalCase to differentiate them from other identifiers.
|
||||
The root of the identifier name SHOULD begin with a verb.
|
||||
|
||||
// NAZ: The "Is...Exists" structure is Engrish through and through, but I use it for consistency with built-in function names.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
function<void> DoSomething()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
function<int> GetSomething(int foo_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
function<void> SetSomething(int foo_, float bar_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
function<bool> IsSomethingExists(int foo_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.2.1: Functions
|
||||
|
||||
Functions SHOULD be declared with explicit type keywords in angle brackets, unless the type is unknown or variant.
|
||||
|
||||
Function names MUST use PascalCase with no underscores.*
|
||||
Function calls require trailing parentheses, even when there are no arguments.
|
||||
|
||||
*Excluding cases where there is a necessary prefix or suffix denoting important information, such as object type.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
function<void> DoSomething()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
function<void> DoSomethingElse(bool foo_, float bar_)
|
||||
{
|
||||
DoSomething();
|
||||
// ...
|
||||
}
|
||||
|
||||
function<void> Obj_DoSomething(int obj_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
function<void> DoSomething_Obj_Obj(int obj1_, int obj2_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.2.2: Tasks
|
||||
|
||||
Task names SHOULD use one of the following styles (and consistently): PascalCase with a leading underscore, OR PascalCase with a leading uppercase T.
|
||||
The same rules about affixes and parentheses that apply to functions apply here.
|
||||
|
||||
// NAZ: I like to treat my tasks as private routines, so often times you'll see me create a "public" function that calls task nested inside.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
task _RenderPlayer(int id_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
task _RenderPlayer_Reimu()
|
||||
{
|
||||
_RenderPlayer(PLAYER_REIMU);
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
1.2.3: Subroutines
|
||||
|
||||
Subroutines MUST use PascalCase, and SHOULD include a trailing underscore. Parentheses MAY be used.
|
||||
|
||||
It is possible to use the at sign (@) in place of the "sub" keyword, but scripters SHOULD NOT do so, to prevent confusion with built-in routines (@Initialize, @MainLoop, @Finalize, etc.).
|
||||
|
||||
// NAZ: I don't think I've ever used one of these, lol. I came up with the underscore rule on the fly.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
sub DoSomethingDifferent_
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
2: Whitespace
|
||||
|
||||
Note:
|
||||
|
||||
For the sake of consistency, spaces SHOULD be used instead of tabs in ALL cases.
|
||||
The default tab is equivalent to 4 spaces; any decent editor should have an option to insert spaces upon pressing the tab key.
|
||||
|
||||
2.1: Operators
|
||||
|
||||
Expressions and statements consisting of one or more literals and/or identifiers MUST employ one space on both sides of all binary and ternary operators
|
||||
(= +, -, *, /, ~/, %, ^, ~, +=, -=, *=, /=, ~/=, %=, ^=, ~=, ==, !=, >, <, >=, <=, &&, ||, &, |, ^^, .., ?, :).
|
||||
|
||||
Expressions and statements consisting of an identifier and a unary operator (!, ++, --) MUST NOT employ a space between the operator and operand.
|
||||
|
||||
DO:
|
||||
|
||||
float someNum = 6 * 9 + 4 / 20 - 6 % 66;
|
||||
someNum++;
|
||||
|
||||
DON'T:
|
||||
|
||||
float someNum = 6*9+4/20-6%66;
|
||||
someNum ++;
|
||||
|
||||
// NAZ: I will send you to the Shadow Realm if you don't put spaces in between your operators like in the "DON'T" example. It's entirely unreadable for me.
|
||||
|
||||
2.2: Variables and Constants
|
||||
|
||||
Variable and constant declaration and assignment statements MUST employ one space between the keyword (let, var, const) and the identifier,
|
||||
and on both sides of the assignment operator (=) if applicable.*
|
||||
|
||||
As stated previously, if identifiers have short names or are uninitialized, their declarations MAY go on the same line, separated by commas and followed by spaces.
|
||||
|
||||
*Additional spaces MAY be used to vertically align the operator and right-hand side of each statement in a group of statements. See the example.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
const int BGM_TITLE = 0;
|
||||
const int BGM_1_ROAD = 1;
|
||||
const int BGM_1_BOSS = 2;
|
||||
const int BGM_GAMEOVER = 3;
|
||||
|
||||
|
||||
2.3: Functions, Tasks, and Subroutines
|
||||
|
||||
Function, task, and subroutine definitions MUST employ one space between the keyword (function, task, or sub) and the identifier,
|
||||
and NO space between the identifier and the parentheses, differently from flow control statements.
|
||||
Parameters contained inside the parentheses MUST employ one space between each identifier, i.e. after each comma.
|
||||
|
||||
The opening and closing braces of a function, task, or subroutine block MUST go on their own lines, and all lines in between them MUST be indented.
|
||||
There MUST also be an empty line following each closing brace.
|
||||
The same rules also apply to @Initialize, @MainLoop, @Event, @Finalize, and @Loading.
|
||||
|
||||
// Natashi: I don't like placing opening curly braces on newlines. *turns half of your body into pizza dough*
|
||||
|
||||
Function, task, and subroutine invocations MUST NOT include a space between the identifier and parentheses, if applicable.
|
||||
Like parameters, arguments MUST be separated by whitespace, i.e. after each comma.
|
||||
|
||||
Function and task arguments MAY span several indented lines for readability purposes.
|
||||
There SHOULD be an empty space following each multi-line function call, unless it precedes a closing brace or parenthesis.
|
||||
|
||||
// NAZ: This is only really applicable if the arguments get unbearably long, though. The example just demonstrates it just because.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
@Initialize
|
||||
{
|
||||
DoSomething(
|
||||
true,
|
||||
1,
|
||||
1.1,
|
||||
'e',
|
||||
"abc"
|
||||
);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
function<void> DoSomething(bool foo_, int bar_, float baz_, char qux_, string quux_)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
2.4: Flow Control Statements
|
||||
|
||||
Flow control statements MUST employ whitespace on both sides of each keyword
|
||||
(if, else, loop, while, ascent, descent, in, for, each, alternative, case, others, switch, default, local, yield, break, continue),
|
||||
unless said keyword by itself is a statement (yield, break, continue), in which case it is simply terminated with a semicolon.
|
||||
|
||||
For conditionals and loops, the opening curly brace SHOULD go on the same line as the preceding keyword or closing parenthesis, following a space.*
|
||||
The closing curly brace SHOULD go on its own line, except in the case of "else" and "else if" which SHOULD be written after a space following the closing brace.
|
||||
Loops and conditional structures SHOULD be followed by an empty line.
|
||||
|
||||
For for-loops, each statement ending in a semicolon MUST be followed by a space, i.e. the first and second.
|
||||
The second and third statements may be omitted, in which case a space SHOULD be used instead.
|
||||
When statements are combined with commas, there MUST be a space after each of them.
|
||||
|
||||
*Conditionals and loops containing a single statement terminated with a semicolon MAY be written without curly braces,
|
||||
in which case they SHOULD be written on the same line as the rest of the statement, following a space.
|
||||
Nested conditionals and loops may also be written without curly braces, provided that there is only one semicolon-terminated statement within it.
|
||||
Alternative cases written this way MAY use additional spaces to align their contents.
|
||||
|
||||
EXAMPLE 1 (VERBOSE):
|
||||
|
||||
for (int i = 1, j = 2; i <= 10; i++, j--) {
|
||||
alternative (i)
|
||||
case (1) {
|
||||
WriteLog("i is 1!", "j is 2!");
|
||||
}
|
||||
case (2) {
|
||||
WriteLog("i is 2!", "j is 1!");
|
||||
}
|
||||
others {
|
||||
WriteLog("I can't count that high!");
|
||||
}
|
||||
|
||||
if (i >= 3) {
|
||||
break;
|
||||
} else {
|
||||
loop (5) {
|
||||
yield;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXAMPLE 2 (CONCISE):
|
||||
|
||||
for (int i = 1, j = 2; i <= 10; i++, j--) {
|
||||
alternative (i)
|
||||
case (1) WriteLog("i is 1!", "j is 2!");
|
||||
case (2) WriteLog("i is 2!", "j is 1!");
|
||||
others WriteLog("I can't count that high!");
|
||||
|
||||
if (i >= 3) break;
|
||||
else loop (5) yield;
|
||||
}
|
||||
|
||||
// NAZ: With "wait" being built-in there's no use case for "loop (n) yield;".
|
||||
// NAZ: I simply wanted to demonstrate nested structures and how they can be shortened.
|
||||
|
||||
2.5: Arrays
|
||||
|
||||
Arrays elements MUST be separated by whitespace, i.e. after each comma.
|
||||
|
||||
Multidimensional or otherwise verbose arrays MAY be written across several indented lines.
|
||||
The initial opening square brace MUST go on the same line as the operator that precedes it.
|
||||
The new lines and indenting SHOULD be consistent throughout each dimension of the array.
|
||||
There SHOULD be an empty space following each multi-line array, unless it precedes a closing brace or parenthesis.
|
||||
|
||||
For performance reasons, arrays SHOULD be indexed as infrequently as possible.
|
||||
If only one element is needed, storing it in a variable is recommended.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
int[] arrSmall = [1, 2, 3];
|
||||
int[][] arrBig = [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6, 7],
|
||||
[8, 9, 10, 11, 12]
|
||||
];
|
||||
|
||||
int[][][] arrBigger = [
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5, 6, 7],
|
||||
], [
|
||||
[8, 9, 10, 11, 12],
|
||||
[13, 14, 15, 16, 17, 18],
|
||||
[19, 20, 21, 22, 23, 24, 25],
|
||||
]
|
||||
];
|
||||
|
||||
int numSmall = arrSmall[2];
|
||||
int numBig = arrBig[2][4];
|
||||
int numBigger = arrBigger[1][2][6];
|
||||
|
||||
|
||||
|
||||
3: Organization
|
||||
|
||||
3.1: Script Structure
|
||||
|
||||
All scripts SHOULD have their sections organized in the following order:
|
||||
|
||||
1. Headers (#TouhouDanmakufu, #ScriptVersion*, #Title, #Text, #System, #Background, #BGM)
|
||||
2. #include directives
|
||||
3. Global variables
|
||||
4. Predefined routines (@Initialize, @Event, @MainLoop, @Finalize, @Loading)
|
||||
5. Script-specific routines
|
||||
|
||||
*The #ScriptVersion header can only take one possible argument (3), and SHOULD be omitted altogether.
|
||||
|
||||
EXAMPLE:
|
||||
|
||||
#TouhouDanmakufu[Stage]
|
||||
#Title["Example Stage"]
|
||||
#Text["An example of a stage script."]
|
||||
#System["script/script_system.dnh"]
|
||||
|
||||
#include "script/include_stg.dnh"
|
||||
|
||||
int _idScript;
|
||||
|
||||
@Initialize
|
||||
{
|
||||
_idScript = GetOwnScriptID();
|
||||
_Main();
|
||||
}
|
||||
|
||||
@MainLoop
|
||||
{
|
||||
yield;
|
||||
}
|
||||
|
||||
@Finalize
|
||||
{
|
||||
WriteLog("Game over!");
|
||||
}
|
||||
|
||||
task _Main()
|
||||
{
|
||||
while (GetPlayerState() != STATE_END) yield;
|
||||
CloseScript(_idScript);
|
||||
}
|
||||
|
||||
|
||||
3.2: Included Files
|
||||
|
||||
As a preface, what the #include directive does is tell the engine to copy the contents of a given text file and paste them into the script, replacing the #include directive.
|
||||
If a file has already been included in the script, it will be skipped.
|
||||
|
||||
To reduce the amount of boilerplate in each script file, the scripter SHOULD create files with the express purpose of including several other files, ideally in a hierarchical manner.
|
||||
|
||||
DO:
|
||||
// In include_main.dnh
|
||||
|
||||
#include "./lib_main.dnh"
|
||||
#include "./lib_const.dnh"
|
||||
#include "./lib_math.dnh"
|
||||
#include "./lib_render.dnh"
|
||||
#include "./lib_event.dnh"
|
||||
|
||||
// In include_stg.dnh
|
||||
|
||||
#include "./include_main.dnh"
|
||||
#include "./lib_stg.dnh"
|
||||
#include "./lib_move.dnh"
|
||||
#include "./lib_shot.dnh"
|
||||
#include "./lib_enemy.dnh"
|
||||
|
||||
// In include_boss.dnh
|
||||
|
||||
#include "./include_stg.dnh"
|
||||
#include "./lib_boss.dnh"
|
||||
#include "./lib_anim.dnh"
|
||||
#include "./lib_spell.dnh"
|
||||
|
||||
// In the main script
|
||||
|
||||
#TouhouDanmakufu[Single]
|
||||
// ...
|
||||
|
||||
#include "script/include_boss.dnh"
|
||||
|
||||
@Initialize
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
DON'T:
|
||||
|
||||
// In the main script
|
||||
|
||||
#TouhouDanmakufu[Single]
|
||||
// ...
|
||||
|
||||
#include "./lib_main.dnh"
|
||||
#include "./lib_const.dnh"
|
||||
#include "./lib_math.dnh"
|
||||
#include "./lib_render.dnh"
|
||||
#include "./lib_event.dnh"
|
||||
#include "./lib_stg.dnh"
|
||||
#include "./lib_move.dnh"
|
||||
#include "./lib_shot.dnh"
|
||||
#include "./lib_enemy.dnh"
|
||||
#include "./lib_boss.dnh"
|
||||
#include "./lib_anim.dnh"
|
||||
#include "./lib_spell.dnh"
|
||||
|
||||
@Initialize
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
// NAZ: These file paths assume that the script as well as all of the library files are located in the base script directory.
|
||||
// NAZ: Ideally, you should have a dedicated lib folder, possibly with subfolders corresponding to the libraries contained in each "include" file.
|
||||
|
||||
3.3: Script Routines
|
||||
|
||||
Scripts (particularly those in which danmaku is created) SHOULD call a task named _Main (or TMain, depending on your chosen style) from @Initialize.
|
||||
This task SHOULD be the ultimate source of all other script-specific routine invocations.
|
||||
|
||||
The scripter SHOULD make use of nesting for a few reasons:
|
||||
|
||||
1. To ensure that variables are limited to their intended scopes.
|
||||
2. To prevent the need to pass variables around unnecessarily via arguments.
|
||||
|
||||
EXAMPLE 1 (NON-NESTED):
|
||||
|
||||
task _Main()
|
||||
{
|
||||
float dir;
|
||||
|
||||
loop {
|
||||
dir = rand(0, 360);
|
||||
_Fire(dir);
|
||||
wait(60);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
task _Fire(float dir_)
|
||||
{
|
||||
float speed = 1;
|
||||
|
||||
loop (5) {
|
||||
Shoot(speed, dir_);
|
||||
speed++;
|
||||
wait(2);
|
||||
}
|
||||
}
|
||||
|
||||
function<void> Shoot(float speed_, float dir_)
|
||||
{
|
||||
int obj = CreateShotA1(someX, someY, speed_, dir_, someID, 15);
|
||||
ObjShot_SetDeleteFrame(obj, 180);
|
||||
}
|
||||
|
||||
EXAMPLE 2 (NESTED):
|
||||
|
||||
task _Main()
|
||||
{
|
||||
float dir;
|
||||
|
||||
loop {
|
||||
dir = rand(0, 360);
|
||||
_Fire();
|
||||
wait(60);
|
||||
}
|
||||
|
||||
task _Fire()
|
||||
{
|
||||
float speed = 1;
|
||||
|
||||
loop (5) {
|
||||
Shoot_;
|
||||
speed++;
|
||||
wait(2);
|
||||
}
|
||||
|
||||
sub Shoot_
|
||||
{
|
||||
int obj = CreateShotA1(someX, someY, speed, dir, someID, 15);
|
||||
ObjShot_SetDeleteFrame(obj, 180);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NAZ: These examples are intentionally bare-bones and only exist for the purposes of demonstrating how nesting can simplify task and function signatures and establish a sense of hierarchy.
|
||||
|
5053
docs/New Functions Documentation.txt
Normal file
5053
docs/New Functions Documentation.txt
Normal file
File diff suppressed because it is too large
Load diff
716
docs/New Scripting Features.txt
Normal file
716
docs/New Scripting Features.txt
Normal file
|
@ -0,0 +1,716 @@
|
|||
- Re: Syntax Tutorial
|
||||
|
||||
- Number literals
|
||||
|
||||
- Base literals
|
||||
|
||||
WriteLog(0b1011); //Binary literal, outputs 11
|
||||
WriteLog(0o503); //Octal literal, outputs 323
|
||||
WriteLog(0x8f62); //Hexadecimal literal, outputs 36706
|
||||
|
||||
Base literals default to integer type unless suffixed otherwise.
|
||||
|
||||
- Suffix
|
||||
|
||||
- "f" / "F"
|
||||
Forces a number literal to a float type.
|
||||
- "i" / "I"
|
||||
Forces a number literal to an integer type.
|
||||
|
||||
Example:
|
||||
WriteLog(5); //5.000000
|
||||
WriteLog(5f); //5.000000
|
||||
WriteLog(5i); //5
|
||||
WriteLog(0x5f); //95
|
||||
WriteLog(0x5fi); //95
|
||||
WriteLog(7.76); //7.760000
|
||||
WriteLog(7.76f); //7.760000
|
||||
WriteLog(7.76i); //7
|
||||
|
||||
- Digit separator
|
||||
|
||||
The "_" character can be used in number literals to aid in visibility.
|
||||
Has no effect on the resultant value.
|
||||
|
||||
WriteLog(5000000000i); //5000000000
|
||||
WriteLog(5_000_000_000i); //still 5000000000
|
||||
WriteLog(0x7f23a7e2); //2133043170
|
||||
WriteLog(0x7f23_a7e2); //still 2133043170
|
||||
|
||||
- Variables
|
||||
|
||||
- Explicit types
|
||||
|
||||
Originally, you'd declare a variable with one of these three keywords:
|
||||
- let
|
||||
- var
|
||||
- real
|
||||
All three keywords had the same effect on the declaration.
|
||||
|
||||
However, with version 1.30a, the scripting language has gone through a considerable amount of changes as follows:
|
||||
- "real" has been renamed to "float". (1.32a)
|
||||
|
||||
- You may now explicitly state the type of the variable you are declaring.
|
||||
|
||||
Example:
|
||||
int a = 700; //typeof(a) == VAR_INT
|
||||
float b = 56.243; //typeof(b) == VAR_FLOAT
|
||||
char c = '0'; //typeof(c) == VAR_CHAR
|
||||
bool d = false; //typeof(d) == VAR_BOOL
|
||||
string e = "aubergine"; //typeof(e) == VAR_STRING
|
||||
int[] f = [4i, 8]; //typeof(f) == VAR_ARRAY, ftypeof(f) == VAR_INT
|
||||
|
||||
- This does not change "let" and "var", they will still behave similarly to "auto" in C++.
|
||||
|
||||
Example:
|
||||
let a = 700i; //typeof(a) == VAR_INT
|
||||
let b = 56.243; //typeof(b) == VAR_FLOAT
|
||||
let c = '0'; //typeof(c) == VAR_CHAR
|
||||
let d = false; //typeof(d) == VAR_BOOL
|
||||
let e = "aubergine"; //typeof(e) == VAR_STRING
|
||||
let f = [4i, 8]; //typeof(f) == VAR_ARRAY, ftypeof(f) == VAR_INT
|
||||
|
||||
- You may not use "let[]" or "const[]".
|
||||
|
||||
An array type declaration may only be used with a non-auto type.
|
||||
|
||||
- Multiple variables declaration.
|
||||
|
||||
Example:
|
||||
int a, b = 7, c = 100, d; //All will be of type "int"
|
||||
const bool e = true, f = true; //All will be of type "const bool"
|
||||
let g = 56, h = true, i = 6i; //g will be "float", h will be "bool", and i will be "int"
|
||||
bool[][][] j, k; //All will be of type "bool[][][]" (3D bool array)
|
||||
|
||||
- Using "const"
|
||||
|
||||
"const" is used to declare constant variables.
|
||||
|
||||
A standalone "const" will behave like a "let".
|
||||
"const" can be prefixed or suffixed by another type.
|
||||
|
||||
Constant variables cannot be modified.
|
||||
Attempting to do so will throw a compile-time error.
|
||||
|
||||
Example:
|
||||
const a = 1;
|
||||
const let b = true;
|
||||
const string c = "xolotl";
|
||||
const int d;
|
||||
|
||||
a = 6; //ERROR
|
||||
d = 10; //ERROR
|
||||
|
||||
- Supplement for smart people
|
||||
|
||||
ph3sx script type | internal C type | size in bytes |
|
||||
----------------------------------------------------------
|
||||
int | int64_t | 8 |
|
||||
float | double | 8 |
|
||||
bool | bool | 1 |
|
||||
char | wchar_t | 2 |
|
||||
|
||||
- Scoping
|
||||
|
||||
- "local" has been deprecated. While they have not yet been completely removed, it is advisable to stop using it.
|
||||
|
||||
- But what can I use in its place?
|
||||
|
||||
Nothing.
|
||||
Literally.
|
||||
|
||||
What used to be:
|
||||
|
||||
local {
|
||||
//...
|
||||
}
|
||||
|
||||
can now be reduced to just:
|
||||
|
||||
{
|
||||
//...
|
||||
}
|
||||
|
||||
Scoping rules will still apply normally, like so:
|
||||
|
||||
let a;
|
||||
|
||||
//Only a is accessible here
|
||||
|
||||
{
|
||||
let b;
|
||||
|
||||
//a and b are both accessible here
|
||||
|
||||
{
|
||||
let c;
|
||||
|
||||
//a, b, and c are all accessible here
|
||||
}
|
||||
}
|
||||
|
||||
- Operators
|
||||
|
||||
All available script operators are listed as follows.
|
||||
They are arranged in order of precedence, highest-to-lowest.
|
||||
|
||||
1. ()
|
||||
Function call
|
||||
let c = SomeFunc(a, b);
|
||||
1. as_x()
|
||||
Type cast
|
||||
let a = as_int(x);
|
||||
let b = as_bool(56);
|
||||
1. length()
|
||||
Array length
|
||||
let a = length(x);
|
||||
let b = length([1, 2, 3]);
|
||||
1. []
|
||||
Array indexing
|
||||
let a = arr[3];
|
||||
let b = [10, 100, 1000][x];
|
||||
1. (| |)
|
||||
Absolute
|
||||
let a = (|-4|); //a == 4
|
||||
let b = (|a|); //b == 4
|
||||
1. ()
|
||||
Parentheses
|
||||
2. ^
|
||||
Power (Right-associative)
|
||||
let a = 2 ^ 4; //a == 16
|
||||
let b = 2 ^ 2 ^ 3; //b == 256
|
||||
2. [..]
|
||||
Array slice
|
||||
let x = [9, 10, 11, 12, 13];
|
||||
let a = x[0..2]; //a == [9, 10]
|
||||
let b = x[2..999]; //b == [11, 12, 13]
|
||||
let c = x[3..0]; //c == [11, 10, 9]
|
||||
3. +
|
||||
Unary plus
|
||||
let a = +6;
|
||||
3. -
|
||||
Unary minus
|
||||
let a = -10;
|
||||
3. !
|
||||
Unary logical not
|
||||
let a = !b;
|
||||
3. ~
|
||||
Unary bitwise not
|
||||
let a = ~312; //a == -313
|
||||
let b = ~(0b1011001); //b == -90
|
||||
4. *
|
||||
Multiply
|
||||
let a = 4 * 10; //a == 40
|
||||
4. /
|
||||
Divide
|
||||
let a = 10 / 3; //a == 3.333333
|
||||
4. ~/
|
||||
Floored divide
|
||||
let a = 10 ~/ 3; //a == 3
|
||||
4. %
|
||||
Remainder (Modulo)
|
||||
let a = 7 % 4; //a == 3
|
||||
5. +
|
||||
Add
|
||||
let a = 3 + 32; //a == 35
|
||||
5. -
|
||||
Subtract
|
||||
let a = 9 - 12; //a == -3
|
||||
5. ~
|
||||
Array concatenate
|
||||
let a = [8, 3] ~ [10]; //a == [8, 3, 10]
|
||||
6. <<
|
||||
Bitwise shift left
|
||||
let a = 7 << 3; //a == 56
|
||||
6. >>
|
||||
Bitwise shift right
|
||||
let a = 198 >> 2; //a == 49
|
||||
7. ==
|
||||
!=
|
||||
<
|
||||
<=
|
||||
>
|
||||
>=
|
||||
Comparison
|
||||
let a = 5 < 6;
|
||||
let b = a != false;
|
||||
let c = 10 >= 10;
|
||||
8. ^^
|
||||
Bitwise XOR
|
||||
let a = 63 ^^ 234; //a == 213
|
||||
9. |
|
||||
Bitwise OR
|
||||
let a = 63 | 234; //a == 255
|
||||
10. &
|
||||
Bitwise AND
|
||||
let a = 63 & 234; //a == 42
|
||||
11. ||
|
||||
Logical OR
|
||||
let a = true || false; //a == true
|
||||
11. &&
|
||||
Logical AND
|
||||
let a = true || false; //a == false
|
||||
12. ?:
|
||||
Ternary expression
|
||||
let a = x > y ? 10 : 20;
|
||||
let b = z == 0 ? x * 10 : y + 4;
|
||||
let c = k ? (y ? 8 : 0) : p ? 5 : 2 + x;
|
||||
|
||||
- Boolean expressions
|
||||
|
||||
- Short-circuiting
|
||||
|
||||
This feature was present in vanilla ph3 as well, but I have yet to see a tutorial mention it, so here it is.
|
||||
|
||||
Short-circuiting (short-circuit evaluation) is an optimization for boolean expressions.
|
||||
|
||||
Take these statements, for example:
|
||||
bool c = a && b;
|
||||
bool z = x || y;
|
||||
|
||||
This !RUN-TIME! optimization will occur when expression (a) evaluates to false,
|
||||
where the evaluation of expression (b) will be completely skipped over.
|
||||
Conversely, in the second statement, the evaluation of expression (y) will also be skipped over if
|
||||
expression (x) evaluates to true.
|
||||
|
||||
Short-circuiting will take place left-to-right, so it is beneficial to format your logical expressions
|
||||
in a way that more lightweight expressions get evaluated sooner rather than later.
|
||||
|
||||
Example:
|
||||
if (bCheckHit && GetShotIdInCircleA2(...)) { /*...*/ }
|
||||
|
||||
would benefit more from short-circuit evaluation than
|
||||
|
||||
if (GetShotIdInCircleA2(...) && bCheckHit) { /*...*/ }
|
||||
|
||||
Short-circuiting only applies to logical expressions, not bitwise expressions.
|
||||
|
||||
Example:
|
||||
bool c = a & b;
|
||||
bool d = a | b;
|
||||
|
||||
Here, both expressions (a) and (b) will be evaluated regardless of the result of expression (a).
|
||||
|
||||
- Loops
|
||||
|
||||
- Ascent/Descent
|
||||
|
||||
Ascent and descent loops remain unchanged, but you may now assign an explicit type to the counter variable.
|
||||
|
||||
Example:
|
||||
|
||||
ascent (i in 0..3)
|
||||
WriteLog(i);
|
||||
|
||||
Will result in the following output:
|
||||
0.000000
|
||||
1.000000
|
||||
2.000000
|
||||
|
||||
//-----------------------------------------------
|
||||
|
||||
ascent (i in 0i..3)
|
||||
WriteLog(i);
|
||||
|
||||
Will result in the following output:
|
||||
0
|
||||
1
|
||||
2
|
||||
|
||||
//-----------------------------------------------
|
||||
|
||||
ascent (int i in 0..3)
|
||||
WriteLog(i);
|
||||
|
||||
Will result in the following output:
|
||||
0
|
||||
1
|
||||
2
|
||||
|
||||
- In ph3sx, two new loops are available for use.
|
||||
|
||||
- For loop
|
||||
|
||||
The for loop is the more generalized version of ascent/descent loops.
|
||||
|
||||
It's also the standard loop format in most programming languages,
|
||||
which means I don't have to explain its usage here.
|
||||
|
||||
- For-each loop
|
||||
|
||||
The for-each loop is a quick and efficient method to iterate through arrays.
|
||||
|
||||
Example:
|
||||
|
||||
int[] arr = [10, 9, 8, 7];
|
||||
for each (int i in arr)
|
||||
WriteLog(i);
|
||||
|
||||
Will result in the following output:
|
||||
10
|
||||
9
|
||||
8
|
||||
7
|
||||
|
||||
//-----------------------------------------------
|
||||
|
||||
for each (float i in arr)
|
||||
WriteLog(i);
|
||||
|
||||
Will result in the following output:
|
||||
10.000000
|
||||
9.000000
|
||||
8.000000
|
||||
7.000000
|
||||
|
||||
- The "ref" keyword
|
||||
|
||||
Normally, the array fed into a for-each loop will be a copy of the original array.
|
||||
However, you can force the loop to directly read from the original array with the "ref" keyword.
|
||||
|
||||
As the array won't be copied, there would also be some performance benefits to be had,
|
||||
and the loop will respond to any modifications to the array rather than being unaffected.
|
||||
|
||||
Example:
|
||||
|
||||
int[] arr = [1, 2, 3, 4];
|
||||
|
||||
for each (i in arr) {
|
||||
if (i % 2 == 0)
|
||||
arr ~= [5];
|
||||
WriteLog(i);
|
||||
}
|
||||
WriteLog(arr);
|
||||
|
||||
Will result in the following output:
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
[1, 2, 3, 4, 5, 5]
|
||||
|
||||
//-----------------------------------------------
|
||||
|
||||
for each (i in ref arr) {
|
||||
if (i % 2 == 0)
|
||||
arr ~= [5];
|
||||
WriteLog(i);
|
||||
}
|
||||
WriteLog(arr);
|
||||
|
||||
Will result in the following output:
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
5
|
||||
[1, 2, 3, 4, 5, 5]
|
||||
|
||||
- Special syntaxes
|
||||
|
||||
- There is also another declaration syntax for the for-each loop:
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
for each (itr in array) {
|
||||
//...
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
//is equivalent to:
|
||||
|
||||
for each (i, itr in array) {
|
||||
//...
|
||||
}
|
||||
|
||||
- These formats are also allowed:
|
||||
|
||||
for each ((i, itr) in array) { /*...*/ }
|
||||
for each ((int i, itr) in array) { /*...*/ }
|
||||
for each (i, float itr in array) { /*...*/ }
|
||||
for each ((float i, string itr) in array) { /*...*/ }
|
||||
|
||||
- You may use a colon(:) in place of the keyword "in"
|
||||
|
||||
for each (itr : array) { /*...*/ }
|
||||
for each ((i, itr) : array) { /*...*/ }
|
||||
|
||||
- In addition, there is a new flow control statement "continue".
|
||||
|
||||
"continue" is used in the same manner as "break", but rather than simply ending the loop,
|
||||
it will merely skip the current iteration of the loop.
|
||||
|
||||
Example:
|
||||
|
||||
ascent (int i in 0..8) {
|
||||
if (i % 2 == 0) continue;
|
||||
WriteLog(i);
|
||||
}
|
||||
|
||||
Will result in the following output:
|
||||
1
|
||||
3
|
||||
5
|
||||
7
|
||||
|
||||
- Unlike in vanilla ph3, "break" can no longer be used outside a loop.
|
||||
- Attempting to do so will throw a compile-time error.
|
||||
- The same applies to "continue".
|
||||
|
||||
- Functions, Tasks, Subs ("Callables")
|
||||
|
||||
- Parameters
|
||||
|
||||
Parameters, like variables, can have explicit types.
|
||||
|
||||
Example:
|
||||
|
||||
function Func(int a, float b, const string[] c) {}
|
||||
|
||||
- Function return type
|
||||
|
||||
- You may explicitly specify a function's return type.
|
||||
|
||||
function<int> Func1(a, b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
WriteLog(Func1(10, 4.2)); //Output: 14
|
||||
WriteLog(Func1(10, "sdfs")); //ERROR: Invalid implicit casting
|
||||
|
||||
- Marking a function with type "void" will forbid it from returning a value.
|
||||
|
||||
function<void> Func1(a, b) {
|
||||
return; //OK: no return value
|
||||
}
|
||||
|
||||
function<void> Func2(a, b) {
|
||||
return a + b; //ERROR: void function can't return a value
|
||||
}
|
||||
|
||||
- Overloading
|
||||
|
||||
Two callables with the same name, but different argument counts, will be treated as two different, unique callables.
|
||||
|
||||
Example:
|
||||
|
||||
function<int> Func() {
|
||||
return 0;
|
||||
}
|
||||
function<int> Func(a) {
|
||||
return 100;
|
||||
}
|
||||
function<int> Func(a, b, c) {
|
||||
return a + b + c;
|
||||
}
|
||||
|
||||
DoStuff(); //Returns 0
|
||||
DoStuff("asdf"); //Returns 100
|
||||
DoStuff(1, 2, 3); //Returns 6
|
||||
|
||||
- Variadic argument count (varargs)
|
||||
|
||||
- Some default functions now allow for varargs.
|
||||
|
||||
Example:
|
||||
|
||||
NotifyEventAll(EV_USER, 0);
|
||||
NotifyEventAll(EV_USER, 0, 1, 2, 3);
|
||||
NotifyEventAll(EV_USER, 0, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
||||
//All of the above are valid calls to NotifyEventAll.
|
||||
|
||||
- You can pass a maximum of around 357900000 arguments, but please please don't actually do that.
|
||||
|
||||
- Scripters currently cannot define their own callables with varargs.
|
||||
|
||||
- Async
|
||||
|
||||
Async blocks can be placed anywhere in the code, they behave like inlined tasks.
|
||||
|
||||
Example:
|
||||
|
||||
function Func() {
|
||||
WriteLog(0);
|
||||
|
||||
async {
|
||||
WriteLog(1);
|
||||
wait(10);
|
||||
WriteLog(2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//is equivalent to:
|
||||
|
||||
function Func() {
|
||||
WriteLog(0);
|
||||
|
||||
task AsyncTask() {
|
||||
WriteLog(1);
|
||||
wait(10);
|
||||
WriteLog(2);
|
||||
}
|
||||
AsyncTask();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- Script
|
||||
|
||||
- Char
|
||||
|
||||
- Backslash escapes (\\) is properly recognized in char/string literals.
|
||||
- Hexadecimal char literals (\x[hex]) can be used in char/string literals.
|
||||
Example:
|
||||
"\x74" -> "t"
|
||||
'\x3042' -> 'あ'
|
||||
"\x042\x5f" -> "B_"
|
||||
|
||||
- One-lined statements
|
||||
|
||||
Example:
|
||||
|
||||
ascent (i in 0..10) WriteLog(i);
|
||||
|
||||
if (true) a += 10;
|
||||
else a -= 4;
|
||||
|
||||
Can be used everywhere except in function/task/sub declarations, async blocks, @-blocks, and local{} blocks.
|
||||
|
||||
- Optimizations
|
||||
|
||||
- The script compiler will try to perform basic optimizations on maths expressions.
|
||||
|
||||
Examples:
|
||||
|
||||
a = 5 + 5 - 1; -> optimize -> a = 9;
|
||||
a = 5 * 8 / 7; -> optimize -> a = 5.714286;
|
||||
a = func(b) + 5 % 10; -> optimize -> a = func(b) + 5;
|
||||
|
||||
- Empty loops and blocks will be optimized away during script compiling.
|
||||
|
||||
Examples:
|
||||
|
||||
while (true) {}
|
||||
|
||||
for (let i = 0; i < 10; i++) {}
|
||||
|
||||
ascent (i in 0..100000000) {}
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
loop (1000) {
|
||||
}
|
||||
|
||||
for each (i in "aaaaaaaaaa") {}
|
||||
|
||||
async {}
|
||||
|
||||
//All of the above examples will be optimized away
|
||||
|
||||
- Loops containing a single yield will be automatically transformed into a wait.
|
||||
|
||||
Examples:
|
||||
|
||||
loop (60) yield; -> optimize -> wait(60);
|
||||
|
||||
loop (a * 2 + 60 - 20) { -> optimize -> wait(a * 2 + 60 - 20);
|
||||
yield;
|
||||
}
|
||||
|
||||
- Text Object Tags
|
||||
|
||||
Text object tags are special formatting patterns that can be used to dynamically alter rendering of text objects.
|
||||
|
||||
Available tags:
|
||||
|
||||
- r
|
||||
|
||||
Inserts a new line. Also resets formatting from other tags.
|
||||
|
||||
- font / f
|
||||
|
||||
Modifies the font.
|
||||
|
||||
Available tag properties:
|
||||
|
||||
- reset / rs / r / clear / clr / c
|
||||
|
||||
Resets the text to its original settings. Present in vanilla ph3 as "clear".
|
||||
|
||||
- size / sz
|
||||
|
||||
Changes the font size. Unchanged from vanilla ph3.
|
||||
|
||||
- ox / oy
|
||||
|
||||
Changes the position offset.
|
||||
|
||||
- it
|
||||
|
||||
Toggles italic. (true/false or 1/0)
|
||||
|
||||
- wg
|
||||
|
||||
Changes the font's weight.
|
||||
|
||||
- br / bg / bb
|
||||
|
||||
Changes the font's bottom color.
|
||||
|
||||
- tr / tg / tb
|
||||
|
||||
Changes the font's top color.
|
||||
|
||||
- or / og / ob
|
||||
|
||||
Changes the font's border color.
|
||||
|
||||
- bc
|
||||
|
||||
Changes the font's bottom color as a (r, g, b) list.
|
||||
|
||||
- tc
|
||||
|
||||
Changes the font's top color as a (r, g, b) list.
|
||||
|
||||
- oc
|
||||
|
||||
Changes the font's border color as a (r, g, b) list.
|
||||
|
||||
Example:
|
||||
|
||||
ObjText_SetText(obj, "Lorem ipsum [font size=48 it=1 bc=(255, 0, 0)]dolor sit[font clr] amet");
|
||||
|
||||
- ruby
|
||||
|
||||
Creates a ruby(furigana) text.
|
||||
|
||||
Available tag properties:
|
||||
|
||||
- rb
|
||||
|
||||
Sets the main(bottom) text. Unchanged from vanilla ph3.
|
||||
- rt
|
||||
|
||||
Sets the furigana(top) text. Unchanged from vanilla ph3.
|
||||
- sz
|
||||
|
||||
Changes the furigana text's font size.
|
||||
|
||||
- wg
|
||||
|
||||
Changes the furigana text's font weight.
|
||||
|
||||
- ox
|
||||
|
||||
Changes the furigana text's left margin.
|
||||
|
||||
- op
|
||||
|
||||
Changes the furigana text's side pitch.
|
Loading…
Add table
Add a link
Reference in a new issue