dig rework: Continue digging after action loss if possible; allow dig start from several attachment actions

Sven Eberhardt 2010-02-09 22:29:48 +01:00
parent 15713eabb3
commit 3bea3bb083
4 changed files with 76 additions and 34 deletions

View File

@ -1275,6 +1275,7 @@ Dig = {
AbortCall = "StopDigging",
DigFree = 11,
InLiquidAction = "Swim",
Attach = CNAT_Left | CNAT_Right | CNAT_Bottom,
},
Bridge = {
Prototype = Action,

View File

@ -15,22 +15,13 @@ public func GetCarryTransform(clonk)
public func GetCarrySpecial(clonk) { if(clonk->~GetAction() == "Dig") return "pos_hand1"; }
local fDigging;
public func IsDigging() { return fDigging; }
public func ControlUseStart(object clonk, int x, int y)
{
if(clonk->GetAction() == "Walk")
{
clonk->SetAction("Dig");
clonk->SetComDir(COMD_None);
clonk->SetXDir(0);
clonk->SetYDir(1);
AddEffect("ShovelDust",clonk,1,1,this);
fDigging = 1;
}
else
clonk->CancelUse();
ControlUseHolding(clonk, x, y);
return true;
}
@ -38,25 +29,55 @@ public func HoldingEnabled() { return true; }
public func ControlUseHolding(object clonk, int x, int y)
{
// something happened - don't try to dig anymore
var xdir_boost = 0, ydir_boost = 0;
// Currently not digging?
if(clonk->GetAction() != "Dig")
{
clonk->CancelUse();
return true;
var is_scaling = (clonk->GetProcedure() == "SCALE");
var can_dig = (clonk->GetAction() == "Walk" || is_scaling || clonk->GetProcedure() == "HANGLE");
if (can_dig)
{
clonk->SetAction("Dig");
clonk->SetComDir(COMD_None);
if (is_scaling)
{
// speed boost when Clonk started digging from scaling, so we don't drop down
xdir_boost = (clonk->GetDir()*2-1)*1000;
ydir_boost = -100;
}
}
else
{
if (fDigging)
{
fDigging = false;
RemoveEffect("ShovelDust",clonk,0);
}
return true;
}
}
// Dig start procedure
if(!fDigging && clonk->GetAction() == "Dig")
{
AddEffect("ShovelDust",clonk,1,1,this);
fDigging = true;
}
if (fDigging)
{
var angle = Angle(0,0,x,y);
var speed = clonk->GetPhysical("Dig")/400;
var angle = Angle(0,0,x,y);
var speed = clonk->GetPhysical("Dig")/400;
var iAnimation = EffectVar(1, clonk, GetEffect("IntDig", clonk));
var iPosition = clonk->GetAnimationPosition(iAnimation)*180/clonk->GetAnimationLength("Dig");
Message("%d", clonk, iPosition);
speed = speed*(Cos(iPosition-45, 50)**2)/2500;
Message("%d", clonk, speed);
// limit angle
angle = BoundBy(angle,65,300);
clonk->SetXDir(Sin(angle,+speed),100);
clonk->SetYDir(Cos(angle,-speed),100);
var iAnimation = EffectVar(1, clonk, GetEffect("IntDig", clonk));
var iPosition = clonk->GetAnimationPosition(iAnimation)*180/clonk->GetAnimationLength("Dig");
Message("%d", clonk, iPosition);
speed = speed*(Cos(iPosition-45, 50)**2)/2500;
Message("%d", clonk, speed);
// limit angle
angle = BoundBy(angle,65,300);
clonk->SetXDir(Sin(angle,+speed)+xdir_boost,100);
clonk->SetYDir(Cos(angle,-speed)+ydir_boost,100);
}
return true;
}
@ -68,8 +89,11 @@ public func ControlUseCancel(object clonk, int x, int y)
public func ControlUseStop(object clonk, int x, int y)
{
fDigging = 0;
RemoveEffect("ShovelDust",clonk,0);
if (fDigging)
{
fDigging = 0;
RemoveEffect("ShovelDust",clonk,0);
}
if(clonk->GetAction() != "Dig") return true;
// EffectCall(clonk, GetEffect("IntDig", clonk), "StopDig");

View File

@ -3571,7 +3571,7 @@ void C4Object::ContactAction()
break;
case DFA_DIG:
// Dig: Stop
ObjectComStopDig(this); return;
if (!(Action.pActionDef->GetPropertyInt(P_Attach) & CNAT_Top)) ObjectComStopDig(this); return;
case DFA_HANGLE:
Action.ComDir=COMD_Stop;
break;
@ -3623,7 +3623,7 @@ void C4Object::ContactAction()
return;
case DFA_DIG:
// Dig: Stop
ObjectComStopDig(this);
if (!(Action.pActionDef->GetPropertyInt(P_Attach) & CNAT_Left)) ObjectComStopDig(this);
return;
}
}
@ -3674,7 +3674,7 @@ void C4Object::ContactAction()
return;
case DFA_DIG:
// Dig: Stop
ObjectComStopDig(this);
if (!(Action.pActionDef->GetPropertyInt(P_Attach) & CNAT_Right)) ObjectComStopDig(this);
return;
}
}
@ -4075,16 +4075,31 @@ void C4Object::ExecAction()
break;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case DFA_DIG:
{
if (pAction->GetPropertyInt(P_Attach))
{
Action.t_attach |= pAction->GetPropertyInt(P_Attach);
}
else
{
Action.t_attach |= CNAT_Bottom;
}
smpx=GetX(); smpy=GetY();
if (!Shape.Attach(smpx,smpy,CNAT_Bottom))
{ ObjectComStopDig(this); return; }
lLimit=ValByPhysical(125, pPhysical->Dig);
bool fAttachOK = false;
if (Action.t_attach & CNAT_Bottom && Shape.Attach(smpx,smpy,CNAT_Bottom)) fAttachOK = true;
else if (Action.t_attach & CNAT_Left && Shape.Attach(smpx,smpy,CNAT_Left)) { fAttachOK = true; }
else if (Action.t_attach & CNAT_Right && Shape.Attach(smpx,smpy,CNAT_Right)) { fAttachOK = true; }
else if (Action.t_attach & CNAT_Top && Shape.Attach(smpx,smpy,CNAT_Top)) fAttachOK = true;
if (!fAttachOK)
{ ObjectComStopDig(this); return; }
iPhaseAdvance=40*lLimit;
if (xdir < 0) SetDir(DIR_Left); else if (xdir > 0) SetDir(DIR_Right);
Action.t_attach=CNAT_None;
Mobile=1;
break;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case DFA_SWIM:
lLimit=ValByPhysical(160, pPhysical->Swim);

View File

@ -786,8 +786,10 @@ bool ObjectComCancelAttach(C4Object *cObj)
void ObjectComStopDig(C4Object *cObj)
{
// Stand
// Stand - but keep momentum to allow more dyanamic digging
FIXED o_xdir = cObj->xdir, o_ydir = cObj->ydir;
ObjectActionStand(cObj);
cObj->xdir = o_xdir; cObj->ydir = o_ydir;
// Clear digging command
if (cObj->Command)
if (cObj->Command->Command == C4CMD_Dig)