Posted to tcl by hypnotoad at Mon Dec 08 22:00:08 GMT 2014view pretty
/* ** Advance a crew member by ms milliseconds or less. Return any time ** remaining. */ int Crew_Member_Step(Crew *crewPtr, int ms){ Waypoint *pW=NULL; Portal *pPortal=NULL; if (crewPtr->public_paused) { return 0; } if (crewPtr->public_team > 1 && crewPtr->public_team != crewPtr->id) { return 0; } if(!crewPtr->aStep) { crewPtr->public_operation=CREW_OPERATION_DONE; } switch( crewPtr->public_operation ){ case CREW_OPERATION_ERROR: crewPtr->public_operation=CREW_OPERATION_ERROR; crewPtr->public_countdown=0; return 0; case CREW_OPERATION_BLOCKED: crewPtr->public_operation=CREW_OPERATION_BLOCKED; crewPtr->public_countdown=0; return 0; case CREW_OPERATION_TRAFFIC: case CREW_OPERATION_QUEUED: case CREW_OPERATION_MOVE: case CREW_OPERATION_OPEN: case CREW_OPERATION_VTRANS: case CREW_OPERATION_TRANS: case CREW_OPERATION_CLOSE: crewPtr->blockedReason=NULL; break; case CREW_OPERATION_ARRIVED: case CREW_OPERATION_STOPPED: case CREW_OPERATION_DONE: default: crewPtr->blockedReason=NULL; crewPtr->public_operation=CREW_OPERATION_DONE; crewPtr->public_countdown=0; return 0; } /* ** If we are in a countdown mode, ** finish the countdown */ if( crewPtr->public_countdown>ms ){ crewPtr->public_countdown -= ms; return 0; } ms-=crewPtr->public_countdown; crewPtr->public_countdown=0; crewPtr->public_moved=1; pW = &crewPtr->aStep[crewPtr->iStep]; if(pW->pid) { pPortal=Portal_ById(pW->pid,0); if(!pPortal) { /* Treat any transition with a non-existent portal as a move */ crewPtr->public_operation=CREW_OPERATION_MOVE; } } crewPtr->public_moved=1; if(crewPtr->public_operation==CREW_OPERATION_MOVE || crewPtr->public_operation==CREW_OPERATION_TRAFFIC) { int msUsed,offset=0; if(crewPtr->iStep<(crewPtr->nStep-1)) { offset=0; } else { offset=crewPtr->targetDistance; } if(pW->pid) { crewPtr->public_operation = CREW_OPERATION_OPEN; } else { int movecode=advanceCrewToWaypoint(crewPtr,ms,pW,offset,&msUsed); switch(movecode) { case 0: { ms-=msUsed; crewPtr->public_compartment_entering = 0; LinkRemove(&crewPtr->link2); return ms; } case 1: { if(pW->pid) { crewPtr->public_portal = pW->pid; } else { gotoNextStep(crewPtr); msUsed = 0; return ms; } } case 2: { Crew_Halt(crewPtr,CREW_OPERATION_ERROR); return 0; } } } } if(crewPtr->public_operation==CREW_OPERATION_OPEN) { /* Trying to open a portal. If the portal is on an airlock and ** the airlock is open, then reset the timer and keep trying. */ int code=0; crewPtr->public_portal = pW->pid; code=Portal_Action(pPortal,crewPtr,PORTAL_ACTION_OPEN,pW->openTm*100); if(code<0) { /* ** Portal could not be opened */ Portal_Release(pPortal,crewPtr); Crew_Halt(crewPtr,CREW_OPERATION_BLOCKED); return 0; } if(code>0) { /* ** Waiting for the door to become available ** or for the door to finish opening */ return 0; } if(crewPtr->public_moving!=CREW_MOVING_FLEEING) { Compartment *pTo=Compartment_ById(pW->cid,0); if(pTo->public_accessible > crewPtr->public_protected) { Compartment *pFrom=Compartment_ById(crewPtr->public_compartment,0); if (pTo->public_accessible > pFrom->public_accessible) { /* ** RULE: crew-movement-0001 ** A crewman will not transition from a compartment with ** a lower accessible score to a higher accessible score ** unless the higher accessible score is less than or ** equal to the crew's protection rating */ /* ** Cannot transit, close the door and halt */ if(!anybodyWantsPortalOpen(crewPtr, pW->pid, pW->x, pW->y, pW->deckid) ){ code=Portal_Action(pPortal,crewPtr,PORTAL_ACTION_CLOSE,pW->closeTm*100); if(code==1) { /* ** Waiting for portal to close */ return 0; } } Portal_Release(pPortal,crewPtr); crewPtr->blockedReason="crew-movement-0001"; Crew_Halt(crewPtr,CREW_OPERATION_BLOCKED); return 0; } } } crewPtr->public_operation=CREW_OPERATION_QUEUED; if(pPortal->delta->public_door_state != pPortal->public_door_state) { /* ** If we did change the state of the door, count that ** as time served */ return 0; } } if(crewPtr->public_operation==CREW_OPERATION_QUEUED) { int msUsed=0; /* ** Count the crew going through the portal. If it ** exceeds the number of crew rated, enter wait state */ if(pPortal->public_transit_count) { Crew *p; int count=0; for(p=CurrentSim->pAllCrew; p; p=p->pNext){ if(p->id==crewPtr->id) continue; if(p->public_portal==pW->pid) { if(p->public_operation==CREW_OPERATION_VTRANS || p->public_operation==CREW_OPERATION_TRANS) { count++; } } } /* ** Waiting for portal */ if(count>=pPortal->public_transit_count) { return 0; } } int transitTime=pW->transTm*100; if(pPortal->public_transit_count && crewPtr->public_team) { transitTime=pW->transTm*100*(crewPtr->inParty+1)/pPortal->public_transit_count; } crewPtr->public_compartment_entering = pW->cid; crewPtr->public_countdown=transitTime; if(crewPtr->deckid != pW->deckid) { crewPtr->deckchange=1; crewPtr->public_operation=CREW_OPERATION_VTRANS; } else { crewPtr->deckchange=0; crewPtr->public_operation=CREW_OPERATION_TRANS; } pW->cost = transitTime/1000 + pW->closeTm*0.1; return 0; } if(crewPtr->public_operation==CREW_OPERATION_VTRANS || crewPtr->public_operation==CREW_OPERATION_TRANS) { int code=2; code=Portal_Action(pPortal,crewPtr,PORTAL_ACTION_TRANSIT,1); /* Manage Airlock */ if(code<0) { Portal_Release(pPortal,crewPtr); Crew_Halt(crewPtr,CREW_OPERATION_BLOCKED); return 0; } if(code>0) { /* ** Waiting for the transit time to elapse */ return 0; } /* Move the crew to the waypoint */ crewPtr->tx=pW->x; crewPtr->ty=pW->y; crewPtr->x=pW->x; crewPtr->y=pW->y; crewPtr->deckid=pW->deckid; crewPtr->public_countdown = 0; /* Start the close operation */ crewPtr->public_operation = CREW_OPERATION_CLOSE; pW->cost = pW->closeTm*0.1; } if(crewPtr->public_operation==CREW_OPERATION_CLOSE) { /* Close a portal after moving through it. */ crewPtr->public_compartment=pW->cid; crewPtr->public_compartment_entering=0; int close=0; crewPtr->nextPid = 0; if(!anybodyWantsPortalOpen(crewPtr, pW->pid, pW->x, pW->y, pW->deckid) ){ close=Portal_Action(pPortal,crewPtr,PORTAL_ACTION_CLOSE,pW->closeTm/10.0); if(close==1) { /* ** Waiting for portal to close */ return 0; } } crewPtr->public_portal=0; crewPtr->public_compartment_entering = 0; Portal_Release(pPortal,crewPtr); pW->cost = 0; gotoNextStep(crewPtr); return 0; } return ms; }