diff --git a/files/scripts/compat/internal/addfixes.lua b/files/scripts/compat/internal/addfixes.lua new file mode 100644 index 0000000..a26f427 --- /dev/null +++ b/files/scripts/compat/internal/addfixes.lua @@ -0,0 +1,26 @@ +-- Extra fixes to warn about compatibility issues, eg. crashes in earlier versions + +local BUILTIN = {} + +local function wouldcrash(fn) + errorLog("Old Aquaria would have crashed now. Calling function: " .. fn) +end + +local F = +{ + -- Old version would crash if e is not a string + createEntity = function(e, name, x, y) + if type(e) == "string" and #e > 0 then + return BUILTIN.createEntity(e, name, x, y) + end + wouldcrash"createEntity" + return 0 + end, +} + +for name, f in pairs(F) do + if not BUILTIN[name] then + BUILTIN[name] = assert(_G[name], name) + _G[name] = f + end +end diff --git a/files/scripts/compat/internal/addquirks.lua b/files/scripts/compat/internal/addquirks.lua new file mode 100644 index 0000000..1fdb0c3 --- /dev/null +++ b/files/scripts/compat/internal/addquirks.lua @@ -0,0 +1,24 @@ +-- Some things that behave differently or have received fixes after v1.1 +-- Loading this file restores the 1.1 behavior as much as is feasible + +local BUILTIN = {} + +local F = +{ +} + +-- TODO -- + +-- dofile() should not accept mod-relative paths +-- entity_color() should undo interpolation modes +-- *_getNearestNode() and *_getNearestEntity() -- remove ignore param +-- *_getNearestNode -- must only scan by full name +-- entity_setHealth(), entity_changeHealth() -- cast to int + + +for name, f in pairs(F) do + if not BUILTIN[name] then + BUILTIN[name] = assert(_G[name], name) + _G[name] = f + end +end diff --git a/files/scripts/compat/internal/funclist_1.1.lua b/files/scripts/compat/internal/funclist_1.1.lua new file mode 100644 index 0000000..68519d7 --- /dev/null +++ b/files/scripts/compat/internal/funclist_1.1.lua @@ -0,0 +1,671 @@ +-- All Lua functions that existed in v1.1, extracted via tools/oldfunclist.lua and reformatted +-- Returns table with function names as keys + +local fns = [[ +addInfluence +appendUserDataPath +avatar_clampPosition +avatar_fallOffWall +avatar_getRollDirection +avatar_getSpellCharge +avatar_getStillTimer +avatar_isBursting +avatar_isLockable +avatar_isOnWall +avatar_isRolling +avatar_isShieldActive +avatar_isSinging +avatar_isTouchHit +avatar_setBlockSinging +avatar_setCanDie +avatar_setHeadTexture +avatar_setPullTarget +avatar_toggleCape +avatar_toggleMovement +avatar_updatePosition +beaconEffect +beam_delete +beam_setAngle +beam_setBeamWidth +beam_setDamage +beam_setPosition +beam_setTexture +bedEffects +bone_addSegment +bone_alpha +bone_color +bone_damageFlash +bone_getIndex +bone_getName +bone_getNormal +bone_getPosition +bone_getRotation +bone_getScale +bone_getWorldPosition +bone_getWorldRotation +bone_getidx +bone_isName +bone_isVisible +bone_lookAtEntity +bone_offset +bone_rotate +bone_rotateOffset +bone_scale +bone_setAnimated +bone_setBlendType +bone_setColor +bone_setPosition +bone_setRenderPass +bone_setSegmentChainHead +bone_setSegmentOffset +bone_setSegmentProps +bone_setSegs +bone_setTexture +bone_setTouchDamage +bone_setVisible +bone_showFrame +bone_update +cam_setPosition +cam_snap +cam_toEntity +cam_toNode +castSong +centerText +chance +changeForm +clearControlHint +clearHelp +clearShots +confirm +createBeam +createEntity +createQuad +createShot +createSpore +createWeb +cureAllStatus +debugLog +decrFlag +disableInput +disableOverrideZoom +doLoadMenu +doModSelect +dofile +egetv +egetvf +eisv +emote +enableInput +entityFollowEntity +entity_addGroupVel +entity_addIgnoreShotDamageType +entity_addRandomVel +entity_addTargetPoint +entity_addVel +entity_addVel2 +entity_adjustPositionBySurfaceNormal +entity_alpha +entity_animate +entity_applyRandomForce +entity_applySurfaceNormalForce +entity_avgVel +entity_changeHealth +entity_checkSplash +entity_checkSurface +entity_clampToHit +entity_clampToSurface +entity_clearTargetPoints +entity_clearVel +entity_clearVel2 +entity_collideCircleVsLine +entity_collideCircleVsLineAngle +entity_collideHairVsCircle +entity_collideSkeletalVsCircle +entity_collideSkeletalVsCircleForListByName +entity_collideSkeletalVsLine +entity_color +entity_createEntity +entity_damage +entity_debugText +entity_decrTargetLeaches +entity_delete +entity_disableMotionBlur +entity_doCollisionAvoidance +entity_doEntityAvoidance +entity_doFriction +entity_doGlint +entity_doSpellAvoidance +entity_enableMotionBlur +entity_ensureLimit +entity_exertHairForce +entity_fh +entity_fhTo +entity_findNearestEntityOfType +entity_findTarget +entity_fireAtTarget +entity_fireGas +entity_fireShot +entity_flipHToAvatar +entity_flipHorizontal +entity_flipTo +entity_flipToEntity +entity_flipToNode +entity_flipToSame +entity_flipToVel +entity_flipVertical +entity_followEntity +entity_followPath +entity_fv +entity_generateCollisionMask +entity_getAimVector +entity_getAlpha +entity_getAnimLen +entity_getAnimName +entity_getAnimationLength +entity_getAnimationName +entity_getBehaviorType +entity_getBoneByIdx +entity_getBoneByName +entity_getBoneLockEntity +entity_getBounceType +entity_getCollideRadius +entity_getDistanceToEntity +entity_getDistanceToTarget +entity_getEnqueuedState +entity_getEntityType +entity_getGroupID +entity_getHairPosition +entity_getHealth +entity_getHealthPerc +entity_getID +entity_getLookAtPoint +entity_getMaxSpeed +entity_getName +entity_getNearestBoneToPosition +entity_getNearestEntity +entity_getNearestNode +entity_getNormal +entity_getOffset +entity_getPosition +entity_getPositionX +entity_getPositionY +entity_getPrevState +entity_getRandomTargetPoint +entity_getRiding +entity_getRotation +entity_getScale +entity_getState +entity_getStateTime +entity_getTarget +entity_getTargetPoint +entity_getTargetPositionX +entity_getTargetPositionY +entity_getVectorToEntity +entity_getVelLen +entity_grabTarget +entity_handleShotCollisions +entity_handleShotCollisionsHair +entity_handleShotCollisionsSkeletal +entity_hasTarget +entity_heal +entity_hurtTarget +entity_idle +entity_incrTargetLeaches +entity_initEmitter +entity_initHair +entity_initPart +entity_initSegments +entity_initSkeletal +entity_initStrands +entity_interpolateTo +entity_isAnimating +entity_isBeingPulled +entity_isDamageTarget +entity_isDead +entity_isEntityInRange +entity_isFlag +entity_isFlippedHorizontal +entity_isFollowingEntity +entity_isFollowingPath +entity_isHit +entity_isInDarkness +entity_isInRect +entity_isInterpolating +entity_isInvincible +entity_isName +entity_isNearGround +entity_isNearObstruction +entity_isPositionInRange +entity_isProperty +entity_isRidingOnEntity +entity_isRotating +entity_isSaying +entity_isScaling +entity_isSlowingToStopPath +entity_isState +entity_isTargetInRange +entity_isUnderWater +entity_isValidTarget +entity_isVelIn +entity_isfh +entity_isfv +entity_move +entity_moveAlongSurface +entity_moveAround +entity_moveAroundAngle +entity_moveAroundTarget +entity_moveToBack +entity_moveToFront +entity_moveToNode +entity_moveTowards +entity_moveTowardsAngle +entity_moveTowardsGroupCenter +entity_moveTowardsGroupHeading +entity_moveTowardsTarget +entity_msg +entity_offset +entity_offsetUpdate +entity_partAlpha +entity_partBlendType +entity_partRotate +entity_partSetSegs +entity_partWidthHeight +entity_pathBurst +entity_playSfx +entity_pullEntities +entity_push +entity_pushTarget +entity_releaseTarget +entity_resetTimer +entity_resumePath +entity_revive +entity_rotate +entity_rotateOffset +entity_rotateTo +entity_rotateToEntity +entity_rotateToSurfaceNormal +entity_rotateToTarget +entity_rotateToVec +entity_rotateToVel +entity_say +entity_scale +entity_setActivation +entity_setActivationType +entity_setAffectedBySpell +entity_setAffectedBySpells +entity_setAllDamageTargets +entity_setAnimLayerTimeMult +entity_setAutoSkeletalUpdate +entity_setBeautyFlip +entity_setBehaviorType +entity_setBlendType +entity_setBoneLock +entity_setBounce +entity_setBounceType +entity_setCanLeaveWater +entity_setClampOnSwitchDir +entity_setCollideRadius +entity_setCollideWithAvatar +entity_setColor +entity_setCull +entity_setCullRadius +entity_setCurrentTarget +entity_setDamageTarget +entity_setDeathParticleEffect +entity_setDeathScene +entity_setDeathSound +entity_setDieTimer +entity_setDropChance +entity_setEatType +entity_setEnergyChargeTarget +entity_setEnergyShotTarget +entity_setEnergyShotTargetPosition +entity_setEntityLayer +entity_setEntityType +entity_setFillGrid +entity_setFlag +entity_setHairHeadPosition +entity_setHealth +entity_setHeight +entity_setIngredient +entity_setInternalOffset +entity_setInvincible +entity_setLife +entity_setLookAtPoint +entity_setMaxSpeed +entity_setMaxSpeedLerp +entity_setNaijaReaction +entity_setName +entity_setNodeGroupActive +entity_setOverrideCullRadius +entity_setPauseInConversation +entity_setPosition +entity_setPositionX +entity_setPositionY +entity_setProperty +entity_setRegisterEntityDied +entity_setRenderPass +entity_setRiding +entity_setRidingData +entity_setRidingPosition +entity_setSayPosition +entity_setSegmentTexture +entity_setSegs +entity_setSegsMaxDist +entity_setSpiritFreeze +entity_setState +entity_setStateTime +entity_setTarget +entity_setTargetPriority +entity_setTargetRange +entity_setTexture +entity_setTouchDamage +entity_setTouchPush +entity_setUpdateCull +entity_setVelLen +entity_setWeight +entity_setWidth +entity_slowToStopPath +entity_sound +entity_soundFreq +entity_spawnParticlesFromCollisionMask +entity_startEmitter +entity_stopAllAnimations +entity_stopEmitter +entity_stopFollowingPath +entity_stopInterpolating +entity_stopPull +entity_stopTimer +entity_swimToNode +entity_swimToPosition +entity_switchLayer +entity_switchSurfaceDirection +entity_toggleBone +entity_touchAvatarDamage +entity_update +entity_updateCurrents +entity_updateHair +entity_updateLocalWarpAreas +entity_updateMovement +entity_updateSkeletal +entity_velTowards +entity_velx +entity_vely +entity_waitForPath +entity_warpLastPosition +entity_warpSegments +entity_warpToNode +entity_warpToPathStart +entity_watchEntity +entity_watchForPath +entity_x +entity_y +esetv +esetvf +fade +fade2 +fade3 +fadeIn +fadeOut +fadeOutMusic +fadeSfx +findWall +flingMonkey +foundLostMemory +getAngleBetween +getAngleBetweenEntities +getAvatar +getBeacon +getCostume +getEnqueuedState +getEntity +getEntityByID +getEntityByName +getEntityInGroup +getFirstEntity +getFlag +getForm +getHalfTimer +getIngredientGfx +getLastCollidePosition +getLi +getLiPower +getMapName +getMousePos +getMouseWorldPos +getNaija +getNearestIngredient +getNearestNode +getNearestNodeByType +getNextEntity +getNode +getNodeByName +getNodeFromEntity +getNodeToActivate +getNoteColor +getNoteName +getNoteVector +getNumberOfEntitiesNamed +getPetPower +getRandNote +getRandVector +getScreenCenter +getStory +getStringBank +getStringFlag +getTimer +getWallNormal +getWaterLevel +getWorldType +goToTitle +hasFormUpgrade +hasLi +hasSong +healEntity +hideImage +hideInGameMenu +incrFlag +ing_hasIET +inp +isDemo +isDeveloperKeys +isElementLayerVisible +isEscapeKey +isFlag +isForm +isInCutscene +isInDialog +isInputEnabled +isLeftMouse +isMapName +isNested +isNestedMain +isObstructed +isObstructedBlock +isPlat +isPlayingVoice +isQuitFlag +isRightMouse +isStory +isStreamingVoice +isWithin +jumpState +killEntity +learnFormUpgrade +learnSong +learnSpell +loadMap +loadSound +mapNameContains +moveEntity +msg +musicVolume +node_activate +node_getAmount +node_getContent +node_getFlag +node_getName +node_getNearestEntity +node_getNearestNode +node_getNumEntitiesIn +node_getPathPosition +node_getPosition +node_getSize +node_isEntityIn +node_isEntityInRange +node_isEntityPast +node_isFlag +node_isPositionIn +node_setActive +node_setCatchActions +node_setCursorActivation +node_setEffectOn +node_setElementsInLayerActive +node_setFlag +node_setPosition +node_x +node_y +overrideZoom +pause +pickupGem +playMusic +playMusicOnce +playMusicStraight +playNoEffect +playSfx +playVfx +playVisualEffect +playVoice +quad_alpha +quad_alphaMod +quad_color +quad_delete +quad_getAlpha +quad_rotate +quad_scale +quad_setBlendType +quad_setPosition +quit +quitNestedMain +randAngle360 +randRange +randVector +reconstructEntityGrid +reconstructGrid +registerSporeChildData +registerSporeDrop +reloadTextures +resetContinuity +resetTimer +savePoint +screenFadeCapture +screenFadeGo +screenFadeTransition +sendEntityMessage +setActivation +setActivePet +setBeacon +setBlackBarsColor +setCameraLerpDelay +setCanChangeForm +setCanWarp +setControlHint +setCostume +setCutscene +setElementLayerVisible +setEntityScript +setFlag +setGLNearest +setGameOver +setGameSpeed +setInvincible +setInvincibleOnNested +setLi +setLiPower +setMiniMapHint +setMousePos +setMusicToPlay +setNaijaHeadTexture +setNaijaModel +setNodeToActivate +setOverrideMusic +setOverrideVoiceFader +setPoison +setSceneColor +setStory +setStringFlag +setTimerText +setTimerTextAlpha +setVersionLabelText +setWaterLevel +setupBasicEntity +setupConversationEntity +setupEntity +shakeCamera +shot_getPosition +shot_setAimVector +shot_setBounceType +shot_setLifeTime +shot_setNice +shot_setOut +shot_setVel +showControls +showImage +showInGameMenu +spawnAllIngredients +spawnAroundEntity +spawnIngredient +spawnManaBall +spawnParticleEffect +stopAllSfx +stopAllVoice +stopCursorGlow +stopMusic +stopVoice +streamSfx +toWindowFromWorld +toggleBlackBars +toggleConversationWindow +toggleCursor +toggleDamageSprite +toggleDialogWindow +toggleLiCombat +toggleSteam +toggleTransitFishRide +toggleVersionLabel +unlearnSong +unpause +updateMusic +upgradeHealth +user_save +user_set_demo_intro +vector_cap +vector_dot +vector_getLength +vector_isLength2DIn +vector_normalize +vector_setLength +vision +voice +voiceInterupt +voiceOnce +wait +warpAvatar +warpNaijaToEntity +warpNaijaToSceneNode +watch +watchForVoice +web_addPoint +web_delete +web_getNumPoints +web_setPoint +wnd +wnds +]] + +local tab = {} +for f in fns:gmatch"%S+" do + tab[f] = true +end + +return tab diff --git a/files/scripts/compat/internal/loader.lua b/files/scripts/compat/internal/loader.lua index 16a05b0..44b4f17 100644 --- a/files/scripts/compat/internal/loader.lua +++ b/files/scripts/compat/internal/loader.lua @@ -1,5 +1,7 @@ -- Script loader hijack -- Intercepts loads of script files and patches interface functions on the fly +-- Mods may provide their own mod-compat.lua file (optionally containing aditional hooks). +-- Requires instance variables in "v". assert(AQUARIA_VERSION) @@ -10,7 +12,7 @@ local errorLog_o = assert(errorLog, "errorLog() not present") -- IMPORTANT that this gets loaded only once. Exit & re-enter the mod if the file was changed. if rawget(_G, ".__COMPAT_LOADED") then - errorLog_o("ERROR: Compat loader already loaded") + errorLog_o("COMPAT: Compat loader already loaded") return end @@ -30,15 +32,19 @@ rawset(_G, "errorLog", errorLogWrap) ---- Create hook scripts for entity interface function detouring ---- --------------------------------------------------------------------- -local WARNINGS = isDeveloperKeys() -local HOOKS = dofile("mod-compat.lua") or {} +local WARNINGS --= isDeveloperKeys() +local HOOKS +if fileExists("mod-compat.lua") then + HOOKS = dofile("mod-compat.lua") +end +HOOKS = HOOKS or {} assert(type(HOOKS) == "table", "mod-compat.lua must return nothing or table, not " .. type(HOOKS)) local v_meta if WARNINGS then local function _warnUndefInstance(tab, key) if WARNINGS then - errorLog("WARNING: script tried to get/call undefined instance variable " .. tostring(key), 3) + errorLog("COMPAT/WARNING: script tried to get/call undefined instance variable " .. tostring(key), 3) rawset(tab, key, false) -- warn only once, not spam end end @@ -57,6 +63,8 @@ local function onCreateScript(scriptname, functable) local function newinit(me) assert(v) setmetatable(v, v_meta) -- global lookup: uses entity context's v + -- ^ and yes, this overwrites v's previous metatable that is added by C++ in dev mode. + -- We don't want warnings for mods that don't initialize their variables if oldinit then oldinit(me) end diff --git a/files/scripts/compat/internal/oldfunctions.lua b/files/scripts/compat/internal/oldfunctions.lua index 401b2e2..1b6d9db 100644 --- a/files/scripts/compat/internal/oldfunctions.lua +++ b/files/scripts/compat/internal/oldfunctions.lua @@ -3,20 +3,36 @@ -- Most that had no function are dummied out, some existed but threw errors, -- and others were registered under different names. +local NULLREF = 0 + +-- these did something but are now gone local WARN_FUNCTIONS = { - getAngleBetween = true, - getAngleBetweenEntities = true, - getNearestNode = true, - getNodeFromEntity = true, healEntity = true, killEntity = true, entity_warpToPathStart = true, sendEntityMessage = true, entity_fireShot = true, entity_resetTimer = true, + moveEntity = true, + playVfx = true, + registerSporeChildData = true, + setMiniMapHint = true, + setupConversationEntity = true, } +-- These returned something important, so here we just return a failure/dummy value +local WARN_FUNCTIONS_VAL = +{ + getAngleBetween = 0.0, + getAngleBetweenEntities = 0.0, + getEntityInGroup = NULLREF, + getNearestNode = NULLREF, + getNodeFromEntity = NULLREF, + isInDialog = false, +} + +-- These had no function and we can just ignore the call local DUMMY_FUNCTIONS = { entity_setCollideWithAvatar = true, @@ -48,11 +64,31 @@ local DUMMY_FUNCTIONS = stopCursorGlow = true, toggleTransitFishRide = true, entity_stopTimer = true, + setEntityScript = true, + streamSfx = true, } +-- Deprecated stuff from v1.1's scripts/entities/entityinclude.lua + +local function entity_watchSwimToEntitySide(ent1, ent2) + local xoff=entity_getCollideRadius(ent2)+64 + if entity_x(ent1) < entity_x(ent2) then + xoff = -xoff + end + entity_swimToPosition(ent1, entity_x(ent2)+xoff, entity_y(ent2)) + entity_watchForPath(ent1) + entity_idle(ent1) + entity_clearVel(ent1) + entity_flipToEntity(ent1, ent2) + entity_flipToEntity(ent2, ent1) +end + + +-- Duplicated and renamed functions local REPLACED_FUNCTIONS = { - -- alternate names + -- alternate names, old name on the left, new name on the right + -- (Might want tp use the name on the right, they existed in 1.1.1 already) entity_getPositionX = entity_x, entity_getPositionY = entity_y, entity_applyRandomForce = entity_addRandomVel, @@ -60,22 +96,50 @@ local REPLACED_FUNCTIONS = getEntityByName = getEntity, entity_flipTo = entity_fhTo, bone_getidx = bone_getIndex, + getAvatar = getNaija, + getRandVector = randVector, + inp = toggleInput, + isPlayingVoice = isStreamingVoice, + playVoice = voice, + + -- These are unfortunately broken and can't be fixed. + -- They are interface function names and the first loaded script would grab them, + -- thinking an interface function with that name was provided by whichever script was just loaded. + -- So we ignore these and hope nobody misses them. + --msg = screenMessage, + --castSong = singSong, + + -- entityinclude functions + entity_watchSwimToEntitySide = entity_watchSwimToEntitySide, } ---------------------------------------------------- ---- Functors to generate replacement function ----- ---------------------------------------------------- -local function mkwarn(name, param) - local err = "Dummy function: " .. name .. "() - no longer present in the current API, fix the script!" - return function() errorLog(err) end +local warnLog = (isDeveloperKeys() and errorLog) or debugLog + +-- generate function that warns when called and returns nil +local function warndummy(name) + warnLog("Dummy function: " .. name .. "() - no longer present in the current API, fix the script!") +end +local function mkwarn(name) + return function() warndummy(name) end end -local function dummy(name, param) +-- generate function that warns when called and returns a non-nil fixed value +local function mkwarnret(name, param) + return function() warndummy(name) return param end end + +-- generate silent dummy that does nothing when called and returns nil +local function dummy() end local function mkdummy(name, param) return dummy end + + +-- register existing function under a different name local function mkalias(name, param) return assert(param, name) end @@ -95,5 +159,6 @@ end ---- Do it! ---- ---------------- makestubs(WARN_FUNCTIONS, mkwarn) +makestubs(WARN_FUNCTIONS_VAL, mkwarnret) makestubs(DUMMY_FUNCTIONS, mkdummy) makestubs(REPLACED_FUNCTIONS, mkalias) diff --git a/files/scripts/compat/internal/old_1.1.lua b/files/scripts/compat/internal/redirect_to_v.lua similarity index 80% rename from files/scripts/compat/internal/old_1.1.lua rename to files/scripts/compat/internal/redirect_to_v.lua index 21bdedf..2cba909 100644 --- a/files/scripts/compat/internal/old_1.1.lua +++ b/files/scripts/compat/internal/redirect_to_v.lua @@ -1,27 +1,30 @@ -- Compatibility wrapper [interface detouring] -- allows to run scripts written for the old script interface (1.1.0, 1.1.1, 1.1.2) -- on 1.1.3+ / OSE and its new scripting interface. +-- Adds automatic detouring of what used to be per-script globals to the new instance-local "v" table. + -- Note that this is a gross hack and a lot of guesswork is involved, -- but any sanely written mod should run without changes. -- Notes: --- * Any assignment to the global "v" will break things. Like v = 0. --- * Variables whose names only contain all-uppercase, underscores, and numbers are considered globals. +-- * Any assignment to a global named "v" will break things. Like v = 0. +-- * Variables whose names only contain all-uppercase, underscores, and numbers are considered true globals. -- Assignments to those will not cause warnings and go to _G. -- Assignments to non-globals will go to _G.v. -- Undefined reads from either _G or v will cause a warning (in dev mode). --- * Mods must provide their own mod-compat.lua file (optionally containing aditional hooks). local rawset = rawset local rawget = rawget local _G = _G -local debug = rawget(_G, "debug") -- not present in some 1.1.3+ versions +-- All global constants are UPPERCASE_DEFINE_NAMES (hopefully) local function looksLikeGlobal(s) return not s:match("[^_%u%d]") end -dofile("scripts/compat/internal/oldfunctions.lua") +-- Restore functions that only existed in v1.1 and have been removed since then +-- Most are dummied out, but it allows some mods to run + -- loading entityinclude.lua is no longer necessary and would do more bad than good, -- so make sure it's not loaded even if scripts explicitly load that file. @@ -35,17 +38,6 @@ end rawset(_G, "dofile", dofileWrap) ------------------------------------------------------ ----- Fixup functions that differ in behavior now ---- ------------------------------------------------------ -local createEntity_o = createEntity -rawset(_G, "createEntity", function(e, name, x, y) - if type(e) == "string" and #e > 0 then - return createEntity_o(e, name, x, y) - end - return 0 -end) - -- Prepare interface function lookup table local INTERFACE_LUT = {} do @@ -102,6 +94,4 @@ local _G_meta = } setmetatable(_G, _G_meta) -rawset(_G, "OLD_SCRIPT_INTERFACE_COMPATIBLE", true) -- mod-init.lua should check for this - debugLog("COMPAT/1.1: Redirecting global writes to v") diff --git a/files/scripts/compat/internal/removenewfunctions.lua b/files/scripts/compat/internal/removenewfunctions.lua new file mode 100644 index 0000000..f7e2151 --- /dev/null +++ b/files/scripts/compat/internal/removenewfunctions.lua @@ -0,0 +1,45 @@ +-- Remove all functions that didn't exist in v1.1 + +-- The known-good list of old script functions +local oldfuncs = dofile("scripts/compat/internal/funclist_1.1.lua") + +-- Ignore any standard Lua function known to exist in _G +local luafuncs51 = +{ + assert = true, + collectgarbage = true, + dofile = true, + error = true, + getfenv = true, + getmetatable = true, + ipairs = true, + load = true, + loadfile = true, + loadstring = true, + next = true, + pairs = true, + pcall = true, + print = true, + rawequal = true, + rawget = true, + rawset = true, + select = true, + setfenv = true, + setmetatable = true, + tonumber = true, + tostring = true, + type = true, + unpack = true, + xpcall = true, +} + +for k, f in pairs(_G) do + if type(k) == "string" + and type(f) == "function" + and not luafuncs51[k] + and not oldfuncs[k] + then + debugLog("Compatibility: Remove new script function " .. k) + _G[k] = nil + end +end diff --git a/files/scripts/compat/legacy-strict.lua b/files/scripts/compat/legacy-strict.lua new file mode 100644 index 0000000..86f7649 --- /dev/null +++ b/files/scripts/compat/legacy-strict.lua @@ -0,0 +1,14 @@ +-- Same compatibility wrapper as "legacy", +-- but in addition removes all functions added after the last commercial release (1.1.1) +-- If your scripts run in this mode it's very likely that they will work +-- in the Steam/GOG/Humble/Ambrosia/... version. + +dofile("scripts/compat/legacy.lua") +dofile("scripts/compat/internal/addquirks.lua") +dofile("scripts/compat/internal/removenewfunctions.lua") + +-- v1.1 does not expose the debug library +debug = nil + +-- This MUST NOT be removed. Core scripts depend on this, and mods are likely to use some of those. +--AQUARIA_VERSION = nil diff --git a/files/scripts/compat/legacy.lua b/files/scripts/compat/legacy.lua index 1a905ed..b3fe62c 100644 --- a/files/scripts/compat/legacy.lua +++ b/files/scripts/compat/legacy.lua @@ -1,5 +1,8 @@ -- 1.1.3+ compatibility wrapper --- allows to run scripts written for the old script interface. +-- Allows to run scripts written for the old script interface, +-- but also exposes new functions. +dofile("scripts/compat/internal/oldfunctions.lua") dofile("scripts/compat/internal/loader.lua") -dofile("scripts/compat/internal/old_1.1.lua") +dofile("scripts/compat/internal/redirect_to_v.lua") +dofile("scripts/compat/internal/addfixes.lua") diff --git a/tools/oldfunclist.lua b/tools/oldfunclist.lua new file mode 100644 index 0000000..7068004 --- /dev/null +++ b/tools/oldfunclist.lua @@ -0,0 +1,29 @@ +-- To generate the list of function names available in 1.1, run this script on ScriptInterface.cpp +-- obtained from: +-- https://hg.icculus.org/icculus/aquaria/raw-file/75924df9cbe8/Aquaria/ScriptInterface.cpp + + +local F = {} + +for line in io.lines((...)) do + local f = line:match'^%s*lua_register%s*%(.-%"([^%"]+)%".-%)' + if f then + F[f] = true + end + + f = line:match'^%s*luar%s*%(%s*([%w_]+)%s*%)' + if f then + F[f] = true + end +end + +-- These are commented out but the regex picks them up +F.opt = nil +F.options = nil + +local LIST = {} +for k in pairs(F) do + table.insert(LIST, k) +end +table.sort(LIST) +print(table.concat(LIST, "\n")) diff --git a/tools/scriptfunclist.lua b/tools/scriptfunclist.lua new file mode 100644 index 0000000..220da92 --- /dev/null +++ b/tools/scriptfunclist.lua @@ -0,0 +1,45 @@ +-- Generate list of script function names available in the OSE version +-- call with path/to/ScriptInterface.cpp + +local RO = { flipHorizontal = true, flipVertical = true } +local Q = {} +local F = {} + +local function emit(prefix, a) + for k in pairs(a) do + F[prefix .. "_" .. k] = true + end +end + +for line in io.lines((...)) do + local fn = line:match"^%s*luaRegister%(([%w_]+)%)" + if fn then + F[fn] = true + end + + local rf = line:match"^%s*RO_FUNC%(.-([%w_]+)%s*%)" + if rf then + RO[rf] = true + end + + local qf = line:match"^%s*Q_FUNC%(.-([%w_]+)%s*%)" + if qf then + Q[qf] = true + RO[qf] = true + end + + local lut = { QUAD = Q, ROBJ = RO } + local c, p = line:match"^%s*MAKE_([A-Z]+)_FUNCS%(.-([%w_]+)%s*%)" + if c and p ~= "prefix" then + --print(c, p, line) + emit(p, lut[c]) + end +end + +local LIST = {} +for k in pairs(F) do + table.insert(LIST, k) +end +table.sort(LIST) +print(table.concat(LIST, "\n")) +