diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 5aef53c81..c12e50078 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -634,26 +634,26 @@ static int GetLine (void) // misc1 = vrange (arg +3), misc2 = hrange (arg+4) static int CreateMushroomFunc(VMFunctionBuilder &buildit, int value1, int value2) { // A_Mushroom - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // spawntype - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // numspawns + buildit.Emit(OP_PARAM, REGT_NIL, 0); // spawntype + buildit.Emit(OP_PARAM, REGT_NIL, 0); // numspawns buildit.Emit(OP_PARAMI, 1); // flag // vrange if (value1 == 0) { - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); + buildit.Emit(OP_PARAM, REGT_NIL, 0); } else { - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value1))); + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value1))); } // hrange if (value2 == 0) { - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); + buildit.Emit(OP_PARAM, REGT_NIL, 0); } else { - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value2))); + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(DEHToDouble(value2))); } return 5; } @@ -669,9 +669,9 @@ static int CreateSpawnFunc(VMFunctionBuilder &buildit, int value1, int value2) int typereg = buildit.GetConstantAddress(InfoNames[value1-1]); int heightreg = buildit.GetConstantFloat(value2); - buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, typereg); // itemtype - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // distance - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, heightreg); // height + buildit.Emit(OP_PARAM, REGT_POINTER | REGT_KONST, typereg); // itemtype + buildit.Emit(OP_PARAM, REGT_NIL, 0); // distance + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, heightreg); // height // The rest of the parameters to A_SpawnItem can just keep their defaults return 3; } @@ -679,14 +679,14 @@ static int CreateSpawnFunc(VMFunctionBuilder &buildit, int value1, int value2) // misc1 = angle (in degrees) (arg +0 but factor in current actor angle too) static int CreateTurnFunc(VMFunctionBuilder &buildit, int value1, int value2) { // A_Turn - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(value1)); // angle + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(value1)); // angle return 1; } // misc1 = angle (in degrees) (arg +0) static int CreateFaceFunc(VMFunctionBuilder &buildit, int value1, int value2) { // A_FaceTarget - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(value1)); // angle + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, buildit.GetConstantFloat(value1)); // angle return 1; } @@ -710,9 +710,9 @@ static int CreatePlaySoundFunc(VMFunctionBuilder &buildit, int value1, int value buildit.EmitParamInt(SoundMap[value1-1]); // soundid buildit.Emit(OP_PARAMI, CHAN_BODY); // channel - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, float1); // volume + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, float1); // volume buildit.Emit(OP_PARAMI, false); // looping - buildit.Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, attenreg); // attenuation + buildit.Emit(OP_PARAM, REGT_FLOAT | REGT_KONST, attenreg); // attenuation return 5; } @@ -722,7 +722,7 @@ static int CreateRandomJumpFunc(VMFunctionBuilder &buildit, int value1, int valu int statereg = buildit.GetConstantAddress(FindState(value1)); buildit.EmitParamInt(value2); // maxchance - buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, statereg); // jumpto + buildit.Emit(OP_PARAM, REGT_POINTER | REGT_KONST, statereg); // jumpto return 2; } @@ -744,11 +744,11 @@ static int CreateNailBombFunc(VMFunctionBuilder &buildit, int value1, int value2 { // A_Explode // This one does not actually have MBF-style parameters. But since // we're aliasing it to an extension of A_Explode... - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // damage - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // distance - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // flags - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // alert - buildit.Emit(OP_PARAM, 0, REGT_NIL, 0); // fulldamagedistance + buildit.Emit(OP_PARAM, REGT_NIL, 0); // damage + buildit.Emit(OP_PARAM, REGT_NIL, 0); // distance + buildit.Emit(OP_PARAM, REGT_NIL, 0); // flags + buildit.Emit(OP_PARAM, REGT_NIL, 0); // alert + buildit.Emit(OP_PARAM, REGT_NIL, 0); // fulldamagedistance buildit.Emit(OP_PARAMI, 30); // nails buildit.Emit(OP_PARAMI, 10); // naildamage return 7; @@ -804,7 +804,7 @@ void SetDehParams(FState *state, int codepointer) // Emit code to pass the standard action function parameters. for (int i = 0; i < numargs; i++) { - buildit.Emit(OP_PARAM, 0, REGT_POINTER, i); + buildit.Emit(OP_PARAM, REGT_POINTER, i); } // Emit code for action parameters. int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2); diff --git a/src/p_user.cpp b/src/p_user.cpp index 29efe9001..e910eac97 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1195,6 +1195,12 @@ AWeapon *APlayerPawn::PickNewWeapon(PClassActor *ammotype) return best; } +DEFINE_ACTION_FUNCTION(APlayerPawn, PickNewWeapon) +{ + PARAM_SELF_PROLOGUE(APlayerPawn); + PARAM_CLASS(ammo, AActor); + ACTION_RETURN_POINTER(self->PickNewWeapon(ammo)); +} //=========================================================================== // // APlayerPawn :: GiveDeathmatchInventory diff --git a/src/r_videoscale.cpp b/src/r_videoscale.cpp index 4da84849b..420d2fc8b 100644 --- a/src/r_videoscale.cpp +++ b/src/r_videoscale.cpp @@ -79,17 +79,22 @@ namespace CUSTOM_CVAR(Float, vid_scalefactor, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { + setsizeneeded = true; if (self < 0.05 || self > 2.0) self = 1.0; } CUSTOM_CVAR(Int, vid_scalemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { + setsizeneeded = true; if (isOutOfBounds(self)) self = 0; } -CVAR(Bool, vid_cropaspect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Bool, vid_cropaspect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + setsizeneeded = true; +} bool ViewportLinearScale() { diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index d6fc442c6..919c6d953 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -519,12 +519,12 @@ static int EmitParameter(VMFunctionBuilder *build, FxExpression *operand, const if (where.RegType == REGT_NIL) { pos.Message(MSG_ERROR, "Attempted to pass a non-value"); - build->Emit(OP_PARAM, 0, where.RegType, where.RegNum); + build->Emit(OP_PARAM, where.RegType, where.RegNum); return 1; } else { - build->Emit(OP_PARAM, 0, EncodeRegType(where), where.RegNum); + build->Emit(OP_PARAM, EncodeRegType(where), where.RegNum); if (tempstrings != nullptr && where.RegType == REGT_STRING && !where.Fixed && !where.Konst) { tempstrings->Push(where); // keep temp strings until after the function call. @@ -5549,7 +5549,7 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); if (min != nullptr && max != nullptr) { EmitParameter(build, min, ScriptPosition); @@ -5670,7 +5670,7 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build) assert(((PSymbolVMFunction *)sym)->Function != nullptr); callfunc = ((PSymbolVMFunction *)sym)->Function; - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); build->EmitParamInt(0); build->EmitParamInt(choices.Size() - 1); build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 3, 1); @@ -5800,7 +5800,7 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); if (min != nullptr && max != nullptr) { EmitParameter(build, min, ScriptPosition); @@ -5895,7 +5895,7 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); EmitParameter(build, mask, ScriptPosition); build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 1); @@ -5978,7 +5978,7 @@ ExpEmit FxRandomSeed::Emit(VMFunctionBuilder *build) if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng)); EmitParameter(build, seed, ScriptPosition); build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 0); @@ -8644,7 +8644,7 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build) build->Emit(OP_PARAMI, abs(Special)); // pass special number ExpEmit selfemit(Self->Emit(build)); - build->Emit(OP_PARAM, 0, selfemit.Konst ? REGT_POINTER | REGT_KONST : REGT_POINTER, selfemit.RegNum); // pass special number + build->Emit(OP_PARAM, selfemit.Konst ? REGT_POINTER | REGT_KONST : REGT_POINTER, selfemit.RegNum); // pass special number for (; i < ArgList.Size(); ++i) { FxExpression *argex = ArgList[i]; @@ -8664,7 +8664,7 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build) else { ExpEmit arg(argex->Emit(build)); - build->Emit(OP_PARAM, 0, arg.RegType, arg.RegNum); + build->Emit(OP_PARAM, arg.RegType, arg.RegNum); arg.Free(build); } } @@ -9086,11 +9086,11 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) if ((selfemit.Fixed && selfemit.Target) || selfemit.RegType == REGT_STRING) { // Address of a local variable. - build->Emit(OP_PARAM, 0, selfemit.RegType | REGT_ADDROF, selfemit.RegNum); + build->Emit(OP_PARAM, selfemit.RegType | REGT_ADDROF, selfemit.RegNum); } else { - build->Emit(OP_PARAM, 0, selfemit.RegType, selfemit.RegNum); + build->Emit(OP_PARAM, selfemit.RegType, selfemit.RegNum); } count += 1; if (Function->Variants[0].Flags & VARF_Action) @@ -9098,14 +9098,14 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) static_assert(NAP == 3, "This code needs to be updated if NAP changes"); if (build->NumImplicits == NAP && selfemit.RegNum == 0) // only pass this function's stateowner and stateinfo if the subfunction is run in self's context. { - build->Emit(OP_PARAM, 0, REGT_POINTER, 1); - build->Emit(OP_PARAM, 0, REGT_POINTER, 2); + build->Emit(OP_PARAM, REGT_POINTER, 1); + build->Emit(OP_PARAM, REGT_POINTER, 2); } else { // pass self as stateowner, otherwise all attempts of the subfunction to retrieve a state from a name would fail. - build->Emit(OP_PARAM, 0, selfemit.RegType, selfemit.RegNum); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr)); + build->Emit(OP_PARAM, selfemit.RegType, selfemit.RegNum); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr)); } count += 2; } @@ -10696,7 +10696,7 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build) assert(pstr->mDestructor != nullptr); ExpEmit reg(build, REGT_POINTER); build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset)); - build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum); + build->Emit(OP_PARAM, reg.RegType, reg.RegNum); build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0); reg.Free(build); } @@ -10893,8 +10893,8 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build) ExpEmit clsname = basex->Emit(build); assert(!clsname.Konst); ExpEmit dest(build, REGT_POINTER); - build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast(desttype))); + build->Emit(OP_PARAM, clsname.RegType, clsname.RegNum); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast(desttype))); // Call the BuiltinNameToClass function to convert from 'name' to class. VMFunction *callfunc; @@ -11002,8 +11002,8 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) { ExpEmit clsname = basex->Emit(build); - build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum); - build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype)); + build->Emit(OP_PARAM, clsname.RegType, clsname.RegNum); + build->Emit(OP_PARAM, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype)); VMFunction *callfunc; PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast); @@ -11388,7 +11388,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build) { ExpEmit reg(build, REGT_POINTER); build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset)); - build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum); + build->Emit(OP_PARAM, reg.RegType, reg.RegNum); build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor), 1, 0); reg.Free(build); } @@ -11414,7 +11414,7 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build) { ExpEmit reg(build, REGT_POINTER); build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset)); - build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum); + build->Emit(OP_PARAM, reg.RegType, reg.RegNum); build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0); reg.Free(build); } diff --git a/src/scripting/backend/vmbuilder.cpp b/src/scripting/backend/vmbuilder.cpp index 89061d128..11898d09d 100644 --- a/src/scripting/backend/vmbuilder.cpp +++ b/src/scripting/backend/vmbuilder.cpp @@ -594,39 +594,19 @@ size_t VMFunctionBuilder::Emit(int opcode, int opa, int opb, int opc) } if (opc > 255) { - if (opcode == OP_PARAM && (opb & REGT_KONST) && opc <= 32767) + if (opRemap[opcode].kReg != 4 || opc > 32767) { - int regtype = opb & REGT_TYPE; - opb = regtype; - ExpEmit emit(this, regtype); - Emit(opcodes[regtype], emit.RegNum, opc); - opc = emit.RegNum; - emit.Free(this); - } - else - { - if (opRemap[opcode].kReg != 4 || opc > 32767) - { - I_Error("Register limit exceeded"); - } - int regtype = opRemap[opcode].kType; - ExpEmit emit(this, regtype); - Emit(opcodes[regtype], emit.RegNum, opc); - opcode = opRemap[opcode].altOp; - opc = emit.RegNum; - emit.Free(this); + I_Error("Register limit exceeded"); } + int regtype = opRemap[opcode].kType; + ExpEmit emit(this, regtype); + Emit(opcodes[regtype], emit.RegNum, opc); + opcode = opRemap[opcode].altOp; + opc = emit.RegNum; + emit.Free(this); } - if (opcode == OP_PARAM) - { - int chg; - if (opb & REGT_MULTIREG2) chg = 2; - else if (opb®T_MULTIREG3) chg = 3; - else chg = 1; - ParamChange(chg); - } - else if (opcode == OP_CALL || opcode == OP_CALL_K || opcode == OP_TAIL || opcode == OP_TAIL_K) + if (opcode == OP_CALL || opcode == OP_CALL_K || opcode == OP_TAIL || opcode == OP_TAIL_K) { ParamChange(-opb); } @@ -642,6 +622,16 @@ size_t VMFunctionBuilder::Emit(int opcode, int opa, VM_SHALF opbc) { assert(opcode >= 0 && opcode < NUM_OPS); assert(opa >= 0 && opa <= 255); + + if (opcode == OP_PARAM) + { + int chg; + if (opa & REGT_MULTIREG2) chg = 2; + else if (opa & REGT_MULTIREG3) chg = 3; + else chg = 1; + ParamChange(chg); + } + //assert(opbc >= -32768 && opbc <= 32767); always true due to parameter's width VMOP op; op.op = opcode; @@ -682,7 +672,7 @@ size_t VMFunctionBuilder::EmitParamInt(int value) } else { - return Emit(OP_PARAM, 0, REGT_INT | REGT_KONST, GetConstantInt(value)); + return Emit(OP_PARAM, REGT_INT | REGT_KONST, GetConstantInt(value)); } } diff --git a/src/scripting/backend/vmdisasm.cpp b/src/scripting/backend/vmdisasm.cpp index f7e46ac38..53b8891c1 100644 --- a/src/scripting/backend/vmdisasm.cpp +++ b/src/scripting/backend/vmdisasm.cpp @@ -82,7 +82,7 @@ #define I24 MODE_ABCJOINT #define I8 MODE_AIMMZ | MODE_BUNUSED | MODE_CUNUSED #define I8I16 MODE_AIMMZ | MODE_BCIMMZ -#define __BCP MODE_AUNUSED | MODE_BCJOINT | MODE_BCPARAM +#define __BCP MODE_PARAM24 #define RPI8 MODE_AP | MODE_BIMMZ | MODE_CUNUSED #define KPI8 MODE_AKP | MODE_BIMMZ | MODE_CUNUSED #define RPI8I8 MODE_AP | MODE_BIMMZ | MODE_CIMMZ @@ -292,7 +292,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction a &= CMP_CHECK | CMP_APPROX; cmp = true; } - if (code[i].op == OP_PARAM && code[i].b & REGT_ADDROF) + if (code[i].op == OP_PARAM && code[i].a & REGT_ADDROF) { name = "parama"; } @@ -340,6 +340,20 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction } break; } + + case OP_PARAM: + { + col = print_reg(out, col, code[i].i24 & 0xffffff, MODE_PARAM24, 16, func); + break; + } + + case OP_RESULT: + { + // Default handling for this broke after changing OP_PARAM... + col = print_reg(out, col, code[i].i16u, MODE_PARAM, 16, func); + break; + } + case OP_RET: if (code[i].b != REGT_NIL) { @@ -583,14 +597,31 @@ static int print_reg(FILE *out, int col, int arg, int mode, int immshift, const return col+printf_wrapper(out, "%d", arg); case MODE_PARAM: - { - int regtype, regnum; + case MODE_PARAM24: + { + int regtype, regnum; #ifdef __BIG_ENDIAN__ + if (mode == MODE_PARAM) + { regtype = (arg >> 8) & 255; regnum = arg & 255; + } + else + { + regtype = (arg >> 16) & 255; + regnum = arg & 65535; + } #else + if (mode == MODE_PARAM) + { regtype = arg & 255; regnum = (arg >> 8) & 255; + } + else + { + regtype = arg & 255; + regnum = (arg >> 8) & 65535; + } #endif switch (regtype & (REGT_TYPE | REGT_KONST | REGT_MULTIREG)) { diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 8f17b24b3..0a6392724 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -569,77 +569,77 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) assert(f->NumParam < sfunc->MaxParam); { VMValue *param = ®.param[f->NumParam++]; - b = B; - if (b == REGT_NIL) + b = BC; + if (a == REGT_NIL) { ::new(param) VMValue(); } else { - switch(b) + switch(a) { case REGT_INT: - assert(C < f->NumRegD); - ::new(param) VMValue(reg.d[C]); + assert(b < f->NumRegD); + ::new(param) VMValue(reg.d[b]); break; case REGT_INT | REGT_ADDROF: - assert(C < f->NumRegD); - ::new(param) VMValue(®.d[C]); + assert(b < f->NumRegD); + ::new(param) VMValue(®.d[b]); break; case REGT_INT | REGT_KONST: - assert(C < sfunc->NumKonstD); - ::new(param) VMValue(konstd[C]); + assert(b < sfunc->NumKonstD); + ::new(param) VMValue(konstd[b]); break; case REGT_STRING: - assert(C < f->NumRegS); - ::new(param) VMValue(®.s[C]); + assert(b < f->NumRegS); + ::new(param) VMValue(®.s[b]); break; case REGT_STRING | REGT_ADDROF: - assert(C < f->NumRegS); - ::new(param) VMValue((void*)®.s[C]); // Note that this may not use the FString* version of the constructor! + assert(b < f->NumRegS); + ::new(param) VMValue((void*)®.s[b]); // Note that this may not use the FString* version of the constructor! break; case REGT_STRING | REGT_KONST: - assert(C < sfunc->NumKonstS); - ::new(param) VMValue(&konsts[C]); + assert(b < sfunc->NumKonstS); + ::new(param) VMValue(&konsts[b]); break; case REGT_POINTER: - assert(C < f->NumRegA); - ::new(param) VMValue(reg.a[C]); + assert(b < f->NumRegA); + ::new(param) VMValue(reg.a[b]); break; case REGT_POINTER | REGT_ADDROF: - assert(C < f->NumRegA); - ::new(param) VMValue(®.a[C]); + assert(b < f->NumRegA); + ::new(param) VMValue(®.a[b]); break; case REGT_POINTER | REGT_KONST: - assert(C < sfunc->NumKonstA); - ::new(param) VMValue(konsta[C].v); + assert(b < sfunc->NumKonstA); + ::new(param) VMValue(konsta[b].v); break; case REGT_FLOAT: - assert(C < f->NumRegF); - ::new(param) VMValue(reg.f[C]); + assert(b < f->NumRegF); + ::new(param) VMValue(reg.f[b]); break; case REGT_FLOAT | REGT_MULTIREG2: - assert(C < f->NumRegF - 1); + assert(b < f->NumRegF - 1); assert(f->NumParam < sfunc->MaxParam); - ::new(param) VMValue(reg.f[C]); - ::new(param + 1) VMValue(reg.f[C + 1]); + ::new(param) VMValue(reg.f[b]); + ::new(param + 1) VMValue(reg.f[b + 1]); f->NumParam++; break; case REGT_FLOAT | REGT_MULTIREG3: - assert(C < f->NumRegF - 2); + assert(b < f->NumRegF - 2); assert(f->NumParam < sfunc->MaxParam - 1); - ::new(param) VMValue(reg.f[C]); - ::new(param + 1) VMValue(reg.f[C + 1]); - ::new(param + 2) VMValue(reg.f[C + 2]); + ::new(param) VMValue(reg.f[b]); + ::new(param + 1) VMValue(reg.f[b + 1]); + ::new(param + 2) VMValue(reg.f[b + 2]); f->NumParam += 2; break; case REGT_FLOAT | REGT_ADDROF: - assert(C < f->NumRegF); - ::new(param) VMValue(®.f[C]); + assert(b < f->NumRegF); + ::new(param) VMValue(®.f[b]); break; case REGT_FLOAT | REGT_KONST: - assert(C < sfunc->NumKonstF); - ::new(param) VMValue(konstf[C]); + assert(b < sfunc->NumKonstF); + ::new(param) VMValue(konstf[b]); break; default: assert(0); diff --git a/src/scripting/vm/vmintern.h b/src/scripting/vm/vmintern.h index 60850ee8a..5d4ace94c 100644 --- a/src/scripting/vm/vmintern.h +++ b/src/scripting/vm/vmintern.h @@ -163,6 +163,7 @@ enum EVMOpMode MODE_CMP, MODE_PARAM, + MODE_PARAM24, MODE_THROW, MODE_CATCH, MODE_CAST, @@ -209,7 +210,8 @@ enum EVMOpMode MODE_CIMMS = MODE_IMMS << MODE_CSHIFT, MODE_CIMMZ = MODE_IMMZ << MODE_CSHIFT, - MODE_BCJOINT = (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT), + MODE_ABCJOINT = (MODE_JOINT << MODE_ASHIFT) | (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT), + MODE_BCJOINT = (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT), MODE_BCKI = MODE_KI << MODE_BCSHIFT, MODE_BCKF = MODE_KF << MODE_BCSHIFT, MODE_BCKS = MODE_KS << MODE_BCSHIFT, @@ -220,8 +222,6 @@ enum EVMOpMode MODE_BCTHROW = MODE_THROW << MODE_BCSHIFT, MODE_BCCATCH = MODE_CATCH << MODE_BCSHIFT, MODE_BCCAST = MODE_CAST << MODE_BCSHIFT, - - MODE_ABCJOINT = (MODE_JOINT << MODE_ASHIFT) | MODE_BCJOINT, }; struct VMOpInfo diff --git a/wadsrc/static/zscript/level_compatibility.txt b/wadsrc/static/zscript/level_compatibility.txt index 7bc2b017a..a78d1fc13 100644 --- a/wadsrc/static/zscript/level_compatibility.txt +++ b/wadsrc/static/zscript/level_compatibility.txt @@ -4,26 +4,7 @@ class LevelCompatibility play private static void Apply(Name checksum) { switch (checksum) - { - case 'AB24AE6E2CB13CBDD04600A4D37F9189': // doom2.wad map02 - case '1EC0AF1E3985650F0C9000319C599D0C': // doom2bfg.wad map02 - { - // Missing textures - TextureID stone4 = TexMan.CheckForTexture("STONE4", TexMan.Type_Wall); - SetWallTextureID(327, Line.front, Side.bottom, stone4); - SetWallTextureID(328, Line.front, Side.bottom, stone4); - SetWallTextureID(338, Line.front, Side.bottom, stone4); - SetWallTextureID(339, Line.front, Side.bottom, stone4); - break; - } - - case '66C46385EB1A23D60839D1532522076B': // doom2.wad map08 - { - // Missing texture - SetWallTexture(101, Line.back, Side.top, "BRICK7"); - break; - } - + { case 'E2B5D1400279335811C1C1C0B437D9C8': // Deathknights of the Dark Citadel, map54 { // This map has two gear boxes which are flagged for player cross @@ -152,7 +133,7 @@ class LevelCompatibility play case '1E785E841A5247B6223C042EC712EBB3': // TNT: Evilution MAP08 { // Missing texture when lowering sector to red keycard - SetWallTexture(480, Line.back, Side.Bottom, "METAL2"); + SetWallTexture(480, Line.back, Side.bottom, "METAL2"); break; } @@ -162,6 +143,13 @@ class LevelCompatibility play AddSectorTag(330, 11); break; } + + case '55C8DA7B531AE47014AD73FFF4687A36': // TNT: Evilution MAP21 + { + // Missing texture that is most likely unintentional + SetWallTexture(1138, Line.front, Side.top, "PANEL4"); + break; + } case '2C4A3356C5EB3526D2C72A4AA4B18A36': // TNT: Evilution map29 { @@ -191,15 +179,82 @@ class LevelCompatibility play SetLineSpecial(1240, Floor_LowerToLowest, 38, 32); break; } + + case '56D4060662C290791822EDB7225273B7': // Plutonia Experiment MAP08 + { + // Raising ceiling causing a HOM. + OffsetSectorPlane(130, Sector.ceiling, 16); + break; + } + + case '25A16C30CD10157382C01E5DD9C6604B': // Plutonia Experiment MAP10 + { + // Missing textures + SetWallTexture(548, Line.front, Side.bottom, "METAL"); + SetSectorTexture(71, Sector.ceiling, "FLOOR7_1"); + SetWallTexture(1010, Line.front, Side.top, "GSTONE1"); + break; + } case '1EF7DEAECA03DE03BF363A3193757B5C': // PLUTONIA.wad map11 { SetLineSectorRef(41, Line.back, 6); break; - } + } + + case 'B02ACA32AE9630042543037BA630CDE9': // Plutonia Experiment MAP13 + { + // Textures on wrong side at level start. + SetWallTexture(107, Line.back, Side.top, "A-BROWN1"); + SetWallTexture(119, Line.back, Side.top, "A-BROWN1"); + break; + } + + case '9D84B423D8FD28553DDE23B55F97CF4A': // Plutonia Experiment MAP25 + { + // Missing texture at level exit. + SetWallTexture(1152, Line.front, Side.top, "A-BROCK2"); + break; + } + + case 'ABC4EB5A1535ECCD0061AD14F3547908': // Plutonia Experiment, map26 + { + SetSectorSpecial(156, 0); + // Missing textures + SetWallTexture(322, Line.front, Side.top, "A-MUD"); + SetWallTexture(323, Line.front, Side.top, "A-MUD"); + break; + } + + case 'A2634C462717328CC1AD81E81EE77B08': // Plutonia Experiment MAP28 + { + // Missing textures + SetWallTexture(675, Line.front, Side.bottom, "BRICK10"); + SetWallTexture(676, Line.front, Side.bottom, "BRICK10"); + SetWallTexture(834, Line.front, Side.bottom, "WOOD8"); + SetWallTexture(835, Line.front, Side.bottom, "WOOD8"); + SetWallTexture(2460, Line.front, Side.top, "BIGDOOR7"); + SetWallTexture(2496, Line.front, Side.top, "BRICK10"); + + // Allow a player to leave the room in deathmatch without + // needing another player to activate a switch. + SetLineSpecial(1033, Floor_LowerToLowest, 10, 8); + SetLineActivation(1033, SPAC_Use); + break; + } + + case '850AC6D62F0AC57A4DD7EBC2689AC38E': // Plutonia Experiment MAP29 + { + // Texture applied on bottom instead of top + SetWallTexture(2842, Line.front, Side.top, "A-BROCK2"); + break; + } case '279BB50468FE9F5B36C6D821E4902369': // Plutonia Experiment map30 { + // Missing texture and unpegged gate texture during boss reveal + SetWallTexture(730, Line.front, Side.bottom, "ROCKRED1"); + SetLineFlags(730, 0, Line.ML_DONTPEGBOTTOM); // flag items in deathmatch-only area correctly so that 100% items // are possible in solo SetThingFlags(250, 17); @@ -210,6 +265,18 @@ class LevelCompatibility play SetThingFlags(206, 17); break; } + + case 'D5F64E02679A81B82006AF34A6A8EAC3': // Plutonia Experiment MAP32 + { + // Missing textures + TextureID mosrok = TexMan.CheckForTexture("A-MOSROK", TexMan.Type_Wall); + for(int i=0; i<4; i++) + { + SetWallTextureID(569+i, Line.front, Side.top, MOSROK); + } + SetWallTexture(805, Line.front, Side.top, "A-BRICK3"); + break; + } case '4CB7AAC5C43CF32BDF05FD36481C1D9F': // Plutonia: Revisited map27 { @@ -232,6 +299,7 @@ class LevelCompatibility play OffsetSectorPlane(137, Sector.floor, 8); break; } + case 'A24FE135D5B6FD427FE27BEF89717A65': // doom.wad e2m2 { // missing textures @@ -239,6 +307,7 @@ class LevelCompatibility play SetWallTexture(1596, Line.back, Side.top, "WOOD1"); break; } + case '1BC04D646B32D3A3E411DAF3C1A38FF8': // doom.wad e2m4 { // missing textures @@ -248,25 +317,30 @@ class LevelCompatibility play SetWallTexture(1071, Line.front, Side.top, "MARBLE1"); break; } + case '99C580AD8FABE923CAB485CB7F3C5E5D': // doom.wad e2m5 { // missing textures SetWallTexture(590, Line.back, Side.top, "GRAYBIG"); SetWallTexture(590, Line.front, Side.bottom, "BROWN1"); + SetWallTexture(1027, Line.back, Side.top, "SP_HOT1"); break; } + case '3838AB29292587A7EE3CA71E7040868D': // doom.wad e2m6 { // missing texture SetWallTexture(1091, Line.back, Side.top, "compspan"); break; } + case '8590F489879870C098CD7029C3187159': // doom.wad e2m7 { // missing texture SetWallTexture(1286, Line.front, Side.bottom, "SHAWN2"); break; } + case '8A6399FAAA2E68649D4E4B16642074BE': // doom.wad e2m9 { // missing textures @@ -275,6 +349,7 @@ class LevelCompatibility play SetWallTexture(140, Line.back, Side.top, "GSTONE1"); break; } + case '2B65CB046EA40D2E44576949381769CA': // Commercial Doom e3m4 { // This line is erroneously specified as Door_Raise that monsters @@ -282,20 +357,53 @@ class LevelCompatibility play // this into a one-shot Door_Open so that it won't close. SetLineSpecial(1069, Door_Open, 0, 16); SetLineFlags(1069, 0, Line.ML_REPEAT_SPECIAL); + // Fix HOM error from AASTINKY texture + SetWallTexture(470, Line.front, Side.top, "BIGDOOR2"); break; } + + case '100106C75157B7DECB0DCAD2A59C1919': // Doom E3M5 + { + // Replace AASTINKY textures + SetWallTexture(833, Line.front, Side.mid, "FIREWALL"); + SetWallTexture(834, Line.front, Side.mid, "FIREWALL"); + SetWallTexture(836, Line.front, Side.mid, "FIREWALL"); + SetWallTexture(839, Line.front, Side.mid, "FIREWALL"); + // Missing textures at the door leading to the BFG + SetWallTexture(1329, Line.back, Side.bottom, "METAL"); + SetWallTexture(1330, Line.back, Side.bottom, "METAL"); + break; + } + case '5AC51CA9F1B57D4538049422A5E37291': // doom.wad e3m7 { - // missing texture + // missing textures + SetWallTexture(901, Line.back, Side.bottom, "GSTONE1"); SetWallTexture(971, Line.back, Side.top, "SP_HOT1"); break; } + + case 'FE97DCB9E6235FB3C52AE7C143160D73': // Doom E3M9 + { + // Missing texture + SetWallTexture(102, Line.back, Side.bottom, "STONE3"); + break; + } + case 'DA0C8281AC70EEC31127C228BCD7FE2C': // doom.wad e4m1 { // missing texture SetWallTexture(470, Line.front, Side.top, "GSTONE1"); break; } + + case '771092812F38236C9DF2CB06B2D6B24F': // Ultimate Doom E4M2 + { + // Missing texture + SetWallTexture(165, Line.back, Side.top, "WOOD5"); + break; + } + case 'F6EE16F770AD309D608EA0B1F1E249FC': // Ultimate Doom, e4m3 { // Remove unreachable secrets @@ -322,6 +430,7 @@ class LevelCompatibility play SetSectorSpecial(155, 0); break; } + case 'AAECADD4D97970AFF702D86FAFAC7D17': // doom.wad e4m4 { // missing textures @@ -332,6 +441,31 @@ class LevelCompatibility play SetWallTextureID(572, Line.front, Side.top, BROWNHUG); break; } + + case 'C2E09AB0BDD03925305A48AE935B71CA': // Ultimate Doom E4M5 + { + // Missing textures + SetWallTexture(19, Line.back, Side.bottom, "GSTONE1"); + SetWallTexture(109, Line.back, Side.top, "GSTONE1"); + SetWallTexture(711, Line.back, Side.bottom, "FIRELAV2"); + SetWallTexture(713, Line.back, Side.bottom, "FIRELAV2"); + // Lower ceiling on teleporter to fix HOMs. + OffsetSectorPlane(35, Sector.ceiling, -24); + break; + } + + case 'CBBFF61A8C231DFFC8E8A2A2BAEB77FF': // Ultimate Doom E4M6 + { + // Textures on wrong side at Yellow Skull room. + SetWallTexture(475, Line.back, Side.top, "MARBLE2"); + SetWallTexture(476, Line.back, Side.top, "MARBLE2"); + SetWallTexture(479, Line.back, Side.top, "MARBLE2"); + SetWallTexture(480, Line.back, Side.top, "MARBLE2"); + SetWallTexture(481, Line.back, Side.top, "MARBLE2"); + SetWallTexture(482, Line.back, Side.top, "MARBLE2"); + break; + } + case '94D4C869A0C02EF4F7375022B36AAE45': // Ultimate Doom, e4m7 { // Remove unreachable secrets @@ -339,6 +473,25 @@ class LevelCompatibility play SetSectorSpecial(264, 0); break; } + + case '2DC939E508AB8EB68AF79D5B60568711': // Ultimate Doom E4M8 + { + // Missing texture + SetWallTexture(425, Line.front, Side.mid, "SP_HOT1"); + break; + } + + case 'AB24AE6E2CB13CBDD04600A4D37F9189': // doom2.wad map02 + case '1EC0AF1E3985650F0C9000319C599D0C': // doom2bfg.wad map02 + { + // Missing textures + TextureID stone4 = TexMan.CheckForTexture("STONE4", TexMan.Type_Wall); + SetWallTextureID(327, Line.front, Side.bottom, stone4); + SetWallTextureID(328, Line.front, Side.bottom, stone4); + SetWallTextureID(338, Line.front, Side.bottom, stone4); + SetWallTextureID(339, Line.front, Side.bottom, stone4); + break; + } case 'CEC791136A83EEC4B91D39718BDF9D82': // doom2.wad map04 { @@ -351,7 +504,8 @@ class LevelCompatibility play SetWallTextureID(111, Line.front, Side.top, STONE); SetWallTextureID(127, Line.front, Side.top, STONE); SetWallTextureID(128, Line.front, Side.top, STONE); - // remove erroneous blue keycard pickup ambush sector tags (nearby viewing windows, and the lights) + // remove erroneous blue keycard pickup ambush sector tags + // (nearby viewing windows, and the lights) ClearSectorTags(19); ClearSectorTags(20); ClearSectorTags(23); @@ -362,38 +516,125 @@ class LevelCompatibility play ClearSectorTags(85); break; } + case '9E061AD7FBCD7FAD968C976CB4AA3B9D': // doom2.wad map05 { - // fix bug with opening westmost door in door hallway - incorrect sector tagging - see doomwiki.org for more info + // fix bug with opening westmost door in door hallway + // incorrect sector tagging - see doomwiki.org for more info ClearSectorTags(4); ClearSectorTags(153); + // Missing textures + SetWallTexture(489, Line.back, Side.top, "SUPPORT3"); + SetWallTexture(560, Line.back, Side.top, "SUPPORT3"); break; } + + case '291F24417FB3DD411339AE82EF9B3597': // Doom II MAP07 + { + // Missing texture at BFG deathmatch spawn. + SetWallTexture(168, Line.back, Side.bottom, "BRONZE3"); + SetLineFlags(168, 0, Line.ML_DONTPEGBOTTOM); + break; + } + + case '66C46385EB1A23D60839D1532522076B': // doom2.wad map08 + { + // Missing texture + SetWallTexture(101, Line.back, Side.top, "BRICK7"); + break; + } + + case 'FBA6547B9FD44E95671A923A066E516F': // Doom II MAP13 + { + // Missing texture + SetWallTexture(622, Line.back, Side.top, "BROWNGRN"); + break; + } + case '5BDA34DA60C0530794CC1EA2DA017976': // doom2.wad map14 { // missing textures + SetWallTexture(429, Line.front, Side.top, "BSTONE2"); + SetWallTexture(430, Line.front, Side.top, "BSTONE2"); + SetWallTexture(531, Line.front, Side.top, "BSTONE1"); SetWallTexture(1259, Line.back, Side.top, "BSTONE2"); SetWallTexture(1305, Line.back, Side.top, "BSTONE2"); + + TextureID bstone2 = TexMan.CheckForTexture("BSTONE2", TexMan.Type_Wall); + for(int i=0; i<3; i++) + { + SetWallTextureID(607+i, Line.back, Side.top, BSTONE2); + } + + TextureID tanrock5 = TexMan.CheckForTexture("TANROCK5", TexMan.Type_Wall); + for(int i=0; i<7; i++) + { + SetWallTextureID(786+i, Line.back, Side.top, TANROCK5); + } + + TextureID bstone1 = TexMan.CheckForTexture("BSTONE1", TexMan.Type_Wall); + for(int i=0; i<3; i++) + { + SetWallTextureID(1133+i, Line.back, Side.top, BSTONE1); + SetWallTextureID(1137+i, Line.back, Side.top, BSTONE1); + SetWallTextureID(1140+i, Line.back, Side.top, BSTONE1); + } + + // Raise floor between lifts to correspond with others. + OffsetSectorPlane(106, Sector.floor, 16); + break; } + case '1A540BA717BF9EC85F8522594C352F2A': // Doom II, map15 { SetSectorSpecial(147, 0); + // Missing textures + SetWallTexture(94, Line.back, Side.top, "METAL"); + SetWallTexture(95, Line.back, Side.top, "METAL"); + SetWallTexture(989, Line.back, Side.top, "BRICK10"); break; } + + case '6B60F37B91309DFF1CDF02E5E476210D': // Doom II MAP16 + { + // Missing textures + SetWallTexture(162, Line.back, Side.top, "BRICK6"); + SetWallTexture(303, Line.front, Side.top, "STUCCO"); + SetWallTexture(304, Line.front, Side.top, "STUCCO"); + break; + } + + case 'E1CFD5C6E60C3B6C30F8B95FC287E9FE': // Doom II MAP17 + { + // Missing texture + SetWallTexture(379, Line.back, Side.top, "METAL2"); + break; + } + case '0D491365C1B88B7D1B603890100DD03E': // doom2.wad map18 { // missing textures SetWallTexture(451, Line.front, Side.mid, "metal"); SetWallTexture(459, Line.front, Side.mid, "metal"); + SetWallTexture(574, Line.front, Side.top, "grayvine"); break; } + case 'B5506B1E8F2FC272AD0C77B9E0DF5491': // doom2.wad map19 { // missing textures SetWallTexture(355, Line.back, Side.top, "STONE2"); SetWallTexture(736, Line.front, Side.top, "SLADWALL"); + SetWallTexture(1181, Line.back, Side.top, "MARBLE1"); + + TextureID step4 = TexMan.CheckForTexture("STEP4", TexMan.Type_Wall); + for(int i=0; i<3; i++) + { + SetWallTextureID(286+i, Line.back, Side.bottom, STEP4); + } break; } + case 'EBDAC00E9D25D884B2C8F4B1F0390539': // doom2.wad map21 { // push ceiling down in glitchy sectors above the stair switches @@ -401,12 +642,44 @@ class LevelCompatibility play OffsetSectorPlane(54, Sector.ceiling, -56); break; } + + case '94893A0DC429A22ADC4B3A73DA537E16': // Doom II MAP25 + { + // Missing texture at bloodfall near level start + SetWallTexture(436, Line.back, Side.top, "STONE6"); + break; + } + + case '1037366026AAB4B0CF11BAB27DB90E4E': // Doom II MAP26 + { + // Missing texture at level exit + SetWallTexture(761, Line.back, Side.top, "METAL2"); + break; + } + case '110F84DE041052B59307FAF0293E6BC0': // Doom II, map27 { SetSectorSpecial(93, 0); SetWallTexture(582, Line.back, Side.top, "ZIMMER3"); break; } + + case '84BB2C8ED2343C91136B87F1832E7CA5': // Doom II MAP28 + { + // Missing textures + TextureID ashwall6 = TexMan.CheckForTexture("ASHWALL6", TexMan.Type_Wall); + for(int i=0; i<5; i++) + { + SetWallTextureID(103+i, Line.front, Side.top, ASHWALL6); + } + SetWallTexture(221, Line.front, Side.bottom, "BFALL1"); + SetWallTexture(391, Line.front, Side.top, "BIGDOOR5"); + SetWallTexture(531, Line.back, Side.top, "WOOD8"); + SetWallTexture(547, Line.back, Side.top, "WOOD8"); + SetWallTexture(548, Line.back, Side.top, "WOOD8"); + break; + } + case '20251EDA21B2F2ECF6FF5B8BBC00B26C': // Doom II, MAP29 { // Missing textures on teleporters @@ -415,10 +688,13 @@ class LevelCompatibility play { SetWallTextureID(405+i, Line.back, Side.bottom, SUPPORT3); SetWallTextureID(516+i, Line.back, Side.bottom, SUPPORT3); - SetWallTextureID(524+1, Line.back, Side.bottom, SUPPORT3); + SetWallTextureID(524+i, Line.back, Side.bottom, SUPPORT3); SetWallTextureID(1146+i, Line.back, Side.bottom, SUPPORT3); SetWallTextureID(1138+i, Line.back, Side.bottom, SUPPORT3); } + // Fix missing textures at switch with Arch-Vile. + OffsetSectorPlane(152, Sector.ceiling, -32); + SetWallTexture(603, Line.back, Side.top, "WOOD5"); break; } @@ -441,12 +717,6 @@ class LevelCompatibility play break; } - case 'ABC4EB5A1535ECCD0061AD14F3547908': // Plutonia Experiment, map26 - { - SetSectorSpecial(156, 0); - break; - } - case 'FF635FB9A2F076566299910F8C78F707': // nerve.wad, level04 { SetSectorSpecial(868, 0); @@ -463,6 +733,7 @@ class LevelCompatibility play SetWallTextureID(1057, Line.front, Side.top, mossrck1); break; } + case 'ADD0FAC41AFB0B3C9B9F3C0006F93805': // heretic.wad e1m3 { // Broken door between the hallway that leads to a Torch @@ -471,6 +742,7 @@ class LevelCompatibility play OffsetSectorPlane(86, Sector.ceiling, -128); break; } + case '916318D8B06DAC2D83424B23E4B66531': // heretic.wad e1m4 { // Wrong sector offsets @@ -493,6 +765,7 @@ class LevelCompatibility play SetWallTextureID(1296, Line.front, Side.bottom, woodwl); break; } + case '397A0E17A39542E4E8294E156FAB0502': // heretic.wad e2m2 { // Missing green door statues on easy and hard difficulties @@ -500,6 +773,7 @@ class LevelCompatibility play SetThingSkills(18, 31); break; } + case 'CA3773ED313E8899311F3DD0CA195A68': // heretic.wad e3m6 { // Quartz flask outside of map @@ -512,6 +786,7 @@ class LevelCompatibility play SetWallTextureID(370, Line.front, Side.top, mossrck1); break; } + case '5E3FCFDE78310BB89F92B1626A47D0AD': // heretic.wad E4M7 { // Missing textures diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 7b7682e4c..e7c05e7d6 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -1277,6 +1277,7 @@ class PlayerPawn : Actor native native void CheckUse(); native void CheckWeaponButtons(); native Weapon BestWeapon(class ammotype); + native Weapon PickNewWeapon(class ammotype); }