/** Process double by creating new units by suming new unit to existing unit and appending if not existing params: double data - (in) new double struct Array ** solution - (out) pointer to solution struct Array * units - (in / out) pointer to array of units found */ void processData(double data, struct Array ** solution, struct Array * units) { debug_printf("Process: %f\n", data); struct Unit * unit; int currentUnit = (int)round(data * 100) % 100, newUnit; if(currentUnit == 0) { debug_printf("Solution found: %d with data %f\n", currentUnit, data); //we found the solution struct Array * sol = MakeArrayDouble(); sol->funcTable->AddElement(sol, &data); *solution = sol; return; } int unitsLength = units->length; debug_printf("Create new units with %d units and data: %f\n", unitsLength, data); for(int i = 0; i < unitsLength; i++) { unit = UnitsGetUnitAtIndex(units, i); if(unit != NULL) { newUnit = (unit->unit + currentUnit) % 100; debug_printf("--Got newunit %d from unit at index with unit: %d %f\n", newUnit, unit->unit, data); struct Unit * newUnitObj = UnitsGetUnit(units, newUnit); if(newUnitObj == NULL) { debug_printf("--Create new unit with unit: %d\n", newUnit); struct Unit * unitToAdd = MakeUnit(); unitToAdd->unit = newUnit; printArrayOfDoublesEx(unit->array, 1); debug_printf("\n"); if(unit->array) { unitToAdd->array->funcTable->CopyArray(unitToAdd->array, unit->array); } printArrayOfDoublesEx(unitToAdd->array, 1); debug_printf("\n"); unitToAdd->array->funcTable->AddElement(unitToAdd->array, &data); printArrayOfDoublesEx(unitToAdd->array, 1); debug_printf("\n"); units->funcTable->AddElement(units, unitToAdd); if(newUnit == 0) { *solution = unitToAdd->array; return; } } if(newUnit == 0) { *solution = unit->array; return; } } } unit = UnitsGetUnit(units, currentUnit); if(unit == NULL) { struct Unit * unitToAdd = MakeUnit(); unitToAdd->unit = currentUnit; unitToAdd->array->funcTable->AddElement(unitToAdd->array, &data); units->funcTable->AddElement(units, unitToAdd); } }
/** ** Show Map Location ** ** @param l Lua state. */ static int CclShowMapLocation(lua_State *l) { // Put a unit on map, use its properties, except for // what is listed below LuaCheckArgs(l, 4); const char *unitname = LuaToString(l, 5); CUnitType *unitType = UnitTypeByIdent(unitname); if (!unitType) { DebugPrint("Unable to find UnitType '%s'" _C_ unitname); return 0; } CUnit *target = MakeUnit(*unitType, ThisPlayer); if (target != NULL) { target->Variable[HP_INDEX].Value = 0; target->tilePos.x = LuaToNumber(l, 1); target->tilePos.y = LuaToNumber(l, 2); target->TTL = GameCycle + LuaToNumber(l, 4); target->CurrentSightRange = LuaToNumber(l, 3); //Wyrmgus start UpdateUnitSightRange(*target); //Wyrmgus end MapMarkUnitSight(*target); } else { DebugPrint("Unable to allocate Unit"); } return 0; }
//------------------------------------------------------------------------- void CSeqMaskerWindowPattern::FillWindow( Uint4 winstart ) { first_unit = 0; TUnit unit = 0; Int4 iter = 0; end = winstart + unit_size - 1; Uint4 wstart = winstart; for( ; iter < NumUnits() && end < data.size() && end < winend; ) if( MakeUnit( winstart, unit ) ) { units[iter] = unit; ++iter; end += unit_step; winstart += unit_step; } else { iter = 0; wstart += window_step; winstart = wstart; end = winstart + unit_size - 1; } end -= unit_step; end += (window_size - unit_size)%unit_step; start = end - window_size + 1; state = (iter == NumUnits()); }
void AddNormalAndVolToDofs(struct StateData * state, const EL_INFO * el_info) { REAL_D normal; int nVerts = DIM_OF_WORLD; int i, j, dof; GetElNormal(el_info, normal, state); MakeUnit(normal); REAL area = el_volume(el_info); for (i = 0; i< nVerts; i++) { dof = *(el_info->el->dof[i]); for (j = 0; j< DIM_OF_WORLD; j++) state->surf_normals->vec[dof][j] += normal[j]*area; } }
/** ** Create a unit and place it on the map ** ** @param l Lua state. ** ** @return Returns the slot number of the made unit. */ static int CclCreateUnit(lua_State *l) { LuaCheckArgs(l, 3); lua_pushvalue(l, 1); CUnitType *unittype = CclGetUnitType(l); if (unittype == NULL) { LuaError(l, "Bad unittype"); } lua_pop(l, 1); Vec2i ipos; CclGetPos(l, &ipos.x, &ipos.y, 3); lua_pushvalue(l, 2); const int playerno = TriggerGetPlayer(l); lua_pop(l, 1); if (playerno == -1) { printf("CreateUnit: You cannot use \"any\" in create-unit, specify a player\n"); LuaError(l, "bad player"); return 0; } if (Players[playerno].Type == PlayerNobody) { printf("CreateUnit: player %d does not exist\n", playerno); LuaError(l, "bad player"); return 0; } CUnit *unit = MakeUnit(*unittype, &Players[playerno]); if (unit == NULL) { DebugPrint("Unable to allocate unit"); return 0; } else { if (UnitCanBeAt(*unit, ipos) || (unit->Type->Building && CanBuildUnitType(NULL, *unit->Type, ipos, 0))) { unit->Place(ipos); } else { const int heading = SyncRand() % 256; unit->tilePos = ipos; DropOutOnSide(*unit, heading, NULL); } UpdateForNewUnit(*unit, 0); lua_pushnumber(l, UnitNumber(*unit)); return 1; } }
//------------------------------------------------------------------------- void CSeqMaskerWindowPatternAmbig::FillWindow( Uint4 winstart ) { first_unit = 0; TUnit unit = 0; Int4 iter = 0; end = winstart + unit_size - 1; for( ; iter < NumUnits() && end < data.size(); ++iter, end += unit_step, winstart += unit_step ) { if( MakeUnit( winstart, unit ) ) { units[iter] = unit; } else { units[iter] = ambig_unit; } } end -= unit_step; end += (window_size - unit_size)%unit_step; start = end - window_size + 1; state = (iter == NumUnits()); }
/* virtual */ void CAnimation_SpawnUnit::Action(CUnit &unit, int &/*move*/, int /*scale*/) const { Assert(unit.Anim.Anim == this); const int offX = ParseAnimInt(unit, this->offXStr.c_str()); const int offY = ParseAnimInt(unit, this->offYStr.c_str()); const int range = ParseAnimInt(unit, this->rangeStr.c_str()); const int playerId = ParseAnimInt(unit, this->playerStr.c_str()); const SpawnUnit_Flags flags = (SpawnUnit_Flags)(ParseAnimFlags(unit, this->flagsStr.c_str())); CPlayer &player = Players[playerId]; const Vec2i pos(unit.tilePos.x + offX, unit.tilePos.y + offY); CUnitType *type = UnitTypeByIdent(this->unitTypeStr.c_str()); Assert(type); Vec2i resPos; DebugPrint("Creating a %s\n" _C_ type->Name.c_str()); FindNearestDrop(*type, pos, resPos, LookingW); if (SquareDistance(pos, resPos) <= square(range)) { CUnit *target = MakeUnit(*type, &player); if (target != NULL) { target->tilePos = resPos; target->Place(resPos); if (flags & SU_Summoned) { target->Summoned = 1; } if ((flags & SU_JoinToAIForce) && unit.Player->AiEnabled) { int force = unit.Player->Ai->Force.GetForce(unit); if (force != -1) { unit.Player->Ai->Force[force].Insert(*target); target->GroupId = unit.GroupId; CommandDefend(*target, unit, FlushCommands); } } //DropOutOnSide(*target, LookingW, NULL); } else { DebugPrint("Unable to allocate Unit"); } } }
bool COrder_Build::StartBuilding(CUnit &unit, CUnit &ontop) { const CUnitType &type = this->GetUnitType(); unit.Player->SubUnitType(type); CUnit *build = MakeUnit(const_cast<CUnitType &>(type), unit.Player); // If unable to make unit, stop, and report message if (build == NULL) { // FIXME: Should we retry this? unit.Player->Notify(NotifyYellow, unit.tilePos, _("Unable to create building %s"), type.Name.c_str()); if (unit.Player->AiEnabled) { AiCanNotBuild(unit, type); } return false; } build->Constructed = 1; build->CurrentSightRange = 0; // Building on top of something, may remove what is beneath it if (&ontop != &unit) { CBuildRestrictionOnTop *b; b = static_cast<CBuildRestrictionOnTop *>(OnTopDetails(*build, ontop.Type)); Assert(b); if (b->ReplaceOnBuild) { build->ResourcesHeld = ontop.ResourcesHeld; // We capture the value of what is beneath. build->Variable[GIVERESOURCE_INDEX].Value = ontop.Variable[GIVERESOURCE_INDEX].Value; build->Variable[GIVERESOURCE_INDEX].Max = ontop.Variable[GIVERESOURCE_INDEX].Max; build->Variable[GIVERESOURCE_INDEX].Enable = ontop.Variable[GIVERESOURCE_INDEX].Enable; ontop.Remove(NULL); // Destroy building beneath UnitLost(ontop); UnitClearOrders(ontop); ontop.Release(); } } // Must set action before placing, otherwise it will incorrectly mark radar delete build->CurrentOrder(); build->Orders[0] = COrder::NewActionBuilt(unit, *build); UpdateUnitSightRange(*build); // Must place after previous for map flags build->Place(this->goalPos); // HACK: the building is not ready yet build->Player->UnitTypesCount[type.Slot]--; if (build->Active) { build->Player->UnitTypesAiActiveCount[type.Slot]--; } // We need somebody to work on it. if (!type.BoolFlag[BUILDEROUTSIDE_INDEX].value) { UnitShowAnimation(unit, unit.Type->Animations->Still); unit.Remove(build); this->State = State_BuildFromInside; if (unit.Selected) { SelectedUnitChanged(); } } else { this->State = State_BuildFromOutside; this->BuildingUnit = build; unit.Direction = DirectionToHeading(build->tilePos - unit.tilePos); UnitUpdateHeading(unit); } return true; }
/** ** Unit trains unit! ** ** @param unit Unit that trains. */ global void HandleActionTrain(Unit* unit) { Unit* nunit; UnitType* type; Player* player; #if 0 // JOHNS: should be checked by the user-interface if( &Players[unit->Player]==ThisPlayer ) { // FIXME: If so used you get millions of messages. if( ThisPlayer->Food<=ThisPlayer->Units && unit->Command.Data.Train.Ticks ) { SetMessage( "You need more farms!" ); } else { AiNeedMoreFarms(unit); } } #endif player=unit->Player; unit->Command.Data.Train.Ticks+=SpeedTrain; // FIXME: Should count down if( unit->Command.Data.Train.Ticks >=unit->Command.Data.Train.What[0] ->Stats[player->Player].Costs[TimeCost] ) { // // Check if enough food available. // if( player->Food<=player->NumUnits ) { // FIXME: GameMessage if( player==ThisPlayer ) { // FIXME: PlayVoice :), see task.txt SetMessage("You need more farms!"); } else { // FIXME: Callback for AI! // AiNeedMoreFarms(unit); } unit->Command.Data.Train.Ticks-=SpeedTrain; unit->Reset=1; unit->Wait=FRAMES_PER_SECOND/6; return; } nunit=MakeUnit(&UnitTypes[unit->Command.Data.Train.What[0]->Type] ,player); nunit->X=unit->X; nunit->Y=unit->Y; type=unit->Type; DropOutOnSide(nunit,HeadingW,type->TileWidth,type->TileHeight); // FIXME: GameMessage if( player==ThisPlayer ) { SetMessage("Training complete"); PlayUnitSound(nunit,VoiceReady); } else { AiTrainingComplete(unit,nunit); } unit->Reset=1; unit->Wait=1; if ( --unit->Command.Data.Train.Count ) { int z; for( z = 0; z < MAX_UNIT_TRAIN-1; z++ ) { unit->Command.Data.Train.What[z] = unit->Command.Data.Train.What[z+1]; } unit->Command.Data.Train.Ticks=0; } else { unit->Command.Action=UnitActionStill; } nunit->Command=unit->PendCommand; if( IsSelected(unit) ) { UpdateBottomPanel(); MustRedraw|=RedrawPanels; } return; } if( IsSelected(unit) ) { MustRedraw|=RedrawTopPanel; } unit->Reset=1; unit->Wait=FRAMES_PER_SECOND/6; }
//Wyrmgus start ///* virtual */ int Spell_Summon::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &goalPos) /* virtual */ int Spell_Summon::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &goalPos, int z) //Wyrmgus end { Vec2i pos = goalPos; bool cansummon; CUnitType &unittype = *this->UnitType; int ttl = this->TTL; if (this->RequireCorpse) { const Vec2i offset(1, 1); const Vec2i minPos = pos - offset; const Vec2i maxPos = pos + offset; //Wyrmgus start // CUnit *unit = FindUnit_If(minPos, maxPos, IsDyingAndNotABuilding()); CUnit *unit = FindUnit_If(minPos, maxPos, z, IsDyingAndNotABuilding()); //Wyrmgus end cansummon = false; if (unit != NULL) { // Found a corpse. eliminate it and proceed to summoning. pos = unit->tilePos; //Wyrmgus start z = unit->MapLayer; //Wyrmgus end unit->Remove(NULL); unit->Release(); cansummon = true; } } else { cansummon = true; } if (cansummon) { //Wyrmgus start // DebugPrint("Summoning a %s\n" _C_ unittype.Name.c_str()); DebugPrint("Summoning a %s\n" _C_ unittype.GetDefaultName(*caster.Player).c_str()); //Wyrmgus end // // Create units. // FIXME: do summoned units count on food? // target = MakeUnit(unittype, caster.Player); if (target != NULL) { target->tilePos = pos; //Wyrmgus start target->MapLayer = z; //Wyrmgus end DropOutOnSide(*target, LookingW, NULL); // To avoid defending summoned unit for AI target->Summoned = 1; // // set life span. ttl=0 results in a permanent unit. // if (ttl) { target->TTL = GameCycle + ttl; } // Insert summoned unit to AI force so it will help them in battle if (this->JoinToAiForce && caster.Player->AiEnabled) { int force = caster.Player->Ai->Force.GetForce(caster); if (force != -1) { caster.Player->Ai->Force[force].Insert(*target); target->GroupId = caster.GroupId; CommandDefend(*target, caster, FlushCommands); } } caster.Variable[MANA_INDEX].Value -= spell.ManaCost; } else { DebugPrint("Unable to allocate Unit"); } return 1; } return 0; }
/* virtual */ void COrder_Train::Execute(CUnit &unit) { AnimateActionTrain(unit); if (unit.Wait) { unit.Wait--; return ; } CPlayer &player = *unit.Player; const CUnitType &nType = *this->Type; const int cost = nType.Stats[player.Index].Costs[TimeCost]; this->Ticks += std::max(1, player.SpeedTrain / SPEEDUP_FACTOR); if (this->Ticks < cost) { unit.Wait = CYCLES_PER_SECOND / 6; return ; } this->Ticks = std::min(this->Ticks, cost); // Check if enough supply available. const int food = player.CheckLimits(nType); if (food < 0) { if (food == -3 && unit.Player->AiEnabled) { AiNeedMoreSupply(*unit.Player); } unit.Wait = CYCLES_PER_SECOND / 6; return ; } CUnit *newUnit = MakeUnit(nType, &player); if (newUnit == NULL) { // No more memory :/ player.Notify(NotifyYellow, unit.tilePos, _("Unable to train %s"), nType.Name.c_str()); unit.Wait = CYCLES_PER_SECOND / 6; return ; } // New unit might supply food UpdateForNewUnit(*newUnit, 0); // Set life span if (unit.Type->DecayRate) { newUnit->TTL = GameCycle + unit.Type->DecayRate * 6 * CYCLES_PER_SECOND; } /* Auto Group Add */ if (!unit.Player->AiEnabled && unit.GroupId) { int num = 0; while (!(unit.GroupId & (1 << num))) { ++num; } AddToGroup(&newUnit, 1, num); } DropOutOnSide(*newUnit, LookingW, &unit); player.Notify(NotifyGreen, newUnit->tilePos, _("New %s ready"), nType.Name.c_str()); if (&player == ThisPlayer) { PlayUnitSound(*newUnit, VoiceReady); } if (unit.Player->AiEnabled) { AiTrainingComplete(unit, *newUnit); } if (unit.NewOrder && unit.NewOrder->HasGoal() && unit.NewOrder->GetGoal()->Destroyed) { delete unit.NewOrder; unit.NewOrder = NULL; } if (CanHandleOrder(*newUnit, unit.NewOrder) == true) { delete newUnit->Orders[0]; newUnit->Orders[0] = unit.NewOrder->Clone(); } else { #if 0 // Tell the unit to rigth-click ? #endif } this->Finished = true; if (IsOnlySelected(unit)) { UI.ButtonPanel.Update(); } }