-{ T C o r p s e : }
-
-constructor TCorpse.Create(X, Y: Integer; ModelName: String; aMess: Boolean);
-begin
- g_Obj_Init(@FObj);
- FObj.X := X;
- FObj.Y := Y;
- FObj.Rect := PLAYER_CORPSERECT;
- FMess := aMess;
- FModel := g_PlayerModel_Get(ModelName);
-
- if FMess then
- begin
- FState := CORPSE_STATE_MESS;
- FModel.ChangeAnimation(A_DIE2);
- end
- else
- begin
- FState := CORPSE_STATE_NORMAL;
- FModel.ChangeAnimation(A_DIE1);
- end;
-end;
-
-destructor TCorpse.Destroy();
-begin
- FModel.Free;
- inherited;
-end;
-
-function TCorpse.ObjPtr (): PObj; inline; begin result := @FObj; end;
-
-procedure TCorpse.positionChanged (); inline; begin end;
-
-procedure TCorpse.moveBy (dx, dy: Integer); inline;
-begin
- if (dx <> 0) or (dy <> 0) then
- begin
- FObj.X += dx;
- FObj.Y += dy;
- positionChanged();
- end;
-end;
-
-
-procedure TCorpse.getMapBox (out x, y, w, h: Integer); inline;
-begin
- x := FObj.X+PLAYER_CORPSERECT.X;
- y := FObj.Y+PLAYER_CORPSERECT.Y;
- w := PLAYER_CORPSERECT.Width;
- h := PLAYER_CORPSERECT.Height;
-end;
-
-
-procedure TCorpse.Damage(Value: Word; SpawnerUID: Word; vx, vy: Integer);
- {$IFDEF ENABLE_GFX}
- var Blood: TModelBlood;
- {$ENDIF}
-begin
- if FState = CORPSE_STATE_REMOVEME then
- Exit;
-
- FDamage := FDamage + Value;
-
-{$IFDEF ENABLE_GIBS}
- if FDamage > 150 then
- begin
- if FModel <> nil then
- begin
- FState := CORPSE_STATE_REMOVEME;
-
- g_Gibs_Create(
- FObj.X + FObj.Rect.X + (FObj.Rect.Width div 2),
- FObj.Y + FObj.Rect.Y + (FObj.Rect.Height div 2),
- FModel.id,
- FModel.Color
- );
-
- // Звук мяса от трупа:
- FModel.PlaySound(MODELSOUND_DIE, 5, FObj.X, FObj.Y);
-
- // Зловещий смех:
- if (gBodyKillEvent <> -1) and gDelayedEvents[gBodyKillEvent].Pending then
- gDelayedEvents[gBodyKillEvent].Pending := False;
- gBodyKillEvent := g_Game_DelayEvent(DE_BODYKILL, 1050, SpawnerUID);
-
- FModel.Free;
- FModel := nil;
- end
- end
- else
-{$ENDIF}
- begin
- FObj.Vel.X := FObj.Vel.X + vx;
- FObj.Vel.Y := FObj.Vel.Y + vy;
- {$IFDEF ENABLE_GFX}
- Blood := FModel.GetBlood();
- g_GFX_Blood(FObj.X+PLAYER_CORPSERECT.X+(PLAYER_CORPSERECT.Width div 2),
- FObj.Y+PLAYER_CORPSERECT.Y+(PLAYER_CORPSERECT.Height div 2),
- Value, vx, vy, 16, (PLAYER_CORPSERECT.Height*2) div 3,
- Blood.R, Blood.G, Blood.B, Blood.Kind);
- {$ENDIF}
- end;
-end;
-
-procedure TCorpse.Update();
-var
- st: Word;
-begin
- if FState = CORPSE_STATE_REMOVEME then
- Exit;
-
- FObj.oldX := FObj.X;
- FObj.oldY := FObj.Y;
-
- if gTime mod (GAME_TICK*2) <> 0 then
- begin
- g_Obj_Move(@FObj, True, True, True);
- positionChanged(); // this updates spatial accelerators
- Exit;
- end;
-
-// Сопротивление воздуха для трупа:
- FObj.Vel.X := z_dec(FObj.Vel.X, 1);
-
- st := g_Obj_Move(@FObj, True, True, True);
- positionChanged(); // this updates spatial accelerators
-
- if WordBool(st and MOVE_FALLOUT) then
- begin
- FState := CORPSE_STATE_REMOVEME;
- Exit;
- end;
-
- if FModel <> nil then
- FModel.Update;
-end;
-
-
-procedure TCorpse.SaveState (st: TStream);
- var anim: Boolean;
-begin
- assert(st <> nil);
-
- // Сигнатура трупа
- utils.writeSign(st, 'CORP');
- utils.writeInt(st, Byte(0));
- // Состояние
- utils.writeInt(st, Byte(FState));
- // Накопленный урон
- utils.writeInt(st, Byte(FDamage));
- // Цвет
- utils.writeInt(st, Byte(FModel.Color.R));
- utils.writeInt(st, Byte(FModel.Color.G));
- utils.writeInt(st, Byte(FModel.Color.B));
- // Объект трупа
- Obj_SaveState(st, @FObj);
- utils.writeInt(st, Word(FPlayerUID));
- // animation
- anim := (FModel <> nil);
- utils.writeBool(st, anim);
- if anim then FModel.AnimState.SaveState(st, 0, False);
- // animation for mask (same as animation, compat with older saves)
- anim := (FModel <> nil);
- utils.writeBool(st, anim);
- if anim then FModel.AnimState.SaveState(st, 0, False);
-end;
-
-
-procedure TCorpse.LoadState (st: TStream);
- var anim, blending: Boolean; r, g, b, alpha: Byte; stub: TAnimationState;
-begin
- assert(st <> nil);
-
- // Сигнатура трупа
- if not utils.checkSign(st, 'CORP') then raise XStreamError.Create('invalid corpse signature');
- if (utils.readByte(st) <> 0) then raise XStreamError.Create('invalid corpse version');
- // Состояние
- FState := utils.readByte(st);
- // Накопленный урон
- FDamage := utils.readByte(st);
- // Цвет
- r := utils.readByte(st);
- g := utils.readByte(st);
- b := utils.readByte(st);
- FModel.SetColor(r, g, b);
- // Объект трупа
- Obj_LoadState(@FObj, st);
- FPlayerUID := utils.readWord(st);
- // animation
- stub := TAnimationState.Create(False, 0, 0);
- anim := utils.readBool(st);
- if anim then
- begin
- stub.LoadState(st, alpha, blending);
- FModel.AnimState.CurrentFrame := Min(stub.CurrentFrame, FModel.AnimState.Length);
- end
- else
- begin
- FModel.Free;
- FModel := nil
- end;
- // animation for mask (same as animation, compat with older saves)
- anim := utils.readBool(st);
- if anim then stub.LoadState(st, alpha, blending);
- stub.Free;
-end;
-